2015-04-30 15:56:05 +00:00
/*
* $ Id $
*
2016-02-12 16:23:26 +00:00
Copyright ( c ) 2014 - 2016 Chung , Hyung - Hwan . All rights reserved .
2015-04-30 15:56:05 +00:00
Redistribution and use in source and binary forms , with or without
modification , are permitted provided that the following conditions
are met :
1. Redistributions of source code must retain the above copyright
notice , this list of conditions and the following disclaimer .
2. Redistributions in binary form must reproduce the above copyright
notice , this list of conditions and the following disclaimer in the
documentation and / or other materials provided with the distribution .
THIS SOFTWARE IS PROVIDED BY THE AUTHOR " AS IS " AND ANY EXPRESS OR
IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
2017-01-09 09:54:49 +00:00
# include "moo-prv.h"
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
void * moo_allocbytes ( moo_t * moo , moo_oow_t size )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
moo_uint8_t * ptr ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
# if defined(MOO_DEBUG_GC)
if ( ! ( moo - > option . trait & MOO_NOGC ) ) moo_gc ( moo ) ;
2015-05-07 15:58:04 +00:00
# endif
2017-01-09 09:54:49 +00:00
ptr = moo_allocheapmem ( moo , moo - > curheap , size ) ;
if ( ! ptr & & moo - > errnum = = MOO_EOOMEM & & ! ( moo - > option . trait & MOO_NOGC ) )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
moo_gc ( moo ) ;
ptr = moo_allocheapmem ( moo , moo - > curheap , size ) ;
2015-05-03 17:10:30 +00:00
/* TODO: grow heap if ptr is still null. */
2015-04-30 15:56:05 +00:00
}
return ptr ;
}
2017-01-09 09:54:49 +00:00
moo_oop_t moo_allocoopobj ( moo_t * moo , moo_oow_t size )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
moo_oop_oop_t hdr ;
moo_oow_t nbytes , nbytes_aligned ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
nbytes = size * MOO_SIZEOF ( moo_oop_t ) ;
2015-04-30 15:56:05 +00:00
/* this isn't really necessary since nbytes must be
* aligned already . */
2017-01-09 09:54:49 +00:00
nbytes_aligned = MOO_ALIGN ( nbytes , MOO_SIZEOF ( moo_oop_t ) ) ;
2015-04-30 15:56:05 +00:00
/* making the number of bytes to allocate a multiple of
2017-01-09 09:54:49 +00:00
* MOO_SIZEOF ( moo_oop_t ) will guarantee the starting address
2015-04-30 15:56:05 +00:00
* of the allocated space to be an even number .
2017-01-09 09:54:49 +00:00
* see MOO_OOP_IS_NUMERIC ( ) and MOO_OOP_IS_POINTER ( ) */
hdr = moo_allocbytes ( moo , MOO_SIZEOF ( moo_obj_t ) + nbytes_aligned ) ;
if ( ! hdr ) return MOO_NULL ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
hdr - > _flags = MOO_OBJ_MAKE_FLAGS ( MOO_OBJ_TYPE_OOP , MOO_SIZEOF ( moo_oop_t ) , 0 , 0 , 0 , 0 , 0 ) ;
MOO_OBJ_SET_SIZE ( hdr , size ) ;
MOO_OBJ_SET_CLASS ( hdr , moo - > _nil ) ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
while ( size > 0 ) hdr - > slot [ - - size ] = moo - > _nil ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
return ( moo_oop_t ) hdr ;
2015-04-30 15:56:05 +00:00
}
2017-01-09 09:54:49 +00:00
# if defined(MOO_USE_OBJECT_TRAILER)
moo_oop_t moo_allocoopobjwithtrailer ( moo_t * moo , moo_oow_t size , const moo_oob_t * bptr , moo_oow_t blen )
2015-07-01 15:01:39 +00:00
{
2017-01-09 09:54:49 +00:00
moo_oop_oop_t hdr ;
moo_oow_t nbytes , nbytes_aligned ;
moo_oow_t i ;
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
/* +1 for the trailer size of the moo_oow_t type */
nbytes = ( size + 1 ) * MOO_SIZEOF ( moo_oop_t ) + blen ;
nbytes_aligned = MOO_ALIGN ( nbytes , MOO_SIZEOF ( moo_oop_t ) ) ;
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
hdr = moo_allocbytes ( moo , MOO_SIZEOF ( moo_obj_t ) + nbytes_aligned ) ;
if ( ! hdr ) return MOO_NULL ;
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
hdr - > _flags = MOO_OBJ_MAKE_FLAGS ( MOO_OBJ_TYPE_OOP , MOO_SIZEOF ( moo_oop_t ) , 0 , 0 , 0 , 0 , 1 ) ;
MOO_OBJ_SET_SIZE ( hdr , size ) ;
MOO_OBJ_SET_CLASS ( hdr , moo - > _nil ) ;
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
for ( i = 0 ; i < size ; i + + ) hdr - > slot [ i ] = moo - > _nil ;
2015-07-01 15:01:39 +00:00
/* [NOTE] this is not converted to a SmallInteger object */
2017-01-09 09:54:49 +00:00
hdr - > slot [ size ] = ( moo_oop_t ) blen ;
2015-07-01 15:01:39 +00:00
if ( bptr )
{
2017-01-09 09:54:49 +00:00
MOO_MEMCPY ( & hdr - > slot [ size + 1 ] , bptr , blen ) ;
2015-07-01 15:01:39 +00:00
}
else
{
2017-01-09 09:54:49 +00:00
MOO_MEMSET ( & hdr - > slot [ size + 1 ] , 0 , blen ) ;
2015-07-01 15:01:39 +00:00
}
2017-01-09 09:54:49 +00:00
return ( moo_oop_t ) hdr ;
2015-07-01 15:01:39 +00:00
}
# endif
2017-01-09 09:54:49 +00:00
static MOO_INLINE moo_oop_t alloc_numeric_array ( moo_t * moo , const void * ptr , moo_oow_t len , moo_obj_type_t type , moo_oow_t unit , int extra )
2015-04-30 15:56:05 +00:00
{
/* allocate a variable object */
2017-01-09 09:54:49 +00:00
moo_oop_t hdr ;
moo_oow_t xbytes , nbytes , nbytes_aligned ;
2015-04-30 15:56:05 +00:00
xbytes = len * unit ;
/* 'extra' indicates an extra unit to append at the end.
* it ' s useful to store a string with a terminating null */
nbytes = extra ? xbytes + len : xbytes ;
2017-01-09 09:54:49 +00:00
nbytes_aligned = MOO_ALIGN ( nbytes , MOO_SIZEOF ( moo_oop_t ) ) ;
2015-05-08 14:29:35 +00:00
/* TODO: check overflow in size calculation*/
2015-04-30 15:56:05 +00:00
/* making the number of bytes to allocate a multiple of
2017-01-09 09:54:49 +00:00
* MOO_SIZEOF ( moo_oop_t ) will guarantee the starting address
2015-04-30 15:56:05 +00:00
* of the allocated space to be an even number .
2017-01-09 09:54:49 +00:00
* see MOO_OOP_IS_NUMERIC ( ) and MOO_OOP_IS_POINTER ( ) */
hdr = moo_allocbytes ( moo , MOO_SIZEOF ( moo_obj_t ) + nbytes_aligned ) ;
if ( ! hdr ) return MOO_NULL ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
hdr - > _flags = MOO_OBJ_MAKE_FLAGS ( type , unit , extra , 0 , 0 , 0 , 0 ) ;
2015-05-03 17:10:30 +00:00
hdr - > _size = len ;
2017-01-09 09:54:49 +00:00
MOO_OBJ_SET_SIZE ( hdr , len ) ;
MOO_OBJ_SET_CLASS ( hdr , moo - > _nil ) ;
2015-04-30 15:56:05 +00:00
if ( ptr )
{
/* copy data */
2017-01-09 09:54:49 +00:00
MOO_MEMCPY ( hdr + 1 , ptr , xbytes ) ;
MOO_MEMSET ( ( moo_uint8_t * ) ( hdr + 1 ) + xbytes , 0 , nbytes_aligned - xbytes ) ;
2015-04-30 15:56:05 +00:00
}
else
{
/* initialize with zeros when the string pointer is not given */
2017-01-09 09:54:49 +00:00
MOO_MEMSET ( ( hdr + 1 ) , 0 , nbytes_aligned ) ;
2015-04-30 15:56:05 +00:00
}
return hdr ;
}
2017-01-09 09:54:49 +00:00
moo_oop_t moo_alloccharobj ( moo_t * moo , const moo_ooch_t * ptr , moo_oow_t len )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
return alloc_numeric_array ( moo , ptr , len , MOO_OBJ_TYPE_CHAR , MOO_SIZEOF ( moo_ooch_t ) , 1 ) ;
2015-04-30 15:56:05 +00:00
}
2017-01-09 09:54:49 +00:00
moo_oop_t moo_allocbyteobj ( moo_t * moo , const moo_oob_t * ptr , moo_oow_t len )
2015-07-01 15:01:39 +00:00
{
2017-01-09 09:54:49 +00:00
return alloc_numeric_array ( moo , ptr , len , MOO_OBJ_TYPE_BYTE , MOO_SIZEOF ( moo_oob_t ) , 0 ) ;
2015-07-01 15:01:39 +00:00
}
2017-01-09 09:54:49 +00:00
moo_oop_t moo_allochalfwordobj ( moo_t * moo , const moo_oohw_t * ptr , moo_oow_t len )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
return alloc_numeric_array ( moo , ptr , len , MOO_OBJ_TYPE_HALFWORD , MOO_SIZEOF ( moo_oohw_t ) , 0 ) ;
2015-04-30 15:56:05 +00:00
}
2017-01-09 09:54:49 +00:00
moo_oop_t moo_allocwordobj ( moo_t * moo , const moo_oow_t * ptr , moo_oow_t len )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
return alloc_numeric_array ( moo , ptr , len , MOO_OBJ_TYPE_WORD , MOO_SIZEOF ( moo_oow_t ) , 0 ) ;
2015-04-30 15:56:05 +00:00
}
2017-01-09 09:54:49 +00:00
static MOO_INLINE int decode_spec ( moo_t * moo , moo_oop_t _class , moo_oow_t vlen , moo_obj_type_t * type , moo_oow_t * outlen )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
moo_oow_t spec ;
moo_oow_t named_instvar ;
moo_obj_type_t indexed_type ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
MOO_ASSERT ( moo , MOO_OOP_IS_POINTER ( _class ) ) ;
MOO_ASSERT ( moo , MOO_CLASSOF ( moo , _class ) = = moo - > _class ) ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
MOO_ASSERT ( moo , MOO_OOP_IS_SMOOI ( ( ( moo_oop_class_t ) _class ) - > spec ) ) ;
spec = MOO_OOP_TO_SMOOI ( ( ( moo_oop_class_t ) _class ) - > spec ) ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
named_instvar = MOO_CLASS_SPEC_NAMED_INSTVAR ( spec ) ; /* size of the named_instvar part */
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
if ( MOO_CLASS_SPEC_IS_INDEXED ( spec ) )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
indexed_type = MOO_CLASS_SPEC_INDEXED_TYPE ( spec ) ;
2015-05-03 17:10:30 +00:00
2017-01-09 09:54:49 +00:00
if ( indexed_type = = MOO_OBJ_TYPE_OOP )
2015-05-03 17:10:30 +00:00
{
2017-01-09 09:54:49 +00:00
if ( named_instvar > MOO_MAX_NAMED_INSTVARS )
2015-05-03 17:10:30 +00:00
{
2017-01-09 09:54:49 +00:00
MOO_DEBUG3 ( moo , " Too many named instance variables for a variable-pointer class %O - %zu/%zu \n " , _class , named_instvar , ( moo_oow_t ) MOO_MAX_NAMED_INSTVARS ) ;
2016-11-18 18:11:13 +00:00
return - 1 ;
}
2017-01-09 09:54:49 +00:00
if ( vlen > MOO_MAX_INDEXED_INSTVARS ( named_instvar ) )
2016-11-18 18:11:13 +00:00
{
2017-01-09 09:54:49 +00:00
MOO_DEBUG3 ( moo , " Too many unnamed instance variables for a variable-pointer class %O - %zu/%zu \n " , _class , vlen , ( moo_oow_t ) MOO_MAX_INDEXED_INSTVARS ( named_instvar ) ) ;
2015-12-27 18:02:59 +00:00
return - 1 ;
2015-05-03 17:10:30 +00:00
}
2015-12-22 07:49:28 +00:00
2017-01-09 09:54:49 +00:00
MOO_ASSERT ( moo , named_instvar + vlen < = MOO_OBJ_SIZE_MAX ) ;
2015-05-03 17:10:30 +00:00
}
else
{
/* a non-pointer indexed class can't have named instance variables */
2016-11-18 18:11:13 +00:00
if ( named_instvar > 0 )
{
2017-01-09 09:54:49 +00:00
MOO_DEBUG1 ( moo , " Named instance variables in a variable-nonpointer class %O \n " , _class ) ;
2016-11-18 18:11:13 +00:00
return - 1 ;
}
2017-01-09 09:54:49 +00:00
if ( vlen > MOO_OBJ_SIZE_MAX )
2016-11-18 18:11:13 +00:00
{
2017-01-09 09:54:49 +00:00
MOO_DEBUG3 ( moo , " Too many unnamed instance variables for a variable-nonpointer class %O - %zu/%zu \n " , _class , vlen , ( moo_oow_t ) MOO_OBJ_SIZE_MAX ) ;
2016-11-18 18:11:13 +00:00
return - 1 ;
}
2015-05-03 17:10:30 +00:00
}
2015-04-30 15:56:05 +00:00
}
else
{
2015-05-03 17:10:30 +00:00
/* named instance variables only. treat it as if it is an
* indexable class with no variable data */
2017-01-09 09:54:49 +00:00
indexed_type = MOO_OBJ_TYPE_OOP ;
2015-05-03 17:10:30 +00:00
2016-11-18 18:11:13 +00:00
if ( vlen > 0 )
{
2017-01-09 09:54:49 +00:00
MOO_DEBUG2 ( moo , " Unamed instance variables for a fixed class %O - %zu \n " , _class , vlen ) ;
2016-11-18 18:11:13 +00:00
return - 1 ;
}
/*vlen = 0;*/ /* vlen is not used */
2017-01-09 09:54:49 +00:00
if ( named_instvar > MOO_MAX_NAMED_INSTVARS )
2016-11-18 18:11:13 +00:00
{
2017-01-09 09:54:49 +00:00
MOO_DEBUG3 ( moo , " Too many named instance variables for a fixed class %O - %zu/%zu \n " , _class , named_instvar , ( moo_oow_t ) MOO_MAX_NAMED_INSTVARS ) ;
2016-11-18 18:11:13 +00:00
return - 1 ;
}
2017-01-09 09:54:49 +00:00
MOO_ASSERT ( moo , named_instvar < = MOO_OBJ_SIZE_MAX ) ;
2015-04-30 15:56:05 +00:00
}
2015-12-27 18:02:59 +00:00
* type = indexed_type ;
* outlen = named_instvar + vlen ;
return 0 ;
}
2017-01-09 09:54:49 +00:00
moo_oop_t moo_instantiate ( moo_t * moo , moo_oop_t _class , const void * vptr , moo_oow_t vlen )
2015-12-27 18:02:59 +00:00
{
2017-01-09 09:54:49 +00:00
moo_oop_t oop ;
moo_obj_type_t type ;
moo_oow_t alloclen ;
moo_oow_t tmp_count = 0 ;
2015-12-27 18:02:59 +00:00
2017-01-09 09:54:49 +00:00
MOO_ASSERT ( moo , moo - > _nil ! = MOO_NULL ) ;
2015-12-27 18:02:59 +00:00
2017-01-09 09:54:49 +00:00
if ( decode_spec ( moo , _class , vlen , & type , & alloclen ) < = - 1 )
2015-12-27 18:02:59 +00:00
{
2017-01-09 09:54:49 +00:00
moo - > errnum = MOO_EINVAL ;
return MOO_NULL ;
2015-12-27 18:02:59 +00:00
}
2017-01-09 09:54:49 +00:00
moo_pushtmp ( moo , & _class ) ; tmp_count + + ;
2015-05-07 15:58:04 +00:00
2015-12-27 18:02:59 +00:00
switch ( type )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_OOP :
2015-05-07 15:58:04 +00:00
/* both the fixed part(named instance variables) and
* the variable part ( indexed instance variables ) are allowed . */
2017-01-09 09:54:49 +00:00
oop = moo_allocoopobj ( moo , alloclen ) ;
2015-04-30 15:56:05 +00:00
2017-01-09 09:54:49 +00:00
MOO_ASSERT ( moo , vptr = = MOO_NULL ) ;
2015-06-03 17:24:11 +00:00
/*
This function is not GC - safe . so i don ' t want to initialize
2015-12-02 15:24:13 +00:00
the payload of a pointer object . The caller can call this
function and initialize payloads then .
2015-05-08 14:29:35 +00:00
if ( oop & & vptr & & vlen > 0 )
2015-04-30 15:56:05 +00:00
{
2017-01-09 09:54:49 +00:00
moo_oop_oop_t hdr = ( moo_oop_oop_t ) oop ;
MOO_MEMCPY ( & hdr - > slot [ named_instvar ] , vptr , vlen * MOO_SIZEOF ( moo_oop_t ) ) ;
2015-04-30 15:56:05 +00:00
}
2015-12-02 15:24:13 +00:00
For the above code to work , it should protect the elements of
2017-01-09 09:54:49 +00:00
the vptr array with moo_pushtmp ( ) . So it might be better
2015-12-02 15:24:13 +00:00
to disallow a non - NULL vptr when indexed_type is OOP . See
the assertion above this comment block .
2015-06-03 17:24:11 +00:00
*/
2015-04-30 15:56:05 +00:00
break ;
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_CHAR :
oop = moo_alloccharobj ( moo , vptr , alloclen ) ;
2015-04-30 15:56:05 +00:00
break ;
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_BYTE :
oop = moo_allocbyteobj ( moo , vptr , alloclen ) ;
2015-10-30 15:36:37 +00:00
break ;
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_HALFWORD :
oop = moo_allochalfwordobj ( moo , vptr , alloclen ) ;
2015-04-30 15:56:05 +00:00
break ;
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_WORD :
oop = moo_allocwordobj ( moo , vptr , alloclen ) ;
2015-04-30 15:56:05 +00:00
break ;
default :
2017-01-09 09:54:49 +00:00
moo - > errnum = MOO_EINTERN ;
oop = MOO_NULL ;
2015-05-08 14:29:35 +00:00
break ;
2015-04-30 15:56:05 +00:00
}
2017-01-09 09:54:49 +00:00
if ( oop ) MOO_OBJ_SET_CLASS ( oop , _class ) ;
moo_poptmps ( moo , tmp_count ) ;
2015-04-30 15:56:05 +00:00
return oop ;
}
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
moo_oop_t moo_instantiate2 ( moo_t * moo , moo_oop_t _class , const void * vptr , moo_oow_t vlen , int ngc )
2015-07-01 15:01:39 +00:00
{
2017-01-09 09:54:49 +00:00
moo_oop_t oop ;
moo_obj_type_t type ;
moo_oow_t alloclen ;
moo_oow_t tmp_count = 0 ;
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
MOO_ASSERT ( moo , moo - > _nil ! = MOO_NULL ) ;
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
if ( decode_spec ( moo , _class , vlen , & type , & alloclen ) < = - 1 )
2015-12-27 18:02:59 +00:00
{
2017-01-09 09:54:49 +00:00
moo - > errnum = MOO_EINVAL ;
return MOO_NULL ;
2015-12-27 18:02:59 +00:00
}
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
moo_pushtmp ( moo , & _class ) ; tmp_count + + ;
2015-07-01 15:01:39 +00:00
2015-12-27 18:02:59 +00:00
/* TODO: support NGC */
switch ( type )
2015-07-01 15:01:39 +00:00
{
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_OOP :
2015-12-27 18:02:59 +00:00
/* NOTE: vptr is not used for GC unsafety */
2017-01-09 09:54:49 +00:00
oop = moo_allocoopobj ( moo , alloclen ) ;
2015-12-27 18:02:59 +00:00
break ;
2015-07-01 15:01:39 +00:00
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_CHAR :
oop = moo_alloccharobj ( moo , vptr , alloclen ) ;
2015-12-27 18:02:59 +00:00
break ;
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_BYTE :
oop = moo_allocbyteobj ( moo , vptr , alloclen ) ;
2015-12-27 18:02:59 +00:00
break ;
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_HALFWORD :
oop = moo_allochalfwordobj ( moo , vptr , alloclen ) ;
2015-12-27 18:02:59 +00:00
break ;
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_WORD :
oop = moo_allocwordobj ( moo , vptr , alloclen ) ;
2015-12-27 18:02:59 +00:00
break ;
default :
2017-01-09 09:54:49 +00:00
moo - > errnum = MOO_EINTERN ;
oop = MOO_NULL ;
2015-12-27 18:02:59 +00:00
break ;
2015-07-01 15:01:39 +00:00
}
2017-01-09 09:54:49 +00:00
if ( oop ) MOO_OBJ_SET_CLASS ( oop , _class ) ;
moo_poptmps ( moo , tmp_count ) ;
2015-12-27 18:02:59 +00:00
return oop ;
}
2017-01-09 09:54:49 +00:00
# if defined(MOO_USE_OBJECT_TRAILER)
2015-12-27 18:02:59 +00:00
2017-01-09 09:54:49 +00:00
moo_oop_t moo_instantiatewithtrailer ( moo_t * moo , moo_oop_t _class , moo_oow_t vlen , const moo_oob_t * tptr , moo_oow_t tlen )
2015-12-27 18:02:59 +00:00
{
2017-01-09 09:54:49 +00:00
moo_oop_t oop ;
moo_obj_type_t type ;
moo_oow_t alloclen ;
moo_oow_t tmp_count = 0 ;
2015-12-27 18:02:59 +00:00
2017-01-09 09:54:49 +00:00
MOO_ASSERT ( moo , moo - > _nil ! = MOO_NULL ) ;
2015-12-27 18:02:59 +00:00
2017-01-09 09:54:49 +00:00
if ( decode_spec ( moo , _class , vlen , & type , & alloclen ) < = - 1 )
2015-12-27 18:02:59 +00:00
{
2017-01-09 09:54:49 +00:00
moo - > errnum = MOO_EINVAL ;
return MOO_NULL ;
2015-07-01 15:01:39 +00:00
}
2017-01-09 09:54:49 +00:00
moo_pushtmp ( moo , & _class ) ; tmp_count + + ;
2015-07-01 15:01:39 +00:00
2015-12-27 18:02:59 +00:00
switch ( type )
2015-07-01 15:01:39 +00:00
{
2017-01-09 09:54:49 +00:00
case MOO_OBJ_TYPE_OOP :
2015-12-27 18:02:59 +00:00
/* NOTE: vptr is not used for GC unsafety */
2017-01-09 09:54:49 +00:00
oop = moo_allocoopobjwithtrailer ( moo , alloclen , tptr , tlen ) ;
2015-07-01 15:01:39 +00:00
break ;
default :
2017-01-09 09:54:49 +00:00
moo - > errnum = MOO_EINTERN ;
oop = MOO_NULL ;
2015-07-01 15:01:39 +00:00
break ;
}
2017-01-09 09:54:49 +00:00
if ( oop ) MOO_OBJ_SET_CLASS ( oop , _class ) ;
moo_poptmps ( moo , tmp_count ) ;
2015-07-01 15:01:39 +00:00
return oop ;
}
# endif
2015-10-30 15:36:37 +00:00