From f105bc27714749feb62a63b51c98928dc3e73413 Mon Sep 17 00:00:00 2001 From: Ge Wang Date: Thu, 9 Nov 2023 00:43:25 -0800 Subject: [PATCH] refactor chugin api create array --- src/core/chuck_dl.cpp | 92 ++++++++++++++++++++++++++++++++++------ src/core/chuck_instr.cpp | 28 ------------ src/core/chuck_instr.h | 10 +++++ src/core/chuck_type.cpp | 22 ++++++---- 4 files changed, 104 insertions(+), 48 deletions(-) diff --git a/src/core/chuck_dl.cpp b/src/core/chuck_dl.cpp index 4ea7a017a..9ea512a5e 100644 --- a/src/core/chuck_dl.cpp +++ b/src/core/chuck_dl.cpp @@ -1498,6 +1498,57 @@ t_CKUINT CK_DLL_CALL ck_refcount( Chuck_DL_Api::Object object ) } + + +//----------------------------------------------------------------------------- +// helper function +//----------------------------------------------------------------------------- +Chuck_Object * do_ck_create( Chuck_VM_Shred * shred, Chuck_VM * vm, Chuck_DL_Api::Type t, vector & caps, t_CKBOOL addRef ) +{ + // type + Chuck_Type * type = (Chuck_Type *)t; + // object + Chuck_Object * object = NULL; + + // check if type is some kind of array + if( isa(type, vm->env()->ckt_array) ) + { + // 1.5.1.9 (nshaheed) added + t_CKINT index = 0; + bool is_object = isa(type->array_type, vm->env()->ckt_object); + // get array depth + t_CKUINT depth = type->array_depth; + // create capacity + t_CKINT * capacity = new t_CKINT[depth]; + // make sure + assert( depth == caps.size() ); + // iterate and copy + for( t_CKUINT i = 0; i < depth; i++ ) capacity[i] = caps[i]; + // allocate array + object = do_alloc_array( vm, shred, + &capacity[depth - 1], capacity, + getkindof(vm->env(), type->array_type), + is_object, NULL, index, type ); + // clean up + CK_SAFE_DELETE_ARRAY( capacity ); + } + else + { + // instantiate and initialize + if( shred ) object = instantiate_and_initialize_object( type, shred, vm ); + else object = instantiate_and_initialize_object( type, vm ); + } + + // if requested to add ref + if( object && addRef ) CK_SAFE_ADD_REF(object); + + // done + return object; +} + + + + //----------------------------------------------------------------------------- // name: ck_create_with_shred() // desc: host-side hook implementation for instantiating and initializing @@ -1520,15 +1571,24 @@ static Chuck_DL_Api::Object CK_DLL_CALL ck_create_with_shred( Chuck_VM_Shred * s // type Chuck_Type * type = (Chuck_Type *)t; - // instantiate and initialize - Chuck_Object * o = instantiate_and_initialize_object( type, shred, shred->vm_ref ); - // if requested to add ref - if( o && addRef ) CK_SAFE_ADD_REF(o); - // done - return (Chuck_DL_Api::Object)o; + // do_alloc_array() expects a stack of intial capacities for + // each dimension of the array. Because this is only expected + // to be used through the chuck_dl API, which does not support + // setting the capacity explicitly, only empty arrays are + // initialized | 1.5.1.9 + vector caps; + // check for array type + if( type->array_depth ) + for( t_CKUINT i = 0; i < type->array_depth; i++ ) + caps.push_back(0); + + // process and return + return (Chuck_DL_Api::Object)do_ck_create( shred, shred->vm_ref, t, caps, addRef ); } + + //----------------------------------------------------------------------------- // name: ck_create_without_shred() // desc: host-side hook implementation for instantiating and initializing @@ -1548,16 +1608,24 @@ static Chuck_DL_Api::Object CK_DLL_CALL ck_create_without_shred( Chuck_VM * vm, // type Chuck_Type * type = (Chuck_Type *)t; - // instantiate and initialize - Chuck_Object * o = instantiate_and_initialize_object( type, vm ); - // if requested to add ref - if( o && addRef ) CK_SAFE_ADD_REF(o); - // done - return (Chuck_DL_Api::Object)o; + // do_alloc_array() expects a stack of intial capacities for + // each dimension of the array. Because this is only expected + // to be used through the chuck_dl API, which does not support + // setting the capacity explicitly, only empty arrays are + // initialized | 1.5.1.9 + vector caps; + // check for array type + if( type->array_depth ) + for( t_CKUINT i = 0; i < type->array_depth; i++ ) + caps.push_back(0); + + // process and return + return (Chuck_DL_Api::Object)do_ck_create( NULL, vm, t, caps, addRef ); } + //----------------------------------------------------------------------------- // name: ck_create_string() // desc: host-side hook implementation for creating a chuck string diff --git a/src/core/chuck_instr.cpp b/src/core/chuck_instr.cpp index 9cb23f50e..05e904f07 100644 --- a/src/core/chuck_instr.cpp +++ b/src/core/chuck_instr.cpp @@ -48,12 +48,6 @@ using namespace std; -// do alloc array -Chuck_Object * do_alloc_array( Chuck_VM * vm, Chuck_VM_Shred * shred, t_CKINT * capacity, - const t_CKINT * top, t_CKUINT kind, t_CKBOOL is_obj, - t_CKUINT * objs, t_CKINT & index, Chuck_Type * type); - - //----------------------------------------------------------------------------- @@ -4401,28 +4395,6 @@ Chuck_Object * instantiate_and_initialize_object( Chuck_Type * type, Chuck_VM_Sh // initialize shred | 1.5.1.5 (ge) added, along with child mem and reg stack size hints if( !newShred->initialize( NULL, mems, regs ) ) goto error; } - else if (isa(type, vm->env()->ckt_array)) - { - // 1.5.1.9 (nshaheed) added - t_CKINT index = 0; - bool is_object = isa(type->array_type, vm->env()->ckt_object); - - int depth = type->array_depth; - t_CKINT* capacity = new t_CKINT[depth](); - - // do_alloc_array expects a stack of intial capacities for - // each dimension of the array. Because this is only expected - // to be used through the chuck_dl API, which does not support - // setting the capacity explicitly, only empty arrays are - // initialized. - for (int i = 0; i < depth; i++) { - capacity[i] = 0; - } - object = do_alloc_array(vm, shred, - &capacity[depth - 1], capacity, - getkindof(vm->env(), type->array_type), - is_object, nullptr, index, type); - } // 1.5.0.0 (ge) added -- here my feeble brain starts leaking out of my eyeballs else if( isa( type, vm->env()->ckt_class ) ) object = new Chuck_Type( vm->env(), te_class, type->base_name, type, type->size ); // TODO: is this ok? diff --git a/src/core/chuck_instr.h b/src/core/chuck_instr.h index c220f9d03..77556cb63 100644 --- a/src/core/chuck_instr.h +++ b/src/core/chuck_instr.h @@ -3563,6 +3563,16 @@ struct Chuck_Instr_Array_Alloc : public Chuck_Instr +//----------------------------------------------------------------------------- +// do alloc array +//----------------------------------------------------------------------------- +Chuck_Object * do_alloc_array( Chuck_VM * vm, Chuck_VM_Shred * shred, t_CKINT * capacity, + const t_CKINT * top, t_CKUINT kind, t_CKBOOL is_obj, + t_CKUINT * objs, t_CKINT & index, Chuck_Type * type); + + + + //----------------------------------------------------------------------------- // name: struct Chuck_Instr_Array_Access // desc: ... diff --git a/src/core/chuck_type.cpp b/src/core/chuck_type.cpp index d544f4438..51651a498 100644 --- a/src/core/chuck_type.cpp +++ b/src/core/chuck_type.cpp @@ -5310,10 +5310,10 @@ Chuck_Type * Chuck_Namespace::lookup_type( S_Symbol theName, t_CKINT climb, // remove arrays from name int depth = 0; S_Symbol oldName = theName; - std::string theNameStr = S_name(theName); - while (theNameStr.size() >= 2 && theNameStr.substr(theNameStr.size() - 2, 2) == "[]") + // parse for [] | 1.5.1.9 + while( theNameStr.size() >= 2 && theNameStr.substr(theNameStr.size() - 2, 2) == "[]" ) { depth++; // remove "[]" from the name @@ -5321,13 +5321,14 @@ Chuck_Type * Chuck_Namespace::lookup_type( S_Symbol theName, t_CKINT climb, theNameStr.pop_back(); } - // If this is an array, create an S_Symbol with only the base type. - // (i.e. "int[]" becomes "int". - if (depth) + // if this is an array, create an S_Symbol with only the base type + // (i.e. "int[]" becomes "int" | 1.5.1.9 + if( depth ) { theName = insert_symbol(theNameStr.c_str()); } + // find base type Chuck_Type * t = type.lookup( theName, climb ); // respect stayWithinClassDef; check if we are in class def using pre_ctor t_CKBOOL keepGoing = ( this->pre_ctor && stayWithinClassDef ) == FALSE; @@ -5335,11 +5336,16 @@ Chuck_Type * Chuck_Namespace::lookup_type( S_Symbol theName, t_CKINT climb, if( climb > 0 && !t && parent && keepGoing ) return parent->lookup_type( oldName, climb, stayWithinClassDef ); - // If this is an array, create an array type and return that. - if (depth) { - Chuck_Type* baseT = t; + // if this is an array, create an array type and return that | 1.5.1.9 + if( depth ) + { + // base type + Chuck_Type * baseT = t; + // new array type t = new_array_type(baseT->env(), baseT->env()->ckt_array, depth, baseT, baseT->env()->curr); } + + // return t return t; }