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:
Oliver Buchtala 2012-09-08 01:15:12 +00:00
commit 7c7d1cf3b9
3 changed files with 87 additions and 28 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);
}
}