Fix errors related to wrapping and destruction of (undefined) SWIG_TYPES.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13824 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
296a5d0285
commit
7c7d1cf3b9
3 changed files with 87 additions and 28 deletions
|
|
@ -52,7 +52,7 @@ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) {
|
|||
SWIGV8_Proxy* proxy = (SWIGV8_Proxy*) parameter;
|
||||
if(proxy->swigCMemOwn && proxy->swigCObject) {
|
||||
std::cout << "Deleting wrapped instance: " << proxy->info->name << std::endl;
|
||||
delete ($jstype*) proxy->swigCObject;
|
||||
$jsfree proxy->swigCObject;
|
||||
}
|
||||
delete proxy;
|
||||
}
|
||||
|
|
@ -150,7 +150,7 @@ fail:
|
|||
%{v8::Handle<v8::FunctionTemplate> $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname");
|
||||
$jsmangledname_clientData.class_templ = $jsmangledname_class;
|
||||
$jsmangledname_clientData.dtor = $jsdtor;
|
||||
SWIGTYPE_p$jsmangledtype->clientdata = &$jsmangledname_clientData;%}
|
||||
SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData;%}
|
||||
|
||||
%fragment("jsv8_inherit", "templates")
|
||||
%{$jsmangledname_class->Inherit($jsbaseclass_class);%}
|
||||
|
|
@ -194,6 +194,8 @@ void $jsname_initialize(v8::Handle<v8::Context> context)
|
|||
v8::HandleScope scope;
|
||||
v8::Local<v8::Object> global_obj = context->Global();
|
||||
|
||||
SWIGV8_SWIGTYPE_Proxy_class_templ = SWIGV8_CreateClassTemplate("SwigProxy");
|
||||
|
||||
/* create objects for namespaces */
|
||||
$jsv8nspaces
|
||||
|
||||
|
|
|
|||
|
|
@ -86,10 +86,8 @@ public:
|
|||
void (*dtor) (v8::Persistent< v8::Value > object, void *parameter);
|
||||
};
|
||||
|
||||
%}
|
||||
v8::Persistent<v8::FunctionTemplate> SWIGV8_SWIGTYPE_Proxy_class_templ;
|
||||
|
||||
|
||||
%insert(runtime) %{
|
||||
int SWIG_V8_ConvertInstancePtr(v8::Handle<v8::Object> objRef, void** ptr, swig_type_info *info, int flags) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
|
|
@ -120,14 +118,27 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle<v8::Object> objRef, void** ptr, swig_t
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) {
|
||||
SWIGV8_Proxy* proxy = (SWIGV8_Proxy*) parameter;
|
||||
if(proxy) {
|
||||
delete proxy;
|
||||
}
|
||||
}
|
||||
|
||||
void SWIGV8_SetPrivateData(v8::Handle<v8::Object> obj, void* ptr, swig_type_info *info, int flags) {
|
||||
SWIGV8_Proxy* cdata = new SWIGV8_Proxy();
|
||||
cdata->swigCObject = ptr;
|
||||
cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0;
|
||||
cdata->info = info;
|
||||
obj->SetPointerInInternalField(0, cdata);
|
||||
|
||||
v8::Persistent<v8::Object> weakptr = v8::Persistent<v8::Object>::New(obj);
|
||||
weakptr.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
|
||||
// clientdata must be set for owned data as we need to register the dtor
|
||||
if(cdata->swigCMemOwn) {
|
||||
weakptr.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
|
||||
} else {
|
||||
weakptr.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor);
|
||||
}
|
||||
}
|
||||
|
||||
int SWIG_V8_ConvertPtr(v8::Handle<v8::Value> valRef, void** ptr, swig_type_info *info, int flags) {
|
||||
|
|
@ -142,8 +153,13 @@ int SWIG_V8_ConvertPtr(v8::Handle<v8::Value> valRef, void** ptr, swig_type_info
|
|||
|
||||
v8::Handle<v8::Object> SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) {
|
||||
v8::HandleScope scope;
|
||||
|
||||
v8::Handle<v8::FunctionTemplate> class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ;
|
||||
|
||||
v8::Handle<v8::FunctionTemplate> class_templ;
|
||||
if(info->clientdata != 0) {
|
||||
class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ;
|
||||
} else {
|
||||
class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ;
|
||||
}
|
||||
v8::Handle<v8::Object> result = class_templ->InstanceTemplate()->NewInstance();
|
||||
SWIGV8_SetPrivateData(result, ptr, info, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ bool js_template_enable_debug = false;
|
|||
#define T_ARGCOUNT "$jsargcount"
|
||||
#define T_LOCALS "$jslocals"
|
||||
#define T_CODE "$jscode"
|
||||
#define T_FREE "$jsfree"
|
||||
|
||||
// v8 specific variables used in templates
|
||||
#define V8_NAME_SPACES "$jsv8nspaces"
|
||||
|
|
@ -269,6 +270,8 @@ protected:
|
|||
|
||||
virtual void marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, const String *cresult=0, bool emitReturnVariable = true);
|
||||
|
||||
void registerProxyType(SwigType* type);
|
||||
|
||||
/**
|
||||
* Helper function to retrieve the first parent class node.
|
||||
*/
|
||||
|
|
@ -281,6 +284,7 @@ protected:
|
|||
virtual Hash *createNamespaceEntry(const char *name, const char *parent);
|
||||
|
||||
virtual int emitNamespaces() = 0;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
|
@ -865,12 +869,27 @@ int JSEmitter::emitDtor(Node *n) {
|
|||
|
||||
Template t_dtor = getTemplate("JS_destructordefn");
|
||||
String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
|
||||
|
||||
SwigType *type = state.clazz(TYPE);
|
||||
String *p_classtype = SwigType_add_pointer(state.clazz(TYPE));
|
||||
String *ctype = SwigType_lstr(p_classtype, "");
|
||||
String *free = NewString("");
|
||||
if(SwigType_isarray(type)) {
|
||||
Printf(free, "delete [] (%s)", ctype);
|
||||
} else {
|
||||
Printf(free, "delete (%s)", ctype);
|
||||
}
|
||||
|
||||
state.clazz(DTOR, wrap_name);
|
||||
t_dtor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED))
|
||||
.replace(T_WRAPPER, wrap_name)
|
||||
.replace(T_TYPE, state.clazz(TYPE))
|
||||
.replace(T_FREE, free)
|
||||
.pretty_print(f_wrappers);
|
||||
|
||||
Delete(p_classtype);
|
||||
Delete(ctype);
|
||||
Delete(free);
|
||||
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1050,15 +1069,30 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) {
|
|||
return SWIG_OK;
|
||||
}
|
||||
|
||||
void JSEmitter::registerProxyType(SwigType* type) {
|
||||
SwigType *ftype = SwigType_typedef_resolve_all(type);
|
||||
|
||||
// register undefined wrappers
|
||||
int needs_proxy= (SwigType_ispointer(ftype)
|
||||
|| SwigType_isarray(ftype) || SwigType_isreference(ftype))
|
||||
&& !(Language::instance()->classLookup(ftype));
|
||||
if (needs_proxy) {
|
||||
SwigType_remember_clientdata(ftype, 0);
|
||||
Setattr(undefined_types, SwigType_manglestr(ftype), ftype);
|
||||
} else {
|
||||
Delete(ftype);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) {
|
||||
// Get input typemap for current param
|
||||
String *tm = Getattr(p, "tmap:in");
|
||||
SwigType *pt = Getattr(p, "type");
|
||||
|
||||
SwigType *type = Getattr(p, "type");
|
||||
|
||||
if (tm != NULL) {
|
||||
Replaceall(tm, "$input", arg);
|
||||
Setattr(p, "emit:input", arg);
|
||||
|
||||
// do replacements for built-in variables
|
||||
if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
|
||||
Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
|
||||
|
|
@ -1068,28 +1102,24 @@ void JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg
|
|||
Replaceall(tm, "$symname", Getattr(n, "sym:name"));
|
||||
Printf(wrapper->code, "%s\n", tm);
|
||||
} else {
|
||||
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
|
||||
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) {
|
||||
SwigType *type = Getattr(n, "type");
|
||||
Setattr(n, "type", type);
|
||||
String *tm;
|
||||
|
||||
// register undefined wrappers
|
||||
if (SwigType_ispointer(type) && !Language::instance()->classLookup(type)) {
|
||||
SwigType_remember_clientdata(type, 0);
|
||||
Setattr(undefined_types, SwigType_manglestr(type), type);
|
||||
}
|
||||
|
||||
// adds a declaration for the result variable
|
||||
if(emitReturnVariable) emit_return_variable(n, type, wrapper);
|
||||
|
||||
// if not given, use default result identifier ('result') for output typemap
|
||||
if(cresult == 0) cresult = defaultResultName;
|
||||
|
||||
if ((tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode))) {
|
||||
tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode);
|
||||
if(GetFlag(n, "feature:new")) {
|
||||
registerProxyType(type);
|
||||
}
|
||||
|
||||
if (tm) {
|
||||
Replaceall(tm, "$result", "jsresult");
|
||||
Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0)));
|
||||
|
||||
|
|
@ -1744,10 +1774,12 @@ int V8Emitter::exitClass(Node *n)
|
|||
SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), clientData);
|
||||
|
||||
// emit definition of v8 class template
|
||||
String *p_classtype = state.clazz(TYPE);
|
||||
String *p_classtype_str = SwigType_manglestr(p_classtype);
|
||||
Template t_def_class(getTemplate("jsv8_define_class_template"));
|
||||
t_def_class.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED))
|
||||
.replace(T_NAME, state.clazz(NAME))
|
||||
.replace(T_TYPE_MANGLED, SwigType_manglestr(Getattr(n, "classtype")))
|
||||
.replace(T_TYPE_MANGLED, p_classtype_str)
|
||||
.replace(T_DTOR, state.clazz(DTOR))
|
||||
.pretty_print(f_init_class_templates);
|
||||
|
||||
|
|
@ -1951,9 +1983,17 @@ void V8Emitter::emitUndefined() {
|
|||
Iterator ki;
|
||||
for (ki = First(undefined_types); ki.item; ki = Next(ki)) {
|
||||
String *mangled_name = ki.key;
|
||||
SwigType *type = ki.item;
|
||||
String *dtor = Swig_name_destroy("", mangled_name);
|
||||
SwigType *deref = SwigType_del_pointer(ki.item);
|
||||
String *type_mangled = SwigType_manglestr(ki.item);
|
||||
String *type_mangled = SwigType_manglestr(type);
|
||||
String *ctype = SwigType_lstr(type, "");
|
||||
|
||||
String *free = NewString("");
|
||||
if(SwigType_isarray(type)) {
|
||||
Printf(free, "delete [] (%s)", ctype);
|
||||
} else {
|
||||
Printf(free, "delete (%s)", ctype);
|
||||
}
|
||||
|
||||
// emit clientData declaration
|
||||
Template clientDataDecl = getTemplate("jsv8_declare_class_template");
|
||||
|
|
@ -1964,7 +2004,7 @@ void V8Emitter::emitUndefined() {
|
|||
Template t_dtor = getTemplate("JS_destructordefn");
|
||||
t_dtor.replace(T_NAME_MANGLED, mangled_name)
|
||||
.replace(T_WRAPPER, dtor)
|
||||
.replace(T_TYPE, deref)
|
||||
.replace(T_FREE, free)
|
||||
.pretty_print(f_wrappers);
|
||||
|
||||
// create a class template and initialize clientData
|
||||
|
|
@ -1976,8 +2016,9 @@ void V8Emitter::emitUndefined() {
|
|||
.pretty_print(f_init_class_templates);
|
||||
|
||||
Delete(dtor);
|
||||
Delete(deref);
|
||||
Delete(free);
|
||||
Delete(type_mangled);
|
||||
Delete(ctype);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue