Skip to content

Commit

Permalink
Merge pull request #407 from nshaheed/type-array
Browse files Browse the repository at this point in the history
Adding array support in Type (partially working)
  • Loading branch information
gewang authored Nov 9, 2023
2 parents b2143eb + c3b5b21 commit 82b2d4b
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 165 deletions.
2 changes: 1 addition & 1 deletion src/core/chuck_absyn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,10 +584,10 @@ a_Exp new_exp_from_array_lit( a_Array_Sub exp_list, uint32_t lineNum, uint32_t p
a->s_meta = ae_meta_value;
a->primary.s_type = ae_primary_array;
a->primary.array = exp_list;
a->primary.array->self = a; // 1.5.1.9 (ge & nshaheed) added
a->line = lineNum; a->where = posNum;
a->primary.line = lineNum; a->primary.where = posNum;
a->primary.self = a;

return a;
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/chuck_emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2568,7 +2568,7 @@ t_CKBOOL emit_engine_emit_op( Chuck_Emitter * emit, ae_Operator op, a_Exp lhs, a
{
// check size (1.3.1.0: changed to getkindof)
t_CKUINT kind = getkindof( emit->env, t_left->array_type );
// but if array depth > 1, we are actulaly dealing with pointers, hence back to INT
// but if array depth > 1, we are actually dealing with pointers, hence back to INT
if( t_left->array_depth > 1 ) kind = kindof_INT;
emit->append( instr = new Chuck_Instr_Array_Append( kind ) );
instr->set_linepos( lhs->line );
Expand Down
348 changes: 187 additions & 161 deletions src/core/chuck_instr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4351,6 +4351,171 @@ Chuck_Object * instantiate_and_initialize_object( Chuck_Type * type, Chuck_VM *



//-----------------------------------------------------------------------------
// name: do_alloc_array()
// desc: 1.3.1.0 -- changed size to kind
//-----------------------------------------------------------------------------
Chuck_Object* do_alloc_array(Chuck_VM* vm, // REFACTOR-2017: added
Chuck_VM_Shred* shred, // 1.5.1.5 added
t_CKINT* capacity, const t_CKINT* top,
t_CKUINT kind, t_CKBOOL is_obj,
t_CKUINT* objs, t_CKINT& index,
Chuck_Type* type)
{
// not top level
Chuck_ArrayInt* theBase = NULL;
Chuck_Object* next = NULL;
Chuck_Type* typeNext = NULL;
t_CKINT i = 0;

// capacity
if (*capacity < 0) goto negative_array_size;

// see if top level
if (capacity >= top)
{
// check size
// 1.3.1.0: look at type to use kind instead of size
if (kind == kindof_INT) // ISSUE: 64-bit (fixed 1.3.1.0)
{
Chuck_ArrayInt* baseX = new Chuck_ArrayInt(is_obj, *capacity);
if (!baseX) goto out_of_memory;

// if object
if (is_obj && objs)
{
// loop
for (i = 0; i < *capacity; i++)
{
// add to array for later allocation
objs[index++] = baseX->addr(i);
}
}

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object(baseX, type, shred, vm);
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}
else if (kind == kindof_FLOAT) // ISSUE: 64-bit (fixed 1.3.1.0)
{
Chuck_ArrayFloat* baseX = new Chuck_ArrayFloat(*capacity);
if (!baseX) goto out_of_memory;

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object(baseX, type, shred, vm);
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}
else if (kind == kindof_VEC2) // ISSUE: 64-bit (fixed 1.3.1.0) | 1.5.1.7 (ge) complex -> vec2
{
Chuck_Array16* baseX = new Chuck_Array16(*capacity);
if (!baseX) goto out_of_memory;

// check array type
Chuck_Type* array_type = type->array_type;
// differentiate between complex and polar | 1.5.1.0 (ge) added, used for sorting Array16s
if (array_type && isa(array_type, vm->env()->ckt_polar)) baseX->m_isPolarType = TRUE;

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object(baseX, type, shred, vm);
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}
else if (kind == kindof_VEC3) // 1.3.5.3
{
Chuck_Array24* baseX = new Chuck_Array24(*capacity);
if (!baseX) goto out_of_memory;

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object(baseX, type, shred, vm);
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}
else if (kind == kindof_VEC4) // 1.3.5.3
{
Chuck_Array32* baseX = new Chuck_Array32(*capacity);
if (!baseX) goto out_of_memory;

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object(baseX, type, shred, vm);
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}

// shouldn't get here
assert(FALSE);
}

// not top level
theBase = new Chuck_ArrayInt(TRUE, *capacity);
if (!theBase) goto out_of_memory;

// construct type for next array level | 1.5.0.0 (ge) added
// TODO: look up in common array type pool before allocating
// pass in NULL (context) as typeNext is meant to be temporary and
// shouldn't be associated with context; also by this point,
// vm->env()->context is likely the global context, and the
// originating context (e.g., ck file) is already cleaned up | 1.5.1.1
typeNext = type->copy(vm->env(), NULL);
// check
if (typeNext->array_depth == 0) goto internal_error_array_depth;
// minus the depth
typeNext->array_depth--;
// add ref | 1.5.1.1
CK_SAFE_ADD_REF(typeNext);

// allocate the next level
for (i = 0; i < *capacity; i++)
{
// the next | REFACTOR-2017: added vm
next = do_alloc_array(vm, shred, capacity + 1, top, kind, is_obj, objs, index, typeNext);
// error if NULL
if (!next) goto error;
// set that, with ref count
theBase->set(i, (t_CKUINT)next);
}

// release | 1.5.1.1
CK_SAFE_RELEASE(typeNext);

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object(theBase, type, shred, vm);
// initialize_object( theBase, vm->env()->ckt_array );
return theBase;

internal_error_array_depth:
// we have a big problem
EM_exception(
"(internal error) multi-dimensional array depth mismatch while allocating arrays...");
goto error;

out_of_memory:
// we have a problem
EM_exception(
"OutOfMemory: while allocating arrays...");
goto error;

negative_array_size:
// we have a problem
EM_exception(
"NegativeArraySize: while allocating arrays...");
goto error;

error:
// base shouldn't have been ref counted
CK_SAFE_DELETE(theBase);
return NULL;
}




//-----------------------------------------------------------------------------
// name: instantiate_and_initialize_object()
Expand Down Expand Up @@ -4395,6 +4560,28 @@ 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?
Expand Down Expand Up @@ -6318,168 +6505,7 @@ Chuck_Instr_Array_Alloc::~Chuck_Instr_Array_Alloc()



//-----------------------------------------------------------------------------
// name: do_alloc_array()
// desc: 1.3.1.0 -- changed size to kind
//-----------------------------------------------------------------------------
Chuck_Object * do_alloc_array( Chuck_VM * vm, // REFACTOR-2017: added
Chuck_VM_Shred * shred, // 1.5.1.5 added
t_CKINT * capacity, const t_CKINT * top,
t_CKUINT kind, t_CKBOOL is_obj,
t_CKUINT * objs, t_CKINT & index,
Chuck_Type * type )
{
// not top level
Chuck_ArrayInt * theBase = NULL;
Chuck_Object * next = NULL;
Chuck_Type * typeNext = NULL;
t_CKINT i = 0;

// capacity
if( *capacity < 0 ) goto negative_array_size;

// see if top level
if( capacity >= top )
{
// check size
// 1.3.1.0: look at type to use kind instead of size
if( kind == kindof_INT ) // ISSUE: 64-bit (fixed 1.3.1.0)
{
Chuck_ArrayInt * baseX = new Chuck_ArrayInt( is_obj, *capacity );
if( !baseX ) goto out_of_memory;

// if object
if( is_obj && objs )
{
// loop
for( i = 0; i < *capacity; i++ )
{
// add to array for later allocation
objs[index++] = baseX->addr( i );
}
}

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object( baseX, type, shred, vm );
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}
else if( kind == kindof_FLOAT ) // ISSUE: 64-bit (fixed 1.3.1.0)
{
Chuck_ArrayFloat * baseX = new Chuck_ArrayFloat( *capacity );
if( !baseX ) goto out_of_memory;

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object( baseX, type, shred, vm );
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}
else if( kind == kindof_VEC2 ) // ISSUE: 64-bit (fixed 1.3.1.0) | 1.5.1.7 (ge) complex -> vec2
{
Chuck_Array16 * baseX = new Chuck_Array16( *capacity );
if( !baseX ) goto out_of_memory;

// check array type
Chuck_Type * array_type = type->array_type;
// differentiate between complex and polar | 1.5.1.0 (ge) added, used for sorting Array16s
if( array_type && isa(array_type, vm->env()->ckt_polar) ) baseX->m_isPolarType = TRUE;

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object( baseX, type, shred, vm );
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}
else if( kind == kindof_VEC3 ) // 1.3.5.3
{
Chuck_Array24 * baseX = new Chuck_Array24( *capacity );
if( !baseX ) goto out_of_memory;

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object( baseX, type, shred, vm );
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}
else if( kind == kindof_VEC4 ) // 1.3.5.3
{
Chuck_Array32 * baseX = new Chuck_Array32( *capacity );
if( !baseX ) goto out_of_memory;

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object( baseX, type, shred, vm );
// initialize_object( baseX, vm->env()->ckt_array );
return baseX;
}

// shouldn't get here
assert( FALSE );
}

// not top level
theBase = new Chuck_ArrayInt( TRUE, *capacity );
if( !theBase) goto out_of_memory;

// construct type for next array level | 1.5.0.0 (ge) added
// TODO: look up in common array type pool before allocating
// pass in NULL (context) as typeNext is meant to be temporary and
// shouldn't be associated with context; also by this point,
// vm->env()->context is likely the global context, and the
// originating context (e.g., ck file) is already cleaned up | 1.5.1.1
typeNext = type->copy( vm->env(), NULL );
// check
if( typeNext->array_depth == 0 ) goto internal_error_array_depth;
// minus the depth
typeNext->array_depth--;
// add ref | 1.5.1.1
CK_SAFE_ADD_REF( typeNext );

// allocate the next level
for( i = 0; i < *capacity; i++ )
{
// the next | REFACTOR-2017: added vm
next = do_alloc_array( vm, shred, capacity+1, top, kind, is_obj, objs, index, typeNext );
// error if NULL
if( !next ) goto error;
// set that, with ref count
theBase->set( i, (t_CKUINT)next );
}

// release | 1.5.1.1
CK_SAFE_RELEASE( typeNext );

// initialize object | 1.5.0.0 (ge) use array type instead of base t_array
// for the object->type_ref to contain more specific information
initialize_object( theBase, type, shred, vm );
// initialize_object( theBase, vm->env()->ckt_array );
return theBase;

internal_error_array_depth:
// we have a big problem
EM_exception(
"(internal error) multi-dimensional array depth mismatch while allocating arrays..." );
goto error;

out_of_memory:
// we have a problem
EM_exception(
"OutOfMemory: while allocating arrays..." );
goto error;

negative_array_size:
// we have a problem
EM_exception(
"NegativeArraySize: while allocating arrays..." );
goto error;

error:
// base shouldn't have been ref counted
CK_SAFE_DELETE( theBase );
return NULL;
}



Expand Down
Loading

0 comments on commit 82b2d4b

Please sign in to comment.