aboutsummaryrefslogtreecommitdiff
path: root/clr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clr.cpp')
-rwxr-xr-xclr.cpp927
1 files changed, 295 insertions, 632 deletions
diff --git a/clr.cpp b/clr.cpp
index 5f0a96b..cef43ff 100755
--- a/clr.cpp
+++ b/clr.cpp
@@ -7,6 +7,9 @@ extern "C" {
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/class.h>
#include <mono/metadata/metadata.h>
+
+// we need this one - it's in mono-devel
+gpointer mono_delegate_to_ftnptr (MonoDelegate *delegate);
}
#ifdef _MSC_VER
@@ -30,6 +33,8 @@ extern "C" {
#include <list>
+#define CALL __stdcall
+
// main class library
#define CORELIB "PureData"
#define DLLEXT "dll"
@@ -40,35 +45,42 @@ extern "C" {
static t_symbol *sym_object;
-// cached mono data
-static MonoDomain *monodomain;
-static MonoClass *clr_symbol,*clr_pointer,*clr_atom,*clr_atomlist,*clr_external;
-static MonoMethodDesc *clr_desc_tostring,*clr_desc_ctor;
-static MonoMethod *clr_meth_invoke;
-static MonoProperty *clr_prop_method;
+struct PassedData
+{
+ MonoObject object;
+ MonoObject *klass;
+ MonoObject *ext;
+ MonoObject *obj;
+};
struct AtomList
{
- int argc;
+ AtomList(int c,t_atom *v): argc(c),argv(v) {}
+
+ int argc;
t_atom *argv;
-
- void Set(int c,t_atom *v) { argc = c,argv = v; }
};
-// transforms a pointer (like MonoObject *) into a 3 element-list
+
+// cached mono data
+static MonoDomain *monodomain;
+static PassedData *clr_pass;
+
+// transforms a pointer (like MonoObject *) into a atom list
+template <class T>
struct ObjectAtom
{
// 64-bit safe...
- enum { bitshift = 22,size = sizeof(void*)*8/bitshift+1 };
+ enum { bitshift = 22,size = sizeof(T)*8/bitshift+1 };
t_atom msg[size];
ObjectAtom() {}
- ObjectAtom(void *o)
+ ObjectAtom(T o)
{
- size_t ptr = (size_t)o;
+ long ptr = (long)o;
for(int i = 0; i < size; ++i) {
SETFLOAT(msg+i,(int)(ptr&((1<<bitshift)-1)));
ptr >>= bitshift;
@@ -83,139 +95,37 @@ struct ObjectAtom
return true;
}
- static void *ptr(const t_atom *argv)
+ static T ptr(const t_atom *argv)
{
- size_t ret = 0;
+ long ret = 0;
for(int i = size-1; i >= 0; --i)
ret = (ret<<bitshift)+(int)argv[i].a_w.w_float;
- return (void *)ret;
+ return (T)ret;
}
- template<class T> static T ptr(const t_atom *argv) { return (T)ptr(argv); }
-
operator t_atom *() { return msg; }
};
-// temporary workspace items
-
-static MonoArray *clr_objarr_1,*clr_objarr_2,*clr_objarr_3;
-static MonoObject *clr_obj_int,*clr_obj_single,*clr_obj_symbol,*clr_obj_pointer,*clr_obj_atomlist;
-static int *clr_val_int;
-static float *clr_val_single;
-static t_symbol **clr_val_symbol;
-static void **clr_val_pointer;
-static AtomList *clr_val_atomlist;
-
-
-struct t_clr;
-
-struct Delegate
-{
- enum Kind { k_bang,k_float,k_symbol,k_pointer,k_list,k_anything,k_object };
-
- inline operator bool() const { return methodinfo != NULL; }
-
- MonoObject *methodinfo;
- MonoMethod *virtmethod;
- Kind kind;
-
- inline void init(MonoObject *method,Kind k)
- {
- methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
- assert(methodinfo);
- virtmethod = mono_object_get_virtual_method(methodinfo,clr_meth_invoke);
- assert(virtmethod);
- kind = k;
- }
-
- inline MonoObject *invoke(MonoObject *obj,void *arg) const
- {
- gpointer args[2] = {obj,arg};
- assert(methodinfo);
- MonoObject *exc;
- mono_runtime_invoke(virtmethod,methodinfo,args,&exc);
- return exc;
- }
-
- inline MonoObject *invokeatom(MonoObject *obj,MonoObject *atom) const
- {
- mono_array_set(clr_objarr_1,void*,0,atom);
- return invoke(obj,clr_objarr_1);
- }
-
- inline MonoObject *operator()(MonoObject *obj) const
- {
- return invoke(obj,NULL);
- }
-
- inline MonoObject *operator()(MonoObject *obj,float f) const
- {
- *clr_val_single = f;
- return invokeatom(obj,clr_obj_single);
- }
-
- inline MonoObject *operator()(MonoObject *obj,t_symbol *s) const
- {
- *clr_val_symbol = s;
- return invokeatom(obj,clr_obj_symbol);
- }
-
- inline MonoObject *operator()(MonoObject *obj,t_gpointer *p) const
- {
- *clr_val_pointer = p;
- return invokeatom(obj,clr_obj_pointer);
- }
-
- inline MonoObject *operator()(MonoObject *obj,int argc,t_atom *argv) const
- {
- clr_val_atomlist->Set(argc,argv);
- return invokeatom(obj,clr_obj_atomlist);
- }
-
- inline MonoObject *operator()(MonoObject *obj,int inlet,t_symbol *s,int argc,t_atom *argv) const
- {
- *clr_val_int = inlet;
- *clr_val_symbol = s;
- clr_val_atomlist->Set(argc,argv);
- mono_array_set(clr_objarr_3,void*,0,clr_obj_int);
- mono_array_set(clr_objarr_3,void*,1,clr_obj_symbol);
- mono_array_set(clr_objarr_3,void*,2,clr_obj_atomlist);
- return invoke(obj,clr_objarr_3);
- }
-
- inline MonoObject *operator()(MonoObject *obj,int inlet,MonoObject *clrobj) const
- {
- *clr_val_int = inlet;
- mono_array_set(clr_objarr_2,void*,0,clr_obj_int);
- mono_array_set(clr_objarr_2,void*,1,clrobj);
- return invoke(obj,clr_objarr_2);
- }
-};
+enum Kind { k_bang, k_float, k_symbol, k_pointer, k_list, k_anything, k_object };
-typedef std::map<t_symbol *,Delegate> ClrMethodMap;
-typedef std::vector<ClrMethodMap *> ClrMethods;
// this is the class structure
// holding the pd and mono class
-// and our CLR method pointers
struct t_clr_class
{
t_class *pd_class;
- MonoClass *mono_class;
- MonoMethod *mono_ctor;
- MonoClassField *obj_field; // ptr field in PureData.External
- t_symbol *name;
- Delegate method_bang,method_float,method_symbol,method_pointer,method_list,method_anything,method_object;
- ClrMethods *methods; // explicit method selectors
+ MonoObject *mono_class;
};
static t_class *proxy_class;
+struct t_instance;
+
struct t_proxy
{
t_object pd_obj; // myself
- t_clr *parent; // parent object
+ t_instance *parent; // parent object
int inlet;
};
@@ -232,302 +142,144 @@ static t_clr_class *clr_setup_class = NULL;
// inlet index... must start with 0 every time a new object is made
static int clr_inlet;
+
// this is the class instance object structure
-struct t_clr
+struct t_instance
{
t_object pd_obj; // myself
- t_clr_class *clr_clss; // pointer to our class structure
+ t_clr_class *pd_class;
MonoObject *mono_obj; // the mono class instance
- OutletArr *outlets;
+ guint32 mono_handle; // the mono class instance
+
+ OutletArr *outlets;
ProxyList *proxies;
};
-
+typedef void (__stdcall NewClass)(t_clr_class *c,const t_symbol *sym);
+typedef void (__stdcall NewInstance)(t_instance *p,AtomList l);
+typedef void (__stdcall CallBang)();
+typedef void (__stdcall CallFloat)(float f);
+typedef void (__stdcall CallSymbol)(const t_symbol *sym);
+typedef void (__stdcall CallPointer)(const t_gpointer *ptr);
+typedef void (__stdcall CallList)(AtomList l);
+typedef void (__stdcall CallAnything)(int inlet,const t_symbol *sym,AtomList l);
+typedef void (__stdcall CallObject)(int inlet);
+
+static NewClass *newclass = NULL;
+static NewInstance *newinstance = NULL;
+static CallBang *callbang = NULL;
+static CallFloat *callfloat = NULL;
+static CallSymbol *callsymbol = NULL;
+static CallPointer *callpointer = NULL;
+static CallList *calllist = NULL;
+static CallAnything *callanything = NULL;
+static CallObject *callobject = NULL;
+
+#if 0
// Print error message given by exception
-static void error_exc(char *txt,char *cname,MonoObject *exc)
+static void error_exc(char* txt,char* cname,MonoObject* exc)
{
- MonoMethod *m = mono_method_desc_search_in_class(clr_desc_tostring,mono_get_exception_class());
+ MonoMethod* m = mono_method_desc_search_in_class(clr_desc_tostring,mono_get_exception_class());
assert(m);
m = mono_object_get_virtual_method(exc,m);
assert(m);
- MonoString *str = (MonoString *)mono_runtime_invoke(m,exc,NULL,NULL);
+ MonoString* str = (MonoString*)mono_runtime_invoke(m,exc,NULL,NULL);
assert(str);
error("CLR class %s: %s",txt,cname);
error(mono_string_to_utf8(str));
}
+#endif
+
-static void clr_method_bang(t_clr *x)
+static void clr_method_bang(t_instance *x)
{
- assert(x && x->clr_clss);
- MonoObject *exc = x->clr_clss->method_bang(x->mono_obj);
- if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
+ assert(x);
+ assert(callbang);
+ clr_pass->ext = x->mono_obj;
+ callbang();
}
-static void clr_method_float(t_clr *x,t_float f)
+static void clr_method_float(t_instance *x,t_float f)
{
- assert(x && x->clr_clss);
- MonoObject *exc = x->clr_clss->method_float(x->mono_obj,f);
- if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
+ assert(x);
+ assert(callfloat);
+ clr_pass->ext = x->mono_obj;
+ callfloat(f);
}
-static void clr_method_symbol(t_clr *x,t_symbol *s)
+static void clr_method_symbol(t_instance *x,t_symbol *s)
{
- assert(x && x->clr_clss);
- MonoObject *exc = x->clr_clss->method_symbol(x->mono_obj,s);
- if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
+ assert(x);
+ assert(callsymbol);
+ clr_pass->ext = x->mono_obj;
+ callsymbol(s);
}
-static void clr_method_pointer(t_clr *x,t_gpointer *p)
+static void clr_method_pointer(t_instance *x,t_gpointer *p)
{
- assert(x && x->clr_clss);
- MonoObject *exc = x->clr_clss->method_pointer(x->mono_obj,p);
- if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
+ assert(x);
+ assert(callpointer);
+ clr_pass->ext = x->mono_obj;
+ callpointer(p);
}
-static void clr_method_list(t_clr *x,t_symbol *,int argc,t_atom *argv)
+static void clr_method_list(t_instance *x,t_symbol *,int argc,t_atom *argv)
{
- assert(x && x->clr_clss);
- MonoObject *exc = x->clr_clss->method_list(x->mono_obj,argc,argv);
- if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
+ assert(x);
+ assert(calllist);
+ clr_pass->ext = x->mono_obj;
+ calllist(AtomList(argc,argv));
}
-static void call_anything(t_clr *x,int inlet,t_symbol *s,int argc,t_atom *argv)
+static void call_anything(t_instance *x,int inlet,t_symbol *s,int argc,t_atom *argv)
{
- assert(x && x->clr_clss);
-
- const Delegate *d;
-
- ClrMethods *methods = x->clr_clss->methods;
- if(methods && inlet < (int)methods->size()) {
- ClrMethodMap *methmap = (*methods)[inlet];
- if(methmap) {
- ClrMethodMap::iterator it = methmap->find(s);
- if(it != methmap->end()) {
- d = &it->second;
- goto found;
- }
-
- if(inlet) {
- // search for NULL symbol pointer
- it = methmap->find(NULL);
- if(it != methmap->end()) {
- d = &it->second;
- goto found;
- }
- }
- }
- }
-
- // no selectors: general method
- d = &x->clr_clss->method_anything;
-
- found:
-
- // we must have found something....
- assert(d);
-
- MonoObject *exc;
- switch(d->kind) {
- case Delegate::k_bang:
- exc = (*d)(x->mono_obj);
- break;
- case Delegate::k_float:
- if((argc == 1 || (argc >= 1 && s == &s_list)) && argv[0].a_type == A_FLOAT)
- exc = (*d)(x->mono_obj,argv[0].a_w.w_float);
- else {
- error("%s - %s handler: float argument expected",x->clr_clss->name->s_name,s->s_name);
- return;
- }
- break;
- case Delegate::k_symbol:
- if((argc == 1 || (argc >= 1 && s == &s_list)) && argv[0].a_type == A_SYMBOL)
- exc = (*d)(x->mono_obj,argv[0].a_w.w_symbol);
- else {
- error("%s - %s handler: symbol argument expected",x->clr_clss->name->s_name,s->s_name);
- return;
- }
- break;
- case Delegate::k_pointer:
- if((argc == 1 || (argc >= 1 && s == &s_list)) && argv[0].a_type == A_POINTER)
- exc = (*d)(x->mono_obj,argv[0].a_w.w_gpointer);
- else {
- error("%s - %s handler: pointer argument expected",x->clr_clss->name->s_name,s->s_name);
- return;
- }
- break;
- case Delegate::k_list:
- exc = (*d)(x->mono_obj,argc,argv);
- break;
- case Delegate::k_anything:
- exc = (*d)(x->mono_obj,inlet,s,argc,argv);
- break;
- case Delegate::k_object:
- if(s != sym_object || !ObjectAtom::check(argc,argv)) {
- error("CLR - object handler: invalid arguments");
- return;
- }
- exc = (*d)(x->mono_obj,inlet,ObjectAtom::ptr<MonoObject *>(argv));
- break;
- default:
- assert(false);
- }
-
- if(exc) error_exc("Exception raised",x->clr_clss->name->s_name,exc);
+ assert(x);
+ clr_pass->ext = x->mono_obj;
+ if(s == sym_object && ObjectAtom<guint32>::check(argc,argv)) {
+ assert(callobject);
+ guint32 hnd = ObjectAtom<guint32>::ptr(argv);
+ clr_pass->obj = mono_gchandle_get_target(hnd);
+ callobject(inlet);
+ }
+ else {
+ assert(callanything);
+ callanything(inlet,s,AtomList(argc,argv));
+ }
}
-static void clr_method_anything(t_clr *x,t_symbol *s,int argc,t_atom *argv) { call_anything(x,0,s,argc,argv); }
+static void clr_method_anything(t_instance *x,t_symbol *s,int argc,t_atom *argv) { call_anything(x,0,s,argc,argv); }
static void clr_method_proxy(t_proxy *x,t_symbol *s,int argc,t_atom *argv) { call_anything(x->parent,x->inlet,s,argc,argv); }
-static void PD_Post(MonoString *str)
+static void CALL PD_Post(MonoString *str)
{
post("%s",mono_string_to_utf8(str));
}
-static void PD_PostError(MonoString *str)
+static void CALL PD_PostError(MonoString *str)
{
error("%s",mono_string_to_utf8(str));
}
-static void PD_PostVerbose(int lvl,MonoString *str)
+static void CALL PD_PostVerbose(int lvl,MonoString *str)
{
verbose(lvl,"%s",mono_string_to_utf8(str));
}
-static void *PD_SymGen(MonoString *str)
+static void *CALL PD_SymGen(MonoString *str)
{
assert(str);
return gensym(mono_string_to_utf8(str));
}
-static MonoString *PD_SymEval(t_symbol *sym)
+static MonoString *CALL PD_SymEval(t_symbol *sym)
{
assert(sym);
return mono_string_new(monodomain,sym->s_name);
}
-static void PD_AddMethodHandler(int inlet,t_symbol *sym,MonoObject *method,Delegate::Kind kind)
-{
- assert(clr_setup_class);
- Delegate d;
- d.methodinfo = mono_property_get_value(clr_prop_method,method,NULL,NULL);
- d.virtmethod = mono_object_get_virtual_method(d.methodinfo,clr_meth_invoke);
- d.kind = kind;
-
- ClrMethods *ms = clr_setup_class->methods;
- if(!ms)
- clr_setup_class->methods = ms = new ClrMethods;
-
- ClrMethodMap *m;
- if(inlet >= (int)ms->size()) {
- ms->resize(inlet+1,NULL);
- (*ms)[inlet] = m = new ClrMethodMap;
- }
- else
- m = (*ms)[inlet];
- assert(m);
-
- // add tag to map
- (*m)[sym] = d;
-}
-
-static void PD_AddMethodBang(int inlet,MonoObject *method)
-{
- if(inlet)
- PD_AddMethodHandler(inlet,&s_bang,method,Delegate::k_bang);
- else {
- assert(clr_setup_class);
- clr_setup_class->method_bang.init(method,Delegate::k_bang);
- }
-}
-
-static void PD_AddMethodFloat(int inlet,MonoObject *method)
-{
- if(inlet)
- PD_AddMethodHandler(inlet,&s_float,method,Delegate::k_float);
- else {
- assert(clr_setup_class);
- clr_setup_class->method_float.init(method,Delegate::k_float);
- }
-}
-
-static void PD_AddMethodSymbol(int inlet,MonoObject *method)
-{
- if(inlet)
- PD_AddMethodHandler(inlet,&s_symbol,method,Delegate::k_symbol);
- else {
- assert(clr_setup_class);
- clr_setup_class->method_symbol.init(method,Delegate::k_symbol);
- }
-}
-
-static void PD_AddMethodPointer(int inlet,MonoObject *method)
-{
- if(inlet)
- PD_AddMethodHandler(inlet,&s_pointer,method,Delegate::k_pointer);
- else {
- assert(clr_setup_class);
- clr_setup_class->method_pointer.init(method,Delegate::k_pointer);
- }
-}
-
-static void PD_AddMethodList(int inlet,MonoObject *method)
-{
- if(inlet)
- PD_AddMethodHandler(inlet,&s_list,method,Delegate::k_list);
- else {
- assert(clr_setup_class);
- clr_setup_class->method_list.init(method,Delegate::k_list);
- }
-}
-
-static void PD_AddMethodAnything(int inlet,MonoObject *method)
-{
- if(inlet)
- PD_AddMethodHandler(inlet,NULL,method,Delegate::k_anything);
- else {
- assert(clr_setup_class);
- clr_setup_class->method_anything.init(method,Delegate::k_anything);
- }
-}
-
-static void PD_AddMethodSelBang(int inlet,t_symbol *sym,MonoObject *method)
-{
- PD_AddMethodHandler(inlet,sym,method,Delegate::k_bang);
-}
-
-static void PD_AddMethodSelFloat(int inlet,t_symbol *sym,MonoObject *method)
-{
- PD_AddMethodHandler(inlet,sym,method,Delegate::k_float);
-}
-
-static void PD_AddMethodSelSymbol(int inlet,t_symbol *sym,MonoObject *method)
-{
- PD_AddMethodHandler(inlet,sym,method,Delegate::k_symbol);
-}
-static void PD_AddMethodSelPointer(int inlet,t_symbol *sym,MonoObject *method)
-{
- PD_AddMethodHandler(inlet,sym,method,Delegate::k_pointer);
-}
-
-static void PD_AddMethodSelList(int inlet,t_symbol *sym,MonoObject *method)
-{
- PD_AddMethodHandler(inlet,sym,method,Delegate::k_list);
-}
-
-static void PD_AddMethodSelAnything(int inlet,t_symbol *sym,MonoObject *method)
-{
- PD_AddMethodHandler(inlet,sym,method,Delegate::k_anything);
-}
-
-static void PD_AddMethodObject(int inlet,MonoObject *method)
-{
- PD_AddMethodHandler(inlet,sym_object,method,Delegate::k_object);
-}
-
-
-static void PD_AddInletAlias(t_clr *obj,t_symbol *sel,t_symbol *to_sel)
+static void CALL PD_AddInletAlias(t_instance *obj,t_symbol *sel,t_symbol *to_sel)
{
++clr_inlet;
assert(obj);
@@ -535,7 +287,7 @@ static void PD_AddInletAlias(t_clr *obj,t_symbol *sel,t_symbol *to_sel)
assert(in);
}
-static void PD_AddInletFloat(t_clr *obj,float *f)
+static void CALL PD_AddInletFloat(t_instance *obj,float *f)
{
++clr_inlet;
assert(obj);
@@ -543,7 +295,7 @@ static void PD_AddInletFloat(t_clr *obj,float *f)
assert(in);
}
-static void PD_AddInletSymbol(t_clr *obj,t_symbol **s)
+static void CALL PD_AddInletSymbol(t_instance *obj,t_symbol **s)
{
++clr_inlet;
assert(obj);
@@ -552,7 +304,7 @@ static void PD_AddInletSymbol(t_clr *obj,t_symbol **s)
}
/*
-static void PD_AddInletPointer(t_clr *obj,t_gpointer *p)
+static void CALL PD_AddInletPointer(t_clr *obj,t_gpointer *p)
{
++clr_inlet;
assert(obj);
@@ -561,7 +313,7 @@ static void PD_AddInletPointer(t_clr *obj,t_gpointer *p)
}
*/
-static void PD_AddInletProxyTyped(t_clr *obj,t_symbol *type)
+static void CALL PD_AddInletProxyTyped(t_instance *obj,t_symbol *type)
{
assert(obj);
t_proxy *p = (t_proxy *)pd_new(proxy_class);
@@ -573,10 +325,10 @@ static void PD_AddInletProxyTyped(t_clr *obj,t_symbol *type)
assert(in);
}
-static void PD_AddInletProxy(t_clr *obj) { PD_AddInletProxyTyped(obj,NULL); }
+static void CALL PD_AddInletProxy(t_instance *obj) { PD_AddInletProxyTyped(obj,NULL); }
-static void PD_AddOutlet(t_clr *obj,t_symbol *type)
+static void CALL PD_AddOutlet(t_instance *obj,t_symbol *type)
{
assert(obj);
t_outlet *out = outlet_new(&obj->pd_obj,type);
@@ -585,7 +337,7 @@ static void PD_AddOutlet(t_clr *obj,t_symbol *type)
obj->outlets->push_back(out);
}
-static void PD_OutletBang(t_clr *obj,int n)
+static void CALL PD_OutletBang(t_instance *obj,int n)
{
assert(obj);
assert(obj->outlets);
@@ -593,7 +345,7 @@ static void PD_OutletBang(t_clr *obj,int n)
outlet_bang((*obj->outlets)[n]);
}
-static void PD_OutletFloat(t_clr *obj,int n,float f)
+static void CALL PD_OutletFloat(t_instance *obj,int n,float f)
{
assert(obj);
assert(obj->outlets);
@@ -601,7 +353,7 @@ static void PD_OutletFloat(t_clr *obj,int n,float f)
outlet_float((*obj->outlets)[n],f);
}
-static void PD_OutletSymbol(t_clr *obj,int n,t_symbol *s)
+static void CALL PD_OutletSymbol(t_instance *obj,int n,t_symbol *s)
{
assert(obj);
assert(obj->outlets);
@@ -609,7 +361,7 @@ static void PD_OutletSymbol(t_clr *obj,int n,t_symbol *s)
outlet_symbol((*obj->outlets)[n],s);
}
-static void PD_OutletPointer(t_clr *obj,int n,t_gpointer *p)
+static void CALL PD_OutletPointer(t_instance *obj,int n,t_gpointer *p)
{
assert(obj);
assert(obj->outlets);
@@ -617,12 +369,12 @@ static void PD_OutletPointer(t_clr *obj,int n,t_gpointer *p)
outlet_pointer((*obj->outlets)[n],p);
}
-static void PD_OutletAtom(t_clr *obj,int n,t_atom l)
+static void CALL PD_OutletAtom(t_instance *obj,int n,t_atom l)
{
assert(obj);
assert(obj->outlets);
assert(n >= 0 && n < (int)obj->outlets->size());
- t_outlet *out = (*obj->outlets)[n];
+ t_outlet* out = (*obj->outlets)[n];
switch(l.a_type) {
case A_FLOAT: outlet_float(out,l.a_w.w_float); break;
case A_SYMBOL: outlet_symbol(out,l.a_w.w_symbol); break;
@@ -631,15 +383,7 @@ static void PD_OutletAtom(t_clr *obj,int n,t_atom l)
}
}
-static void PD_OutletAnything(t_clr *obj,int n,t_symbol *s,AtomList l)
-{
- assert(obj);
- assert(obj->outlets);
- assert(n >= 0 && n < (int)obj->outlets->size());
- outlet_anything((*obj->outlets)[n],s,l.argc,l.argv);
-}
-
-static void PD_OutletAnything2(t_clr *obj,int n,t_symbol *s,MonoArray *l)
+static void CALL PD_OutletAnything(t_instance *obj,int n,t_symbol *s,MonoArray *l)
{
assert(obj);
assert(obj->outlets);
@@ -649,50 +393,68 @@ static void PD_OutletAnything2(t_clr *obj,int n,t_symbol *s,MonoArray *l)
}
-static void PD_OutletObject(t_clr *obj,int n,MonoObject *o)
+static void CALL PD_OutletObject(t_instance *obj,int n,MonoObject *o)
{
assert(obj);
assert(obj->outlets);
assert(n >= 0 && n < (int)obj->outlets->size());
- ObjectAtom oa(o);
+ guint32 hnd = mono_gchandle_new(o,TRUE);
+ ObjectAtom<guint32> oa(hnd);
outlet_anything((*obj->outlets)[n],sym_object,oa.size,oa);
+ mono_gchandle_free(hnd);
}
-static void PD_SendAtom(t_symbol *dst,t_atom a)
+static void CALL PD_SendAtom(t_symbol *dst,t_atom a)
{
void *cl = dst->s_thing;
if(cl) pd_forwardmess((t_class **)cl,1,&a);
}
-static void PD_SendAnything(t_symbol *dst,t_symbol *s,AtomList l)
-{
- void *cl = dst->s_thing;
- if(cl) pd_typedmess((t_class **)cl,s,l.argc,l.argv);
-}
-
-static void PD_SendAnything2(t_symbol *dst,t_symbol *s,MonoArray *l)
+static void CALL PD_SendAnything(t_symbol *dst,t_symbol *s,MonoArray *l)
{
void *cl = dst->s_thing;
// assert(mono_object_get_class(&l->obj) == clr_atom);
if(cl) pd_typedmess((t_class **)cl,s,mono_array_length(l),mono_array_addr(l,t_atom,0));
}
-static void PD_SendObject(t_symbol *dst,MonoObject *o)
+static void CALL PD_SendObject(t_symbol *dst,MonoObject *o)
{
void *cl = dst->s_thing;
// assert(mono_object_get_class(&l->obj) == clr_atom);
if(cl) {
- ObjectAtom oa(o);
+ guint32 hnd = mono_gchandle_new(o,TRUE);
+ ObjectAtom<guint32> oa(hnd);
pd_typedmess((t_class **)cl,sym_object,oa.size,oa);
+ mono_gchandle_free(hnd);
}
}
+static MonoString *CALL PD_SearchPath(MonoString *file)
+{
+ char *filestr = mono_string_to_utf8(file);
+ char dirbuf[MAXPDSTRING],*nameptr;
+ // search for classname.dll in the PD path
+ int fd;
+ if ((fd = open_via_path("",filestr,"",dirbuf, &nameptr, MAXPDSTRING, 1)) >= 0) {
+ // found
+ if(dirbuf != nameptr) {
+ // fix for the fact that open_via_path doesn't return a path, when it's found in .
+ strcat(dirbuf,"/");
+ strcat(dirbuf,filestr);
+
+// close(fd); // strange - we get an assertion failure here...
+ }
+ return mono_string_new(monodomain,dirbuf);
+ }
+ else
+ return mono_string_new(monodomain,"");
+}
+
void *clr_new(t_symbol *classname, int argc, t_atom *argv)
{
- // find class name in map
-
+ // find class name in map
ClrMap::iterator it = clr_map.find(classname);
if(it == clr_map.end()) {
error("CLR - class %s not found",classname->s_name);
@@ -702,51 +464,37 @@ void *clr_new(t_symbol *classname, int argc, t_atom *argv)
t_clr_class *clss = it->second;
// make instance
- t_clr *x = (t_clr *)pd_new(clss->pd_class);
- x->mono_obj = mono_object_new (monodomain,clss->mono_class);
- if(!x->mono_obj) {
- pd_free((t_pd *)x);
- error("CLR - class %s could not be instantiated",classname->s_name);
- return NULL;
- }
-
- // store class pointer
- x->clr_clss = clss;
- x->clr_clss->name = classname;
-
- // store our object pointer in External::ptr member
- mono_field_set_value(x->mono_obj,clss->obj_field,x);
-
+ t_instance *x = (t_instance *)pd_new(clss->pd_class);
+ x->pd_class = clss;
x->outlets = NULL;
x->proxies = NULL;
- // ok, we have an object - look for constructor
- if(clss->mono_ctor) {
- // reset inlet index
- clr_inlet = 0;
+ clr_inlet = 0;
- AtomList al;
- al.Set(argc,argv);
- gpointer args = &al;
+ assert(newinstance);
- // call constructor
- MonoObject *exc;
- mono_runtime_invoke(clss->mono_ctor,x->mono_obj,&args,&exc);
-
- if(exc) {
- pd_free((t_pd *)x);
- error_exc("exception raised in constructor",classname->s_name,exc);
- return NULL;
- }
- }
- else
- verbose(1,"CLR - Warning: no constructor for class %s found",classname->s_name);
+ clr_pass->klass = clss->mono_class;
+ newinstance(x,AtomList(argc,argv));
+ x->mono_obj = clr_pass->ext;
+#ifdef _DEBUG
+ clr_pass->klass = NULL;
+#endif
- return x;
+ if(x->mono_obj) {
+ x->mono_handle = mono_gchandle_new(x->mono_obj,TRUE);
+ return x;
+ }
+ else {
+ pd_free((t_pd *)x);
+ error("CLR - class %s could not be instantiated",classname->s_name);
+ return NULL;
+ }
}
-void clr_free(t_clr *obj)
+void clr_free(t_instance *obj)
{
+ mono_gchandle_free(obj->mono_handle);
+
if(obj->outlets) delete obj->outlets;
if(obj->proxies) {
@@ -755,129 +503,67 @@ void clr_free(t_clr *obj)
}
}
-static int classloader(char *dirname, char *classname, char *altname)
+static void CALL PD_Register(MonoDelegate *d_class,MonoDelegate *d_new,MonoDelegate *d_bang,MonoDelegate *d_float,MonoDelegate *d_symbol,MonoDelegate *d_pointer,MonoDelegate *d_list,MonoDelegate *d_anything,MonoDelegate *d_object)
{
- t_clr_class *clr_class = NULL;
- t_symbol *classsym;
- MonoAssembly *assembly;
- MonoImage *image;
- MonoMethod *method;
- int flags = CLASS_DEFAULT;
-
- char *realname;
- char dirbuf[MAXPDSTRING],*nameptr;
- // search for classname.dll in the PD path
- int fd;
- if ((fd = open_via_path(dirname, realname = classname, "." DLLEXT, dirbuf, &nameptr, MAXPDSTRING, 1)) < 0)
- if (!altname || (fd = open_via_path(dirname, realname = altname, "." DLLEXT, dirbuf, &nameptr, MAXPDSTRING, 1)) < 0)
- // not found
- goto bailout;
-
- // found
- close(fd);
-
- clr_class = (t_clr_class *)getbytes(sizeof(t_clr_class));
- // set all struct members to 0
- memset(clr_class,0,sizeof(*clr_class));
-
- // try to load assembly
- strcat(dirbuf,"/");
- strcat(dirbuf,realname);
- strcat(dirbuf,"." DLLEXT);
+ newclass = (NewClass *)mono_delegate_to_ftnptr(d_class);
+ newinstance = (NewInstance *)mono_delegate_to_ftnptr(d_new);
+ callbang = (CallBang *)mono_delegate_to_ftnptr(d_bang);
+ callfloat = (CallFloat *)mono_delegate_to_ftnptr(d_float);
+ callsymbol = (CallSymbol *)mono_delegate_to_ftnptr(d_symbol);
+ callpointer = (CallPointer *)mono_delegate_to_ftnptr(d_pointer);
+ calllist = (CallList *)mono_delegate_to_ftnptr(d_list);
+ callanything = (CallAnything *)mono_delegate_to_ftnptr(d_anything);
+ callobject = (CallObject *)mono_delegate_to_ftnptr(d_object);
+}
- assembly = mono_domain_assembly_open(monodomain,dirbuf);
- if(!assembly) {
- error("clr: file %s couldn't be loaded!",dirbuf);
- goto bailout;
+static bool CALL PD_RegisterClass(t_clr_class *c,t_symbol *classsym,int classflags,int methodflags)
+{
+ assert(c && !c->pd_class);
+ c->pd_class = class_new(classsym,(t_newmethod)clr_new,(t_method)clr_free, sizeof(t_instance), classflags, A_GIMME, A_NULL);
+ if(c->pd_class) {
+ if(methodflags&0x01) class_addbang(c->pd_class,clr_method_bang);
+ if(methodflags&0x02) class_addfloat(c->pd_class,clr_method_float);
+ if(methodflags&0x04) class_addsymbol(c->pd_class,clr_method_symbol);
+ if(methodflags&0x08) class_addpointer(c->pd_class,clr_method_pointer);
+ if(methodflags&0x10) class_addlist(c->pd_class,clr_method_list);
+ if(methodflags&0x20) class_addanything(c->pd_class,clr_method_anything);
+ return true;
}
+ else
+ return false;
+}
- image = mono_assembly_get_image(assembly);
- assert(image);
- // try to find class
- // "" means no namespace
- clr_class->mono_class = mono_class_from_name(image,"",realname);
- if(!clr_class->mono_class) {
- error("Can't find %s class in %s\n",classname,mono_image_get_filename(image));
- goto bailout;
+static int classloader(char *dirname, char *classname, char *altname)
+{
+ if(!newclass) {
+ post("CLR - Entry point not set");
+ return 0;
}
- // make new class (with classname)
- classsym = gensym(classname);
- clr_class->pd_class = NULL;
-
- clr_class->obj_field = mono_class_get_field_from_name(clr_class->mono_class,"ptr");
- assert(clr_class->obj_field);
-
- // find static Setup method
- MonoMethodDesc *clr_desc_main = mono_method_desc_new("::Setup",FALSE);
- assert(clr_desc_main);
+ t_symbol *classsym = gensym(classname);
- method = mono_method_desc_search_in_class(clr_desc_main,clr_class->mono_class);
- if(method) {
- MonoObject *obj = mono_object_new(monodomain,clr_class->mono_class);
- if(!obj) {
- error("CLR class %s could not be instantiated",classname);
- goto bailout;
- }
-
- // store NULL in External::ptr member
- mono_field_set_value(obj,clr_class->obj_field,NULL);
-
- // set current class
- clr_setup_class = clr_class;
+ t_clr_class *classdef = (t_clr_class *)getbytes(sizeof(t_clr_class));
+ // set all struct members to 0
+ memset(classdef,0,sizeof(t_clr_class));
- // call static Setup method
- gpointer args = obj;
- MonoObject *exc;
- MonoObject *ret = mono_runtime_invoke(method,NULL,&args,&exc);
- if(ret) {
- // \TODO check return type
- flags = *(int *)mono_object_unbox(ret);
- }
+ newclass(classdef,classsym);
+ classdef->mono_class = clr_pass->klass;
- // unset current class
- clr_setup_class = NULL;
+ if(!classdef->mono_class)
+ {
+ freebytes(classdef,sizeof(t_clr_class));
+ return 0;
+ }
- if(exc) {
- error_exc("CLR - Exception raised by Setup",classname,exc);
- goto bailout;
- }
- }
- else
- post("CLR - Warning: no %s.Setup method found",classname);
-
- // find and save constructor
- clr_class->mono_ctor = mono_method_desc_search_in_class(clr_desc_ctor,clr_class->mono_class);
-
- // make pd class
- clr_class->pd_class = class_new(classsym,(t_newmethod)clr_new,(t_method)clr_free, sizeof(t_clr), flags, A_GIMME, A_NULL);
-
- // register methods
- if(clr_class->method_bang)
- class_addbang(clr_class->pd_class,clr_method_bang);
- if(clr_class->method_float)
- class_addfloat(clr_class->pd_class,clr_method_float);
- if(clr_class->method_symbol)
- class_addsymbol(clr_class->pd_class,clr_method_symbol);
- if(clr_class->method_pointer)
- class_addpointer(clr_class->pd_class,clr_method_pointer);
- if(clr_class->method_list)
- class_addlist(clr_class->pd_class,clr_method_list);
- if(clr_class->method_anything || clr_class->methods)
- class_addanything(clr_class->pd_class,clr_method_anything);
+ mono_gchandle_new(classdef->mono_class,TRUE); // we don't remember the handle... won't be freed later
// put into map
- clr_map[classsym] = clr_class;
+ clr_map[classsym] = classdef;
verbose(1,"CLR - Loaded class %s OK",classname);
return 1;
-
-bailout:
- if(clr_class) freebytes(clr_class,sizeof(t_clr_class));
-
- return 0;
}
extern "C"
@@ -902,26 +588,29 @@ void clr_setup(void)
mono_set_dirs(tlib,tconf);
#endif
+ // try to find PureData.dll in the PD path
+ char dirbuf[MAXPDSTRING],*nameptr;
+ // search in the PD path
+ int fd;
+ if ((fd = open_via_path("",CORELIB,"." DLLEXT,dirbuf,&nameptr,MAXPDSTRING,1)) >= 0) {
+ if(dirbuf != nameptr) // fix for the fact that open_via_path doesn't return a path, when it's found in .
+ strcat(dirbuf,"/" CORELIB "." DLLEXT);
+// close(fd); // strange - we get an assertion failure here...
+ }
+ else {
+ error("CLR - " CORELIB "." DLLEXT " not found in path");
+ return;
+ }
+
try {
- monodomain = mono_jit_init(CORELIB);
+ monodomain = mono_jit_init(dirbuf);
}
catch(...) {
monodomain = NULL;
}
- if(monodomain) {
- // try to find PureData.dll in the PD path
- char dirbuf[MAXPDSTRING],*nameptr;
- // search in the PD path
- int fd;
- if ((fd = open_via_path("",CORELIB,"." DLLEXT,dirbuf,&nameptr,MAXPDSTRING,1)) >= 0) {
- if(dirbuf != nameptr) // fix for the fact that open_via_path doesn't return a path, when it's found in .
- strcat(dirbuf,"/" CORELIB "." DLLEXT);
- close(fd);
- }
- else
- strcpy(dirbuf,CORELIB "." DLLEXT);
+ if(monodomain) {
// look for PureData.dll
MonoAssembly *assembly = mono_domain_assembly_open (monodomain,dirbuf);
if(!assembly) {
@@ -935,92 +624,43 @@ void clr_setup(void)
// add mono to C hooks
mono_add_internal_call("PureData.Internal::SymGen(string)", (const void *)PD_SymGen);
- mono_add_internal_call("PureData.Internal::SymEval(void*)", (const void *)PD_SymEval);
-
- mono_add_internal_call("PureData.External::Post(string)",(const void *)PD_Post);
- mono_add_internal_call("PureData.External::PostError(string)",(const void *)PD_PostError);
- mono_add_internal_call("PureData.External::PostVerbose(int,string)",(const void *)PD_PostVerbose);
-
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/Method)", (const void *)PD_AddMethodBang);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodFloat)", (const void *)PD_AddMethodFloat);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodSymbol)", (const void *)PD_AddMethodSymbol);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodPointer)", (const void *)PD_AddMethodPointer);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodList)", (const void *)PD_AddMethodList);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodAnything)", (const void *)PD_AddMethodAnything);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.Symbol,PureData.External/Method)", (const void *)PD_AddMethodSelBang);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.Symbol,PureData.External/MethodFloat)", (const void *)PD_AddMethodSelFloat);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.Symbol,PureData.External/MethodSymbol)", (const void *)PD_AddMethodSelSymbol);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.Symbol,PureData.External/MethodPointer)", (const void *)PD_AddMethodSelPointer);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.Symbol,PureData.External/MethodList)", (const void *)PD_AddMethodSelList);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.Symbol,PureData.External/MethodAnything)", (const void *)PD_AddMethodSelAnything);
- mono_add_internal_call("PureData.External::AddMethod(int,PureData.External/MethodObject)", (const void *)PD_AddMethodObject);
-
- mono_add_internal_call("PureData.Internal::AddInlet(void*,PureData.Symbol,PureData.Symbol)", (const void *)PD_AddInletAlias);
- mono_add_internal_call("PureData.Internal::AddInlet(void*,single&)", (const void *)PD_AddInletFloat);
- mono_add_internal_call("PureData.Internal::AddInlet(void*,PureData.Symbol&)", (const void *)PD_AddInletSymbol);
-// mono_add_internal_call("PureData.Internal::AddInlet(void*,PureData.Pointer&)", (const void *)PD_AddInletPointer);
-// mono_add_internal_call("PureData.Internal::AddInlet(void*,PureData.Symbol)", (const void *)PD_AddInletTyped);
- mono_add_internal_call("PureData.Internal::AddInlet(void*)", (const void *)PD_AddInletProxy);
-
- mono_add_internal_call("PureData.Internal::AddOutlet(void*,PureData.Symbol)", (const void *)PD_AddOutlet);
-
- mono_add_internal_call("PureData.Internal::Outlet(void*,int)", (const void *)PD_OutletBang);
- mono_add_internal_call("PureData.Internal::Outlet(void*,int,single)", (const void *)PD_OutletFloat);
- mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Symbol)", (const void *)PD_OutletSymbol);
- mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Pointer)", (const void *)PD_OutletPointer);
- mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Atom)", (const void *)PD_OutletAtom);
- mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Symbol,PureData.AtomList)", (const void *)PD_OutletAnything);
- mono_add_internal_call("PureData.Internal::Outlet(void*,int,PureData.Symbol,PureData.Atom[])", (const void *)PD_OutletAnything2);
- mono_add_internal_call("PureData.Internal::OutletEx(void*,int,object)", (const void *)PD_OutletObject);
-
-// mono_add_internal_call("PureData.Internal::Bind(void*,PureData.Symbol)", (const void *)PD_Bind);
-// mono_add_internal_call("PureData.Internal::Unbind(void*,PureData.Symbol)", (const void *)PD_Unbind);
+ mono_add_internal_call("PureData.Internal::SymEval(PureData.Symbol)", (const void *)PD_SymEval);
+
+ mono_add_internal_call("PureData.Public::Post(string)",(const void *)PD_Post);
+ mono_add_internal_call("PureData.Public::PostError(string)",(const void *)PD_PostError);
+ mono_add_internal_call("PureData.Public::PostVerbose(int,string)",(const void *)PD_PostVerbose);
+ mono_add_internal_call("PureData.Public::SearchPath(string)",(const void *)PD_SearchPath);
+
+ mono_add_internal_call("PureData.Internal::AddInlet(PureData.ExternalPtr,PureData.Symbol,PureData.Symbol)", (const void *)PD_AddInletAlias);
+ mono_add_internal_call("PureData.Internal::AddInlet(PureData.ExternalPtr,single&)", (const void *)PD_AddInletFloat);
+ mono_add_internal_call("PureData.Internal::AddInlet(PureData.ExternalPtr,PureData.Symbol&)", (const void *)PD_AddInletSymbol);
+// mono_add_internal_call("PureData.Internal::AddInlet(PureData.ExternalPtr,PureData.Pointer&)", (const void *)PD_AddInletPointer);
+// mono_add_internal_call("PureData.Internal::AddInlet(PureData.ExternalPtr,PureData.Symbol)", (const void *)PD_AddInletTyped);
+ mono_add_internal_call("PureData.Internal::AddInlet(PureData.ExternalPtr)", (const void *)PD_AddInletProxy);
+
+ mono_add_internal_call("PureData.Internal::AddOutlet(PureData.ExternalPtr,PureData.Symbol)", (const void *)PD_AddOutlet);
+
+ mono_add_internal_call("PureData.Internal::Outlet(PureData.ExternalPtr,int)", (const void *)PD_OutletBang);
+ mono_add_internal_call("PureData.Internal::Outlet(PureData.ExternalPtr,int,single)", (const void *)PD_OutletFloat);
+ mono_add_internal_call("PureData.Internal::Outlet(PureData.ExternalPtr,int,PureData.Symbol)", (const void *)PD_OutletSymbol);
+ mono_add_internal_call("PureData.Internal::Outlet(PureData.ExternalPtr,int,PureData.Pointer)", (const void *)PD_OutletPointer);
+ mono_add_internal_call("PureData.Internal::Outlet(PureData.ExternalPtr,int,PureData.Atom)", (const void *)PD_OutletAtom);
+ mono_add_internal_call("PureData.Internal::Outlet(PureData.ExternalPtr,int,PureData.Symbol,PureData.Atom[])", (const void *)PD_OutletAnything);
+ mono_add_internal_call("PureData.Internal::OutletEx(PureData.ExternalPtr,int,object)", (const void *)PD_OutletObject);
+
+// mono_add_internal_call("PureData.Internal::Bind(PureData.ExternalPtr,PureData.Symbol)", (const void *)PD_Bind);
+// mono_add_internal_call("PureData.Internal::Unbind(PureData.ExternalPtr,PureData.Symbol)", (const void *)PD_Unbind);
+
+ mono_add_internal_call("PureData.Class::Register(PureData.Class/DelegateClass,PureData.Class/DelegateNew,PureData.Class/DelegateBang,PureData.Class/DelegateFloat,PureData.Class/DelegateSymbol,PureData.Class/DelegatePointer,PureData.Class/DelegateList,PureData.Class/DelegateAnything,PureData.Class/DelegateObject)", (const void *)PD_Register);
+ mono_add_internal_call("PureData.Class::RegisterClass(PureData.ClassPtr,PureData.Symbol,PureData.Public/ClassType,PureData.Class/MethodFlags)", (const void *)PD_RegisterClass);
+// mono_add_internal_call("PureData.Class::AddMethodIntern(PureData.ClassPtr,int,PureData.Symbol,PureData.Class/Kind,System.Delegate)", (const void *)PD_AddMethodIntern);
mono_add_internal_call("PureData.External::Send(PureData.Symbol,PureData.Atom)", (const void *)PD_SendAtom);
- mono_add_internal_call("PureData.External::Send(PureData.Symbol,PureData.Symbol,PureData.AtomList)", (const void *)PD_SendAnything);
- mono_add_internal_call("PureData.External::Send(PureData.Symbol,PureData.Symbol,PureData.Atom[])", (const void *)PD_SendAnything2);
+ mono_add_internal_call("PureData.External::Send(PureData.Symbol,PureData.Symbol,PureData.Atom[])", (const void *)PD_SendAnything);
mono_add_internal_call("PureData.External::SendEx(PureData.Symbol,object)", (const void *)PD_SendObject);
- // load important classes
- clr_symbol = mono_class_from_name(image,"PureData","Symbol");
- assert(clr_symbol);
- clr_pointer = mono_class_from_name(image,"PureData","Pointer");
- assert(clr_pointer);
- clr_atom = mono_class_from_name(image,"PureData","Atom");
- assert(clr_atom);
- clr_atomlist = mono_class_from_name(image,"PureData","AtomList");
- assert(clr_atomlist);
- clr_external = mono_class_from_name(image,"PureData","External");
- assert(clr_external);
-
- clr_desc_tostring = mono_method_desc_new("::ToString()",FALSE);
- assert(clr_desc_tostring);
- clr_desc_ctor = mono_method_desc_new("::.ctor(AtomList)",FALSE);
- assert(clr_desc_ctor);
-
- MonoMethodDesc *desc = mono_method_desc_new("System.Reflection.MethodBase:Invoke(object,object[])",FALSE);
- clr_meth_invoke = mono_method_desc_search_in_image(desc,mono_get_corlib());
-
- MonoClass *delegate = mono_class_from_name(mono_get_corlib(),"System","Delegate");
- assert(delegate);
- clr_prop_method = mono_class_get_property_from_name(delegate,"Method");
- assert(clr_prop_method);
-
- // static objects to avoid allocation at method call time
- clr_objarr_1 = mono_array_new(monodomain,mono_get_object_class(),1);
- clr_objarr_2 = mono_array_new(monodomain,mono_get_object_class(),2);
- clr_objarr_3 = mono_array_new(monodomain,mono_get_object_class(),3);
- clr_obj_int = mono_object_new(monodomain,mono_get_int32_class());
- clr_obj_single = mono_object_new(monodomain,mono_get_single_class());
- clr_obj_symbol = mono_object_new(monodomain,clr_symbol);
- clr_obj_pointer = mono_object_new(monodomain,clr_pointer);
- clr_obj_atomlist = mono_object_new(monodomain,clr_atomlist);
- // unboxed addresses
- clr_val_int = (int *)mono_object_unbox(clr_obj_int);
- clr_val_single = (float *)mono_object_unbox(clr_obj_single);
- clr_val_symbol = (t_symbol **)mono_object_unbox(clr_obj_symbol);
- clr_val_pointer = (void **)mono_object_unbox(clr_obj_pointer);
- clr_val_atomlist = (AtomList *)mono_object_unbox(clr_obj_atomlist);
+
+ ///////////////////////////////////////////////////////////
// make proxy class
proxy_class = class_new(gensym("clr proxy"),NULL,NULL,sizeof(t_proxy),CLASS_PD|CLASS_NOINLET,A_NULL);
@@ -1032,8 +672,31 @@ void clr_setup(void)
// install loader hook
sys_register_loader(classloader);
- // ready!
- post("CLR extension - (c)2006 Davide Morelli, Thomas Grill");
+ ///////////////////////////////////////////////////////////
+
+ // call static Class::Setup function
+ MonoClass *clr_class = mono_class_from_name(image,"PureData","Class");
+ assert(clr_class);
+ MonoMethodDesc *desc = mono_method_desc_new("::Setup()",FALSE);
+ MonoMethod *setup = mono_method_desc_search_in_class(desc,clr_class);
+
+ MonoObject *exc;
+ mono_runtime_invoke(setup,NULL,NULL,&exc);
+ if(exc)
+ post("CLR - setup function failed");
+ else {
+ // ready!
+ post("CLR extension - (c)2006 Davide Morelli, Thomas Grill");
+ }
+
+ // necessary data should have been set by Setup
+ MonoClass *clr_internal = mono_class_from_name(image,"PureData","Internal");
+ assert(clr_internal);
+ MonoVTable *clr_internal_vt = mono_class_vtable(monodomain,clr_internal);
+ MonoClassField *fld = mono_class_get_field_from_name (clr_internal,"pass");
+ assert(fld);
+ mono_field_static_get_value(clr_internal_vt,fld,&clr_pass);
+ assert(clr_pass);
}
else
error("clr: mono domain couldn't be initialized!");