2015-04-30 15:56:05 +00:00
/*
* $ Id $
*
2018-02-21 10:11:39 +00:00
Copyright ( c ) 2014 - 2018 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
{
2018-02-21 09:35:59 +00:00
# if defined(MOO_BUILD_DEBUG)
2018-02-05 09:20:30 +00:00
if ( ( moo - > option . trait & MOO_DEBUG_GC ) & & ! ( moo - > option . trait & MOO_NOGC ) ) moo_gc ( moo ) ;
2015-05-07 15:58:04 +00:00
# endif
2018-12-09 07:21:16 +00:00
if ( MOO_UNLIKELY ( moo - > igniting ) )
2015-04-30 15:56:05 +00:00
{
2018-12-09 17:14:56 +00:00
/* you must increase the size of the permspace if this allocation fails */
2018-12-09 07:21:16 +00:00
return ( moo_uint8_t * ) moo_allocheapspace ( moo , & moo - > heap - > permspace , size ) ;
}
else
{
moo_uint8_t * ptr ;
2018-11-30 13:37:15 +00:00
ptr = ( moo_uint8_t * ) moo_allocheapspace ( moo , & moo - > heap - > curspace , size ) ;
2018-12-09 07:21:16 +00:00
if ( ! ptr & & moo - > errnum = = MOO_EOOMEM & & ! ( moo - > option . trait & MOO_NOGC ) )
{
moo_gc ( moo ) ;
MOO_LOG4 ( moo , MOO_LOG_GC | MOO_LOG_INFO ,
" GC completed - current heap ptr %p limit %p size %zd free %zd \n " ,
moo - > heap - > curspace . ptr , moo - > heap - > curspace . limit ,
( moo_oow_t ) ( moo - > heap - > curspace . limit - moo - > heap - > curspace . base ) ,
( moo_oow_t ) ( moo - > heap - > curspace . limit - moo - > heap - > curspace . ptr )
) ;
ptr = ( moo_uint8_t * ) moo_allocheapspace ( moo , & moo - > heap - > curspace , size ) ;
/* TODO: grow heap if ptr is still null. */
}
return ptr ;
2015-04-30 15:56:05 +00:00
}
}
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 ( ) */
2018-02-26 15:30:38 +00:00
hdr = ( moo_oop_oop_t ) moo_allocbytes ( moo , MOO_SIZEOF ( moo_obj_t ) + nbytes_aligned ) ;
2017-01-09 09:54:49 +00:00
if ( ! hdr ) return MOO_NULL ;
2015-04-30 15:56:05 +00:00
2018-12-09 07:21:16 +00:00
hdr - > _flags = MOO_OBJ_MAKE_FLAGS ( MOO_OBJ_TYPE_OOP , MOO_SIZEOF ( moo_oop_t ) , 0 , 0 , moo - > igniting , 0 , 0 , 0 ) ;
2017-01-09 09:54:49 +00:00
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
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
2018-02-26 15:30:38 +00:00
hdr = ( moo_oop_oop_t ) moo_allocbytes ( moo , MOO_SIZEOF ( moo_obj_t ) + nbytes_aligned ) ;
2017-01-09 09:54:49 +00:00
if ( ! hdr ) return MOO_NULL ;
2015-07-01 15:01:39 +00:00
2018-12-09 07:21:16 +00:00
hdr - > _flags = MOO_OBJ_MAKE_FLAGS ( MOO_OBJ_TYPE_OOP , MOO_SIZEOF ( moo_oop_t ) , 0 , 0 , moo - > igniting , 0 , 0 , 1 ) ;
2017-01-09 09:54:49 +00:00
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
}
2018-02-07 10:54:26 +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 , int ngc )
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
2018-02-07 10:54:26 +00:00
if ( MOO_UNLIKELY ( ngc ) )
{
2018-02-26 15:30:38 +00:00
hdr = ( moo_oop_t ) moo_callocmem ( moo , MOO_SIZEOF ( moo_obj_t ) + nbytes_aligned ) ;
2018-02-07 10:54:26 +00:00
if ( ! hdr ) return MOO_NULL ;
}
else
{
/* making the number of bytes to allocate a multiple of
* MOO_SIZEOF ( moo_oop_t ) will guarantee the starting address
* of the allocated space to be an even number .
* see MOO_OOP_IS_NUMERIC ( ) and MOO_OOP_IS_POINTER ( ) */
2018-02-26 15:30:38 +00:00
hdr = ( moo_oop_t ) moo_allocbytes ( moo , MOO_SIZEOF ( moo_obj_t ) + nbytes_aligned ) ;
2018-02-07 10:54:26 +00:00
if ( ! hdr ) return MOO_NULL ;
}
2015-04-30 15:56:05 +00:00
2018-12-09 07:21:16 +00:00
hdr - > _flags = MOO_OBJ_MAKE_FLAGS ( type , unit , extra , 0 , moo - > igniting , 0 , ngc , 0 ) ; /* TODO: review. ngc and perm flags seems to conflict with each other ... the diff is that ngc is malloc() and perm is allocated in the perm heap */
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
{
2017-01-15 17:53:37 +00:00
/* initialize with zeros when the data pointer is NULL */
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-05-07 05:18:21 +00:00
MOO_INLINE 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
{
2018-02-26 15:30:38 +00:00
return alloc_numeric_array ( moo , ptr , len , MOO_OBJ_TYPE_CHAR , MOO_SIZEOF ( moo_ooch_t ) , 1 , 0 ) ;
2015-04-30 15:56:05 +00:00
}
2017-05-07 05:18:21 +00:00
MOO_INLINE 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
{
2018-02-26 15:30:38 +00:00
return alloc_numeric_array ( moo , ptr , len , MOO_OBJ_TYPE_BYTE , MOO_SIZEOF ( moo_oob_t ) , 0 , 0 ) ;
2015-07-01 15:01:39 +00:00
}
2017-05-07 05:18:21 +00:00
MOO_INLINE 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
{
2018-02-26 15:30:38 +00:00
return alloc_numeric_array ( moo , ptr , len , MOO_OBJ_TYPE_HALFWORD , MOO_SIZEOF ( moo_oohw_t ) , 0 , 0 ) ;
2015-04-30 15:56:05 +00:00
}
2017-05-07 05:18:21 +00:00
MOO_INLINE 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
{
2018-02-26 15:30:38 +00:00
return alloc_numeric_array ( moo , ptr , len , MOO_OBJ_TYPE_WORD , MOO_SIZEOF ( moo_oow_t ) , 0 , 0 ) ;
2015-04-30 15:56:05 +00:00
}
2018-01-07 14:59:54 +00:00
static MOO_INLINE int decode_spec ( moo_t * moo , moo_oop_class_t _class , moo_oow_t num_flexi_fields , 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 ;
2018-01-07 14:59:54 +00:00
moo_oow_t num_fixed_fields ;
2017-01-09 09:54:49 +00:00
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-02-15 11:57:24 +00:00
MOO_ASSERT ( moo , MOO_OOP_IS_SMOOI ( _class - > spec ) ) ;
spec = MOO_OOP_TO_SMOOI ( _class - > spec ) ;
2015-04-30 15:56:05 +00:00
2018-01-07 14:59:54 +00:00
num_fixed_fields = MOO_CLASS_SPEC_NAMED_INSTVARS ( spec ) ;
MOO_ASSERT ( moo , num_fixed_fields < = MOO_MAX_NAMED_INSTVARS ) ;
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
2018-01-07 14:59:54 +00:00
/* the number of the fixed fields for a non-pointer object are supported.
* the fixed fields of a pointer object holds named instance variables
* and a non - pointer object is facilitated with the fixed fields of the size
2018-01-06 04:18:10 +00:00
* specified in the class description like # byte ( 5 ) , # word ( 10 ) .
*
2018-01-07 14:59:54 +00:00
* when it comes to spec decoding , there is no difference between a pointer
2018-01-06 04:18:10 +00:00
* object and a non - pointer object */
2018-01-07 14:59:54 +00:00
if ( num_flexi_fields > MOO_MAX_INDEXED_INSTVARS ( num_fixed_fields ) )
2018-01-06 04:18:10 +00:00
{
2018-01-07 14:59:54 +00:00
moo_seterrbfmt ( moo , MOO_EINVAL , " number of flexi-fields(%zu) too big for a class %O " , num_flexi_fields , _class ) ;
2018-01-06 04:18:10 +00:00
return - 1 ;
}
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
2018-01-07 14:59:54 +00:00
if ( num_flexi_fields > 0 )
2016-11-18 18:11:13 +00:00
{
2018-05-13 16:28:22 +00:00
moo_seterrbfmt ( moo , MOO_EPERM , " flexi-fields(%zu) disallowed for a class %O " , num_flexi_fields , _class ) ;
2016-11-18 18:11:13 +00:00
return - 1 ;
}
2015-04-30 15:56:05 +00:00
}
2018-01-07 14:59:54 +00:00
MOO_ASSERT ( moo , num_fixed_fields + num_flexi_fields < = MOO_OBJ_SIZE_MAX ) ;
2015-12-27 18:02:59 +00:00
* type = indexed_type ;
2018-01-07 14:59:54 +00:00
* outlen = num_fixed_fields + num_flexi_fields ;
2015-12-27 18:02:59 +00:00
return 0 ;
}
2017-02-15 11:57:24 +00:00
moo_oop_t moo_instantiate ( moo_t * moo , moo_oop_class_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
2018-01-05 17:46:10 +00:00
if ( decode_spec ( moo , _class , vlen , & type , & alloclen ) < = - 1 ) return MOO_NULL ;
2015-12-27 18:02:59 +00:00
2017-02-15 11:57:24 +00:00
moo_pushtmp ( moo , ( moo_oop_t * ) & _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 . */
2018-02-26 15:30:38 +00:00
oop = moo_allocoopobj ( moo , alloclen ) ;
2017-04-19 16:46:44 +00:00
if ( oop )
{
/* initialize named instance variables with default values */
2017-04-24 14:32:21 +00:00
if ( _class - > initv [ 0 ] ! = moo - > _nil )
2017-04-19 16:46:44 +00:00
{
2017-04-24 14:32:21 +00:00
moo_oow_t i = MOO_OBJ_GET_SIZE ( _class - > initv [ 0 ] ) ;
2017-04-19 16:46:44 +00:00
2017-04-24 04:26:03 +00:00
/* [NOTE] i don't deep-copy initial values.
* if you change the contents of compound values like arrays ,
* it affects subsequent instantiation of the class .
* it ' s important that the compiler should mark compound initial
* values read - only . */
2017-04-19 16:46:44 +00:00
while ( i > 0 )
{
- - i ;
2017-04-24 14:32:21 +00:00
( ( moo_oop_oop_t ) oop ) - > slot [ i ] = ( ( moo_oop_oop_t ) _class - > initv [ 0 ] ) - > slot [ i ] ;
2017-04-19 16:46:44 +00:00
}
}
}
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 :
2018-02-26 15:30:38 +00:00
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 :
2018-02-26 15:30:38 +00:00
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 :
2018-02-26 15:30:38 +00:00
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 :
2018-02-26 15:30:38 +00:00
oop = moo_allocwordobj ( moo , vptr , alloclen ) ;
2015-04-30 15:56:05 +00:00
break ;
default :
2017-05-11 14:59:20 +00:00
moo_seterrnum ( moo , MOO_EINTERN ) ;
2017-01-09 09:54:49 +00:00
oop = MOO_NULL ;
2015-05-08 14:29:35 +00:00
break ;
2015-04-30 15:56:05 +00:00
}
2017-05-07 05:18:21 +00:00
if ( oop )
2015-07-01 15:01:39 +00:00
{
2017-05-07 05:18:21 +00:00
MOO_OBJ_SET_CLASS ( oop , ( moo_oop_t ) _class ) ;
if ( MOO_CLASS_SPEC_IS_IMMUTABLE ( MOO_OOP_TO_SMOOI ( _class - > spec ) ) ) MOO_OBJ_SET_FLAGS_RDONLY ( oop , 1 ) ;
2015-07-01 15:01:39 +00:00
}
2017-01-09 09:54:49 +00:00
moo_poptmps ( moo , tmp_count ) ;
2015-12-27 18:02:59 +00:00
return oop ;
}
2017-02-15 11:57:24 +00:00
moo_oop_t moo_instantiatewithtrailer ( moo_t * moo , moo_oop_class_t _class , moo_oow_t vlen , const moo_oob_t * trptr , moo_oow_t trlen )
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
2018-01-05 17:46:10 +00:00
if ( decode_spec ( moo , _class , vlen , & type , & alloclen ) < = - 1 ) return MOO_NULL ;
2015-07-01 15:01:39 +00:00
2017-02-15 11:57:24 +00:00
moo_pushtmp ( moo , ( moo_oop_t * ) & _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 :
2017-02-14 10:25:26 +00:00
oop = moo_allocoopobjwithtrailer ( moo , alloclen , trptr , trlen ) ;
2017-05-07 05:18:21 +00:00
if ( oop )
{
/* initialize named instance variables with default values */
if ( _class - > initv [ 0 ] ! = moo - > _nil )
{
moo_oow_t i = MOO_OBJ_GET_SIZE ( _class - > initv [ 0 ] ) ;
/* [NOTE] i don't deep-copy initial values.
* if you change the contents of compound values like arrays ,
* it affects subsequent instantiation of the class .
* it ' s important that the compiler should mark compound initial
* values read - only . */
while ( i > 0 )
{
- - i ;
( ( moo_oop_oop_t ) oop ) - > slot [ i ] = ( ( moo_oop_oop_t ) _class - > initv [ 0 ] ) - > slot [ i ] ;
}
}
}
2015-07-01 15:01:39 +00:00
break ;
default :
2017-02-14 08:29:30 +00:00
MOO_DEBUG3 ( moo , " Not allowed to instantiate a non-pointer object of the %.*js class with trailer %zu \n " ,
2017-02-15 11:57:24 +00:00
MOO_OBJ_GET_SIZE ( _class - > name ) ,
MOO_OBJ_GET_CHAR_SLOT ( _class - > name ) ,
2017-02-14 10:25:26 +00:00
trlen ) ;
2017-02-14 08:29:30 +00:00
2017-05-11 14:59:20 +00:00
moo_seterrnum ( moo , MOO_EPERM ) ;
2017-01-09 09:54:49 +00:00
oop = MOO_NULL ;
2015-07-01 15:01:39 +00:00
break ;
}
2017-05-07 05:18:21 +00:00
if ( oop )
{
MOO_OBJ_SET_CLASS ( oop , _class ) ;
if ( MOO_CLASS_SPEC_IS_IMMUTABLE ( MOO_OOP_TO_SMOOI ( _class - > spec ) ) ) MOO_OBJ_SET_FLAGS_RDONLY ( oop , 1 ) ;
}
2017-01-09 09:54:49 +00:00
moo_poptmps ( moo , tmp_count ) ;
2015-07-01 15:01:39 +00:00
return oop ;
}