From: <ol...@us...> - 2012-09-08 00:58:17
|
Revision: 13767 http://swig.svn.sourceforge.net/swig/?rev=13767&view=rev Author: oliv3rb Date: 2012-09-08 00:58:11 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Switch to global variable for enabling code template debug information. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:57:57 UTC (rev 13766) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:58:11 UTC (rev 13767) @@ -12,6 +12,11 @@ * code fragments */ class Template; +/** + * Enables extra debugging information in typemaps. + */ +bool js_template_enable_debug = false; + class State { public: @@ -197,8 +202,6 @@ */ Template getTemplate(const String *name); - void enableDebug(); - void setStaticFlag(bool is_static = false); protected: @@ -246,12 +249,6 @@ Parm *skipIgnoredArgs(Parm *p); - /** - * Enables extra debugging information in typemaps. - * TODO: make this global/static... js_emitter_template_enable_debug - */ - void enableDebugTemplates(); - protected: // empty string used at different places in the code @@ -264,8 +261,6 @@ State state; bool is_static; - - bool debug; }; /* factory methods for concrete JSEmitters: */ @@ -525,7 +520,7 @@ } if (debug_templates) { - emitter->enableDebug(); + js_template_enable_debug = true; } // Add a symbol to the parser for conditional compilation @@ -595,8 +590,7 @@ JSEmitter::JSEmitter() : empty_string(NewString("")), current_wrapper(NULL), - is_static(false), - debug(false) + is_static(false) { templates = NewHash(); } @@ -630,7 +624,7 @@ SWIG_exit(EXIT_FAILURE); } - Template t(templ, name, debug); + Template t(templ, name, js_template_enable_debug); return t; } @@ -639,10 +633,6 @@ return SWIG_OK; } -void JSEmitter::enableDebug() { - debug = true; -} - void JSEmitter::setStaticFlag(bool _is_static) { is_static = _is_static; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ol...@us...> - 2012-09-08 00:58:29
|
Revision: 13768 http://swig.svn.sourceforge.net/swig/?rev=13768&view=rev Author: oliv3rb Date: 2012-09-08 00:58:23 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Remove a global variable from JSEmitter by making use of JSEmitterState. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:58:11 UTC (rev 13767) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:58:23 UTC (rev 13768) @@ -8,27 +8,40 @@ * JAVASCRIPT: swig module implementation **********************************************************************/ -/* forward decl: Template is a convenience helper class for dealing with - * code fragments */ -class Template; - /** * Enables extra debugging information in typemaps. */ bool js_template_enable_debug = false; -class State { +// keywords used for state variables + +#undef NAME +#define NAME "name" +#define NAME_MANGLED "name_mangled" +#define TYPE "type" +#define TYPE_MANGLED "type_mangled" +#define WRAPPER_NAME "wrapper" +#define IS_IMMUTABLE "is_immutable" +#define IS_STATIC "is_static" + +/** + * A convenience class to manage state variables for emitters. + * The implementation delegates to swig Hash DOHs and provides + * named sub-hashes for class, variable, and function states. + */ +class JSEmitterState { public: - State(): _global(NewHash()) { + JSEmitterState(): + _global(NewHash()) { // initialize sub-hashes Setattr(_global, "class", NewHash()); Setattr(_global, "function", NewHash()); Setattr(_global, "variable", NewHash()); } - ~State() { Delete(_global); } + ~JSEmitterState() { Delete(_global); } DOH *getState(const char* key, bool _new = false) { if (_new) { @@ -99,12 +112,20 @@ Hash *_global; }; +/* forward decl: Template is a convenience helper class for dealing with + * code fragments */ +class Template; + /** * JSEmitter represents an abstraction of javascript code generators * for different javascript engines. **/ class JSEmitter { +protected: + + typedef JSEmitterState State; + public: enum JSEmitterType { @@ -202,7 +223,7 @@ */ Template getTemplate(const String *name); - void setStaticFlag(bool is_static = false); + State &getState(); protected: @@ -259,8 +280,6 @@ Wrapper *current_wrapper; State state; - - bool is_static; }; /* factory methods for concrete JSEmitters: */ @@ -351,9 +370,9 @@ int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { // workaround: storage=static is not set for static member functions - emitter->setStaticFlag(true); + emitter->getState().function(IS_STATIC, NewString("1")); Language::staticmemberfunctionHandler(n); - emitter->setStaticFlag(false); + emitter->getState().function(IS_STATIC, NULL); return SWIG_OK; } @@ -575,22 +594,13 @@ bool debug; }; -#define __NAME__ "name" -#define NAME_MANGLED "name_mangled" -#define TYPE "type" -#define TYPE_MANGLED "type_mangled" -#define WRAPPER_NAME "wrapper" -#define IS_IMMUTABLE "is_immutable" -#define IS_STATIC "is_static" - /* ----------------------------------------------------------------------------- * JSEmitter() * ----------------------------------------------------------------------------- */ JSEmitter::JSEmitter() : empty_string(NewString("")), - current_wrapper(NULL), - is_static(false) + current_wrapper(NULL) { templates = NewHash(); } @@ -629,14 +639,14 @@ return t; } +JSEmitterState &JSEmitter::getState() { + return state; +} + int JSEmitter::initialize(Node *) { return SWIG_OK; } -void JSEmitter::setStaticFlag(bool _is_static) { - is_static = _is_static; -} - /* ----------------------------------------------------------------------------- * JSEmitter::typemapLookup() * @@ -753,7 +763,7 @@ int JSEmitter::enterClass(Node *n) { state.clazz(true); - state.clazz(__NAME__, Getattr(n, "sym:name")); + state.clazz(NAME, Getattr(n, "sym:name")); state.clazz(NAME_MANGLED, SwigType_manglestr(Getattr(n, "name"))); state.clazz(TYPE, NewString(Getattr(n, "classtype"))); @@ -769,14 +779,14 @@ int JSEmitter::enterFunction(Node *n) { state.function(true); - state.function(__NAME__, Getattr(n, "sym:name")); + state.function(NAME, Getattr(n, "sym:name")); return SWIG_OK; } int JSEmitter::enterVariable(Node *n) { state.variable(true); - state.variable(__NAME__, Swig_scopename_last(Getattr(n, "name"))); + state.variable(NAME, Swig_scopename_last(Getattr(n, "name"))); state.variable(IS_IMMUTABLE, Getattr(n, "wrap:immutable")); return SWIG_OK; } @@ -1238,7 +1248,7 @@ } } - t_function.replace("${functionname}", state.function(__NAME__)) + t_function.replace("${functionname}", state.function(NAME)) .replace("${functionwrapper}", state.function(WRAPPER_NAME)); if (is_member) { @@ -1268,7 +1278,7 @@ Template t_variable(getTemplate("JS_variabledecl")); t_variable.replace("${setname}", state.variable(SETTER)) .replace("${getname}", state.variable(GETTER)) - .replace("${propertyname}", state.variable(__NAME__)); + .replace("${propertyname}", state.variable(NAME)); if (GetFlag(n, "ismember")) { if (Equal(Getattr(n, "storage"), "static") || (Equal(Getattr(n, "nodeType"), "enumitem"))) { @@ -1341,7 +1351,7 @@ /* adds a class registration statement to initializer function */ Template t_registerclass(getTemplate("JS_register_class")); - t_registerclass.replace("${classname}", state.clazz(__NAME__)) + t_registerclass.replace("${classname}", state.clazz(NAME)) .replace("${classname_mangled}", state.clazz(NAME_MANGLED)) .replace("${namespace_mangled}", Getattr(current_namespace, "name_mangled")) .pretty_print(state.global(INITIALIZER)); @@ -1509,23 +1519,24 @@ // in these cases the context (staticmemberfunctionHandler) is // exploited and a flag is set temporarily // TODO: this could be done in general with is_member and is_static - bool is_static = JSEmitter::is_static || Equal(Getattr(n, "storage"), "static"); + bool is_static = State::IsSet(state.function(IS_STATIC)) || Equal(Getattr(n, "storage"), "static"); + bool is_overloaded = GetFlag(n, "sym:overloaded"); - bool is_overloaded = GetFlag(n, "sym:overloaded"); + // prepare the function wrapper name String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - if (is_overloaded) { Append(wrap_name, Getattr(n, "sym:overname")); } - Setattr(n, "wrap:name", wrap_name); state.function(WRAPPER_NAME, wrap_name); + // prepare local variables ParmList *params = Getattr(n, "parms"); emit_parameter_variables(params, current_wrapper); emit_attach_parmmaps(params, current_wrapper); Wrapper_add_local(current_wrapper, "jsresult", "JSValueRef jsresult"); + // prepare code part String *action = emit_action(n); marshalInputArgs(n, params, current_wrapper, Function, is_member, is_static); marshalOutput(n, action, current_wrapper); @@ -1535,6 +1546,7 @@ .replace("${CODE}", current_wrapper->code) .pretty_print(f_wrappers); + // handle function overloading if (is_overloaded) { Template t_dispatch_case = getTemplate("JS_function_dispatch_case"); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ol...@us...> - 2012-09-08 00:58:55
|
Revision: 13770 http://swig.svn.sourceforge.net/swig/?rev=13770&view=rev Author: oliv3rb Date: 2012-09-08 00:58:49 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Remove member variable current_wrapper from JSEmitter. Instead each emitting function creates local wrapper instance. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:58:37 UTC (rev 13769) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:58:49 UTC (rev 13770) @@ -239,8 +239,6 @@ String *empty_string; Hash *templates; - - Wrapper *current_wrapper; State state; }; @@ -544,8 +542,7 @@ * ----------------------------------------------------------------------------- */ JSEmitter::JSEmitter() -: empty_string(NewString("")), - current_wrapper(NULL) +: empty_string(NewString("")) { templates = NewHash(); } @@ -645,10 +642,8 @@ while (base.item && GetFlag(base.item, "feature:ignore")) { base = Next(base); } - return base.item; } - return NULL; } @@ -659,9 +654,6 @@ int JSEmitter::emitWrapperFunction(Node *n) { int ret = SWIG_OK; - current_wrapper = NewWrapper(); - Setattr(n, "wrap:name", Getattr(n, "sym:name")); - String *kind = Getattr(n, "kind"); if (kind) { @@ -699,9 +691,6 @@ } } - DelWrapper(current_wrapper); - current_wrapper = 0; - return ret; } @@ -1225,6 +1214,8 @@ } int JSCEmitter::emitCtor(Node *n) { + + Wrapper *wrapper = NewWrapper(); Template t_ctor(getTemplate("JS_ctordefn")); String *mangled_name = SwigType_manglestr(Getattr(n, "name")); @@ -1234,20 +1225,20 @@ Setattr(n, "wrap:name", wrap_name); ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_wrapper); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); - Printf(current_wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0)); + Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0)); int num_args = emit_num_arguments(params); String *action = emit_action(n); - marshalInputArgs(n, params, current_wrapper, Ctor, true); + marshalInputArgs(n, params, wrapper, Ctor, true); - Printv(current_wrapper->code, action, "\n", 0); + Printv(wrapper->code, action, "\n", 0); t_ctor.replace("${classname_mangled}", mangled_name) .replace("${overloadext}", overname) - .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code) + .replace("${LOCALS}", wrapper->locals) + .replace("${CODE}", wrapper->code) .replace("${type_mangled}", state.clazz(TYPE_MANGLED)) .pretty_print(state.clazz(CTORS)); @@ -1259,6 +1250,8 @@ .replace("${argcount}", argcount); Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); Delete(argcount); + + DelWrapper(wrapper); return SWIG_OK; } @@ -1274,6 +1267,8 @@ } int JSCEmitter::emitGetter(Node *n, bool is_member) { + Wrapper *wrapper = NewWrapper(); + Template t_getter(getTemplate("JS_getproperty")); bool is_static = Equal(Getattr(n, "storage"), "static"); @@ -1282,19 +1277,21 @@ state.variable(GETTER, wrap_name); ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_wrapper); - Wrapper_add_local(current_wrapper, "jsresult", "JSValueRef jsresult"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); String *action = emit_action(n); - marshalInputArgs(n, params, current_wrapper, Getter, is_member, is_static); - marshalOutput(n, action, current_wrapper); + marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); + marshalOutput(n, action, wrapper); t_getter.replace("${getname}", wrap_name) - .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code) + .replace("${LOCALS}", wrapper->locals) + .replace("${CODE}", wrapper->code) .pretty_print(f_wrappers); + DelWrapper(wrapper); + return SWIG_OK; } @@ -1304,6 +1301,8 @@ if (State::IsSet(state.variable(IS_IMMUTABLE))) { return SWIG_OK; } + + Wrapper *wrapper = NewWrapper(); Template t_setter(getTemplate("JS_setproperty")); bool is_static = Equal(Getattr(n, "storage"), "static"); @@ -1313,18 +1312,20 @@ state.variable(SETTER, wrap_name); ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_wrapper); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); String *action = emit_action(n); - marshalInputArgs(n, params, current_wrapper, Setter, is_member, is_static); - Append(current_wrapper->code, action); + marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); + Append(wrapper->code, action); t_setter.replace("${setname}", wrap_name) - .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code) + .replace("${LOCALS}", wrapper->locals) + .replace("${CODE}", wrapper->code) .pretty_print(f_wrappers); + DelWrapper(wrapper); + return SWIG_OK; } @@ -1334,16 +1335,24 @@ int JSCEmitter::emitConstant(Node *n) { + Wrapper *wrapper = NewWrapper(); + + Template t_getter(getTemplate("JS_getproperty")); + // call the variable methods as a constants are // registred in same way enterVariable(n); - current_wrapper = NewWrapper(); + // prepare function wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); + state.variable(GETTER, wrap_name); + Setattr(n, "wrap:name", wrap_name); + // prepare local variables + Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); + + // prepare action String *action = NewString(""); - - String *name = Getattr(n, "name"); - String *wrap_name = Swig_name_wrapper(name); String *value = Getattr(n, "rawval"); if (value == NULL) { value = Getattr(n, "rawvalue"); @@ -1351,32 +1360,27 @@ if (value == NULL) { value = Getattr(n, "value"); } - - Template t_getter(getTemplate("JS_getproperty")); - - state.variable(GETTER, wrap_name); - Setattr(n, "wrap:name", wrap_name); - Printf(action, "result = %s;\n", value); Setattr(n, "wrap:action", action); - Wrapper_add_local(current_wrapper, "jsresult", "JSValueRef jsresult"); - marshalOutput(n, action, current_wrapper); + marshalOutput(n, action, wrapper); t_getter.replace("${getname}", wrap_name) - .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code) + .replace("${LOCALS}", wrapper->locals) + .replace("${CODE}", wrapper->code) .pretty_print(f_wrappers); - DelWrapper(current_wrapper); - current_wrapper = 0; - exitVariable(n); + DelWrapper(wrapper); + return SWIG_OK; } int JSCEmitter::emitFunction(Node *n, bool is_member) { + + Wrapper *wrapper = NewWrapper(); + Template t_function(getTemplate("JS_functionwrapper")); // Note: there is an inconsistency in SWIG with static member functions @@ -1397,18 +1401,18 @@ // prepare local variables ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_wrapper); - Wrapper_add_local(current_wrapper, "jsresult", "JSValueRef jsresult"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); // prepare code part String *action = emit_action(n); - marshalInputArgs(n, params, current_wrapper, Function, is_member, is_static); - marshalOutput(n, action, current_wrapper); + marshalInputArgs(n, params, wrapper, Function, is_member, is_static); + marshalOutput(n, action, wrapper); t_function.replace("${functionname}", wrap_name) - .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code) + .replace("${LOCALS}", wrapper->locals) + .replace("${CODE}", wrapper->code) .pretty_print(f_wrappers); // handle function overloading @@ -1426,6 +1430,8 @@ Delete(argcount); } + + DelWrapper(wrapper); return SWIG_OK; } @@ -1994,15 +2000,15 @@ Template t(GetTemplate(V8_CTOR_WRAPPER)); //HACK: manually add declaration of instance pointer - Printf(current_wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"),0)); + Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"),0)); String* action = emit_action(n); - Printv(current_wrapper->code, action, 0); + Printv(wrapper->code, action, 0); t.Replace(KW_MANGLED_NAME, current_classname_mangled) .Replace(KW_UNQUALIFIED_NAME, current_classname_unqualified) - .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_CODE, current_wrapper->code); + .Replace(KW_LOCALS, wrapper->locals) + .Replace(KW_CODE, wrapper->code); Wrapper_pretty_print(t.str(), f_wrapper); @@ -2022,17 +2028,17 @@ current_getter = Getattr(n,"wrap:name"); ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_wrapper); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); int num_args = emit_num_arguments(params); String* action = emit_action(n); - marshalInputArgs(n, params, num_args, current_wrapper); - marshalOutput(n, action, current_wrapper); + marshalInputArgs(n, params, num_args, wrapper); + marshalOutput(n, action, wrapper); t_getter.Replace(KW_MANGLED_NAME, current_variable_mangled) - .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_CODE, current_wrapper->code); + .Replace(KW_LOCALS, wrapper->locals) + .Replace(KW_CODE, wrapper->code); Wrapper_pretty_print(t_getter.str(), f_wrapper); @@ -2046,17 +2052,17 @@ current_setter = Getattr(n,"wrap:name"); ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_wrapper); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); int num_args = emit_num_arguments(params); String* action = emit_action(n); - marshalInputArgs(n, params, num_args, current_wrapper); - Printv(current_wrapper->code, action, 0); + marshalInputArgs(n, params, num_args, wrapper); + Printv(wrapper->code, action, 0); t_setter.Replace(KW_MANGLED_NAME, current_variable_mangled) - .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_CODE, current_wrapper->code); + .Replace(KW_LOCALS, wrapper->locals) + .Replace(KW_CODE, wrapper->code); Wrapper_pretty_print(t_setter.str(), f_wrapper); @@ -2073,17 +2079,17 @@ Setattr(n, "wrap:name", wrap_name); ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_wrapper); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); int num_args = emit_num_arguments(params); String* action = emit_action(n); - marshalInputArgs(n, params, num_args, current_wrapper); - marshalOutput(n, action, current_wrapper); + marshalInputArgs(n, params, num_args, wrapper); + marshalOutput(n, action, wrapper); t_function.Replace(KW_MANGLED_NAME, current_function_mangled) - .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_CODE, current_wrapper->code); + .Replace(KW_LOCALS, wrapper->locals) + .Replace(KW_CODE, wrapper->code); Wrapper_pretty_print(t_function.str(), f_wrapper); return SWIG_OK; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ol...@us...> - 2012-09-08 00:59:49
|
Revision: 13774 http://swig.svn.sourceforge.net/swig/?rev=13774&view=rev Author: oliv3rb Date: 2012-09-08 00:59:43 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Simplify implementation using new issetter flag. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:59:31 UTC (rev 13773) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:59:43 UTC (rev 13774) @@ -215,12 +215,6 @@ virtual int emitSetter(Node *n, bool is_member, bool is_static) = 0; /** - * Helper function to find out if a function is a setter or not. - * TODO: there should be some kind of support in swig core for that? - */ - bool isSetterMethod(Node *n); - - /** * Helper function to retrieve the first parent class node. */ Node *getBaseClass(Node *n); @@ -618,7 +612,8 @@ ret = emitFunction(n, is_member, is_static); } else if (Cmp(kind, "variable") == 0) { bool is_static = GetFlag(state.variable(), IS_STATIC); - if (isSetterMethod(n)) { + bool is_setter = GetFlag(n, "wrap:issetter"); + if (is_setter) { ret = emitSetter(n, is_member, is_static); } else { ret = emitGetter(n, is_member, is_static); @@ -691,35 +686,6 @@ return SWIG_OK; } - -/* ----------------------------------------------------------------------------- - * __swigjs_str_ends_with() : c string helper to check suffix match - * ----------------------------------------------------------------------------- */ - -int __swigjs_str_ends_with(const char *str, const char *suffix) { - - if (str == NULL || suffix == NULL) - return 0; - - size_t str_len = strlen(str); - size_t suffix_len = strlen(suffix); - - if (suffix_len > str_len) - return 0; - - return 0 == strncmp(str + str_len - suffix_len, suffix, suffix_len); -} - - -/* ----------------------------------------------------------------------------- - * JSEmitter::isSetterMethod() : helper to check if a method is a setter function - * ----------------------------------------------------------------------------- */ - -bool JSEmitter::isSetterMethod(Node *n) { - String *symname = Getattr(n, "sym:name"); - return (__swigjs_str_ends_with((char *) Data(symname), "_set") != 0); -} - /********************************************************************** * JavascriptCore: JSEmitter implementation for JavascriptCore engine **********************************************************************/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ol...@us...> - 2012-09-08 01:00:01
|
Revision: 13775 http://swig.svn.sourceforge.net/swig/?rev=13775&view=rev Author: oliv3rb Date: 2012-09-08 00:59:55 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Pull namespace implementation up to be shared between js emitters. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:59:43 UTC (rev 13774) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:59:55 UTC (rev 13775) @@ -122,9 +122,7 @@ * be registered in certain static tables. * This method should be used to switch output DOHs correspondingly. */ - virtual int switchNamespace(Node *) { - return SWIG_OK; - }; + virtual int switchNamespace(Node *); /** * Invoked at the beginning of the classHandler. @@ -221,11 +219,24 @@ Parm *skipIgnoredArgs(Parm *p); + virtual int createNamespace(String *scope); + + virtual Hash *createNamespaceEntry(const char *name, const char *parent) = 0; + + virtual int emitNamespaces() = 0; + protected: Hash *templates; State state; + + // contains context specific structs + // to allow generation of different class definition tables + // which are switched on namespace change + Hash *namespaces; + Hash *current_namespace; + }; /********************************************************************** @@ -523,7 +534,9 @@ * ----------------------------------------------------------------------------- */ JSEmitter::JSEmitter() -: templates(NewHash()) +: templates(NewHash()), + namespaces(NULL), + current_namespace(NULL) { } @@ -564,7 +577,16 @@ return state; } -int JSEmitter::initialize(Node *) { +int JSEmitter::initialize(Node * n) { + + if(namespaces != NULL) { + Delete(namespaces); + } + namespaces = NewHash(); + Hash *global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); + Setattr(namespaces, "::", global_namespace); + current_namespace = global_namespace; + return SWIG_OK; } @@ -686,6 +708,49 @@ return SWIG_OK; } +int JSEmitter::switchNamespace(Node *n) { + + if (!GetFlag(n, "feature:nspace")) { + current_namespace = Getattr(namespaces, "::"); + } else { + String *scope = Swig_scopename_prefix(Getattr(n, "name")); + if (scope) { + // if the scope is not yet registered + // create all scopes/namespaces recursively + if (!Getattr(namespaces, scope)) { + createNamespace(scope); + } + current_namespace = Getattr(namespaces, scope); + } else { + current_namespace = Getattr(namespaces, "::"); + } + } + + return SWIG_OK; +} + +int JSEmitter::createNamespace(String *scope) { + + String *parent_scope = Swig_scopename_prefix(scope); + Hash *parent_namespace; + if (parent_scope == 0) { + parent_namespace = Getattr(namespaces, "::"); + } else if (!Getattr(namespaces, parent_scope)) { + createNamespace(parent_scope); + parent_namespace = Getattr(namespaces, parent_scope); + } else { + parent_namespace = Getattr(namespaces, parent_scope); + } + assert(parent_namespace != 0); + + Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name"))); + Setattr(namespaces, scope, new_namespace); + + Delete(parent_scope); + return SWIG_OK; +} + + /********************************************************************** * JavascriptCore: JSEmitter implementation for JavascriptCore engine **********************************************************************/ @@ -746,10 +811,6 @@ void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); - virtual int switchNamespace(Node *n); - - virtual int createNamespace(String *scope); - virtual Hash *createNamespaceEntry(const char *name, const char *parent); virtual int emitNamespaces(); @@ -760,11 +821,6 @@ String *VETO_SET; const char *GLOBAL_STR; - // contains context specific structs - // to allow generation of different class definition tables - // which are switched on namespace change - Hash *namespaces; - Hash *current_namespace; // output file and major code parts File *f_wrap_cpp; @@ -798,8 +854,6 @@ NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), GLOBAL_STR(NULL), - namespaces(NULL), - current_namespace(NULL), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), @@ -907,13 +961,11 @@ } else { Replaceall(tm, "$owner", "0"); } - Append(wrapper->code, tm); if (Len(tm) > 0) { Printf(wrapper->code, "\n"); } - } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name")); } @@ -944,11 +996,6 @@ state.global(REGISTER_NAMESPACES, NewString("")); state.global(INITIALIZER, NewString("")); - namespaces = NewHash(); - Hash *global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); - Setattr(namespaces, "::", global_namespace); - current_namespace = global_namespace; - /* Register file targets with the SWIG file handler */ Swig_register_filebyname("begin", f_wrap_cpp); Swig_register_filebyname("header", f_header); @@ -1388,48 +1435,6 @@ return SWIG_OK; } -int JSCEmitter::switchNamespace(Node *n) { - - if (!GetFlag(n, "feature:nspace")) { - current_namespace = Getattr(namespaces, "::"); - } else { - String *scope = Swig_scopename_prefix(Getattr(n, "name")); - if (scope) { - // if the scope is not yet registered - // create all scopes/namespaces recursively - if (!Getattr(namespaces, scope)) { - createNamespace(scope); - } - current_namespace = Getattr(namespaces, scope); - } else { - current_namespace = Getattr(namespaces, "::"); - } - } - - return SWIG_OK; -} - -int JSCEmitter::createNamespace(String *scope) { - - String *parent_scope = Swig_scopename_prefix(scope); - Hash *parent_namespace; - if (parent_scope == 0) { - parent_namespace = Getattr(namespaces, "::"); - } else if (!Getattr(namespaces, parent_scope)) { - createNamespace(parent_scope); - parent_namespace = Getattr(namespaces, parent_scope); - } else { - parent_namespace = Getattr(namespaces, parent_scope); - } - assert(parent_namespace != 0); - - Hash *new_namespace = createNamespaceEntry(Char(scope), Char(Getattr(parent_namespace, "name"))); - Setattr(namespaces, scope, new_namespace); - - Delete(parent_scope); - return SWIG_OK; -} - Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent) { Hash *entry = NewHash(); String *_name = NewString(name); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ol...@us...> - 2012-09-08 01:00:22
|
Revision: 13776 http://swig.svn.sourceforge.net/swig/?rev=13776&view=rev Author: oliv3rb Date: 2012-09-08 01:00:15 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Refactored JSEmitters to share unified code. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 00:59:55 UTC (rev 13775) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 01:00:15 UTC (rev 13776) @@ -88,6 +88,13 @@ typedef JSEmitterState State; + enum MarshallingMode { + Setter, + Getter, + Ctor, + Function + }; + public: enum JSEmitterType { @@ -168,7 +175,7 @@ /** * Invoked from constantWrapper after call to Language::constantWrapper. **/ - virtual int emitConstant(Node *n) = 0; + virtual int emitConstant(Node *n); /** * Registers a given code snippet for a given key name. @@ -190,28 +197,34 @@ /** * Generates code for a constructor function. */ - virtual int emitCtor(Node *n) = 0; + virtual int emitCtor(Node *n); /** * Generates code for a destructor function. */ - virtual int emitDtor(Node *n) = 0; + virtual int emitDtor(Node *n); /** * Generates code for a function. */ - virtual int emitFunction(Node *n, bool is_member, bool is_static) = 0; + virtual int emitFunction(Node *n, bool is_member, bool is_static); + virtual int emitFunctionDispatcher(Node *n, bool /*is_member */ ); + /** * Generates code for a getter function. */ - virtual int emitGetter(Node *n, bool is_member, bool is_static) = 0; + virtual int emitGetter(Node *n, bool is_member, bool is_static); /** * Generates code for a setter function. */ - virtual int emitSetter(Node *n, bool is_member, bool is_static) = 0; + virtual int emitSetter(Node *n, bool is_member, bool is_static); + virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) = 0; + + virtual void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); + /** * Helper function to retrieve the first parent class node. */ @@ -221,7 +234,7 @@ virtual int createNamespace(String *scope); - virtual Hash *createNamespaceEntry(const char *name, const char *parent) = 0; + virtual Hash *createNamespaceEntry(const char *name, const char *parent); virtual int emitNamespaces() = 0; @@ -231,12 +244,14 @@ State state; - // contains context specific structs - // to allow generation of different class definition tables + // contains context specific data (DOHs) + // to allow generation of namespace related code // which are switched on namespace change Hash *namespaces; Hash *current_namespace; + File *f_wrappers; + }; /********************************************************************** @@ -244,6 +259,7 @@ **********************************************************************/ /* factory methods for concrete JSEmitters: */ + JSEmitter *swig_javascript_create_JSCEmitter(); JSEmitter *swig_javascript_create_V8Emitter(); @@ -265,13 +281,13 @@ virtual int classHandler(Node *n); virtual int functionWrapper(Node *n); virtual int constantWrapper(Node *n); + virtual void main(int argc, char *argv[]); + virtual int top(Node *n); /** * Registers all %fragments assigned to section "templates". **/ virtual int fragmentDirective(Node *n); - virtual void main(int argc, char *argv[]); - virtual int top(Node *n); private: @@ -536,7 +552,8 @@ JSEmitter::JSEmitter() : templates(NewHash()), namespaces(NULL), - current_namespace(NULL) + current_namespace(NULL), + f_wrappers(NULL) { } @@ -557,7 +574,7 @@ } /* ----------------------------------------------------------------------------- - * JSEmitter::GetTemplate() : Retrieves a registered a code template + * JSEmitter::getTemplate() : Retrieves a registered a code template * ----------------------------------------------------------------------------- */ Template JSEmitter::getTemplate(const String *name) { @@ -587,6 +604,8 @@ Setattr(namespaces, "::", global_namespace); current_namespace = global_namespace; + f_wrappers = NewString(""); + return SWIG_OK; } @@ -750,6 +769,16 @@ return SWIG_OK; } +Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent) { + Hash *entry = NewHash(); + String *name = NewString(_name); + Setattr(entry, "name", Swig_scopename_last(name)); + Setattr(entry, "name_mangled", Swig_name_mangle(name)); + Setattr(entry, "parent", NewString(parent)); + + Delete(name); + return entry; +} /********************************************************************** * JavascriptCore: JSEmitter implementation for JavascriptCore engine @@ -757,15 +786,6 @@ class JSCEmitter:public JSEmitter { -private: - - enum MarshallingMode { - Setter, - Getter, - Ctor, - Function - }; - public: JSCEmitter(); @@ -781,10 +801,6 @@ protected: - virtual int emitCtor(Node *n); - - virtual int emitDtor(Node *n); - virtual int enterVariable(Node *n); virtual int exitVariable(Node *n); @@ -797,20 +813,8 @@ virtual int exitClass(Node *n); - virtual int emitFunction(Node *n, bool is_member, bool is_static); + virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); - virtual int emitFunctionDispatcher(Node *n, bool is_member); - - virtual int emitGetter(Node *n, bool is_member, bool is_static); - - virtual int emitSetter(Node *n, bool is_member, bool is_static); - - virtual int emitConstant(Node *n); - - void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static = false); - - void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); - virtual Hash *createNamespaceEntry(const char *name, const char *parent); virtual int emitNamespaces(); @@ -826,7 +830,6 @@ File *f_wrap_cpp; File *f_runtime; File *f_header; - File *f_wrappers; File *f_init; }; @@ -857,7 +860,6 @@ f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), - f_wrappers(NULL), f_init(NULL) { } @@ -934,44 +936,6 @@ } } -/* --------------------------------------------------------------------- -* marshalOutput() -* -* Process the return value of the C/C++ function call -* and convert them into the Javascript types using the -* supplied typemaps. -* --------------------------------------------------------------------- */ - -void JSCEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { - SwigType *type = Getattr(n, "type"); - Setattr(n, "type", type); - String *tm; - - // HACK: output types are not registered as swig_types automatically - if (SwigType_ispointer(type)) { - SwigType_remember_clientdata(type, NewString("0")); - } - - if ((tm = Swig_typemap_lookup_out("out", n, "result", wrapper, actioncode))) { - Replaceall(tm, "$result", "jsresult"); - Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); - - if (GetFlag(n, "feature:new")) { - Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); - } else { - Replaceall(tm, "$owner", "0"); - } - Append(wrapper->code, tm); - - if (Len(tm) > 0) { - Printf(wrapper->code, "\n"); - } - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name")); - } - emit_return_variable(n, type, wrapper); -} - int JSCEmitter::initialize(Node *n) { JSEmitter::initialize(n); @@ -990,7 +954,6 @@ f_runtime = NewString(""); f_init = NewString(""); f_header = NewString(""); - f_wrappers = NewString(""); state.global(CREATE_NAMESPACES, NewString("")); state.global(REGISTER_NAMESPACES, NewString("")); @@ -1193,7 +1156,7 @@ return SWIG_OK; } -int JSCEmitter::emitCtor(Node *n) { +int JSEmitter::emitCtor(Node *n) { Wrapper *wrapper = NewWrapper(); @@ -1212,7 +1175,7 @@ int num_args = emit_num_arguments(params); String *action = emit_action(n); - marshalInputArgs(n, params, wrapper, Ctor, true); + marshalInputArgs(n, params, wrapper, Ctor, true, false); Printv(wrapper->code, action, "\n", 0); t_ctor.replace("${classname_mangled}", mangled_name) @@ -1236,7 +1199,7 @@ return SWIG_OK; } -int JSCEmitter::emitDtor(Node *) { +int JSEmitter::emitDtor(Node *) { Template t_dtor = getTemplate("JS_destructordefn"); t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) @@ -1246,7 +1209,7 @@ return SWIG_OK; } -int JSCEmitter::emitGetter(Node *n, bool is_member, bool is_static) { +int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { Wrapper *wrapper = NewWrapper(); Template t_getter(getTemplate("JS_getproperty")); @@ -1276,7 +1239,7 @@ return SWIG_OK; } -int JSCEmitter::emitSetter(Node *n, bool is_member, bool is_static) { +int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { // skip variables that are immutable if (State::IsSet(state.variable(IS_IMMUTABLE))) { @@ -1316,7 +1279,7 @@ * JSCEmitter::emitConstant() : triggers code generation for constants * ----------------------------------------------------------------------------- */ -int JSCEmitter::emitConstant(Node *n) { +int JSEmitter::emitConstant(Node *n) { Wrapper *wrapper = NewWrapper(); @@ -1359,10 +1322,9 @@ return SWIG_OK; } -int JSCEmitter::emitFunction(Node *n, bool is_member, bool is_static) { +int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { - Wrapper *wrapper = NewWrapper(); - + Wrapper *wrapper = NewWrapper(); Template t_function(getTemplate("JS_functionwrapper")); bool is_overloaded = GetFlag(n, "sym:overloaded"); @@ -1412,7 +1374,7 @@ return SWIG_OK; } -int JSCEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { +int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { Template t_function(getTemplate("JS_functionwrapper")); @@ -1435,16 +1397,40 @@ return SWIG_OK; } +void JSEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { + SwigType *type = Getattr(n, "type"); + Setattr(n, "type", type); + String *tm; + + // HACK: output types are not registered as swig_types automatically + if (SwigType_ispointer(type)) { + SwigType_remember_clientdata(type, NewString("0")); + } + + if ((tm = Swig_typemap_lookup_out("out", n, "result", wrapper, actioncode))) { + Replaceall(tm, "$result", "jsresult"); + Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); + + if (GetFlag(n, "feature:new")) { + Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); + } else { + Replaceall(tm, "$owner", "0"); + } + Append(wrapper->code, tm); + + if (Len(tm) > 0) { + Printf(wrapper->code, "\n"); + } + } else { + Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name")); + } + emit_return_variable(n, type, wrapper); +} + Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent) { - Hash *entry = NewHash(); - String *_name = NewString(name); - Setattr(entry, "name", Swig_scopename_last(_name)); - Setattr(entry, "name_mangled", Swig_name_mangle(_name)); - Setattr(entry, "parent", NewString(parent)); + Hash *entry = JSEmitter::createNamespaceEntry(name, parent); Setattr(entry, "functions", NewString("")); Setattr(entry, "values", NewString("")); - - Delete(_name); return entry; } @@ -1483,93 +1469,62 @@ return new JSCEmitter(); } -/* class V8Emitter: public JSEmitter { public: - V8Emitter(); + V8Emitter(); - virtual ~V8Emitter(); - - virtual int Initialize(Node *n); + virtual ~V8Emitter(); + + virtual int initialize(Node *n); - virtual int Dump(Node *n); - - virtual int Close(); + virtual int dump(Node *n); + + virtual int close(); + + virtual int enterClass(Node *n); + + virtual int exitClass(Node *n); - virtual int SwitchContext(Node *n); - - virtual int EnterClass(Node *n); - - virtual int ExitClass(Node *n); + virtual int enterVariable(Node *n); - virtual int EnterVariable(Node *n); + virtual int exitVariable(Node *n); - virtual int ExitVariable(Node *n); + virtual int enterFunction(Node *n); - virtual int EnterFunction(Node *n); + virtual int exitFunction(Node *n); - virtual int ExitFunction(Node *n); - protected: - int CreateNamespace(String* scope); + virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); - virtual int EmitCtor(Node *n); - - virtual int EmitDtor(Node *n); + virtual int emitNamespaces(); - virtual int EmitFunction(Node *n, bool is_member); - - virtual int EmitGetter(Node *n, bool is_member); - - virtual int EmitSetter(Node *n, bool is_member); - - void marshalInputArgs(Node *n, ParmList *parms, int numarg, Wrapper *wrapper); - - void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); - - Parm *skipIgnoredArgs(Parm *p); - private: - File *f_runtime; - File *f_header; - File *f_class_templates; - File *f_wrapper; - - File *f_init_namespaces; - File *f_init_class_templates; - File *f_init_wrappers; - File *f_init_inheritance; - File *f_init_class_instances; - File *f_init_static_wrappers; - File *f_init_register_classes; - File *f_init_register_namespaces; - - // the output cpp file - File *f_wrap_cpp; - - // state variables - String* current_context; - String* current_class_type; - String* current_classname_mangled; - String* current_classname_unqualified; - String* current_variable_mangled; - String* current_variable_unqualified; - String* current_getter; - String* current_setter; - String* current_function_mangled; - String* current_function_unqualified; - - String* GLOBAL; - String* NULL_STR; - Hash* namespaces; + File *f_runtime; + File *f_header; + File *f_class_templates; + File *f_wrapper; + File *f_init; + + File *f_init_namespaces; + File *f_init_class_templates; + File *f_init_wrappers; + File *f_init_inheritance; + File *f_init_class_instances; + File *f_init_static_wrappers; + File *f_init_register_classes; + File *f_init_register_namespaces; + + // the output cpp file + File *f_wrap_cpp; + + String* GLOBAL; + String* NULL_STR; }; -*/ -/* // name of templates #define V8_INITIALIZER "v8_initializer" #define V8_DECL_CLASSTEMPLATE "v8_declare_class_template" @@ -1614,510 +1569,316 @@ #define KW_LOCALS "${LOCALS}" #define KW_CODE "${CODE}" -#define KW_MARSHAL_INPUT "${MARSHAL_INPUT}" -#define KW_ACTION "${ACTION}" -#define KW_MARSHAL_OUTPUT "${MARSHAL_OUTPUT}" V8Emitter::V8Emitter() - : JSEmitter(), - GLOBAL(NewString("global")), - NULL_STR(NewString("0")), - namespaces(NewHash()) +: JSEmitter(), + GLOBAL(NewString("global")), + NULL_STR(NewString("0")) { } V8Emitter::~V8Emitter() { - Delete(GLOBAL); - Delete(NULL_STR); - Delete(namespaces); + Delete(GLOBAL); + Delete(NULL_STR); } int V8Emitter::initialize(Node *n) { - - // Get the output file name - String *outfile = Getattr(n,"outfile"); - f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); - if (!f_wrap_cpp) { - FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); - } + JSEmitter::initialize(n); + + // Get the output file name + String *outfile = Getattr(n,"outfile"); + f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); + if (!f_wrap_cpp) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } - f_runtime = NewString(""); - f_header = NewString(""); - f_class_templates = NewString(""); - f_wrapper = NewString(""); - - f_init_namespaces = NewString(""); - f_init_class_templates = NewString(""); - f_init_wrappers = NewString(""); - f_init_inheritance = NewString(""); - f_init_class_instances = NewString(""); - f_init_static_wrappers = NewString(""); - f_init_register_classes = NewString(""); - f_init_register_namespaces = NewString(""); + f_runtime = NewString(""); + f_header = NewString(""); + f_class_templates = NewString(""); + f_wrapper = NewString(""); + f_init = NewString(""); + + f_init_namespaces = NewString(""); + f_init_class_templates = NewString(""); + f_init_wrappers = NewString(""); + f_init_inheritance = NewString(""); + f_init_class_instances = NewString(""); + f_init_static_wrappers = NewString(""); + f_init_register_classes = NewString(""); + f_init_register_namespaces = NewString(""); - // note: this is necessary for built-in generation of swig runtime code - Swig_register_filebyname("runtime", f_runtime); + // note: this is necessary for built-in generation of swig runtime code + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("init", f_init); + Swig_register_filebyname("wrapper", f_wrapper); - return SWIG_OK; + return SWIG_OK; } int V8Emitter::dump(Node *n) { - // Get the module name - String* module = Getattr(n,"name"); + // Get the module name + String* module = Getattr(n,"name"); - // write the swig banner - Swig_banner(f_wrap_cpp); + // write the swig banner + Swig_banner(f_wrap_cpp); - Printv(f_wrap_cpp, f_runtime, "\n", 0); - Printv(f_wrap_cpp, f_header, "\n", 0); - Printv(f_wrap_cpp, f_class_templates, "\n", 0); - Printv(f_wrap_cpp, f_wrapper, "\n", 0); + Printv(f_wrap_cpp, f_runtime, "\n", 0); + Printv(f_wrap_cpp, f_header, "\n", 0); + Printv(f_wrap_cpp, f_class_templates, "\n", 0); + Printv(f_wrap_cpp, f_wrapper, "\n", 0); - // compose the initializer function using a template - // filled with sub-parts - Template initializer(GetTemplate(V8_INITIALIZER)); - initializer.Replace(KW_MODULE_NAME, module) - .Replace(KW_NAME_SPACES, f_init_namespaces) - .Replace(KW_CLASS_TEMPLATES, f_init_class_templates) - .Replace(KW_WRAPPERS, f_init_wrappers) - .Replace(KW_INHERITANCE, f_init_inheritance) - .Replace(KW_CLASS_INSTANCES, f_init_class_instances) - .Replace(KW_STATIC_WRAPPERS, f_init_static_wrappers) - .Replace(KW_REGISTER_CLASSES, f_init_register_classes) - .Replace(KW_REGISTER_NS, f_init_register_namespaces); - Wrapper_pretty_print(initializer.str(), f_wrap_cpp); + // compose the initializer function using a template + // filled with sub-parts + Template initializer(getTemplate(V8_INITIALIZER)); + initializer.replace(KW_MODULE_NAME, module) + .replace(KW_NAME_SPACES, f_init_namespaces) + .replace(KW_CLASS_TEMPLATES, f_init_class_templates) + .replace(KW_WRAPPERS, f_init_wrappers) + .replace(KW_INHERITANCE, f_init_inheritance) + .replace(KW_CLASS_INSTANCES, f_init_class_instances) + .replace(KW_STATIC_WRAPPERS, f_init_static_wrappers) + .replace(KW_REGISTER_CLASSES, f_init_register_classes) + .replace(KW_REGISTER_NS, f_init_register_namespaces) + .pretty_print(f_wrap_cpp); - return SWIG_OK; + return SWIG_OK; } int V8Emitter::close() { - // strings - Delete(f_runtime); - Delete(f_header); - Delete(f_class_templates); - Delete(f_wrapper); - Delete(f_init_namespaces); - Delete(f_init_class_templates); - Delete(f_init_wrappers); - Delete(f_init_inheritance); - Delete(f_init_class_instances); - Delete(f_init_static_wrappers); - Delete(f_init_register_classes); - Delete(f_init_register_namespaces); - - // files - Close(f_wrap_cpp); - Delete(f_wrap_cpp); - - return SWIG_OK; + // strings + Delete(f_runtime); + Delete(f_header); + Delete(f_class_templates); + Delete(f_wrapper); + Delete(f_init_namespaces); + Delete(f_init_class_templates); + Delete(f_init_wrappers); + Delete(f_init_inheritance); + Delete(f_init_class_instances); + Delete(f_init_static_wrappers); + Delete(f_init_register_classes); + Delete(f_init_register_namespaces); + + // files + Close(f_wrap_cpp); + Delete(f_wrap_cpp); + + return SWIG_OK; } -int V8Emitter::SwitchContext(Node *n) +int V8Emitter::enterClass(Node *n) { - String* scope = Swig_scopename_prefix(Getattr(n, "name")); + JSEmitter::enterClass(n); - if (scope) { - // if the scope is not yet registered - // create all scopes/namespaces recursively - if(!Getattr(namespaces, scope)) { - CreateNamespace(scope); - } - current_context = Getattr(namespaces, scope); - } else { - current_context = GLOBAL; - } - - return SWIG_OK; -} + // emit declaration of a v8 class template + Template t_decl_class(getTemplate(V8_DECL_CLASSTEMPLATE)); + t_decl_class.replace(KW_MANGLED_NAME, state.clazz(NAME_MANGLED)) + .pretty_print(f_class_templates); -int V8Emitter::CreateNamespace(String* scope) { - String* parent_scope = Swig_scopename_prefix(scope); - String* parent_scope_mangled = 0; + // emit definition of v8 class template + Template t_def_class(getTemplate(V8_DEFINE_CLASSTEMPLATE)); + t_def_class.replace(KW_MANGLED_NAME, state.clazz(NAME_MANGLED)) + .replace(KW_UNQUALIFIED_NAME, state.clazz(NAME)) + .pretty_print(f_init_class_templates); - if(!parent_scope) { - parent_scope_mangled = NewString("global"); - } else { - parent_scope_mangled = Swig_name_mangle(parent_scope); + Template t_class_instance(getTemplate(V8_CREATE_CLASS_INSTANCE)); + t_class_instance.replace(KW_MANGLED_NAME, state.clazz(NAME_MANGLED)) + .pretty_print(f_init_class_instances); - } - - if (parent_scope && !Getattr(namespaces, parent_scope)) { - CreateNamespace(parent_scope); - } - - String* scope_mangled = Swig_string_mangle(scope); - String* scope_unqualified = Swig_scopename_last(scope); - Setattr(namespaces, scope, scope_mangled); - - // create namespace object and register it to the parent scope - Template t_create_ns(GetTemplate(V8_CREATE_NAMESPACE)); - t_create_ns.Replace(KW_MANGLED_NAME, scope_mangled); - - Template t_register_ns(GetTemplate(V8_REGISTER_NAMESPACE)); - t_register_ns.Replace(KW_MANGLED_NAME, scope_mangled) - .Replace(KW_CONTEXT, parent_scope_mangled) - .Replace(KW_UNQUALIFIED_NAME, scope_unqualified); - - Printv(f_init_namespaces, t_create_ns.str(), 0); - // prepend in order to achieve reversed order of registration statements - Insert(f_init_register_namespaces, 0, t_register_ns.str()); - - Delete(parent_scope); - Delete(parent_scope_mangled); - Delete(scope_unqualified); - return SWIG_OK; + return SWIG_OK; } -int V8Emitter::EnterClass(Node *n) +int V8Emitter::exitClass(Node *n) { - current_classname_mangled = Swig_string_mangle(Getattr(n, "name")); - current_classname_unqualified = Swig_scopename_last(Getattr(n, "name")); - current_class_type = Getattr(n, "classtype"); - - // emit declaration of a v8 class template - Template t_decl_class(GetTemplate(V8_DECL_CLASSTEMPLATE)); - t_decl_class.Replace(KW_MANGLED_NAME, current_classname_mangled); - Printv(f_class_templates, t_decl_class.str(), 0); - - // emit definition of v8 class template - Template t_def_class(GetTemplate(V8_DEFINE_CLASSTEMPLATE)); - t_def_class.Replace(KW_MANGLED_NAME, current_classname_mangled) - .Replace(KW_UNQUALIFIED_NAME, current_classname_unqualified); - Printv(f_init_class_templates, t_def_class.str(), 0); - - Template t_class_instance(GetTemplate(V8_CREATE_CLASS_INSTANCE)); - t_class_instance.Replace(KW_MANGLED_NAME, current_classname_mangled); - Printv(f_init_class_instances, t_class_instance.str(), 0); - - return SWIG_OK; + // emit inheritance setup + Node* baseClass = getBaseClass(n); + if(baseClass) { + Template t_inherit(getTemplate(V8_INHERIT)); + String *base_name_mangled = SwigType_manglestr(Getattr(baseClass, "name")); + t_inherit.replace(KW_MANGLED_NAME, state.clazz(NAME_MANGLED)) + .replace(KW_BASE_CLASS, base_name_mangled) + .pretty_print(f_init_inheritance); + Delete(base_name_mangled); + } + + // emit registeration of class template + Template t_register(getTemplate(V8_REGISTER_CLASS)); + t_register.replace(KW_MANGLED_NAME, state.clazz(NAME_MANGLED)) + .replace(KW_UNQUALIFIED_NAME, state.clazz(NAME)) + .replace(KW_CONTEXT, Getattr(current_namespace, "name_mangled")) + .pretty_print(f_init_register_classes); + + return SWIG_OK; } -int V8Emitter::ExitClass(Node *n) +int V8Emitter::enterVariable(Node* n) { - // emit inheritance setup - Node* baseClass = GetBaseClass(n); - if(baseClass) { - Template t_inherit(GetTemplate(V8_INHERIT)); - t_inherit.Replace(KW_MANGLED_NAME, current_classname_mangled) - .Replace(KW_BASE_CLASS, Swig_string_mangle(Getattr(baseClass, "name"))); - Printv(f_init_inheritance, t_inherit.str(), 0); - } - - // emit registeration of class template - Template t_register(GetTemplate(V8_REGISTER_CLASS)); - t_register.Replace(KW_MANGLED_NAME, current_classname_mangled) - .Replace(KW_UNQUALIFIED_NAME, current_classname_unqualified) - .Replace(KW_CONTEXT, Swig_string_mangle(current_context)); - Printv(f_init_register_classes, t_register.str(), 0); + JSEmitter::enterVariable(n); + + state.variable(GETTER, NULL_STR); + state.variable(SETTER, NULL_STR); - Delete(current_classname_mangled); - Delete(current_classname_unqualified); - current_classname_mangled = 0; - current_classname_unqualified = 0; - current_class_type = 0; - - return SWIG_OK; + return SWIG_OK; } -int V8Emitter::EnterVariable(Node* n) +int V8Emitter::exitVariable(Node* n) { - current_variable_unqualified = Swig_scopename_last(Getattr(n, "name")); - if(GetFlag(n, "ismember")) { - current_variable_mangled = NewString(""); - Printf(current_variable_mangled, "%s_%s", current_classname_mangled, current_variable_unqualified); + if(GetFlag(n, "ismember")) { + if(GetFlag(state.variable(), IS_STATIC)) { + Template t_register(getTemplate(V8_REGISTER_GLOBAL_VARIABLE)); + String *class_instance = NewString(""); + Printf(class_instance, "class_%s", state.clazz(NAME_MANGLED)); + t_register.replace(KW_CONTEXT, class_instance) + .replace(KW_UNQUALIFIED_NAME, state.variable(NAME)) + .replace(KW_GETTER, state.variable(GETTER)) + .replace(KW_SETTER, state.variable(SETTER)) + .pretty_print(f_init_static_wrappers); + Delete(class_instance); } else { - current_variable_mangled = Swig_string_mangle(Getattr(n, "name")); + Template t_register(getTemplate(V8_REGISTER_MEMBER_VARIABLE)); + t_register.replace(KW_CLASSNAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(KW_UNQUALIFIED_NAME, state.clazz(NAME)) + .replace(KW_GETTER, state.variable(GETTER)) + .replace(KW_SETTER, state.variable(SETTER)) + .pretty_print(f_init_wrappers); } + } else { + Template t_register(getTemplate(V8_REGISTER_GLOBAL_VARIABLE)); + t_register.replace(KW_CONTEXT, Getattr(current_namespace, "name")) + .replace(KW_UNQUALIFIED_NAME, state.variable(NAME)) + .replace(KW_GETTER, state.variable(GETTER)) + .replace(KW_SETTER, state.variable(SETTER)) + .pretty_print(f_init_wrappers); + } - current_getter = NULL_STR; - current_setter = NULL_STR; - - return SWIG_OK; + return SWIG_OK; } -int V8Emitter::ExitVariable(Node* n) +int V8Emitter::enterFunction(Node* n) { - if(GetFlag(n, "ismember")) { - if(Equal(Getattr(n, "storage"), "static")) { - Template t_register(GetTemplate(V8_REGISTER_GLOBAL_VARIABLE)); - String *class_instance = NewString(""); - Printf(class_instance, "class_%s", current_classname_mangled); - t_register.Replace(KW_CONTEXT, class_instance) - .Replace(KW_UNQUALIFIED_NAME, current_variable_unqualified) - .Replace(KW_GETTER, current_getter) - .Replace(KW_SETTER, current_setter); - Printv(f_init_static_wrappers, t_register.str(), 0); - Delete(class_instance); - } else { - Template t_register(GetTemplate(V8_REGISTER_MEMBER_VARIABLE)); - t_register.Replace(KW_CLASSNAME_MANGLED, current_classname_mangled) - .Replace(KW_UNQUALIFIED_NAME, current_variable_unqualified) - .Replace(KW_GETTER, current_getter) - .Replace(KW_SETTER, current_setter); - Printv(f_init_wrappers, t_register.str(), 0); - } - } else { - Template t_register(GetTemplate(V8_REGISTER_GLOBAL_VARIABLE)); - t_register.Replace(KW_CONTEXT, current_context) - .Replace(KW_UNQUALIFIED_NAME, current_variable_unqualified) - .Replace(KW_GETTER, current_getter) - .Replace(KW_SETTER, current_setter); - Printv(f_init_wrappers, t_register.str(), 0); - } - - Delete(current_variable_mangled); - Delete(current_variable_unqualified); - current_variable_mangled = 0; - current_variable_unqualified = 0; - - return SWIG_OK; + JSEmitter::enterFunction(n); + + return SWIG_OK; } -int V8Emitter::EnterFunction(Node* n) -{ - current_function_unqualified = Swig_scopename_last(Getattr(n, "name")); - if(GetFlag(n, "ismember")) { - current_function_mangled = NewString(""); - Printf(current_function_mangled, "%s_%s", current_classname_mangled, current_function_unqualified); - } else { - current_function_mangled = Swig_string_mangle(Getattr(n, "name")); - } - - return SWIG_OK; -} - -int V8Emitter::ExitFunction(Node* n) +int V8Emitter::exitFunction(Node* n) { - // register the function at the specific context - if(GetFlag(n, "ismember")) { - if(Equal(Getattr(n, "storage"), "static")) { - Template t_register(GetTemplate(V8_REGISTER_GLOBAL_FUNCTION)); - String *class_instance = NewString(""); - Printf(class_instance, "class_%s", current_classname_mangled); - t_register.Replace(KW_CONTEXT, class_instance) - .Replace(KW_UNQUALIFIED_NAME, current_function_unqualified) - .Replace(KW_MANGLED_NAME, Getattr(n, "wrap:name")); - Printv(f_init_static_wrappers, t_register.str(), 0); - Delete(class_instance); - } else { - Template t_register(GetTemplate(V8_REGISTER_MEMBER_FUNCTION)); - t_register.Replace(KW_CLASSNAME_MANGLED, current_classname_mangled) - .Replace(KW_UNQUALIFIED_NAME, current_function_unqualified) - .Replace(KW_MANGLED_NAME, Getattr(n, "wrap:name")); - Printv(f_init_wrappers, t_register.str(), "\n", 0); - } + // register the function at the specific context + if(GetFlag(n, "ismember")) { + if(GetFlag(state.function(), IS_STATIC)) { + Template t_register(getTemplate(V8_REGISTER_GLOBAL_FUNCTION)); + String *class_instance = NewString(""); + Printf(class_instance, "class_%s", state.clazz(NAME_MANGLED)); + t_register.replace(KW_CONTEXT, class_instance) + .replace(KW_UNQUALIFIED_NAME, state.function(NAME)) + .replace(KW_MANGLED_NAME, Getattr(n, "wrap:name")); + Printv(f_init_static_wrappers, t_register.str(), 0); + Delete(class_instance); } else { - Template t_register(GetTemplate(V8_REGISTER_GLOBAL_FUNCTION)); - t_register.Replace(KW_CONTEXT, current_context) - .Replace(KW_UNQUALIFIED_NAME, current_function_unqualified) - .Replace(KW_MANGLED_NAME, Getattr(n, "wrap:name")); - Printv(f_init_wrappers, t_register.str(), 0); + Template t_register(getTemplate(V8_REGISTER_MEMBER_FUNCTION)); + t_register.replace(KW_CLASSNAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(KW_UNQUALIFIED_NAME, state.function(NAME)) + .replace(KW_MANGLED_NAME, Getattr(n, "wrap:name")); + Printv(f_init_wrappers, t_register.str(), "\n", 0); } - - - Delete(current_function_mangled); - Delete(current_function_unqualified); - current_function_mangled = 0; - current_function_unqualified = 0; - - return SWIG_OK; -} + } else { + Template t_register(getTemplate(V8_REGISTER_GLOBAL_FUNCTION)); + t_register.replace(KW_CONTEXT, Getattr(current_namespace, "name")) + .replace(KW_UNQUALIFIED_NAME, state.function(NAME)) + .replace(KW_MANGLED_NAME, Getattr(n, "wrap:name")); + Printv(f_init_wrappers, t_register.str(), 0); + } -int V8Emitter::EmitCtor(Node* n) -{ - // TODO: handle overloaded ctors using a dispatcher - Template t(GetTemplate(V8_CTOR_WRAPPER)); - - //HACK: manually add declaration of instance pointer - Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"),0)); - - String* action = emit_action(n); - Printv(wrapper->code, action, 0); - - t.Replace(KW_MANGLED_NAME, current_classname_mangled) - .Replace(KW_UNQUALIFIED_NAME, current_classname_unqualified) - .Replace(KW_LOCALS, wrapper->locals) - .Replace(KW_CODE, wrapper->code); - - Wrapper_pretty_print(t.str(), f_wrapper); - - return SWIG_OK; + return SWIG_OK; } -int V8Emitter::EmitDtor(Node* n) -{ - // TODO: - // find out how to register a dtor in v8 - return SWIG_OK; -} +void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { + String *tm; + Parm *p; -int V8Emitter::EmitGetter(Node *n, bool is_member) { - Template t_getter(GetTemplate(V8_GETTER)); + int startIdx = 0; + if (is_member && !is_static) { + startIdx = 1; + } - current_getter = Getattr(n,"wrap:name"); + int i = 0; + for (p = parms; p; p = nextSibling(p), i++) { + SwigType *pt = Getattr(p, "type"); + String *arg = NewString(""); - ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); + switch (mode) { + case Getter: + case Function: + if (is_member && !is_static && i == 0) { + Printv(arg, "args[0]", 0); + } else { + Printf(arg, "args[%d]", i - startIdx); + } - int num_args = emit_num_arguments(params); - String* action = emit_action(n); - marshalInputArgs(n, params, num_args, wrapper); - marshalOutput(n, action, wrapper); - - t_getter.Replace(KW_MANGLED_NAME, current_variable_mangled) - .Replace(KW_LOCALS, wrapper->locals) - .Replace(KW_CODE, wrapper->code); + break; + case Setter: + if (is_member && !is_static && i == 0) { + Printv(arg, "args[0]", 0); + } else { + Printv(arg, "value", 0); + } + break; + case Ctor: + Printf(arg, "args[%d]", i); + break; + default: + throw "Illegal state."; + } - Wrapper_pretty_print(t_getter.str(), f_wrapper); - - return SWIG_OK; -} + tm = Getattr(p, "tmap:in"); // Get typemap for this argument + if (tm != NULL) { + Replaceall(tm, "$input", arg); + Setattr(p, "emit:input", arg); -int V8Emitter::EmitSetter(Node* n, bool is_member) -{ - Template t_setter(GetTemplate(V8_SETTER)); + if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { + Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); + } else { + Replaceall(tm, "$disown", "0"); + } + Replaceall(tm, "$symname", Getattr(n, "sym:name")); - current_setter = Getattr(n,"wrap:name"); - - ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - - int num_args = emit_num_arguments(params); - String* action = emit_action(n); - marshalInputArgs(n, params, num_args, wrapper); - Printv(wrapper->code, action, 0); - - t_setter.Replace(KW_MANGLED_NAME, current_variable_mangled) - .Replace(KW_LOCALS, wrapper->locals) - .Replace(KW_CODE, wrapper->code); - - Wrapper_pretty_print(t_setter.str(), f_wrapper); - - return SWIG_OK; + 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)); + } + Delete(arg); + } } - -int V8Emitter::EmitFunction(Node* n, bool is_member) -{ - Template t_function(GetTemplate(V8_FUNCTION)); - - String* wrap_name = NewString(""); - Printv(wrap_name, current_function_mangled, 0); - Setattr(n, "wrap:name", wrap_name); +int V8Emitter::emitNamespaces() { +// TODO: handle namespaces: +/* + // create namespace object and register it to the parent scope + Template t_create_ns(getTemplate(V8_CREATE_NAMESPACE)); + t_create_ns.Replace(KW_MANGLED_NAME, scope_mangled); - ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - - int num_args = emit_num_arguments(params); - String* action = emit_action(n); - marshalInputArgs(n, params, num_args, wrapper); - marshalOutput(n, action, wrapper); - - t_function.Replace(KW_MANGLED_NAME, current_function_mangled) - .Replace(KW_LOCALS, wrapper->locals) - .Replace(KW_CODE, wrapper->code); - Wrapper_pretty_print(t_function.str(), f_wrapper); + Template t_register_ns(getTemplate(V8_REGISTER_NAMESPACE)); + t_register_ns.Replace(KW_MANGLED_NAME, scope_mangled) + .Replace(KW_CONTEXT, parent_scope_mangled) + .Replace(KW_UNQUALIFIED_NAME, scope_unqualified); - return SWIG_OK; + Printv(f_init_namespaces, t_create_ns.str(), 0); + // prepend in order to achieve reversed order of registration statements + Insert(f_init_register_namespaces, 0, t_register_ns.str()); +*/ + + return SWIG_OK; } -void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, int numarg, Wrapper *wrapper) { - String *tm; - Parm *p; - - bool is_member = (current_class_type != 0); - bool is_setter = IsSetterMethod(n); - bool is_function = (current_function_mangled != 0); - int start_idx; - if(is_member) { - start_idx = 1; - } else { - start_idx = 0; - } - - // retrieve this pointer for member functions - if(is_member) { - - Template t_selfptr(GetTemplate(V8_THIS_PTR)); - String *type_str = SwigType_strip_qualifiers(SwigType_str(current_class_type,0)); - String *arg_str; - if(is_function) { - arg_str = NewString("args"); - } else { - arg_str = NewString("info"); - } - - t_selfptr.Replace(KW_TYPE, type_str) - .Replace(KW_ARG, arg_str); - Printv(wrapper->code, t_selfptr.str(), 0); - - Delete(type_str); - Delete(arg_str); - } - - int i = 0; - for (i = 0, p = parms; i < numarg; i++) - { - p = skipIgnoredArgs(p); - SwigType *pt = Getattr(p, "type"); - - String *arg = NewString(""); - if (i == 0) { - if(start_idx == 0) { - Printv(arg, is_setter?"value":"args[0]", 0); - } else { - p = Getattr(p, "tmap:in:next"); - Delete(arg); - continue; // special case: skip the typemaps for the first argument - } - } else { - Printf(arg, is_setter?"value":"args[%d]", i - start_idx); - } - - if ((tm = Getattr(p, "tmap:in"))) // Get typemap for this argument - { - Replaceall(tm, "$input", arg); - Setattr(p, "emit:input", arg); - Printf(wrapper->code, "%s\n", tm); - p = Getattr(p, "tmap:in:next"); - } 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)); - p = nextSibling(p); - } - Delete(arg); - } -} - -void V8Emitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { - SwigType *type = Getattr(n, "type"); - Setattr(n, "type", type); - String *tm; - if ((tm = Swig_typemap_lookup_out("out", n, "result", wrapper, actioncode))) - { - Replaceall(tm, "$result", "jsresult"); - // TODO: May not be the correct way - Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); - Printf(wrapper->code, "%s", tm); - if (Len(tm)) - Printf(wrapper->code, "\n"); - } else { - Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name")); - } - emit_return_variable(n, type, wrapper); -} - -*/ JSEmitter *swig_javascript_create_V8Emitter() { - return 0; + return new V8Emitter(); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ol...@us...> - 2012-09-08 01:06:45
|
Revision: 13792 http://swig.svn.sourceforge.net/swig/?rev=13792&view=rev Author: oliv3rb Date: 2012-09-08 01:06:39 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Minor refactor of marshalInputArgs for generalization. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 01:06:26 UTC (rev 13791) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 01:06:39 UTC (rev 13792) @@ -261,6 +261,8 @@ virtual int emitSetter(Node *n, bool is_member, bool is_static); virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) = 0; + + virtual void emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg); virtual void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); @@ -931,7 +933,6 @@ * --------------------------------------------------------------------- */ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { - String *tm; Parm *p; // determine an offset index, as members have an extra 'this' argument @@ -950,9 +951,7 @@ // process arguments int i = 0; for (p = parms; p; p = nextSibling(p), i++) { - SwigType *pt = Getattr(p, "type"); String *arg = NewString(""); - switch (mode) { case Getter: case Function: @@ -975,23 +974,7 @@ default: throw "Illegal state."; } - - tm = Getattr(p, "tmap:in"); // Get typemap for this argument - if (tm != NULL) { - Replaceall(tm, "$input", arg); - Setattr(p, "emit:input", arg); - - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - 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)); - } + emitInputTypemap(n, p, wrapper, arg); Delete(arg); } } @@ -1464,6 +1447,28 @@ return SWIG_OK; } +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"); + + 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"); + } else { + Replaceall(tm, "$disown", "0"); + } + 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)); + } +} + void JSEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { SwigType *type = Getattr(n, "type"); Setattr(n, "type", type); @@ -1825,7 +1830,6 @@ } void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { - String *tm; Parm *p; int startIdx = 0; @@ -1833,9 +1837,14 @@ startIdx = 1; } + // store number of arguments for argument checks + int num_args = emit_num_arguments(parms) - startIdx; + String *argcount = NewString(""); + Printf(argcount, "%d", num_args); + Setattr(n, ARGCOUNT, argcount); + int i = 0; for (p = parms; p; p = nextSibling(p), i++) { - SwigType *pt = Getattr(p, "type"); String *arg = NewString(""); switch (mode) { @@ -1866,23 +1875,7 @@ default: throw "Illegal state."; } - - tm = Getattr(p, "tmap:in"); // Get typemap for this argument - if (tm != NULL) { - Replaceall(tm, "$input", arg); - Setattr(p, "emit:input", arg); - - if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); - } else { - Replaceall(tm, "$disown", "0"); - } - 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)); - } + emitInputTypemap(n, p, wrapper, arg); Delete(arg); } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ol...@us...> - 2012-09-08 01:10:16
|
Revision: 13805 http://swig.svn.sourceforge.net/swig/?rev=13805&view=rev Author: oliv3rb Date: 2012-09-08 01:10:10 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Fix string warnings of for char* constants in CPP wrappers. This has been done by changing the implementation of marshalOutputArgs, which now does not create a local result variable in this case, and uses the constant inline in the output typemap. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 01:09:57 UTC (rev 13804) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 01:10:10 UTC (rev 13805) @@ -265,7 +265,7 @@ virtual void emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg); - virtual void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); + virtual void marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, const String *cresult=0, bool emitReturnVariable = true); /** * Helper function to retrieve the first parent class node. @@ -291,6 +291,8 @@ // which are switched on namespace change Hash *namespaces; Hash *current_namespace; + + String *defaultResultName; File *f_wrappers; @@ -595,6 +597,7 @@ : templates(NewHash()), namespaces(NULL), current_namespace(NULL), + defaultResultName(NewString("result")), f_wrappers(NULL) { } @@ -872,7 +875,7 @@ // prepare code part String *action = emit_action(n); marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); - marshalOutput(n, action, wrapper); + marshalOutput(n, wrapper, action); t_getter.replace(T_GETTER, wrap_name) .replace(T_LOCALS, wrapper->locals) @@ -927,7 +930,7 @@ int JSEmitter::emitConstant(Node *n) { Wrapper *wrapper = NewWrapper(); - + Template t_getter(getTemplate("JS_getproperty")); // call the variable methods as a constants are @@ -944,13 +947,10 @@ String *value = Getattr(n, "rawval"); if (value == NULL) { value = Getattr(n, "rawvalue"); + if (value == NULL) value = Getattr(n, "value"); } - if (value == NULL) { - value = Getattr(n, "value"); - } - Printf(action, "result = %s;\n", value); - Setattr(n, "wrap:action", action); - marshalOutput(n, action, wrapper); + assert(value != NULL); + marshalOutput(n, wrapper, action, value, false); t_getter.replace(T_GETTER, wrap_name) .replace(T_LOCALS, wrapper->locals) @@ -988,7 +988,7 @@ // prepare code part String *action = emit_action(n); marshalInputArgs(n, params, wrapper, Function, is_member, is_static); - marshalOutput(n, action, wrapper); + marshalOutput(n, wrapper, action); t_function.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) @@ -1059,17 +1059,21 @@ } } -void JSEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { +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; - + // HACK: output types are not registered as swig_types automatically - if (SwigType_ispointer(type)) { - SwigType_remember_clientdata(type, NewString("0")); - } + if (SwigType_ispointer(type)) SwigType_remember_clientdata(type, NewString("0")); - if ((tm = Swig_typemap_lookup_out("out", n, "result", wrapper, actioncode))) { + // 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))) { Replaceall(tm, "$result", "jsresult"); Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); @@ -1086,7 +1090,6 @@ } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name")); } - emit_return_variable(n, type, wrapper); } int JSEmitter::switchNamespace(Node *n) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ol...@us...> - 2012-09-08 01:17:00
|
Revision: 13830 http://swig.svn.sourceforge.net/swig/?rev=13830&view=rev Author: oliv3rb Date: 2012-09-08 01:16:54 +0000 (Sat, 08 Sep 2012) Log Message: ----------- Beautify output of v8 emitter. Trimming some of the code templates. Modified Paths: -------------- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx Modified: branches/oliverb-javascript-v8/Source/Modules/javascript.cxx =================================================================== --- branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 01:16:42 UTC (rev 13829) +++ branches/oliverb-javascript-v8/Source/Modules/javascript.cxx 2012-09-08 01:16:54 UTC (rev 13830) @@ -114,10 +114,8 @@ void operator=(const Template& t); -protected: + Template& trim(); - void trim(); - private: String *code; @@ -1604,7 +1602,6 @@ virtual int exitClass(Node *n); virtual int enterVariable(Node *n); virtual int exitVariable(Node *n); - virtual int enterFunction(Node *n); virtual int exitFunction(Node *n); protected: @@ -1758,6 +1755,7 @@ // emit declaration of a v8 class template Template t_decl_class(getTemplate("jsv8_declare_class_template")); t_decl_class.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .trim() .pretty_print(f_class_templates); return SWIG_OK; @@ -1780,35 +1778,39 @@ // 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")); + 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, p_classtype_str) .replace(T_DTOR, state.clazz(DTOR)) + .trim() .pretty_print(f_init_class_templates); - Template t_class_instance(getTemplate("jsv8_create_class_instance")); + Template t_class_instance = getTemplate("jsv8_create_class_instance"); t_class_instance.replace(T_NAME, state.clazz(NAME)) .replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_CTOR, state.clazz(CTOR)) + .trim() .pretty_print(f_init_class_instances); // emit inheritance setup Node* baseClass = getBaseClass(n); if(baseClass) { - Template t_inherit(getTemplate("jsv8_inherit")); + Template t_inherit = getTemplate("jsv8_inherit"); String *base_name_mangled = SwigType_manglestr(Getattr(baseClass, "name")); t_inherit.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_BASECLASS, base_name_mangled) + .trim() .pretty_print(f_init_inheritance); Delete(base_name_mangled); } // emit registeration of class template - Template t_register(getTemplate("jsv8_register_class")); + Template t_register = getTemplate("jsv8_register_class"); t_register.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.clazz(NAME)) .replace(T_PARENT, Getattr(current_namespace, "name_mangled")) + .trim() .pretty_print(f_init_register_classes); return SWIG_OK; @@ -1828,40 +1830,37 @@ { if(GetFlag(n, "ismember")) { if(GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem") ) { - Template t_register(getTemplate("jsv8_register_static_variable")); + Template t_register = getTemplate("jsv8_register_static_variable"); t_register.replace(T_PARENT, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.variable(NAME)) .replace(T_GETTER, state.variable(GETTER)) .replace(T_SETTER, state.variable(SETTER)) + .trim() .pretty_print(f_init_static_wrappers); } else { - Template t_register(getTemplate("jsv8_register_member_variable")); + Template t_register = getTemplate("jsv8_register_member_variable"); t_register.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.variable(NAME)) .replace(T_GETTER, state.variable(GETTER)) .replace(T_SETTER, state.variable(SETTER)) + .trim() .pretty_print(f_init_wrappers); } } else { // Note: a global variable is treated like a static variable // with the parent being a nspace object (instead of class object) - Template t_register(getTemplate("jsv8_register_static_variable")); + Template t_register = getTemplate("jsv8_register_static_variable"); t_register.replace(T_PARENT, Getattr(current_namespace, NAME)) .replace(T_NAME, state.variable(NAME)) .replace(T_GETTER, state.variable(GETTER)) .replace(T_SETTER, state.variable(SETTER)) + .trim() .pretty_print(f_init_wrappers); } return SWIG_OK; } -int V8Emitter::enterFunction(Node* n) -{ - JSEmitter::enterFunction(n); - return SWIG_OK; -} - int V8Emitter::exitFunction(Node* n) { bool is_member = GetFlag(n, "ismember"); @@ -1881,25 +1880,28 @@ // register the function at the specific context if(is_member) { if(GetFlag(state.function(), IS_STATIC)) { - Template t_register(getTemplate("jsv8_register_static_function")); + Template t_register = getTemplate("jsv8_register_static_function"); t_register.replace(T_PARENT, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.function(NAME)) .replace(T_WRAPPER, state.function(WRAPPER_NAME)) + .trim() .pretty_print(f_init_static_wrappers); } else { - Template t_register(getTemplate("jsv8_register_member_function")); + Template t_register = getTemplate("jsv8_register_member_function"); t_register.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.function(NAME)) .replace(T_WRAPPER, state.function(WRAPPER_NAME)) + .trim() .pretty_print(f_init_wrappers); } } else { // Note: a global function is treated like a static function // with the parent being a nspace object instead of class object - Template t_register(getTemplate("jsv8_register_static_function")); + Template t_register = getTemplate("jsv8_register_static_function"); t_register.replace(T_PARENT, Getattr(current_namespace, NAME)) .replace(T_NAME, state.function(NAME)) .replace(T_WRAPPER, state.function(WRAPPER_NAME)) + .trim() .pretty_print(f_init_static_wrappers); } @@ -1966,14 +1968,16 @@ String *parent_mangled = Swig_name_mangle(parent); // create namespace object and register it to the parent scope - Template t_create_ns(getTemplate("jsv8_create_namespace")); + Template t_create_ns = getTemplate("jsv8_create_namespace"); t_create_ns.replace(T_NAME_MANGLED, name_mangled) + .trim() .pretty_print(f_init_namespaces); - Template t_register_ns(getTemplate("jsv8_register_namespace")); + Template t_register_ns = getTemplate("jsv8_register_namespace"); t_register_ns.replace(T_NAME_MANGLED, name_mangled) .replace(T_NAME, name) - .replace(T_PARENT, parent_mangled); + .replace(T_PARENT, parent_mangled) + .trim(); // prepend in order to achieve reversed order of registration statements Insert(f_init_register_namespaces, 0, t_register_ns.str()); @@ -2001,6 +2005,7 @@ // emit clientData declaration Template clientDataDecl = getTemplate("jsv8_declare_class_template"); clientDataDecl.replace(T_NAME_MANGLED, mangled_name) + .trim() .pretty_print(f_class_templates); // emit an extra dtor for unknown types @@ -2008,6 +2013,7 @@ t_dtor.replace(T_NAME_MANGLED, mangled_name) .replace(T_WRAPPER, dtor) .replace(T_FREE, free) + .trim() .pretty_print(f_wrappers); // create a class template and initialize clientData @@ -2016,6 +2022,7 @@ .replace(T_NAME, mangled_name) .replace(T_TYPE_MANGLED, type_mangled) .replace(T_DTOR, dtor) + .trim() .pretty_print(f_init_class_templates); Delete(mangled_name); @@ -2137,8 +2144,6 @@ } code = NewString(code_); templateName = NewString(""); - - trim(); } Template::Template(const String *code_, const String *templateName_) { @@ -2150,8 +2155,6 @@ code = NewString(code_); templateName = NewString(templateName_); - - trim(); } @@ -2186,22 +2189,22 @@ return code; } -void Template::trim() { +Template& Template::trim() { const char* str = Char(code); - if (str == 0) return; + if (str == 0) return *this; int length = Len(code); - if (length == 0) return; + if (length == 0) return *this; int idx; for(idx=0; idx < length; ++idx) { - if (str[idx] == ' ' || str[idx] == '\t' || str[idx] == '\r' || str[idx] == '\n') + if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n') break; } int start_pos = idx; for(idx=length-1; idx >= start_pos; --idx) { - if (str[idx] == ' ' || str[idx] == '\t' || str[idx] == '\r' || str[idx] == '\n') + if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n') break; } int end_pos = idx; @@ -2214,6 +2217,8 @@ Delete(code); code = NewString(newstr); delete[] newstr; + + return *this; } /* ----------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |