4315 lines · 106.9 KB · C++
RawDownload
/*----------------------------------------------------------------------------  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 addr

Lines 1–500 of 4315.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t