diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index dfa51e143..51b49039c 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -58,21 +58,37 @@ JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectR } %} -/************************************************************************************** -function_dispatch_case: This template is used for the function which is overloaded -***************************************************************************************/ +%fragment ("JS_functionwrapper_overload", "templates") +%{ +int ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* result) +{ + ${LOCALS} + ${CODE} + *result = jsresult; + return SWIG_OK; + + goto fail; + fail: + return SWIG_TypeError; +} +%} + +/*********************************************************************** + * JS_function_dispatch_case: + * This template is used to create a branch for dispatching + * to an overloaded function. + ***********************************************************************/ %fragment ("JS_function_dispatch_case", "templates") %{if(argc == ${argcount}) { - jsresult = ${functionwrapper}(context, function, thisObject, argc, argv, exception); - } else %} + res = ${functionwrapper}(context, function, thisObject, argc, argv, exception, &jsresult); + if(res == SWIG_OK) { *exception = 0; return jsresult; } + } +%} %fragment ("JS_function_dispatch_case_default", "templates") %{ - { - // TODO: throw JS exception - throw "Invalid function arguments."; - } + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function ${functionname}."); %} /* Added template for function declaration */ @@ -173,18 +189,16 @@ void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) JSObjectRef _wrap_create_${classname_mangled}(JSContextRef context, JSObjectRef ctorObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { - JSObjectRef thisObject; + JSObjectRef thisObject = NULL; + // switch all cases by means of series of if-returns. ${DISPATCH_CASES} - { - // TODO: handle illegal arguments - SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of ${classname_mangled}"); - } - return thisObject; + // default: + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of ${classname_mangled}"); fail: - return NULL; + return thisObject; } %} @@ -195,7 +209,9 @@ ctor_dispatch_case: This template is used for the constructor which is overloade %fragment ("JS_ctor_dispatch_case", "templates") %{if(argc == ${argcount}) { thisObject = _wrap_create_${classname_mangled}${overloadext}(context, NULL, argc, argv, exception); - } else %} + if(thisObject != NULL) { *exception=0; return thisObject; } /* reset exception and return */ + } +%} %fragment ("JS_ctordefn", "templates") diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 69c5e4adf..72be9b4f0 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -70,6 +70,8 @@ public: Template& replace(const String *pattern, const String *repl); Template& pretty_print(DOH *doh); + + void operator=(const Template& t); private: @@ -1019,8 +1021,8 @@ int JSCEmitter::enterFunction(Node *n) { /* Initialize DOH for collecting function dispatchers */ bool is_overloaded = GetFlag(n, "sym:overloaded"); - if (is_overloaded && state.function(FUNCTION_DISPATCHERS) == 0) { - state.function(FUNCTION_DISPATCHERS, NewString("")); + if (is_overloaded && state.global(FUNCTION_DISPATCHERS) == 0) { + state.global(FUNCTION_DISPATCHERS, NewString("")); } return SWIG_OK; @@ -1333,6 +1335,7 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); if (is_overloaded) { Append(wrap_name, Getattr(n, "sym:overname")); + t_function = getTemplate("JS_functionwrapper_overload"); } Setattr(n, "wrap:name", wrap_name); state.function(WRAPPER_NAME, wrap_name); @@ -1364,7 +1367,7 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { t_dispatch_case.replace("${functionwrapper}", wrap_name) .replace("${argcount}", argcount); - Append(state.function(FUNCTION_DISPATCHERS), t_dispatch_case.str()); + Append(state.global(FUNCTION_DISPATCHERS), t_dispatch_case.str()); Delete(argcount); } @@ -1382,16 +1385,21 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); Setattr(n, "wrap:name", wrap_name); + Wrapper_add_local(wrapper, "res", "int res"); Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); - Append(wrapper->code, state.function(FUNCTION_DISPATCHERS)); + Append(wrapper->code, state.global(FUNCTION_DISPATCHERS)); Append(wrapper->code, getTemplate("JS_function_dispatch_case_default").str()); + t_function.replace("${LOCALS}", wrapper->locals) + .replace("${CODE}", wrapper->code); + + // call this here, to replace all variables t_function.replace("${functionname}", wrap_name) - .replace("${LOCALS}", wrapper->locals) - .replace("${CODE}", wrapper->code) .pretty_print(f_wrappers); + // Delete the state variable + state.global(FUNCTION_DISPATCHERS, 0); DelWrapper(wrapper); return SWIG_OK; @@ -2052,3 +2060,10 @@ Template& Template::pretty_print(DOH *doh) { Wrapper_pretty_print(str(), doh); return *this; } + +void Template::operator=(const Template& t) { + Delete(code); + Delete(templateName); + code = NewString(t.code); + templateName = NewString(t.templateName); +}