/*---------------------------------------------------------------------------- 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.-----------------------------------------------------------------------------*/ //-----------------------------------------------------------------------------// name: chuck_dl.cpp// desc: chuck dynamic linking header//// authors: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)// Ari Lazier (alazier@cs.princeton.edu)// Spencer Salazar (spencer@ccrma.stanford.edu)// mac os code based on apple's open source//// date: spring 2004 - 1.1// spring 2005 - 1.2//-----------------------------------------------------------------------------#include "chuck_dl.h"#include "chuck_errmsg.h"#include "chuck_type.h"#include "chuck_instr.h"#include "chuck_compile.h"#include "chuck_vm.h"#include "chuck.h"#include <sstream>using namespace std; #if defined(__MACOSX_CORE__)char g_default_chugin_path[] = "/usr/local/lib/chuck:/Library/Application Support/ChucK/ChuGins:~/Library/Application Support/ChucK/ChuGins";#elif defined(__PLATFORM_WIN32__)char g_default_chugin_path[] = "C:\\WINDOWS\\system32\\ChucK;C:\\Program Files\\ChucK\\chugins;C:\\Program Files (x86)\\ChucK\\chugins";#else // Linux/Cygwinchar g_default_chugin_path[] = "/usr/local/lib/chuck";#endif char g_chugin_path_envvar[] = "CHUCK_CHUGIN_PATH"; //-----------------------------------------------------------------------------// internal implementation of query functions//----------------------------------------------------------------------------- t_CKUINT ck_builtin_declversion() { return CK_DLL_VERSION; } //-----------------------------------------------------------------------------// name: ck_setname()// desc: set the name of the module//-----------------------------------------------------------------------------void CK_DLL_CALL ck_setname( Chuck_DL_Query * query, const char * name ){ // set the name query->dll_name = name;} //-----------------------------------------------------------------------------// name: ck_begin_class()// desc: begin class/namespace, can be nexted//-----------------------------------------------------------------------------void CK_DLL_CALL ck_begin_class( Chuck_DL_Query * query, const char * name, const char * parent ){ // find parent mvar offset t_CKINT parent_offset = 0; if(parent && parent[0] != '\0') { a_Id_List parent_path = str2list( parent ); if( !parent_path ) { // error EM_error2( 0, "class import: ck_begin_class: unknown parent type '%s'", query->curr_class->name.c_str(), name, parent ); return; } Chuck_Type * ck_parent_type = type_engine_find_type( query->env(), parent_path ); delete_id_list( parent_path ); if( !ck_parent_type ) { // error EM_error2( 0, "class import: ck_begin_class: unable to find parent type '%s'", ck_parent_type ); return; } parent_offset = ck_parent_type->obj_size; } // push query->stack.push_back( query->curr_class ); // allocate Chuck_DL_Class * c = new Chuck_DL_Class; // add class if( query->curr_class ) // recursive query->curr_class->classes.push_back( c ); // 1.3.2.0: do not save class for later import (will import it on class close)// else// // first level// query->classes.push_back( c ); // remember info c->name = name; c->parent = parent; c->current_mvar_offset = parent_offset; // curr query->curr_class = c; query->curr_func = NULL;} //-----------------------------------------------------------------------------// name: ck_add_ctor()// desc: add constructor, can be followed by add_arg//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_ctor( Chuck_DL_Query * query, f_ctor ctor ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_ctor invoked without begin_class..." ); return; } // allocate Chuck_DL_Func * f = new Chuck_DL_Func; f->name = "[ctor]"; f->type = "void"; f->ctor = ctor; // add query->curr_class->ctors.push_back( f ); query->curr_func = f;} //-----------------------------------------------------------------------------// name: ck_add_dtor()// add destructor, no args allowed//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_dtor( Chuck_DL_Query * query, f_dtor dtor ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_dtor invoked without begin_class..." ); return; } // make sure there are no duplicates if( query->curr_class->dtor ) { // error EM_error2( 0, "class import: multiple dtor added ..." ); return; } // allocate Chuck_DL_Func * f = new Chuck_DL_Func; f->name = "[dtor]"; f->type = "void"; f->dtor = dtor; // add query->curr_class->dtor = f; // set query->curr_func = NULL;} //-----------------------------------------------------------------------------// name: ck_add_mfun()// desc: add member function, can be followed by add_arg//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_mfun( Chuck_DL_Query * query, f_mfun addr, const char * type, const char * name ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_mfun invoked without begin_class..." ); return; } // allocate Chuck_DL_Func * f = new Chuck_DL_Func; f->name = name; f->type = type; f->mfun = addr; // add query->curr_class->mfuns.push_back( f ); query->curr_func = f;} //-----------------------------------------------------------------------------// name: ck_add_sfun()// desc: add static function, can be followed by add_arg//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_sfun( Chuck_DL_Query * query, f_sfun addr, const char * type, const char * name ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_sfun invoked without begin_class..." ); return; } // allocate Chuck_DL_Func * f = new Chuck_DL_Func; f->name = name; f->type = type; f->sfun = addr; // add query->curr_class->sfuns.push_back( f ); query->curr_func = f;} //-----------------------------------------------------------------------------// name: ck_add_mvar()// desc: add member var//-----------------------------------------------------------------------------t_CKUINT CK_DLL_CALL ck_add_mvar( Chuck_DL_Query * query, const char * type, const char * name, t_CKBOOL is_const ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_mvar invoked without begin_class..." ); return CK_INVALID_OFFSET; } a_Id_List path = str2list( type ); if( !path ) { // error EM_error2( 0, "class import: add_mvar: mvar %s.%s has unknown type '%s'", query->curr_class->name.c_str(), name, type ); return CK_INVALID_OFFSET; } Chuck_Type * ck_type = type_engine_find_type( query->env(), path ); delete_id_list( path ); if( !ck_type ) { // error EM_error2( 0, "class import: add_mvar: unable to find type '%s'", type ); return CK_INVALID_OFFSET; } // allocate Chuck_DL_Value * v = new Chuck_DL_Value; v->name = name; v->type = type; v->is_const = is_const; // add query->curr_class->mvars.push_back( v ); query->curr_func = NULL; query->last_var = v; t_CKUINT offset = query->curr_class->current_mvar_offset; query->curr_class->current_mvar_offset = type_engine_next_offset( query->curr_class->current_mvar_offset, ck_type ); return offset;} //-----------------------------------------------------------------------------// name: ck_add_svar()// desc: add static var//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_svar( Chuck_DL_Query * query, const char * type, const char * name, t_CKBOOL is_const, void * addr ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_svar invoked without begin_class..." ); return; } // allocate Chuck_DL_Value * v = new Chuck_DL_Value; v->name = name; v->type = type; v->is_const = is_const; v->static_addr = addr; // add query->curr_class->svars.push_back( v ); query->curr_func = NULL; query->last_var = v;} //-----------------------------------------------------------------------------// name: ck_add_arg()// desc: add argument to function//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_arg( Chuck_DL_Query * query, const char * type, const char * name ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_arg invoked without begin_class..." ); return; } // make sure there is function if( !query->curr_func ) { // error EM_error2( 0, "class import: add_arg can only follow 'ctor', 'mfun', 'sfun', 'arg'..." ); return; } // allocate Chuck_DL_Value * v = new Chuck_DL_Value; v->name = name; v->type = type; // add query->curr_func->args.push_back( v );} //-----------------------------------------------------------------------------// name: ck_add_ugen_func()// desc: (ugen only) add tick and pmsg functions//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_ugen_func( Chuck_DL_Query * query, f_tick ugen_tick, f_pmsg ugen_pmsg, t_CKUINT num_in, t_CKUINT num_out ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_ugen_func invoked without begin_class..." ); return; } // make sure tick not defined already if( query->curr_class->ugen_tick && ugen_tick ) { // error EM_error2( 0, "class import: ugen_tick already defined..." ); return; } // make sure pmsg not defined already if( query->curr_class->ugen_pmsg && ugen_pmsg ) { // error EM_error2( 0, "class import: ugen_pmsg already defined..." ); return; } // set if( ugen_tick ) query->curr_class->ugen_tick = ugen_tick; if( ugen_pmsg ) query->curr_class->ugen_pmsg = ugen_pmsg; query->curr_class->ugen_num_in = num_in; query->curr_class->ugen_num_out = num_out; query->curr_func = NULL;} //-----------------------------------------------------------------------------// name: ck_add_ugen_funcf()// desc: (ugen only) add tick and pmsg functions//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_ugen_funcf( Chuck_DL_Query * query, f_tickf ugen_tickf, f_pmsg ugen_pmsg, t_CKUINT num_in, t_CKUINT num_out ){ // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_ugen_func invoked without begin_class..." ); return; } // make sure tick not defined already if( query->curr_class->ugen_tickf && ugen_tickf ) { // error EM_error2( 0, "class import: ugen_tick already defined..." ); return; } // make sure pmsg not defined already if( query->curr_class->ugen_pmsg && ugen_pmsg ) { // error EM_error2( 0, "class import: ugen_pmsg already defined..." ); return; } // set if( ugen_tickf ) query->curr_class->ugen_tickf = ugen_tickf; if( ugen_pmsg ) query->curr_class->ugen_pmsg = ugen_pmsg; query->curr_class->ugen_num_in = num_in; query->curr_class->ugen_num_out = num_out; query->curr_func = NULL;} //-----------------------------------------------------------------------------// name: ck_add_ugen_funcf_auto_num_channels()// desc: (ugen only) add tick and pmsg functions. specify num channels by vm.//-----------------------------------------------------------------------------void CK_DLL_CALL ck_add_ugen_funcf_auto_num_channels( Chuck_DL_Query * query, f_tickf ugen_tickf, f_pmsg ugen_pmsg ){ ck_add_ugen_funcf( query, ugen_tickf, ugen_pmsg, query->vm()->m_num_adc_channels, query->vm()->m_num_dac_channels );} //-----------------------------------------------------------------------------// name: ck_add_ugen_ctrl()// desc: (ugen only) add ctrl parameters//-----------------------------------------------------------------------------//void CK_DLL_CALL ck_add_ugen_ctrl( Chuck_DL_Query * query, f_ctrl ugen_ctrl, f_cget ugen_cget,// const char * type, const char * name )//{// // this is no longer used// EM_error2( 0, "class import: obselete ck_add_ugen_ctrl invoked..." );// return;//Lines 1–500 of 1343. 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. -----------------------------------------------------------------------------*/ //----------------------------------------------------------------------------- // name: chuck_dl.cpp // desc: chuck dynamic linking header // // authors: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu) // Ari Lazier (alazier@cs.princeton.edu) // Spencer Salazar (spencer@ccrma.stanford.edu) // mac os code based on apple's open source // // date: spring 2004 - 1.1 // spring 2005 - 1.2 //----------------------------------------------------------------------------- #include "chuck_dl.h" #include "chuck_errmsg.h" #include "chuck_type.h" #include "chuck_instr.h" #include "chuck_compile.h" #include "chuck_vm.h" #include "chuck.h" #include <sstream> using namespace std; #if defined(__MACOSX_CORE__) char g_default_chugin_path[] = "/usr/local/lib/chuck:/Library/Application Support/ChucK/ChuGins:~/Library/Application Support/ChucK/ChuGins"; #elif defined(__PLATFORM_WIN32__) char g_default_chugin_path[] = "C:\\WINDOWS\\system32\\ChucK;C:\\Program Files\\ChucK\\chugins;C:\\Program Files (x86)\\ChucK\\chugins"; #else // Linux/Cygwin char g_default_chugin_path[] = "/usr/local/lib/chuck"; #endif char g_chugin_path_envvar[] = "CHUCK_CHUGIN_PATH"; //----------------------------------------------------------------------------- // internal implementation of query functions //----------------------------------------------------------------------------- t_CKUINT ck_builtin_declversion() { return CK_DLL_VERSION; } //----------------------------------------------------------------------------- // name: ck_setname() // desc: set the name of the module //----------------------------------------------------------------------------- void CK_DLL_CALL ck_setname( Chuck_DL_Query * query, const char * name ) { // set the name query->dll_name = name; } //----------------------------------------------------------------------------- // name: ck_begin_class() // desc: begin class/namespace, can be nexted //----------------------------------------------------------------------------- void CK_DLL_CALL ck_begin_class( Chuck_DL_Query * query, const char * name, const char * parent ) { // find parent mvar offset t_CKINT parent_offset = 0; if(parent && parent[0] != '\0') { a_Id_List parent_path = str2list( parent ); if( !parent_path ) { // error EM_error2( 0, "class import: ck_begin_class: unknown parent type '%s'", query->curr_class->name.c_str(), name, parent ); return; } Chuck_Type * ck_parent_type = type_engine_find_type( query->env(), parent_path ); delete_id_list( parent_path ); if( !ck_parent_type ) { // error EM_error2( 0, "class import: ck_begin_class: unable to find parent type '%s'", ck_parent_type ); return; } parent_offset = ck_parent_type->obj_size; } // push query->stack.push_back( query->curr_class ); // allocate Chuck_DL_Class * c = new Chuck_DL_Class; // add class if( query->curr_class ) // recursive query->curr_class->classes.push_back( c ); // 1.3.2.0: do not save class for later import (will import it on class close) // else // // first level // query->classes.push_back( c ); // remember info c->name = name; c->parent = parent; c->current_mvar_offset = parent_offset; // curr query->curr_class = c; query->curr_func = NULL; } //----------------------------------------------------------------------------- // name: ck_add_ctor() // desc: add constructor, can be followed by add_arg //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_ctor( Chuck_DL_Query * query, f_ctor ctor ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_ctor invoked without begin_class..." ); return; } // allocate Chuck_DL_Func * f = new Chuck_DL_Func; f->name = "[ctor]"; f->type = "void"; f->ctor = ctor; // add query->curr_class->ctors.push_back( f ); query->curr_func = f; } //----------------------------------------------------------------------------- // name: ck_add_dtor() // add destructor, no args allowed //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_dtor( Chuck_DL_Query * query, f_dtor dtor ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_dtor invoked without begin_class..." ); return; } // make sure there are no duplicates if( query->curr_class->dtor ) { // error EM_error2( 0, "class import: multiple dtor added ..." ); return; } // allocate Chuck_DL_Func * f = new Chuck_DL_Func; f->name = "[dtor]"; f->type = "void"; f->dtor = dtor; // add query->curr_class->dtor = f; // set query->curr_func = NULL; } //----------------------------------------------------------------------------- // name: ck_add_mfun() // desc: add member function, can be followed by add_arg //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_mfun( Chuck_DL_Query * query, f_mfun addr, const char * type, const char * name ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_mfun invoked without begin_class..." ); return; } // allocate Chuck_DL_Func * f = new Chuck_DL_Func; f->name = name; f->type = type; f->mfun = addr; // add query->curr_class->mfuns.push_back( f ); query->curr_func = f; } //----------------------------------------------------------------------------- // name: ck_add_sfun() // desc: add static function, can be followed by add_arg //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_sfun( Chuck_DL_Query * query, f_sfun addr, const char * type, const char * name ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_sfun invoked without begin_class..." ); return; } // allocate Chuck_DL_Func * f = new Chuck_DL_Func; f->name = name; f->type = type; f->sfun = addr; // add query->curr_class->sfuns.push_back( f ); query->curr_func = f; } //----------------------------------------------------------------------------- // name: ck_add_mvar() // desc: add member var //----------------------------------------------------------------------------- t_CKUINT CK_DLL_CALL ck_add_mvar( Chuck_DL_Query * query, const char * type, const char * name, t_CKBOOL is_const ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_mvar invoked without begin_class..." ); return CK_INVALID_OFFSET; } a_Id_List path = str2list( type ); if( !path ) { // error EM_error2( 0, "class import: add_mvar: mvar %s.%s has unknown type '%s'", query->curr_class->name.c_str(), name, type ); return CK_INVALID_OFFSET; } Chuck_Type * ck_type = type_engine_find_type( query->env(), path ); delete_id_list( path ); if( !ck_type ) { // error EM_error2( 0, "class import: add_mvar: unable to find type '%s'", type ); return CK_INVALID_OFFSET; } // allocate Chuck_DL_Value * v = new Chuck_DL_Value; v->name = name; v->type = type; v->is_const = is_const; // add query->curr_class->mvars.push_back( v ); query->curr_func = NULL; query->last_var = v; t_CKUINT offset = query->curr_class->current_mvar_offset; query->curr_class->current_mvar_offset = type_engine_next_offset( query->curr_class->current_mvar_offset, ck_type ); return offset; } //----------------------------------------------------------------------------- // name: ck_add_svar() // desc: add static var //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_svar( Chuck_DL_Query * query, const char * type, const char * name, t_CKBOOL is_const, void * addr ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_svar invoked without begin_class..." ); return; } // allocate Chuck_DL_Value * v = new Chuck_DL_Value; v->name = name; v->type = type; v->is_const = is_const; v->static_addr = addr; // add query->curr_class->svars.push_back( v ); query->curr_func = NULL; query->last_var = v; } //----------------------------------------------------------------------------- // name: ck_add_arg() // desc: add argument to function //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_arg( Chuck_DL_Query * query, const char * type, const char * name ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_arg invoked without begin_class..." ); return; } // make sure there is function if( !query->curr_func ) { // error EM_error2( 0, "class import: add_arg can only follow 'ctor', 'mfun', 'sfun', 'arg'..." ); return; } // allocate Chuck_DL_Value * v = new Chuck_DL_Value; v->name = name; v->type = type; // add query->curr_func->args.push_back( v ); } //----------------------------------------------------------------------------- // name: ck_add_ugen_func() // desc: (ugen only) add tick and pmsg functions //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_ugen_func( Chuck_DL_Query * query, f_tick ugen_tick, f_pmsg ugen_pmsg, t_CKUINT num_in, t_CKUINT num_out ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_ugen_func invoked without begin_class..." ); return; } // make sure tick not defined already if( query->curr_class->ugen_tick && ugen_tick ) { // error EM_error2( 0, "class import: ugen_tick already defined..." ); return; } // make sure pmsg not defined already if( query->curr_class->ugen_pmsg && ugen_pmsg ) { // error EM_error2( 0, "class import: ugen_pmsg already defined..." ); return; } // set if( ugen_tick ) query->curr_class->ugen_tick = ugen_tick; if( ugen_pmsg ) query->curr_class->ugen_pmsg = ugen_pmsg; query->curr_class->ugen_num_in = num_in; query->curr_class->ugen_num_out = num_out; query->curr_func = NULL; } //----------------------------------------------------------------------------- // name: ck_add_ugen_funcf() // desc: (ugen only) add tick and pmsg functions //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_ugen_funcf( Chuck_DL_Query * query, f_tickf ugen_tickf, f_pmsg ugen_pmsg, t_CKUINT num_in, t_CKUINT num_out ) { // make sure there is class if( !query->curr_class ) { // error EM_error2( 0, "class import: add_ugen_func invoked without begin_class..." ); return; } // make sure tick not defined already if( query->curr_class->ugen_tickf && ugen_tickf ) { // error EM_error2( 0, "class import: ugen_tick already defined..." ); return; } // make sure pmsg not defined already if( query->curr_class->ugen_pmsg && ugen_pmsg ) { // error EM_error2( 0, "class import: ugen_pmsg already defined..." ); return; } // set if( ugen_tickf ) query->curr_class->ugen_tickf = ugen_tickf; if( ugen_pmsg ) query->curr_class->ugen_pmsg = ugen_pmsg; query->curr_class->ugen_num_in = num_in; query->curr_class->ugen_num_out = num_out; query->curr_func = NULL; } //----------------------------------------------------------------------------- // name: ck_add_ugen_funcf_auto_num_channels() // desc: (ugen only) add tick and pmsg functions. specify num channels by vm. //----------------------------------------------------------------------------- void CK_DLL_CALL ck_add_ugen_funcf_auto_num_channels( Chuck_DL_Query * query, f_tickf ugen_tickf, f_pmsg ugen_pmsg ) { ck_add_ugen_funcf( query, ugen_tickf, ugen_pmsg, query->vm()->m_num_adc_channels, query->vm()->m_num_dac_channels ); } //----------------------------------------------------------------------------- // name: ck_add_ugen_ctrl() // desc: (ugen only) add ctrl parameters //----------------------------------------------------------------------------- //void CK_DLL_CALL ck_add_ugen_ctrl( Chuck_DL_Query * query, f_ctrl ugen_ctrl, f_cget ugen_cget, // const char * type, const char * name ) //{ // // this is no longer used // EM_error2( 0, "class import: obselete ck_add_ugen_ctrl invoked..." ); // return; //