/*---------------------------------------------------------------------------- ChucK Concurrent, On-the-fly Audio Programming Language Compiler and Virtual Machine Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved. http://chuck.stanford.edu/ http://chuck.cs.princeton.edu/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U.S.A.-----------------------------------------------------------------------------*/ //-----------------------------------------------------------------------------// file: chuck_oo.cpp// desc: chuck baes objects//// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)// Ananya Misra (amisra@cs.princeton.edu)// Andrew Schran (aschran@princeton.edu) - fileIO implementation// date: Autumn 2004//-----------------------------------------------------------------------------#include "chuck_oo.h"#include "chuck_type.h"#include "chuck_vm.h"#include "chuck_instr.h"#include "chuck_errmsg.h"#include "chuck_dl.h"#include "util_math.h" #include <algorithm>#include <iostream>#include <sstream>#include <iomanip>#include <typeinfo>using namespace std; #if defined(__PLATFORM_WIN32__) #include "dirent_win32.h"#endif // initializet_CKBOOL Chuck_VM_Object::our_locks_in_effect = TRUE; // constantsconst t_CKINT Chuck_IO::TYPE_ASCII = 0x1;const t_CKINT Chuck_IO::TYPE_BINARY = 0x2;const t_CKINT Chuck_IO::FLOAT32 = 0x10;const t_CKINT Chuck_IO::FLOAT64 = 0x20;const t_CKINT Chuck_IO::INT8 = 0x100;const t_CKINT Chuck_IO::INT16 = 0x200;const t_CKINT Chuck_IO::INT24 = 0x400;const t_CKINT Chuck_IO::INT32 = 0x800;const t_CKINT Chuck_IO::INT64 = 0x1000;const t_CKINT Chuck_IO::SINT8 = 0x2000;const t_CKINT Chuck_IO::SINT16 = 0x4000;const t_CKINT Chuck_IO::SINT24 = 0x8000;const t_CKINT Chuck_IO::SINT32 = 0x10000;const t_CKINT Chuck_IO::SINT64 = 0x20000;const t_CKINT Chuck_IO::UINT8 = 0x40000;const t_CKINT Chuck_IO::UINT16 = 0x80000;const t_CKINT Chuck_IO::UINT24 = 0x100000;const t_CKINT Chuck_IO::UINT32 = 0x200000;const t_CKINT Chuck_IO::UINT64 = 0x400000;const t_CKINT Chuck_IO::FLAG_READONLY = 0x100;const t_CKINT Chuck_IO::FLAG_WRITEONLY = 0x200;const t_CKINT Chuck_IO::FLAG_READ_WRITE = 0x400;const t_CKINT Chuck_IO::FLAG_APPEND = 0x800; #ifndef __DISABLE_THREADS__const t_CKINT Chuck_IO::MODE_SYNC = 0;const t_CKINT Chuck_IO::MODE_ASYNC = 1;#elseconst t_CKINT Chuck_IO::MODE_SYNC = 1;const t_CKINT Chuck_IO::MODE_ASYNC = 0;#endif //-----------------------------------------------------------------------------// name: Chuck_VM_Object()// desc: constructor//-----------------------------------------------------------------------------Chuck_VM_Object::Chuck_VM_Object(){ this->init_ref(); } //-----------------------------------------------------------------------------// name: ~Chuck_VM_Object()// desc: destructor//-----------------------------------------------------------------------------Chuck_VM_Object::~Chuck_VM_Object(){ } //-----------------------------------------------------------------------------// name: init_ref()// desc: initialize vm object//-----------------------------------------------------------------------------void Chuck_VM_Object::init_ref(){ // set reference count m_ref_count = 0; // set flag m_pooled = FALSE; // set to not locked m_locked = FALSE; // set v ref m_v_ref = NULL; // add to vm allocator // Chuck_VM_Alloc::instance()->add_object( this );} //-----------------------------------------------------------------------------// name: add_ref()// desc: add reference//-----------------------------------------------------------------------------void Chuck_VM_Object::add_ref(){ // increment reference count m_ref_count++; // // if going from 0 to 1// if( m_ref_count == 1 )// {// // add to vm allocator// Chuck_VM_Alloc::instance()->add_object( this );// } // added 1.3.0.0 CK_MEMMGMT_TRACK(CK_FPRINTF_STDERR( "Chuck_VM_Object::add_ref() : 0x%08x, %s, %lu\n", this, typeid(*this).name(), m_ref_count)); // string n = typeid(*this).name(); // cerr << "ADDREF: " << dec << n << " " << m_ref_count << " 0x" << hex << (int)this << endl;} //-----------------------------------------------------------------------------// name: release()// desc: remove reference//-----------------------------------------------------------------------------void Chuck_VM_Object::release(){ // check if( m_ref_count <= 0 ) { // print error EM_error3( "[chuck]: internal error: Object.release() refcount == %d", m_ref_count ); // make sure there is at least one reference assert( m_ref_count > 0 ); } // decrement m_ref_count--; // added 1.3.0.0 CK_MEMMGMT_TRACK(CK_FPRINTF_STDERR( "Chuck_VM_Object::release() : 0x%08x, %s, %ulu\n", this, typeid(*this).name(), m_ref_count)); // string n = typeid(*this).name(); // cerr << "RELEASE: " << dec << n << " " << m_ref_count << " 0x" << hex << (int)this << endl; // if no more references if( m_ref_count == 0 ) { // this is not good | TODO: our_locks_in_effect assumes single VM if( our_locks_in_effect && m_locked ) { EM_error2( 0, "internal error: releasing locked VM object!" ); // fail assert( FALSE ); // in case assert is disabled *(int *)0 = 1; } #ifndef __CHUNREAL_ENGINE__ // log | 1.5.0.0 (ge) added EM_log( CK_LOG_FINEST, "reclaiming %s: 0x%08x", typeid(*this).name(), this ); #else // #chunreal UE seems to disallow real-time type info EM_log( CK_LOG_FINEST, "reclaiming object: 0x%08x", this ); #endif // #ifndef __CHUNREAL_ENGINE__ // tell the object manager to set this free // Chuck_VM_Alloc::instance()->free_object( this ); // REFACTOR-2017: doing this for now delete this; }} //-----------------------------------------------------------------------------// name: lock()// desc: lock to keep from deleted//-----------------------------------------------------------------------------void Chuck_VM_Object::lock(){ m_locked = TRUE;} //-----------------------------------------------------------------------------// name: unlock()// desc: unlock to allow deleting//-----------------------------------------------------------------------------void Chuck_VM_Object::unlock(){ m_locked = FALSE;} //-----------------------------------------------------------------------------// name: lock_all()// desc: disallow deletion of locked objects//-----------------------------------------------------------------------------void Chuck_VM_Object::lock_all(){ // log EM_log( CK_LOG_SYSTEM, "locking down special objects..." ); // set flag our_locks_in_effect = TRUE;} //-----------------------------------------------------------------------------// name: unlock_all()// desc: allow deletion of locked objects (USE WITH CAUTION!)//-----------------------------------------------------------------------------void Chuck_VM_Object::unlock_all(){ // log EM_log( CK_LOG_SYSTEM, "unprotecting special objects..." ); // set flag our_locks_in_effect = FALSE;} // static member// Chuck_VM_Alloc * Chuck_VM_Alloc::our_instance = NULL; //-----------------------------------------------------------------------------// name: instance()// desc: return static instance//-----------------------------------------------------------------------------//Chuck_VM_Alloc * Chuck_VM_Alloc::instance()//{// if( !our_instance )// {// our_instance = new Chuck_VM_Alloc;// assert( our_instance != NULL );// }//// return our_instance;//} //-----------------------------------------------------------------------------// name: add_object()// desc: add newly allocated vm object//-----------------------------------------------------------------------------//void Chuck_VM_Alloc::add_object( Chuck_VM_Object * obj )//{// // do log// if( DO_LOG( CK_LOG_ALL ) )// {// // log it// EM_log( CK_LOG_ALL, "adding '%s' (0x%lx)...",// mini_type( typeid(*obj).name() ), obj );// }//// // add it to map//} //-----------------------------------------------------------------------------// name: free_object()// desc: free vm object - reference count should be 0//-----------------------------------------------------------------------------//void Chuck_VM_Alloc::free_object( Chuck_VM_Object * obj )//{// // make sure the ref count is 0// assert( obj && obj->m_ref_count == 0 );//// // do log// if( DO_LOG( CK_LOG_FINEST ) )// {// // log it// EM_log( CK_LOG_FINEST, "freeing '%s' (0x%lx)...",// mini_type( typeid(*obj).name() ), obj );// }//// // remove it from map//// // delete it// delete obj;//} //-----------------------------------------------------------------------------// name: Chuck_VM_Alloc()// desc: constructor////-----------------------------------------------------------------------------//Chuck_VM_Alloc::Chuck_VM_Alloc()//{ } //-----------------------------------------------------------------------------// name: ~Chuck_VM_Alloc()// desc: destructor//-----------------------------------------------------------------------------//Chuck_VM_Alloc::~Chuck_VM_Alloc()//{ } //-----------------------------------------------------------------------------// name: Chuck_Object()// desc: constructor//-----------------------------------------------------------------------------Chuck_Object::Chuck_Object(){ // zero virtual table vtable = NULL; // zero type type_ref = NULL; // zero data data = NULL; // zero size data_size = 0; // add to vm allocator // Chuck_VM_Alloc::instance()->add_object( this );} //-----------------------------------------------------------------------------// name: Chuck_Object()// desc: ...//-----------------------------------------------------------------------------Chuck_Object::~Chuck_Object(){ // added 1.3.0.0: // call destructors, from latest descended child to oldest parent Chuck_Type * type = this->type_ref; while( type != NULL ) { // SPENCER TODO: HACK! is there a better way to call the dtor? if( type->info && type->has_destructor ) // 1.5.0.0 (ge) added type->info check { // sanity check assert( type->info->dtor && type->info->dtor->native_func ); // REFACTOR-2017: do we know which VM to pass in? (currently NULL) ((f_dtor)(type->info->dtor->native_func))( this, NULL, NULL, Chuck_DL_Api::Api::instance() ); } // go up the inheritance type = type->parent; } // free SAFE_DELETE( vtable ); SAFE_RELEASE( type_ref ); SAFE_DELETE_ARRAY( data ); // if( vtable ) { delete vtable; vtable = NULL; } // if( type_ref ) { type_ref->release(); type_ref = NULL; } // if( data ) { delete [] data; size = 0; data = NULL; }} //-----------------------------------------------------------------------------// name: dump()// desc: output current state (can be overridden)//-----------------------------------------------------------------------------void Chuck_Object::dump() // 1.4.1.1 (ge){ // need type info Chuck_Type * type = this->type_ref; // output state with type info type->dump( this );} //-----------------------------------------------------------------------------// name: help()// desc: output type info (can be overriden; but probably shouldn't be)//-----------------------------------------------------------------------------void Chuck_Object::help() // 1.4.1.0 (ge){ // type to unpack Chuck_Type * type = this->type_ref; // unpack type and output its info type->apropos();} //-----------------------------------------------------------------------------// name: ~Chuck_Array()// desc: destructor//-----------------------------------------------------------------------------Chuck_Array::~Chuck_Array(){ // decrement reference count; added (ge): 1.4.1.0 SAFE_RELEASE( m_array_type );} //-----------------------------------------------------------------------------// name: Chuck_Array4()// desc: constructor//-----------------------------------------------------------------------------Chuck_Array4::Chuck_Array4( t_CKBOOL is_obj, t_CKINT capacity ){ // sanity check assert( capacity >= 0 ); // set size m_vector.resize( capacity ); // clear (as non-object, so no releases) m_is_obj = FALSE; this->zero( 0, m_vector.capacity() ); // is object (set after clear) m_is_obj = is_obj;} //-----------------------------------------------------------------------------// name: ~Chuck_Array4()// desc: destructor//-----------------------------------------------------------------------------Chuck_Array4::~Chuck_Array4(){ // 1.4.2.0 (ge) | added, which should cascade to nested array objects clear();} //-----------------------------------------------------------------------------// name: addr()// desc: ...//-----------------------------------------------------------------------------t_CKUINT Chuck_Array4::addr( t_CKINT i ){ // bound check if( i < 0 || i >= m_vector.capacity() ) return 0; // get the addrLines 1–500 of 4315. Load more
/*---------------------------------------------------------------------------- ChucK Concurrent, On-the-fly Audio Programming Language Compiler and Virtual Machine Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved. http://chuck.stanford.edu/ http://chuck.cs.princeton.edu/ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 U.S.A. -----------------------------------------------------------------------------*/ //----------------------------------------------------------------------------- // file: chuck_oo.cpp // desc: chuck baes objects // // author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu) // Ananya Misra (amisra@cs.princeton.edu) // Andrew Schran (aschran@princeton.edu) - fileIO implementation // date: Autumn 2004 //----------------------------------------------------------------------------- #include "chuck_oo.h" #include "chuck_type.h" #include "chuck_vm.h" #include "chuck_instr.h" #include "chuck_errmsg.h" #include "chuck_dl.h" #include "util_math.h" #include <algorithm> #include <iostream> #include <sstream> #include <iomanip> #include <typeinfo> using namespace std; #if defined(__PLATFORM_WIN32__) #include "dirent_win32.h" #endif // initialize t_CKBOOL Chuck_VM_Object::our_locks_in_effect = TRUE; // constants const t_CKINT Chuck_IO::TYPE_ASCII = 0x1; const t_CKINT Chuck_IO::TYPE_BINARY = 0x2; const t_CKINT Chuck_IO::FLOAT32 = 0x10; const t_CKINT Chuck_IO::FLOAT64 = 0x20; const t_CKINT Chuck_IO::INT8 = 0x100; const t_CKINT Chuck_IO::INT16 = 0x200; const t_CKINT Chuck_IO::INT24 = 0x400; const t_CKINT Chuck_IO::INT32 = 0x800; const t_CKINT Chuck_IO::INT64 = 0x1000; const t_CKINT Chuck_IO::SINT8 = 0x2000; const t_CKINT Chuck_IO::SINT16 = 0x4000; const t_CKINT Chuck_IO::SINT24 = 0x8000; const t_CKINT Chuck_IO::SINT32 = 0x10000; const t_CKINT Chuck_IO::SINT64 = 0x20000; const t_CKINT Chuck_IO::UINT8 = 0x40000; const t_CKINT Chuck_IO::UINT16 = 0x80000; const t_CKINT Chuck_IO::UINT24 = 0x100000; const t_CKINT Chuck_IO::UINT32 = 0x200000; const t_CKINT Chuck_IO::UINT64 = 0x400000; const t_CKINT Chuck_IO::FLAG_READONLY = 0x100; const t_CKINT Chuck_IO::FLAG_WRITEONLY = 0x200; const t_CKINT Chuck_IO::FLAG_READ_WRITE = 0x400; const t_CKINT Chuck_IO::FLAG_APPEND = 0x800; #ifndef __DISABLE_THREADS__ const t_CKINT Chuck_IO::MODE_SYNC = 0; const t_CKINT Chuck_IO::MODE_ASYNC = 1; #else const t_CKINT Chuck_IO::MODE_SYNC = 1; const t_CKINT Chuck_IO::MODE_ASYNC = 0; #endif //----------------------------------------------------------------------------- // name: Chuck_VM_Object() // desc: constructor //----------------------------------------------------------------------------- Chuck_VM_Object::Chuck_VM_Object() { this->init_ref(); } //----------------------------------------------------------------------------- // name: ~Chuck_VM_Object() // desc: destructor //----------------------------------------------------------------------------- Chuck_VM_Object::~Chuck_VM_Object() { } //----------------------------------------------------------------------------- // name: init_ref() // desc: initialize vm object //----------------------------------------------------------------------------- void Chuck_VM_Object::init_ref() { // set reference count m_ref_count = 0; // set flag m_pooled = FALSE; // set to not locked m_locked = FALSE; // set v ref m_v_ref = NULL; // add to vm allocator // Chuck_VM_Alloc::instance()->add_object( this ); } //----------------------------------------------------------------------------- // name: add_ref() // desc: add reference //----------------------------------------------------------------------------- void Chuck_VM_Object::add_ref() { // increment reference count m_ref_count++; // // if going from 0 to 1 // if( m_ref_count == 1 ) // { // // add to vm allocator // Chuck_VM_Alloc::instance()->add_object( this ); // } // added 1.3.0.0 CK_MEMMGMT_TRACK(CK_FPRINTF_STDERR( "Chuck_VM_Object::add_ref() : 0x%08x, %s, %lu\n", this, typeid(*this).name(), m_ref_count)); // string n = typeid(*this).name(); // cerr << "ADDREF: " << dec << n << " " << m_ref_count << " 0x" << hex << (int)this << endl; } //----------------------------------------------------------------------------- // name: release() // desc: remove reference //----------------------------------------------------------------------------- void Chuck_VM_Object::release() { // check if( m_ref_count <= 0 ) { // print error EM_error3( "[chuck]: internal error: Object.release() refcount == %d", m_ref_count ); // make sure there is at least one reference assert( m_ref_count > 0 ); } // decrement m_ref_count--; // added 1.3.0.0 CK_MEMMGMT_TRACK(CK_FPRINTF_STDERR( "Chuck_VM_Object::release() : 0x%08x, %s, %ulu\n", this, typeid(*this).name(), m_ref_count)); // string n = typeid(*this).name(); // cerr << "RELEASE: " << dec << n << " " << m_ref_count << " 0x" << hex << (int)this << endl; // if no more references if( m_ref_count == 0 ) { // this is not good | TODO: our_locks_in_effect assumes single VM if( our_locks_in_effect && m_locked ) { EM_error2( 0, "internal error: releasing locked VM object!" ); // fail assert( FALSE ); // in case assert is disabled *(int *)0 = 1; } #ifndef __CHUNREAL_ENGINE__ // log | 1.5.0.0 (ge) added EM_log( CK_LOG_FINEST, "reclaiming %s: 0x%08x", typeid(*this).name(), this ); #else // #chunreal UE seems to disallow real-time type info EM_log( CK_LOG_FINEST, "reclaiming object: 0x%08x", this ); #endif // #ifndef __CHUNREAL_ENGINE__ // tell the object manager to set this free // Chuck_VM_Alloc::instance()->free_object( this ); // REFACTOR-2017: doing this for now delete this; } } //----------------------------------------------------------------------------- // name: lock() // desc: lock to keep from deleted //----------------------------------------------------------------------------- void Chuck_VM_Object::lock() { m_locked = TRUE; } //----------------------------------------------------------------------------- // name: unlock() // desc: unlock to allow deleting //----------------------------------------------------------------------------- void Chuck_VM_Object::unlock() { m_locked = FALSE; } //----------------------------------------------------------------------------- // name: lock_all() // desc: disallow deletion of locked objects //----------------------------------------------------------------------------- void Chuck_VM_Object::lock_all() { // log EM_log( CK_LOG_SYSTEM, "locking down special objects..." ); // set flag our_locks_in_effect = TRUE; } //----------------------------------------------------------------------------- // name: unlock_all() // desc: allow deletion of locked objects (USE WITH CAUTION!) //----------------------------------------------------------------------------- void Chuck_VM_Object::unlock_all() { // log EM_log( CK_LOG_SYSTEM, "unprotecting special objects..." ); // set flag our_locks_in_effect = FALSE; } // static member // Chuck_VM_Alloc * Chuck_VM_Alloc::our_instance = NULL; //----------------------------------------------------------------------------- // name: instance() // desc: return static instance //----------------------------------------------------------------------------- //Chuck_VM_Alloc * Chuck_VM_Alloc::instance() //{ // if( !our_instance ) // { // our_instance = new Chuck_VM_Alloc; // assert( our_instance != NULL ); // } // // return our_instance; //} //----------------------------------------------------------------------------- // name: add_object() // desc: add newly allocated vm object //----------------------------------------------------------------------------- //void Chuck_VM_Alloc::add_object( Chuck_VM_Object * obj ) //{ // // do log // if( DO_LOG( CK_LOG_ALL ) ) // { // // log it // EM_log( CK_LOG_ALL, "adding '%s' (0x%lx)...", // mini_type( typeid(*obj).name() ), obj ); // } // // // add it to map //} //----------------------------------------------------------------------------- // name: free_object() // desc: free vm object - reference count should be 0 //----------------------------------------------------------------------------- //void Chuck_VM_Alloc::free_object( Chuck_VM_Object * obj ) //{ // // make sure the ref count is 0 // assert( obj && obj->m_ref_count == 0 ); // // // do log // if( DO_LOG( CK_LOG_FINEST ) ) // { // // log it // EM_log( CK_LOG_FINEST, "freeing '%s' (0x%lx)...", // mini_type( typeid(*obj).name() ), obj ); // } // // // remove it from map // // // delete it // delete obj; //} //----------------------------------------------------------------------------- // name: Chuck_VM_Alloc() // desc: constructor ////----------------------------------------------------------------------------- //Chuck_VM_Alloc::Chuck_VM_Alloc() //{ } //----------------------------------------------------------------------------- // name: ~Chuck_VM_Alloc() // desc: destructor //----------------------------------------------------------------------------- //Chuck_VM_Alloc::~Chuck_VM_Alloc() //{ } //----------------------------------------------------------------------------- // name: Chuck_Object() // desc: constructor //----------------------------------------------------------------------------- Chuck_Object::Chuck_Object() { // zero virtual table vtable = NULL; // zero type type_ref = NULL; // zero data data = NULL; // zero size data_size = 0; // add to vm allocator // Chuck_VM_Alloc::instance()->add_object( this ); } //----------------------------------------------------------------------------- // name: Chuck_Object() // desc: ... //----------------------------------------------------------------------------- Chuck_Object::~Chuck_Object() { // added 1.3.0.0: // call destructors, from latest descended child to oldest parent Chuck_Type * type = this->type_ref; while( type != NULL ) { // SPENCER TODO: HACK! is there a better way to call the dtor? if( type->info && type->has_destructor ) // 1.5.0.0 (ge) added type->info check { // sanity check assert( type->info->dtor && type->info->dtor->native_func ); // REFACTOR-2017: do we know which VM to pass in? (currently NULL) ((f_dtor)(type->info->dtor->native_func))( this, NULL, NULL, Chuck_DL_Api::Api::instance() ); } // go up the inheritance type = type->parent; } // free SAFE_DELETE( vtable ); SAFE_RELEASE( type_ref ); SAFE_DELETE_ARRAY( data ); // if( vtable ) { delete vtable; vtable = NULL; } // if( type_ref ) { type_ref->release(); type_ref = NULL; } // if( data ) { delete [] data; size = 0; data = NULL; } } //----------------------------------------------------------------------------- // name: dump() // desc: output current state (can be overridden) //----------------------------------------------------------------------------- void Chuck_Object::dump() // 1.4.1.1 (ge) { // need type info Chuck_Type * type = this->type_ref; // output state with type info type->dump( this ); } //----------------------------------------------------------------------------- // name: help() // desc: output type info (can be overriden; but probably shouldn't be) //----------------------------------------------------------------------------- void Chuck_Object::help() // 1.4.1.0 (ge) { // type to unpack Chuck_Type * type = this->type_ref; // unpack type and output its info type->apropos(); } //----------------------------------------------------------------------------- // name: ~Chuck_Array() // desc: destructor //----------------------------------------------------------------------------- Chuck_Array::~Chuck_Array() { // decrement reference count; added (ge): 1.4.1.0 SAFE_RELEASE( m_array_type ); } //----------------------------------------------------------------------------- // name: Chuck_Array4() // desc: constructor //----------------------------------------------------------------------------- Chuck_Array4::Chuck_Array4( t_CKBOOL is_obj, t_CKINT capacity ) { // sanity check assert( capacity >= 0 ); // set size m_vector.resize( capacity ); // clear (as non-object, so no releases) m_is_obj = FALSE; this->zero( 0, m_vector.capacity() ); // is object (set after clear) m_is_obj = is_obj; } //----------------------------------------------------------------------------- // name: ~Chuck_Array4() // desc: destructor //----------------------------------------------------------------------------- Chuck_Array4::~Chuck_Array4() { // 1.4.2.0 (ge) | added, which should cascade to nested array objects clear(); } //----------------------------------------------------------------------------- // name: addr() // desc: ... //----------------------------------------------------------------------------- t_CKUINT Chuck_Array4::addr( t_CKINT i ) { // bound check if( i < 0 || i >= m_vector.capacity() ) return 0; // get the addr