From d6060ceced397c2dd3baaba94c783d0045ddc38e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 11 May 2012 13:55:16 +0000 Subject: [PATCH 001/352] Add copyright entry for Oliver Buchtala. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13067 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- COPYRIGHT | 1 + 1 file changed, 1 insertion(+) diff --git a/COPYRIGHT b/COPYRIGHT index 2fe0099b8..774761a48 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -60,6 +60,7 @@ Past SWIG developers and major contributors include: Ian Lance Taylor (Go) Vadim Zeitlin (PCRE) Stefan Zager (szager@gmail.com) (Python) + Oliver Buchtala (Javascript) Past contributors include: James Michael DuPont, Clark McGrew, Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran From c86ce942c2d0498169d4371bdd6c9acd503fdffa Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 11 May 2012 19:20:07 +0000 Subject: [PATCH 002/352] Correct place of copyright entry. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13070 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- COPYRIGHT | 1 + 1 file changed, 1 insertion(+) diff --git a/COPYRIGHT b/COPYRIGHT index 774761a48..173d1807d 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -16,6 +16,7 @@ Active SWIG Developers: Joseph Wang (joequant@gmail.com) (R) Xavier Delacour (xavier.delacour@gmail.com) (Octave) David Nadlinger (code@klickverbot.at) (D) + Oliver Buchtala (Javascript) Past SWIG developers and major contributors include: Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl) From d71a5f483a6ad3307ff306ce2c72cfcd0e361556 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:44:54 +0000 Subject: [PATCH 003/352] Add module for Javascript target. This module comes with a design that allows different code emitter implementations. For the the phase of development the module is split into multiple files which will be merged together when development converges. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13737 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/javascript.swg | 15 ++ Lib/javascript/javascriptkw.swg | 40 +++++ Source/Makefile.am | 2 + Source/Modules/javascript.cxx | 246 ++++++++++++++++++++++++++ Source/Modules/javascript_emitter.cxx | 198 +++++++++++++++++++++ Source/Modules/javascript_emitter.h | 139 +++++++++++++++ Source/Modules/swigmain.cxx | 2 + 7 files changed, 642 insertions(+) create mode 100644 Lib/javascript/javascript.swg create mode 100644 Lib/javascript/javascriptkw.swg create mode 100644 Source/Modules/javascript.cxx create mode 100644 Source/Modules/javascript_emitter.cxx create mode 100644 Source/Modules/javascript_emitter.h diff --git a/Lib/javascript/javascript.swg b/Lib/javascript/javascript.swg new file mode 100644 index 000000000..fb01a63bb --- /dev/null +++ b/Lib/javascript/javascript.swg @@ -0,0 +1,15 @@ +/* ----------------------------------------------------------------------------- + * javascript.swg + * + * Javascript typemaps + * ----------------------------------------------------------------------------- */ + +%include + +%include + +%include + +%include + +%include diff --git a/Lib/javascript/javascriptkw.swg b/Lib/javascript/javascriptkw.swg new file mode 100644 index 000000000..c3c118391 --- /dev/null +++ b/Lib/javascript/javascriptkw.swg @@ -0,0 +1,40 @@ +#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_ +#define JAVASCRIPT_JAVASCRIPTKW_SWG_ + +/* Warnings for Java keywords */ +#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s") `x` + +/* Taken from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Reserved_Words */ + +JAVASCRIPTKW(break); +JAVASCRIPTKW(case); +JAVASCRIPTKW(catch); +JAVASCRIPTKW(continue); +JAVASCRIPTKW(default); +JAVASCRIPTKW(delete); +JAVASCRIPTKW(do); +JAVASCRIPTKW(else); +JAVASCRIPTKW(finally); +JAVASCRIPTKW(for); +JAVASCRIPTKW(function); +JAVASCRIPTKW(if); +JAVASCRIPTKW(in); +JAVASCRIPTKW(instanceof); +JAVASCRIPTKW(new); +JAVASCRIPTKW(return); +JAVASCRIPTKW(switch); +JAVASCRIPTKW(this); +JAVASCRIPTKW(throw); +JAVASCRIPTKW(try); +JAVASCRIPTKW(typeof); +JAVASCRIPTKW(var); +JAVASCRIPTKW(void); +JAVASCRIPTKW(while); +JAVASCRIPTKW(with); + +/* others bad names if any*/ +// for example %namewarn("321:clone() is a javascript bad method name") *::clone(); + +#undef JAVASCRIPTKW + +#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_ diff --git a/Source/Makefile.am b/Source/Makefile.am index 984b9c268..fa11bfdcb 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -49,6 +49,8 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/guile.cxx \ Modules/java.cxx \ Modules/lang.cxx \ + Modules/javascript.cxx \ + Modules/javascript_emitter.cxx \ Modules/lua.cxx \ Modules/main.cxx \ Modules/modula3.cxx \ diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx new file mode 100644 index 000000000..e1336d82a --- /dev/null +++ b/Source/Modules/javascript.cxx @@ -0,0 +1,246 @@ +#include "swigmod.h" + +#include +#include +#include + +#include "javascript_emitter.h" + +/* ******************************************************************** + * JAVASCRIPT + * ********************************************************************/ + +class JAVASCRIPT : public Language { + +public: + JAVASCRIPT() {} + ~JAVASCRIPT() {} + + virtual int functionHandler(Node *n); + virtual int globalfunctionHandler(Node *n); + virtual int variableHandler(Node *n); + virtual int globalvariableHandler(Node *n); + virtual int classHandler(Node *n); + virtual int functionWrapper(Node *n); + + /** + * Registers all %fragments assigned to section "templates" with the Emitter. + **/ + virtual int fragmentDirective(Node *n); + + virtual void main(int argc, char *argv[]); + virtual int top(Node *n); + +private: + + JSEmitter* emitter; +}; + +/* --------------------------------------------------------------------- + * functionWrapper() + * + * Low level code generator for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::functionWrapper(Node *n) { + + Language::functionWrapper(n); + + emitter->EmitWrapperFunction(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * functionHandler() + * + * Function handler for generating wrappers for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::functionHandler(Node *n) { + + emitter->EnterFunction(n); + + Language::functionHandler(n); + + emitter->ExitFunction(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * globalfunctionHandler() + * + * Function handler for generating wrappers for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::globalfunctionHandler(Node *n) { + emitter->SwitchContext(n); + + Language::globalfunctionHandler(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * variableHandler() + * + * Function handler for generating wrappers for variables + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::variableHandler(Node *n) { + + emitter->EnterVariable(n); + + Language::variableHandler(n); + + emitter->ExitVariable(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * globalvariableHandler() + * + * Function handler for generating wrappers for global variables + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::globalvariableHandler(Node *n) { + + emitter->SwitchContext(n); + + Language::globalvariableHandler(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * classHandler() + * + * Function handler for generating wrappers for class + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::classHandler(Node *n) { + emitter->SwitchContext(n); + + emitter->EnterClass(n); + Language::classHandler(n); + emitter->ExitClass(n); + + return SWIG_OK; +} + +int JAVASCRIPT::fragmentDirective(Node *n) { + + // catch all fragment directives that have "templates" as location + // and register them at the emitter. + String *section = Getattr(n, "section"); + + if(Cmp(section, "templates") == 0) { + emitter->RegisterTemplate(Getattr(n, "value"), Getattr(n, "code")); + } else { + Swig_fragment_register(n); + } + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * top() + * + * Function handler for processing top node of the parse tree + * Wrapper code generation essentially starts from here + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::top(Node *n) { + + emitter->Initialize(n); + + Language::top(n); + + emitter->Dump(n); + emitter->Close(); + + delete emitter; + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * main() + * + * Entry point for the JAVASCRIPT module + * --------------------------------------------------------------------- */ + +void JAVASCRIPT::main(int argc, char *argv[]) { + + const char* lib_dir; + + // Set javascript subdirectory in SWIG library + SWIG_library_directory("javascript"); + + int mode = -1; + + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i], "-v8") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + } else if (strcmp(argv[i], "-jsc") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::JavascriptCore; + SWIG_library_directory("javascript/jsc"); + } else if (strcmp(argv[i], "-qt") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::QtScript; + SWIG_library_directory("javascript/qt"); + } + } + } + + switch(mode) { + case JSEmitter::V8: + { + // TODO: emitter = create_v8_emitter(); + break; + } + case JSEmitter::JavascriptCore: + { + // TODO: emitter = create_jsc_emitter(); + break; + } + case JSEmitter::QtScript: + { + // TODO: emitter = create_qtscript_emitter(); + break; + } + default: + { + Printf(stderr, "Unknown emitter type."); + SWIG_exit(-1); + } + } + + + // Add a symbol to the parser for conditional compilation + Preprocessor_define("SWIGJAVASCRIPT 1", 0); + + // Add typemap definitions + SWIG_typemap_lang("javascript"); + + // Set configuration file + SWIG_config_file("javascript.swg"); + + allow_overloading(); +} + +/* ----------------------------------------------------------------------------- + * swig_JAVASCRIPT() - Instantiate module + * ----------------------------------------------------------------------------- */ + +static Language *new_swig_javascript() { + return new JAVASCRIPT(); +} + +extern "C" Language *swig_javascript(void) { + return new_swig_javascript(); +} diff --git a/Source/Modules/javascript_emitter.cxx b/Source/Modules/javascript_emitter.cxx new file mode 100644 index 000000000..7b49aaf5d --- /dev/null +++ b/Source/Modules/javascript_emitter.cxx @@ -0,0 +1,198 @@ +#include "javascript_emitter.h" + +#include "swigmod.h" + +/* ----------------------------------------------------------------------------- + * JSEmitter() + * ----------------------------------------------------------------------------- */ + +JSEmitter::JSEmitter() + : empty_string(NewString("")) +{ + templates = NewHash(); +} + +/* ----------------------------------------------------------------------------- + * ~JSEmitter() + * ----------------------------------------------------------------------------- */ + +JSEmitter::~JSEmitter() +{ + Delete(empty_string); + Delete(templates); +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::RegisterTemplate() : Registers a code template + * ----------------------------------------------------------------------------- */ + +int JSEmitter::RegisterTemplate(const String *name, const String *code) +{ + return Setattr(templates, name, code); +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::GetTemplate() : Retrieves a registered a code template + * ----------------------------------------------------------------------------- */ + +const String* JSEmitter::GetTemplate(const String *name) +{ + String* templ = Getattr(templates, name); + + if(!templ) { + Printf(stderr, "Could not find template %s\n.", name); + SWIG_exit(EXIT_FAILURE); + } + + return templ; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::typemapLookup() + * n - for input only and must contain info for Getfile(n) and Getline(n) to work + * tmap_method - typemap method name + * type - typemap type to lookup + * warning - warning number to issue if no typemaps found + * typemap_attributes - the typemap attributes are attached to this node and will + * also be used for temporary storage if non null + * return is never NULL, unlike Swig_typemap_lookup() + * ----------------------------------------------------------------------------- */ + +const String *JSEmitter::typemapLookup(Node *n, const_String_or_char_ptr tmap_method, + SwigType *type, int warning, Node *typemap_attributes) { + Node *node = !typemap_attributes ? NewHash() : typemap_attributes; + Setattr(node, "type", type); + Setfile(node, Getfile(n)); + Setline(node, Getline(n)); + const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); + if (!tm) { + tm = empty_string; + if (warning != WARN_NONE) { + Swig_warning(warning, Getfile(n), Getline(n), + "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); + } + } + if (!typemap_attributes) { + Delete(node); + } + return tm; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::GetBaseClass() : the node of the base class or NULL + * ----------------------------------------------------------------------------- */ + +Node* JSEmitter::GetBaseClass(Node* n) +{ + // retrieve the first base class that is not %ignored + List *baselist = Getattr(n, "bases"); + if (baselist) { + Iterator base = First(baselist); + while (base.item && GetFlag(base.item, "feature:ignore")) { + base = Next(base); + } + + return base.item; + } + + return NULL; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::EmitWrapperFunction() : dispatches emitter functions + * ----------------------------------------------------------------------------- */ + +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) { + bool is_member = GetFlag(n, "ismember"); + if( Cmp(kind, "function") == 0 ) { + ret = EmitFunction(n, is_member); + } else if (Cmp(kind, "variable") == 0) { + if(IsSetterMethod(n)) { + ret = EmitSetter(n, is_member); + } else { + ret = EmitGetter(n, is_member); + } + } else { + Printf(stderr, "Warning: unsupported wrapper function type\n"); + Swig_print_node(n); + } + } else { + String *view = Getattr(n, "view"); + + if( Cmp(view, "constructorHandler") == 0 ) { + ret = EmitCtor(n); + + } else if( Cmp(view, "destructorHandler") == 0 ) { + ret = EmitDtor(n); + + } else { + Printf(stderr, "Warning: unsupported wrapper function type"); + Swig_print_node(n); + } + } + + DelWrapper(current_wrapper); + current_wrapper = 0; + + return ret; +} + +/* ----------------------------------------------------------------------------- + * str_ends_with() : c string helper to check suffix match + * ----------------------------------------------------------------------------- */ + +// TODO: shift this to DOH string API +int 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 ( str_ends_with( (char*) Data(symname), "_set") != 0 ); +} + +Template::Template(const String* code) +{ + if(!code) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + + m_code = NewString(code); +} + +Template::~Template() { + Delete(m_code); +} + +String* Template::str() { + return m_code; +} + +Template& Template::Replace(const String* pattern, const String* repl) { + ::Replaceall(m_code, pattern, repl); + return *this; +} diff --git a/Source/Modules/javascript_emitter.h b/Source/Modules/javascript_emitter.h new file mode 100644 index 000000000..b73bb55b4 --- /dev/null +++ b/Source/Modules/javascript_emitter.h @@ -0,0 +1,139 @@ +#ifndef JAVASCRIPT_EMITTER_H +#define JAVASCRIPT_EMITTER_H + +#include "swigmod.h" + +/** + * A class that wraps a code snippet used as template for code generation. + */ +class Template { + +public: + Template(const String* code); + + ~Template(); + + String* str(); + + Template& Replace(const String* pattern, const String* repl); + +private: + String* m_code; +}; + +class JSEmitter { + +public: + + enum JSEmitterType { + JavascriptCore, + V8, + QtScript + }; + + JSEmitter(); + + virtual ~JSEmitter(); + + /** + * Opens output files and temporary output DOHs. + */ + virtual int Initialize(Node *n) = 0; + + /** + * Writes all collected code into the output file(s). + */ + virtual int Dump(Node *n) = 0; + + /** + * Cleans up all open output DOHs. + */ + virtual int Close() = 0; + + /** + * Switches the context for code generation. + * + * Classes, global variables and global functions may need to + * be registered in certain static tables. + * This method should be used to switch output DOHs correspondingly. + */ + virtual int SwitchContext(Node *n) { return SWIG_OK; }; + + /** + * Invoked at the beginning of the classHandler. + */ + virtual int EnterClass(Node *n) { return SWIG_OK; }; + + /** + * Invoked at the end of the classHandler. + */ + virtual int ExitClass(Node *n) { return SWIG_OK; }; + + /** + * Invoked at the beginning of the variableHandler. + */ + virtual int EnterVariable(Node *n) { return SWIG_OK; }; + + /** + * Invoked at the end of the variableHandler. + */ + virtual int ExitVariable(Node *n) { return SWIG_OK; }; + + /** + * Invoked at the beginning of the functionHandler. + */ + virtual int EnterFunction(Node *n) { return SWIG_OK; }; + + /** + * Invoked at the end of the functionHandler. + */ + virtual int ExitFunction(Node *n) { return SWIG_OK; }; + + /** + * Invoked by functionWrapper callback after call to Language::functionWrapper. + */ + virtual int EmitWrapperFunction(Node *n); + + /** + * Registers a given code snippet for a given key name. + * + * This method is called by the fragmentDirective handler + * of the JAVASCRIPT language module. + */ + int RegisterTemplate(const String *name, const String *code); + + /** + * Retrieve the code template registered for a given name. + */ + const String* GetTemplate(const String *name); + +protected: + + virtual int EmitCtor(Node *n) = 0; + + virtual int EmitDtor(Node *n) = 0; + + virtual int EmitFunction(Node *n, bool is_member) = 0; + + virtual int EmitGetter(Node *n, bool is_member) = 0; + + virtual int EmitSetter(Node *n, bool is_member) = 0; + + bool IsSetterMethod(Node *n); + + Node* GetBaseClass(Node *n); + + const String* typemapLookup(Node *n, const_String_or_char_ptr tmap_method, + SwigType *type, int warning, Node *typemap_attributes = 0); + +protected: + + // empty string used at different places in the code + String *empty_string; + + Hash *templates; + + Wrapper* current_wrapper; +}; + +#endif // JAVASCRIPT_EMITTER_H diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 01ab1b79f..f4c86addc 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -53,6 +53,7 @@ extern "C" { Language *swig_r(void); Language *swig_go(void); Language *swig_d(void); + Language *swig_javascript(void); } struct swig_module { @@ -94,6 +95,7 @@ static swig_module modules[] = { {"-tcl8", swig_tcl, 0}, {"-uffi", swig_uffi, "Common Lisp / UFFI"}, {"-xml", swig_xml, "XML"}, + {"-javascript", swig_javascript, "Javascript"}, {NULL, NULL, NULL} }; From ba40fffd91bc07fc5020fe7870a6104863a39f94 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:45:35 +0000 Subject: [PATCH 004/352] Add initial specification of code generator templates for V8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13738 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 290 ++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md new file mode 100644 index 000000000..b8e2b8a78 --- /dev/null +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -0,0 +1,290 @@ +Javascript: Specification of a Code Generator for V8 +==================================================== + +The aim of this is to evolve a specification for a code generator. + +## Top Level structure + +The generated code consists of the following blocks: + +~~~~ + + + + + + + + + + +~~~~ + +- `HELPER_FUNCTIONS`: static, from swg-file +- `INCLUDES`: static, module property +- `CLASS_TEMPLATES`: dynamically growing, on class declarations +- `FUNCTION_WRAPPERS`: dynamically growing, on method declarations +- `INITIALIZER`: dynamically growing, aggregates everything (to be specified in more detail) + +## INCLUDES + +~~~~ +#include + + +~~~~ + +`USER_DEFINED_INCLUDES`: a module property + +## CLASS_TEMPLATES + +Static references to class templates which are (should be) read-only and can be reused. + +~~~~ +v8::Persistent SWIGV8_$CLASSNAME; +~~~~ + +Notes: + - it is very important to consider namespaces from the beginning. + `CLASSNAME` should be fully canonical, e.g., `foo_bar_MyClass` for `foo::bar::MyClass` + - namespaces do not need a function template, as they will not be + instantiated + +## FUNCTION_WRAPPERS + +There are different types of function wrappers: + + - Static Functions (global/namespace/class) + - Constructors / Destructors + - Getters / Settters + - Member Functions + +## Static Functions + +TODO + +## Constructors + +~~~~ +v8::Handle $CLASSNAME_new(const v8::Arguments& args) { + v8::HandleScope scope; + + // retrieve the instance + v8::Handle self = args.Holder(); + + // TODO: declare arguments + + //convert JS arguments to C++ + // TODO: apply input typemaps + + $CLASS_LVAL* ptr = new $CLASS_LVAL($ARGS); + self->SetInternalField(0, v8::External::New(ptr)); + + return self; +} +~~~~ + +- `$CLASS_LVAL`: should be the canonical name of the class, e.g. `ns1::ns2::MyClass` +- `$ARGS`: arguments should be declared at the beginning and checked and set in the + input typemap block + +## Destructors + +TODO + +## Getters + +~~~~ +v8::Handle $CLASSNAME_get$VARNAME(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + + // retrieve pointer to C++-this + $CLASS_LVAL* self = SWIGV8_UnwrapThisPointer<$CLASS_LVAL>(info.Holder()); + $RET_LVAL retval = self->$VARNAME; + + v8::Handle ret = ; + return scope.Close(ret); +} +~~~~ + +- TODO: output typemapping + +## Setters + +~~~~ +void $CLASSNAME_set$VARNAME(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + + // retrieve pointer to this + $CLASS_LVAL* self = SWIGV8_UnwrapThisPointer<$CLASS_LVAL>(info.Holder()); + + // TODO: declare input arg + + // map java-script type to C++ type + self->$VARNAME = ; + +} +~~~~ + +TODO: + - input type mapping should be addressed in extra step, together with type check + +## Member functions + +~~~~ +v8::Handle $CLASSNAME_$FUNCTIONNAME(const v8::Arguments& args) +{ + v8::HandleScope scope; + + $CLASS_LVAL* self = SWIGV8_UnwrapThisPointer<$CLASS_LVAL>(args.Holder()); + + // TODO: declare input args + + //convert JS arguments to C++ + // TODO: input typemappings and type checking + + //call C++ method + $RET_LTYPE result = self->$FUNCTIONNAME($ARGS); + + //convert C++ JS arguments to C++ + v8::Handle ret = ; + + return scope.Close(ret); +} +~~~~ + +- if the function does not have a return value, return v8::Undefined + +## Initializer + +~~~~ +void $MODULENAME_Initialize(v8::Handle context) +{ + v8::HandleScope scope; + + // register the module in globale context + v8::Local global = context->Global(); + + + + + + + + + + +} +~~~~ + +## Namespaces + +Namespaces are objects without class templates. I.e., instances are created, +referenced locally, used as contexts for other registrations, and stored +in the according parent contexts. + +## Create Class Template + +~~~~ + SWIGV8_$CLASSNAME = SWIGV8_CreateClassTemplate("$LOCAL_CLASSNAME" , $CLASSNAME_new); +~~~~ + +- `LOCAL_CLASSNAME`: the class name without context, i.e., namespaces + +## Add Member Function + +~~~~ + SWIGV8_AddClassMethod(SWIGV8_$CLASSNAME, "$METHODNAME", $METHOD_WRAPPER); +~~~~ + +- `METHODNAME`: the name of the function as in C++ +- `METHOD_WRAPPER`: the name of the generated wrapper function + TODO: specify different versions + +## Add Property + +~~~~ + SWIGV8_AddProperty(SWIGV8_$CLASSNAME, "$VARNAME", $GET_WRAPPER, $SET_WRAPPER); +~~~~ + +- `GET_WRAPPER`: the name of the generated wrapper for the property getter +- `SET_WRAPPER`: the name of the generated wrapper for property setter; optional (i.e., maybe `NULL`) + +## Inheritance + +~~~~ + SWIGV8_$CLASSNAME->Inherit(SWIGV8_$SUPERCLASS); +~~~~ + +- Note: multiple inheritance is not possible; thus we will always take the first parent class + +## Register class + +~~~~ + $CONTEXT->Set(v8::String::NewSymbol("$LOCAL_CLASSNAME"), SWIGV8_$CLASSNAME->GetFunction()); +~~~~ + +- Note: every class template has an associated ctor function wrapper, which is registered here +- `CONTEXT`: either global, or the according namespace instance + +## HELPER_FUNCTIONS + +A lot of boiler-plate code can be shifted into static helper functions: + +~~~~ + +/** + * Creates a class template for a class without extra initialization function. + */ +v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol) { + v8::Local class_templ = v8::FunctionTemplate::New(); + class_templ->SetClassName(v8::String::NewSymbol(symbol)); + + v8::Handle inst_templ = class_templ->InstanceTemplate(); + inst_templ->SetInternalFieldCount(1); + + return v8::Persistent::New(class_templ); +} + +/** + * Creates a class template for a class with specified initialization function. + */ +v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol, v8::InvocationCallback _func) { + v8::Local class_templ = v8::FunctionTemplate::New(_func); + class_templ->SetClassName(v8::String::NewSymbol(symbol)); + + v8::Handle inst_templ = class_templ->InstanceTemplate(); + inst_templ->SetInternalFieldCount(1); + + return v8::Persistent::New(class_templ); +} + +/** + * Sets the pimpl data of a V8 class. + */ +v8::Handle V8GeneratorUtils::SetInstance(const v8::Arguments& args, void* data) { + v8::HandleScope scope; + + v8::Handle self = args.Holder(); + self->SetInternalField(0, v8::External::New(data)); + + return self; +} + +/** + * Registers a class method with given name for a given class template. + */ +void V8GeneratorUtils::AddClassMethod(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { + v8::Handle proto_templ = class_templ->PrototypeTemplate(); + proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); +} + +/** + * Registers a class property with given name for a given class template. + */ +void V8GeneratorUtils::AddProperty(v8::Handle class_templ, const char* varname, v8::AccessorGetter getter, v8::AccessorSetter setter) { + v8::Handle proto_templ = class_templ->InstanceTemplate(); + proto_templ->SetAccessor(v8::String::New(varname), getter, setter); +} + +~~~~ From 5c3fef6367ba41982032dea8a2b29f6a7f62de9f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:45:49 +0000 Subject: [PATCH 005/352] Add initial version of a CMake configuration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13739 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CMakeLists.txt | 175 +++++++++++++++++++++++++++++++++++++++ Tools/swigconfig.h.cmake | 89 ++++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 Tools/swigconfig.h.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..442fa6d6a --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,175 @@ +project(swig) +cmake_minimum_required(VERSION 2.8) + +# Project wide configuration variables +# ------------------------------------ + +set(SWIG_VERSION 2.0.6) +set(SWIG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Source" CACHE INTERNAL "Path of swig sources" FORCE) + +# Configure +# --------- + +include(CheckIncludeFiles) +include(CheckIncludeFile) +include(CheckTypeSize) +include(CheckSymbolExists) +include(CheckLibraryExists) +include(CheckCSourceCompiles) + +# HACK: didn't get the bool check working for Visual Studio 2008 +if(MSVC) +set(HAVE_BOOL 1) +else() +set(CMAKE_EXTRA_INCLUDE_FILES stdbool.h) +check_type_size("bool" HAVE_BOOL) +set(CMAKE_EXTRA_INCLUDE_FILES) +endif() + +check_include_file("inttypes.h" HAVE_INTTYPES_H) +check_include_file("memory.h" HAVE_MEMORY_H) +check_include_file("stddef.h" HAVE_STDDEF_H) +check_include_file("stdint.h" HAVE_STDINT_H) +check_include_file("stdlib.h" HAVE_STDLIB_H) +check_include_file("string.h" HAVE_STRING_H) +check_include_file("strings.h" HAVE_STRINGS_H) +check_include_file("sys/stat.h" HAVE_SYS_STAT_H) +check_include_file("sys/types.h" HAVE_SYS_TYPES_H) +check_include_file("unistd.h" HAVE_UNISTD_H) +check_include_files( "stdlib.h;stdarg.h;string.h;float.h" HAVE_STDC_HEADERS ) + +check_library_exists(dl dlopen "" HAVE_LIBDL) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Tools/swigconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/Source/Include/swigconfig.h) + +# Compiler flags +# -------------- + +include_directories("${SWIG_SOURCE_DIR}/CParse" + "${SWIG_SOURCE_DIR}/Include" + "${SWIG_SOURCE_DIR}/DOH" + "${SWIG_SOURCE_DIR}/Swig" + "${SWIG_SOURCE_DIR}/Preprocessor" + "${SWIG_SOURCE_DIR}/Modules" + "${PROJECT_BINARY_DIR}/Source/Include" +) + +# Pre-Build +# --------- + +# Copy Lib directory into the build dist folder +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Dist) +file(COPY ${PROJECT_SOURCE_DIR}/Lib DESTINATION ${PROJECT_BINARY_DIR}/Dist) + +# add the command to generate the source code (depends on bison) +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Source/CParse) +add_custom_command ( + OUTPUT ${PROJECT_BINARY_DIR}/Source/CParse/parser.c + DEPENDS ${SWIG_SOURCE_DIR}/CParse/parser.y + COMMAND bison -o ${PROJECT_BINARY_DIR}/Source/CParse/parser.c --defines=${PROJECT_BINARY_DIR}/Source/Include/parser.h ${SWIG_SOURCE_DIR}/CParse/parser.y +) +set_property(SOURCE ${PROJECT_BINARY_DIR}/Source/CParse/parser.c PROPERTY GENERATED 1) +set_property(SOURCE ${PROJECT_BINARY_DIR}/Source/CParse/parser.h PROPERTY GENERATED 1) + +# generate swigwarn.swg +file(READ ${SWIG_SOURCE_DIR}/Include/swigwarn.h SWIG_WARN_H) +string(REGEX REPLACE "#define WARN([^ \\t]*)[ \\t]*([0-9]+)" "%define SWIGWARN\\1 \\2 %enddef" SWIG_WARN_SWG ${SWIG_WARN_H}) +file(WRITE ${PROJECT_BINARY_DIR}/Dist/Lib/swigwarn.swg ${SWIG_WARN_SWG}) +set_property(SOURCE ${PROJECT_BINARY_DIR}/Dist/Lib/swigwarn.swg PROPERTY GENERATED 1) + +# Libraries +# --------- + +add_library(cparse "${SWIG_SOURCE_DIR}/CParse/cscanner.c" + "${SWIG_SOURCE_DIR}/CParse/templ.c" + "${SWIG_SOURCE_DIR}/CParse/util.c" + "${PROJECT_BINARY_DIR}/Source/CParse/parser.c" + "${PROJECT_BINARY_DIR}/Source/CParse/parser.h" +) + +add_library(preprocessor "${SWIG_SOURCE_DIR}/Preprocessor/cpp.c" + "${SWIG_SOURCE_DIR}/Preprocessor/expr.c" +) + +add_library(doh "${SWIG_SOURCE_DIR}/DOH/base.c" + "${SWIG_SOURCE_DIR}/DOH/file.c" + "${SWIG_SOURCE_DIR}/DOH/fio.c" + "${SWIG_SOURCE_DIR}/DOH/hash.c" + "${SWIG_SOURCE_DIR}/DOH/list.c" + "${SWIG_SOURCE_DIR}/DOH/memory.c" + "${SWIG_SOURCE_DIR}/DOH/string.c" + "${SWIG_SOURCE_DIR}/DOH/void.c" +) + +add_library(core "${SWIG_SOURCE_DIR}/Swig/cwrap.c" + "${SWIG_SOURCE_DIR}/Swig/deprecate.c" + "${SWIG_SOURCE_DIR}/Swig/error.c" + "${SWIG_SOURCE_DIR}/Swig/fragment.c" + "${SWIG_SOURCE_DIR}/Swig/getopt.c" + "${SWIG_SOURCE_DIR}/Swig/include.c" + "${SWIG_SOURCE_DIR}/Swig/misc.c" + "${SWIG_SOURCE_DIR}/Swig/naming.c" + "${SWIG_SOURCE_DIR}/Swig/parms.c" + "${SWIG_SOURCE_DIR}/Swig/scanner.c" + "${SWIG_SOURCE_DIR}/Swig/stype.c" + "${SWIG_SOURCE_DIR}/Swig/symbol.c" + "${SWIG_SOURCE_DIR}/Swig/tree.c" + "${SWIG_SOURCE_DIR}/Swig/typemap.c" + "${SWIG_SOURCE_DIR}/Swig/typeobj.c" + "${SWIG_SOURCE_DIR}/Swig/typesys.c" + "${SWIG_SOURCE_DIR}/Swig/wrapfunc.c" +) + +add_library(modules "${SWIG_SOURCE_DIR}/Modules/allegrocl.cxx" + "${SWIG_SOURCE_DIR}/Modules/allocate.cxx" + "${SWIG_SOURCE_DIR}/Modules/browser.cxx" + "${SWIG_SOURCE_DIR}/Modules/cffi.cxx" + "${SWIG_SOURCE_DIR}/Modules/chicken.cxx" + "${SWIG_SOURCE_DIR}/Modules/clisp.cxx" + "${SWIG_SOURCE_DIR}/Modules/contract.cxx" + "${SWIG_SOURCE_DIR}/Modules/csharp.cxx" + "${SWIG_SOURCE_DIR}/Modules/d.cxx" + "${SWIG_SOURCE_DIR}/Modules/directors.cxx" + "${SWIG_SOURCE_DIR}/Modules/emit.cxx" + "${SWIG_SOURCE_DIR}/Modules/go.cxx" + "${SWIG_SOURCE_DIR}/Modules/guile.cxx" + "${SWIG_SOURCE_DIR}/Modules/java.cxx" + "${SWIG_SOURCE_DIR}/Modules/javascript.cxx" + "${SWIG_SOURCE_DIR}/Modules/javascript_emitter.h" + "${SWIG_SOURCE_DIR}/Modules/javascript_emitter.cxx" + "${SWIG_SOURCE_DIR}/Modules/lang.cxx" + "${SWIG_SOURCE_DIR}/Modules/lua.cxx" + "${SWIG_SOURCE_DIR}/Modules/modula3.cxx" + "${SWIG_SOURCE_DIR}/Modules/module.cxx" + "${SWIG_SOURCE_DIR}/Modules/mzscheme.cxx" + "${SWIG_SOURCE_DIR}/Modules/ocaml.cxx" + "${SWIG_SOURCE_DIR}/Modules/octave.cxx" + "${SWIG_SOURCE_DIR}/Modules/overload.cxx" + "${SWIG_SOURCE_DIR}/Modules/perl5.cxx" + "${SWIG_SOURCE_DIR}/Modules/php.cxx" + "${SWIG_SOURCE_DIR}/Modules/pike.cxx" + "${SWIG_SOURCE_DIR}/Modules/python.cxx" + "${SWIG_SOURCE_DIR}/Modules/r.cxx" + "${SWIG_SOURCE_DIR}/Modules/ruby.cxx" + "${SWIG_SOURCE_DIR}/Modules/s-exp.cxx" + "${SWIG_SOURCE_DIR}/Modules/tcl8.cxx" + "${SWIG_SOURCE_DIR}/Modules/typepass.cxx" + "${SWIG_SOURCE_DIR}/Modules/uffi.cxx" + "${SWIG_SOURCE_DIR}/Modules/utils.cxx" + "${SWIG_SOURCE_DIR}/Modules/xml.cxx" + "${PROJECT_BINARY_DIR}/Source/Include/swigconfig.h" + "${SWIG_SOURCE_DIR}/Include/swigwarn.h" +) + +add_executable(swig + "${SWIG_SOURCE_DIR}/Modules/main.cxx" + "${SWIG_SOURCE_DIR}/Modules/swigmain.cxx" +) + +target_link_libraries(swig cparse preprocessor doh core modules) + +# copy binary into Dist folder +get_property(SWIG_EXECUTABLE TARGET swig PROPERTY LOCATION) +add_custom_command(TARGET swig POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${SWIG_EXECUTABLE} ${PROJECT_BINARY_DIR}/Dist +) diff --git a/Tools/swigconfig.h.cmake b/Tools/swigconfig.h.cmake new file mode 100644 index 000000000..e4f0b42c4 --- /dev/null +++ b/Tools/swigconfig.h.cmake @@ -0,0 +1,89 @@ +/* Define to 1 if the system has the type `bool'. */ +#cmakedefine HAVE_BOOL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `dl' library (-ldl). */ +#cmakedefine HAVE_LIBDL 1 + +/* Define to 1 if you have the `dld' library (-ldld). */ +#cmakedefine HAVE_LIBDLD 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define if popen is available */ +#cmakedefine HAVE_POPEN 1 + +/* Define if rxspencer is available */ +#cmakedefine HAVE_RXSPENCER 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#cmakedefine NO_MINUS_C_MINUS_O 1 + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS 1 + +/* Name of package */ +#define PACKAGE "swig" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "http://www.swig.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "swig" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "swig @SWIG_VERSION@" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "swig" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "@SWIG_VERSION@" + +/* Compiler that built SWIG */ +#define SWIG_CXX "@SWIG_CXX@" + +/* Directory for SWIG system-independent libraries */ +#define SWIG_LIB "/usr/local/share/swig/2.0.0" + +/* Directory for SWIG system-independent libraries (Unix install on native + Windows) */ +#define SWIG_LIB_WIN_UNIX "C:/cygwin/usr/local/share/swig/2.0.0" + +/* Platform that SWIG is built for */ +#define SWIG_PLATFORM "i686-pc-cygwin" + +/* Version number of package */ +#define VERSION "@SWIG_VERSION@" + +/* Default language */ +#define SWIG_LANG "-tcl" + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif From 5b5fdb171e720228b24c2f9fbb1667649693b3ab Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:46:03 +0000 Subject: [PATCH 006/352] Add a paragraph about control flow analysis to V8 specification. Control flow analysis for use cases: - static variables - simple class - class properties - class methods - static class variables and functions - inheritance. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13740 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 318 ++++++++++++++++++ 1 file changed, 318 insertions(+) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index b8e2b8a78..2990f1d00 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -288,3 +288,321 @@ void V8GeneratorUtils::AddProperty(v8::Handle class_templ, } ~~~~ + +# Control flow analysis + +## Global variables + +### Example: +~~~~ +int x; + +namespace foo { + double y; +} +~~~~ + +### Control flow: +Command: +~~~~ +swig -analyze -c++ functionWrapper +before globalvariableHandler +before example.i +~~~~ + +~~~~ +enter top() of example +enter variableHandler() of x +enter globalvariableHandler() of x + | sym:name - "x" + | name - "x" + | type - "int" + + enter variableWrapper() of x + + enter functionWrapper() of x + | name - "x" + | sym:name - "x_set" + | parms - int + | wrap:action - "x = arg1;" + | type - "void" + exit functionWrapper() of x + + enter functionWrapper() of x + | name - "x" + | sym:name - "x_get" + | type - "int" + exit functionWrapper() of x + exit variableWrapper() of x +exit globalvariableHandler() of x +exit variableHandler() of x + +enter variableHandler() of foo::y +enter globalvariableHandler() of foo::y + | sym:name - "y" + | name - "foo::y" + | type - "double" + + enter variableWrapper() of foo::y + enter functionWrapper() of foo::y + | name - "foo::y" + | sym:name - "y_set" + | parms - double + | wrap:action - "foo::y = arg1;" + | type - "void" + exit functionWrapper() of foo::y + + enter functionWrapper() of foo::y + | name - "foo::y" + | sym:name - "y_get" + | wrap:action - "result = (double)foo::y;" + | type - "double" + exit functionWrapper() of foo::y + exit variableWrapper() of foo::y +exit globalvariableHandler() of foo::y +exit variableHandler() of foo::y +exit top() of example + +~~~~ + +## Simple class + +### Example: + +~~~~ +class A { +public: + A(); + ~A(); +}; + +namespace foo { + class B { + }; +} +~~~~ + +### Control flow: + +~~~~ +enter top() of example + enter classHandler() of A + enter constructorHandler() of A + enter functionWrapper() of A + | name - "A" + | sym:name - "new_A" + | access - "public" + | wrap:action - "result = (A *)new A();" + | type - "p.A" + exit functionWrapper() of A + exit constructorHandler() of A + enter destructorHandler() of ~A + enter functionWrapper() of ~A + | name - "~A" + | sym:name - "delete_A" + | parms - A * + | wrap:action - "delete arg1;" + exit functionWrapper() of ~A + exit destructorHandler() of ~A +exit classHandler() of A +enter classHandler() of foo::B + enter constructorHandler() of foo::B::B + enter functionWrapper() of foo::B::B + | name - "foo::B::B" + | sym:name - "new_B" + | access - "public" + | wrap:action - "result = (foo::B *)new foo::B();" + | type - "p.foo::B" + exit functionWrapper() of foo::B::B + exit constructorHandler() of foo::B::B + enter destructorHandler() of foo::B::~B + enter functionWrapper() of foo::B::~B + | name - "foo::B::~B" + | sym:name - "delete_B" + | parms - foo::B * + | wrap:action - "delete arg1;" + | type - "void" + exit functionWrapper() of foo::B::~B + exit destructorHandler() of foo::B::~B +exit classHandler() of foo::B +exit top() of example + +~~~~ + +### Example + +~~~~ +class A { +public: + int x; +}; +~~~~ + + +### Control flow + +~~~~ +enter top() of example +enter classHandler() of A + enter variableHandler() of x + enter membervariableHandler() of x + enter functionWrapper() of x + | name - "x" + | sym:name - "A_x_set" + | access - "public" + | parms - A *,int + | wrap:action - "if (arg1) (arg1)->x = arg2;" + | type - "void" + | memberset - "1" + exit functionWrapper() of x + enter functionWrapper() of x + | name - "x" + | sym:name - "A_x_get" + | access - "public" + | parms - A * + | wrap:action - "result = (int) ((arg1)->x);" + | type - "int" + | memberset - "1" + | memberget - "1" + exit functionWrapper() of x + exit membervariableHandler() of x + exit variableHandler() of x + enter constructorHandler() of A::A + enter functionWrapper() of A::A + exit functionWrapper() of A::A + exit constructorHandler() of A::A + enter destructorHandler() of A::~A + enter functionWrapper() of A::~A + exit functionWrapper() of A::~A + exit destructorHandler() of A::~A +exit classHandler() of A +exit top() of example +~~~~ + +## Class method + +### Example + +~~~~ +class A { +public: + void foo(int x, double y); +private: + void bar(); +}; +~~~~ + +### Control flow + +~~~~ +enter top() of example +enter classHandler() of A + enter functionHandler() of foo + enter memberfunctionHandler() of foo + enter functionWrapper() of foo + | name - "foo" + | sym:name - "A_foo" + | access - "public" + | parms - A *,int,double + | wrap:action - "(arg1)->foo(arg2,arg3);" + | type - "void" + exit functionWrapper() of foo + exit memberfunctionHandler() of foo + exit functionHandler() of foo +... +exit classHandler() of A +exit top() of example +~~~~ + +## Static class variable and method + +### Example + +~~~~ +class A { +public: + static int x; + + static void foo(); +}; +~~~~ + +### Control flow + +~~~~ +enter top() of example +enter classHandler() of A + enter variableHandler() of x + enter staticmembervariableHandler() of x + enter variableWrapper() of A::x + enter functionWrapper() of A::x + | name - "A::x" + | sym:name - "A_x_set" + | parms - int + | wrap:action - "A::x = arg1;" + | type - "void" + exit functionWrapper() of A::x + enter functionWrapper() of A::x + +++ cdecl ---------------------------------------- + | name - "A::x" + | ismember - "1" + | sym:name - "A_x_get" + | variableWrapper:sym:name - "A_x" + | wrap:action - "result = (int)A::x;" + | type - "int" + exit functionWrapper() of A::x + exit variableWrapper() of A::x + exit staticmembervariableHandler() of x + exit variableHandler() of x + enter functionHandler() of foo + enter staticmemberfunctionHandler() of foo + enter globalfunctionHandler() of A::foo + enter functionWrapper() of A::foo + | name - "A::foo" + | sym:name - "A_foo" + | wrap:action - "A::foo();" + | type - "void" + exit functionWrapper() of A::foo + exit globalfunctionHandler() of A::foo + exit staticmemberfunctionHandler() of foo + exit functionHandler() of foo + enter constructorHandler() of A::A + exit constructorHandler() of A::A + enter destructorHandler() of A::~A + exit destructorHandler() of A::~A +exit classHandler() of A +exit top() of example +~~~~ + +## Inheritance + +### Example + +~~~~ +class A { +}; + +class B: public A { +}; +~~~~ + +### Control flow + +~~~~ +enter top() of example +enter classHandler() of A + +++ class ---------------------------------------- + | name - "A" + | sym:name - "A" +... +exit classHandler() of A +enter classHandler() of B + | name - "B" + | sym:name - "B" + | privatebaselist - 0xf1238f10 + | protectedbaselist - 0xf1238ef0 + | baselist - 0xf1238ed0 + | bases - 0xf1239830 + | allbases - 0xf1239c30 +... +exit classHandler() of B +exit top() of example +~~~~ From e888d7a892702aa0a3e42449737c8f1bfb747a2f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:46:18 +0000 Subject: [PATCH 007/352] Add a document about mapping C++ language features to Javascript. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13741 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../Javascript/MappingC++ToJavascript.md | 220 ++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 Doc/Devel/Javascript/MappingC++ToJavascript.md diff --git a/Doc/Devel/Javascript/MappingC++ToJavascript.md b/Doc/Devel/Javascript/MappingC++ToJavascript.md new file mode 100644 index 000000000..c77064933 --- /dev/null +++ b/Doc/Devel/Javascript/MappingC++ToJavascript.md @@ -0,0 +1,220 @@ +# Mapping C++ language features to Javascript + +## Namespaces + +A namespace is represented as a static instance (global variable) +containing other namespaces, global variables and functions +and class templates + +### Example: + +C++: + +~~~~c++ +namespace foo { + int x; + namespace bar { + double y; + } +} +~~~~ + +Javascript: + +~~~~javascript +var foo = new Object(); +foo.x = 0; +foo.bar = new Object(); +foo.bar.y = 0.0; +~~~~ + +## Global variables and functions + +Global variables and functions are properties of other context objects +(global or namespaces). + +### Example: + +C++: + +~~~~c++ +int x; +namespace foo { + void bar(); +} +~~~~ + +Javascript: + +~~~~javascript +var x = 0; +var foo = new Object(); +foo.bar = function() { + return undefined; +} +~~~~ + +## Classes + +Classes are defined as class templates and instantiated using the `new` +operator. +Class members are set in the constructor function using the `this` reference. +Private class members are set using the `var` keyword. + +### Example: + +C++: + +~~~~c++ +class Foo { + int bar(); + +private: + int x; +} +~~~~ + +Javascript: + +~~~~javascript +var Foo = function() { + var x = 42; + this.bar = function() { return x; }; +}; + +var foo = new Foo(); +foo.bar(); +~~~~ + +## Static class members and functions + +Static variables and functions should be added to the class template object. + +~~~~c++ +class Foo { + static std::string foo(); + std::string bar(); +} +~~~~ + +Javascript: + +~~~~javascript +var Foo = function() { + this.bar = function() { + return "bar"; + } +}; +Foo.foo = function() { + return "foo"; +}; + +var foo = new Foo(); +foo.foo() +> TypeError: Object [object Object] has no method 'foo' +Foo.foo() +> "foo" +foo.bar(); +> "bar" +~~~~ + +## Inheritance + +Javascript uses a prototype based inheritance mechanism. This limits +feature support to single inheritance. + +### Example: + +C++: + +~~~~c++ +class Foo { +public: + int foo(); + +private: + int x; +} + +class Bar: public Foo { +public: + int bar(); +} +~~~~ + +Javascript: + +~~~~javascript +var Foo = function() { + var x = 42; + this.foo = function() { return x; }; +}; + +var Bar = function() { + this.bar = function() { return 6; }; +} +Bar.prototype = new Foo(); +Bar.prototype.constructor = Bar; + +var foo = new Foo(); +var bar = new Bar(); + +foo.foo() +> 42 +foo.bar() +> TypeError: Object [object Object] has no method 'bar' +bar.foo() +> 42 +bar.bar() +> 6 +~~~~ + +## Virtual methods + +The prototype mechanism of Javascript allows method overriding which is +needed to map the concept of virtual functions. + +### Example: + +C++: + +~~~~c++ +class Foo { +public: + virtual int foo(); +} + +class Bar: public Foo { +public: + virtual int foo(); +} +~~~~ + +Javascript: + +~~~~javascript +var Foo = function() { + this.foo = function() { return 1; }; +}; + +var Bar = function() {} +Bar.prototype = new Foo(); +Bar.prototype.constructor = Bar; +Bar.prototype.foo = function() { return 42; }; + +var foo = new Foo(); +var bar = new Bar(); + +foo.foo() +> 1 +bar.foo() +> 42 +~~~~ + +## Overloading + +In Javascript like in other scripting languages method overloading is not +available. I.e., there can only be one function for one function name. +Therefore, it is necessary to implement a method dispatching mechanism +for these methods. + From 4bcfca05dd0eff51c4ecfa11ed182a6bcf147dbf Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:46:31 +0000 Subject: [PATCH 008/352] Add some implementation details to specification of v8 code generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13742 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../Javascript/V8_CodeGeneratorSpecification.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index 2990f1d00..b7d06e220 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -46,7 +46,8 @@ v8::Persistent SWIGV8_$CLASSNAME; Notes: - it is very important to consider namespaces from the beginning. - `CLASSNAME` should be fully canonical, e.g., `foo_bar_MyClass` for `foo::bar::MyClass` + `CLASSNAME` should be the mangled qualified class name, e.g., `foo_bar_MyClass` for `foo::bar::MyClass`, + which is retrieved ny `Swig_string_mangle(Getattr(n, "name"))` - namespaces do not need a function template, as they will not be instantiated @@ -84,7 +85,8 @@ v8::Handle $CLASSNAME_new(const v8::Arguments& args) { } ~~~~ -- `$CLASS_LVAL`: should be the canonical name of the class, e.g. `ns1::ns2::MyClass` +- `$CLASS_LVAL`: should be the canonical name of the class, e.g. `ns1::ns2::MyClass`, + which can be retrieved using `Getattr(n, "name")` - `$ARGS`: arguments should be declared at the beginning and checked and set in the input typemap block @@ -189,7 +191,8 @@ in the according parent contexts. SWIGV8_$CLASSNAME = SWIGV8_CreateClassTemplate("$LOCAL_CLASSNAME" , $CLASSNAME_new); ~~~~ -- `LOCAL_CLASSNAME`: the class name without context, i.e., namespaces +- `LOCAL_CLASSNAME`: the class name without context, i.e., namespaces, + which is retrieved by `Getattr(n, "sym:name")` ## Add Member Function @@ -198,8 +201,8 @@ in the according parent contexts. ~~~~ - `METHODNAME`: the name of the function as in C++ -- `METHOD_WRAPPER`: the name of the generated wrapper function - TODO: specify different versions +- `METHOD_WRAPPER`: the name of the generated wrapper function, which + should have the form `wrap__` ## Add Property From 3c30e2d382cbbacef66563bcc8d54289f9543339 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:47:19 +0000 Subject: [PATCH 009/352] Add initial Javascript V8 emitter implementation. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13743 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CMakeLists.txt | 2 + Lib/javascript/v8/javascriptcode.swg | 73 ++++ Lib/javascript/v8/javascripthelpers.swg | 58 ++++ Lib/javascript/v8/javascriptprimitives.swg | 265 +++++++++++++++ Lib/javascript/v8/javascriptruntime.swg | 9 + Source/Makefile.am | 1 + Source/Modules/javascript.cxx | 4 +- Source/Modules/javascript_v8.cxx | 369 +++++++++++++++++++++ Source/Modules/javascript_v8.h | 77 +++++ 9 files changed, 857 insertions(+), 1 deletion(-) create mode 100644 Lib/javascript/v8/javascriptcode.swg create mode 100644 Lib/javascript/v8/javascripthelpers.swg create mode 100644 Lib/javascript/v8/javascriptprimitives.swg create mode 100644 Lib/javascript/v8/javascriptruntime.swg create mode 100644 Source/Modules/javascript_v8.cxx create mode 100644 Source/Modules/javascript_v8.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 442fa6d6a..e7d96cc8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,6 +137,8 @@ add_library(modules "${SWIG_SOURCE_DIR}/Modules/allegrocl.cxx" "${SWIG_SOURCE_DIR}/Modules/javascript.cxx" "${SWIG_SOURCE_DIR}/Modules/javascript_emitter.h" "${SWIG_SOURCE_DIR}/Modules/javascript_emitter.cxx" + "${SWIG_SOURCE_DIR}/Modules/javascript_v8.h" + "${SWIG_SOURCE_DIR}/Modules/javascript_v8.cxx" "${SWIG_SOURCE_DIR}/Modules/lang.cxx" "${SWIG_SOURCE_DIR}/Modules/lua.cxx" "${SWIG_SOURCE_DIR}/Modules/modula3.cxx" diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg new file mode 100644 index 000000000..1b6d33662 --- /dev/null +++ b/Lib/javascript/v8/javascriptcode.swg @@ -0,0 +1,73 @@ + +%fragment("v8_initializer", "templates") %{ +void ${MODULE}_Initialize(v8::Handle context) +{ + v8::HandleScope scope; + + // register the module in globale context + v8::Local global = context->Global(); + + ${PART_NAMESPACES} + + ${PART_CLASS_TEMPLATES} + + ${PART_WRAPPERS} + + ${PART_INHERITANCE} + + ${PART_REGISTER} +}%} + +%fragment("v8_declare_class_template", "templates") %{ +v8::Persistent SWIGV8_${NAME_MANGLED};%} + +%fragment("v8_define_class_template", "templates") %{ +SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new);%} + +%fragment("v8_inherit", "templates") %{ +SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS});%} + +%fragment("v8_register_class", "templates") %{ +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction()));%} + +%fragment("v8_ctor_wrapper", "templates") %{ +v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + ${LOCALS} + ${ACTION} + self->SetInternalField(0, v8::External::New(ptr)); + return self; +} +%} + +%fragment("v8_getter", "templates") %{ +v8::Handle ${NAME_MANGLED}_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle ret; + ${LOCALS} + ${ACTION} + ${MARSHAL_OUTPUT} + return scope.Close(ret); +} +%} + +%fragment("v8_setter", "templates") %{ +void ${NAME_MANGLED}_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + ${LOCALS} + ${MARSHAL_INPUT} + ${ACTION} +} +%} + +%fragment("v8_function", "templates") %{ +v8::Handle ${NAME_MANGLED}(const Arguments &args) { + v8::HandleScope scope; + v8::Handle ret; + ${LOCALS} + ${MARSHAL_INPUT} + ${ACTION} + ${MARSHAL_OUTPUT} + return scope.Close(ret); +} +%} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg new file mode 100644 index 000000000..61836c87d --- /dev/null +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -0,0 +1,58 @@ + +%insert(runtime) %{ + +/** + * Creates a class template for a class without extra initialization function. + */ +v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol) { + v8::Local class_templ = v8::FunctionTemplate::New(); + class_templ->SetClassName(v8::String::NewSymbol(symbol)); + + v8::Handle inst_templ = class_templ->InstanceTemplate(); + inst_templ->SetInternalFieldCount(1); + + return v8::Persistent::New(class_templ); +} + +/** + * Creates a class template for a class with specified initialization function. + */ +v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol, v8::InvocationCallback _func) { + v8::Local class_templ = v8::FunctionTemplate::New(_func); + class_templ->SetClassName(v8::String::NewSymbol(symbol)); + + v8::Handle inst_templ = class_templ->InstanceTemplate(); + inst_templ->SetInternalFieldCount(1); + + return v8::Persistent::New(class_templ); +} + +/** + * Sets the pimpl data of a V8 class. + */ +v8::Handle V8GeneratorUtils::SetInstance(const v8::Arguments& args, void* data) { + v8::HandleScope scope; + + v8::Handle self = args.Holder(); + self->SetInternalField(0, v8::External::New(data)); + + return self; +} + +/** + * Registers a class method with given name for a given class template. + */ +void V8GeneratorUtils::AddClassMethod(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { + v8::Handle proto_templ = class_templ->PrototypeTemplate(); + proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); +} + +/** + * Registers a class property with given name for a given class template. + */ +void V8GeneratorUtils::AddProperty(v8::Handle class_templ, const char* varname, v8::AccessorGetter getter, v8::AccessorSetter setter) { + v8::Handle proto_templ = class_templ->InstanceTemplate(); + proto_templ->SetAccessor(v8::String::New(varname), getter, setter); +} + +%} // v8_helper_functions diff --git a/Lib/javascript/v8/javascriptprimitives.swg b/Lib/javascript/v8/javascriptprimitives.swg new file mode 100644 index 000000000..d5c89c690 --- /dev/null +++ b/Lib/javascript/v8/javascriptprimitives.swg @@ -0,0 +1,265 @@ +// Primitive types +%typemap(in) char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double +%{ $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} + +%typemap(in) const bool &, bool &, + const char &, char &, + const signed char &, signed char &, + const unsigned char &, unsigned char &, + const short &, short &, + const unsigned short &, unsigned short &, + const int &, int &, + const unsigned int &, unsigned int &, + const long &, long &, + const unsigned long &, unsigned long &, + const long long &, long long &, + const unsigned long long &,unsigned long long &, + const float &, float &, + const double &, double & +%{ $1 = ($1_ltype)&$input; %} + +%typemap(out) char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double +%{ $result = JSValueMakeNumber(context, $1); %} + +%typemap(out) const bool &, bool &, + const char &, char &, + const signed char &, signed char &, + const unsigned char &, unsigned char &, + const short &, short &, + const unsigned short &, unsigned short &, + const int &, int &, + const unsigned int &, unsigned int &, + const long &, long &, + const unsigned long &, unsigned long &, + const long long &, long long &, + const unsigned long long &,unsigned long long &, + const float &, float &, + const double &, double & +%{ $result = JSValueMakeNumber(context,*$1); %} + + +%typemap(in) short *, + unsigned short *, + int *, + unsigned int *, + long *, + unsigned long *, + long long *, + unsigned long long *, + float *, + double * +%{ + JSObjectRef o$1 = JSValueToObject(context,$input, NULL); + SWIG_PRV_DATA *$1_privatedata = (SWIG_PRV_DATA *)JSObjectGetPrivate(o$1); + $1 = ($1_ltype)$1_privatedata->swigCObject; +%} + + +%typemap(out) short *, + unsigned short *, + int *, + unsigned int *, + long *, + unsigned long *, + long long *, + unsigned long long *, + float *, + double * +%{ + SWIG_PRV_DATA *privatedata = new SWIG_PRV_DATA(); + privatedata->swigCMemOwn = false; + privatedata->swigCObject = result; + $result = JSObjectMake(context, _wrap_swig_ptr_$*1_ltype_createJSClass(context), privatedata); +%} + +%typemap(in) bool +%{ + $1 = ($1_ltype)JSValueToBoolean(context, $input); +%} + +%typemap(out) bool +%{ + $result = JSValueMakeBoolean(context, $1); +%} + + +%typemap(out) void +%{ $result = JSValueMakeUndefined(context); %} + + +%typemap(in) char * +%{ + JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); + size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); + $1 = (char *)malloc($1_strsize * sizeof(char)); + JSStringGetUTF8CString($1_str, $1, $1_strsize); +%} + +%typemap(out) char * +%{ + JSStringRef jsstring = JSStringCreateWithUTF8CString($1); + $result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); +%} + +%typemap(arginit) char * "" + +%typemap(in) char *& ($*1_ltype temp = 0) %{ + temp = ($*1_ltype)$input; + JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); + size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); + $1 = (char *)malloc($1_strsize * sizeof(char)); + JSStringGetUTF8CString($1_str, $1, $1_strsize); +%} + +%typemap(out) char *& +%{ + JSStringRef jsstring = JSStringCreateWithUTF8CString((const char *)*$1); + $result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); +%} + +/* char arrays - treat as String */ +%typemap(in) char[ANY], char[] %{ + JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); + size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); + JSStringGetUTF8CString($1_str, $1, $1_strsize); +%} + +%typemap(out) char[ANY], char[] +%{ + JSStringRef jsstring = JSStringCreateWithUTF8CString($1); + $result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); +%} + +%typemap(freearg) char *, char *&, char[ANY], char[] //TODO: Not working: A memory leak +%{ free($1); %} + + +/* Typemaps for composite types */ +%typemap(in) SWIGTYPE ($&1_type argp) // Objects passed by value, convert to a pointer +%{ + JSObjectRef o$1 = JSValueToObject(context,$input, NULL); + SWIG_PRV_DATA *$1_privatedata = (SWIG_PRV_DATA *)JSObjectGetPrivate(o$1); + argp = ($&1_ltype)$1_privatedata->swigCObject; + $1 = *argp; +%} + +%typemap(out) SWIGTYPE ($&1_type temp) +#ifdef __cplusplus +%{ + temp = new $1_ltype((const $1_ltype &)$1); + SWIG_PRV_DATA *privatedata = new SWIG_PRV_DATA(); + privatedata->swigCMemOwn = false; + privatedata->swigCObject = temp; + $result = JSObjectMake(context, _wrap_$1_type_createJSClass(context), privatedata); + //$result = JSObjectMake(context, _wrap_$1_basetype_createJSClass(context), privatedata); + //$result = JSObjectMake(context, _wrap_$objecttype_createJSClass(context), privatedata); + // $1_mangle + // $1_descriptor +%} +#else +{ + $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype)); + memmove($1ptr, &$1, sizeof($1_type)); + temp = $1ptr; + SWIG_PRV_DATA *privatedata = (SWIG_PRV_DATA *)malloc(sizeof(SWIG_PRV_DATA()); + privatedata->swigCMemOwn = false; + privatedata->swigCObject = temp; + $result = JSObjectMake(context, _wrap_$1_ltype_createJSClass(context), privatedata); + //$result = JSObjectMake(context, _wrap_$1_basetype_createJSClass(context), privatedata); + //$result = JSObjectMake(context, _wrap_$objecttype_createJSClass(context), privatedata); + // $1_mangle + // $1_descriptor +} +#endif + +%typemap(in) SWIGTYPE *, SWIGTYPE & +%{ + JSObjectRef o$1 = JSValueToObject(context,$input, NULL); + SWIG_PRV_DATA *$1_privatedata = (SWIG_PRV_DATA *)JSObjectGetPrivate(o$1); + $1 = ($1_ltype)$1_privatedata->swigCObject; +%} + +%typemap(out) SWIGTYPE *, SWIGTYPE & +%{ + SWIG_PRV_DATA *privatedata = new SWIG_PRV_DATA(); + privatedata->swigCMemOwn = false; + privatedata->swigCObject = result; + $result = JSObjectMake(context, _wrap_$*1_ltype_createJSClass(context), privatedata); + //$result = JSObjectMake(context, _wrap_$1_basetype_createJSClass(context), privatedata); + //$result = JSObjectMake(context, _wrap_$objecttype_createJSClass(context), privatedata); + // $1_mangle + // $1_descriptor +%} + +%typemap(arginit) SWIGTYPE * +%{ + // Sanity check if the call is not on the global object + if (!JSValueIsEqual(context, + JSValueToObject(context,thisObject,NULL), + JSValueToObject(context,JSContextGetGlobalObject(context), NULL), + NULL)) { + SWIG_PRV_DATA* $1_swigprivatedata = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + $1 = ($1_ltype)$1_swigprivatedata->swigCObject; + } +%} + +%typemap(in) SWIGTYPE (CLASS::*) "" + +%typemap(out) SWIGTYPE (CLASS::*) +%{ + // Class* out typemap + $result = JSObjectMake(context, _wrap_$*1_ltype_createJSClass(context), result); +%} + + + +/* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions + * that cannot be overloaded in Javascript as more than one C++ type maps to a single Javascript type */ +// TODO + + +// Default array handling +%typemap(in) SWIGTYPE [] %{ $1 = ($1_ltype)$input; %} +%typemap(out) SWIGTYPE [] %{ $result = $1; %} + + +// Javascript specific directives +//TODO + +// Some ANSI C typemaps */ +%apply unsigned long { size_t }; + +%apply const unsigned long & { const size_t & }; + +// Array reference typemaps +%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) } + +// const pointers +%apply SWIGTYPE * { SWIGTYPE *const } diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg new file mode 100644 index 000000000..ad34b6df2 --- /dev/null +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -0,0 +1,9 @@ +/* ----------------------------------------------------------------------------- + * javascriptruntime.swg + * + * Javascript support code + * ----------------------------------------------------------------------------- */ + +%insert(runtime) %{ +#include +%} diff --git a/Source/Makefile.am b/Source/Makefile.am index fa11bfdcb..85530fd45 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -51,6 +51,7 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/lang.cxx \ Modules/javascript.cxx \ Modules/javascript_emitter.cxx \ + Modules/javascript_v8.cxx \ Modules/lua.cxx \ Modules/main.cxx \ Modules/modula3.cxx \ diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index e1336d82a..64d943453 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -6,6 +6,8 @@ #include "javascript_emitter.h" +extern JSEmitter* create_v8_emitter(); + /* ******************************************************************** * JAVASCRIPT * ********************************************************************/ @@ -200,7 +202,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) { switch(mode) { case JSEmitter::V8: { - // TODO: emitter = create_v8_emitter(); + emitter = create_v8_emitter(); break; } case JSEmitter::JavascriptCore: diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx new file mode 100644 index 000000000..7d2583aca --- /dev/null +++ b/Source/Modules/javascript_v8.cxx @@ -0,0 +1,369 @@ +#include "javascript_v8.h" +#include "swigmod.h" + +/* ----------------------------------------------------------------------- + * String constants that are used in Lib/javascript/v8/javascriptcode.swg + *------------------------------------------------------------------------ */ + +// name of templates +#define V8_INITIALIZER "v8_initializer" +#define V8_DECL_CLASSTEMPLATE "v8_declare_class_template" +#define V8_DEFINE_CLASSTEMPLATE "v8_define_class_template" +#define V8_INHERIT "v8_inherit" +#define V8_REGISTER_CLASS "v8_register_class" +#define V8_CTOR_WRAPPER "v8_ctor_wrapper" +#define V8_GETTER "v8_getter" +#define V8_SETTER "v8_setter" +#define V8_FUNCTION "v8_function" +#define V8_RETRIEVE_THIS "v8_retrieve_this" + +// keywords used in templates +#define KW_MODULE_NAME "${MODULE}" +#define KW_MANGLED_NAME "${NAME_MANGLED}" +#define KW_UNQUALIFIED_NAME "${NAME_UNQUALIFIED}" +#define KW_BASE_CLASS "${BASE_CLASS}" +#define KW_CONTEXT "${CONTEXT}" + +#define KW_NAME_SPACES "${PART_NAMESPACES}" +#define KW_CLASS_TEMPLATES "${PART_CLASS_TEMPLATES}" +#define KW_WRAPPERS "${PART_WRAPPERS}" +#define KW_INHERITANCE "${PART_INHERITANCE}" +#define KW_REGISTER "${PART_REGISTER}" + +#define KW_LOCALS "${LOCALS}" +#define KW_MARSHAL_INPUT "${MARSHAL_INPUT}" +#define KW_ACTION "${ACTION}" +#define KW_MARSHAL_OUTPUT "${MARSHAL_OUTPUT}" + +V8Emitter::V8Emitter() + : JSEmitter(), + GLOBAL(NewString("global")), + namespaces(NewHash()) +{ +} + +V8Emitter::~V8Emitter() +{ + Delete(GLOBAL); + Delete(namespaces); +} + +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); + } + + 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_register = NewString(""); + + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrapper); + + return SWIG_OK; +} + +int V8Emitter::Dump(Node *n) +{ + /* Get the module name */ + String* module = Getattr(n,"name"); + + // 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); + + // 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_REGISTER, f_init_register); + Wrapper_pretty_print(initializer.str(), f_wrap_cpp); + + return SWIG_OK; +} + +int V8Emitter::Close() +{ + 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_register); + ::Close(f_wrap_cpp); + Delete(f_wrap_cpp); + + return SWIG_OK; +} + +int V8Emitter::SwitchContext(Node *n) +{ + 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_context = Getattr(namespaces, scope); + } else { + current_context = GLOBAL; + } + + return SWIG_OK; +} + +int V8Emitter::CreateNamespace(String* scope) { + String* parent_scope = Swig_scopename_prefix(scope); + + if (parent_scope && !Getattr(namespaces, parent_scope)) { + CreateNamespace(parent_scope); + } + + String* ns = Swig_string_mangle(scope); + Setattr(namespaces, scope, ns); + + // TODO: create namespace object and register it to the parent scope + Printf(f_init_namespaces, "create_ns(%s);\n", ns); + + return SWIG_OK; +} + +int V8Emitter::EnterClass(Node *n) +{ + current_classname_mangled = Swig_string_mangle(Getattr(n, "name")); + current_classname_unqualified = Swig_scopename_last(Getattr(n, "name")); + + // emit declaration of a v8 class template in part + Template t(GetTemplate(V8_DECL_CLASSTEMPLATE)); + t.Replace(KW_MANGLED_NAME, current_classname_mangled); + Printv(f_class_templates, t.str(), 0); + + // emit definition of v8 class template in part + Template t2(GetTemplate(V8_DEFINE_CLASSTEMPLATE)); + t2.Replace(KW_MANGLED_NAME, current_classname_mangled) + .Replace(KW_UNQUALIFIED_NAME, current_classname_unqualified); + Printv(f_init_class_templates, t2.str(), 0); + + return SWIG_OK; +} + +int V8Emitter::ExitClass(Node *n) +{ + // emit inheritance setup + Node* baseClass = GetBaseClass(n); + if(baseClass) { + Template t(GetTemplate(V8_INHERIT)); + t.Replace(KW_MANGLED_NAME, current_classname_mangled) + .Replace(KW_BASE_CLASS, Swig_string_mangle(Getattr(baseClass, "name"))); + Printv(f_init_inheritance, t.str(), 0); + } + + // emit registeration of class template + Template t(GetTemplate(V8_REGISTER_CLASS)); + t.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, t.str(), 0); + + Delete(current_classname_mangled); + Delete(current_classname_unqualified); + current_classname_mangled = 0; + current_classname_unqualified = 0; + + return SWIG_OK; +} + +int V8Emitter::EnterVariable(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); + } else { + current_variable_mangled = Swig_string_mangle(Getattr(n, "name")); + } + + return SWIG_OK; +} + +int V8Emitter::ExitVariable(Node* n) +{ + + // TODO: Register variable in context + + Delete(current_variable_mangled); + Delete(current_variable_unqualified); + current_variable_mangled = 0; + current_variable_unqualified = 0; + + 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) +{ + // TODO: Register function in context + + Delete(current_function_mangled); + Delete(current_function_unqualified); + current_function_mangled = 0; + current_function_unqualified = 0; + + return SWIG_OK; +} + +int V8Emitter::EmitCtor(Node* n) +{ + // TODO: + // - handle overloaded ctors using a dispatcher + // - marshal inputs + Template t(GetTemplate(V8_CTOR_WRAPPER)); + + ParmList *params = Getattr(n,"parms"); + String* action = Getattr(n, "wrap:action"); + String* input = NewString(""); + + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_wrapper); + + t.Replace(KW_MANGLED_NAME, current_classname_mangled) + .Replace(KW_UNQUALIFIED_NAME, current_classname_unqualified) + .Replace(KW_LOCALS, current_wrapper->locals) + .Replace(KW_ACTION, action) + .Replace(KW_MARSHAL_INPUT, input); + + Wrapper_pretty_print(t.str(), f_wrapper); + + return SWIG_OK; +} + +int V8Emitter::EmitDtor(Node* n) +{ + // TODO: + // find out how to register a dtor in v8 + + Printv(f_wrapper, "/* TODO: Wrap dtor */\n", 0); + + return SWIG_OK; +} + +int V8Emitter::EmitGetter(Node *n, bool is_member) { + Template t(GetTemplate(V8_GETTER)); + + Setattr(n, "wrap:name", Getattr(n, "sym:name")); + Printf(current_wrapper->locals, "%s result;\n", SwigType_str(Getattr(n, "type"), 0)); + + String* action = emit_action(n); + String* output = NewString("// TODO: marshal output.\n ret = v8::Undefined();"); + + t.Replace(KW_MANGLED_NAME, current_variable_mangled) + .Replace(KW_LOCALS, current_wrapper->locals) + .Replace(KW_ACTION, action) + .Replace(KW_MARSHAL_OUTPUT, output); + + Wrapper_pretty_print(t.str(), f_wrapper); + + Delete(output); + + return SWIG_OK; +} + +int V8Emitter::EmitSetter(Node* n, bool is_member) +{ + Template t(GetTemplate(V8_SETTER)); + + Setattr(n, "wrap:name", Getattr(n, "sym:name")); + ParmList *params = Getattr(n,"parms"); + + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_wrapper); + + String* action = emit_action(n); + String* input = NewString("// TODO: marshal input.\n"); + + t.Replace(KW_MANGLED_NAME, current_variable_mangled) + .Replace(KW_LOCALS, current_wrapper->locals) + .Replace(KW_ACTION, action) + .Replace(KW_MARSHAL_INPUT, input); + + Wrapper_pretty_print(t.str(), f_wrapper); + + Delete(input); + + return SWIG_OK; +} + + +int V8Emitter::EmitFunction(Node* n, bool is_member) +{ + Template t(GetTemplate(V8_FUNCTION)); + + Setattr(n, "wrap:name", Getattr(n, "sym:name")); + ParmList *params = Getattr(n,"parms"); + + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_wrapper); + Printf(current_wrapper->locals, "%s result;\n", SwigType_str(Getattr(n, "type"), 0)); + + + String* input = NewString("// TODO: marshal input"); + String* action = emit_action(n); + String* output = NewString("// TODO: marshal output.\n ret = v8::Undefined();"); + + t.Replace(KW_MANGLED_NAME, current_function_mangled) + .Replace(KW_LOCALS, current_wrapper->locals) + .Replace(KW_ACTION, action) + .Replace(KW_MARSHAL_INPUT, input) + .Replace(KW_MARSHAL_OUTPUT, output); + + Wrapper_pretty_print(t.str(), f_wrapper); + + Delete(input); + Delete(output); + + return SWIG_OK; +} + +JSEmitter* create_v8_emitter() +{ + return new V8Emitter(); +} diff --git a/Source/Modules/javascript_v8.h b/Source/Modules/javascript_v8.h new file mode 100644 index 000000000..bb190a71b --- /dev/null +++ b/Source/Modules/javascript_v8.h @@ -0,0 +1,77 @@ +#ifndef JAVASCRIPT_V8_H +#define JAVASCRIPT_V8_H + +#include "javascript_emitter.h" + +class V8Emitter: public JSEmitter { + +public: + + V8Emitter(); + + virtual ~V8Emitter(); + + virtual int Initialize(Node *n); + + virtual int Dump(Node *n); + + virtual int Close(); + + virtual int SwitchContext(Node *n); + + virtual int EnterClass(Node *n); + + 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: + + int CreateNamespace(String* scope); + + virtual int EmitCtor(Node *n); + + virtual int EmitDtor(Node *n); + + virtual int EmitFunction(Node *n, bool is_member); + + virtual int EmitGetter(Node *n, bool is_member); + + virtual int EmitSetter(Node *n, bool is_member); + +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_register; + + // the output cpp file + File *f_wrap_cpp; + + // state variables + String* current_context; + String* current_classname_mangled; + String* current_classname_unqualified; + String* current_variable_mangled; + String* current_variable_unqualified; + String* current_function_mangled; + String* current_function_unqualified; + + String* GLOBAL; + Hash* namespaces; +}; + +#endif // JAVASCRIPT_V8_H From a0b71935f278ff342583e17cdf6e94d43ac77c58 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:47:38 +0000 Subject: [PATCH 010/352] Update v8 code generator specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13744 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 118 ++++++++---------- Lib/javascript/v8/javascriptcode.swg | 1 + 2 files changed, 50 insertions(+), 69 deletions(-) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index b7d06e220..891b46b17 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -41,12 +41,12 @@ The generated code consists of the following blocks: Static references to class templates which are (should be) read-only and can be reused. ~~~~ -v8::Persistent SWIGV8_$CLASSNAME; +v8::Persistent SWIGV8_${NAME_MANGLED}; ~~~~ Notes: - it is very important to consider namespaces from the beginning. - `CLASSNAME` should be the mangled qualified class name, e.g., `foo_bar_MyClass` for `foo::bar::MyClass`, + `NAME_MANGLED` is the mangled qualified class name, e.g., `foo_bar_MyClass` for `foo::bar::MyClass`, which is retrieved ny `Swig_string_mangle(Getattr(n, "name"))` - namespaces do not need a function template, as they will not be instantiated @@ -67,115 +67,96 @@ TODO ## Constructors ~~~~ -v8::Handle $CLASSNAME_new(const v8::Arguments& args) { +v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { v8::HandleScope scope; - - // retrieve the instance v8::Handle self = args.Holder(); - - // TODO: declare arguments - - //convert JS arguments to C++ - // TODO: apply input typemaps - - $CLASS_LVAL* ptr = new $CLASS_LVAL($ARGS); + ${LOCALS} + ${MARSHAL_INPUT} + ${ACTION} self->SetInternalField(0, v8::External::New(ptr)); - return self; } ~~~~ -- `$CLASS_LVAL`: should be the canonical name of the class, e.g. `ns1::ns2::MyClass`, - which can be retrieved using `Getattr(n, "name")` -- `$ARGS`: arguments should be declared at the beginning and checked and set in the - input typemap block +- `LOCALS`: declaration and marshalling for input arguments +- `MARSHAL_INPUT`: code is generated by applying input typemaps +- `ACTION`: the C/C++ ctor to be executed ## Destructors -TODO +TODO: I haven't found out yet how a descrtuctor can be registered ## Getters ~~~~ -v8::Handle $CLASSNAME_get$VARNAME(v8::Local property, const v8::AccessorInfo& info) { +v8::Handle ${NAME_MANGLED}_get(v8::Local property, const v8::AccessorInfo& info) { v8::HandleScope scope; - - // retrieve pointer to C++-this - $CLASS_LVAL* self = SWIGV8_UnwrapThisPointer<$CLASS_LVAL>(info.Holder()); - $RET_LVAL retval = self->$VARNAME; - - v8::Handle ret = ; + v8::Handle ret; + ${LOCALS} + ${ACTION} + ${MARSHAL_OUTPUT} return scope.Close(ret); } ~~~~ -- TODO: output typemapping +- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` +- `LOCALS`: declare C return variable +- `MARSHAL_OUTPUT`: code is generated by applying output typemaps ## Setters ~~~~ -void $CLASSNAME_set$VARNAME(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - v8::HandleScope scope; - - // retrieve pointer to this - $CLASS_LVAL* self = SWIGV8_UnwrapThisPointer<$CLASS_LVAL>(info.Holder()); - - // TODO: declare input arg - - // map java-script type to C++ type - self->$VARNAME = ; - +void ${NAME_MANGLED}_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + ${LOCALS} + ${MARSHAL_INPUT} + ${ACTION} } ~~~~ +- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` +- `LOCALS`: declarations for input arguments +- `MARSHAL_INPUT`: code is generated by applying input typemaps -TODO: - - input type mapping should be addressed in extra step, together with type check - -## Member functions +## Functions ~~~~ -v8::Handle $CLASSNAME_$FUNCTIONNAME(const v8::Arguments& args) -{ +v8::Handle ${NAME_MANGLED}(const Arguments &args) { v8::HandleScope scope; - - $CLASS_LVAL* self = SWIGV8_UnwrapThisPointer<$CLASS_LVAL>(args.Holder()); - - // TODO: declare input args - - //convert JS arguments to C++ - // TODO: input typemappings and type checking - - //call C++ method - $RET_LTYPE result = self->$FUNCTIONNAME($ARGS); - - //convert C++ JS arguments to C++ - v8::Handle ret = ; - + v8::Handle ret; + ${LOCALS} + ${MARSHAL_INPUT} + ${ACTION} + ${MARSHAL_OUTPUT} return scope.Close(ret); } ~~~~ - if the function does not have a return value, return v8::Undefined +## Overloading + +TODO: if a function or a ctor is overloaded, a dispatcher function +must be generated which calls overloading wrappers depending on number +and type of input arguments. + ## Initializer ~~~~ -void $MODULENAME_Initialize(v8::Handle context) +void ${MODULE}_Initialize(v8::Handle context) { v8::HandleScope scope; // register the module in globale context v8::Local global = context->Global(); - - - + ${PART_NAMESPACES} - + ${PART_CLASS_TEMPLATES} - + ${PART_WRAPPERS} - + ${PART_INHERITANCE} + + ${PART_REGISTER} } ~~~~ @@ -188,11 +169,10 @@ in the according parent contexts. ## Create Class Template ~~~~ - SWIGV8_$CLASSNAME = SWIGV8_CreateClassTemplate("$LOCAL_CLASSNAME" , $CLASSNAME_new); +SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new); ~~~~ -- `LOCAL_CLASSNAME`: the class name without context, i.e., namespaces, - which is retrieved by `Getattr(n, "sym:name")` +- `NAME_UNQUALIFIED`: the class name without context, i.e., namespaces ## Add Member Function @@ -216,7 +196,7 @@ in the according parent contexts. ## Inheritance ~~~~ - SWIGV8_$CLASSNAME->Inherit(SWIGV8_$SUPERCLASS); +SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS}); ~~~~ - Note: multiple inheritance is not possible; thus we will always take the first parent class @@ -224,7 +204,7 @@ in the according parent contexts. ## Register class ~~~~ - $CONTEXT->Set(v8::String::NewSymbol("$LOCAL_CLASSNAME"), SWIGV8_$CLASSNAME->GetFunction()); +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction())); ~~~~ - Note: every class template has an associated ctor function wrapper, which is registered here diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 1b6d33662..2671fc117 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -35,6 +35,7 @@ v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { v8::HandleScope scope; v8::Handle self = args.Holder(); ${LOCALS} + ${MARSHAL_INPUT} ${ACTION} self->SetInternalField(0, v8::External::New(ptr)); return self; From 83ac7193155a0d91fad992f197a448591f3e829c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:47:51 +0000 Subject: [PATCH 011/352] Add manual generated v8 wrapper examples to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13745 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 161 +++++++++++++++++- 1 file changed, 160 insertions(+), 1 deletion(-) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index 891b46b17..095936ff8 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -166,6 +166,10 @@ Namespaces are objects without class templates. I.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. +~~~~~ +v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New(); +~~~~~ + ## Create Class Template ~~~~ @@ -201,7 +205,24 @@ SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS}); - Note: multiple inheritance is not possible; thus we will always take the first parent class -## Register class +## Registration + +The registration part consists of registering classes at contexts (i.e., global or namespace), +methods and properties at classes or contexts, and namespaces as objects at +parent contexts. + +### Global Variable + +~~~~ +${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER}, ${SETTER}); +~~~~ + +- `CONTEXT`: either global, or the according namespace template +- `${SETTER} = 0` for read-only variables + +### Global Function + +### Class ~~~~ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction())); @@ -210,6 +231,32 @@ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGL - Note: every class template has an associated ctor function wrapper, which is registered here - `CONTEXT`: either global, or the according namespace instance +### Class method + +### Class variable + +## Namespace + +~~~~ +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance())); +~~~~ + +Note: it is important to register the namespace objects in reverse order, +e.g., + +~~~~ +namespace foo { + namespace bar {} +} +~~~~ + +would be registered in this order: + +~~~~ +foo->Set(v8::String::NewSymbol("bar", bar->NewInstance())); +global->Set(v8::String::NewSymbol("foo", foo->NewInstance())); +~~~~ + ## HELPER_FUNCTIONS A lot of boiler-plate code can be shifted into static helper functions: @@ -589,3 +636,115 @@ enter classHandler() of B exit classHandler() of B exit top() of example ~~~~ + +Examples +======== + +## Global variable + +~~~~~ +static double Foo = 42.0; + +void Foo_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + double arg1 ; + arg1 = value->NumberValue(); + Foo = arg1; +} + +v8::Handle Foo_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle ret; + double result; + + result = Foo; + + ret = v8::Number::New(result); + return scope.Close(ret); +} + +int GlobalVar_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + global->SetAccessor(v8::String::New("Foo"), Foo_get, Foo_set); + + return 0; +} +~~~~~ + +## Global functions + +~~~~~ + +static double foo(int bla) { + return (bla * 2.1); +} + +v8::Handle wrap_foo(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle ret; + + int arg1 ; + double result; + + arg1 = args[0]->Int32Value(); + + result = foo(arg1); + + ret = v8::Number::New(result); + + return scope.Close(ret); +} + +int GlobalFunc_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + global->Set(v8::String::NewSymbol("foo"), v8::FunctionTemplate::New(wrap_foo)->GetFunction()); + + return 0; +} +~~~~~ + + +## Namespaces + +~~~~~ + +namespace foo { + static double bar = 42.0; +} + +void foo_bar_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + + double arg1 ; + arg1 = value->NumberValue(); + foo::bar = arg1; + +} + +v8::Handle foo_bar_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle ret; + double result; + + result = foo::bar; + + ret = v8::Number::New(result); + return scope.Close(ret); +} + +int Namespace_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Handle foo = v8::ObjectTemplate::New(); + + foo->SetAccessor(v8::String::New("bar"), foo_bar_get, foo_bar_set); + + global->Set(v8::String::New("foo"), foo->NewInstance()); + return 0; +} + +~~~~~ From 6c90d1eb6d46bd1dd52aa3121d38511974423d8b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:48:11 +0000 Subject: [PATCH 012/352] Minor improvements in v8 emitter implementation git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13746 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 4 ++ Lib/javascript/v8/javascripthelpers.swg | 17 +++++- Source/Modules/javascript_v8.cxx | 76 +++++++++++++++---------- 3 files changed, 64 insertions(+), 33 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 2671fc117..d83ded12e 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -72,3 +72,7 @@ v8::Handle ${NAME_MANGLED}(const Arguments &args) { return scope.Close(ret); } %} + +%fragment("v8_register_member_function", "templates") %{ +SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${WRAPPER}); +%} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index 61836c87d..c96bd346a 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -27,10 +27,14 @@ v8::Persistent SWIGV8_CreateClassTemplate(const char* symb return v8::Persistent::New(class_templ); } +v8::Handle SWIGV8_CreateNamespace(const char* name, v8::Handle parentContext) { + Handle namespace = ObjectTemplate::New(); +} + /** * Sets the pimpl data of a V8 class. */ -v8::Handle V8GeneratorUtils::SetInstance(const v8::Arguments& args, void* data) { +v8::Handle SWIGV8_SetInstance(const v8::Arguments& args, void* data) { v8::HandleScope scope; v8::Handle self = args.Holder(); @@ -42,15 +46,22 @@ v8::Handle V8GeneratorUtils::SetInstance(const v8::Arguments& args, v /** * Registers a class method with given name for a given class template. */ -void V8GeneratorUtils::AddClassMethod(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { +void SWIGV8_AddClassMethod(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { v8::Handle proto_templ = class_templ->PrototypeTemplate(); proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); } +/** + * Registers a class method with given name for a given class template. + */ +void SWIGV8_AddGlobalMethod(v8::Handle obj_templ, const char* symbol, v8::InvocationCallback _func) { + obj_templ->Set(String::New(symbol), FunctionTemplate::New(_func)); +} + /** * Registers a class property with given name for a given class template. */ -void V8GeneratorUtils::AddProperty(v8::Handle class_templ, const char* varname, v8::AccessorGetter getter, v8::AccessorSetter setter) { +void SWIGV8_AddProperty(v8::Handle class_templ, const char* varname, v8::AccessorGetter getter, v8::AccessorSetter setter) { v8::Handle proto_templ = class_templ->InstanceTemplate(); proto_templ->SetAccessor(v8::String::New(varname), getter, setter); } diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index 7d2583aca..9abb66976 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -16,13 +16,16 @@ #define V8_SETTER "v8_setter" #define V8_FUNCTION "v8_function" #define V8_RETRIEVE_THIS "v8_retrieve_this" +#define V8_REGISTER_MEMBER_FUNCTION "v8_register_member_function" // keywords used in templates #define KW_MODULE_NAME "${MODULE}" #define KW_MANGLED_NAME "${NAME_MANGLED}" #define KW_UNQUALIFIED_NAME "${NAME_UNQUALIFIED}" +#define KW_CLASSNAME_MANGLED "${CLASSNAME_MANGLED}" #define KW_BASE_CLASS "${BASE_CLASS}" #define KW_CONTEXT "${CONTEXT}" +#define KW_WRAPPER "${WRAPPER}" #define KW_NAME_SPACES "${PART_NAMESPACES}" #define KW_CLASS_TEMPLATES "${PART_CLASS_TEMPLATES}" @@ -70,9 +73,8 @@ int V8Emitter::Initialize(Node *n) f_init_inheritance = NewString(""); f_init_register = NewString(""); + // 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("wrapper", f_wrapper); return SWIG_OK; } @@ -179,18 +181,18 @@ int V8Emitter::ExitClass(Node *n) // emit inheritance setup Node* baseClass = GetBaseClass(n); if(baseClass) { - Template t(GetTemplate(V8_INHERIT)); - t.Replace(KW_MANGLED_NAME, current_classname_mangled) + 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.str(), 0); + Printv(f_init_inheritance, t_inherit.str(), 0); } // emit registeration of class template - Template t(GetTemplate(V8_REGISTER_CLASS)); - t.Replace(KW_MANGLED_NAME, current_classname_mangled) + 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, t.str(), 0); + Printv(f_init_register, t_register.str(), 0); Delete(current_classname_mangled); Delete(current_classname_unqualified); @@ -229,6 +231,7 @@ int V8Emitter::ExitVariable(Node* n) 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); @@ -259,11 +262,11 @@ int V8Emitter::EmitCtor(Node* n) Template t(GetTemplate(V8_CTOR_WRAPPER)); ParmList *params = Getattr(n,"parms"); - String* action = Getattr(n, "wrap:action"); - String* input = NewString(""); - emit_parameter_variables(params, current_wrapper); emit_attach_parmmaps(params, current_wrapper); + + String* action = Getattr(n, "wrap:action"); + String* input = NewString(""); t.Replace(KW_MANGLED_NAME, current_classname_mangled) .Replace(KW_UNQUALIFIED_NAME, current_classname_unqualified) @@ -272,7 +275,7 @@ int V8Emitter::EmitCtor(Node* n) .Replace(KW_MARSHAL_INPUT, input); Wrapper_pretty_print(t.str(), f_wrapper); - + return SWIG_OK; } @@ -287,21 +290,21 @@ int V8Emitter::EmitDtor(Node* n) } int V8Emitter::EmitGetter(Node *n, bool is_member) { - Template t(GetTemplate(V8_GETTER)); + Template t_getter(GetTemplate(V8_GETTER)); - Setattr(n, "wrap:name", Getattr(n, "sym:name")); Printf(current_wrapper->locals, "%s result;\n", SwigType_str(Getattr(n, "type"), 0)); String* action = emit_action(n); String* output = NewString("// TODO: marshal output.\n ret = v8::Undefined();"); - t.Replace(KW_MANGLED_NAME, current_variable_mangled) + t_getter.Replace(KW_MANGLED_NAME, current_variable_mangled) .Replace(KW_LOCALS, current_wrapper->locals) .Replace(KW_ACTION, action) .Replace(KW_MARSHAL_OUTPUT, output); - Wrapper_pretty_print(t.str(), f_wrapper); - + Wrapper_pretty_print(t_getter.str(), f_wrapper); + + // clean up Delete(output); return SWIG_OK; @@ -309,24 +312,23 @@ int V8Emitter::EmitGetter(Node *n, bool is_member) { int V8Emitter::EmitSetter(Node* n, bool is_member) { - Template t(GetTemplate(V8_SETTER)); - - Setattr(n, "wrap:name", Getattr(n, "sym:name")); + Template t_setter(GetTemplate(V8_SETTER)); + ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); emit_attach_parmmaps(params, current_wrapper); String* action = emit_action(n); String* input = NewString("// TODO: marshal input.\n"); - t.Replace(KW_MANGLED_NAME, current_variable_mangled) + t_setter.Replace(KW_MANGLED_NAME, current_variable_mangled) .Replace(KW_LOCALS, current_wrapper->locals) .Replace(KW_ACTION, action) .Replace(KW_MARSHAL_INPUT, input); - Wrapper_pretty_print(t.str(), f_wrapper); + Wrapper_pretty_print(t_setter.str(), f_wrapper); + // clean up Delete(input); return SWIG_OK; @@ -335,30 +337,44 @@ int V8Emitter::EmitSetter(Node* n, bool is_member) int V8Emitter::EmitFunction(Node* n, bool is_member) { - Template t(GetTemplate(V8_FUNCTION)); + Template t_function(GetTemplate(V8_FUNCTION)); - Setattr(n, "wrap:name", Getattr(n, "sym:name")); + String* wrap_name = NewString(""); + Printv(wrap_name, current_function_mangled, 0); + Setattr(n, "wrap:name", wrap_name); + ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); emit_attach_parmmaps(params, current_wrapper); Printf(current_wrapper->locals, "%s result;\n", SwigType_str(Getattr(n, "type"), 0)); - - + String* input = NewString("// TODO: marshal input"); String* action = emit_action(n); String* output = NewString("// TODO: marshal output.\n ret = v8::Undefined();"); - t.Replace(KW_MANGLED_NAME, current_function_mangled) + t_function.Replace(KW_MANGLED_NAME, current_function_mangled) .Replace(KW_LOCALS, current_wrapper->locals) .Replace(KW_ACTION, action) .Replace(KW_MARSHAL_INPUT, input) .Replace(KW_MARSHAL_OUTPUT, output); - Wrapper_pretty_print(t.str(), f_wrapper); + Wrapper_pretty_print(t_function.str(), f_wrapper); + // register the function at the specific context + if (is_member) { + Template t_register(GetTemplate(V8_REGISTER_MEMBER_FUNCTION)); + t_register.Replace(KW_UNQUALIFIED_NAME, current_function_unqualified) + .Replace(KW_WRAPPER, wrap_name) + .Replace(KW_CLASSNAME_MANGLED, current_classname_mangled); + Printv(f_init_register, t_register.str(), "\n", 0); + } else { + // TODO + } + + // clean up Delete(input); Delete(output); + Delete(wrap_name); return SWIG_OK; } From 90bbc6430bf5fb8f234c5ea46a09ef5f528ec72d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:48:24 +0000 Subject: [PATCH 013/352] Update v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13747 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 328 ++++++++++-------- 1 file changed, 175 insertions(+), 153 deletions(-) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index 095936ff8..fcd581755 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -26,7 +26,7 @@ The generated code consists of the following blocks: - `FUNCTION_WRAPPERS`: dynamically growing, on method declarations - `INITIALIZER`: dynamically growing, aggregates everything (to be specified in more detail) -## INCLUDES +### INCLUDES ~~~~ #include @@ -36,7 +36,7 @@ The generated code consists of the following blocks: `USER_DEFINED_INCLUDES`: a module property -## CLASS_TEMPLATES +### CLASS_TEMPLATES Static references to class templates which are (should be) read-only and can be reused. @@ -55,16 +55,28 @@ Notes: There are different types of function wrappers: - - Static Functions (global/namespace/class) + - Global Functions (global/namespace/class) - Constructors / Destructors - Getters / Settters - Member Functions -## Static Functions +### Global Functions -TODO +~~~~ +v8::Handle wrap_${NAME_MANGLED}(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle ret; -## Constructors + ${LOCALS} + ${MARSHAL_INPUT} + ${ACTION} + ${MARSHAL_OUTPUT} + + return scope.Close(ret); +} +~~~~ + +### Constructors ~~~~ v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { @@ -82,11 +94,11 @@ v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { - `MARSHAL_INPUT`: code is generated by applying input typemaps - `ACTION`: the C/C++ ctor to be executed -## Destructors +### Destructors TODO: I haven't found out yet how a descrtuctor can be registered -## Getters +### Getters ~~~~ v8::Handle ${NAME_MANGLED}_get(v8::Local property, const v8::AccessorInfo& info) { @@ -103,7 +115,7 @@ v8::Handle ${NAME_MANGLED}_get(v8::Local property, const - `LOCALS`: declare C return variable - `MARSHAL_OUTPUT`: code is generated by applying output typemaps -## Setters +### Setters ~~~~ void ${NAME_MANGLED}_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { @@ -116,7 +128,7 @@ void ${NAME_MANGLED}_set(v8::Local property, v8::Local va - `LOCALS`: declarations for input arguments - `MARSHAL_INPUT`: code is generated by applying input typemaps -## Functions +### Functions ~~~~ v8::Handle ${NAME_MANGLED}(const Arguments &args) { @@ -132,12 +144,13 @@ v8::Handle ${NAME_MANGLED}(const Arguments &args) { - if the function does not have a return value, return v8::Undefined -## Overloading +### Overloading TODO: if a function or a ctor is overloaded, a dispatcher function must be generated which calls overloading wrappers depending on number and type of input arguments. + ## Initializer ~~~~ @@ -160,7 +173,7 @@ void ${MODULE}_Initialize(v8::Handle context) } ~~~~ -## Namespaces +### Namespaces Namespaces are objects without class templates. I.e., instances are created, referenced locally, used as contexts for other registrations, and stored @@ -170,7 +183,7 @@ in the according parent contexts. v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New(); ~~~~~ -## Create Class Template +### Class Templates ~~~~ SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new); @@ -178,26 +191,7 @@ SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NA - `NAME_UNQUALIFIED`: the class name without context, i.e., namespaces -## Add Member Function - -~~~~ - SWIGV8_AddClassMethod(SWIGV8_$CLASSNAME, "$METHODNAME", $METHOD_WRAPPER); -~~~~ - -- `METHODNAME`: the name of the function as in C++ -- `METHOD_WRAPPER`: the name of the generated wrapper function, which - should have the form `wrap__` - -## Add Property - -~~~~ - SWIGV8_AddProperty(SWIGV8_$CLASSNAME, "$VARNAME", $GET_WRAPPER, $SET_WRAPPER); -~~~~ - -- `GET_WRAPPER`: the name of the generated wrapper for the property getter -- `SET_WRAPPER`: the name of the generated wrapper for property setter; optional (i.e., maybe `NULL`) - -## Inheritance +### Inheritance ~~~~ SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS}); @@ -205,13 +199,13 @@ SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS}); - Note: multiple inheritance is not possible; thus we will always take the first parent class -## Registration +### Registration The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. -### Global Variable +#### Global Variable ~~~~ ${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER}, ${SETTER}); @@ -220,9 +214,15 @@ ${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER}, - `CONTEXT`: either global, or the according namespace template - `${SETTER} = 0` for read-only variables -### Global Function +#### Global Function -### Class +~~~~ +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), v8::FunctionTemplate::New(wrap_${NAME_QUALIFIED})->GetFunction()); +~~~~ + +- `CONTEXT`: either global, or the according namespace template + +#### Class ~~~~ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction())); @@ -231,11 +231,24 @@ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGL - Note: every class template has an associated ctor function wrapper, which is registered here - `CONTEXT`: either global, or the according namespace instance -### Class method +#### Class method -### Class variable +~~~~ +SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED}); +~~~~ -## Namespace +Note: implemented in static helper function + +#### Class variable + +~~~~ +SWIGV8_AddProperty(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER}); +~~~~ + +- `GETTER`: the name of the generated wrapper for the property getter +- `SETTER`: the name of the generated wrapper for property setter; optional (i.e., maybe `NULL`) + +### Namespace ~~~~ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance())); @@ -319,7 +332,128 @@ void V8GeneratorUtils::AddProperty(v8::Handle class_templ, ~~~~ -# Control flow analysis +------------------------- + +Examples +======== + +In this chapter manually coded wrappers are presented. +This has been useful for studying the addressed code generation on basis +of examples. + +## Global variable + +~~~~~ +static double Foo = 42.0; + +void Foo_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + double arg1 ; + arg1 = value->NumberValue(); + Foo = arg1; +} + +v8::Handle Foo_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle ret; + double result; + + result = Foo; + + ret = v8::Number::New(result); + return scope.Close(ret); +} + +int GlobalVar_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + global->SetAccessor(v8::String::New("Foo"), Foo_get, Foo_set); + + return 0; +} +~~~~~ + +## Global functions + +~~~~~ + +static double foo(int bla) { + return (bla * 2.1); +} + +v8::Handle wrap_foo(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle ret; + + int arg1 ; + double result; + + arg1 = args[0]->Int32Value(); + + result = foo(arg1); + + ret = v8::Number::New(result); + + return scope.Close(ret); +} + +int GlobalFunc_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + global->Set(v8::String::NewSymbol("foo"), v8::FunctionTemplate::New(wrap_foo)->GetFunction()); + + return 0; +} +~~~~~ + + +## Namespaces + +~~~~~ + +namespace foo { + static double bar = 42.0; +} + +void foo_bar_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + + double arg1 ; + arg1 = value->NumberValue(); + foo::bar = arg1; + +} + +v8::Handle foo_bar_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle ret; + double result; + + result = foo::bar; + + ret = v8::Number::New(result); + return scope.Close(ret); +} + +int Namespace_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Handle foo = v8::ObjectTemplate::New(); + + foo->SetAccessor(v8::String::New("bar"), foo_bar_get, foo_bar_set); + + global->Set(v8::String::New("foo"), foo->NewInstance()); + return 0; +} + +~~~~~ + +------------------------- + +Control flow analysis +===================== ## Global variables @@ -636,115 +770,3 @@ enter classHandler() of B exit classHandler() of B exit top() of example ~~~~ - -Examples -======== - -## Global variable - -~~~~~ -static double Foo = 42.0; - -void Foo_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - v8::HandleScope scope; - double arg1 ; - arg1 = value->NumberValue(); - Foo = arg1; -} - -v8::Handle Foo_get(v8::Local property, const v8::AccessorInfo& info) { - v8::HandleScope scope; - v8::Handle ret; - double result; - - result = Foo; - - ret = v8::Number::New(result); - return scope.Close(ret); -} - -int GlobalVar_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - global->SetAccessor(v8::String::New("Foo"), Foo_get, Foo_set); - - return 0; -} -~~~~~ - -## Global functions - -~~~~~ - -static double foo(int bla) { - return (bla * 2.1); -} - -v8::Handle wrap_foo(const v8::Arguments &args) { - v8::HandleScope scope; - v8::Handle ret; - - int arg1 ; - double result; - - arg1 = args[0]->Int32Value(); - - result = foo(arg1); - - ret = v8::Number::New(result); - - return scope.Close(ret); -} - -int GlobalFunc_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - - global->Set(v8::String::NewSymbol("foo"), v8::FunctionTemplate::New(wrap_foo)->GetFunction()); - - return 0; -} -~~~~~ - - -## Namespaces - -~~~~~ - -namespace foo { - static double bar = 42.0; -} - -void foo_bar_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - v8::HandleScope scope; - - double arg1 ; - arg1 = value->NumberValue(); - foo::bar = arg1; - -} - -v8::Handle foo_bar_get(v8::Local property, const v8::AccessorInfo& info) { - v8::HandleScope scope; - v8::Handle ret; - double result; - - result = foo::bar; - - ret = v8::Number::New(result); - return scope.Close(ret); -} - -int Namespace_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - - v8::Handle foo = v8::ObjectTemplate::New(); - - foo->SetAccessor(v8::String::New("bar"), foo_bar_get, foo_bar_set); - - global->Set(v8::String::New("foo"), foo->NewInstance()); - return 0; -} - -~~~~~ From 886f17c34372ded14504ad684b71cd786faa8e42 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:48:43 +0000 Subject: [PATCH 014/352] Implement namespace support for v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13748 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 27 ++++++++++++++------ Source/Modules/javascript_v8.cxx | 38 ++++++++++++++++++++++++---- Source/Modules/javascript_v8.h | 1 + 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index d83ded12e..4f4d5e292 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -3,19 +3,25 @@ void ${MODULE}_Initialize(v8::Handle context) { v8::HandleScope scope; - - // register the module in globale context v8::Local global = context->Global(); + /* create object templates for namespaces */ ${PART_NAMESPACES} - + + /* create class templates */ ${PART_CLASS_TEMPLATES} - + + /* register wrapper functions */ ${PART_WRAPPERS} - + + /* setup inheritances */ ${PART_INHERITANCE} - + + /* some registration TODO: what specifically?*/ ${PART_REGISTER} + + /* create and register namespace objects */ + ${PART_REGISTER_NS} }%} %fragment("v8_declare_class_template", "templates") %{ @@ -74,5 +80,10 @@ v8::Handle ${NAME_MANGLED}(const Arguments &args) { %} %fragment("v8_register_member_function", "templates") %{ -SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${WRAPPER}); -%} +SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${WRAPPER});%} + +%fragment("v8_create_namespace", "templates") %{ +v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New();%} + +%fragment("v8_register_namespace", "templates") %{ +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance()));%} diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index 9abb66976..36c24c15f 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -17,6 +17,9 @@ #define V8_FUNCTION "v8_function" #define V8_RETRIEVE_THIS "v8_retrieve_this" #define V8_REGISTER_MEMBER_FUNCTION "v8_register_member_function" +#define V8_CREATE_NAMESPACE "v8_create_namespace" +#define V8_REGISTER_NAMESPACE "v8_register_namespace" + // keywords used in templates #define KW_MODULE_NAME "${MODULE}" @@ -32,6 +35,7 @@ #define KW_WRAPPERS "${PART_WRAPPERS}" #define KW_INHERITANCE "${PART_INHERITANCE}" #define KW_REGISTER "${PART_REGISTER}" +#define KW_REGISTER_NS "${PART_REGISTER_NS}" #define KW_LOCALS "${LOCALS}" #define KW_MARSHAL_INPUT "${MARSHAL_INPUT}" @@ -72,6 +76,7 @@ int V8Emitter::Initialize(Node *n) f_init_wrappers = NewString(""); f_init_inheritance = NewString(""); f_init_register = NewString(""); + f_init_register_namespaces = NewString(""); // note: this is necessary for built-in generation of swig runtime code Swig_register_filebyname("runtime", f_runtime); @@ -100,7 +105,8 @@ int V8Emitter::Dump(Node *n) .Replace(KW_CLASS_TEMPLATES, f_init_class_templates) .Replace(KW_WRAPPERS, f_init_wrappers) .Replace(KW_INHERITANCE, f_init_inheritance) - .Replace(KW_REGISTER, f_init_register); + .Replace(KW_REGISTER, f_init_register) + .Replace(KW_REGISTER_NS, f_init_register_namespaces); Wrapper_pretty_print(initializer.str(), f_wrap_cpp); return SWIG_OK; @@ -117,6 +123,7 @@ int V8Emitter::Close() Delete(f_init_wrappers); Delete(f_init_inheritance); Delete(f_init_register); + Delete(f_init_register_namespaces); ::Close(f_wrap_cpp); Delete(f_wrap_cpp); @@ -143,17 +150,38 @@ int V8Emitter::SwitchContext(Node *n) int V8Emitter::CreateNamespace(String* scope) { String* parent_scope = Swig_scopename_prefix(scope); + String* parent_scope_mangled = 0; + + if(!parent_scope) { + parent_scope_mangled = NewString("global"); + } else { + parent_scope_mangled = Swig_name_mangle(parent_scope); + + } if (parent_scope && !Getattr(namespaces, parent_scope)) { CreateNamespace(parent_scope); } - String* ns = Swig_string_mangle(scope); - Setattr(namespaces, scope, ns); + String* scope_mangled = Swig_string_mangle(scope); + String* scope_unqualified = Swig_scopename_last(scope); + Setattr(namespaces, scope, scope_mangled); - // TODO: create namespace object and register it to the parent scope - Printf(f_init_namespaces, "create_ns(%s);\n", ns); + // 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; } diff --git a/Source/Modules/javascript_v8.h b/Source/Modules/javascript_v8.h index bb190a71b..29bb381ee 100644 --- a/Source/Modules/javascript_v8.h +++ b/Source/Modules/javascript_v8.h @@ -57,6 +57,7 @@ private: File *f_init_wrappers; File *f_init_inheritance; File *f_init_register; + File *f_init_register_namespaces; // the output cpp file File *f_wrap_cpp; From 9a599be8ab6c3426362beb3dd572cd399620da8d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:49:02 +0000 Subject: [PATCH 015/352] Fix order of registration in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13749 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 4 ++-- Source/Modules/javascript_v8.cxx | 12 ++++++------ Source/Modules/javascript_v8.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 4f4d5e292..1eb20c20d 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -17,8 +17,8 @@ void ${MODULE}_Initialize(v8::Handle context) /* setup inheritances */ ${PART_INHERITANCE} - /* some registration TODO: what specifically?*/ - ${PART_REGISTER} + /* register classes */ + ${PART_REGISTER_CLASSES} /* create and register namespace objects */ ${PART_REGISTER_NS} diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index 36c24c15f..3ec8393b4 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -34,7 +34,7 @@ #define KW_CLASS_TEMPLATES "${PART_CLASS_TEMPLATES}" #define KW_WRAPPERS "${PART_WRAPPERS}" #define KW_INHERITANCE "${PART_INHERITANCE}" -#define KW_REGISTER "${PART_REGISTER}" +#define KW_REGISTER_CLASSES "${PART_REGISTER_CLASSES}" #define KW_REGISTER_NS "${PART_REGISTER_NS}" #define KW_LOCALS "${LOCALS}" @@ -75,7 +75,7 @@ int V8Emitter::Initialize(Node *n) f_init_class_templates = NewString(""); f_init_wrappers = NewString(""); f_init_inheritance = NewString(""); - f_init_register = NewString(""); + f_init_register_classes = NewString(""); f_init_register_namespaces = NewString(""); // note: this is necessary for built-in generation of swig runtime code @@ -105,7 +105,7 @@ int V8Emitter::Dump(Node *n) .Replace(KW_CLASS_TEMPLATES, f_init_class_templates) .Replace(KW_WRAPPERS, f_init_wrappers) .Replace(KW_INHERITANCE, f_init_inheritance) - .Replace(KW_REGISTER, f_init_register) + .Replace(KW_REGISTER_CLASSES, f_init_register_classes) .Replace(KW_REGISTER_NS, f_init_register_namespaces); Wrapper_pretty_print(initializer.str(), f_wrap_cpp); @@ -122,7 +122,7 @@ int V8Emitter::Close() Delete(f_init_class_templates); Delete(f_init_wrappers); Delete(f_init_inheritance); - Delete(f_init_register); + Delete(f_init_register_classes); Delete(f_init_register_namespaces); ::Close(f_wrap_cpp); Delete(f_wrap_cpp); @@ -220,7 +220,7 @@ int V8Emitter::ExitClass(Node *n) 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, t_register.str(), 0); + Printv(f_init_register_classes, t_register.str(), 0); Delete(current_classname_mangled); Delete(current_classname_unqualified); @@ -394,7 +394,7 @@ int V8Emitter::EmitFunction(Node* n, bool is_member) t_register.Replace(KW_UNQUALIFIED_NAME, current_function_unqualified) .Replace(KW_WRAPPER, wrap_name) .Replace(KW_CLASSNAME_MANGLED, current_classname_mangled); - Printv(f_init_register, t_register.str(), "\n", 0); + Printv(f_init_wrappers, t_register.str(), "\n", 0); } else { // TODO } diff --git a/Source/Modules/javascript_v8.h b/Source/Modules/javascript_v8.h index 29bb381ee..0738b930b 100644 --- a/Source/Modules/javascript_v8.h +++ b/Source/Modules/javascript_v8.h @@ -56,7 +56,7 @@ private: File *f_init_class_templates; File *f_init_wrappers; File *f_init_inheritance; - File *f_init_register; + File *f_init_register_classes; File *f_init_register_namespaces; // the output cpp file From 7ba26c8a26e52d2f499e20b866b273571c6264b8 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:49:15 +0000 Subject: [PATCH 016/352] Minor change in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13750 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript_v8.cxx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index 3ec8393b4..5c404b07c 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -190,16 +190,16 @@ int V8Emitter::EnterClass(Node *n) current_classname_mangled = Swig_string_mangle(Getattr(n, "name")); current_classname_unqualified = Swig_scopename_last(Getattr(n, "name")); - // emit declaration of a v8 class template in part - Template t(GetTemplate(V8_DECL_CLASSTEMPLATE)); - t.Replace(KW_MANGLED_NAME, current_classname_mangled); - Printv(f_class_templates, t.str(), 0); + // 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 in part - Template t2(GetTemplate(V8_DEFINE_CLASSTEMPLATE)); - t2.Replace(KW_MANGLED_NAME, current_classname_mangled) - .Replace(KW_UNQUALIFIED_NAME, current_classname_unqualified); - Printv(f_init_class_templates, t2.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); return SWIG_OK; } From 285badb95b03a3f1ee7a84fa1b473b06c477f35d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:49:32 +0000 Subject: [PATCH 017/352] Improve v8 generator regarding registration of function wrappers. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13751 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 11 +++++++---- Source/Modules/javascript_v8.cxx | 15 +++++++++------ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 1eb20c20d..dbc5c788d 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -68,7 +68,7 @@ void ${NAME_MANGLED}_set(v8::Local property, v8::Local va %} %fragment("v8_function", "templates") %{ -v8::Handle ${NAME_MANGLED}(const Arguments &args) { +v8::Handle wrap_${NAME_MANGLED}(const Arguments &args) { v8::HandleScope scope; v8::Handle ret; ${LOCALS} @@ -79,11 +79,14 @@ v8::Handle ${NAME_MANGLED}(const Arguments &args) { } %} -%fragment("v8_register_member_function", "templates") %{ -SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${WRAPPER});%} - %fragment("v8_create_namespace", "templates") %{ v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New();%} +%fragment("v8_register_member_function", "templates") %{ +SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} + +%fragment("v8_register_global_function", "templates") %{ +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), v8::FunctionTemplate::New(wrap_${NAME_MANGLED})->GetFunction());%} + %fragment("v8_register_namespace", "templates") %{ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance()));%} diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index 5c404b07c..bf284aac5 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -17,6 +17,7 @@ #define V8_FUNCTION "v8_function" #define V8_RETRIEVE_THIS "v8_retrieve_this" #define V8_REGISTER_MEMBER_FUNCTION "v8_register_member_function" +#define V8_REGISTER_GLOBAL_FUNCTION "v8_register_global_function" #define V8_CREATE_NAMESPACE "v8_create_namespace" #define V8_REGISTER_NAMESPACE "v8_register_namespace" @@ -247,6 +248,7 @@ int V8Emitter::ExitVariable(Node* n) { // TODO: Register variable in context + Swig_print_node(n); Delete(current_variable_mangled); Delete(current_variable_unqualified); @@ -271,9 +273,7 @@ int V8Emitter::EnterFunction(Node* n) } int V8Emitter::ExitFunction(Node* n) -{ - // TODO: Register function in context - +{ Delete(current_function_mangled); Delete(current_function_unqualified); current_function_mangled = 0; @@ -385,18 +385,21 @@ int V8Emitter::EmitFunction(Node* n, bool is_member) .Replace(KW_ACTION, action) .Replace(KW_MARSHAL_INPUT, input) .Replace(KW_MARSHAL_OUTPUT, output); - Wrapper_pretty_print(t_function.str(), f_wrapper); // register the function at the specific context if (is_member) { Template t_register(GetTemplate(V8_REGISTER_MEMBER_FUNCTION)); t_register.Replace(KW_UNQUALIFIED_NAME, current_function_unqualified) - .Replace(KW_WRAPPER, wrap_name) + .Replace(KW_MANGLED_NAME, wrap_name) .Replace(KW_CLASSNAME_MANGLED, current_classname_mangled); Printv(f_init_wrappers, t_register.str(), "\n", 0); } else { - // TODO + 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, wrap_name); + Printv(f_init_wrappers, t_register.str(), 0); } // clean up From 8e0711cbc63ceb6b0adcc1a2ec4133b0fa198a25 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:49:44 +0000 Subject: [PATCH 018/352] Fix memory related bug in generalized javascript emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13752 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript_emitter.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/javascript_emitter.cxx b/Source/Modules/javascript_emitter.cxx index 7b49aaf5d..b9446663a 100644 --- a/Source/Modules/javascript_emitter.cxx +++ b/Source/Modules/javascript_emitter.cxx @@ -107,7 +107,7 @@ int JSEmitter::EmitWrapperFunction(Node* n) int ret = SWIG_OK; current_wrapper = NewWrapper(); - Setattr(n, "wrap:name", Getattr(n, "sym:name")); + Setattr(n, "wrap:name", NewString(Getattr(n, "sym:name"))); String* kind = Getattr(n, "kind"); From 71bee1e78c52a65c5a159768c2f6f02cf3eb903f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:50:06 +0000 Subject: [PATCH 019/352] Complement variable processing in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13753 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 8 ++++++- Lib/javascript/v8/javascripthelpers.swg | 12 +++++++--- Source/Modules/javascript_v8.cxx | 32 ++++++++++++++++++++++--- Source/Modules/javascript_v8.h | 3 +++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index dbc5c788d..52a0651b3 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -86,7 +86,13 @@ v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New();%} SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} %fragment("v8_register_global_function", "templates") %{ -${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), v8::FunctionTemplate::New(wrap_${NAME_MANGLED})->GetFunction());%} +SWIGV8_AddGlobalMethod(${CONTEXT}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} + +%fragment("v8_register_member_variable", "templates") %{ +SWIGV8_AddClassVariable(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER});%} + +%fragment("v8_register_global_variable", "templates") %{ +SWIGV8_AddGlobalVariable(${CONTEXT}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER});%} %fragment("v8_register_namespace", "templates") %{ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance()));%} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index c96bd346a..bc2822c8f 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -55,15 +55,21 @@ void SWIGV8_AddClassMethod(v8::Handle class_templ, const c * Registers a class method with given name for a given class template. */ void SWIGV8_AddGlobalMethod(v8::Handle obj_templ, const char* symbol, v8::InvocationCallback _func) { - obj_templ->Set(String::New(symbol), FunctionTemplate::New(_func)); + obj_templ->Set(String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); } /** * Registers a class property with given name for a given class template. */ -void SWIGV8_AddProperty(v8::Handle class_templ, const char* varname, v8::AccessorGetter getter, v8::AccessorSetter setter) { +void SWIGV8_AddClassVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { v8::Handle proto_templ = class_templ->InstanceTemplate(); - proto_templ->SetAccessor(v8::String::New(varname), getter, setter); + proto_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } +/** + * Registers a class method with given name for a given class template. + */ +void SWIGV8_AddGlobalVariable(v8::Handle obj_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { + obj_templ->SetAccessor(String::NewSymbol(symbol), getter, setter); +} %} // v8_helper_functions diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index bf284aac5..8c1667d25 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -18,10 +18,11 @@ #define V8_RETRIEVE_THIS "v8_retrieve_this" #define V8_REGISTER_MEMBER_FUNCTION "v8_register_member_function" #define V8_REGISTER_GLOBAL_FUNCTION "v8_register_global_function" +#define V8_REGISTER_MEMBER_VARIABLE "v8_register_member_variable" +#define V8_REGISTER_GLOBAL_VARIABLE "v8_register_global_variable" #define V8_CREATE_NAMESPACE "v8_create_namespace" #define V8_REGISTER_NAMESPACE "v8_register_namespace" - // keywords used in templates #define KW_MODULE_NAME "${MODULE}" #define KW_MANGLED_NAME "${NAME_MANGLED}" @@ -30,6 +31,8 @@ #define KW_BASE_CLASS "${BASE_CLASS}" #define KW_CONTEXT "${CONTEXT}" #define KW_WRAPPER "${WRAPPER}" +#define KW_GETTER "${GETTER}" +#define KW_SETTER "${SETTER}" #define KW_NAME_SPACES "${PART_NAMESPACES}" #define KW_CLASS_TEMPLATES "${PART_CLASS_TEMPLATES}" @@ -46,6 +49,7 @@ V8Emitter::V8Emitter() : JSEmitter(), GLOBAL(NewString("global")), + NULL_STR(NewString("0")), namespaces(NewHash()) { } @@ -53,6 +57,7 @@ V8Emitter::V8Emitter() V8Emitter::~V8Emitter() { Delete(GLOBAL); + Delete(NULL_STR); Delete(namespaces); } @@ -171,6 +176,7 @@ int V8Emitter::CreateNamespace(String* scope) { // 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) @@ -240,6 +246,9 @@ int V8Emitter::EnterVariable(Node* n) } else { current_variable_mangled = Swig_string_mangle(Getattr(n, "name")); } + + current_getter = NULL_STR; + current_setter = NULL_STR; return SWIG_OK; } @@ -247,8 +256,21 @@ int V8Emitter::EnterVariable(Node* n) int V8Emitter::ExitVariable(Node* n) { - // TODO: Register variable in context - Swig_print_node(n); + if(GetFlag(n, "ismember")) { + 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); @@ -320,6 +342,8 @@ int V8Emitter::EmitDtor(Node* n) int V8Emitter::EmitGetter(Node *n, bool is_member) { Template t_getter(GetTemplate(V8_GETTER)); + current_getter = Getattr(n,"wrap:name"); + Printf(current_wrapper->locals, "%s result;\n", SwigType_str(Getattr(n, "type"), 0)); String* action = emit_action(n); @@ -341,6 +365,8 @@ int V8Emitter::EmitGetter(Node *n, bool is_member) { int V8Emitter::EmitSetter(Node* n, bool is_member) { Template t_setter(GetTemplate(V8_SETTER)); + + current_setter = Getattr(n,"wrap:name"); ParmList *params = Getattr(n,"parms"); emit_parameter_variables(params, current_wrapper); diff --git a/Source/Modules/javascript_v8.h b/Source/Modules/javascript_v8.h index 0738b930b..c70d54e34 100644 --- a/Source/Modules/javascript_v8.h +++ b/Source/Modules/javascript_v8.h @@ -68,10 +68,13 @@ private: 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; }; From 0e60acfebde30181f93b1acfa57c65b50a13e6c5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:50:19 +0000 Subject: [PATCH 020/352] Minor restructuring in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13754 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript_v8.cxx | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index 8c1667d25..70e0402d4 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -296,6 +296,22 @@ int V8Emitter::EnterFunction(Node* n) int V8Emitter::ExitFunction(Node* n) { + // register the function at the specific context + if(GetFlag(n, "ismember")) { + 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); + } 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); + } + + Delete(current_function_mangled); Delete(current_function_unqualified); current_function_mangled = 0; @@ -413,25 +429,9 @@ int V8Emitter::EmitFunction(Node* n, bool is_member) .Replace(KW_MARSHAL_OUTPUT, output); Wrapper_pretty_print(t_function.str(), f_wrapper); - // register the function at the specific context - if (is_member) { - Template t_register(GetTemplate(V8_REGISTER_MEMBER_FUNCTION)); - t_register.Replace(KW_UNQUALIFIED_NAME, current_function_unqualified) - .Replace(KW_MANGLED_NAME, wrap_name) - .Replace(KW_CLASSNAME_MANGLED, current_classname_mangled); - Printv(f_init_wrappers, t_register.str(), "\n", 0); - } 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, wrap_name); - Printv(f_init_wrappers, t_register.str(), 0); - } - // clean up Delete(input); Delete(output); - Delete(wrap_name); return SWIG_OK; } From 65d4769af8792f4193cba47ef56547f9998c247c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:50:41 +0000 Subject: [PATCH 021/352] Add initial support for argument marshalling using typemaps to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13755 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 40 ++-- Lib/javascript/v8/javascriptprimitives.swg | 237 ++++++++------------- Source/Modules/javascript_v8.cxx | 173 +++++++++++---- Source/Modules/javascript_v8.h | 7 + 4 files changed, 246 insertions(+), 211 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 52a0651b3..855f72284 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -1,4 +1,3 @@ - %fragment("v8_initializer", "templates") %{ void ${MODULE}_Initialize(v8::Handle context) { @@ -41,43 +40,34 @@ v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { v8::HandleScope scope; v8::Handle self = args.Holder(); ${LOCALS} - ${MARSHAL_INPUT} - ${ACTION} - self->SetInternalField(0, v8::External::New(ptr)); + ${CODE} + self->SetInternalField(0, v8::External::New(result)); return self; -} -%} +}%} %fragment("v8_getter", "templates") %{ v8::Handle ${NAME_MANGLED}_get(v8::Local property, const v8::AccessorInfo& info) { v8::HandleScope scope; - v8::Handle ret; + v8::Handle jsresult; ${LOCALS} - ${ACTION} - ${MARSHAL_OUTPUT} - return scope.Close(ret); -} -%} + ${CODE} + return scope.Close(jsresult); +}%} %fragment("v8_setter", "templates") %{ void ${NAME_MANGLED}_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { ${LOCALS} - ${MARSHAL_INPUT} - ${ACTION} -} -%} + ${CODE} +}%} %fragment("v8_function", "templates") %{ v8::Handle wrap_${NAME_MANGLED}(const Arguments &args) { v8::HandleScope scope; - v8::Handle ret; + v8::Handle jsresult; ${LOCALS} - ${MARSHAL_INPUT} - ${ACTION} - ${MARSHAL_OUTPUT} - return scope.Close(ret); -} -%} + ${CODE} + return scope.Close(jsresult); +}%} %fragment("v8_create_namespace", "templates") %{ v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New();%} @@ -96,3 +86,7 @@ SWIGV8_AddGlobalVariable(${CONTEXT}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER} %fragment("v8_register_namespace", "templates") %{ ${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance()));%} + +%fragment("v8_this_ptr", "templates") %{ +arg1 = SWIGV8_UnwrapThisPointer<${TYPE}>(${ARG}.Holder()); +%} diff --git a/Lib/javascript/v8/javascriptprimitives.swg b/Lib/javascript/v8/javascriptprimitives.swg index d5c89c690..b9b255f86 100644 --- a/Lib/javascript/v8/javascriptprimitives.swg +++ b/Lib/javascript/v8/javascriptprimitives.swg @@ -1,66 +1,84 @@ +%typemap(in) bool +%{ $1 = ($1_ltype) $input->BooleanValue();%} + // Primitive types %typemap(in) char, signed char, unsigned char, - short, + short, unsigned short, - int, - unsigned int, + int +%{ $1 = ($1_ltype) $input->Int32Value();%} + +%typemap(in) unsigned int, long, unsigned long, long long, - unsigned long long, - float, - double -%{ $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} + unsigned long long +%{ $1 = ($1_ltype) $input->UInt32Value();%} -%typemap(in) const bool &, bool &, - const char &, char &, - const signed char &, signed char &, - const unsigned char &, unsigned char &, - const short &, short &, - const unsigned short &, unsigned short &, - const int &, int &, - const unsigned int &, unsigned int &, - const long &, long &, - const unsigned long &, unsigned long &, - const long long &, long long &, - const unsigned long long &,unsigned long long &, - const float &, float &, - const double &, double & -%{ $1 = ($1_ltype)&$input; %} +%typemap(in) float, double +%{ $1 = ($1_ltype) $input->NumberValue();%} + + +%typemap(in) const bool &, bool &, + const char &, char &, + const signed char &, signed char &, + const unsigned char &, unsigned char &, + const short &, short &, + const unsigned short &, unsigned short &, + const int &, int &, + const unsigned int &, unsigned int &, + const long &, long &, + const unsigned long &, unsigned long &, + const long long &, long long &, + const unsigned long long &, unsigned long long &, + const float &, float &, + const double &, double & +%{ + // TODO: typemap(in) const bool& at al +} + +%typemap(out) bool +%{ $result = v8::Boolean::New($1);%} %typemap(out) char, signed char, unsigned char, - short, + short, unsigned short, - int, - unsigned int, + int +%{ $result = v8::Int32::New($1);%} + +%typemap(out) unsigned int, long, unsigned long, - long long, - unsigned long long, - float, - double -%{ $result = JSValueMakeNumber(context, $1); %} + long long, + unsigned long long +%{ $result = v8::UInt32::New($1);%} -%typemap(out) const bool &, bool &, - const char &, char &, - const signed char &, signed char &, - const unsigned char &, unsigned char &, - const short &, short &, - const unsigned short &, unsigned short &, - const int &, int &, - const unsigned int &, unsigned int &, - const long &, long &, - const unsigned long &, unsigned long &, - const long long &, long long &, - const unsigned long long &,unsigned long long &, - const float &, float &, - const double &, double & -%{ $result = JSValueMakeNumber(context,*$1); %} +%typemap(out) float, double +%{ $result = v8::Number::New($1); %} +%typemap(out) const bool &, bool &, + const char &, char &, + const signed char &, signed char &, + const unsigned char &, unsigned char &, + const short &, short &, + const unsigned short &, unsigned short &, + const int &, int & +%{ $result = v8::Int32::New((*$1);%} + +%typemap(out) const unsigned int &, unsigned int &, + const long &, long &, + const unsigned long &, unsigned long &, + const long long &, long long &, + const unsigned long long &, unsigned long long & +%{ $result = v8::UInt32::New(*$1);%} + +%typemap(out) const float &, float &, + const double &, double & +%{ $result = v8::Number::New(*$1);%} %typemap(in) short *, unsigned short *, @@ -73,9 +91,7 @@ float *, double * %{ - JSObjectRef o$1 = JSValueToObject(context,$input, NULL); - SWIG_PRV_DATA *$1_privatedata = (SWIG_PRV_DATA *)JSObjectGetPrivate(o$1); - $1 = ($1_ltype)$1_privatedata->swigCObject; + // TODO: typemap(in): short* et al. %} @@ -90,169 +106,88 @@ float *, double * %{ - SWIG_PRV_DATA *privatedata = new SWIG_PRV_DATA(); - privatedata->swigCMemOwn = false; - privatedata->swigCObject = result; - $result = JSObjectMake(context, _wrap_swig_ptr_$*1_ltype_createJSClass(context), privatedata); + // TODO: typemap(out) short* et al. %} -%typemap(in) bool -%{ - $1 = ($1_ltype)JSValueToBoolean(context, $input); -%} - -%typemap(out) bool -%{ - $result = JSValueMakeBoolean(context, $1); -%} - %typemap(out) void -%{ $result = JSValueMakeUndefined(context); %} +%{ $result = v8::Undefined(); %} %typemap(in) char * %{ - JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); - size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); - $1 = (char *)malloc($1_strsize * sizeof(char)); - JSStringGetUTF8CString($1_str, $1, $1_strsize); + // TODO: input typemap for char* %} %typemap(out) char * %{ - JSStringRef jsstring = JSStringCreateWithUTF8CString($1); - $result = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); + // TODO: output typemap for char* %} -%typemap(arginit) char * "" - %typemap(in) char *& ($*1_ltype temp = 0) %{ - temp = ($*1_ltype)$input; - JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); - size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); - $1 = (char *)malloc($1_strsize * sizeof(char)); - JSStringGetUTF8CString($1_str, $1, $1_strsize); + // TODO: input typemap for char*& %} %typemap(out) char *& %{ - JSStringRef jsstring = JSStringCreateWithUTF8CString((const char *)*$1); - $result = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); + // TODO: output typemap for char*& %} /* char arrays - treat as String */ %typemap(in) char[ANY], char[] %{ - JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); - size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); - JSStringGetUTF8CString($1_str, $1, $1_strsize); + // TODO: input typemap for char[] %} %typemap(out) char[ANY], char[] %{ - JSStringRef jsstring = JSStringCreateWithUTF8CString($1); - $result = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); + // TODO: output typemap for char[] %} %typemap(freearg) char *, char *&, char[ANY], char[] //TODO: Not working: A memory leak -%{ free($1); %} +%{ + // TODO: freearg char* et al +%} /* Typemaps for composite types */ %typemap(in) SWIGTYPE ($&1_type argp) // Objects passed by value, convert to a pointer %{ - JSObjectRef o$1 = JSValueToObject(context,$input, NULL); - SWIG_PRV_DATA *$1_privatedata = (SWIG_PRV_DATA *)JSObjectGetPrivate(o$1); - argp = ($&1_ltype)$1_privatedata->swigCObject; - $1 = *argp; + // TODO: input typemap for composite types %} %typemap(out) SWIGTYPE ($&1_type temp) -#ifdef __cplusplus %{ - temp = new $1_ltype((const $1_ltype &)$1); - SWIG_PRV_DATA *privatedata = new SWIG_PRV_DATA(); - privatedata->swigCMemOwn = false; - privatedata->swigCObject = temp; - $result = JSObjectMake(context, _wrap_$1_type_createJSClass(context), privatedata); - //$result = JSObjectMake(context, _wrap_$1_basetype_createJSClass(context), privatedata); - //$result = JSObjectMake(context, _wrap_$objecttype_createJSClass(context), privatedata); - // $1_mangle - // $1_descriptor + // TODO: output typemap for composite types %} -#else -{ - $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype)); - memmove($1ptr, &$1, sizeof($1_type)); - temp = $1ptr; - SWIG_PRV_DATA *privatedata = (SWIG_PRV_DATA *)malloc(sizeof(SWIG_PRV_DATA()); - privatedata->swigCMemOwn = false; - privatedata->swigCObject = temp; - $result = JSObjectMake(context, _wrap_$1_ltype_createJSClass(context), privatedata); - //$result = JSObjectMake(context, _wrap_$1_basetype_createJSClass(context), privatedata); - //$result = JSObjectMake(context, _wrap_$objecttype_createJSClass(context), privatedata); - // $1_mangle - // $1_descriptor -} -#endif %typemap(in) SWIGTYPE *, SWIGTYPE & %{ - JSObjectRef o$1 = JSValueToObject(context,$input, NULL); - SWIG_PRV_DATA *$1_privatedata = (SWIG_PRV_DATA *)JSObjectGetPrivate(o$1); - $1 = ($1_ltype)$1_privatedata->swigCObject; + // TODO: input typemap for ptr types %} %typemap(out) SWIGTYPE *, SWIGTYPE & %{ - SWIG_PRV_DATA *privatedata = new SWIG_PRV_DATA(); - privatedata->swigCMemOwn = false; - privatedata->swigCObject = result; - $result = JSObjectMake(context, _wrap_$*1_ltype_createJSClass(context), privatedata); - //$result = JSObjectMake(context, _wrap_$1_basetype_createJSClass(context), privatedata); - //$result = JSObjectMake(context, _wrap_$objecttype_createJSClass(context), privatedata); - // $1_mangle - // $1_descriptor + // TODO: output typemap for ptr types %} +// TODO: sanity check? %typemap(arginit) SWIGTYPE * -%{ - // Sanity check if the call is not on the global object - if (!JSValueIsEqual(context, - JSValueToObject(context,thisObject,NULL), - JSValueToObject(context,JSContextGetGlobalObject(context), NULL), - NULL)) { - SWIG_PRV_DATA* $1_swigprivatedata = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); - $1 = ($1_ltype)$1_swigprivatedata->swigCObject; - } -%} +%{%} %typemap(in) SWIGTYPE (CLASS::*) "" %typemap(out) SWIGTYPE (CLASS::*) %{ - // Class* out typemap - $result = JSObjectMake(context, _wrap_$*1_ltype_createJSClass(context), result); + // TODO: output typemap for CLASS::* %} - - -/* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions - * that cannot be overloaded in Javascript as more than one C++ type maps to a single Javascript type */ -// TODO - - // Default array handling -%typemap(in) SWIGTYPE [] %{ $1 = ($1_ltype)$input; %} +%typemap(in) SWIGTYPE [] %{ + // TODO: typemap for arrays; +%} + %typemap(out) SWIGTYPE [] %{ $result = $1; %} - -// Javascript specific directives -//TODO - // Some ANSI C typemaps */ %apply unsigned long { size_t }; diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index 70e0402d4..7d6e9a327 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -22,6 +22,8 @@ #define V8_REGISTER_GLOBAL_VARIABLE "v8_register_global_variable" #define V8_CREATE_NAMESPACE "v8_create_namespace" #define V8_REGISTER_NAMESPACE "v8_register_namespace" +#define V8_THIS_PTR "v8_this_ptr" + // keywords used in templates #define KW_MODULE_NAME "${MODULE}" @@ -30,6 +32,8 @@ #define KW_CLASSNAME_MANGLED "${CLASSNAME_MANGLED}" #define KW_BASE_CLASS "${BASE_CLASS}" #define KW_CONTEXT "${CONTEXT}" +#define KW_TYPE "${TYPE}" +#define KW_ARG "${ARG}" #define KW_WRAPPER "${WRAPPER}" #define KW_GETTER "${GETTER}" #define KW_SETTER "${SETTER}" @@ -42,6 +46,7 @@ #define KW_REGISTER_NS "${PART_REGISTER_NS}" #define KW_LOCALS "${LOCALS}" +#define KW_CODE "${CODE}" #define KW_MARSHAL_INPUT "${MARSHAL_INPUT}" #define KW_ACTION "${ACTION}" #define KW_MARSHAL_OUTPUT "${MARSHAL_OUTPUT}" @@ -196,7 +201,8 @@ int V8Emitter::EnterClass(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); @@ -233,6 +239,7 @@ int V8Emitter::ExitClass(Node *n) Delete(current_classname_unqualified); current_classname_mangled = 0; current_classname_unqualified = 0; + current_class_type = 0; return SWIG_OK; } @@ -322,23 +329,19 @@ int V8Emitter::ExitFunction(Node* n) int V8Emitter::EmitCtor(Node* n) { - // TODO: - // - handle overloaded ctors using a dispatcher - // - marshal inputs + // TODO: handle overloaded ctors using a dispatcher Template t(GetTemplate(V8_CTOR_WRAPPER)); + + //HACK: manually add declaration of instance pointer + Printf(current_wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"),0)); - ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_wrapper); - - String* action = Getattr(n, "wrap:action"); - String* input = NewString(""); + String* action = emit_action(n); + Printv(current_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_ACTION, action) - .Replace(KW_MARSHAL_INPUT, input); + .Replace(KW_CODE, current_wrapper->code); Wrapper_pretty_print(t.str(), f_wrapper); @@ -360,21 +363,21 @@ int V8Emitter::EmitGetter(Node *n, bool is_member) { current_getter = Getattr(n,"wrap:name"); - Printf(current_wrapper->locals, "%s result;\n", SwigType_str(Getattr(n, "type"), 0)); - + ParmList *params = Getattr(n,"parms"); + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_wrapper); + + int num_args = emit_num_arguments(params); String* action = emit_action(n); - String* output = NewString("// TODO: marshal output.\n ret = v8::Undefined();"); + marshalInputArgs(n, params, num_args, current_wrapper); + marshalOutput(n, action, current_wrapper); t_getter.Replace(KW_MANGLED_NAME, current_variable_mangled) .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_ACTION, action) - .Replace(KW_MARSHAL_OUTPUT, output); + .Replace(KW_CODE, current_wrapper->code); Wrapper_pretty_print(t_getter.str(), f_wrapper); - - // clean up - Delete(output); - + return SWIG_OK; } @@ -388,19 +391,17 @@ int V8Emitter::EmitSetter(Node* n, bool is_member) emit_parameter_variables(params, current_wrapper); emit_attach_parmmaps(params, current_wrapper); + int num_args = emit_num_arguments(params); String* action = emit_action(n); - String* input = NewString("// TODO: marshal input.\n"); + marshalInputArgs(n, params, num_args, current_wrapper); + Printv(current_wrapper->code, action, 0); t_setter.Replace(KW_MANGLED_NAME, current_variable_mangled) .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_ACTION, action) - .Replace(KW_MARSHAL_INPUT, input); + .Replace(KW_CODE, current_wrapper->code); Wrapper_pretty_print(t_setter.str(), f_wrapper); - // clean up - Delete(input); - return SWIG_OK; } @@ -416,26 +417,124 @@ int V8Emitter::EmitFunction(Node* n, bool is_member) ParmList *params = Getattr(n,"parms"); emit_parameter_variables(params, current_wrapper); emit_attach_parmmaps(params, current_wrapper); - Printf(current_wrapper->locals, "%s result;\n", SwigType_str(Getattr(n, "type"), 0)); - String* input = NewString("// TODO: marshal input"); + int num_args = emit_num_arguments(params); String* action = emit_action(n); - String* output = NewString("// TODO: marshal output.\n ret = v8::Undefined();"); + marshalInputArgs(n, params, num_args, current_wrapper); + marshalOutput(n, action, current_wrapper); t_function.Replace(KW_MANGLED_NAME, current_function_mangled) .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_ACTION, action) - .Replace(KW_MARSHAL_INPUT, input) - .Replace(KW_MARSHAL_OUTPUT, output); + .Replace(KW_CODE, current_wrapper->code); Wrapper_pretty_print(t_function.str(), f_wrapper); - // clean up - Delete(input); - Delete(output); - 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); + } +} + +/* --------------------------------------------------------------------- + * marshalOutput() + * + * Process the return value of the C/C++ function call + * and convert them into the Javascript types using the + * supplied typemaps. + * --------------------------------------------------------------------- */ + +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); +} + +Parm* V8Emitter::skipIgnoredArgs(Parm *p) { + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + return p; +} + + JSEmitter* create_v8_emitter() { return new V8Emitter(); diff --git a/Source/Modules/javascript_v8.h b/Source/Modules/javascript_v8.h index c70d54e34..7ff11f136 100644 --- a/Source/Modules/javascript_v8.h +++ b/Source/Modules/javascript_v8.h @@ -45,6 +45,12 @@ protected: 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; @@ -64,6 +70,7 @@ private: // state variables String* current_context; + String* current_class_type; String* current_classname_mangled; String* current_classname_unqualified; String* current_variable_mangled; From badf090cb5f2a3dd396b616ba0b997f562a28496 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:51:00 +0000 Subject: [PATCH 022/352] Extend and rename v8 helper functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13756 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 74 +++++++++++-------- Lib/javascript/v8/javascriptcode.swg | 6 +- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index fcd581755..2265e6a5d 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -279,8 +279,9 @@ A lot of boiler-plate code can be shifted into static helper functions: /** * Creates a class template for a class without extra initialization function. */ -v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol) { - v8::Local class_templ = v8::FunctionTemplate::New(); +v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol, v8::InvocationCallback func) +{ + v8::Local class_templ = v8::FunctionTemplate::New(func); class_templ->SetClassName(v8::String::NewSymbol(symbol)); v8::Handle inst_templ = class_templ->InstanceTemplate(); @@ -289,47 +290,60 @@ v8::Persistent SWIGV8_CreateClassTemplate(const char* symb return v8::Persistent::New(class_templ); } -/** - * Creates a class template for a class with specified initialization function. - */ -v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol, v8::InvocationCallback _func) { - v8::Local class_templ = v8::FunctionTemplate::New(_func); - class_templ->SetClassName(v8::String::NewSymbol(symbol)); - - v8::Handle inst_templ = class_templ->InstanceTemplate(); - inst_templ->SetInternalFieldCount(1); - - return v8::Persistent::New(class_templ); -} - -/** - * Sets the pimpl data of a V8 class. - */ -v8::Handle V8GeneratorUtils::SetInstance(const v8::Arguments& args, void* data) { - v8::HandleScope scope; - - v8::Handle self = args.Holder(); - self->SetInternalField(0, v8::External::New(data)); - - return self; -} - /** * Registers a class method with given name for a given class template. */ -void V8GeneratorUtils::AddClassMethod(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { +void SWIGV8_AddMemberFunction(v8::Handle class_templ, + const char* symbol, + v8::InvocationCallback func) +{ v8::Handle proto_templ = class_templ->PrototypeTemplate(); - proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); + proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)); } /** * Registers a class property with given name for a given class template. */ -void V8GeneratorUtils::AddProperty(v8::Handle class_templ, const char* varname, v8::AccessorGetter getter, v8::AccessorSetter setter) { +void SWIGV8_AddMemberVariable(v8::Handle class_templ, + const char* varname, + v8::AccessorGetter getter, + v8::AccessorSetter setter) +{ v8::Handle proto_templ = class_templ->InstanceTemplate(); proto_templ->SetAccessor(v8::String::New(varname), getter, setter); } + +/** + * Adds a property with given name to a given context. + */ +void SWIGV8_AddGlobalVariable(v8::Handle context, + const char* varname, + v8::AccessorGetter getter, + v8::AccessorSetter setter) +{ + context->SetAccessor(v8::String::NewSymbol(varname), getter, setter); +} + +/** + * Adds a function with given name to a given context. + */ +void SWIGV8_AddGlobalFunction(v8::Handle context, + const char* symbol, + v8::InvocationCallback func) +{ + context->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)->GetFunction()); +} + +template +static T* SWIGV8_UnwrapThisPointer (v8::Handle handle) +{ + // assert(!handle.IsEmpty()); + // assert(handle->InternalFieldCount() > 0); + v8::Local wrap = v8::Local::Cast(handle->GetInternalField(0)); + return static_cast(wrap->Value()); +} + ~~~~ ------------------------- diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 855f72284..c8dc0a109 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -73,13 +73,13 @@ v8::Handle wrap_${NAME_MANGLED}(const Arguments &args) { v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New();%} %fragment("v8_register_member_function", "templates") %{ -SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} +SWIGV8_AddMemberFunction(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} %fragment("v8_register_global_function", "templates") %{ -SWIGV8_AddGlobalMethod(${CONTEXT}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} +SWIGV8_AddGlobalFunction(${CONTEXT}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} %fragment("v8_register_member_variable", "templates") %{ -SWIGV8_AddClassVariable(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER});%} +SWIGV8_AddMemberVariable(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER});%} %fragment("v8_register_global_variable", "templates") %{ SWIGV8_AddGlobalVariable(${CONTEXT}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER});%} From 0fd30dc60f462afa797acf84f0f0ad6cea0077a3 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:51:16 +0000 Subject: [PATCH 023/352] Add examples to specification of v8 code generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13757 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index 2265e6a5d..112cffbdb 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -464,6 +464,180 @@ int Namespace_Initialize(v8::Handle context) { ~~~~~ +## Class + +~~~~~ + +class A { +public: + A() { + x = 42; + } + + ~A() {} + + double foo(bool a) { + if(a) + return 11.11; + else + return 22.22; + } + + int x; +}; + +v8::Handle A_new(const v8::Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + A *result; + result = new A(); + self->SetInternalField(0, v8::External::New(result)); + return self; +} + +void A_x_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + A *arg1; + int arg2; + + arg1 = SWIGV8_UnwrapThisPointer(info.Holder()); + arg2 = value->Int32Value(); + + arg1->x = arg2; + +} + +v8::Handle A_x_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle jsresult; + A *arg1; + int result; + + arg1 = SWIGV8_UnwrapThisPointer(info.Holder()); + result = arg1->x; + + jsresult = v8::Int32::New(result); + return scope.Close(jsresult); +} + +v8::Handle wrap_A_foo(const v8::Arguments& args) +{ + v8::HandleScope scope; + v8::Handle jsresult; + A *arg1; + double arg2; + double result; + + arg1 = SWIGV8_UnwrapThisPointer(args.Holder()); + arg2 = args[0]->NumberValue(); + + result = arg1->foo(arg2); + + jsresult = v8::Number::New(result); + return scope.Close(jsresult); +} + +int Class_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Persistent class_A = SWIGV8_CreateClassTemplate("A", A_new); + SWIGV8_AddMemberVariable(class_A, "x", A_x_get, A_x_set); + SWIGV8_AddMemberFunction(class_A, "foo", wrap_A_foo); + + global->Set(v8::String::NewSymbol("A"), class_A->GetFunction()); + + return 0; +} + +~~~~~ + +## Static variables and functions + +Static variables and functions are implemented similar to global ones. +They are added to the class object instead of the class template. +Therefore, these are only accessible via the class object and not via +instances of this class. + +~~~~~ + +class A { +public: + A() { + x = 7; + } + + ~A() {} + + static int foo() { + return 42; + } + + static int x; +}; + +int A::x = 7; + +v8::Handle A_new(const v8::Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + A *result; + result = new A(); + self->SetInternalField(0, v8::External::New(result)); + return self; +} + +void A_x_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + int arg1; + + arg1 = value->Int32Value(); + + A::x = arg1; + +} + +v8::Handle A_x_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle jsresult; + int result; + + result = A::x; + + jsresult = v8::Int32::New(result); + return scope.Close(jsresult); +} + +v8::Handle wrap_A_foo(const v8::Arguments& args) +{ + v8::HandleScope scope; + v8::Handle jsresult; + int result; + + result = A::foo(); + + jsresult = v8::Number::New(result); + return scope.Close(jsresult); +} + +int Class_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Persistent classtempl_A = SWIGV8_CreateClassTemplate("A", A_new); + + v8::Handle class_A = classtempl_A->GetFunction(); + + SWIGV8_AddGlobalVariable(class_A, "x", A_x_get, A_x_set); + SWIGV8_AddGlobalFunction(class_A, "foo", wrap_A_foo); + + global->Set(v8::String::NewSymbol("A"), class_A); + + return 0; +} + +~~~~~ + ------------------------- Control flow analysis From e8dd979d165faa481b057a1b4cb145b3b789d36e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:51:29 +0000 Subject: [PATCH 024/352] Update v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13758 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 44 +++++++++---------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index 112cffbdb..7037c665d 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -66,16 +66,15 @@ There are different types of function wrappers: v8::Handle wrap_${NAME_MANGLED}(const v8::Arguments &args) { v8::HandleScope scope; v8::Handle ret; - ${LOCALS} - ${MARSHAL_INPUT} - ${ACTION} - ${MARSHAL_OUTPUT} - + ${CODE} return scope.Close(ret); } ~~~~ +- `LOCALS`: declarations for input and output arguments +- `CODE` contains input marshalling, the action, and output marshalling + ### Constructors ~~~~ @@ -83,16 +82,14 @@ v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { v8::HandleScope scope; v8::Handle self = args.Holder(); ${LOCALS} - ${MARSHAL_INPUT} - ${ACTION} + ${CODE} self->SetInternalField(0, v8::External::New(ptr)); return self; } ~~~~ -- `LOCALS`: declaration and marshalling for input arguments -- `MARSHAL_INPUT`: code is generated by applying input typemaps -- `ACTION`: the C/C++ ctor to be executed +- `LOCALS`: declarations for input arguments +- `CODE` contains input marshalling, and the action ### Destructors @@ -105,28 +102,26 @@ v8::Handle ${NAME_MANGLED}_get(v8::Local property, const v8::HandleScope scope; v8::Handle ret; ${LOCALS} - ${ACTION} - ${MARSHAL_OUTPUT} + ${CODE} return scope.Close(ret); } ~~~~ - `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` -- `LOCALS`: declare C return variable -- `MARSHAL_OUTPUT`: code is generated by applying output typemaps +- `LOCALS`: declarations for output arguments +- `CODE` contains the action, and output marshalling ### Setters ~~~~ void ${NAME_MANGLED}_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { ${LOCALS} - ${MARSHAL_INPUT} - ${ACTION} + ${CODE} } ~~~~ - `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` - `LOCALS`: declarations for input arguments -- `MARSHAL_INPUT`: code is generated by applying input typemaps +- `CODE` contains input marshalling, and the action ### Functions @@ -135,14 +130,15 @@ v8::Handle ${NAME_MANGLED}(const Arguments &args) { v8::HandleScope scope; v8::Handle ret; ${LOCALS} - ${MARSHAL_INPUT} - ${ACTION} - ${MARSHAL_OUTPUT} + ${CODE} return scope.Close(ret); } ~~~~ -- if the function does not have a return value, return v8::Undefined +- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` +- `LOCALS`: declarations for input arguments +- `CODE` contains input marshalling, the action, and output marshalling + ### Overloading @@ -169,7 +165,9 @@ void ${MODULE}_Initialize(v8::Handle context) ${PART_INHERITANCE} - ${PART_REGISTER} + ${PART_REGISTER_CLASSES} + + ${PART_REGISTER_NS} } ~~~~ @@ -217,7 +215,7 @@ ${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER}, #### Global Function ~~~~ -${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), v8::FunctionTemplate::New(wrap_${NAME_QUALIFIED})->GetFunction()); +SWIGV8_AddGlobalFunction(${CONTEXT}, "${NAME_UNQUALIFIED}", wrap_${NAME_QUALIFIED}); ~~~~ - `CONTEXT`: either global, or the according namespace template From 32a32633ba1ad9fe12e07f90b1eeaee2665b2631 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:51:47 +0000 Subject: [PATCH 025/352] Add support for static member variables and functions to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13759 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 11 ++++- Source/Modules/javascript_v8.cxx | 64 ++++++++++++++++++++++------ Source/Modules/javascript_v8.h | 2 + 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index c8dc0a109..e5a1f1eba 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -16,6 +16,12 @@ void ${MODULE}_Initialize(v8::Handle context) /* setup inheritances */ ${PART_INHERITANCE} + /* class instances */ + ${PART_CLASS_INSTANCES} + + /* add static class functions and variables */ + ${PART_STATIC_WRAPPERS} + /* register classes */ ${PART_REGISTER_CLASSES} @@ -29,11 +35,14 @@ v8::Persistent SWIGV8_${NAME_MANGLED};%} %fragment("v8_define_class_template", "templates") %{ SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new);%} +%fragment("v8_create_class_instance", "templates") %{ +v8::Handle class_${NAME_MANGLED} = SWIGV8_${NAME_MANGLED}->GetFunction();%} + %fragment("v8_inherit", "templates") %{ SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS});%} %fragment("v8_register_class", "templates") %{ -${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction()));%} +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), class_${NAME_MANGLED});%} %fragment("v8_ctor_wrapper", "templates") %{ v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx index 7d6e9a327..cacceb214 100644 --- a/Source/Modules/javascript_v8.cxx +++ b/Source/Modules/javascript_v8.cxx @@ -9,6 +9,7 @@ #define V8_INITIALIZER "v8_initializer" #define V8_DECL_CLASSTEMPLATE "v8_declare_class_template" #define V8_DEFINE_CLASSTEMPLATE "v8_define_class_template" +#define V8_CREATE_CLASS_INSTANCE "v8_create_class_instance" #define V8_INHERIT "v8_inherit" #define V8_REGISTER_CLASS "v8_register_class" #define V8_CTOR_WRAPPER "v8_ctor_wrapper" @@ -42,6 +43,8 @@ #define KW_CLASS_TEMPLATES "${PART_CLASS_TEMPLATES}" #define KW_WRAPPERS "${PART_WRAPPERS}" #define KW_INHERITANCE "${PART_INHERITANCE}" +#define KW_CLASS_INSTANCES "${PART_CLASS_INSTANCES}" +#define KW_STATIC_WRAPPERS "${PART_STATIC_WRAPPERS}" #define KW_REGISTER_CLASSES "${PART_REGISTER_CLASSES}" #define KW_REGISTER_NS "${PART_REGISTER_NS}" @@ -86,6 +89,8 @@ int V8Emitter::Initialize(Node *n) 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(""); @@ -116,6 +121,8 @@ int V8Emitter::Dump(Node *n) .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); @@ -125,6 +132,7 @@ int V8Emitter::Dump(Node *n) int V8Emitter::Close() { + /* strings */ Delete(f_runtime); Delete(f_header); Delete(f_class_templates); @@ -133,8 +141,12 @@ int V8Emitter::Close() 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); @@ -210,9 +222,13 @@ int V8Emitter::EnterClass(Node *n) // emit definition of v8 class template Template t_def_class(GetTemplate(V8_DEFINE_CLASSTEMPLATE)); - t_def_class.Replace(KW_MANGLED_NAME, current_classname_mangled) + 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; } @@ -262,14 +278,25 @@ int V8Emitter::EnterVariable(Node* n) int V8Emitter::ExitVariable(Node* n) { - if(GetFlag(n, "ismember")) { - 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); + 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) @@ -305,11 +332,22 @@ int V8Emitter::ExitFunction(Node* n) { // register the function at the specific context if(GetFlag(n, "ismember")) { - 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); + 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); + } } else { Template t_register(GetTemplate(V8_REGISTER_GLOBAL_FUNCTION)); t_register.Replace(KW_CONTEXT, current_context) diff --git a/Source/Modules/javascript_v8.h b/Source/Modules/javascript_v8.h index 7ff11f136..8d9e6d0b0 100644 --- a/Source/Modules/javascript_v8.h +++ b/Source/Modules/javascript_v8.h @@ -62,6 +62,8 @@ private: 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; From 67a3de9a93433585a8daca77d3e300713bf91762 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:52:02 +0000 Subject: [PATCH 026/352] Add example for inheritance to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13760 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index 7037c665d..3b6af8108 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -636,6 +636,51 @@ int Class_Initialize(v8::Handle context) { ~~~~~ +## Inheritance + +~~~~~ +class A { +public: + A() {} + + ~A() {} + + double foo() { + return 11.11; + } +}; + +class B: public A { +public: + B() {} + ~B() {} + + int bar() { + return 7; + } +}; + +... (left out function wrappers) ... + +int Class_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Persistent class_A = SWIGV8_CreateClassTemplate("A", A_new); + v8::Persistent class_B = SWIGV8_CreateClassTemplate("B", B_new); + + SWIGV8_AddMemberFunction(class_A, "foo", wrap_A_foo); + SWIGV8_AddMemberFunction(class_B, "bar", wrap_B_bar); + + class_B->Inherit(class_A); + + global->Set(v8::String::NewSymbol("A"), class_A->GetFunction()); + global->Set(v8::String::NewSymbol("B"), class_B->GetFunction()); + + return 0; +} +~~~~~ + ------------------------- Control flow analysis From 8168750c1b43d42a24efa598a1da14c9f56a95f4 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:52:16 +0000 Subject: [PATCH 027/352] Add example for string marshalling to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13761 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .../V8_CodeGeneratorSpecification.md | 68 +++++++++++++++++-- 1 file changed, 64 insertions(+), 4 deletions(-) diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md index 3b6af8108..63027b74d 100644 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -84,7 +84,7 @@ v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { ${LOCALS} ${CODE} self->SetInternalField(0, v8::External::New(ptr)); - return self; + return self; } ~~~~ @@ -296,7 +296,7 @@ void SWIGV8_AddMemberFunction(v8::Handle class_templ, v8::InvocationCallback func) { v8::Handle proto_templ = class_templ->PrototypeTemplate(); - proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)); + proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)); } /** @@ -330,7 +330,7 @@ void SWIGV8_AddGlobalFunction(v8::Handle context, const char* symbol, v8::InvocationCallback func) { - context->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)->GetFunction()); + context->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)->GetFunction()); } template @@ -582,7 +582,7 @@ v8::Handle A_new(const v8::Arguments& args) { A *result; result = new A(); self->SetInternalField(0, v8::External::New(result)); - return self; + return self; } void A_x_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { @@ -681,6 +681,66 @@ int Class_Initialize(v8::Handle context) { } ~~~~~ +## String arguments + +At a first stage all strings are treated as Utf8. +For proper handling strings as return values I have to study +other modules. + +~~~~~ +int my_strlen(const char* s) { + return strlen(s); +} + +// creates a new string +const char* foo(int a) { + char* result = new char[a+1]; + result[a] = 0; + memset(result, 'a', a); + return result; +} + +v8::Handle wrap_my_strlen(const v8::Arguments& args) +{ + v8::HandleScope scope; + v8::Handle jsresult; + const char* arg1; + int result; + + v8::String::Utf8Value utf8(args[0]); + + result = my_strlen(*utf8); + + jsresult = v8::Number::New(result); + return scope.Close(jsresult); +} + +v8::Handle wrap_foo(const v8::Arguments& args) +{ + v8::HandleScope scope; + v8::Handle jsresult; + int arg1; + const char* result; + + arg1 = args[0]->Int32Value(); + result = foo(arg1); + + jsresult = v8::String::New(result); + + return scope.Close(jsresult); +} + +int Strings_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + SWIGV8_AddGlobalFunction(global, "strlen", wrap_my_strlen); + SWIGV8_AddGlobalFunction(global, "foo", wrap_foo); + + return 0; +} +~~~~~ + ------------------------- Control flow analysis From 229f2d0fa5ffb71c36201a7c70f86e778d256128 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:52:28 +0000 Subject: [PATCH 028/352] Add v8 input typemap for cstrings. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13762 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptprimitives.swg | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Lib/javascript/v8/javascriptprimitives.swg b/Lib/javascript/v8/javascriptprimitives.swg index b9b255f86..b8eb1e569 100644 --- a/Lib/javascript/v8/javascriptprimitives.swg +++ b/Lib/javascript/v8/javascriptprimitives.swg @@ -60,8 +60,10 @@ %typemap(out) float, double %{ $result = v8::Number::New($1); %} -%typemap(out) const bool &, bool &, - const char &, char &, +%typemap(out) const bool &, bool & +%{ $result = v8::Boolean::New((*$1);%} + +%typemap(out) const char &, char &, const signed char &, signed char &, const unsigned char &, unsigned char &, const short &, short &, @@ -109,14 +111,14 @@ // TODO: typemap(out) short* et al. %} - %typemap(out) void %{ $result = v8::Undefined(); %} %typemap(in) char * %{ - // TODO: input typemap for char* + v8::String::Utf8Value _$1($input); + $1 = *_$1; %} %typemap(out) char * @@ -148,7 +150,6 @@ // TODO: freearg char* et al %} - /* Typemaps for composite types */ %typemap(in) SWIGTYPE ($&1_type argp) // Objects passed by value, convert to a pointer %{ From 360ef44e09e9072702215c46306731ccbbbc1d03 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:52:41 +0000 Subject: [PATCH 029/352] Clean up in v8 helper functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13763 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascripthelpers.swg | 32 +++---------------------- 1 file changed, 3 insertions(+), 29 deletions(-) diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index bc2822c8f..b5b462b96 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -1,19 +1,5 @@ - %insert(runtime) %{ -/** - * Creates a class template for a class without extra initialization function. - */ -v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol) { - v8::Local class_templ = v8::FunctionTemplate::New(); - class_templ->SetClassName(v8::String::NewSymbol(symbol)); - - v8::Handle inst_templ = class_templ->InstanceTemplate(); - inst_templ->SetInternalFieldCount(1); - - return v8::Persistent::New(class_templ); -} - /** * Creates a class template for a class with specified initialization function. */ @@ -31,22 +17,10 @@ v8::Handle SWIGV8_CreateNamespace(const char* name, v8::Hand Handle namespace = ObjectTemplate::New(); } -/** - * Sets the pimpl data of a V8 class. - */ -v8::Handle SWIGV8_SetInstance(const v8::Arguments& args, void* data) { - v8::HandleScope scope; - - v8::Handle self = args.Holder(); - self->SetInternalField(0, v8::External::New(data)); - - return self; -} - /** * Registers a class method with given name for a given class template. */ -void SWIGV8_AddClassMethod(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { +void SWIGV8_AddMemberFunction(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { v8::Handle proto_templ = class_templ->PrototypeTemplate(); proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); } @@ -54,14 +28,14 @@ void SWIGV8_AddClassMethod(v8::Handle class_templ, const c /** * Registers a class method with given name for a given class template. */ -void SWIGV8_AddGlobalMethod(v8::Handle obj_templ, const char* symbol, v8::InvocationCallback _func) { +void SWIGV8_AddGlobalFunction(v8::Handle obj_templ, const char* symbol, v8::InvocationCallback _func) { obj_templ->Set(String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); } /** * Registers a class property with given name for a given class template. */ -void SWIGV8_AddClassVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { +void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { v8::Handle proto_templ = class_templ->InstanceTemplate(); proto_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } From 050219d998c0a518b54366c6c543fa926e601e5b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:56:48 +0000 Subject: [PATCH 030/352] Merge branch 'devel' of https://github.com/Neha03/gsoc2012-javascript into devel Conflicts: .project COPYRIGHT Doc/Manual/style.css Examples/Makefile.in Examples/test-suite/common.mk Lib/typemaps/strings.swg Makefile.in Source/DOH/fio.c Source/Makefile.am Source/Modules/emit.cxx Source/Modules/javascript.cxx configure.in git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13764 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .cproject | 72 + .project | 16 + COPYRIGHT | 6 +- Doc/Manual/Javascript.html | 770 ++++++++ Doc/Manual/Javascript.md | 1103 ++++++++++++ Doc/Manual/pandoc_template.html | 56 + Doc/Manual/style.css | 6 +- Examples/Makefile.in | 59 + Examples/javascript/class/Makefile | 24 + Examples/javascript/class/example.cpp | 28 + Examples/javascript/class/example.h | 35 + Examples/javascript/class/example.i | 10 + Examples/javascript/class/runme.js | 51 + Examples/javascript/constant/Makefile | 24 + Examples/javascript/constant/example.h | 8 + Examples/javascript/constant/example.i | 24 + Examples/javascript/constant/runme.js | 14 + Examples/javascript/enum/Makefile | 24 + Examples/javascript/enum/example.cpp | 37 + Examples/javascript/enum/example.h | 13 + Examples/javascript/enum/example.i | 11 + Examples/javascript/enum/runme.js | 34 + Examples/javascript/exception/Makefile | 24 + Examples/javascript/exception/example.cpp | 1 + Examples/javascript/exception/example.h | 53 + Examples/javascript/exception/example.i | 12 + Examples/javascript/exception/runme.js | 54 + Examples/javascript/functor/Makefile | 24 + Examples/javascript/functor/example.cpp | 0 Examples/javascript/functor/example.i | 25 + Examples/javascript/functor/runme.js | 16 + Examples/javascript/namespace/Makefile | 24 + Examples/javascript/namespace/example.cpp | 36 + Examples/javascript/namespace/example.h | 20 + Examples/javascript/namespace/example.i | 10 + Examples/javascript/namespace/runme.js | 11 + Examples/javascript/operator/Makefile | 24 + Examples/javascript/operator/example.cpp | 0 Examples/javascript/operator/example.h | 36 + Examples/javascript/operator/example.i | 34 + Examples/javascript/operator/runme.js | 25 + Examples/javascript/overload/Makefile | 24 + Examples/javascript/overload/example.cpp | 0 Examples/javascript/overload/example.h | 28 + Examples/javascript/overload/example.i | 20 + Examples/javascript/overload/runme.js | 7 + Examples/javascript/pointer/Makefile | 24 + Examples/javascript/pointer/example.cpp | 16 + Examples/javascript/pointer/example.i | 30 + Examples/javascript/pointer/runme.js | 38 + Examples/javascript/reference/Makefile | 24 + Examples/javascript/reference/example.cpp | 46 + Examples/javascript/reference/example.h | 26 + Examples/javascript/reference/example.i | 42 + Examples/javascript/reference/runme.js | 67 + Examples/javascript/simple/Makefile | 24 + Examples/javascript/simple/example.cpp | 28 + Examples/javascript/simple/example.i | 15 + Examples/javascript/simple/runme.js | 26 + Examples/javascript/template/Makefile | 24 + Examples/javascript/template/example.cpp | 0 Examples/javascript/template/example.h | 32 + Examples/javascript/template/example.i | 17 + Examples/javascript/template/runme.js | 32 + Examples/javascript/variables/Makefile | 24 + Examples/javascript/variables/example.c | 91 + Examples/javascript/variables/example.h | 6 + Examples/javascript/variables/example.i | 49 + Examples/javascript/variables/runme.js | 68 + Examples/test-suite/common.mk | 7 +- Examples/test-suite/javascript/Makefile.in | 94 + Examples/test-suite/javascript/README | 4 + .../javascript/abstract_access_runme.js | 5 + .../javascript/abstract_typedef2_runme.js | 4 + .../javascript/abstract_typedef_runme.js | 6 + .../javascript/abstract_virtual_runme.js | 9 + .../javascript/array_member_runme.js | 20 + .../javascript/arrays_global_runme.js | 16 + .../javascript/char_binary_runme.js | 36 + .../javascript/class_ignore_runme.js | 5 + .../javascript/class_scope_weird_runme.js | 5 + .../javascript/complextest_runme.js | 21 + .../test-suite/javascript/constover_runme.js | 31 + .../test-suite/javascript/cpp_enum_runme.js | 26 + .../javascript/cpp_namespace_runme.js | 45 + .../test-suite/javascript/cpp_static_runme.js | 7 + .../javascript/director_alternating_runme.js | 4 + .../javascript/enum_template_runme.js | 6 + .../namespace_virtual_method_runme.js | 2 + .../javascript/overload_copy_runme.js | 3 + .../javascript/preproc_include_runme.js | 22 + .../test-suite/javascript/preproc_runme.js | 13 + .../javascript/ret_by_value_runme.js | 7 + .../javascript/struct_value_runme.js | 10 + .../javascript/template_static_runme.js | 2 + .../javascript/typedef_class_runme.js | 5 + .../javascript/typedef_inherit_runme.js | 22 + .../javascript/typedef_scope_runme.js | 11 + .../javascript/typemap_arrays_runme.js | 4 + .../javascript/typemap_delete_runme.js | 4 + .../javascript/typemap_namespace_runme.js | 6 + .../javascript/typemap_ns_using_runme.js | 3 + .../test-suite/javascript/using1_runme.js | 4 + .../test-suite/javascript/using2_runme.js | 3 + Lib/javascript/jsc/ccomplex.i | 26 + Lib/javascript/jsc/complex.i | 6 + Lib/javascript/jsc/javascript.swg | 19 + Lib/javascript/jsc/javascriptcode.swg | 292 +++ Lib/javascript/jsc/javascriptcomplex.swg | 146 ++ Lib/javascript/jsc/javascriptfragments.swg | 0 Lib/javascript/jsc/javascripthelpers.swg | 69 + Lib/javascript/jsc/javascriptinit.swg | 15 + Lib/javascript/jsc/javascriptkw.swg | 40 + Lib/javascript/jsc/javascriptprimitives.swg | 104 ++ Lib/javascript/jsc/javascriptruntime.swg | 175 ++ Lib/javascript/jsc/javascriptstrings.swg | 171 ++ Lib/javascript/jsc/javascripttypemaps.swg | 26 + Lib/javascript/jsc/javascriptvaltypes.swg | 1 + Lib/javascript/jsc/std_common.i | 5 + Lib/javascript/jsc/std_complex.i | 19 + Lib/javascript/jsc/std_except.i | 1 + Lib/javascript/jsc/std_map.i | 74 + Lib/javascript/jsc/std_pair.i | 34 + Lib/javascript/jsc/std_string.i | 71 + Lib/javascript/jsc/std_vector.i | 85 + Lib/javascript/jsc/stl.i | 10 + Lib/typemaps/strings.swg | 4 +- Makefile.in | 17 +- Source/DOH/fio.c | 2 + Source/Makefile.am | 1 - Source/Modules/emit.cxx | 6 +- Source/Modules/javascript.cxx | 1591 +++++++++++++++-- Tools/javascript/javascript.cxx | 217 +++ Tools/swigprinters.gdb | 24 + Tools/swigprinters.py | 574 ++++++ configure.in | 149 ++ 136 files changed, 7987 insertions(+), 141 deletions(-) create mode 100644 .cproject create mode 100644 Doc/Manual/Javascript.html create mode 100644 Doc/Manual/Javascript.md create mode 100644 Doc/Manual/pandoc_template.html create mode 100755 Examples/javascript/class/Makefile create mode 100755 Examples/javascript/class/example.cpp create mode 100755 Examples/javascript/class/example.h create mode 100755 Examples/javascript/class/example.i create mode 100755 Examples/javascript/class/runme.js create mode 100755 Examples/javascript/constant/Makefile create mode 100644 Examples/javascript/constant/example.h create mode 100755 Examples/javascript/constant/example.i create mode 100755 Examples/javascript/constant/runme.js create mode 100755 Examples/javascript/enum/Makefile create mode 100755 Examples/javascript/enum/example.cpp create mode 100755 Examples/javascript/enum/example.h create mode 100755 Examples/javascript/enum/example.i create mode 100755 Examples/javascript/enum/runme.js create mode 100755 Examples/javascript/exception/Makefile create mode 100644 Examples/javascript/exception/example.cpp create mode 100644 Examples/javascript/exception/example.h create mode 100644 Examples/javascript/exception/example.i create mode 100644 Examples/javascript/exception/runme.js create mode 100755 Examples/javascript/functor/Makefile create mode 100644 Examples/javascript/functor/example.cpp create mode 100644 Examples/javascript/functor/example.i create mode 100644 Examples/javascript/functor/runme.js create mode 100755 Examples/javascript/namespace/Makefile create mode 100644 Examples/javascript/namespace/example.cpp create mode 100644 Examples/javascript/namespace/example.h create mode 100644 Examples/javascript/namespace/example.i create mode 100644 Examples/javascript/namespace/runme.js create mode 100755 Examples/javascript/operator/Makefile create mode 100644 Examples/javascript/operator/example.cpp create mode 100644 Examples/javascript/operator/example.h create mode 100644 Examples/javascript/operator/example.i create mode 100644 Examples/javascript/operator/runme.js create mode 100755 Examples/javascript/overload/Makefile create mode 100644 Examples/javascript/overload/example.cpp create mode 100644 Examples/javascript/overload/example.h create mode 100644 Examples/javascript/overload/example.i create mode 100644 Examples/javascript/overload/runme.js create mode 100755 Examples/javascript/pointer/Makefile create mode 100755 Examples/javascript/pointer/example.cpp create mode 100755 Examples/javascript/pointer/example.i create mode 100755 Examples/javascript/pointer/runme.js create mode 100755 Examples/javascript/reference/Makefile create mode 100755 Examples/javascript/reference/example.cpp create mode 100755 Examples/javascript/reference/example.h create mode 100755 Examples/javascript/reference/example.i create mode 100755 Examples/javascript/reference/runme.js create mode 100755 Examples/javascript/simple/Makefile create mode 100755 Examples/javascript/simple/example.cpp create mode 100755 Examples/javascript/simple/example.i create mode 100755 Examples/javascript/simple/runme.js create mode 100755 Examples/javascript/template/Makefile create mode 100644 Examples/javascript/template/example.cpp create mode 100644 Examples/javascript/template/example.h create mode 100644 Examples/javascript/template/example.i create mode 100644 Examples/javascript/template/runme.js create mode 100755 Examples/javascript/variables/Makefile create mode 100755 Examples/javascript/variables/example.c create mode 100755 Examples/javascript/variables/example.h create mode 100755 Examples/javascript/variables/example.i create mode 100755 Examples/javascript/variables/runme.js create mode 100755 Examples/test-suite/javascript/Makefile.in create mode 100755 Examples/test-suite/javascript/README create mode 100644 Examples/test-suite/javascript/abstract_access_runme.js create mode 100644 Examples/test-suite/javascript/abstract_typedef2_runme.js create mode 100644 Examples/test-suite/javascript/abstract_typedef_runme.js create mode 100644 Examples/test-suite/javascript/abstract_virtual_runme.js create mode 100644 Examples/test-suite/javascript/array_member_runme.js create mode 100644 Examples/test-suite/javascript/arrays_global_runme.js create mode 100644 Examples/test-suite/javascript/char_binary_runme.js create mode 100644 Examples/test-suite/javascript/class_ignore_runme.js create mode 100644 Examples/test-suite/javascript/class_scope_weird_runme.js create mode 100644 Examples/test-suite/javascript/complextest_runme.js create mode 100644 Examples/test-suite/javascript/constover_runme.js create mode 100644 Examples/test-suite/javascript/cpp_enum_runme.js create mode 100644 Examples/test-suite/javascript/cpp_namespace_runme.js create mode 100644 Examples/test-suite/javascript/cpp_static_runme.js create mode 100644 Examples/test-suite/javascript/director_alternating_runme.js create mode 100644 Examples/test-suite/javascript/enum_template_runme.js create mode 100644 Examples/test-suite/javascript/namespace_virtual_method_runme.js create mode 100644 Examples/test-suite/javascript/overload_copy_runme.js create mode 100644 Examples/test-suite/javascript/preproc_include_runme.js create mode 100644 Examples/test-suite/javascript/preproc_runme.js create mode 100644 Examples/test-suite/javascript/ret_by_value_runme.js create mode 100644 Examples/test-suite/javascript/struct_value_runme.js create mode 100644 Examples/test-suite/javascript/template_static_runme.js create mode 100644 Examples/test-suite/javascript/typedef_class_runme.js create mode 100644 Examples/test-suite/javascript/typedef_inherit_runme.js create mode 100644 Examples/test-suite/javascript/typedef_scope_runme.js create mode 100644 Examples/test-suite/javascript/typemap_arrays_runme.js create mode 100644 Examples/test-suite/javascript/typemap_delete_runme.js create mode 100644 Examples/test-suite/javascript/typemap_namespace_runme.js create mode 100644 Examples/test-suite/javascript/typemap_ns_using_runme.js create mode 100644 Examples/test-suite/javascript/using1_runme.js create mode 100644 Examples/test-suite/javascript/using2_runme.js create mode 100644 Lib/javascript/jsc/ccomplex.i create mode 100644 Lib/javascript/jsc/complex.i create mode 100644 Lib/javascript/jsc/javascript.swg create mode 100644 Lib/javascript/jsc/javascriptcode.swg create mode 100644 Lib/javascript/jsc/javascriptcomplex.swg create mode 100644 Lib/javascript/jsc/javascriptfragments.swg create mode 100644 Lib/javascript/jsc/javascripthelpers.swg create mode 100644 Lib/javascript/jsc/javascriptinit.swg create mode 100644 Lib/javascript/jsc/javascriptkw.swg create mode 100644 Lib/javascript/jsc/javascriptprimitives.swg create mode 100644 Lib/javascript/jsc/javascriptruntime.swg create mode 100644 Lib/javascript/jsc/javascriptstrings.swg create mode 100644 Lib/javascript/jsc/javascripttypemaps.swg create mode 100644 Lib/javascript/jsc/javascriptvaltypes.swg create mode 100755 Lib/javascript/jsc/std_common.i create mode 100644 Lib/javascript/jsc/std_complex.i create mode 100644 Lib/javascript/jsc/std_except.i create mode 100755 Lib/javascript/jsc/std_map.i create mode 100755 Lib/javascript/jsc/std_pair.i create mode 100755 Lib/javascript/jsc/std_string.i create mode 100755 Lib/javascript/jsc/std_vector.i create mode 100755 Lib/javascript/jsc/stl.i create mode 100644 Tools/javascript/javascript.cxx create mode 100644 Tools/swigprinters.gdb create mode 100755 Tools/swigprinters.py diff --git a/.cproject b/.cproject new file mode 100644 index 000000000..e3bfe5f2f --- /dev/null +++ b/.cproject @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + make + + cpp_static.cpptest + true + true + true + + + + diff --git a/.project b/.project index 86af75213..2139d8f0c 100644 --- a/.project +++ b/.project @@ -5,7 +5,23 @@ + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature diff --git a/COPYRIGHT b/COPYRIGHT index 173d1807d..18d821f5e 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -15,8 +15,9 @@ Active SWIG Developers: Olly Betts (olly@survex.com) (PHP) Joseph Wang (joequant@gmail.com) (R) Xavier Delacour (xavier.delacour@gmail.com) (Octave) - David Nadlinger (code@klickverbot.at) (D) - Oliver Buchtala (Javascript) + David Nadlinger (code@klickverbot.at) + Oliver Buchtala (oliver.buchtala@gmail.com) (Javascript) + Neha Narang (narangneha03@gmail.com) (Javascript) Past SWIG developers and major contributors include: Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl) @@ -61,7 +62,6 @@ Past SWIG developers and major contributors include: Ian Lance Taylor (Go) Vadim Zeitlin (PCRE) Stefan Zager (szager@gmail.com) (Python) - Oliver Buchtala (Javascript) Past contributors include: James Michael DuPont, Clark McGrew, Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html new file mode 100644 index 000000000..a53e2a7cd --- /dev/null +++ b/Doc/Manual/Javascript.html @@ -0,0 +1,770 @@ + + + + + + + SWIG AND JAVASCRIPT + + + + + +
+

Overview

+

This chapter describes SWIG support for Javascript. The module is designed to support JavascriptCore and V8 as target engine. Currently only JavascriptCore support is implemented. JavaScriptCore is the built-in JavaScript engine for WebKit, whereas V8 is the engine used by Chromium.

+

JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. C++, on the other hand, is statically typed, compiled, general purpose programming language. The approach I followed here is "Test driven" where I have written the examples/test-cases to be supported for Javascript one-by-one and implemented the required module files in parallel. The support for Javascript would be added similar to other supported target languages in swig. Swig comes with an "Examples" directory for Javascript like other supported language. The directory contains examples for every supported feature of the target language. There is also a test-suite directory for javascript which contains additional tests.

+

Preliminaries

+

In order to use this module, you will need to have installed javascriptcore and you can install it by installing package libwebkit-dev You can find out some necessary compiler/linker flag by

+
pkg-config javascriptcoregtk-1.0 --cflags --libs
+
+

Using the module

+

To generate an extension for JavascriptCore one would call swig as follows

+

swig -c++ -javascript -jsc example.i +
+

This generates a C++ source file containing the wrapper.

+

How does Javascript talk to C++?

+

JavascriptCore provides a C-API which allows to extend a Javascript interpreter with native methods and structures. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is also possible to add your own commands and variables. A reference manual of this API can be found here.

+

Typically, when you add a new command to the javascript interpreter you need to do two things: first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process.

+

Wrapper functions

+

Suppose you have an ordinary C function like this :

+

int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); +} +
+

In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things :

+
    +
  • Gather function arguments and make sure they are valid.
  • +
  • Call the C function.
  • +
  • Convert the return value into a form recognized by the javascript.
  • +
+

As an example, the javascript wrapper function for the fact() function above example might look like the following :

+

JSValueRef wrap_fact(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + int arg1 = (int)JSValueToNumber(context, argv[0], NULL); + int arg2 = (int)JSValueToNumber(context, argv[1], NULL); + int result = (int)fact(arg1,arg2); + JSValueRef jsresult = JSValueMakeNumber(context, result); + return jsresult; +} +
+

Once you have created a wrapper function, the final step is to tell the javascript about the new function. This is done by register function called by the javascript when the module is loaded. For example, adding the above function to the javascript interpreter requires code like the following :

+

bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_globalvarsclassname = JSStringCreateWithUTF8CString(globalvarsclassname); + JSObjectSetProperty(context,js_globalvarsclassname,JSObjectMakeFunctionWithCallback(context, + js_globalvarsclassname, callback), kJSPropertyAttributeNone,NULL); + JSStringRelease(jsstring); + return true; +} + +int example_init(JSContextRef context) { + JSObjectRef global; + ... + jsc_registerFunction(context, global, "fact", wrap_fact); + ... +} +
+

When executed, javascript will now have a new command called "fact" that you can use like any other Javascript command. Although the process of adding a new function to javascript has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code.

+

Variable Linking

+

Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable:

+

double Foo = 3.5; +
+

To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called.

+

bool Foo_set(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef value, + JSValueRef* exception) +{ + JSValueRef jsresult; + double arg1 = (double)JSValueToNumber(context, value, NULL); + Foo = arg1; + jscresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef Foo_get(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + double result = (double)Foo; + jsresult = JSValueMakeNumber(context, result); + return jsresult; +} +
+

In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as Foo might implicitly call the get function. Similarly, typing Foo = 4 would call the underlying set function to change the value.

+

A tour of basic C/C++ wrapping

+

By default, SWIG tries to build a very natural javascript interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping.

+

Modules

+

The SWIG %module directive specifies the name of the Javascript module. If you specify %module example, then everything is wrapped into a Javascript 'example' module. Underneath the covers, this module consists of a cpp source file example.cpp. When choosing a module name, make sure you don't use the same name as a built-in Javascript command or standard module name.

+

Global variables

+

C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that javascript works.

+

// SWIG interface file with global variables +%module example +... +%inline %{ +extern double Foo; +extern int gcd(int x, int y); +%} +... +
+

Now look at the javascript:

+

print("Global variable Foo=" + example.Foo); +example.Foo = 3.1415926; +print("Variable Foo changed to=" + example.Foo); +print("GCD of x and y is=" + example.gcd(x,y)); +
+

Constants and enums

+

C/C++ constants are installed as javascript objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example:

+

#define ICONST 42 +#define FCONST 2.1828 +%constant int iconst = 37; +
+

In javascript they are treated as:

+

print("ICONST = " + example.ICONST + " (should be 42)\n"); +print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +print("iconst = " + example.iconst + " (should be 37)\n"); +
+

For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile. Enums are treated as constants.So if we have enums in c++ as:

+

void enum_test(color c, Foo::speed s); +
+

In javascript they are treated as:

+

example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); +
+

Inside the class

+

For class enums as below:

+

class Foo { +public: +Foo() { } +enum speed { IMPULSE, WARP, LUDICROUS }; +} +
+

In javascript they are treated as:

+

print(" Foo_IMPULSE =" + example.Foo.IMPULSE); +print(" Foo_WARP =" + example.Foo.WARP); +print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); +
+

Pointers

+

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface

+

/* File : example.i */ +%module example +%{ +extern void add(int *, int *, int *); +%} +
+

When wrapped, you will be able to use the functions in a natural way from javascript. For example:

+

// Call the add() function with some pointers +example.add(a, b, c); +
+

// In javascript the code look like as:

+

a = example.new_intp(); +example.intp_assign(a,37); +
+
    +
  • The first one creates an int-pointer instance.
  • +
  • The second one assigns it the value 37.
  • +
+

C++ classes

+

C++ classes are wrapped by javascript classes as well. For example, if you have this class,

+

class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; +}; +
+

you can use it in javascript like this:

+

print("Creating some objects:"); +c = new example.Circle(10); +print("area = " + c.area()); +
+

Class data members are accessed in the same manner as C structures.

+

Static class members and functions are mapped to javascript in a straight-forward manner:

+

class Spam { +public: + static void foo(); + static int bar; +}; +
+

In javascript, the static member can be access in this way:

+

// ----- Access a static member ----- +print("\nA access of static member is" + example.Spam.Foo); // access static member as properties of the class object. +
+

C++ inheritance

+

SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this

+

class A { +public: + void foo(); + virtual void bar(); +}; +class B: public A { +public: + virtual void bar(); +}; +
+

Those classes are wrapped into a hierarchy of javascript classes that reflect the same inheritance structure. All of the usual javascript utility functions work normally:

+

var a = new example.A(); +a.foo(); +a.bar(); +var b = new example.B(); +b.foo(); +b.bar(); +print("b.cPtr = " + b.getCPtr()); +
+

C++ overloaded functions

+

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:

+

void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} +
+

You can use them in javascript in a straightforward manner:

+

example.f(1); +example.f(1, 2); +example.f("bla"); +
+

C++ operators

+

Certain C++ overloaded operators can be handled automatically by SWIG. Though, in javascript operator overloading is not possible. Instead one has to make use of the %rename feature.

+

For example, consider a class like this:

+

/* File : example.h */ +#include <math.h> +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; +
+

When wrapped, it works like you expect:

+

a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +print ("a =" + a); +print ("b =" + b); + +c = a.plus(b); + +print("c =" + c); +print("a*b =" + a.times(b)); +print("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +print("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +print("f =" + f); +
+

One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this

+

class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; +
+

then SWIG ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:

+

%rename(Complex_add_dc) operator+(double, const Complex &);

+

There are ways to make this operator appear as part of the class using the %extend directive.

+

C++ namespaces:

+

SWIG is aware of C++ namespaces, but namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this,

+

%module example +namespace nspace { +extern int gcd(int x, int y); +extern double Foo; +class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; + }; +} +
+

for namespaces, you use the %feature directive in interface file. %feature attaches a new attribute to any parse tree node that matches given prototype.

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%feature("nspace", 1); +%include "example.h" +
+

it works in javascript as follows:

+

print("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +print("Variable Foo changed to " + example.nspace.Foo); +print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); +print("Creating some objects:"); +c = new example.nspace.Circle(10); +print("area = " + c.area()); +
+

If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:

+

%rename(Bar_spam) Bar::spam; +namespace Foo { + int spam(); +} +namespace Bar { + int spam(); +} +
+

If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence.

+

C++ templates

+

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ +%template(maxint) max<int>; +%template(maxdouble) max<double>; +%template(vecint) vector<int>; +%template(vecdouble) vector<double>; +
+

In javascript:

+

//Call some templated functions +print(example.maxint(3,7)); +print(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +print(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +print(sum); +
+

Exception handling

+

The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into javascript exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following:

+

Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the javascript extension by writing the following in an interface file:

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" +
+

Actually in JS there is no support for typed exceptions.For now there is support for integer and string exception. Example for integer exception

+

JSValueRef jsc_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +*exception = JSValueMakeNumber(context, 13); +int result = (int)gcd(arg1,arg2); +JSValueRef jsresult = JSValueMakeNumber(context, result); +
+

and for string exception:

+

JSValueRef wrap_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +JSStringRef message = JSStringCreateWithUTF8CString("This is a test error."); +*exception = JSValueMakeString(context, message); +JSStringRelease(message); +int result = (int)gcd(arg1,arg2); +JSValueRef jscresult = JSValueMakeNumber(context, result); +return jsresult; +} +
+

How to use generated modules?

+

Basically there is no standard extension mechanism in Javascript. We provided a custom interpreter with extension abilities. If JSC is embedded into a custom application, one has to make use of a generated module initializer function that allows easy extension of interpreter. The basic approach is as follows:

+

Basic Mechanism

+
    +
  • Creating the context
  • +
  • Calling module initializer
  • +
  • Evaluate Javascript
  • +
+

Creating the context

+

JSGlobalContextRef context = JSGlobalContextCreate(NULL); +JSObjectRef globalObject = JSContextGetGlobalObject(context); +... +
+

Calling module initializer

+

extern int example_init(JSGlobalContextRef context); + ... + example_init(context); + ... +
+

Evaluate Javascript

+

// Evaluate the javascript +char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); +JSStringRef jsScript; +if(!scriptContent) { + printf("FAIL: runme script could not be loaded.\n"); + failed = 1; + } + else { + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(scriptContent); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + if (!jsResult && ex) { + jsc_printError(context, ex, scriptPath); + failed = 1; + } + } + if (scriptContent != NULL) { + free(scriptContent); + } + JSStringRelease(jsScript); + JSGlobalContextRelease(context); + globalObject = 0; + for(std::vector<HANDLE>::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + dlclose(handle); + } + if (failed) { + printf("FAIL: Some tests failed.\n"); + return 1; + } +} +
+

Typemaps

+

A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from javascript to C, you might define a typemap like this:

+

%typemap(in) int { + $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} + printf("Received an integer : %d\n",$1); +} +
+

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int.

+

Javascript typemaps

+

The previous section illustrated an "in" typemap for converting javascript objects to C. A variety of different typemap methods are defined by the javascript module. For example, to convert a C integer back into a javascript object, you might define an "out" typemap like this:

+

%typemap(out) int { + $result = JSValueMakeNumber(context, $1); +} +
+

The Javascript module makes use of Swig's unified template library.

+

Typemap variables

+

Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

+

$1: A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Javascript.

+

$input: A javascript Object * holding a raw javascript object with an argument or variable value.

+

$result: A javascript Object * that holds the result to be returned to javascript.

+

$1_name: The parameter name that was matched.

+

$1_type: The actual C datatype matched by the typemap.

+

$1_ltype: An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.

+

$symname: The javascript name of the wrapper function being created.

+

Javascript: Specification of a Code Generator for JSC

+

The module implementation tries to accomplish a separation of logic and code generation by making use of code templates. In the following, the templates are explained.

+

Top Level structure

+

The generated code consists of the following blocks:

+

<RUNTIME> +<INCLUDES> +<HELPER_FUNCTIONS> +<FUNCTION_WRAPPERS> +<INITIALIZER> +
+
    +
  • RUNTIME: runtime code generated by swig
  • +
  • HELPER_FUNCTIONS: static, from swg-file
  • +
  • INCLUDES: static, module property
  • +
  • FUNCTION_WRAPPERS: dynamically growing, on method declarations
  • +
  • INITIALIZER: dynamically growing, aggregates everything
  • +
+

INCLUDES

+

#include <JavaScriptCore/JavaScript.h> +<USER_DEFINED_INCLUDES> +
+

USER_DEFINED_INCLUDES: a module property

+

HELPER_FUNCTIONS

+

A lot of boiler-plate code can be shifted into static helper functions:

+

bool JS_registerClass(JSGlobalContextRef& context, JSObjectRef& parentObject,const char* className, + JSClassDefinition* definition) { + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject,js_className, classObject,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef& context,JSObjectRef& namespaceObj,JSObjectRef& parentNamespace,const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace,js_name, namespaceObj,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + return true; +} + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context,object,js_functionName,JSObjectMakeFunctionWithCallback(context, + js_functionName, callback), kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return val; +} +
+

FUNCTION_WRAPPERS

+

There are different types of function wrappers: - Member Functions - Getproperty / Setproperty - Global Functions (global/namespace/class) - Constructors / Destructors

+

Member Functions

+

JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • functionname: the name of generated wrapper for function
  • +
  • LOCALS: declarations for input arguments
  • +
  • CODE: contains input marshalling, the action, and output marshalling
  • +
+

Setproperty

+

bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • setname: the name of the generated wrapper for setproperty.
  • +
  • LOCALS: declarations for input arguments
  • +
  • CODE: contains input marshalling, and the action
  • +
+

Getproperty

+

JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • getname: the name of the generated wrapper for the getproperty
  • +
  • LOCALS: declarations for output arguments
  • +
  • CODE: contains the action, and output marshalling
  • +
+

Global Functions

+

JSStaticValue ${namespace}_values[] = { + ${jsglobalvariables} + { 0, 0, 0, 0 } +}; +JSStaticFunction ${namespace}_functions[] = { + ${jsglobalfunctions} + { 0, 0, 0 } +}; +JSClassDefinition ${namespace}_classDefinition; +
+

Variable declaration

+

{"${propertyname}",${getname}, ${setname}, kJSPropertyAttributeNone} +
+

This is used to fill variable definition tables. kJSPropertyAttributeNone is JSC specific and means that the variable has a getter and setter. Even for read-only variables a setter is used which throws an exception.

+

Constructor

+

~~

+

JSObjectRef wrap_createclassnamemangled{overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { ${LOCALS} ${CODE} return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN);

+
goto fail;
+fail:
+return NULL;
+
+

}

+
- `classname_mangled` is the mangled qualified class name,   e.g., `foo::A -> foo_A`
+- `LOCALS`: declarations for input arguments 
+- `CODE`: contains input marshalling, and the action 
+
+## Destructors
+
+

void wrap${classname_mangled}_finalize(JSObjectRef thisObject) { SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) delete (${type}*)(t->swigCObject); if(t) delete t; }

+

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + +## Initializer +
+

bool ${modulename}_initialize(JSGlobalContextRef context) { SWIG_InitializeModule(0);

+
JSObjectRef global_object = JSContextGetGlobalObject(context);
+
+/* Initialize the base swig type object */
+_SwigObject_objectDefinition.staticFunctions = _SwigObject_functions;
+_SwigObject_objectDefinition.staticValues = _SwigObject_values;
+_SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition);
+
+/* Create objects for namespaces */
+${create_namespaces}
+
+/* Create classes */
+${initializercode}
+
+/* Register namespaces */
+${register_namespaces}
+
+return true;
+
+

}

+

## Class template defintions + +A class is specified by a static part (`*_classDefinition`) and a dynamic part (`*_objectDefinition`). +
+

${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}objectDefinition); SWIGTYPE${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%}

+

Notes: +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + which is retrieved by `Swig_name_mangle(Getattr(n, "name"))` +- ClassDefinitions are built using the staticValues array and the staticFunction array. The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties to the class object. + +## Inheritance +
+

{${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef};

+

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` +- Note: multiple inheritance is not possible; thus we will always take the first parent class + +## Namespaces + +Namespaces are objects without class templates. i.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. +
+

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

+

## Registration + +The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. + +* Global functions +
+

JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper}

+

* Classes +
+

JS_registerClass(context, ${namespace}_object, "${classname}", &${classname_mangled}_classDefinition)

+

Note: every class template has an associated constructor function wrapper, which is registered here + +* Namespaces +
+

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

+

Namespaces are registered using: +
+

JS_registerNamespace(context, ${namespace}_object, ${parent_namespace}_object, "${namespace}");

+

~~

+
+ + diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md new file mode 100644 index 000000000..a01c630d8 --- /dev/null +++ b/Doc/Manual/Javascript.md @@ -0,0 +1,1103 @@ +% SWIG AND JAVASCRIPT + +# Overview + +This chapter describes SWIG support for Javascript. +The module is designed to support JavascriptCore and V8 as target engine. +Currently only JavascriptCore support is implemented. +JavaScriptCore is the built-in JavaScript engine for WebKit, whereas V8 is the engine used by Chromium. + +JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. C++, on the other hand, is statically typed, compiled, general purpose programming language. +The approach I followed here is "Test driven" where I have written the examples/test-cases to be supported for Javascript one-by-one and implemented the required module files in parallel. +The support for Javascript would be added similar to other supported target languages in swig. Swig comes with an "Examples" directory for Javascript like other supported language. The directory contains examples for every supported feature of the target language. There is also a test-suite directory for javascript which contains additional tests. + +# Preliminaries + +In order to use this module, you will need to have installed javascriptcore and you can install it by installing package libwebkit-dev +You can find out some necessary compiler/linker flag by + + pkg-config javascriptcoregtk-1.0 --cflags --libs + +## Using the module + +To generate an extension for JavascriptCore one would call swig as follows + +~~~~ + +swig -c++ -javascript -jsc example.i + +~~~~ + +This generates a C++ source file containing the wrapper. + +## How does Javascript talk to C++? + +JavascriptCore provides a C-API which allows to extend a Javascript interpreter with native methods and structures. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is also possible to add your own commands and variables. A reference manual of this API can be found +[here](http://developer.apple.com/library/mac/#documentation/Carbon/Reference/WebKit_JavaScriptCore_Ref/_index.html). + +Typically, when you add a new command to the javascript interpreter you need to do two things: first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process. + +## Wrapper functions + +Suppose you have an ordinary C function like this : + +~~~~ + +int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); +} + +~~~~ + +In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things : + + - Gather function arguments and make sure they are valid. + - Call the C function. + - Convert the return value into a form recognized by the javascript. + +As an example, the javascript wrapper function for the fact() function above example might look like the following : + +~~~~ + +JSValueRef wrap_fact(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + int arg1 = (int)JSValueToNumber(context, argv[0], NULL); + int arg2 = (int)JSValueToNumber(context, argv[1], NULL); + int result = (int)fact(arg1,arg2); + JSValueRef jsresult = JSValueMakeNumber(context, result); + return jsresult; +} + +~~~~ + +Once you have created a wrapper function, the final step is to tell the javascript about the new function. This is done by register function called by the javascript when the module is loaded. For example, adding the above function to the javascript interpreter requires code like the following : + +~~~~ + +bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_globalvarsclassname = JSStringCreateWithUTF8CString(globalvarsclassname); + JSObjectSetProperty(context,js_globalvarsclassname,JSObjectMakeFunctionWithCallback(context, + js_globalvarsclassname, callback), kJSPropertyAttributeNone,NULL); + JSStringRelease(jsstring); + return true; +} + +int example_init(JSContextRef context) { + JSObjectRef global; + ... + jsc_registerFunction(context, global, "fact", wrap_fact); + ... +} + +~~~~ + +When executed, javascript will now have a new command called "fact" that you can use like any other Javascript command. +Although the process of adding a new function to javascript has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code. + +## Variable Linking + +Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable: + +~~~~ + +double Foo = 3.5; + +~~~~ + +To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called. + +~~~~ + +bool Foo_set(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef value, + JSValueRef* exception) +{ + JSValueRef jsresult; + double arg1 = (double)JSValueToNumber(context, value, NULL); + Foo = arg1; + jscresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef Foo_get(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + double result = (double)Foo; + jsresult = JSValueMakeNumber(context, result); + return jsresult; +} + +~~~~ + +In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as Foo might implicitly call the get function. Similarly, typing Foo = 4 would call the underlying set function to change the value. + +# A tour of basic C/C++ wrapping + +By default, SWIG tries to build a very natural javascript interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping. + +## Modules + +The SWIG %module directive specifies the name of the Javascript module. If you specify `%module example`, then everything is wrapped into a Javascript 'example' module. Underneath the covers, this module consists of a cpp source file example.cpp. When choosing a module name, make sure you don't use the same name as a built-in Javascript command or standard module name. + +## Global variables + +C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that javascript works. + +~~~~ + +// SWIG interface file with global variables +%module example +... +%inline %{ +extern double Foo; +extern int gcd(int x, int y); +%} +... + +~~~~ + +Now look at the javascript: + +~~~~ + +print("Global variable Foo=" + example.Foo); +example.Foo = 3.1415926; +print("Variable Foo changed to=" + example.Foo); +print("GCD of x and y is=" + example.gcd(x,y)); + +~~~~ + +## Constants and enums + +C/C++ constants are installed as javascript objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example: + +~~~~ + +#define ICONST 42 +#define FCONST 2.1828 +%constant int iconst = 37; + +~~~~ + +In javascript they are treated as: + +~~~~ + +print("ICONST = " + example.ICONST + " (should be 42)\n"); +print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +print("iconst = " + example.iconst + " (should be 37)\n"); + +~~~~ + +For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile. +Enums are treated as constants.So if we have enums in c++ as: + +~~~~ + +void enum_test(color c, Foo::speed s); + +~~~~ + +In javascript they are treated as: + +~~~~ + +example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); + +~~~~ + +### Inside the class +For class enums as below: + +~~~~ + +class Foo { +public: +Foo() { } +enum speed { IMPULSE, WARP, LUDICROUS }; +} + +~~~~ + +In javascript they are treated as: + +~~~~ + +print(" Foo_IMPULSE =" + example.Foo.IMPULSE); +print(" Foo_WARP =" + example.Foo.WARP); +print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); + +~~~~ + +## Pointers + +C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface + +~~~~ + +/* File : example.i */ +%module example +%{ +extern void add(int *, int *, int *); +%} + +~~~~ + +When wrapped, you will be able to use the functions in a natural way from javascript. For example: + +~~~~ + +// Call the add() function with some pointers +example.add(a, b, c); + +~~~~ + +// In javascript the code look like as: + +~~~~ + +a = example.new_intp(); +example.intp_assign(a,37); + +~~~~ + +- The first one creates an int-pointer instance. +- The second one assigns it the value 37. + +### C++ classes + +C++ classes are wrapped by javascript classes as well. For example, if you have this class, + +~~~~ + +class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; +}; + +~~~~ + +you can use it in javascript like this: + +~~~~ + +print("Creating some objects:"); +c = new example.Circle(10); +print("area = " + c.area()); + +~~~~ + +Class data members are accessed in the same manner as C structures. + +Static class members and functions are mapped to javascript in a straight-forward manner: + +~~~~ + +class Spam { +public: + static void foo(); + static int bar; +}; + +~~~~ + +In javascript, the static member can be access in this way: + +~~~~ + +// ----- Access a static member ----- +print("\nA access of static member is" + example.Spam.Foo); // access static member as properties of the class object. + +~~~~ + +## C++ inheritance + +SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this + +~~~~ + +class A { +public: + void foo(); + virtual void bar(); +}; +class B: public A { +public: + virtual void bar(); +}; + +~~~~ + +Those classes are wrapped into a hierarchy of javascript classes that reflect the same inheritance structure. All of the usual javascript utility functions work normally: + +~~~~ + +var a = new example.A(); +a.foo(); +a.bar(); +var b = new example.B(); +b.foo(); +b.bar(); +print("b.cPtr = " + b.getCPtr()); + +~~~~ + +## C++ overloaded functions + +C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this: + +~~~~ + +void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} + +~~~~ + +You can use them in javascript in a straightforward manner: + +~~~~ + +example.f(1); +example.f(1, 2); +example.f("bla"); + +~~~~ + +## C++ operators + +Certain C++ overloaded operators can be handled automatically by SWIG. Though, in javascript operator overloading is not possible. Instead one has to make use of the `%rename` feature. + +For example, consider a class like this: + +~~~~ + +/* File : example.h */ +#include +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + +~~~~ + +When wrapped, it works like you expect: + +~~~~ + +a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +print ("a =" + a); +print ("b =" + b); + +c = a.plus(b); + +print("c =" + c); +print("a*b =" + a.times(b)); +print("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +print("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +print("f =" + f); + +~~~~ + +One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this + +~~~~ + +class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; + +~~~~ + +then SWIG ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example: + +%rename(Complex_add_dc) operator+(double, const Complex &); + +There are ways to make this operator appear as part of the class using the %extend directive. + +## C++ namespaces: + +SWIG is aware of C++ namespaces, but namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this, + +~~~~ + +%module example +namespace nspace { +extern int gcd(int x, int y); +extern double Foo; +class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; + }; +} + +~~~~ + +for namespaces, you use the %feature directive in interface file. %feature attaches a new attribute to any parse tree node that matches given prototype. + +~~~~ + +/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%feature("nspace", 1); +%include "example.h" + +~~~~ + +it works in javascript as follows: + +~~~~ + +print("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +print("Variable Foo changed to " + example.nspace.Foo); +print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); +print("Creating some objects:"); +c = new example.nspace.Circle(10); +print("area = " + c.area()); + +~~~~ + +If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example: + +~~~~ + +%rename(Bar_spam) Bar::spam; +namespace Foo { + int spam(); +} +namespace Bar { + int spam(); +} + +~~~~ + +If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. +SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence. + +## C++ templates + +C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example: + +~~~~ + +/* File : example.i */ +%module example +%{ +#include "example.h" +%} +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + +~~~~ + +In javascript: + +~~~~ + +//Call some templated functions +print(example.maxint(3,7)); +print(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +print(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +print(sum); + +~~~~ + +## Exception handling + +The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into javascript exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following: + +Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the javascript extension by writing the following in an interface file: + +~~~~ + +/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" + +~~~~ + +Actually in JS there is no support for typed exceptions.For now there is support for integer and string +exception. Example for integer exception + +~~~~ + +JSValueRef jsc_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +*exception = JSValueMakeNumber(context, 13); +int result = (int)gcd(arg1,arg2); +JSValueRef jsresult = JSValueMakeNumber(context, result); + +~~~~ + +and for string exception: + +~~~~ + +JSValueRef wrap_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +JSStringRef message = JSStringCreateWithUTF8CString("This is a test error."); +*exception = JSValueMakeString(context, message); +JSStringRelease(message); +int result = (int)gcd(arg1,arg2); +JSValueRef jscresult = JSValueMakeNumber(context, result); +return jsresult; +} + +~~~~ + +## How to use generated modules? + +Basically there is no standard extension mechanism in Javascript. We provided a custom interpreter with extension abilities. If JSC is embedded into a custom application, one has to make use of a generated module initializer function that allows easy extension of interpreter. +The basic approach is as follows: + +### Basic Mechanism +- Creating the context +- Calling module initializer +- Evaluate Javascript + +#### Creating the context + +~~~~ + +JSGlobalContextRef context = JSGlobalContextCreate(NULL); +JSObjectRef globalObject = JSContextGetGlobalObject(context); +... + +~~~~ + +### Calling module initializer + +~~~~ + + extern int example_init(JSGlobalContextRef context); + ... + example_init(context); + ... + +~~~~ + +### Evaluate Javascript + +~~~~ + +// Evaluate the javascript +char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); +JSStringRef jsScript; +if(!scriptContent) { + printf("FAIL: runme script could not be loaded.\n"); + failed = 1; + } + else { + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(scriptContent); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + if (!jsResult && ex) { + jsc_printError(context, ex, scriptPath); + failed = 1; + } + } + if (scriptContent != NULL) { + free(scriptContent); + } + JSStringRelease(jsScript); + JSGlobalContextRelease(context); + globalObject = 0; + for(std::vector::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + dlclose(handle); + } + if (failed) { + printf("FAIL: Some tests failed.\n"); + return 1; + } +} + +~~~~ + +## Typemaps + +A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from javascript to C, you might define a typemap like this: + +~~~~ + +%typemap(in) int { + $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} + printf("Received an integer : %d\n",$1); +} + +~~~~ + +Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int. + +## Javascript typemaps + +The previous section illustrated an "in" typemap for converting javascript objects to C. A variety of different typemap methods are defined by the javascript module. For example, to convert a C integer back into a javascript object, you might define an "out" typemap like this: + +~~~~ + +%typemap(out) int { + $result = JSValueMakeNumber(context, $1); +} + +~~~~ + +The Javascript module makes use of Swig's unified template library. + +## Typemap variables + +Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables: + +`$1`: +A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Javascript. + +`$input`: +A javascript Object * holding a raw javascript object with an argument or variable value. + +`$result`: +A javascript Object * that holds the result to be returned to javascript. + +`$1_name`: +The parameter name that was matched. + +`$1_type`: +The actual C datatype matched by the typemap. + +`$1_ltype`: +An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of `$1_type`. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned. + +`$symname`: +The javascript name of the wrapper function being created. + +# Javascript: Specification of a Code Generator for JSC + +The module implementation tries to accomplish a separation of logic and code generation by making +use of code templates. In the following, the templates are explained. + +# Top Level structure + +The generated code consists of the following blocks: + +~~~~ + + + + + + + +~~~~ + +- `RUNTIME`: runtime code generated by swig +- `HELPER_FUNCTIONS`: static, from swg-file +- `INCLUDES`: static, module property +- `FUNCTION_WRAPPERS`: dynamically growing, on method declarations +- `INITIALIZER`: dynamically growing, aggregates everything + +## INCLUDES + +~~~~ + +#include + + +~~~~ + +`USER_DEFINED_INCLUDES`: a module property + +## `HELPER_FUNCTIONS` + +A lot of boiler-plate code can be shifted into static helper functions: + +~~~~ + +bool JS_registerClass(JSGlobalContextRef& context, JSObjectRef& parentObject,const char* className, + JSClassDefinition* definition) { + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject,js_className, classObject,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef& context,JSObjectRef& namespaceObj,JSObjectRef& parentNamespace,const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace,js_name, namespaceObj,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + return true; +} + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context,object,js_functionName,JSObjectMakeFunctionWithCallback(context, + js_functionName, callback), kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return val; +} + +~~~~ + +## `FUNCTION_WRAPPERS` + +There are different types of function wrappers: +- Member Functions +- Getproperty / Setproperty +- Global Functions (global/namespace/class) +- Constructors / Destructors + + +## Member Functions + +~~~~ + +JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} + +~~~~ + +- `functionname`: the name of generated wrapper for function +- `LOCALS`: declarations for input arguments +- `CODE`: contains input marshalling, the action, and output marshalling + +## Setproperty + +~~~~ + +bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} + +~~~~ + +- `setname`: the name of the generated wrapper for setproperty. +- `LOCALS`: declarations for input arguments +- `CODE`: contains input marshalling, and the action + +## Getproperty + +~~~~ + +JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} + +~~~~ + +- `getname`: the name of the generated wrapper for the getproperty +- `LOCALS`: declarations for output arguments +- `CODE`: contains the action, and output marshalling + + +## Global Functions + +~~~~ + +JSStaticValue ${namespace}_values[] = { + ${jsglobalvariables} + { 0, 0, 0, 0 } +}; +JSStaticFunction ${namespace}_functions[] = { + ${jsglobalfunctions} + { 0, 0, 0 } +}; +JSClassDefinition ${namespace}_classDefinition; + +~~~~ + +## Variable declaration + +~~~~ + +{"${propertyname}",${getname}, ${setname}, kJSPropertyAttributeNone} + +~~~~ + +This is used to fill variable definition tables. +`kJSPropertyAttributeNone` is JSC specific and means that the variable has a getter and setter. +Even for read-only variables a setter is used which throws an exception. + +## Constructor + +~~~~ + +JSObjectRef _wrap_create_${classname_mangled}${overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN); + + goto fail; + fail: + return NULL; +} + +~~~~ +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` +- `LOCALS`: declarations for input arguments +- `CODE`: contains input marshalling, and the action + +## Destructors + +~~~~ + +void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) +{ + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) delete (${type}*)(t->swigCObject); + if(t) delete t; +} + +~~~~ + +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + +## Initializer + +~~~~ + +bool ${modulename}_initialize(JSGlobalContextRef context) { + SWIG_InitializeModule(0); + + JSObjectRef global_object = JSContextGetGlobalObject(context); + + /* Initialize the base swig type object */ + _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; + _SwigObject_objectDefinition.staticValues = _SwigObject_values; + _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + + /* Create objects for namespaces */ + ${create_namespaces} + + /* Create classes */ + ${initializercode} + + /* Register namespaces */ + ${register_namespaces} + + return true; +} + +~~~~ + +## Class template defintions + +A class is specified by a static part (`*_classDefinition`) and a dynamic part (`*_objectDefinition`). + +~~~~ + +${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; + ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; + ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; + ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; + ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; + ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; + JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}_objectDefinition); + SWIGTYPE_${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%} + +~~~~ + +Notes: +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + which is retrieved by `Swig_name_mangle(Getattr(n, "name"))` +- ClassDefinitions are built using the staticValues array and the staticFunction array. The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties to the class object. + +## Inheritance + +~~~~ + +{${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef}; + +~~~~ + +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` +- Note: multiple inheritance is not possible; thus we will always take the first parent class + +## Namespaces + +Namespaces are objects without class templates. i.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. + +~~~~ + + ${namespace}_classDefinition.staticFunctions = ${namespace}_functions; + ${namespace}_classDefinition.staticValues = ${namespace}_values; + JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL); + +~~~~ + +## Registration + +The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. + +* Global functions + +~~~~ + +JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper} + +~~~~ + +* Classes + +~~~~ + +JS_registerClass(context, ${namespace}_object, "${classname}", &${classname_mangled}_classDefinition) + +~~~~ + +Note: every class template has an associated constructor function wrapper, which is registered here + +* Namespaces + +~~~~ + +${namespace}_classDefinition.staticFunctions = ${namespace}_functions; +${namespace}_classDefinition.staticValues = ${namespace}_values; +JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL); + +~~~~ + +Namespaces are registered using: + +~~~~ + +JS_registerNamespace(context, ${namespace}_object, ${parent_namespace}_object, "${namespace}"); + +~~~~ + diff --git a/Doc/Manual/pandoc_template.html b/Doc/Manual/pandoc_template.html new file mode 100644 index 000000000..390bfc51c --- /dev/null +++ b/Doc/Manual/pandoc_template.html @@ -0,0 +1,56 @@ + + + + + + +$for(author-meta)$ + +$endfor$ +$if(date-meta)$ + +$endif$ + $if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$ +$if(highlighting-css)$ + +$endif$ +$for(css)$ + +$endfor$ +$if(math)$ + $math$ +$endif$ +$for(header-includes)$ + $header-includes$ +$endfor$ + + +$for(include-before)$ +$include-before$ +$endfor$ +$if(title)$ +
+

$title$

+$for(author)$ +

$author$

+$endfor$ +$if(date)$ +

$date$

+$endif$ +
+$endif$ +$if(toc)$ +
+$toc$ +
+$endif$ +
+$body$ +
+$for(include-after)$ +$include-after$ +$endfor$ + + diff --git a/Doc/Manual/style.css b/Doc/Manual/style.css index 02329e56f..7eabf91ae 100644 --- a/Doc/Manual/style.css +++ b/Doc/Manual/style.css @@ -25,7 +25,7 @@ div.indent { margin-right: 4em; } -div.code { +div.code, div:not(.code) pre { border-style: solid; border-width: 1px; padding: 2pt; @@ -82,3 +82,7 @@ div.indent p { margin-right: 0; } +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration:none; + color: #000000; +} diff --git a/Examples/Makefile.in b/Examples/Makefile.in index e6c0d2f33..80f807631 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -513,6 +513,65 @@ java_clean: rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@JAVASO@ +################################################################## +##### JAVASCRIPT ###### +################################################################## + +# You need to set this variable to the jscore[or other javascript engine] directories containing the +# files "JavaScript.h" and others +JS_INCLUDE= @JSCOREINC@ + +# Extra JAVASCRIPT specific dynamic linking options +JS_DLNK = @JSCOREDYNAMICLINKING@ +JS_LIBPREFIX = @JSCORELIBRARYPREFIX@ +JSSO =@JSCORESO@ +JSLDSHARED = @JSCORELDSHARED@ +JSCXXSHARED = @JSCORECXXSHARED@ +JSCFLAGS = @JSCORECFLAGS@ +JSCXXFLAGS = @JSCXXFLAGS@ + +# ---------------------------------------------------------------- +# Build a javascript dynamically loadable module (C) +# ---------------------------------------------------------------- + +javascript: $(SRCS) + $(SWIG) -javascript -jsc -debug-templates $(SWIGOPT) $(INTERFACEPATH) + $(CC) -c $(CCSHARED) $(JSCFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JS_INCLUDE) + $(JSLDSHARED) $(CCSHARED) $(JSCFLAGS) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) + +# ---------------------------------------------------------------- +# Build a javascript dynamically loadable module (C++) +# ---------------------------------------------------------------- + +javascript_cpp: $(SRCS) + $(SWIG) -javascript -jsc -c++ -debug-templates $(SWIGOPT) $(INTERFACEPATH) + $(CXX) -c $(CCSHARED) $(JSCXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JS_INCLUDE) + $(JSCXXSHARED) $(CCSHARED) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) + +# ---------------------------------------------------------------- +# Compile a javascript executable +# ---------------------------------------------------------------- +javascript_exe: $(SRCS) + $(CXX) $(CXXFLAGS) $(JS_INCLUDE) $(JSCXXSRCS) $(LIBS) $(JS_DLNK) -o $(JAVASCRIPT_EXE) + +# ---------------------------------------------------------------- +# Run the Compile a javascript executable +# ---------------------------------------------------------------- + +javascript_run: $(SRCS) + env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JAVASCRIPT_EXE) -l $(JAVASCRIPT_MODULE) $(JS_SCRIPT) + +# ----------------------------------------------------------------- +# Cleaning the javascript examples +# ----------------------------------------------------------------- + +javascript_clean: + rm -f *_wrap* runme + rm -f core @EXTRA_CLEAN@ + rm -f *.@OBJEXT@ *@JSCORESO@ + + + ################################################################## ##### MODULA3 ###### ################################################################## diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/class/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/class/example.cpp b/Examples/javascript/class/example.cpp new file mode 100755 index 000000000..e23fa6f73 --- /dev/null +++ b/Examples/javascript/class/example.cpp @@ -0,0 +1,28 @@ +/* File : example.c */ +#include +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/javascript/class/example.h b/Examples/javascript/class/example.h new file mode 100755 index 000000000..9d19e340a --- /dev/null +++ b/Examples/javascript/class/example.h @@ -0,0 +1,35 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static void printMe(void); + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; diff --git a/Examples/javascript/class/example.i b/Examples/javascript/class/example.i new file mode 100755 index 000000000..75700b305 --- /dev/null +++ b/Examples/javascript/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js new file mode 100755 index 000000000..922876fc5 --- /dev/null +++ b/Examples/javascript/class/runme.js @@ -0,0 +1,51 @@ +// file: runme.js + +// ----- Object creation ----- + +print("Creating some objects:"); +c = new example.Circle(10); +print("Created circle " + c); +s = new example.Square(10); +print("Created square " + s); + +// ----- Access a static member ----- +print("\nA total of " + example.Shape.nshapes + " shapes were created"); // access static member as properties of the class object + +// ----- Member data access ----- +// Set the location of the object. +// Note: methods in the base class Shape are used since +// x and y are defined there. + +c.x = 20; +c.y = 30; +s.x = -10; +s.y = 5; + +print("\nHere is their current position:"); +print("Circle = (" + c.x + "," + c.y + ")"); +print("Square = (" + s.x + "," + s.y + ")"); + +print("\nHere is their new position:"); +print("Circle = (" + c.x + "," + c.y + ")"); +print("Square = (" + s.x + "," + s.y + ")"); + + +// ----- Call some methods ----- +print("\nHere are some properties of the shapes:"); +print("Circle:"); +print("area = " + c.area() + ""); +print("perimeter = " + c.perimeter() + ""); +print("\n"); +print("Square:"); +print("area = " + s.area() + ""); +print("perimeter = " + s.perimeter() + ""); + +// ----- Delete everything ----- +print("\nGuess I'll clean up now"); +// Note: this invokes the virtual destructor +delete c; +delete s; + +print (example.Shape.nshapes + " shapes remain"); + +print("Goodbye"); diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile new file mode 100755 index 000000000..4bc75b1a0 --- /dev/null +++ b/Examples/javascript/constant/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/constant/example.h b/Examples/javascript/constant/example.h new file mode 100644 index 000000000..2c88ebd1e --- /dev/null +++ b/Examples/javascript/constant/example.h @@ -0,0 +1,8 @@ +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" +#define EXTERN extern +#define FOO (ICONST + BAR) diff --git a/Examples/javascript/constant/example.i b/Examples/javascript/constant/example.i new file mode 100755 index 000000000..a6d28e7c9 --- /dev/null +++ b/Examples/javascript/constant/example.i @@ -0,0 +1,24 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/javascript/constant/runme.js b/Examples/javascript/constant/runme.js new file mode 100755 index 000000000..cd4783a27 --- /dev/null +++ b/Examples/javascript/constant/runme.js @@ -0,0 +1,14 @@ +// file: runme.js + +print("ICONST = " + example.ICONST + " (should be 42)\n"); +print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +print("CCONST = " + example.CCONST + " (should be 'x')\n"); +print("CCONST2 = " + example.CCONST2 + " (this should be on a new line)\n"); +print("SCONST = " + example.SCONST + " (should be 'Hello World')\n"); +print("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')\n"); +print("EXPR = " + example.EXPR + " (should be 48.5484)\n"); +print("iconst = " + example.iconst + " (should be 37)\n"); +print("fconst = " + example.fconst + " (should be 3.14)\n"); + +print("EXTERN = " + example.EXTERN + " (should be undefined)\n"); +print("FOO = " + example.FOO + " (should be undefined)\n"); diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/enum/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/enum/example.cpp b/Examples/javascript/enum/example.cpp new file mode 100755 index 000000000..6785e57ac --- /dev/null +++ b/Examples/javascript/enum/example.cpp @@ -0,0 +1,37 @@ +/* File : example.c */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/javascript/enum/example.h b/Examples/javascript/enum/example.h new file mode 100755 index 000000000..9119cd9fc --- /dev/null +++ b/Examples/javascript/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/javascript/enum/example.i b/Examples/javascript/enum/example.i new file mode 100755 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/javascript/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js new file mode 100755 index 000000000..3f6283639 --- /dev/null +++ b/Examples/javascript/enum/runme.js @@ -0,0 +1,34 @@ +// file: runme.py + +// ----- Object creation ----- + +// Print out the value of some enums +print("*** color ***"); +print(" RED =" + example.RED); +print(" BLUE =" + example.BLUE); +print(" GREEN =" + example.GREEN); + +print("\n*** Foo::speed ***"); +print(" Foo_IMPULSE =" + example.Foo.IMPULSE); +print(" Foo_WARP =" + example.Foo.WARP); +print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); + +print("\nTesting use of enums with functions\n"); + +example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); +example.enum_test(1234,5678); + +print("\nTesting use of enum with class method"); +f = new example.Foo(); + +f.enum_test(example.Foo.IMPULSE); +f.enum_test(example.Foo.WARP); +f.enum_test(example.Foo.LUDICROUS); + +// enum value BLUE of enum color is accessed as property of cconst +print("example.BLUE= " + example.BLUE); + +// enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst +print("example.speed.LUDICROUS= " + example.Foo.LUDICROUS); diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/exception/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/exception/example.cpp b/Examples/javascript/exception/example.cpp new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Examples/javascript/exception/example.cpp @@ -0,0 +1 @@ + diff --git a/Examples/javascript/exception/example.h b/Examples/javascript/exception/example.h new file mode 100644 index 000000000..7cf917d01 --- /dev/null +++ b/Examples/javascript/exception/example.h @@ -0,0 +1,53 @@ +/* File : example.h */ + +#include +#ifndef SWIG +struct A { +}; +#endif + +class Exc { +public: + Exc(int c, const char *m) { + code = c; + strncpy(msg,m,256); + } + int code; + char msg[256]; +}; + +#if defined(_MSC_VER) + #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +class Test { +public: + int simple() throw(int) { + throw(37); + return 1; + } + int message() throw(const char *) { + throw("I died."); + return 1; + } + int hosed() throw(Exc) { + throw(Exc(42,"Hosed")); + return 1; + } + int unknown() throw(A*) { + static A a; + throw &a; + return 1; + } + int multi(int x) throw(int, const char *, Exc) { + if (x == 1) throw(37); + if (x == 2) throw("Bleah!"); + if (x == 3) throw(Exc(42,"No-go-diggy-die")); + return 1; + } +}; + +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + diff --git a/Examples/javascript/exception/example.i b/Examples/javascript/exception/example.i new file mode 100644 index 000000000..08672c3a8 --- /dev/null +++ b/Examples/javascript/exception/example.i @@ -0,0 +1,12 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js new file mode 100644 index 000000000..dfa561993 --- /dev/null +++ b/Examples/javascript/exception/runme.js @@ -0,0 +1,54 @@ +//file: runme.js +// Throw a lot of exceptions + +t = new example.Test(); +try{ + t.unknown(); + throw -1; +} catch(error) +{ + if(error == -1) { + print("t.unknown() didn't throw"); + } +} + +try{ + t.simple(); + throw -1; +} +catch(error){ + if(error == -1) { + print("t.simple() did not throw"); + } +} + +try{ + t.message(); + throw -1; +} catch(error){ + if(error == -1) { + print("t.message() did not throw"); + } +} + +try{ + t.hosed(); + throw -1; +} +catch(error){ + if(error == -1) { + print("t.hosed() did not throw"); + } +} + +for (var i=1; i<4; i++) { + try{ + t.multi(i); + throw -1; + } + catch(error){ + if(error == -1) { + print("t.mulit(" + i + ") did not throw"); + } + } +} diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/functor/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/functor/example.cpp b/Examples/javascript/functor/example.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/functor/example.i b/Examples/javascript/functor/example.i new file mode 100644 index 000000000..0450c2124 --- /dev/null +++ b/Examples/javascript/functor/example.i @@ -0,0 +1,25 @@ +/* File : example.i */ +%module example + + +%inline %{ +// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 +template class Sum { + T res; +public: + Sum(T i = 0) : res(i) { } + void operator() (T x) { res += x; } + T result() const { return res; } +}; + +%} + +%rename(call) *::operator(); // the fn call operator + +// Instantiate a few versions +%template(intSum) Sum; +%template(doubleSum) Sum; + + + + diff --git a/Examples/javascript/functor/runme.js b/Examples/javascript/functor/runme.js new file mode 100644 index 000000000..48d332c83 --- /dev/null +++ b/Examples/javascript/functor/runme.js @@ -0,0 +1,16 @@ +// Operator overloading example + + +a = new example.intSum(0); +b = new example.doubleSum(100.0); + +// Use the objects. They should be callable just like a normal +// javascript function. + +for (i=1;i<=100;i++) + a.call(i); // Note: function call + b.call(Math.sqrt(i)); // Note: function call + +print(a.result()); +print(b.result()); + diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/namespace/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/namespace/example.cpp b/Examples/javascript/namespace/example.cpp new file mode 100644 index 000000000..5beeb09fe --- /dev/null +++ b/Examples/javascript/namespace/example.cpp @@ -0,0 +1,36 @@ +/* File : example.c */ + +#include +#include "example.h" + +#define M_PI 3.14159 + + +/* A global variable */ +namespace nspace +{ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +Circle::Circle(): radius(1.0) {} + +Circle::Circle(double r): radius(r) { + std::cout << "created Circle with r=" << radius << std::endl; +} + +double Circle::area() { + std::cout << "Circle::area called, r=" << radius << std::endl; + return M_PI*radius*radius; +} +} diff --git a/Examples/javascript/namespace/example.h b/Examples/javascript/namespace/example.h new file mode 100644 index 000000000..7f76c2f07 --- /dev/null +++ b/Examples/javascript/namespace/example.h @@ -0,0 +1,20 @@ + +namespace nspace { + +extern int gcd(int x, int y); +extern double Foo; + +class Circle +{ +public: + Circle(); + + Circle(double r); + + double area(); + + double radius; + +}; + +} diff --git a/Examples/javascript/namespace/example.i b/Examples/javascript/namespace/example.i new file mode 100644 index 000000000..e14b10b44 --- /dev/null +++ b/Examples/javascript/namespace/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%feature("nspace", 1); + +%include "example.h" diff --git a/Examples/javascript/namespace/runme.js b/Examples/javascript/namespace/runme.js new file mode 100644 index 000000000..dc49b078e --- /dev/null +++ b/Examples/javascript/namespace/runme.js @@ -0,0 +1,11 @@ + print("Global variable Foo=" + example.nspace.Foo); + example.nspace.Foo = 5; + print("Variable Foo changed to " + example.nspace.Foo); + print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); + +print("Creating some objects:"); +c = new example.nspace.Circle(10); +print("area = " + c.area()); + + + diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/operator/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/operator/example.cpp b/Examples/javascript/operator/example.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/operator/example.h b/Examples/javascript/operator/example.h new file mode 100644 index 000000000..4da6a2307 --- /dev/null +++ b/Examples/javascript/operator/example.h @@ -0,0 +1,36 @@ +/* File : example.h */ +#include + +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + + + + + diff --git a/Examples/javascript/operator/example.i b/Examples/javascript/operator/example.i new file mode 100644 index 000000000..7a1bd45e1 --- /dev/null +++ b/Examples/javascript/operator/example.i @@ -0,0 +1,34 @@ +/* File : example.i */ +%module example +#pragma SWIG nowarn=SWIGWARN_IGNORE_OPERATOR_EQ +%{ +#include "example.h" +%} + +/* This header file is a little tough to handle because it has overloaded + operators and constructors. We're going to try and deal with that here */ + +/* This turns the copy constructor in a function ComplexCopy() that can + be called */ + +%rename(assign) Complex::operator=; +%rename(plus) Complex::operator+; +%rename(minus) Complex::operator-(const Complex &) const; +%rename(uminus) Complex::operator-() const; +%rename(times) Complex::operator*; + +/* Now grab the original header file */ +%include "example.h" + +/* An output method that turns a complex into a short string */ +%extend Complex { + char *toString() { + static char temp[512]; + sprintf(temp,"(%g,%g)", $self->re(), $self->im()); + return temp; + } + static Complex* copy(const Complex& c) { + return new Complex(c); + } +}; + diff --git a/Examples/javascript/operator/runme.js b/Examples/javascript/operator/runme.js new file mode 100644 index 000000000..92b8e3b74 --- /dev/null +++ b/Examples/javascript/operator/runme.js @@ -0,0 +1,25 @@ +// Operator overloading example + +a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +print ("a =" + a); +print ("b =" + b); + +c = a.plus(b); + +print("c =" + c); +print("a*b =" + a.times(b)); +print("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +print("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +print("f =" + f); + + + + + diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/overload/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/overload/example.cpp b/Examples/javascript/overload/example.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/overload/example.h b/Examples/javascript/overload/example.h new file mode 100644 index 000000000..2f112f1e1 --- /dev/null +++ b/Examples/javascript/overload/example.h @@ -0,0 +1,28 @@ +#include + +void f() { + std::cout << "Called f()." << std::endl; +} + +void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} + +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} + +void f(bool val) { + std::cout << "Called f(bool)." << std::endl; +} + +void f(long val) { + std::cout << "Called f(long)." << std::endl; +} + +void f(double val) { + std::cout << "Called f(double)." << std::endl; +} diff --git a/Examples/javascript/overload/example.i b/Examples/javascript/overload/example.i new file mode 100644 index 000000000..c4f652c0a --- /dev/null +++ b/Examples/javascript/overload/example.i @@ -0,0 +1,20 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* + Note: overloading is implemented in a sloppy way currently + i.e., only the number of arguments is taken into conideration + for dispatching. + To solve the problem one has to rename such conflicting methods. +*/ + +%rename(f_string) f(const char* s); +%rename(f_bool) f(bool val); +%rename(f_long) f(long val); +%rename(f_double) f(double val); + +%include "example.h" diff --git a/Examples/javascript/overload/runme.js b/Examples/javascript/overload/runme.js new file mode 100644 index 000000000..c6d4ef68d --- /dev/null +++ b/Examples/javascript/overload/runme.js @@ -0,0 +1,7 @@ +example.f(); +example.f(1); +example.f(1, 2); +example.f_string("bla"); +example.f_bool(false); +example.f_long(11111111111); +example.f_double(1.0); diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/pointer/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/pointer/example.cpp b/Examples/javascript/pointer/example.cpp new file mode 100755 index 000000000..8762329fe --- /dev/null +++ b/Examples/javascript/pointer/example.cpp @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void subtract(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/javascript/pointer/example.i b/Examples/javascript/pointer/example.i new file mode 100755 index 000000000..38c67d7d2 --- /dev/null +++ b/Examples/javascript/pointer/example.i @@ -0,0 +1,30 @@ +/* File : example.i */ +%module example + +%{ +extern void add(int *, int *, int *); +extern void subtract(int *, int *, int *); +extern int divide(int, int, int *); +%} + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void subtract(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +extern int divide(int n, int d, int *r); + + + + diff --git a/Examples/javascript/pointer/runme.js b/Examples/javascript/pointer/runme.js new file mode 100755 index 000000000..48f92f11f --- /dev/null +++ b/Examples/javascript/pointer/runme.js @@ -0,0 +1,38 @@ +// file: runme.js + +// First create some objects using the pointer library. +print("Testing the pointer library\n"); +a = example.new_intp(); +b = example.new_intp(); +c = example.new_intp(); + +example.intp_assign(a,37); +example.intp_assign(b,42); + +print(" a = " + example.intp_value(a) + "\n"); +print(" b = " + example.intp_value(b) + "\n"); +print(" c = " + example.intp_value(c) + "\n"); + +//// Call the add() function with some pointers +example.add(a, b, c); + +// +//// Now get the result +r = example.intp_value(c); +print(" 37 + 42 = " + r + "\n"); + +// Clean up the pointers +example.delete_intp(a); +example.delete_intp(b); +example.delete_intp(c); + +//// Now try the typemap library +//// This should be much easier. Now how it is no longer +//// necessary to manufacture pointers. +//"OUTPUT" Mapping is not supported + +//print("Trying the typemap library"); +//r = example.subtract(37,42); +//print("37 - 42 =" + r); + + diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/reference/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/reference/example.cpp b/Examples/javascript/reference/example.cpp new file mode 100755 index 000000000..8a513bf49 --- /dev/null +++ b/Examples/javascript/reference/example.cpp @@ -0,0 +1,46 @@ +/* File : example.cxx */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include "example.h" +#include +#include + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/Examples/javascript/reference/example.h b/Examples/javascript/reference/example.h new file mode 100755 index 000000000..4915adb1b --- /dev/null +++ b/Examples/javascript/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/Examples/javascript/reference/example.i b/Examples/javascript/reference/example.i new file mode 100755 index 000000000..1cf19c82c --- /dev/null +++ b/Examples/javascript/reference/example.i @@ -0,0 +1,42 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { + return (*$self)[index]; + } + void set(int index, Vector &a) { + (*$self)[index] = a; + } + } +}; diff --git a/Examples/javascript/reference/runme.js b/Examples/javascript/reference/runme.js new file mode 100755 index 000000000..5cf00061e --- /dev/null +++ b/Examples/javascript/reference/runme.js @@ -0,0 +1,67 @@ +// This file illustrates the manipulation of C++ references in Javascript. +// TODO: deleteion of vector objects created here + +// ----- Object creation ----- + +print("Creating some objects:\n"); +a = new example.Vector(3,4,5); +b = new example.Vector(10,11,12); + +print(" created" + a.print()); +print(" created" + b.print()); + +// ----- Call an overloaded operator ----- + +// This calls the wrapper we placed around operator+(const Vector &a, const Vector &) +// It returns a new allocated object. + +print("Adding a+b\n"); +c = example.addv(a, b); +print("a+b = " + c.print()); + + +// TODO: Note: Unless we free the result, a memory leak will occur +//delete_Vector(c); + +// ----- Create a vector array ----- + +// Note: Using the high-level interface here +print("Creating an array of vectors\n"); +va = new example.VectorArray(10); +print("va = " + va + "\n"); + +// ----- Set some values in the array ----- + +// These operators copy the value of a and b to the vector array +va.set(0,a); +va.set(1,b); + +// This will work, but it will cause a memory leak! +va.set(2,example.addv(a,b)); + +// The non-leaky way to do it +//c = addv(a,b); +//va.set(3,c); +//delete_Vector(c); + +// Get some values from the array + +print("Getting some array values\n"); +for (i = 0; i < 5; i++) { + temp = va.get(i); + print(i,temp.print()); +} + +// Watch under resource meter to check on this +print("Making sure we don't leak memory.\n"); +for (i = 0; i < 1000000; i++) { + c = va.get(i % 10); +} +//---------TODO--------- +//----- Clean up ----- +//print("Cleaning up\n"); + +//example.delete_VectorArray(va); +//example.delete_Vector(a); +//example.delete_Vector(b); + diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/simple/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/simple/example.cpp b/Examples/javascript/simple/example.cpp new file mode 100755 index 000000000..e7d3b0f11 --- /dev/null +++ b/Examples/javascript/simple/example.cpp @@ -0,0 +1,28 @@ +#include +#include +#include +#include +using namespace std; + +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + + + + + diff --git a/Examples/javascript/simple/example.i b/Examples/javascript/simple/example.i new file mode 100755 index 000000000..7c345964c --- /dev/null +++ b/Examples/javascript/simple/example.i @@ -0,0 +1,15 @@ +/* File : example.i */ +%module example + +%include "std_string.i" + +%inline %{ +extern int gcd(int x, int y); +extern float gcd(float x, float y); +extern char* helloString(char* s); +extern void delete_helloString(char *newstr); +extern std::string helloString(std::string s); +extern void bar(int x, int y = 3, int z = 4); + +extern double Foo; +%} diff --git a/Examples/javascript/simple/runme.js b/Examples/javascript/simple/runme.js new file mode 100755 index 000000000..96c11a5a2 --- /dev/null +++ b/Examples/javascript/simple/runme.js @@ -0,0 +1,26 @@ +/* file: runme.js */ + +/* Call our gcd() function */ + +x = 42; +y = 105; +g = example.gcd(x,y); +print("GCD of x and y is=" + g); + +/* Manipulate the Foo global variable */ + +/* Output its current value */ +print("Global variable Foo=" + example.Foo); + +/* Change its value */ +example.Foo = 3.1415926; + +/* See if the change took effect */ +print("Variable Foo changed to=" + example.Foo); + + + + + + + diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile new file mode 100755 index 000000000..ea41e55ce --- /dev/null +++ b/Examples/javascript/template/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/template/example.cpp b/Examples/javascript/template/example.cpp new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/template/example.h b/Examples/javascript/template/example.h new file mode 100644 index 000000000..7401df650 --- /dev/null +++ b/Examples/javascript/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return $self->get(index); + } + void setitem(int index, T val) { + $self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/javascript/template/example.i b/Examples/javascript/template/example.i new file mode 100644 index 000000000..8f94c4da1 --- /dev/null +++ b/Examples/javascript/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + diff --git a/Examples/javascript/template/runme.js b/Examples/javascript/template/runme.js new file mode 100644 index 000000000..b2a5264ab --- /dev/null +++ b/Examples/javascript/template/runme.js @@ -0,0 +1,32 @@ +// file: runme.js + +//Call some templated functions +print(example.maxint(3,7)); +print(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +print(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +print(sum); + +delete iv; +delete dv; + + diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile new file mode 100755 index 000000000..e80e370e0 --- /dev/null +++ b/Examples/javascript/variables/Makefile @@ -0,0 +1,24 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx +JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript +JAVASCRIPT_MODULE = example +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i +SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ +SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: all + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + diff --git a/Examples/javascript/variables/example.c b/Examples/javascript/variables/example.c new file mode 100755 index 000000000..aa4ffe9b3 --- /dev/null +++ b/Examples/javascript/variables/example.c @@ -0,0 +1,91 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include +#include +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +const char cstrvar[] = "Goodbye"; +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/javascript/variables/example.h b/Examples/javascript/variables/example.h new file mode 100755 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/javascript/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/javascript/variables/example.i b/Examples/javascript/variables/example.i new file mode 100755 index 000000000..591b871ed --- /dev/null +++ b/Examples/javascript/variables/example.i @@ -0,0 +1,49 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + diff --git a/Examples/javascript/variables/runme.js b/Examples/javascript/variables/runme.js new file mode 100755 index 000000000..7c4e151de --- /dev/null +++ b/Examples/javascript/variables/runme.js @@ -0,0 +1,68 @@ +// file: runme.js + +// Try to set the values of some global variables +example.ivar = 42; +example.svar = -31000; +example.lvar = 65537; +example.uivar = 123456; +example.usvar = 61000; +example.ulvar = 654321; +example.scvar = -13; +example.ucvar = 251; +example.cvar = "S"; +example.fvar = 3.14159; +example.dvar = 2.1828; +example.strvar = "Hello World"; +example.iptrvar= example.new_int(37); +example.ptptr = example.new_Point(37,42); +example.name = "Bill"; + +// Now print out the values of the variables +print("Variables (values printed from Python)" + "\n"); +print("ivar = " + example.ivar + "\n"); +print("svar = " + example.svar + "\n"); +print("lvar = " + example.lvar + "\n"); +print("uivar = " + example.uivar + "\n"); +print("usvar = " + example.usvar + "\n"); +print("ulvar = " + example.ulvar + "\n"); +print("scvar = " + example.scvar + "\n"); +print("ucvar = " + example.ucvar + "\n"); +print("fvar = " + example.fvar + "\n"); +print("dvar = " + example.dvar + "\n"); +print("cvar = " + example.cvar + "\n"); +print("strvar = " + example.strvar+ "\n"); +print("cstrvar = " + example.cstrvar+ "\n"); +print("iptrvar = " + example.iptrvar+ "\n"); +print("name = " + example.name + "\n"); +print("ptptr = " + example.ptptr + ": " + example.Point_print(example.ptptr) + "\n"); +print("pt = " + example.pt + ": " + example.Point_print(example.pt) + "\n"); + + +print("\nVariables (values printed from C)"); + +example.print_vars(); + +print("\nNow I'm going to try and modify some read only variables"); + +print("Tring to set 'path'"); +try{ + example.path = "Whoa!"; + print("Hey, what's going on?!?! This shouldn't work"); +} +catch(e){ + print("Good."); +} + +print("Trying to set 'status'"); +try{ + example.status = 0; + print("Hey, what's going on?!?! This shouldn't work"); +} catch(e){ + print("Good."); +} + +print("\nI'm going to try and update a structure variable.\n"); +example.pt = example.ptptr; +print("The new value is: "); +example.pt_print(); +print("You should see the value: " + example.Point_print(example.ptptr)); diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 7cc410e7a..268dcee39 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -95,6 +95,7 @@ C_TEST_BROKEN += \ # C++ test cases. (Can be run individually using: make testcase.cpptest) +ifndef SKIP_CPP_CASES CPP_TEST_CASES += \ abstract_access \ abstract_inherit \ @@ -459,6 +460,7 @@ CPP_TEST_CASES += \ voidtest \ wallkw \ wrapmacro +endif # # Put all the heavy STD/STL cases here, where they can be skipped if needed @@ -488,6 +490,7 @@ endif # C test cases. (Can be run individually using: make testcase.ctest) +ifndef SKIP_C_CASES C_TEST_CASES += \ arrays \ char_constant \ @@ -532,9 +535,10 @@ C_TEST_CASES += \ typemap_subst \ union_parameter \ unions - +endif # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest) +ifndef SKIP_MULTI_CPP_CASES MULTI_CPP_TEST_CASES += \ clientdata_prop \ imports \ @@ -543,6 +547,7 @@ MULTI_CPP_TEST_CASES += \ mod \ template_typedef_import \ multi_import +endif # Custom tests - tests with additional commandline options wallkw.cpptest: SWIGOPT += -Wallkw diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in new file mode 100755 index 000000000..38f350cb0 --- /dev/null +++ b/Examples/test-suite/javascript/Makefile.in @@ -0,0 +1,94 @@ +####################################################################### +# Makefile for javascript test-suite +####################################################################### + +LANGUAGE = javascript +JAVASCRIPT_EXE = ../../../Tools/javascript/javascript +JAVASCRIPT_EXE_SRC = ../../../Tools/javascript/javascript.cxx +SCRIPTSUFFIX = _runme.js +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +JS_INCLUDE = @JSCOREINC@ +JS_DLNK = @JSCOREDYNAMICLINKING@ +JSCXXFLAGS = @JSCXXFLAGS@ + +C_TEST_CASES = \ + preproc \ + preproc_include + +CPP_TEST_CASES = \ + abstract_access \ + abstract_typedef \ + abstract_typedef2 \ + abstract_virtual \ + array_member \ + arrays_global \ + char_binary \ + class_ignore \ + class_scope_weird \ + complextest \ + constover \ + cpp_enum \ + cpp_namespace \ + cpp_static \ + director_alternating \ + enum_template \ + namespace_virtual_method \ + overload_copy \ + ret_by_value \ + struct_value \ + template_static \ + typedef_class \ + typedef_inherit \ + typedef_scope \ + typemap_arrays \ + typemap_delete \ + typemap_namespace \ + typemap_ns_using \ + using1 \ + using2 + +SKIP_CPP_CASES = @SKIP_CPP_CASES@ +SKIP_C_CASES = @SKIP_C_CASES@ +SKIP_CPP_STD_CASES = @SKIP_CPP_STD_CASES@ +SKIP_MULTI_CPP_CASES = @SKIP_MULTI_CPP_CASES@ + +include $(srcdir)/../common.mk + +# Overridden variables here + +# Custom tests - tests with additional commandline options + +javascript_exe: + $(CXX) $(JSCXXFLAGS) $(JS_INCLUDE) $(JAVASCRIPT_EXE_SRC) $(LIBS) $(JS_DLNK) -o $(JAVASCRIPT_EXE) + +# Rules for the different types of tests +%.cpptest: javascript_exe + $(setup) + +$(swig_and_compile_cpp) + $(run_testcase) + +%.ctest: javascript_exe + $(setup) + +$(swig_and_compile_c) + $(run_testcase) + +%.multicpptest: javascript_exe + $(setup) + +$(swig_and_compile_multi_cpp) + $(run_testcase) + +# Runs the testcase. A testcase is only run if +# a file is found which has _runme.js appended after the testcase name. +run_testcase = \ + if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ + env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(JAVASCRIPT_EXE) -l $* $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \ + fi + +# Clean +%.clean: + + +clean: + $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile javascript_clean diff --git a/Examples/test-suite/javascript/README b/Examples/test-suite/javascript/README new file mode 100755 index 000000000..acb2f7291 --- /dev/null +++ b/Examples/test-suite/javascript/README @@ -0,0 +1,4 @@ +See ../README for common README file. + +Any testcases which have _runme.js appended after the testcase name will be detected and run. + diff --git a/Examples/test-suite/javascript/abstract_access_runme.js b/Examples/test-suite/javascript/abstract_access_runme.js new file mode 100644 index 000000000..356d07ea7 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_access_runme.js @@ -0,0 +1,5 @@ +var d = new abstract_access.D() +if (d.do_x() != 1) { + throw "Error"; +} + diff --git a/Examples/test-suite/javascript/abstract_typedef2_runme.js b/Examples/test-suite/javascript/abstract_typedef2_runme.js new file mode 100644 index 000000000..8adc2e05b --- /dev/null +++ b/Examples/test-suite/javascript/abstract_typedef2_runme.js @@ -0,0 +1,4 @@ +var a = new abstract_typedef2.A_UF(); + +if (a == undefined) + throw "Error"; diff --git a/Examples/test-suite/javascript/abstract_typedef_runme.js b/Examples/test-suite/javascript/abstract_typedef_runme.js new file mode 100644 index 000000000..106baea65 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_typedef_runme.js @@ -0,0 +1,6 @@ +var e = new abstract_typedef.Engine(); +var a = new abstract_typedef.A() + +if (a.write(e) != 1) { + throw "Error"; +} diff --git a/Examples/test-suite/javascript/abstract_virtual_runme.js b/Examples/test-suite/javascript/abstract_virtual_runme.js new file mode 100644 index 000000000..c15abb5f6 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_virtual_runme.js @@ -0,0 +1,9 @@ +d = new abstract_virtual.D() + +if (d == undefined) + throw "Error"; + +e = new abstract_virtual.E() + +if (e == undefined) + throw "Error"; diff --git a/Examples/test-suite/javascript/array_member_runme.js b/Examples/test-suite/javascript/array_member_runme.js new file mode 100644 index 000000000..dee4c2ca9 --- /dev/null +++ b/Examples/test-suite/javascript/array_member_runme.js @@ -0,0 +1,20 @@ +var f = new array_member.Foo(); +f.data = array_member.global_data; + +for (var i=0; i<8; i++) { + if (array_member.get_value(f.data,i) != array_member.get_value(array_member.global_data,i)) { + throw "Bad array assignment (1)"; + } +} + +for (var i=0; i<8; i++) { + array_member.set_value(f.data,i,-i); +} + +array_member.global_data = f.data; + +for (var i=0; i<8; i++){ + if (array_member.get_value(f.data,i) != array_member.get_value(array_member.global_data,i)) { + throw "Bad array assignment (2)"; + } +} diff --git a/Examples/test-suite/javascript/arrays_global_runme.js b/Examples/test-suite/javascript/arrays_global_runme.js new file mode 100644 index 000000000..9668826f3 --- /dev/null +++ b/Examples/test-suite/javascript/arrays_global_runme.js @@ -0,0 +1,16 @@ +arrays_global.array_i = arrays_global.array_const_i; + +arrays_global.BeginString_FIX44a; +arrays_global.BeginString_FIX44b; +arrays_global.BeginString_FIX44c; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44b = "12"+'\0'+"45"; +arrays_global.BeginString_FIX44b; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44e; +arrays_global.BeginString_FIX44f; + +arrays_global.test_a("hello","hi","chello","chi"); + +arrays_global.test_b("1234567","hi"); diff --git a/Examples/test-suite/javascript/char_binary_runme.js b/Examples/test-suite/javascript/char_binary_runme.js new file mode 100644 index 000000000..7cd09bd5c --- /dev/null +++ b/Examples/test-suite/javascript/char_binary_runme.js @@ -0,0 +1,36 @@ +var t = new char_binary.Test(); +if (t.strlen('hile') != 4) { + print(t.strlen('hile')); + throw("bad multi-arg typemap 1"); +} + +if (t.strlen('hil\0') != 4) { + throw("bad multi-arg typemap 2"); +} + +/* + * creating a raw char* + */ +var pc = char_binary.new_pchar(5); +char_binary.pchar_setitem(pc, 0, 'h'); +char_binary.pchar_setitem(pc, 1, 'o'); +char_binary.pchar_setitem(pc, 2, 'l'); +char_binary.pchar_setitem(pc, 3, 'a'); +char_binary.pchar_setitem(pc, 4, 0); + + +if (t.strlen(pc) != 4) { + throw("bad multi-arg typemap (3)"); +} + +char_binary.var_pchar = pc; +if (char_binary.var_pchar != "hola") { + print(char_binary.var_pchar); + throw("bad pointer case (1)"); +} + +char_binary.var_namet = pc; +if (char_binary.var_namet != "hola") { + throw("bad pointer case (2)"); +} +char_binary.delete_pchar(pc); diff --git a/Examples/test-suite/javascript/class_ignore_runme.js b/Examples/test-suite/javascript/class_ignore_runme.js new file mode 100644 index 000000000..00bb2591e --- /dev/null +++ b/Examples/test-suite/javascript/class_ignore_runme.js @@ -0,0 +1,5 @@ + +a = new class_ignore.Bar(); + +if (class_ignore.do_blah(a) != "Bar::blah") + throw "Error"; diff --git a/Examples/test-suite/javascript/class_scope_weird_runme.js b/Examples/test-suite/javascript/class_scope_weird_runme.js new file mode 100644 index 000000000..c442cc7f6 --- /dev/null +++ b/Examples/test-suite/javascript/class_scope_weird_runme.js @@ -0,0 +1,5 @@ + +f = new class_scope_weird.Foo(); +g = new class_scope_weird.Foo(3); +if (f.bar(3) != 3) + throw RuntimeError; diff --git a/Examples/test-suite/javascript/complextest_runme.js b/Examples/test-suite/javascript/complextest_runme.js new file mode 100644 index 000000000..9d3cf4264 --- /dev/null +++ b/Examples/test-suite/javascript/complextest_runme.js @@ -0,0 +1,21 @@ + +a = [-1,2]; + +expected = [-1, -2]; + +a_c = complextest.Conj(a); +if (a_c.toString() != expected.toString()) + throw "Error in Conj(a)"; + +a_c_f = complextest.Conjf(a); +if (a_c_f.toString() != expected.toString()) + throw "Error in Conjf(a)"; + +v = new complextest.VectorStdCplx(); +v.add([1,2]); +v.add([2,3]); +v.add([4,3]); +v.add(1); + +// TODO: how to check validity? +complextest.Copy_h(v); diff --git a/Examples/test-suite/javascript/constover_runme.js b/Examples/test-suite/javascript/constover_runme.js new file mode 100644 index 000000000..f131ef444 --- /dev/null +++ b/Examples/test-suite/javascript/constover_runme.js @@ -0,0 +1,31 @@ +p = constover.test("test"); +if (p != "test") { + throw "test failed!"; +} + +p = constover.test_pconst("test"); +if (p != "test_pconst") { + throw "test_pconst failed!"; +} + +f = new constover.Foo(); + +p = f.test("test"); +if (p != "test") { + throw "member-test failed!"; +} + +p = f.test_pconst("test"); +if (p != "test_pconst") { + throw "member-test_pconst failed!"; +} + +p = f.test_constm("test"); +if (p != "test_constmethod") { + throw "member-test_constm failed!"; +} + +p = f.test_pconstm("test"); +if (p != "test_pconstmethod") { + throw "member-test_pconstm failed!"; +} diff --git a/Examples/test-suite/javascript/cpp_enum_runme.js b/Examples/test-suite/javascript/cpp_enum_runme.js new file mode 100644 index 000000000..f5a9e3595 --- /dev/null +++ b/Examples/test-suite/javascript/cpp_enum_runme.js @@ -0,0 +1,26 @@ +var f = new cpp_enum.Foo() + +if(f.hola != cpp_enum.Hello){ + print(f.hola); + throw "Error"; +} + +f.hola = cpp_enum.Foo.Hi +if(f.hola != cpp_enum.Foo.Hi){ + print(f.hola); + throw "Error"; +} + +f.hola = cpp_enum.Hello + +if(f.hola != cpp_enum.Hello){ + print(f.hola); + throw "Error"; +} + +cpp_enum.Foo.hi = cpp_enum.Hello +if(cpp_enum.Foo.hi != cpp_enum.Hello){ + print(cpp_enum.Foo.hi); + throw "Error"; +} + diff --git a/Examples/test-suite/javascript/cpp_namespace_runme.js b/Examples/test-suite/javascript/cpp_namespace_runme.js new file mode 100644 index 000000000..5795536bd --- /dev/null +++ b/Examples/test-suite/javascript/cpp_namespace_runme.js @@ -0,0 +1,45 @@ +var n = cpp_namespace.fact(4); +if (n != 24){ + throw ("Bad return value error!"); +} +if (cpp_namespace.Foo != 42){ + throw ("Bad variable value error!"); +} + +t = new cpp_namespace.Test(); +if (t.method() != "Test::method"){ + throw ("Bad method return value error!"); +} +if (cpp_namespace.do_method(t) != "Test::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method2(t) != "Test::method"){ + throw ("Bad return value error!"); +} +cpp_namespace.weird("hello", 4); +delete t; + +t2 = new cpp_namespace.Test2(); +t3 = new cpp_namespace.Test3(); +t4 = new cpp_namespace.Test4(); +t5 = new cpp_namespace.Test5(); +if (cpp_namespace.foo3(42) != 42){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t2,40) != "Test2::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t3,40) != "Test3::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t4,40) != "Test4::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t5,40) != "Test5::method"){ + throw ("Bad return value error!"); +} diff --git a/Examples/test-suite/javascript/cpp_static_runme.js b/Examples/test-suite/javascript/cpp_static_runme.js new file mode 100644 index 000000000..0ff28b4ee --- /dev/null +++ b/Examples/test-suite/javascript/cpp_static_runme.js @@ -0,0 +1,7 @@ +cpp_static.StaticFunctionTest.static_func(); +cpp_static.StaticFunctionTest.static_func_2(1); +cpp_static.StaticFunctionTest.static_func_3(1,2); +cpp_static.StaticMemberTest.static_int = 10; +if (cpp_static.StaticMemberTest.static_int != 10) +throw "error"; + diff --git a/Examples/test-suite/javascript/director_alternating_runme.js b/Examples/test-suite/javascript/director_alternating_runme.js new file mode 100644 index 000000000..3c2c883a1 --- /dev/null +++ b/Examples/test-suite/javascript/director_alternating_runme.js @@ -0,0 +1,4 @@ + +id = director_alternating.getBar().id(); +if (id != director_alternating.idFromGetBar()) + throw ("Error, Got wrong id: " + str(id)); diff --git a/Examples/test-suite/javascript/enum_template_runme.js b/Examples/test-suite/javascript/enum_template_runme.js new file mode 100644 index 000000000..54195c78b --- /dev/null +++ b/Examples/test-suite/javascript/enum_template_runme.js @@ -0,0 +1,6 @@ +if (enum_template.MakeETest() != 1) + throw "RuntimeError"; + +if (enum_template.TakeETest(0) != null) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/namespace_virtual_method_runme.js b/Examples/test-suite/javascript/namespace_virtual_method_runme.js new file mode 100644 index 000000000..bb187b993 --- /dev/null +++ b/Examples/test-suite/javascript/namespace_virtual_method_runme.js @@ -0,0 +1,2 @@ + +x = new namespace_virtual_method.Spam(); diff --git a/Examples/test-suite/javascript/overload_copy_runme.js b/Examples/test-suite/javascript/overload_copy_runme.js new file mode 100644 index 000000000..88fab3720 --- /dev/null +++ b/Examples/test-suite/javascript/overload_copy_runme.js @@ -0,0 +1,3 @@ + +f = new overload_copy.Foo(); +g = new overload_copy.Foo(f); diff --git a/Examples/test-suite/javascript/preproc_include_runme.js b/Examples/test-suite/javascript/preproc_include_runme.js new file mode 100644 index 000000000..d52ef97c1 --- /dev/null +++ b/Examples/test-suite/javascript/preproc_include_runme.js @@ -0,0 +1,22 @@ + +if (preproc_include.multiply10(10) != 100) + throw "RuntimeError"; + +if (preproc_include.multiply20(10) != 200) + throw "RuntimeError"; + +if (preproc_include.multiply30(10) != 300) + throw "RuntimeError"; + +if (preproc_include.multiply40(10) != 400) + throw "RuntimeError"; + +if (preproc_include.multiply50(10) != 500) + throw "RuntimeError"; + +if (preproc_include.multiply60(10) != 600) + throw "RuntimeError"; + +if (preproc_include.multiply70(10) != 700) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/preproc_runme.js b/Examples/test-suite/javascript/preproc_runme.js new file mode 100644 index 000000000..b708385da --- /dev/null +++ b/Examples/test-suite/javascript/preproc_runme.js @@ -0,0 +1,13 @@ + +if (preproc.endif != 1) + throw "RuntimeError"; + +if (preproc.define != 1) + throw "RuntimeError"; + +if (preproc.defined != 1) + throw "RuntimeError"; + +if (2*preproc.one != preproc.two) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/ret_by_value_runme.js b/Examples/test-suite/javascript/ret_by_value_runme.js new file mode 100644 index 000000000..720cd398f --- /dev/null +++ b/Examples/test-suite/javascript/ret_by_value_runme.js @@ -0,0 +1,7 @@ + +a = ret_by_value.get_test(); +if (a.myInt != 100) + throw "RuntimeError"; + +if (a.myShort != 200) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/struct_value_runme.js b/Examples/test-suite/javascript/struct_value_runme.js new file mode 100644 index 000000000..314551688 --- /dev/null +++ b/Examples/test-suite/javascript/struct_value_runme.js @@ -0,0 +1,10 @@ + +b = new struct_value.Bar(); + +b.a.x = 3; +if (b.a.x != 3) +throw "RuntimeError"; + +b.b.x = 3; +if (b.b.x != 3) +throw "RuntimeError" diff --git a/Examples/test-suite/javascript/template_static_runme.js b/Examples/test-suite/javascript/template_static_runme.js new file mode 100644 index 000000000..338e2c55c --- /dev/null +++ b/Examples/test-suite/javascript/template_static_runme.js @@ -0,0 +1,2 @@ + +template_static.Foo.bar_double(1); diff --git a/Examples/test-suite/javascript/typedef_class_runme.js b/Examples/test-suite/javascript/typedef_class_runme.js new file mode 100644 index 000000000..accefb499 --- /dev/null +++ b/Examples/test-suite/javascript/typedef_class_runme.js @@ -0,0 +1,5 @@ +a = new typedef_class.RealA(); +a.a = 3; + +b = new typedef_class.B(); +b.testA(a); diff --git a/Examples/test-suite/javascript/typedef_inherit_runme.js b/Examples/test-suite/javascript/typedef_inherit_runme.js new file mode 100644 index 000000000..f16c1787e --- /dev/null +++ b/Examples/test-suite/javascript/typedef_inherit_runme.js @@ -0,0 +1,22 @@ + +a = new typedef_inherit.Foo(); +b = new typedef_inherit.Bar(); + +x = typedef_inherit.do_blah(a); +if (x != "Foo::blah") + print("Whoa! Bad return" + x); + +x = typedef_inherit.do_blah(b); +if (x != "Bar::blah") + print("Whoa! Bad return" + x); + +c = new typedef_inherit.Spam(); +d = new typedef_inherit.Grok(); + +x = typedef_inherit.do_blah2(c); +if (x != "Spam::blah") + print("Whoa! Bad return" + x); + +x = typedef_inherit.do_blah2(d); +if (x != "Grok::blah") + print ("Whoa! Bad return" + x); diff --git a/Examples/test-suite/javascript/typedef_scope_runme.js b/Examples/test-suite/javascript/typedef_scope_runme.js new file mode 100644 index 000000000..8a08ffb9b --- /dev/null +++ b/Examples/test-suite/javascript/typedef_scope_runme.js @@ -0,0 +1,11 @@ + +b = new typedef_scope.Bar(); +x = b.test1(42,"hello"); +if (x != 42) + print("Failed!!"); + +x = b.test2(42,"hello"); +if (x != "hello") + print("Failed!!"); + + diff --git a/Examples/test-suite/javascript/typemap_arrays_runme.js b/Examples/test-suite/javascript/typemap_arrays_runme.js new file mode 100644 index 000000000..2126ed15f --- /dev/null +++ b/Examples/test-suite/javascript/typemap_arrays_runme.js @@ -0,0 +1,4 @@ + +if (typemap_arrays.sumA(null) != 60) + throw "RuntimeError, Sum is wrong"; + diff --git a/Examples/test-suite/javascript/typemap_delete_runme.js b/Examples/test-suite/javascript/typemap_delete_runme.js new file mode 100644 index 000000000..d58684df4 --- /dev/null +++ b/Examples/test-suite/javascript/typemap_delete_runme.js @@ -0,0 +1,4 @@ + +r = new typemap_delete.Rect(123); +if (r.val != 123) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/typemap_namespace_runme.js b/Examples/test-suite/javascript/typemap_namespace_runme.js new file mode 100644 index 000000000..d679f3b0b --- /dev/null +++ b/Examples/test-suite/javascript/typemap_namespace_runme.js @@ -0,0 +1,6 @@ + +if (typemap_namespace.test1("hello") != "hello") + throw "RuntimeError"; + +if (typemap_namespace.test2("hello") != "hello") + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/typemap_ns_using_runme.js b/Examples/test-suite/javascript/typemap_ns_using_runme.js new file mode 100644 index 000000000..d05f7f0c1 --- /dev/null +++ b/Examples/test-suite/javascript/typemap_ns_using_runme.js @@ -0,0 +1,3 @@ + +if (typemap_ns_using.spam(37) != 37) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/using1_runme.js b/Examples/test-suite/javascript/using1_runme.js new file mode 100644 index 000000000..cb54a62fa --- /dev/null +++ b/Examples/test-suite/javascript/using1_runme.js @@ -0,0 +1,4 @@ + + +if (using1.spam(37) != 37) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/using2_runme.js b/Examples/test-suite/javascript/using2_runme.js new file mode 100644 index 000000000..948f58ead --- /dev/null +++ b/Examples/test-suite/javascript/using2_runme.js @@ -0,0 +1,3 @@ + +if (using2.spam(37) != 37) + throw "RuntimeError"; diff --git a/Lib/javascript/jsc/ccomplex.i b/Lib/javascript/jsc/ccomplex.i new file mode 100644 index 000000000..8eda920bb --- /dev/null +++ b/Lib/javascript/jsc/ccomplex.i @@ -0,0 +1,26 @@ +/* ----------------------------------------------------------------------------- + * ccomplex.i + * + * C complex typemaps + * ISO C99: 7.3 Complex arithmetic + * ----------------------------------------------------------------------------- */ + + +%include + +%{ +#include +%} + + +/* C complex constructor */ +#define CCplxConst(r, i) ((r) + I*(i)) + +%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag); + +/* declaring the typemaps */ +%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex); diff --git a/Lib/javascript/jsc/complex.i b/Lib/javascript/jsc/complex.i new file mode 100644 index 000000000..4c3b3c5e2 --- /dev/null +++ b/Lib/javascript/jsc/complex.i @@ -0,0 +1,6 @@ +#ifdef __cplusplus +%include +#else +%include +#endif + diff --git a/Lib/javascript/jsc/javascript.swg b/Lib/javascript/jsc/javascript.swg new file mode 100644 index 000000000..3a83b6495 --- /dev/null +++ b/Lib/javascript/jsc/javascript.swg @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------------- + * javascript.swg + * + * Javascript typemaps + * ----------------------------------------------------------------------------- */ + +%include + +%include + +%include + +%include + +%include + +%include + +%include diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg new file mode 100644 index 000000000..dfa51e143 --- /dev/null +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -0,0 +1,292 @@ +/********************************************************************* + *getproperty: This template gives name to generated wrapper for the getproperty + *{LOCALS}: declarations for input arguments + *{CODE}: contains input marshalling, and the action +*********************************************************************/ + +%fragment ("JS_getproperty", "templates") +%{ +JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + +/********************************************************************** + *setproperty: This template gives name to generated wrapper for the setproperty + *{LOCALS}: declarations for input arguments + *{CODE}: contains input marshalling, and the action +**********************************************************************/ + +%fragment ("JS_setproperty", "templates") +%{ +bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + + return true; + + goto fail; + fail: + return false; +} +%} + +/************************************************************************************ + *functionwrapper: This template gives name to generated wrapper for the function + *{LOCALS}: declarations for input arguments + *{CODE} contains input marshalling, and the action +************************************************************************************/ +%fragment ("JS_functionwrapper", "templates") +%{ +JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + +/************************************************************************************** +function_dispatch_case: This template is used for the function which is overloaded +***************************************************************************************/ + +%fragment ("JS_function_dispatch_case", "templates") +%{if(argc == ${argcount}) { + jsresult = ${functionwrapper}(context, function, thisObject, argc, argv, exception); + } else %} + +%fragment ("JS_function_dispatch_case_default", "templates") +%{ + { + // TODO: throw JS exception + throw "Invalid function arguments."; + } +%} + +/* Added template for function declaration */ + +%fragment ("JS_variabledecl", "templates") +%{{"${propertyname}",${getname}, ${setname},kJSPropertyAttributeNone},%} + + +/* Added template for function declaration */ + +%fragment ("JS_functiondecl", "templates") +%{{"${functionname}",${functionwrapper}, kJSPropertyAttributeNone},%} + +%fragment ("JS_globaldefn", "templates") +%{ +JSStaticValue ${namespace}_values[] = { + ${jsglobalvariables} + { 0, 0, 0, 0 } +}; + +JSStaticFunction ${namespace}_functions[] = { + ${jsglobalfunctions} + { 0, 0, 0 } +}; + +JSClassDefinition ${namespace}_classDefinition; +%} + +/****************************************************************************************** + * class_definition: + * This code template is used for wrapper of classes definition. + * ${classname_mangled}:the mangled name of the qualified class name, e.g., foo::A -> foo_A + *****************************************************************************************/ + +%fragment ("JS_class_definition", "templates") +%{ +JSClassDefinition ${classname_mangled}_classDefinition; + +JSClassDefinition ${classname_mangled}_objectDefinition; + +JSClassRef ${classname_mangled}_classRef; +%} + +/********************************************************************* + * class_table: + * This code template is used to add the wrapper for class declaration + * ${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A +***********************************************************************/ + +%fragment ("JS_class_tables", "templates") +%{ +JSStaticValue ${classname_mangled}_staticValues[] = { + ${jsstaticclassvariables} + { 0, 0, 0, 0 } +}; + +JSStaticFunction ${classname_mangled}_staticFunctions[] = { + ${jsstaticclassfunctions} + { 0, 0, 0 } +}; + +JSStaticValue ${classname_mangled}_values[] = { + ${jsclassvariables} + { 0, 0, 0, 0 } +}; + +JSStaticFunction ${classname_mangled}_functions[] = { + ${jsclassfunctions} + { 0, 0, 0 } +}; +%} + +/********************************************************************* + * destructordefn: + * This code template is used to adds the destructor wrapper function + * ${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A +***********************************************************************/ + +%fragment ("JS_destructordefn", "templates") +%{ +void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) +{ + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject); + if(t) free(t); +} +%} + +/********************************************************************* + * constructor_definition: + * This code template is used to adds the main constructor wrapper function + * ${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A +***********************************************************************/ + + +%fragment ("JS_mainctordefn", "templates") +%{ +JSObjectRef _wrap_create_${classname_mangled}(JSContextRef context, JSObjectRef ctorObject, + size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSObjectRef thisObject; + + ${DISPATCH_CASES} + { + // TODO: handle illegal arguments + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of ${classname_mangled}"); + } + + return thisObject; + + fail: + return NULL; +} +%} + +/************************************************************************************** +ctor_dispatch_case: This template is used for the constructor which is overloaded +***************************************************************************************/ + +%fragment ("JS_ctor_dispatch_case", "templates") +%{if(argc == ${argcount}) { + thisObject = _wrap_create_${classname_mangled}${overloadext}(context, NULL, argc, argv, exception); + } else %} + + +%fragment ("JS_ctordefn", "templates") +%{ +JSObjectRef _wrap_create_${classname_mangled}${overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN); + + goto fail; + fail: + return NULL; +} +%} +/********************************************************************** +initializer:This template is dynamic growing and aggregates everything +**********************************************************************/ + +%fragment ("JS_initializer", "templates") %{ +#ifdef __cplusplus +extern "C" { +#endif + +bool ${modulename}_initialize(JSGlobalContextRef context) { + SWIG_InitializeModule(0); + + JSObjectRef global_object = JSContextGetGlobalObject(context); + + /* Initialize the base swig type object */ + _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; + _SwigObject_objectDefinition.staticValues = _SwigObject_values; + _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + + /* Create objects for namespaces */ + ${create_namespaces} + + /* Create classes */ + ${initializercode} + + /* Register namespaces */ + ${register_namespaces} + + return true; +} + +#ifdef __cplusplus +} +#endif + +%} + +/***************************************************************************************** + *create_class_template: + *This template is used to add a Static references to class templates. + *${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A +*****************************************************************************************/ + +%fragment ("JS_create_class_template", "templates") +%{ ${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; + ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; + ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; + ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; + ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; + ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; + JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}_objectDefinition); + SWIGTYPE_${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%} + +/***************************************************************************************** + *register_class: + *This template is used to adds a class registration statement to initializer function + *${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A +*****************************************************************************************/ + +%fragment ("JS_register_class", "templates") +%{JS_registerClass(context, ${namespace_mangled}_object, "${classname}", &${classname_mangled}_classDefinition);%} + +/* register global function */ +%fragment ("JS_register_global_function", "templates") +%{JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper});%} + + +/* create and register namespaces */ + +%fragment ("JS_create_namespace", "templates") +%{ ${namespace}_classDefinition.staticFunctions = ${namespace}_functions; + ${namespace}_classDefinition.staticValues = ${namespace}_values; + JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL); +%} + +%fragment ("JS_register_namespace", "templates") +%{ +JS_registerNamespace(context, ${namespace_mangled}_object, ${parent_namespace}_object, "${namespace}"); %} diff --git a/Lib/javascript/jsc/javascriptcomplex.swg b/Lib/javascript/jsc/javascriptcomplex.swg new file mode 100644 index 000000000..7d165dce4 --- /dev/null +++ b/Lib/javascript/jsc/javascriptcomplex.swg @@ -0,0 +1,146 @@ +/* + Defines the As/From converters for double/float complex, you need to + provide complex Type, the Name you want to use in the converters, + the complex Constructor method, and the Real and Imag complex + accessor methods. + + See the std_complex.i and ccomplex.i for concret examples. +*/ + +/* the common from converter */ +%define %swig_fromcplx_conv(Type, Real, Imag) +%fragment(SWIG_From_frag(Type),"header", + fragment=SWIG_From_frag(double)) +{ +SWIGINTERNINLINE JSObjectRef +SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) +{ + JSValueRef vals[2]; + vals[0] = SWIG_From(double)(Real(c)); + vals[1] = SWIG_From(double)(Imag(c)); + return JSObjectMakeArray(context, 2, vals, NULL); +} +} +%enddef + +/* the double case */ +%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(double)) +{ +SWIGINTERN int +SWIG_AsVal_dec(Type) (JSValueRef o, Type* val) +{ + if (JSValueIsObject(context, o)) { + JSObjectRef array; + JSValueRef exception, js_re, js_im; + double re, im; + int res; + + exception = 0; + res = 0; + + array = JSValueToObject(context, o, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); + if(exception != 0) + return SWIG_TypeError; + + res = SWIG_AsVal(double)(js_re, &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(js_im, &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if (val) *val = Constructor(re, im); + return SWIG_OK; + } else { + double d; + int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(d, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +/* the float case */ +%define %swig_cplxflt_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(float)) { +SWIGINTERN int +SWIG_AsVal_dec(Type)(JSValueRef o, Type *val) +{ + if (JSValueIsObject(context, o)) { + JSObjectRef array; + JSValueRef exception, js_re, js_im; + double re, im; + int res; + + exception = 0; + res = 0; + + array = JSValueToObject(context, o, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); + if(exception != 0) + return SWIG_TypeError; + + res = SWIG_AsVal(double)(js_re, &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(js_im, &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if ((-FLT_MAX <= re && re <= FLT_MAX) && (-FLT_MAX <= im && im <= FLT_MAX)) { + if (val) *val = Constructor(%numeric_cast(re, float), + %numeric_cast(im, float)); + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else { + float re; + int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(re, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} + +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ +%swig_cplxflt_conv(Type, Constructor, Real, Imag) + + +#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ +%swig_cplxdbl_conv(Type, Constructor, Real, Imag) diff --git a/Lib/javascript/jsc/javascriptfragments.swg b/Lib/javascript/jsc/javascriptfragments.swg new file mode 100644 index 000000000..e69de29bb diff --git a/Lib/javascript/jsc/javascripthelpers.swg b/Lib/javascript/jsc/javascripthelpers.swg new file mode 100644 index 000000000..820075ca6 --- /dev/null +++ b/Lib/javascript/jsc/javascripthelpers.swg @@ -0,0 +1,69 @@ +%insert(wrapper) %{ + +bool JS_registerClass(JSGlobalContextRef context, JSObjectRef parentObject, + const char* className, + JSClassDefinition* definition) { + + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject, + js_className, classObject, + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef context, + JSObjectRef namespaceObj, JSObjectRef parentNamespace, + const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace, + js_name, namespaceObj, + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + + return true; +} + + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context, object, js_functionName, + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} + +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + + return val; +} +%} diff --git a/Lib/javascript/jsc/javascriptinit.swg b/Lib/javascript/jsc/javascriptinit.swg new file mode 100644 index 000000000..69bc3a9b1 --- /dev/null +++ b/Lib/javascript/jsc/javascriptinit.swg @@ -0,0 +1,15 @@ +%insert(init) %{ +SWIGRUNTIME void +SWIG_JSC_SetModule(swig_module_info *swig_module) {} + +SWIGRUNTIME swig_module_info * +SWIG_JSC_GetModule(void) { + return 0; +} + +#define SWIG_GetModule(clientdata) SWIG_JSC_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_JSC_SetModule(pointer) + +%} + +%insert(init) "swiginit.swg" diff --git a/Lib/javascript/jsc/javascriptkw.swg b/Lib/javascript/jsc/javascriptkw.swg new file mode 100644 index 000000000..c3c118391 --- /dev/null +++ b/Lib/javascript/jsc/javascriptkw.swg @@ -0,0 +1,40 @@ +#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_ +#define JAVASCRIPT_JAVASCRIPTKW_SWG_ + +/* Warnings for Java keywords */ +#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s") `x` + +/* Taken from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Reserved_Words */ + +JAVASCRIPTKW(break); +JAVASCRIPTKW(case); +JAVASCRIPTKW(catch); +JAVASCRIPTKW(continue); +JAVASCRIPTKW(default); +JAVASCRIPTKW(delete); +JAVASCRIPTKW(do); +JAVASCRIPTKW(else); +JAVASCRIPTKW(finally); +JAVASCRIPTKW(for); +JAVASCRIPTKW(function); +JAVASCRIPTKW(if); +JAVASCRIPTKW(in); +JAVASCRIPTKW(instanceof); +JAVASCRIPTKW(new); +JAVASCRIPTKW(return); +JAVASCRIPTKW(switch); +JAVASCRIPTKW(this); +JAVASCRIPTKW(throw); +JAVASCRIPTKW(try); +JAVASCRIPTKW(typeof); +JAVASCRIPTKW(var); +JAVASCRIPTKW(void); +JAVASCRIPTKW(while); +JAVASCRIPTKW(with); + +/* others bad names if any*/ +// for example %namewarn("321:clone() is a javascript bad method name") *::clone(); + +#undef JAVASCRIPTKW + +#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_ diff --git a/Lib/javascript/jsc/javascriptprimitives.swg b/Lib/javascript/jsc/javascriptprimitives.swg new file mode 100644 index 000000000..f61e83272 --- /dev/null +++ b/Lib/javascript/jsc/javascriptprimitives.swg @@ -0,0 +1,104 @@ +%fragment(SWIG_From_frag(bool),"header") { +SWIGINTERNINLINE +JSValueRef SWIG_From_dec(bool)(bool value) +{ + return JSValueMakeBoolean(context, value); +} +} + +%fragment(SWIG_AsVal_frag(bool),"header", + fragment=SWIG_AsVal_frag(long)) { +SWIGINTERN +int SWIG_AsVal_dec(bool)(JSValueRef obj, bool *val) +{ + if(!JSValueIsBoolean(context, obj)) { + return SWIG_ERROR; + } + if (val) *val = JSValueToBoolean(context, obj); + return SWIG_OK; +} +} + +%fragment(SWIG_From_frag(int),"header") { +SWIGINTERNINLINE JSValueRef + SWIG_From_dec(int)(int value) +{ + return JSValueMakeNumber(context, value); +} +} + +%fragment(SWIG_From_frag(long),"header") { +SWIGINTERNINLINE JSValueRef + SWIG_From_dec(long)(long value) +{ + return JSValueMakeNumber(context, value); +} +} + +%fragment(SWIG_AsVal_frag(long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN int +SWIG_AsVal_dec(long)(JSValueRef obj, long* val) +{ + if (!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = (long) JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} + +/* unsigned long */ + +%fragment(SWIG_From_frag(unsigned long),"header", + fragment=SWIG_From_frag(long)) { +SWIGINTERNINLINE JSValueRef +SWIG_From_dec(unsigned long)(unsigned long value) +{ + return (value > LONG_MAX) ? + JSValueMakeNumber(context, value) : JSValueMakeNumber(context, %numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN int +SWIG_AsVal_dec(unsigned long)(JSValueRef obj, unsigned long *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + + long longVal = (long) JSValueToNumber(context, obj, NULL); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +%fragment(SWIG_From_frag(double),"header") { +SWIGINTERN JSValueRef +SWIG_From_dec(double) (double val) +{ + return JSValueMakeNumber(context, val); +} +} + +%fragment(SWIG_AsVal_frag(double),"header") { +SWIGINTERN int +SWIG_AsVal_dec(double)(JSValueRef obj, double *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} diff --git a/Lib/javascript/jsc/javascriptruntime.swg b/Lib/javascript/jsc/javascriptruntime.swg new file mode 100644 index 000000000..1eddf93f1 --- /dev/null +++ b/Lib/javascript/jsc/javascriptruntime.swg @@ -0,0 +1,175 @@ +/* ----------------------------------------------------------------------------- + * javascriptruntime.swg + * + * Javascript support code + * ----------------------------------------------------------------------------- */ + +%insert(runtime) %{ +#include +#include +#include +#include +#include +#include +%} + +%insert(runtime) "swigrun.swg"; /* SWIG API */ +%insert(runtime) "swigerrors.swg"; /* SWIG errors */ + +%insert(runtime) %{ +#define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_fail goto fail + +#define SWIG_JSC_FROM_DECL_ARGS(arg1) (JSContextRef context, arg1) +#define SWIG_JSC_FROM_CALL_ARGS(arg1) (context, arg1) +#define SWIG_JSC_AS_DECL_ARGS(arg1, arg2) (JSContextRef context, arg1, arg2) +#define SWIG_JSC_AS_CALL_ARGS(arg1, arg2) (context, arg1, arg2) +%} + +%insert(runtime) %{ +typedef struct { + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; +}SWIG_PRV_DATA; +%} + +%insert(runtime) %{ + +void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) { + JSStringRef message = JSStringCreateWithUTF8CString(type); + *exception = JSValueMakeString(context, message); + JSStringRelease(message); +} + +void SWIG_JSC_exception(JSContextRef context, JSValueRef *exception, int code, const char* msg) { + SWIG_Javascript_Raise(context, exception, msg); +} + +%} + +%insert(runtime) %{ + +JSValueRef _wrap_SwigObject_disown(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) JSObjectGetPrivate(obj); + + cdata->swigCMemOwn = false; + + jsresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef _wrap_SwigObject_getCPtr(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + long result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA*) JSObjectGetPrivate(obj); + + result = (long) cdata->swigCObject; + jsresult = JSValueMakeNumber(context, result); + + return jsresult; +} + +JSStaticValue _SwigObject_values[] = { + { + 0, 0, 0, 0 + } +}; + +JSStaticFunction _SwigObject_functions[] = { + { + "disown",_wrap_SwigObject_disown, kJSPropertyAttributeNone + },{ + "getCPtr",_wrap_SwigObject_getCPtr, kJSPropertyAttributeNone + }, + { + 0, 0, 0 + } +}; + +JSClassDefinition _SwigObject_objectDefinition; + +JSClassRef _SwigObject_classRef; + +%} + + +%insert(runtime) %{ +int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef objRef, void** ptr, swig_type_info *info, int flags) { + SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) JSObjectGetPrivate(objRef); + if(cdata == NULL) { + return SWIG_ERROR; + } + if(cdata->info != info) { + bool type_valid = false; + swig_cast_info *t = info->cast; + while(t != NULL) { + if(t->type == cdata->info) { + type_valid = true; + break; + } + t = t->next; + } + if(!type_valid) { + return SWIG_TypeError; + } + } + + *ptr = cdata->swigCObject; + + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + + return SWIG_OK; +} + +int SWIG_JSC_ConvertPtr(JSContextRef context, JSValueRef valRef, void** ptr, swig_type_info *info, int flags) { + if(!JSValueIsObject(context, valRef)) { + return SWIG_TypeError; + } + + JSObjectRef objRef = JSValueToObject(context, valRef, NULL); + if(objRef == NULL) { + return SWIG_ERROR; + } + + return SWIG_JSC_ConvertInstancePtr(context, objRef, ptr, info, flags); +} + +JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_info *info, int flags) { + + JSClassRef classRef; + if(info->clientdata == NULL) { + classRef = _SwigObject_classRef; + } else { + classRef = (JSClassRef) info->clientdata; + } + + JSObjectRef result = JSObjectMake(context, classRef, NULL); + + SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) malloc(sizeof(SWIG_PRV_DATA)); + cdata->swigCObject = ptr; + cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; + cdata->info = info; + + JSObjectSetPrivate(result, cdata); + + return result; +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_JSC_ConvertPtr(context, obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_JSC_NewPointerObj(context, ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) + +%} diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg new file mode 100644 index 000000000..f97e84cd0 --- /dev/null +++ b/Lib/javascript/jsc/javascriptstrings.swg @@ -0,0 +1,171 @@ +/* ------------------------------------------------------------ + * utility methods for char strings + * ------------------------------------------------------------ */ +%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERN int +SWIG_JSC_AsCharPtrAndSize(JSContextRef context, JSValueRef valRef, char** cptr, size_t* psize, int *alloc) +{ + if(JSValueIsString(context, valRef)) { + JSStringRef js_str = JSValueToStringCopy(context, valRef, NULL); + size_t len = JSStringGetMaximumUTF8CStringSize(js_str); + size_t abs_len = JSStringGetLength(js_str); + char* cstr = (char*) malloc(len * sizeof(char)); + JSStringGetUTF8CString(js_str, cstr, len); + + if(alloc) *alloc = SWIG_NEWOBJ; + if(psize) *psize = abs_len + 1; + if(cptr) *cptr = cstr; + + return SWIG_OK; + } else { + if(JSValueIsObject(context, valRef)) { + JSObjectRef obj = JSValueToObject(context, valRef, NULL); + // try if the object is a wrapped char[] + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + return SWIG_TypeError; + } else { + return SWIG_TypeError; + } + } +} +} + +%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERNINLINE JSValueRef +SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + // TODO: handle extra long strings + //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + //return pchar_descriptor ? + // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); + return JSValueMakeUndefined(context); + } else { + JSStringRef jsstring = JSStringCreateWithUTF8CString(carray); + JSValueRef result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return result; + } + } else { + return JSValueMakeUndefined(context); + } +} +} + +%define %_typemap2_string(StringCode, CharCode, + Char, CharName, + SWIG_AsCharPtrAndSize, + SWIG_FromCharPtrAndSize, + SWIG_CharPtrLen, + SWIG_NewCopyCharArray, + SWIG_DeleteCharArray, + FragLimits, CHAR_MIN, CHAR_MAX) + +%fragment("SWIG_From"#CharName"Ptr","header",fragment=#SWIG_FromCharPtrAndSize) { +SWIGINTERNINLINE SWIG_Object +SWIG_JSC_From##CharName##Ptr(JSContextRef context, const Char *cptr) +{ + return SWIG_JSC_FromCharPtrAndSize(context, cptr, (cptr ? SWIG_CharPtrLen(cptr) : 0)); +} +} + +%fragment("SWIG_From"#CharName"Array","header",fragment=#SWIG_FromCharPtrAndSize) { +SWIGINTERNINLINE SWIG_Object +SWIG_JSC_From##CharName##Array(JSContextRef context, const Char *cptr, size_t size) +{ + return SWIG_JSC_FromCharPtrAndSize(context, cptr, size); +} +} + +%fragment("SWIG_As" #CharName "Ptr","header",fragment=#SWIG_AsCharPtrAndSize) { +%define_as(SWIG_As##CharName##Ptr(obj, val, alloc), SWIG_JSC_AsCharPtrAndSize(context, obj, val, NULL, alloc)) +} + +%fragment("SWIG_As" #CharName "Array","header",fragment=#SWIG_AsCharPtrAndSize) { +SWIGINTERN int +SWIG_JSC_As##CharName##Array(JSContextRef context, SWIG_Object obj, Char *val, size_t size) +{ + Char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ; + int res = SWIG_JSC_AsCharPtrAndSize(context, obj, &cptr, &csize, &alloc); + if (SWIG_IsOK(res)) { + if ((csize == size + 1) && cptr && !(cptr[csize-1])) --csize; + if (csize <= size) { + if (val) { + if (csize) memcpy(val, cptr, csize*sizeof(Char)); + if (csize < size) memset(val + csize, 0, (size - csize)*sizeof(Char)); + } + if (alloc == SWIG_NEWOBJ) { + SWIG_DeleteCharArray(cptr); + res = SWIG_DelNewMask(res); + } + return res; + } + if (alloc == SWIG_NEWOBJ) SWIG_DeleteCharArray(cptr); + } + return SWIG_TypeError; +} + +#define SWIG_As##CharName##Array(obj, val, size) SWIG_JSC_As##CharName##Array(context, obj, val, size) +} + +/* Char */ + +%fragment(SWIG_From_frag(Char),"header",fragment=#SWIG_FromCharPtrAndSize) { +SWIGINTERNINLINE SWIG_Object +SWIG_From_dec(Char)(Char c) +{ + return SWIG_JSC_FromCharPtrAndSize(context, &c,1); +} +} + +%fragment(SWIG_AsVal_frag(Char),"header", + fragment="SWIG_As"#CharName"Array", + fragment=FragLimits, + fragment=SWIG_AsVal_frag(long)) { +SWIGINTERN int +SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val) +{ + int res = SWIG_As##CharName##Array(obj, val, 1); + if (!SWIG_IsOK(res)) { + long v; + res = SWIG_AddCast(SWIG_AsVal(long)(obj, &v)); + if (SWIG_IsOK(res)) { + if ((CHAR_MIN <= v) && (v <= CHAR_MAX)) { + if (val) *val = %numeric_cast(v, Char); + } else { + res = SWIG_OverflowError; + } + } + } + return res; +} +} + +%_typemap_string(StringCode, + Char, + SWIG_AsCharPtrAndSize, + SWIG_FromCharPtrAndSize, + SWIG_CharPtrLen, + SWIG_As##CharName##Ptr, + SWIG_From##CharName##Ptr, + SWIG_As##CharName##Array, + SWIG_NewCopyCharArray, + SWIG_DeleteCharArray) + +%enddef + +%insert(runtime) %{ +#define SWIG_AsCharPtrAndSize(val, cptr, psize, alloc) SWIG_JSC_AsCharPtrAndSize(context, val, cptr, psize, alloc) +#define SWIG_FromCharPtrAndSize(cptr, size) SWIG_JSC_FromCharPtrAndSize(context, cptr, size) +#define SWIG_FromCharPtr(cptr) SWIG_JSC_FromCharPtr(context, cptr) +%} diff --git a/Lib/javascript/jsc/javascripttypemaps.swg b/Lib/javascript/jsc/javascripttypemaps.swg new file mode 100644 index 000000000..e8711cfc5 --- /dev/null +++ b/Lib/javascript/jsc/javascripttypemaps.swg @@ -0,0 +1,26 @@ + +#define SWIG_FROM_DECL_ARGS SWIG_JSC_FROM_DECL_ARGS +#define SWIG_FROM_CALL_ARGS SWIG_JSC_FROM_CALL_ARGS +#define SWIG_AS_DECL_ARGS SWIG_JSC_AS_DECL_ARGS +#define SWIG_AS_CALL_ARGS SWIG_JSC_AS_CALL_ARGS +#define SWIG_Object JSValueRef +#define VOID_Object JSValueMakeUndefined(context) +#define SWIG_AppendOutput(result, obj) +#define SWIG_SetConstant(name, obj) +#define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise(context, exception, type) + +%include + +/* Include fundamental fragemt definitions */ +%include + +/* Python fragments for fundamental types */ +%include + +/* override some of the macros in global valtypes.swg */ +%include + +%include + +/* Include the unified typemap library */ +%include diff --git a/Lib/javascript/jsc/javascriptvaltypes.swg b/Lib/javascript/jsc/javascriptvaltypes.swg new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Lib/javascript/jsc/javascriptvaltypes.swg @@ -0,0 +1 @@ + diff --git a/Lib/javascript/jsc/std_common.i b/Lib/javascript/jsc/std_common.i new file mode 100755 index 000000000..cee11e8ca --- /dev/null +++ b/Lib/javascript/jsc/std_common.i @@ -0,0 +1,5 @@ +%include + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; + diff --git a/Lib/javascript/jsc/std_complex.i b/Lib/javascript/jsc/std_complex.i new file mode 100644 index 000000000..088a4fe7b --- /dev/null +++ b/Lib/javascript/jsc/std_complex.i @@ -0,0 +1,19 @@ +/* + * STD C++ complex typemaps + */ + +%include + +%{ +#include +%} + +/* defining the complex as/from converters */ + +%swig_cplxdbl_convn(std::complex, std::complex, std::real, std::imag) +%swig_cplxflt_convn(std::complex, std::complex, std::real, std::imag) + +/* defining the typemaps */ + +%typemaps_primitive(%checkcode(CPLXDBL), std::complex); +%typemaps_primitive(%checkcode(CPLXFLT), std::complex); diff --git a/Lib/javascript/jsc/std_except.i b/Lib/javascript/jsc/std_except.i new file mode 100644 index 000000000..af98428f6 --- /dev/null +++ b/Lib/javascript/jsc/std_except.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/std_map.i b/Lib/javascript/jsc/std_map.i new file mode 100755 index 000000000..e7812f38a --- /dev/null +++ b/Lib/javascript/jsc/std_map.i @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------------- + * std_map.i + * + * SWIG typemaps for std::map + * ----------------------------------------------------------------------------- */ + +%include + +// ------------------------------------------------------------------------ +// std::map +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class map { + // add typemaps here + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + map(); + map(const map &); + + unsigned int size() const; + bool empty() const; + void clear(); + %extend { + const T& get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + void set(const K& key, const T& x) { + (*self)[key] = x; + } + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + }; + +// Legacy macros (deprecated) +%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) +#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary" +%enddef + +} diff --git a/Lib/javascript/jsc/std_pair.i b/Lib/javascript/jsc/std_pair.i new file mode 100755 index 000000000..fe45ee676 --- /dev/null +++ b/Lib/javascript/jsc/std_pair.i @@ -0,0 +1,34 @@ +/* ----------------------------------------------------------------------------- + * std_pair.i + * + * SWIG typemaps for std::pair + * ----------------------------------------------------------------------------- */ + +%include +%include + +// ------------------------------------------------------------------------ +// std::pair +// ------------------------------------------------------------------------ + +%{ +#include +%} + +namespace std { + + template struct pair { + + pair(); + pair(T first, U second); + pair(const pair& p); + + template pair(const pair &p); + + T first; + U second; + }; + + // add specializations here + +} diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i new file mode 100755 index 000000000..9fbee75ef --- /dev/null +++ b/Lib/javascript/jsc/std_string.i @@ -0,0 +1,71 @@ +/* ----------------------------------------------------------------------------- + * std_string.i + * + * Typemaps for std::string and const std::string& + * These are mapped to a JSCore String and are passed around by value. + * + * To use non-const std::string references use the following %apply. Note + * that they are passed by value. + * %apply const std::string & {std::string &}; + * ----------------------------------------------------------------------------- */ + +%{ +#include +%} + +namespace std { + +%naturalvar string; + +class string; + +// string + +%typemap(in) string +%{ if (!$input) { + // TODO: Throw exception? + return NULL; + } + JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); + size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); + char* $1_cstr = (char *)malloc($1_strsize * sizeof(char)); + JSStringGetUTF8CString($1_str, $1_cstr, $1_strsize); + $1 = std::string($1_cstr); +%} + +%typemap(out) string %{ + JSStringRef jsstring = JSStringCreateWithUTF8CString($1.c_str()); + $result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); +%} + +%typemap(freearg) string //TODO: Not working: A memory leak +%{ free($1_cstr); %} + +//%typemap(typecheck) string = char *; + +// const string & +%typemap(in) const string & +%{ if (!$input) { + // TODO: Throw exception? + return NULL; + } + JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); + size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); + char* $1_cstr = (char *)malloc($1_strsize * sizeof(char)); + JSStringGetUTF8CString($1_str, $1_cstr, $1_strsize); + $1 = new std::string($1_cstr); +%} + +%typemap(out) const string & %{ + JSStringRef jsstring = JSStringCreateWithUTF8CString($1.c_str()); + $result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); +%} + +%typemap(freearg) const string & //TODO: Not working: A memory leak +%{ free($1_cstr); %} + +//%typemap(typecheck) const string & = char *; + +} diff --git a/Lib/javascript/jsc/std_vector.i b/Lib/javascript/jsc/std_vector.i new file mode 100755 index 000000000..3f29b19c7 --- /dev/null +++ b/Lib/javascript/jsc/std_vector.i @@ -0,0 +1,85 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * ----------------------------------------------------------------------------- */ + +%include + +%{ +#include +#include +%} + +namespace std { + + template class vector { + public: + typedef size_t size_type; + typedef T value_type; + typedef const value_type& const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + public: + typedef size_t size_type; + typedef bool value_type; + typedef bool const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i +%include +%include +%include +%include + diff --git a/Lib/typemaps/strings.swg b/Lib/typemaps/strings.swg index 55e9d2bb5..eea913b60 100644 --- a/Lib/typemaps/strings.swg +++ b/Lib/typemaps/strings.swg @@ -493,7 +493,7 @@ * --- String fragment methods --- * ------------------------------------------------------------ */ - +#ifndef %_typemap2_string %define %_typemap2_string(StringCode, CharCode, Char, CharName, SWIG_AsCharPtrAndSize, @@ -593,7 +593,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val) SWIG_DeleteCharArray) %enddef - +#endif /* ------------------------------------------------------------ * String typemaps and fragments, with default allocators diff --git a/Makefile.in b/Makefile.in index 644275773..adc971455 100644 --- a/Makefile.in +++ b/Makefile.in @@ -77,6 +77,7 @@ skip-uffi = test -n "@SKIP_UFFI@" skip-r = test -n "@SKIP_R@" skip-go = test -n "@SKIP_GO@" skip-d = test -n "@SKIP_D@" +skip-javascript = test -n "@SKIP_JAVASCRIPT@" # Additional dependencies for some tests skip-gcj = test -n "@SKIP_GCJ@" @@ -119,6 +120,7 @@ check-aliveness: @$(skip-r) || ./$(TARGET) -r -help @$(skip-go) || ./$(TARGET) -go -help @$(skip-d) || ./$(TARGET) -d -help + @$(skip-javascript)|| ./$(TARGET) -d -help check-ccache: test -z "$(ENABLE_CCACHE)" || (cd $(CCACHE) && $(MAKE) check) @@ -147,7 +149,8 @@ check-examples: \ check-cffi-examples \ check-r-examples \ check-go-examples \ - check-d-examples + check-d-examples \ + check-javascript-examples tcl_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list) perl5_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list) @@ -172,6 +175,7 @@ cffi_examples := r_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/r/check.list) go_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list) d_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list) +javascript_examples:= # all examples check-%-examples : @@ -225,7 +229,8 @@ check-test-suite: \ check-chicken-test-suite \ check-r-test-suite \ check-go-test-suite \ - check-d-test-suite + check-d-test-suite \ + check-javascript-test-suite check-%-test-suite: @if test -z "$(skip-$*)"; then \ @@ -278,7 +283,8 @@ all-test-suite: \ all-chicken-test-suite \ all-r-test-suite \ all-go-test-suite \ - all-d-test-suite + all-d-test-suite \ + all-javascript-test-suite all-%-test-suite: @$(MAKE) -k -s check-$*-test-suite ACTION=all @@ -307,7 +313,8 @@ broken-test-suite: \ broken-chicken-test-suite \ broken-r-test-suite \ broken-go-test-suite \ - broken-d-test-suite + broken-d-test-suite \ + broken-javascript-test-suite broken-%-test-suite: @$(MAKE) -k -s check-$*-test-suite ACTION=broken @@ -424,7 +431,7 @@ install-main: @$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@ lib-languages = gcj typemaps tcl perl5 python guile java mzscheme ruby php ocaml octave \ - pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d + pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d javascript javascript/jsc lib-modules = std diff --git a/Source/DOH/fio.c b/Source/DOH/fio.c index 2ef605c32..4e91a1b51 100644 --- a/Source/DOH/fio.c +++ b/Source/DOH/fio.c @@ -490,6 +490,7 @@ int DohCopyto(DOH *in, DOH *out) { return nbytes; } } + return nbytes; } @@ -588,4 +589,5 @@ DOH *DohReadline(DOH *in) { Putc(c, s); n++; } + return s; } diff --git a/Source/Makefile.am b/Source/Makefile.am index 85530fd45..420fd6d3f 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -50,7 +50,6 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/java.cxx \ Modules/lang.cxx \ Modules/javascript.cxx \ - Modules/javascript_emitter.cxx \ Modules/javascript_v8.cxx \ Modules/lua.cxx \ Modules/main.cxx \ diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx index efcf9a352..7d7f66eaf 100644 --- a/Source/Modules/emit.cxx +++ b/Source/Modules/emit.cxx @@ -470,6 +470,7 @@ String *emit_action(Node *n) { if (catchlist) { int unknown_catch = 0; + int has_varargs = 0; Printf(eaction, "}\n"); for (Parm *ep = catchlist; ep; ep = nextSibling(ep)) { String *em = Swig_typemap_lookup("throws", ep, "_e", 0); @@ -480,6 +481,7 @@ String *emit_action(Node *n) { Printf(eaction, "catch(%s) {", SwigType_str(et, "_e")); } else if (SwigType_isvarargs(etr)) { Printf(eaction, "catch(...) {"); + has_varargs = 1; } else { Printf(eaction, "catch(%s) {", SwigType_str(et, "&_e")); } @@ -490,8 +492,8 @@ String *emit_action(Node *n) { unknown_catch = 1; } } - if (unknown_catch) { - Printf(eaction, "catch(...) { throw; }\n"); + if (unknown_catch && !has_varargs) { + Printf(eaction, "catch(...) { throw; }\n"); } } diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 64d943453..009bcc400 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -4,38 +4,1328 @@ #include #include -#include "javascript_emitter.h" +/** + * A class that wraps a code snippet used as template for code generation. + */ +class Template { -extern JSEmitter* create_v8_emitter(); +public: + Template(const String *code); + + Template(const String *code, const String *templateName, bool debug = false); + + ~Template(); + + String *str(); + + Template & replace(const String *pattern, const String *repl); + +private: + String *code; + String *templateName; + bool debug; +}; + +class JSEmitter { + +public: + + enum JSEmitterType { + JavascriptCore, + V8, + QtScript + }; + + JSEmitter(); + + virtual ~ JSEmitter(); + + /** + * Opens output files and temporary output DOHs. + */ + virtual int initialize(Node *n) = 0; + + /** + * Writes all collected code into the output file(s). + */ + virtual int dump(Node *n) = 0; + + /** + * Cleans up all open output DOHs. + */ + virtual int close() = 0; + + /** + * Switches the context for code generation. + * + * Classes, global variables and global functions may need to + * be registered in certain static tables. + * This method should be used to switch output DOHs correspondingly. + */ + virtual int switchNamespace(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the classHandler. + */ + virtual int enterClass(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the end of the classHandler. + */ + virtual int exitClass(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the variableHandler. + */ + virtual int enterVariable(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the end of the variableHandler. + */ + virtual int exitVariable(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the functionHandler. + */ + virtual int enterFunction(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the end of the functionHandler. + */ + virtual int exitFunction(Node *) { + return SWIG_OK; + }; + + /** + * Invoked by functionWrapper callback after call to Language::functionWrapper. + */ + virtual int emitWrapperFunction(Node *n); + + /** + * Invoked from constantWrapper after call to Language::constantWrapper. + **/ + virtual int emitConstant(Node *n) = 0; + + /** + * Registers a given code snippet for a given key name. + * + * This method is called by the fragmentDirective handler + * of the JAVASCRIPT language module. + **/ + int registerTemplate(const String *name, const String *code); + + /** + * Retrieve the code template registered for a given name. + */ + Template getTemplate(const String *name); + + void enableDebug(); + + void setStaticFlag(bool is_static = false); + +protected: + + virtual int emitCtor(Node *n) = 0; + + virtual int emitDtor(Node *n) = 0; + + virtual int emitFunction(Node *n, bool is_member) = 0; + + virtual int emitGetter(Node *n, bool is_member) = 0; + + virtual int emitSetter(Node *n, bool is_member) = 0; + + bool isSetterMethod(Node *n); + + Node *getBaseClass(Node *n); + + const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0); + + void enableDebugTemplates(); + +protected: + + // empty string used at different places in the code + String *empty_string; + + Hash *templates; + + Wrapper *current_wrapper; + + bool is_static; + + bool debug; +}; + +class JSCEmitter:public JSEmitter { + +private: + + enum MarshallingMode { + Setter, + Getter, + Ctor, + Function + }; + +public: + + JSCEmitter(); + + virtual ~ JSCEmitter(); + + virtual int initialize(Node *n); + + virtual int dump(Node *n); + + virtual int close(); + + +protected: + + virtual int emitCtor(Node *n); + + virtual int emitDtor(Node *n); + + virtual int enterVariable(Node *n); + + virtual int exitVariable(Node *n); + + virtual int enterFunction(Node *n); + + virtual int exitFunction(Node *n); + + virtual int enterClass(Node *n); + + virtual int exitClass(Node *n); + + virtual int emitFunction(Node *n, bool is_member); + + virtual int emitFunctionDispatcher(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, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static = false); + + void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); + + Parm *skipIgnoredArgs(Parm *p); + + virtual int switchNamespace(Node *n); + + virtual int createNamespace(String *scope); + + virtual Hash *createNamespaceEntry(const char *name, const char *parent); + + virtual int emitNamespaces(); + + virtual int emitConstant(Node *n); + +private: + + File *f_wrap_cpp; + File *f_runtime; + File *f_header; + File *f_wrappers; + File *f_init; + + String *NULL_STR; + String *VETO_SET; + const char *GLOBAL_STR; + + // contains context specific structs + // to allow generation different class definition tables + // which are switched on namespace change + Hash *namespaces; + Hash *current_namespace; + + // dynamically filled code parts + + String *create_namespaces_code; + String *register_namespaces_code; + + String *current_class_functions; + String *class_variables_code; + String *class_static_functions_code; + String *class_static_variables_code; + + String *ctor_wrappers; + String *ctor_dispatcher_code; + + String *initializer_code; + String *function_dispatcher_code; + + // state variables + String *current_propertyname; + String *current_getter; + String *current_setter; + bool is_immutable; + + String *current_classname; + String *current_classname_mangled; + String *current_classtype; + String *current_classtype_mangled; + String *current_functionwrapper; + String *current_functionname; +}; + +/* ----------------------------------------------------------------------------- + * JSEmitter() + * ----------------------------------------------------------------------------- */ + +JSEmitter::JSEmitter() +: empty_string(NewString("")), current_wrapper(NULL), is_static(false), debug(false) { + templates = NewHash(); +} + +/* ----------------------------------------------------------------------------- + * ~JSEmitter() + * ----------------------------------------------------------------------------- */ + +JSEmitter::~JSEmitter() { + Delete(empty_string); + Delete(templates); +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::RegisterTemplate() : Registers a code template + * ----------------------------------------------------------------------------- */ + +int JSEmitter::registerTemplate(const String *name, const String *code) { + return Setattr(templates, name, code); +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::GetTemplate() : Retrieves a registered a code template + * ----------------------------------------------------------------------------- */ + +Template JSEmitter::getTemplate(const String *name) { + String *templ = Getattr(templates, name); + + if (!templ) { + Printf(stderr, "Could not find template %s\n.", name); + SWIG_exit(EXIT_FAILURE); + } + + Template t(templ, name, debug); + + return t; +} + +void JSEmitter::enableDebug() { + debug = true; +} + +void JSEmitter::setStaticFlag(bool _is_static) { + is_static = _is_static; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::typemapLookup() + * + * n - for input only and must contain info for Getfile(n) and Getline(n) to work + * tmap_method - typemap method name + * type - typemap type to lookup + * warning - warning number to issue if no typemaps found + * typemap_attributes - the typemap attributes are attached to this node and will + * also be used for temporary storage if non null + * return is never NULL, unlike Swig_typemap_lookup() + * ----------------------------------------------------------------------------- */ + +const String *JSEmitter::typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes) { + Node *node = !typemap_attributes ? NewHash() : typemap_attributes; + Setattr(node, "type", type); + Setfile(node, Getfile(n)); + Setline(node, Getline(n)); + const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); + if (!tm) { + tm = empty_string; + if (warning != WARN_NONE) { + Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); + } + } + if (!typemap_attributes) { + Delete(node); + } + return tm; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::getBaseClass() : the node of the base class or NULL + * ----------------------------------------------------------------------------- */ + +Node *JSEmitter::getBaseClass(Node *n) { + // retrieve the first base class that is not %ignored + List *baselist = Getattr(n, "bases"); + if (baselist) { + Iterator base = First(baselist); + while (base.item && GetFlag(base.item, "feature:ignore")) { + base = Next(base); + } + + return base.item; + } + + return NULL; +} + + /* ----------------------------------------------------------------------------- + * JSEmitter::emitWrapperFunction() : dispatches emitter functions + * ----------------------------------------------------------------------------- */ + +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) { + bool is_member = GetFlag(n, "ismember"); + if (Cmp(kind, "function") == 0) { + ret = emitFunction(n, is_member); + + } else if (Cmp(kind, "variable") == 0) { + if (isSetterMethod(n)) { + ret = emitSetter(n, is_member); + + } else { + ret = emitGetter(n, is_member); + + } + } else { + Printf(stderr, "Warning: unsupported wrapper function type\n"); + Swig_print_node(n); + + ret = SWIG_ERROR; + } + } else { + String *view = Getattr(n, "view"); + + if (Cmp(view, "constructorHandler") == 0) { + ret = emitCtor(n); + + } else if (Cmp(view, "destructorHandler") == 0) { + ret = emitDtor(n); + + } else { + Printf(stderr, "Warning: unsupported wrapper function type"); + Swig_print_node(n); + ret = SWIG_ERROR; + } + } + + DelWrapper(current_wrapper); + current_wrapper = 0; + + return ret; +} + +/* ----------------------------------------------------------------------------- + * __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); +} + +/* ----------------------------------------------------------------------------- + * Template::Template() : creates a Template class for given template code + * ----------------------------------------------------------------------------- */ + +Template::Template(const String *code_) { + + if (!code_) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + debug = false; + code = NewString(code_); + templateName = NewString(""); +} + +Template::Template(const String *code_, const String *templateName_, bool debug_) { + + if (!code_) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + + code = NewString(code_); + templateName = NewString(templateName_); + debug = debug_; +} + + +/* ----------------------------------------------------------------------------- + * Template::~Template() : cleans up of Template. + * ----------------------------------------------------------------------------- */ + +Template::~Template() { + Delete(code); + Delete(templateName); +} + +/* ----------------------------------------------------------------------------- + * String* Template::str() : retrieves the current content of the template. + * ----------------------------------------------------------------------------- */ + +String *Template::str() { + if (debug) { + String *pre_code = NewString(""); + String *post_code = NewString(""); + String *debug_code = NewString(""); + Printf(pre_code, "//begin fragment(\"%s\")\n", templateName); + Printf(post_code, "//end fragment(\"%s\")\n", templateName); + Printf(debug_code, "%s\n%s\n%s", pre_code, code, post_code); + + Delete(code); + Delete(pre_code); + Delete(post_code); + + code = debug_code; + } + return code; +} + +/* ----------------------------------------------------------------------------- + * Template& Template::replace(const String* pattern, const String* repl) : + * + * replaces all occurances of a given pattern with a given replacement. + * + * - pattern: the pattern to be replaced + * - repl: the replacement string + * - returns a reference to the Template to allow chaining of methods. + * ----------------------------------------------------------------------------- */ + +Template & Template::replace(const String *pattern, const String *repl) { + ::Replaceall(code, pattern, repl); + return *this; +} + +JSCEmitter::JSCEmitter() +: +JSEmitter(), NULL_STR(NewString("NULL")), current_classname(NULL), f_header(NULL), current_classtype(NULL), f_runtime(NULL), current_class_functions(NULL), +f_wrappers(NULL), current_getter(NULL), is_immutable(NULL), create_namespaces_code(NULL), current_classname_mangled(NULL), initializer_code(NULL), +register_namespaces_code(NULL), f_wrap_cpp(NULL), current_setter(NULL), ctor_dispatcher_code(NULL), current_functionwrapper(NULL), +class_static_functions_code(NULL), namespaces(NULL), function_dispatcher_code(NULL), namespaces(NULL), GLOBAL_STR(NULL), current_propertyname(NULL), +current_namespace(NULL), ctor_wrappers(NULL), class_static_variables_code(NULL), class_variables_code(NULL), f_init(NULL), current_functionname(NULL), +current_classtype_mangled(NULL), VETO_SET(NewString("JS_veto_set_variable")) { +} + +JSCEmitter::~JSCEmitter() { + Delete(NULL_STR); + Delete(VETO_SET); +} + +/* --------------------------------------------------------------------- + * skipIgnoredArgs() + * --------------------------------------------------------------------- */ + +Parm *JSCEmitter::skipIgnoredArgs(Parm *p) { + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + return p; +} + +/* --------------------------------------------------------------------- + * marshalInputArgs() + * + * Process all of the arguments passed into the argv array + * and convert them into C/C++ function arguments using the + * supplied typemaps. + * --------------------------------------------------------------------- */ + +void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { + String *tm; + Parm *p; + + int startIdx = 0; + if (is_member && !is_static) + startIdx = 1; + + + 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: + if (is_member && !is_static && i == 0) { + Printv(arg, "thisObject", 0); + } else { + Printf(arg, "argv[%d]", i - startIdx); + } + + break; + case Setter: + if (is_member && !is_static && i == 0) { + Printv(arg, "thisObject", 0); + } else { + Printv(arg, "value", 0); + } + break; + case Ctor: + Printf(arg, "argv[%d]", i); + break; + 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)); + } + Delete(arg); + } +} + +/* --------------------------------------------------------------------- +* 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"); + // TODO: May not be the correct way + 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"); + } + + 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); +} + +int JSCEmitter::initialize(Node *n) { + + /* Get the output file name */ + String *outfile = Getattr(n, "outfile"); + + /* Initialize I/O */ + f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); + if (!f_wrap_cpp) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } + + /* Initialization of members */ + f_runtime = NewString(""); + f_init = NewString(""); + f_header = NewString(""); + f_wrappers = NewString(""); + + create_namespaces_code = NewString(""); + register_namespaces_code = NewString(""); + initializer_code = 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); + Swig_register_filebyname("wrapper", f_wrappers); + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("init", f_init); + + return SWIG_OK; +} + +int JSCEmitter::dump(Node *n) { + /* Get the module name */ + String *module = Getattr(n, "name"); + + // write the swig banner + Swig_banner(f_wrap_cpp); + + SwigType_emit_type_table(f_runtime, f_wrappers); + + Printv(f_wrap_cpp, f_runtime, "\n", 0); + Printv(f_wrap_cpp, f_header, "\n", 0); + Printv(f_wrap_cpp, f_wrappers, "\n", 0); + + + emitNamespaces(); + + // compose the initializer function using a template + Template initializer(getTemplate("JS_initializer")); + initializer.replace("${modulename}", module) + .replace("${initializercode}", initializer_code) + .replace("${create_namespaces}", create_namespaces_code) + .replace("${register_namespaces}", register_namespaces_code); + Wrapper_pretty_print(initializer.str(), f_init); + + Printv(f_wrap_cpp, f_init, "\n", 0); + + return SWIG_OK; +} + + +int JSCEmitter::close() { + /* strings */ + Delete(f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + + Delete(create_namespaces_code); + Delete(register_namespaces_code); + Delete(initializer_code); + + Delete(namespaces); + + /* files */ + ::Close(f_wrap_cpp); + Delete(f_wrap_cpp); + + return SWIG_OK; +} + +int JSCEmitter::enterFunction(Node *n) { + + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + current_functionname = Getattr(n, "sym:name"); + + if (is_overloaded && function_dispatcher_code == 0) { + function_dispatcher_code = NewString(""); + } + + return SWIG_OK; +} + +int JSCEmitter::exitFunction(Node *n) { + Template t_function = getTemplate("JS_functiondecl"); + + String *functionname = current_functionname; + String *functionwrapper = current_functionwrapper; + + bool is_member = GetFlag(n, "ismember"); + + // handle overloaded functions + // Note: wrappers for overloaded functions are currently + // not made available (e.g., foo_double, foo_int) + // maybe this could be enabled by an extra feature flag + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + if (is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + + functionwrapper = Swig_name_wrapper(Getattr(n, "name")); + // note: set this attribute to transfer ownership + Setattr(n, "wrap:dispatcher", functionwrapper); + + // create dispatcher + emitFunctionDispatcher(n, is_member); + + Delete(function_dispatcher_code); + function_dispatcher_code = 0; + + } else { + + //don't register wrappers of overloaded functions in function tables + return SWIG_OK; + } + } + + t_function.replace("${functionname}", functionname) + .replace("${functionwrapper}", functionwrapper); + + if (is_member) { + + if (Equal(Getattr(n, "storage"), "static")) { + Printv(class_static_functions_code, t_function.str(), 0); + + } else { + Printv(current_class_functions, t_function.str(), 0); + } + + } else { + Printv(Getattr(current_namespace, "functions"), t_function.str(), 0); + } + + return SWIG_OK; +} + +int JSCEmitter::enterVariable(Node *n) { + current_getter = NULL_STR; + current_setter = VETO_SET; + current_propertyname = Swig_scopename_last(Getattr(n, "name")); + is_immutable = GetFlag(n, "wrap:immutable"); + + return SWIG_OK; +} + + +int JSCEmitter::exitVariable(Node *n) { + Template t_variable(getTemplate("JS_variabledecl")); + t_variable.replace("${setname}", current_setter) + .replace("${getname}", current_getter) + .replace("${propertyname}", current_propertyname); + + if (GetFlag(n, "ismember")) { + if (Equal(Getattr(n, "storage"), "static") || (Equal(Getattr(n, "nodeType"), "enumitem"))) { + + Printv(class_static_variables_code, t_variable.str(), 0); + + } else { + Printv(class_variables_code, t_variable.str(), 0); + } + } else { + Printv(Getattr(current_namespace, "values"), t_variable.str(), 0); + } + + return SWIG_OK; +} + +int JSCEmitter::enterClass(Node *n) { + + current_classname = Getattr(n, "sym:name"); + current_classname_mangled = SwigType_manglestr(Getattr(n, "name")); + current_classtype = NewString(Getattr(n, "classtype")); + + String *type = SwigType_manglestr(Getattr(n, "classtypeobj")); + current_classtype_mangled = NewString(""); + Printf(current_classtype_mangled, "p%s", type); + Delete(type); + + Template t_class_defn = getTemplate("JS_class_definition"); + t_class_defn.replace("${classname_mangled}", current_classname_mangled); + Wrapper_pretty_print(t_class_defn.str(), f_wrappers); + + class_variables_code = NewString(""); + current_class_functions = NewString(""); + class_static_variables_code = NewString(""); + class_static_functions_code = NewString(""); + ctor_wrappers = NewString(""); + ctor_dispatcher_code = NewString(""); + + return SWIG_OK; +} + +int JSCEmitter::exitClass(Node *n) { + + String *mangled_name = SwigType_manglestr(Getattr(n, "name")); + + Template t_class_tables(getTemplate("JS_class_tables")); + t_class_tables.replace("${classname_mangled}", mangled_name) + .replace("${jsclassvariables}", class_variables_code) + .replace("${jsclassfunctions}", current_class_functions) + .replace("${jsstaticclassfunctions}", class_static_functions_code) + .replace("${jsstaticclassvariables}", class_static_variables_code); + Wrapper_pretty_print(t_class_tables.str(), f_wrappers); + + /* adds the ctor wrappers at this position */ + // Note: this is necessary to avoid extra forward declarations. + Printv(f_wrappers, ctor_wrappers, 0); + + /* adds the main constructor wrapper function */ + Template t_mainctor(getTemplate("JS_mainctordefn")); + t_mainctor.replace("${classname_mangled}", mangled_name) + .replace("${DISPATCH_CASES}", ctor_dispatcher_code); + Wrapper_pretty_print(t_mainctor.str(), f_wrappers); + + /* adds a class template statement to initializer function */ + Template t_classtemplate(getTemplate("JS_create_class_template")); + + /* prepare registration of base class */ + String *base_name_mangled = NewString("_SwigObject"); + Node *base_class = getBaseClass(n); + if (base_class != NULL) { + Delete(base_name_mangled); + base_name_mangled = SwigType_manglestr(Getattr(base_class, "name")); + } + + t_classtemplate.replace("${classname_mangled}", mangled_name) + .replace("${classtype_mangled}", current_classtype_mangled) + .replace("${base_classname}", base_name_mangled); + Wrapper_pretty_print(t_classtemplate.str(), initializer_code); + +/* + String *clientdata = NewString(""); + Printv(clientdata, mangled_name, "_classRef", 0); + SwigType_remember_clientdata(current_classtype_mangled, clientdata); +*/ + + SwigType_remember_clientdata(current_classtype_mangled, NewString("0")); + + /* adds a class registration statement to initializer function */ + Template t_registerclass(getTemplate("JS_register_class")); + t_registerclass.replace("${classname}", current_classname) + .replace("${classname_mangled}", current_classname_mangled) + .replace("${namespace_mangled}", Getattr(current_namespace, "name_mangled")); + + Wrapper_pretty_print(t_registerclass.str(), initializer_code); + + /* clean up all DOHs */ + Delete(class_variables_code); + Delete(current_class_functions); + Delete(class_static_variables_code); + Delete(class_static_functions_code); + Delete(ctor_wrappers); + Delete(mangled_name); + Delete(ctor_dispatcher_code); + class_variables_code = 0; + current_class_functions = 0; + class_static_variables_code = 0; + class_static_functions_code = 0; + ctor_wrappers = 0; + ctor_dispatcher_code = 0; + + Delete(current_classname); + Delete(current_classname_mangled); + Delete(current_classtype); + Delete(current_classtype_mangled); + + return SWIG_OK; +} + +int JSCEmitter::emitCtor(Node *n) { + + Template t_ctor(getTemplate("JS_ctordefn")); + String *mangled_name = SwigType_manglestr(Getattr(n, "name")); + + String *name = (Getattr(n, "wrap:name")); + String *overname = Getattr(n, "sym:overname"); + String *wrap_name = Swig_name_wrapper(name); + Setattr(n, "wrap:name", wrap_name); + + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_wrapper); + + Printf(current_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); + + Printv(current_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("${type_mangled}", current_classtype_mangled); + + Wrapper_pretty_print(t_ctor.str(), ctor_wrappers); + + String *argcount = NewString(""); + Printf(argcount, "%d", num_args); + + Template t_ctor_case(getTemplate("JS_ctor_dispatch_case")); + t_ctor_case.replace("${classname_mangled}", mangled_name) + .replace("${overloadext}", overname) + .replace("${argcount}", argcount); + Printv(ctor_dispatcher_code, t_ctor_case.str(), 0); + Delete(argcount); + + return SWIG_OK; + +} + +int JSCEmitter::emitDtor(Node *) { + + Template t_dtor = getTemplate("JS_destructordefn"); + t_dtor.replace("${classname_mangled}", current_classname_mangled) + .replace("${type}", current_classtype); + Wrapper_pretty_print(t_dtor.str(), f_wrappers); + + return SWIG_OK; +} + +int JSCEmitter::emitGetter(Node *n, bool is_member) { + Template t_getter(getTemplate("JS_getproperty")); + bool is_static = Equal(Getattr(n, "storage"), "static"); + + String *name = Getattr(n, "wrap:name"); + String *wrap_name = Swig_name_wrapper(name); + current_getter = wrap_name; + Setattr(n, "wrap:name", 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"); + + String *action = emit_action(n); + marshalInputArgs(n, params, current_wrapper, Getter, is_member, is_static); + marshalOutput(n, action, current_wrapper); + + t_getter.replace("${getname}", wrap_name) + .replace("${LOCALS}", current_wrapper->locals) + .replace("${CODE}", current_wrapper->code); + + Wrapper_pretty_print(t_getter.str(), f_wrappers); + + return SWIG_OK; +} + +int JSCEmitter::emitSetter(Node *n, bool is_member) { + + // skip variable that are immutable + if (is_immutable) + return SWIG_OK; + + Template t_setter(getTemplate("JS_setproperty")); + bool is_static = Equal(Getattr(n, "storage"), "static"); + + String *name = Getattr(n, "wrap:name"); + String *wrap_name = Swig_name_wrapper(name); + current_setter = wrap_name; + Setattr(n, "wrap:name", wrap_name); + + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_wrapper); + + String *action = emit_action(n); + marshalInputArgs(n, params, current_wrapper, Setter, is_member, is_static); + Append(current_wrapper->code, action); + + t_setter.replace("${setname}", wrap_name) + .replace("${LOCALS}", current_wrapper->locals) + .replace("${CODE}", current_wrapper->code); + + Wrapper_pretty_print(t_setter.str(), f_wrappers); + + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * swig::JSEmitter::emitConstant() : triggers code generation for constants + * ----------------------------------------------------------------------------- */ + +int JSCEmitter::emitConstant(Node *n) { + + // call the variable methods as a constants are + // registred in same way + enterVariable(n); + + current_wrapper = NewWrapper(); + + 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"); + } + if (value == NULL) { + value = Getattr(n, "value"); + } + + Template t_getter(getTemplate("JS_getproperty")); + + current_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); + + t_getter.replace("${getname}", wrap_name) + .replace("${LOCALS}", current_wrapper->locals) + .replace("${CODE}", current_wrapper->code); + + Wrapper_pretty_print(t_getter.str(), f_wrappers); + + DelWrapper(current_wrapper); + current_wrapper = 0; + + exitVariable(n); + + return SWIG_OK; +} + +int JSCEmitter::emitFunction(Node *n, bool is_member) { + Template t_function(getTemplate("JS_functionwrapper")); + + // Note: there is an inconsistency in SWIG with static member functions + // that do not have storage:static + // 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_overloaded = GetFlag(n, "sym:overloaded"); + String *name = Getattr(n, "sym:name"); + String *wrap_name = Swig_name_wrapper(name); + + if (is_overloaded) { + Append(wrap_name, Getattr(n, "sym:overname")); + } + + current_functionwrapper = wrap_name; + Setattr(n, "wrap:name", 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"); + + String *action = emit_action(n); + marshalInputArgs(n, params, current_wrapper, Function, is_member, is_static); + marshalOutput(n, action, current_wrapper); + + t_function.replace("${functionname}", wrap_name) + .replace("${LOCALS}", current_wrapper->locals) + .replace("${CODE}", current_wrapper->code); + Wrapper_pretty_print(t_function.str(), f_wrappers); + + if (is_overloaded) { + Template t_dispatch_case = getTemplate("JS_function_dispatch_case"); + + int argc = emit_num_arguments(params); + String *argcount = NewString(""); + Printf(argcount, "%d", argc); + + t_dispatch_case.replace("${functionwrapper}", wrap_name) + .replace("${argcount}", argcount); + + Printv(function_dispatcher_code, t_dispatch_case.str(), 0); + + Delete(argcount); + } + + return SWIG_OK; +} + +int JSCEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { + + Template t_function(getTemplate("JS_functionwrapper")); + + Wrapper *wrapper = NewWrapper(); + String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); + Setattr(n, "wrap:name", wrap_name); + + Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); + + Append(wrapper->code, function_dispatcher_code); + Append(wrapper->code, getTemplate("JS_function_dispatch_case_default").str()); + + t_function.replace("${functionname}", wrap_name) + .replace("${LOCALS}", wrapper->locals) + .replace("${CODE}", wrapper->code); + + Wrapper_pretty_print(t_function.str(), f_wrappers); + + DelWrapper(wrapper); + + 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); + Setattr(entry, "name", Swig_scopename_last(_name)); + Setattr(entry, "name_mangled", Swig_name_mangle(_name)); + Setattr(entry, "parent", NewString(parent)); + Setattr(entry, "functions", NewString("")); + Setattr(entry, "values", NewString("")); + + Delete(_name); + + return entry; +} + +int JSCEmitter::emitNamespaces() { + Iterator it; + for (it = First(namespaces); it.item; it = Next(it)) { + Hash *entry = it.item; + + String *name = Getattr(entry, "name"); + String *parent = Getattr(entry, "parent"); + String *functions = Getattr(entry, "functions"); + String *variables = Getattr(entry, "values"); + String *name_mangled = Getattr(entry, "name_mangled"); + String *parent_mangled = Swig_name_mangle(parent); + + Template namespace_definition(getTemplate("JS_globaldefn")); + namespace_definition.replace("${jsglobalvariables}", variables) + .replace("${jsglobalfunctions}", functions) + .replace("${namespace}", name_mangled); + Wrapper_pretty_print(namespace_definition.str(), f_wrap_cpp); + + Template t_createNamespace(getTemplate("JS_create_namespace")); + t_createNamespace.replace("${namespace}", name_mangled); + Printv(create_namespaces_code, t_createNamespace.str(), 0); + + Template t_registerNamespace(getTemplate("JS_register_namespace")); + t_registerNamespace.replace("${namespace_mangled}", name_mangled) + .replace("${namespace}", name) + .replace("${parent_namespace}", parent_mangled); + Printv(register_namespaces_code, t_registerNamespace.str(), 0); + } + + return SWIG_OK; +} + +JSEmitter *swig_javascript_create_JSC_emitter() { + return new JSCEmitter(); +} + +extern JSEmitter *swig_javascript_create_JSC_emitter(); /* ******************************************************************** * JAVASCRIPT * ********************************************************************/ -class JAVASCRIPT : public Language { +class JAVASCRIPT:public Language { public: - JAVASCRIPT() {} - ~JAVASCRIPT() {} - - virtual int functionHandler(Node *n); - virtual int globalfunctionHandler(Node *n); - virtual int variableHandler(Node *n); - virtual int globalvariableHandler(Node *n); - virtual int classHandler(Node *n); - virtual int functionWrapper(Node *n); + JAVASCRIPT() { + emitter = NULL; + } ~JAVASCRIPT() { + } + virtual int functionHandler(Node *n); + virtual int globalfunctionHandler(Node *n); + virtual int variableHandler(Node *n); + virtual int globalvariableHandler(Node *n); + virtual int staticmemberfunctionHandler(Node *n); + virtual int classHandler(Node *n); + virtual int functionWrapper(Node *n); + virtual int constantWrapper(Node *n); /** * Registers all %fragments assigned to section "templates" with the Emitter. **/ - virtual int fragmentDirective(Node *n); + virtual int fragmentDirective(Node *n); - virtual void main(int argc, char *argv[]); - virtual int top(Node *n); + virtual int constantDirective(Node *n); + + virtual void main(int argc, char *argv[]); + virtual int top(Node *n); private: - JSEmitter* emitter; + JSEmitter * emitter; }; /* --------------------------------------------------------------------- @@ -45,12 +1335,13 @@ private: * --------------------------------------------------------------------- */ int JAVASCRIPT::functionWrapper(Node *n) { - - Language::functionWrapper(n); - - emitter->EmitWrapperFunction(n); - - return SWIG_OK; + + // note: the default implementation only prints a message + // Language::functionWrapper(n); + + emitter->emitWrapperFunction(n); + + return SWIG_OK; } /* --------------------------------------------------------------------- @@ -58,16 +1349,18 @@ int JAVASCRIPT::functionWrapper(Node *n) { * * Function handler for generating wrappers for functions * --------------------------------------------------------------------- */ - int JAVASCRIPT::functionHandler(Node *n) { - - emitter->EnterFunction(n); - - Language::functionHandler(n); - - emitter->ExitFunction(n); - - return SWIG_OK; + + if (GetFlag(n, "isextension") == 1) + SetFlag(n, "ismember"); + + emitter->enterFunction(n); + + Language::functionHandler(n); + + emitter->exitFunction(n); + + return SWIG_OK; } /* --------------------------------------------------------------------- @@ -77,12 +1370,21 @@ int JAVASCRIPT::functionHandler(Node *n) { * --------------------------------------------------------------------- */ int JAVASCRIPT::globalfunctionHandler(Node *n) { - emitter->SwitchContext(n); - - Language::globalfunctionHandler(n); - return SWIG_OK; + emitter->switchNamespace(n); + + Language::globalfunctionHandler(n); + return SWIG_OK; } +int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { + // workaround: storage=static is not set for static member functions + emitter->setStaticFlag(true); + Language::staticmemberfunctionHandler(n); + emitter->setStaticFlag(false); + return SWIG_OK; +} + + /* --------------------------------------------------------------------- * variableHandler() * @@ -90,14 +1392,19 @@ int JAVASCRIPT::globalfunctionHandler(Node *n) { * --------------------------------------------------------------------- */ int JAVASCRIPT::variableHandler(Node *n) { - - emitter->EnterVariable(n); - - Language::variableHandler(n); - - emitter->ExitVariable(n); - return SWIG_OK; + if (!is_assignable(n) + // HACK: don't know why this is assignable? But does not compile + || Equal(Getattr(n, "type"), "a().char")) { + SetFlag(n, "wrap:immutable"); + } + emitter->enterVariable(n); + + Language::variableHandler(n); + + emitter->exitVariable(n); + + return SWIG_OK; } /* --------------------------------------------------------------------- @@ -108,10 +1415,30 @@ int JAVASCRIPT::variableHandler(Node *n) { int JAVASCRIPT::globalvariableHandler(Node *n) { - emitter->SwitchContext(n); + emitter->switchNamespace(n); - Language::globalvariableHandler(n); + Language::globalvariableHandler(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * constantHandler() + * + * Function handler for generating wrappers for constants + * --------------------------------------------------------------------- */ + + +int JAVASCRIPT::constantWrapper(Node *n) { + + // TODO: handle callback declarations + //Note: callbacks trigger this wrapper handler + if (Equal(Getattr(n, "kind"), "function")) { return SWIG_OK; + } + //Language::constantWrapper(n); + emitter->emitConstant(n); + + return SWIG_OK; } /* --------------------------------------------------------------------- @@ -121,28 +1448,35 @@ int JAVASCRIPT::globalvariableHandler(Node *n) { * --------------------------------------------------------------------- */ int JAVASCRIPT::classHandler(Node *n) { - emitter->SwitchContext(n); + emitter->switchNamespace(n); - emitter->EnterClass(n); - Language::classHandler(n); - emitter->ExitClass(n); + emitter->enterClass(n); + Language::classHandler(n); + emitter->exitClass(n); - return SWIG_OK; + return SWIG_OK; } int JAVASCRIPT::fragmentDirective(Node *n) { - - // catch all fragment directives that have "templates" as location - // and register them at the emitter. - String *section = Getattr(n, "section"); - - if(Cmp(section, "templates") == 0) { - emitter->RegisterTemplate(Getattr(n, "value"), Getattr(n, "code")); - } else { - Swig_fragment_register(n); - } - - return SWIG_OK; + + // catch all fragment directives that have "templates" as location + // and register them at the emitter. + String *section = Getattr(n, "section"); + + if (Cmp(section, "templates") == 0) { + emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code")); + } else { + Swig_fragment_register(n); + } + + return SWIG_OK; +} + +int JAVASCRIPT::constantDirective(Node *n) { + + Language::constantDirective(n); + + return SWIG_OK; } /* --------------------------------------------------------------------- @@ -153,17 +1487,17 @@ int JAVASCRIPT::fragmentDirective(Node *n) { * --------------------------------------------------------------------- */ int JAVASCRIPT::top(Node *n) { - - emitter->Initialize(n); - - Language::top(n); - - emitter->Dump(n); - emitter->Close(); - - delete emitter; - - return SWIG_OK; + + emitter->initialize(n); + + Language::top(n); + + emitter->dump(n); + emitter->close(); + + delete emitter; + + return SWIG_OK; } /* --------------------------------------------------------------------- @@ -174,65 +1508,70 @@ int JAVASCRIPT::top(Node *n) { void JAVASCRIPT::main(int argc, char *argv[]) { - const char* lib_dir; + // Set javascript subdirectory in SWIG library + SWIG_library_directory("javascript"); - // Set javascript subdirectory in SWIG library - SWIG_library_directory("javascript"); - - int mode = -1; - - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-v8") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::V8; - SWIG_library_directory("javascript/v8"); - } else if (strcmp(argv[i], "-jsc") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::JavascriptCore; - SWIG_library_directory("javascript/jsc"); - } else if (strcmp(argv[i], "-qt") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::QtScript; - SWIG_library_directory("javascript/qt"); - } - } + int mode = -1; + + bool debug_templates = false; + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i], "-v8") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + } else if (strcmp(argv[i], "-jsc") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::JavascriptCore; + SWIG_library_directory("javascript/jsc"); + } else if (strcmp(argv[i], "-qt") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::QtScript; + SWIG_library_directory("javascript/qt"); + } else if (strcmp(argv[i], "-debug-templates") == 0) { + Swig_mark_arg(i); + debug_templates = true; + } } - - switch(mode) { - case JSEmitter::V8: - { - emitter = create_v8_emitter(); - break; - } - case JSEmitter::JavascriptCore: - { - // TODO: emitter = create_jsc_emitter(); - break; - } - case JSEmitter::QtScript: - { - // TODO: emitter = create_qtscript_emitter(); - break; - } - default: - { - Printf(stderr, "Unknown emitter type."); - SWIG_exit(-1); - } - } - - - // Add a symbol to the parser for conditional compilation - Preprocessor_define("SWIGJAVASCRIPT 1", 0); + } - // Add typemap definitions - SWIG_typemap_lang("javascript"); + switch (mode) { + case JSEmitter::V8: + { + // TODO: emitter = create_v8_emitter(); + break; + } + case JSEmitter::JavascriptCore: + { + emitter = swig_javascript_create_JSC_emitter(); + break; + } + case JSEmitter::QtScript: + { + // TODO: emitter = create_qtscript_emitter(); + break; + } + default: + { + Printf(stderr, "Unknown emitter type."); + SWIG_exit(-1); + break; + } + } - // Set configuration file - SWIG_config_file("javascript.swg"); + if (debug_templates) { + emitter->enableDebug(); + } + // Add a symbol to the parser for conditional compilation + Preprocessor_define("SWIGJAVASCRIPT 1", 0); - allow_overloading(); + // Add typemap definitions + SWIG_typemap_lang("javascript"); + + // Set configuration file + SWIG_config_file("javascript.swg"); + + allow_overloading(); } /* ----------------------------------------------------------------------------- diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx new file mode 100644 index 000000000..9e7dd2809 --- /dev/null +++ b/Tools/javascript/javascript.cxx @@ -0,0 +1,217 @@ + +#include +#include +#include + +#include +#include +#include + +#include + +#include + +using namespace std; + +static JSValueRef jsc_printstring(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); +static char* jsccreateStringWithContentsOfFile(const char* fileName); +bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* FunctionName,JSObjectCallAsFunctionCallback cbFunction); + +typedef void* HANDLE; +typedef int (*JSCIntializer)(JSGlobalContextRef context); + +void jsc_printError(JSContextRef, JSValueRef, const std::string&); + +void print_usage() { + std::cout << "javascript [-l module] " << std::endl; +} + +int main(int argc, char* argv[]) { + + std::string scriptPath; + + std::vector module_names; + + std::vector loaded_modules; + std::vector module_initializers; + + for (int idx = 1; idx < argc; ++idx) { + if(strcmp(argv[idx], "-l") == 0) { + idx++; + if(idx > argc) { + print_usage(); + exit(-1); + } + std::string module_name(argv[idx]); + module_names.push_back(module_name); + } else { + scriptPath = argv[idx]; + } + } + + for(std::vector::iterator it = module_names.begin(); + it != module_names.end(); ++it) { + std::string module_name = *it; + std::string lib_name = std::string("lib").append(module_name).append(".so"); + + HANDLE handle = dlopen(lib_name.c_str(), RTLD_LAZY); + if(handle == 0) { + std::cout << "Could not load library " << lib_name << ":" + << std::endl << dlerror() << std::endl; + continue; + } + + std::string symname; + symname.append(module_name).append("_initialize"); + + JSCIntializer init_function = reinterpret_cast((long) dlsym(handle, symname.c_str())); + if(init_function == 0) { + std::cout << "Could not find initializer function in module " << module_name << std::endl; + dlclose(handle); + continue; + } + + loaded_modules.push_back(handle); + module_initializers.push_back(init_function); + } + + static int failed; + + JSGlobalContextRef context = JSGlobalContextCreate(NULL); + JSObjectRef globalObject = JSContextGetGlobalObject(context); + + jsc_registerFunction(context, globalObject, "print", jsc_printstring); // Utility print function + + // Call module initializers + for(std::vector::iterator it = module_initializers.begin(); + it != module_initializers.end(); ++it) { + JSCIntializer init_function = *it; + init_function(context); + } + + // Evaluate the javascript + char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); + JSStringRef jsScript; + + if(!scriptContent) { + printf("FAIL: runme script could not be loaded.\n"); + failed = 1; + } + else { + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(scriptContent); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + + if (!jsResult && ex) { + jsc_printError(context, ex, scriptPath); + failed = 1; + } + } + + if (scriptContent != NULL) { + free(scriptContent); + } + + JSStringRelease(jsScript); + + JSGlobalContextRelease(context); + globalObject = 0; + + for(std::vector::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + dlclose(handle); + } + + if (failed) { + printf("FAIL: Some tests failed.\n"); + return 1; + } +} + +static JSValueRef jsc_printstring(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex) +{ + if (argc > 0) + { + JSStringRef string = JSValueToStringCopy(context, args[0], NULL); + size_t numChars = JSStringGetMaximumUTF8CStringSize(string); + char *stringUTF8 = new char[numChars]; + JSStringGetUTF8CString(string, stringUTF8, numChars); + printf("%s\n", stringUTF8); + + delete[] stringUTF8; + } + + return JSValueMakeUndefined(context); +} + +static char* jsccreateStringWithContentsOfFile(const char* fileName) +{ + char* buffer; + + size_t buffer_size = 0; + size_t buffer_capacity = 1024; + buffer = (char*)malloc(buffer_capacity); + + FILE* f = fopen(fileName, "r"); + if (!f) + { + fprintf(stderr, "Could not open file: %s\n", fileName); + return 0; + } + + while (!feof(f) && !ferror(f)) + { + buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f); + if (buffer_size == buffer_capacity) + { + // guarantees space for trailing '\0' + buffer_capacity *= 2; + buffer = (char*)realloc(buffer, buffer_capacity); + } + } + fclose(f); + buffer[buffer_size] = '\0'; + + return buffer; +} + +bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context, object, js_functionName, + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} + +void jsc_printError(JSContextRef ctx, JSValueRef err, const std::string& sourceUrl) +{ + char *buffer; + + JSStringRef string = JSValueToStringCopy(ctx, err, 0); + size_t length = JSStringGetLength(string); + + buffer = (char*) malloc(length+1); + JSStringGetUTF8CString(string, buffer, length+1); + std::string errMsg(buffer); + JSStringRelease(string); + free(buffer); + + JSObjectRef errObj = JSValueToObject(ctx, err, 0); + + if(errObj == 0) { + return; + } + // Note: usually you would also retrieve the property "sourceURL" + // though, it happened that this was always "" + JSStringRef lineKey = JSStringCreateWithUTF8CString("line"); + JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0); + int line = (int) JSValueToNumber(ctx, jsLine, 0); + JSStringRelease(lineKey); + + std::cerr << sourceUrl << ":" << line << ":" << errMsg << std::endl; + +} diff --git a/Tools/swigprinters.gdb b/Tools/swigprinters.gdb new file mode 100644 index 000000000..661aa3ea1 --- /dev/null +++ b/Tools/swigprinters.gdb @@ -0,0 +1,24 @@ +python +import sys +import os + +try: + global SWIG_PRINTER_DIR + sys.path.insert(0, SWIG_PRINTER_DIR) +except NameError: + raise RuntimeError(""" +--------------------------------------------------------- +Change ~/.gdbinit to be able to use swig pretty printers: +> set python SWIG_PRINTER_DIR = /Tools +> source /Tools/swigprinters.gdb +--------------------------------------------------------- +""") + +from swigprinters import register_swig_printers, enableGdbPrintWorkaround, \ + setChildrenRecursionLevel + +#enableGdbPrintWorkaround() +#setChildrenRecursionLevel(2) +register_swig_printers (None) + +end diff --git a/Tools/swigprinters.py b/Tools/swigprinters.py new file mode 100755 index 000000000..741565997 --- /dev/null +++ b/Tools/swigprinters.py @@ -0,0 +1,574 @@ +import gdb +import gdb.types +import itertools +import re + +log_file = None +GDB_FLATTENED_CHILDREN_WORKAROUND = False +CHILDREN_MAX_RECURSION_LEVEL = 0 + +# workaround: don't cast the following DOHs to it's actual type +# to avoid infinite pretty-print loops +cast_black_list = { + 'Hash': set(['parentNode', 'symtab', 'csymtab', 'sym:symtab', 'inherit', 'nextSibling', 'previousSibling']) +} + +def print_(msg): + global log_file; + + if True: + if log_file == None: + log_file = open('swig_gdb.log', 'w') + log_file.write(msg) + + print(msg) + +class SwigStringPrinter: + """ + Pretty print Swig String* types. + """ + + def __init__ (self, typename, val): + self.typename = typename + self.val = val + + try: + self.t_swigstr_ptr = gdb.lookup_type("struct String").pointer() + self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + except Exception as err: + print_("SwigStringPrinter: Could not retrieve gdb types.\n %s.\n"%(str(err))) + + def display_hint(self): + return 'string' + + def to_string(self): + ret = "" + + # Conversion taken from Swig Internals manual: + # http://peregrine.hpc.uwm.edu/Head-node-docs/swig/2.0.4/Devel/internals.html#7 + # (*(struct String *)(((DohBase *)s)->data)).str + + dohbase = None; + str_data = None; + char_ptr = None; + + try: + dohbase = self.val.reinterpret_cast(self.t_doh_base_ptr).dereference() + except Exception as err: + print_("SwigStringPrinter: Could not dereference DOHBase*\n"); + return ""; + + try: + str_data = dohbase['data'].reinterpret_cast(self.t_swigstr_ptr).dereference() + except Exception as err: + print_("SwigStringPrinter: Could not dereference struct String*\n"); + return ""; + + try: + char_ptr = str_data['str'] + except Exception as err: + print_("SwigStringPrinter: Could not access field (struct String).str\n"); + return ""; + + if char_ptr.is_lazy is True: + char_ptr.fetch_lazy () + + try: + ret = char_ptr.string() + except Exception as err: + print_("SwigStringPrinter: Could not convert const char* to string\n"); + return ""; + + return ret + +class SwigIterator: + + def __init__(self): + + self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + self.t_string_ptr = gdb.lookup_type("String").pointer() + self.t_node_ptr = gdb.lookup_type("Node").pointer() + self.t_hash_ptr = gdb.lookup_type("Hash").pointer() + self.t_file_ptr = gdb.lookup_type("File").pointer() + self.t_void_ptr = gdb.lookup_type("void").pointer() + + def cast_doh(self, doh, name = None): + + if doh == 0: + return doh + + doh = doh.reinterpret_cast(self.t_doh_base_ptr); + + val_base = doh.dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + + if not name == None and val_typestr in cast_black_list: + blacklist = cast_black_list[val_typestr] + if name in blacklist: + return doh + + if "String" == val_typestr: + doh = doh.reinterpret_cast(self.t_string_ptr) + elif "File" == val_typestr: + doh = doh.reinterpret_cast(self.t_file_ptr) + # BUG: GDB Pyhton can not handle cyclic references yet + # so these casts are deactivated + elif "Hash" == val_typestr: + doh = doh.reinterpret_cast(self.t_hash_ptr) + elif "Node" == val_typestr: + doh = doh.reinterpret_cast(self.t_node_ptr) + + return doh + +class SwigListIterator(SwigIterator): + + def __init__(self, val): + SwigIterator.__init__(self); + + try: + self.valid = False + + self.val = val.reinterpret_cast(self.t_doh_base_ptr) + val_base = self.val.dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + #print_("SwigListIterator: constructing iterator for value of type %s"%val_typestr) + + self.t_struct_list_ptr = gdb.lookup_type("struct List").pointer() + + doh_base = self.val.dereference() + self.l = doh_base['data'].reinterpret_cast(self.t_struct_list_ptr).dereference() + + self.address = 0 + self._index = 0 + self.key = 0 + self.item = 0 + + self.address = self.val.dereference().address + + self.is_first = True + self.valid = True + + except Exception as err: + print_("SwigListIterator: Construction failed.\n %s.\n"%(str(err))) + + def __iter__(self): + return self + + def List_first(self): + + self.object = None; + self._index = 0 + self.key = 0 + self.nitems = int(self.l['nitems']) + self.items = self.l['items'] + + if self.nitems > 0: + self.item = self.items[0] + else: + self.stop() + + def List_next(self): + self._index = self._index + 1 + if self._index >= self.nitems: + self.stop() + else: + self.item = self.items[self._index] + + def next(self): + + if not self.valid: + self.stop() + + if self.is_first: + self.is_first = False + try: + self.List_first() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + else: + try: + self.List_next() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + + key_str = "[%d]"%self._index + item = 0 + + try: + item = self.cast_doh(self.item) + except Exception as err: + print_("SwigListIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + return (key_str, item) + + def stop(self): + self.is_first = True + self.item = 0 + self.key = 0 + raise StopIteration + +class SwigHashIterator(SwigIterator): + + def __init__(self, val): + SwigIterator.__init__(self); + + try: + self.valid = False + + self.val = val.reinterpret_cast(self.t_doh_base_ptr) + + self.t_struct_hash_ptr = gdb.lookup_type("struct Hash").pointer() + self.t_struct_hash_node_ptr = gdb.lookup_type("struct HashNode").pointer() + + doh_base = self.val.dereference() + hash_ = doh_base['data'].reinterpret_cast(self.t_struct_hash_ptr).dereference() + self.hashtable = hash_['hashtable'] + self.hashsize = int(hash_['hashsize']) + self.nitems = int(hash_['nitems']) + + self.next_ = 0 + self.address = 0 + self.pos = 0; + self._current = 0 + self.item = 0 + self.key = 0 + self._index = 0 + + self.address = self.val.dereference().address + + self.is_first = True + self.valid = True + + except Exception as err: + print_("SwigHashIterator: Construction failed.\n %s.\n"%(str(err))) + + def __iter__(self): + return self + + def Hash_firstiter(self): + self._current = 0; + self.item = 0; + self.key = 0; + self._index = 0; + + while (self._index < self.hashsize) and (self.hashtable[self._index] == 0): + self._index = self._index+1; + + if self._index >= self.hashsize: + self.stop(); + + self._current = self.hashtable[self._index] + self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr); + self.item = self._current['object']; + self.key = self._current['key']; + + self._current = self._current['next']; + + + def Hash_nextiter(self): + if self._current == 0: + self._index = self._index + 1 + while (self._index < self.hashsize) and (self.hashtable[self._index] == 0): + self._index = self._index + 1 + + if self._index >= self.hashsize: + self.item = 0; + self.key = 0; + self._current = 0; + self.stop() + + self._current = self.hashtable[self._index]; + + self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr); + self.key = self._current['key']; + self.item = self._current['object']; + + self._current = self._current['next']; + + + def next(self): + + if not self.valid: + self.stop() + + if self.is_first: + self.is_first = False + try: + self.Hash_firstiter() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + else: + try: + self.Hash_nextiter() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + + key_str = "" + item = 0 + try: + string_printer = SwigStringPrinter("String *", self.key) + key_str = string_printer.to_string() + except Exception as err: + print_("SwigHashIterator(%s): Exception during extracting key string:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + try: + item = self.cast_doh(self.item, key_str) + + except Exception as err: + print_("SwigHashIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + return (key_str, item) + + def stop(self): + self.is_first = True + raise StopIteration + +class AlternateKeyValueIterator(): + + def __init__(self, iterable): + self.it = iterable.__iter__() + self._next = None + self.count = -1 + + def __iter__(self): + return self + + def next(self): + if self._next == None: + key, value = self.it.next() + self._next = value + self.count = self.count + 1 + return ("[%d]"%self.count, key) + else: + value = self._next + self._next = None + return ("[%d]"%self.count, value) + +class NopIterator: + + def __init__(self): + pass + + def __iter__(self): + return self + + def next(self): + raise StopIteration + +class SwigListPrinter: + """ + Pretty print Swig List* types (also ParmList*). + """ + + def __init__ (self, typename, val): + + self.typename = typename + self.val = val + + it = SwigListIterator(val) + self.valid = it.valid + self.address = it.address + + + def display_hint(self): + return 'array' + + def to_string(self): + return "%s(%s)" % (str(self.typename), str(self.address)) + + def children(self): + + if not self.valid: + print_("SwigListPrinter: Invalid state.\n") + return NopIterator() + + try: + it = SwigListIterator(self.val) + return it + except Exception as err: + print_("SwigListPrinter: Error during creation of children iterator. \n %s \n" %(str(err))) + raise err + +class SwigHashPrinter: + """ + Pretty print Swig Hash* types (also Node*). + """ + + def __init__ (self, typename, val): + + self.typename = typename + self.val = val + it = SwigHashIterator(val) + self.valid = it.valid + self.address = it.address + self.level = 0; + + def display_hint(self): + return 'map' + + def to_string(self): + return "%s(%s)" % (str(self.typename), str(self.address)) + + def children(self): + global GDB_FLATTENED_CHILDREN_WORKAROUND + global CHILDREN_MAX_RECURSION_LEVEL + + if not self.valid: + print_("SwigHashPrinter: Invalid state.\n") + return NopIterator() + + if self.level > CHILDREN_MAX_RECURSION_LEVEL: + return NopIterator() + + try: + it = SwigHashIterator(self.val) + if GDB_FLATTENED_CHILDREN_WORKAROUND: + return AlternateKeyValueIterator(it) + return it + except Exception as err: + print_("SwigHashPrinter: Error during creation of children iterator. \n %s \n" %(str(err))) + raise err + +class SwigSimplePrinter: + def __init__ (self, typename, val): + self.typename = typename + self.val = val + + def display_hint(self): + return "string" + + def to_string(self): + return "%s(%s)"%(self.typename, str(self.val.address)) + +class SwigDelegatingPrinter: + + def __init__ (self, typename, val): + t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + val_base = val.reinterpret_cast(t_doh_base_ptr).dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + self.has_children = False + + if val_typestr == "Hash": + self.delegate = SwigHashPrinter(typename, val) + self.has_children = True + elif val_typestr == "List": + self.delegate = SwigListPrinter(typename, val) + self.has_children = True + elif val_typestr == "String": + self.delegate = SwigStringPrinter(typename, val) + else: + self.delegate = SwigSimplePrinter(typename, val) + + def display_hint(self): + return self.delegate.display_hint() + + def to_string(self): + return self.delegate.to_string() + + def children(self): + if not self.has_children: + return NopIterator() + + return self.delegate.children() + +class RxPrinter(object): + def __init__(self, name, function): + super(RxPrinter, self).__init__() + self.name = name + self.function = function + self.enabled = True + + def invoke(self, value): + if not self.enabled: + return None + return self.function(self.name, value) + +# A pretty-printer that conforms to the "PrettyPrinter" protocol from +# gdb.printing. It can also be used directly as an old-style printer. +class Printer(object): + def __init__(self, name): + super(Printer, self).__init__() + self.name = name + self.subprinters = [] + self.lookup = {} + self.enabled = True + self.compiled_rx = re.compile('^([a-zA-Z0-9_: *]+)$') + + def add(self, name, function): + if not self.compiled_rx.match(name): + raise ValueError, 'error: "%s" does not match' % name + + printer = RxPrinter(name, function) + self.subprinters.append(printer) + self.lookup[name] = printer + print('Added pretty printer for %s. ' % (name)) + + def __call__(self, val): + typename = str(val.type) + if typename in self.lookup: + ret = self.lookup[typename].invoke(val) + return ret + + # Cannot find a pretty printer. Return None. + return None + +swig_printer = None + +def register_swig_printers(obj): + global swig_printer + + if obj is None: + obj = gdb + + obj.pretty_printers.append(swig_printer) + +def build_swig_printer(): + global swig_printer + + swig_printer = Printer("swig") + swig_printer.add('String *', SwigStringPrinter) + swig_printer.add('const String *', SwigStringPrinter) + swig_printer.add('SwigType *', SwigStringPrinter) + swig_printer.add('Hash *', SwigHashPrinter) + swig_printer.add('const Hash *', SwigHashPrinter) + swig_printer.add('Node *', SwigHashPrinter) + swig_printer.add('const Node *', SwigHashPrinter) + swig_printer.add('Parm *', SwigHashPrinter) + swig_printer.add('const Parm *', SwigHashPrinter) + swig_printer.add('List *', SwigListPrinter) + swig_printer.add('const List *', SwigListPrinter) + swig_printer.add('ParmList *', SwigDelegatingPrinter) + swig_printer.add('const ParmList *', SwigDelegatingPrinter) + swig_printer.add('File *', SwigDelegatingPrinter) + #swig_printer.add('DOH *', SwigDelegatingPrinter) + #swig_printer.add('const DOH *', SwigDelegatingPrinter) + + print_("Loaded swig printers\n"); + +def enableGdbPrintWorkaround(): + global GDB_FLATTENED_CHILDREN_WORKAROUND + GDB_FLATTENED_CHILDREN_WORKAROUND = True + +def setChildrenRecursionLevel(level): + global CHILDREN_MAX_RECURSION_LEVEL + CHILDREN_MAX_RECURSION_LEVEL = level + +build_swig_printer() diff --git a/configure.in b/configure.in index 77791bd02..92955c4c0 100644 --- a/configure.in +++ b/configure.in @@ -1077,6 +1077,140 @@ AC_SUBST(JAVALDSHARED) AC_SUBST(JAVACXXSHARED) AC_SUBST(JAVACFLAGS) +#---------------------------------------------------------------- +# Look for JAVASCRIPT [JavaScriptCore Headers and Library] +#---------------------------------------------------------------- +AC_ARG_WITH(javascript, AS_HELP_STRING([--without-javascript], [Disable JAVASCRIPT]), [with_javascript="$withval"], [with_javascript=yes]) + +# First, check for "--without-javascript" or "--with-javascript=no". +if test x"${with_javascript}" = xno -o x"${with_alllang}" = xno ; then +AC_MSG_NOTICE([Disabling Javascript]) +JAVASCRIPT= +else + +# check for include files +AC_MSG_CHECKING(for include file JavaScriptCore/JavaScript.h) +AC_ARG_WITH(javascriptincl, [ --with-javascript=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=]) + +if test -z "$JSCOREINCDIR"; then + JSCOREINCDIR="/usr/include/ /usr/local/include/" + + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) JSCOREINCDIR="/usr/include/webkit-1.0/ /usr/include/webkitgtk-1.0/ /usr/local/include/webkit-1.0/JavaScriptCore/ $JSCOREINCDIR";; + *-*-darwin*) JSCOREINCDIR="/System/Library/Frameworks/JavaScriptCore.framework/Headers/ $JSCOREINCDIR";; + *);; + esac +fi + +for d in $JSCOREINCDIR ; do + if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then + AC_MSG_RESULT($d) + JSCOREINCDIR=$d + JSCOREINC=-I\"$d\" + break + fi +done + +if test "$JSCOREINC" = "" ; then + AC_MSG_RESULT(not found) +fi + + +# check for JavaScriptCore, Webkit libraries +AC_ARG_WITH(jscorelib,[ --with-jscorelib =path Set location of JavaScriptCore (Webkit) library directory],[ + JSCORELIB="-L$withval"], [JSCORELIB=]) +AC_MSG_CHECKING(for JavaScriptCore(Webkit) library) + +if test -z "$JSCORELIB"; then +dirs="/usr/lib/ /usr/local/lib/" +for i in $dirs ; do + + if test -r $i/libwebkit-1.0.la; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkit-1.0" + break + fi + + if test -r $i/libjavascriptcoregtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -ljavascriptcoregtk-1.0" + break + fi + + if test -r $i/libwebkitgtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkitgtk-1.0" + break + fi +done + +if test -z "$JSCORELIB"; then + AC_MSG_RESULT(not found) +fi + +else +AC_MSG_RESULT($JSCORELIB) +fi + + +# linking options +case $host in +*-*-darwin*) + JSCOREDYNAMICLINKING="-framework JavaScriptCore" + JSCORECFLAGS="" + ;; +*-*-linux*) + JSCOREDYNAMICLINKING="$JSCORELIB" + JSCORECFLAGS="" + ;; +*) + JSCOREDYNAMICLINKING="" + JSCORECFLAGS="" + ;; +esac + +# JSCORELIBRARYPREFIX +case $host in +*-*-cygwin* | *-*-mingw*) JSCORELIBRARYPREFIX="";; +*) JSCORELIBRARYPREFIX="lib";; +esac + +if "$JS_NO_WARNINGS" == "1"; then +case $host in +*-*-darwin* | *-*-linux* | *-*-cygwin* | *-*-mingw*) + echo "HHHHHHHHHHHHHHHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + JSCXXFLAGS="`echo $CXXFLAGS | sed 's/-Wall//g'`" + ;; +*) + JSCXXFLAGS="$CXXFLAGS" +esac +fi + +# library output +case $host in +*-*-darwin*) + JSCORESO=".dylib" + JSCORELDSHARED='$(CC) -dynamiclib' + JSCORECXXSHARED='$(CXX) -dynamiclib' + ;; +*) + JSCORESO=$SO + JSCORELDSHARED='$(LDSHARED)' + JSCORECXXSHARED='$(CXXSHARED)' + ;; +esac +fi + +AC_SUBST(JSCOREINC) +AC_SUBST(JSCOREDYNAMICLINKING) +AC_SUBST(JSCORELIBRARYPREFIX) +AC_SUBST(JSCORECFLAGS) +AC_SUBST(JSCORESO) +AC_SUBST(JSCORELDSHARED) +AC_SUBST(JSCORECXXSHARED) +AC_SUBST(JSCXXFLAGS) + #---------------------------------------------------------------- # Look for gcj #---------------------------------------------------------------- @@ -2237,6 +2371,20 @@ if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then fi AC_SUBST(SKIP_JAVA) +SKIP_JAVASCRIPT= +if test -z "$JSCOREINC"; then + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) if test -z "$JSCORELIB"; then + SKIP_JAVASCRIPT="1" + fi + ;; + *-*-darwin*)SKIP_JAVASCRIPT="1" + ;; + *);; + esac +fi +AC_SUBST(SKIP_JAVASCRIPT) SKIP_GUILE= if test -z "$GUILEINCLUDE" || test -z "$GUILELIB" || test -z "$GUILE_GH_INTERFACE"; then @@ -2443,6 +2591,7 @@ AC_CONFIG_FILES([ \ Examples/test-suite/uffi/Makefile \ Examples/test-suite/r/Makefile \ Examples/test-suite/go/Makefile \ + Examples/test-suite/javascript/Makefile \ Lib/ocaml/swigp4.ml ]) AC_CONFIG_FILES([preinst-swig], [chmod +x preinst-swig]) From 35e6b73d2acbcc010bd239a83fbf16cecefe7b70 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:57:42 +0000 Subject: [PATCH 031/352] Add swig configuration files for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13765 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/ccomplex.i | 2 +- Lib/javascript/jsc/javascriptfragments.swg | 0 Lib/javascript/jsc/javascripttypemaps.swg | 5 - Lib/javascript/jsc/javascriptvaltypes.swg | 1 - Lib/javascript/v8/ccomplex.i | 26 ++ Lib/javascript/v8/complex.i | 6 + Lib/javascript/{ => v8}/javascript.swg | 8 +- Lib/javascript/v8/javascriptcomplex.swg | 146 +++++++++++ Lib/javascript/v8/javascriptinit.swg | 15 ++ Lib/javascript/{ => v8}/javascriptkw.swg | 0 Lib/javascript/v8/javascriptprimitives.swg | 280 +++++++-------------- Lib/javascript/v8/javascriptruntime.swg | 90 +++++++ Lib/javascript/v8/javascripttypemaps.swg | 16 ++ Lib/javascript/v8/std_common.i | 5 + Lib/javascript/v8/std_complex.i | 19 ++ Lib/javascript/v8/std_except.i | 1 + Lib/javascript/v8/std_map.i | 74 ++++++ Lib/javascript/v8/std_pair.i | 34 +++ Lib/javascript/v8/std_vector.i | 85 +++++++ Lib/javascript/v8/stl.i | 10 + 20 files changed, 630 insertions(+), 193 deletions(-) delete mode 100644 Lib/javascript/jsc/javascriptfragments.swg delete mode 100644 Lib/javascript/jsc/javascriptvaltypes.swg create mode 100644 Lib/javascript/v8/ccomplex.i create mode 100644 Lib/javascript/v8/complex.i rename Lib/javascript/{ => v8}/javascript.swg (76%) create mode 100644 Lib/javascript/v8/javascriptcomplex.swg create mode 100644 Lib/javascript/v8/javascriptinit.swg rename Lib/javascript/{ => v8}/javascriptkw.swg (100%) create mode 100644 Lib/javascript/v8/javascripttypemaps.swg create mode 100755 Lib/javascript/v8/std_common.i create mode 100644 Lib/javascript/v8/std_complex.i create mode 100644 Lib/javascript/v8/std_except.i create mode 100755 Lib/javascript/v8/std_map.i create mode 100755 Lib/javascript/v8/std_pair.i create mode 100755 Lib/javascript/v8/std_vector.i create mode 100755 Lib/javascript/v8/stl.i diff --git a/Lib/javascript/jsc/ccomplex.i b/Lib/javascript/jsc/ccomplex.i index 8eda920bb..50f0f95fe 100644 --- a/Lib/javascript/jsc/ccomplex.i +++ b/Lib/javascript/jsc/ccomplex.i @@ -6,7 +6,7 @@ * ----------------------------------------------------------------------------- */ -%include +%include %{ #include diff --git a/Lib/javascript/jsc/javascriptfragments.swg b/Lib/javascript/jsc/javascriptfragments.swg deleted file mode 100644 index e69de29bb..000000000 diff --git a/Lib/javascript/jsc/javascripttypemaps.swg b/Lib/javascript/jsc/javascripttypemaps.swg index e8711cfc5..9bde8eb2a 100644 --- a/Lib/javascript/jsc/javascripttypemaps.swg +++ b/Lib/javascript/jsc/javascripttypemaps.swg @@ -9,17 +9,12 @@ #define SWIG_SetConstant(name, obj) #define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise(context, exception, type) -%include - /* Include fundamental fragemt definitions */ %include /* Python fragments for fundamental types */ %include -/* override some of the macros in global valtypes.swg */ -%include - %include /* Include the unified typemap library */ diff --git a/Lib/javascript/jsc/javascriptvaltypes.swg b/Lib/javascript/jsc/javascriptvaltypes.swg deleted file mode 100644 index 8b1378917..000000000 --- a/Lib/javascript/jsc/javascriptvaltypes.swg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/Lib/javascript/v8/ccomplex.i b/Lib/javascript/v8/ccomplex.i new file mode 100644 index 000000000..8eda920bb --- /dev/null +++ b/Lib/javascript/v8/ccomplex.i @@ -0,0 +1,26 @@ +/* ----------------------------------------------------------------------------- + * ccomplex.i + * + * C complex typemaps + * ISO C99: 7.3 Complex arithmetic + * ----------------------------------------------------------------------------- */ + + +%include + +%{ +#include +%} + + +/* C complex constructor */ +#define CCplxConst(r, i) ((r) + I*(i)) + +%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag); + +/* declaring the typemaps */ +%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex); diff --git a/Lib/javascript/v8/complex.i b/Lib/javascript/v8/complex.i new file mode 100644 index 000000000..4c3b3c5e2 --- /dev/null +++ b/Lib/javascript/v8/complex.i @@ -0,0 +1,6 @@ +#ifdef __cplusplus +%include +#else +%include +#endif + diff --git a/Lib/javascript/javascript.swg b/Lib/javascript/v8/javascript.swg similarity index 76% rename from Lib/javascript/javascript.swg rename to Lib/javascript/v8/javascript.swg index fb01a63bb..3a83b6495 100644 --- a/Lib/javascript/javascript.swg +++ b/Lib/javascript/v8/javascript.swg @@ -4,12 +4,16 @@ * Javascript typemaps * ----------------------------------------------------------------------------- */ +%include + +%include + %include %include -%include - %include %include + +%include diff --git a/Lib/javascript/v8/javascriptcomplex.swg b/Lib/javascript/v8/javascriptcomplex.swg new file mode 100644 index 000000000..7d165dce4 --- /dev/null +++ b/Lib/javascript/v8/javascriptcomplex.swg @@ -0,0 +1,146 @@ +/* + Defines the As/From converters for double/float complex, you need to + provide complex Type, the Name you want to use in the converters, + the complex Constructor method, and the Real and Imag complex + accessor methods. + + See the std_complex.i and ccomplex.i for concret examples. +*/ + +/* the common from converter */ +%define %swig_fromcplx_conv(Type, Real, Imag) +%fragment(SWIG_From_frag(Type),"header", + fragment=SWIG_From_frag(double)) +{ +SWIGINTERNINLINE JSObjectRef +SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) +{ + JSValueRef vals[2]; + vals[0] = SWIG_From(double)(Real(c)); + vals[1] = SWIG_From(double)(Imag(c)); + return JSObjectMakeArray(context, 2, vals, NULL); +} +} +%enddef + +/* the double case */ +%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(double)) +{ +SWIGINTERN int +SWIG_AsVal_dec(Type) (JSValueRef o, Type* val) +{ + if (JSValueIsObject(context, o)) { + JSObjectRef array; + JSValueRef exception, js_re, js_im; + double re, im; + int res; + + exception = 0; + res = 0; + + array = JSValueToObject(context, o, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); + if(exception != 0) + return SWIG_TypeError; + + res = SWIG_AsVal(double)(js_re, &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(js_im, &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if (val) *val = Constructor(re, im); + return SWIG_OK; + } else { + double d; + int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(d, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +/* the float case */ +%define %swig_cplxflt_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(float)) { +SWIGINTERN int +SWIG_AsVal_dec(Type)(JSValueRef o, Type *val) +{ + if (JSValueIsObject(context, o)) { + JSObjectRef array; + JSValueRef exception, js_re, js_im; + double re, im; + int res; + + exception = 0; + res = 0; + + array = JSValueToObject(context, o, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); + if(exception != 0) + return SWIG_TypeError; + + res = SWIG_AsVal(double)(js_re, &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(js_im, &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if ((-FLT_MAX <= re && re <= FLT_MAX) && (-FLT_MAX <= im && im <= FLT_MAX)) { + if (val) *val = Constructor(%numeric_cast(re, float), + %numeric_cast(im, float)); + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else { + float re; + int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(re, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} + +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ +%swig_cplxflt_conv(Type, Constructor, Real, Imag) + + +#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ +%swig_cplxdbl_conv(Type, Constructor, Real, Imag) diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg new file mode 100644 index 000000000..1186b33bc --- /dev/null +++ b/Lib/javascript/v8/javascriptinit.swg @@ -0,0 +1,15 @@ +%insert(init) %{ +SWIGRUNTIME void +SWIG_V8_SetModule(swig_module_info *swig_module) {} + +SWIGRUNTIME swig_module_info * +SWIG_V8_GetModule(void) { + return 0; +} + +#define SWIG_GetModule(clientdata) SWIG_V8_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_V8_SetModule(pointer) + +%} + +%insert(init) "swiginit.swg" diff --git a/Lib/javascript/javascriptkw.swg b/Lib/javascript/v8/javascriptkw.swg similarity index 100% rename from Lib/javascript/javascriptkw.swg rename to Lib/javascript/v8/javascriptkw.swg diff --git a/Lib/javascript/v8/javascriptprimitives.swg b/Lib/javascript/v8/javascriptprimitives.swg index b8eb1e569..09e1ae9f9 100644 --- a/Lib/javascript/v8/javascriptprimitives.swg +++ b/Lib/javascript/v8/javascriptprimitives.swg @@ -1,119 +1,109 @@ -%typemap(in) bool -%{ $1 = ($1_ltype) $input->BooleanValue();%} - -// Primitive types -%typemap(in) char, - signed char, - unsigned char, - short, - unsigned short, - int -%{ $1 = ($1_ltype) $input->Int32Value();%} - -%typemap(in) unsigned int, - long, - unsigned long, - long long, - unsigned long long -%{ $1 = ($1_ltype) $input->UInt32Value();%} - -%typemap(in) float, double -%{ $1 = ($1_ltype) $input->NumberValue();%} - - -%typemap(in) const bool &, bool &, - const char &, char &, - const signed char &, signed char &, - const unsigned char &, unsigned char &, - const short &, short &, - const unsigned short &, unsigned short &, - const int &, int &, - const unsigned int &, unsigned int &, - const long &, long &, - const unsigned long &, unsigned long &, - const long long &, long long &, - const unsigned long long &, unsigned long long &, - const float &, float &, - const double &, double & -%{ - // TODO: typemap(in) const bool& at al +%fragment(SWIG_From_frag(bool),"header") { +SWIGINTERNINLINE +v8::Handle +SWIG_From_dec(bool)(bool value) +{ + return v8::Boolean::New(value); +} } -%typemap(out) bool -%{ $result = v8::Boolean::New($1);%} +%fragment(SWIG_AsVal_frag(bool),"header", + fragment=SWIG_AsVal_frag(long)) { +SWIGINTERN +int SWIG_AsVal_dec(bool)(v8::Handle obj, bool *val) +{ + if(!obj->IsBoolean()) { + return SWIG_ERROR; + } + + if (val) *val = obj->BooleanValue(); + return SWIG_OK; +} +} -%typemap(out) char, - signed char, - unsigned char, - short, - unsigned short, - int -%{ $result = v8::Int32::New($1);%} - -%typemap(out) unsigned int, - long, - unsigned long, - long long, - unsigned long long -%{ $result = v8::UInt32::New($1);%} +%fragment(SWIG_From_frag(int),"header") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(int)(int value) +{ + return v8::Int32::New(value); +} +} -%typemap(out) float, double -%{ $result = v8::Number::New($1); %} +%fragment(SWIG_From_frag(long),"header") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(long)(long value) +{ + return v8::Integer::New(value); +} +} -%typemap(out) const bool &, bool & -%{ $result = v8::Boolean::New((*$1);%} +%fragment(SWIG_AsVal_frag(long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN +int SWIG_AsVal_dec(long)(v8::Handle obj, long* val) +{ + if (!obj->IsInteger()) { + return SWIG_TypeError; + } + if(val) *val = (long) obj->IntegerValue(); + + return SWIG_OK; +} +} -%typemap(out) const char &, char &, - const signed char &, signed char &, - const unsigned char &, unsigned char &, - const short &, short &, - const unsigned short &, unsigned short &, - const int &, int & -%{ $result = v8::Int32::New((*$1);%} - -%typemap(out) const unsigned int &, unsigned int &, - const long &, long &, - const unsigned long &, unsigned long &, - const long long &, long long &, - const unsigned long long &, unsigned long long & -%{ $result = v8::UInt32::New(*$1);%} +/* unsigned long */ -%typemap(out) const float &, float &, - const double &, double & -%{ $result = v8::Number::New(*$1);%} +%fragment(SWIG_From_frag(unsigned long),"header", + fragment=SWIG_From_frag(long)) { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(unsigned long)(unsigned long value) +{ + return (value > LONG_MAX) ? + v8::Integer::NewFromUnsigned(value) : v8::Integer::New(%numeric_cast(value,long)); +} +} -%typemap(in) short *, - unsigned short *, - int *, - unsigned int *, - long *, - unsigned long *, - long long *, - unsigned long long *, - float *, - double * -%{ - // TODO: typemap(in): short* et al. -%} +%fragment(SWIG_AsVal_frag(unsigned long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN +int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + + long longVal = (long) obj->NumberValue(); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} +%fragment(SWIG_From_frag(double),"header") { +SWIGINTERN +v8::Handle SWIG_From_dec(double) (double val) +{ + return v8::Number::New(val); +} +} -%typemap(out) short *, - unsigned short *, - int *, - unsigned int *, - long *, - unsigned long *, - long long *, - unsigned long long *, - float *, - double * -%{ - // TODO: typemap(out) short* et al. -%} - -%typemap(out) void -%{ $result = v8::Undefined(); %} - +%fragment(SWIG_AsVal_frag(double),"header") { +SWIGINTERN +int SWIG_AsVal_dec(double)(v8::Handle obj, double *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = obj->NumberValue(); + + return SWIG_OK; +} +} %typemap(in) char * %{ @@ -121,81 +111,3 @@ $1 = *_$1; %} -%typemap(out) char * -%{ - // TODO: output typemap for char* -%} - -%typemap(in) char *& ($*1_ltype temp = 0) %{ - // TODO: input typemap for char*& -%} - -%typemap(out) char *& -%{ - // TODO: output typemap for char*& -%} - -/* char arrays - treat as String */ -%typemap(in) char[ANY], char[] %{ - // TODO: input typemap for char[] -%} - -%typemap(out) char[ANY], char[] -%{ - // TODO: output typemap for char[] -%} - -%typemap(freearg) char *, char *&, char[ANY], char[] //TODO: Not working: A memory leak -%{ - // TODO: freearg char* et al -%} - -/* Typemaps for composite types */ -%typemap(in) SWIGTYPE ($&1_type argp) // Objects passed by value, convert to a pointer -%{ - // TODO: input typemap for composite types -%} - -%typemap(out) SWIGTYPE ($&1_type temp) -%{ - // TODO: output typemap for composite types -%} - -%typemap(in) SWIGTYPE *, SWIGTYPE & -%{ - // TODO: input typemap for ptr types -%} - -%typemap(out) SWIGTYPE *, SWIGTYPE & -%{ - // TODO: output typemap for ptr types -%} - -// TODO: sanity check? -%typemap(arginit) SWIGTYPE * -%{%} - -%typemap(in) SWIGTYPE (CLASS::*) "" - -%typemap(out) SWIGTYPE (CLASS::*) -%{ - // TODO: output typemap for CLASS::* -%} - -// Default array handling -%typemap(in) SWIGTYPE [] %{ - // TODO: typemap for arrays; -%} - -%typemap(out) SWIGTYPE [] %{ $result = $1; %} - -// Some ANSI C typemaps */ -%apply unsigned long { size_t }; - -%apply const unsigned long & { const size_t & }; - -// Array reference typemaps -%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) } - -// const pointers -%apply SWIGTYPE * { SWIGTYPE *const } diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index ad34b6df2..4440fa6d6 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -7,3 +7,93 @@ %insert(runtime) %{ #include %} + +%insert(runtime) "swigrun.swg"; /* SWIG API */ +%insert(runtime) "swigerrors.swg"; /* SWIG errors */ + +%insert(runtime) %{ +#define SWIG_Error(code, msg) SWIG_V8_exception(code, msg) +#define SWIG_exception(code, msg) SWIG_V8_exception(code, msg) +#define SWIG_fail goto fail +%} + +%insert(runtime) %{ +typedef struct { + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; +}SWIG_PRV_DATA; +%} + +%insert(runtime) %{ + +void SWIG_V8_Raise(const char* type) { + // TODO: throw v8 exception +} + +void SWIG_V8_exception(int code, const char* msg) { + SWIG_V8_Raise(msg); +} + +%} + + +%insert(runtime) %{ +int SWIG_JSC_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { + + if(objRef->InternalFieldCount() < 1) { + return SWIG_ERROR; + } + Handle cdataRef = objRef->GetInternalField(0); + + SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) v8::External::Unwrap(cdataRef); + if(cdata == NULL) { + return SWIG_ERROR; + } + + if(cdata->info != info) { + bool type_valid = false; + swig_cast_info *t = info->cast; + while(t != NULL) { + if(t->type == cdata->info) { + type_valid = true; + break; + } + t = t->next; + } + if(!type_valid) { + return SWIG_TypeError; + } + } + + *ptr = cdata->swigCObject; + + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + + return SWIG_OK; +} + +int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { + if(!valRef->IsObject()) { + return SWIG_TypeError; + } + + v8::Handle objRef = valRef->ToObject(); + + return SWIG_V8_ConvertInstancePtr(context, objRef, ptr, info, flags); +} + +v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { + // TODO: wrap ptr into an v8 object + return 0; +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_V8_ConvertPtr(obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_V8_NewPointerObj(ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_V8_ConvertInstancePtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_V8_NewPointerObj(thisvalue, type, flags) + +%} diff --git a/Lib/javascript/v8/javascripttypemaps.swg b/Lib/javascript/v8/javascripttypemaps.swg new file mode 100644 index 000000000..479a1f076 --- /dev/null +++ b/Lib/javascript/v8/javascripttypemaps.swg @@ -0,0 +1,16 @@ +#define SWIG_Object v8::Handle +#define VOID_Object v8::Undefined() +#define SWIG_AppendOutput(result, obj) +#define SWIG_SetConstant(name, obj) +#define SWIG_Raise(obj, type, desc) SWIG_V8_Raise(type) + +/* Include fundamental fragemt definitions */ +%include + +/* Python fragments for fundamental types */ +%include + +%include + +/* Include the unified typemap library */ +%include diff --git a/Lib/javascript/v8/std_common.i b/Lib/javascript/v8/std_common.i new file mode 100755 index 000000000..cee11e8ca --- /dev/null +++ b/Lib/javascript/v8/std_common.i @@ -0,0 +1,5 @@ +%include + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; + diff --git a/Lib/javascript/v8/std_complex.i b/Lib/javascript/v8/std_complex.i new file mode 100644 index 000000000..088a4fe7b --- /dev/null +++ b/Lib/javascript/v8/std_complex.i @@ -0,0 +1,19 @@ +/* + * STD C++ complex typemaps + */ + +%include + +%{ +#include +%} + +/* defining the complex as/from converters */ + +%swig_cplxdbl_convn(std::complex, std::complex, std::real, std::imag) +%swig_cplxflt_convn(std::complex, std::complex, std::real, std::imag) + +/* defining the typemaps */ + +%typemaps_primitive(%checkcode(CPLXDBL), std::complex); +%typemaps_primitive(%checkcode(CPLXFLT), std::complex); diff --git a/Lib/javascript/v8/std_except.i b/Lib/javascript/v8/std_except.i new file mode 100644 index 000000000..af98428f6 --- /dev/null +++ b/Lib/javascript/v8/std_except.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/std_map.i b/Lib/javascript/v8/std_map.i new file mode 100755 index 000000000..e7812f38a --- /dev/null +++ b/Lib/javascript/v8/std_map.i @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------------- + * std_map.i + * + * SWIG typemaps for std::map + * ----------------------------------------------------------------------------- */ + +%include + +// ------------------------------------------------------------------------ +// std::map +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class map { + // add typemaps here + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + map(); + map(const map &); + + unsigned int size() const; + bool empty() const; + void clear(); + %extend { + const T& get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + void set(const K& key, const T& x) { + (*self)[key] = x; + } + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + }; + +// Legacy macros (deprecated) +%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) +#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary" +%enddef + +} diff --git a/Lib/javascript/v8/std_pair.i b/Lib/javascript/v8/std_pair.i new file mode 100755 index 000000000..fe45ee676 --- /dev/null +++ b/Lib/javascript/v8/std_pair.i @@ -0,0 +1,34 @@ +/* ----------------------------------------------------------------------------- + * std_pair.i + * + * SWIG typemaps for std::pair + * ----------------------------------------------------------------------------- */ + +%include +%include + +// ------------------------------------------------------------------------ +// std::pair +// ------------------------------------------------------------------------ + +%{ +#include +%} + +namespace std { + + template struct pair { + + pair(); + pair(T first, U second); + pair(const pair& p); + + template pair(const pair &p); + + T first; + U second; + }; + + // add specializations here + +} diff --git a/Lib/javascript/v8/std_vector.i b/Lib/javascript/v8/std_vector.i new file mode 100755 index 000000000..3f29b19c7 --- /dev/null +++ b/Lib/javascript/v8/std_vector.i @@ -0,0 +1,85 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * ----------------------------------------------------------------------------- */ + +%include + +%{ +#include +#include +%} + +namespace std { + + template class vector { + public: + typedef size_t size_type; + typedef T value_type; + typedef const value_type& const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + public: + typedef size_t size_type; + typedef bool value_type; + typedef bool const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i +%include +%include +%include +%include + From b39e2bfff0c1082c31149079075faa0999059953 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:57:57 +0000 Subject: [PATCH 032/352] Refactor JSC emitter to reduce global state variables. Also meld v8 emitter into javascript.cxx (provisional). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13766 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Makefile.am | 1 - Source/Modules/javascript.cxx | 2016 ++++++++++++++++++++---------- Source/Modules/javascript_v8.cxx | 579 --------- 3 files changed, 1372 insertions(+), 1224 deletions(-) delete mode 100644 Source/Modules/javascript_v8.cxx diff --git a/Source/Makefile.am b/Source/Makefile.am index 420fd6d3f..9cd55c7dc 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -50,7 +50,6 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/java.cxx \ Modules/lang.cxx \ Modules/javascript.cxx \ - Modules/javascript_v8.cxx \ Modules/lua.cxx \ Modules/main.cxx \ Modules/modula3.cxx \ diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 009bcc400..1fde3cd0c 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -4,28 +4,100 @@ #include #include -/** - * A class that wraps a code snippet used as template for code generation. - */ -class Template { +/********************************************************************** + * JAVASCRIPT: swig module implementation + **********************************************************************/ +/* forward decl: Template is a convenience helper class for dealing with + * code fragments */ +class Template; + +class State { + public: - Template(const String *code); - Template(const String *code, const String *templateName, bool debug = false); + State(): _global(NewHash()) { + // initialize sub-hashes + Setattr(_global, "class", NewHash()); + Setattr(_global, "function", NewHash()); + Setattr(_global, "variable", NewHash()); + } - ~Template(); + ~State() { Delete(_global); } + + DOH *getState(const char* key, bool _new = false) { + if (_new) { + Hash *hash = NewHash(); + Setattr(_global, key, hash); + } + return Getattr(_global, key); + } + + DOH *global() { return _global; } - String *str(); + DOH *global(const char* key, DOH *initial=0) { + if(initial != 0) { + Setattr(_global, key, initial); + } + return Getattr(_global, key); + } - Template & replace(const String *pattern, const String *repl); + DOH *clazz(bool _new = false) { + return getState("class", _new); + } + + DOH *clazz(const char* key, DOH *initial=0) { + DOH *c = clazz(); + if(initial != 0) { + Setattr(c, key, initial); + } + return Getattr(c, key); + } + DOH *function(bool _new = false) { + return getState("function", _new); + } + + DOH *function(const char* key, DOH *initial=0) { + DOH *f = function(); + if(initial != 0) { + Setattr(f, key, initial); + } + return Getattr(f, key); + } + + DOH *variable(bool _new = false) { + return getState("variable", _new); + } + + DOH *variable(const char* key, DOH *initial=0) { + DOH *v = variable(); + if(initial != 0) { + Setattr(v, key, initial); + } + return Getattr(v, key); + } + + static int IsSet(DOH *val) { + if (!val) { + return 0; + } else { + const char *cval = Char(val); + if (!cval) + return 0; + return (strcmp(cval, "0") != 0) ? 1 : 0; + } + } + private: - String *code; - String *templateName; - bool debug; + + Hash *_global; }; +/** + * JSEmitter represents an abstraction of javascript code generators + * for different javascript engines. + **/ class JSEmitter { public: @@ -38,97 +110,91 @@ public: JSEmitter(); - virtual ~ JSEmitter(); + virtual ~JSEmitter(); - /** - * Opens output files and temporary output DOHs. - */ - virtual int initialize(Node *n) = 0; + /** + * Opens output files and temporary output DOHs. + */ + virtual int initialize(Node *n); - /** - * Writes all collected code into the output file(s). - */ + /** + * Writes all collected code into the output file(s). + */ virtual int dump(Node *n) = 0; - /** - * Cleans up all open output DOHs. - */ + /** + * Cleans up all open output DOHs. + */ virtual int close() = 0; - /** - * Switches the context for code generation. - * - * Classes, global variables and global functions may need to - * be registered in certain static tables. - * This method should be used to switch output DOHs correspondingly. - */ + /** + * Switches the context for code generation. + * + * Classes, global variables and global functions may need to + * be registered in certain static tables. + * This method should be used to switch output DOHs correspondingly. + */ virtual int switchNamespace(Node *) { return SWIG_OK; }; - /** - * Invoked at the beginning of the classHandler. - */ - virtual int enterClass(Node *) { - return SWIG_OK; - }; + /** + * Invoked at the beginning of the classHandler. + */ + virtual int enterClass(Node *); - /** - * Invoked at the end of the classHandler. - */ + /** + * Invoked at the end of the classHandler. + */ virtual int exitClass(Node *) { return SWIG_OK; }; - /** - * Invoked at the beginning of the variableHandler. - */ - virtual int enterVariable(Node *) { - return SWIG_OK; - }; + /** + * Invoked at the beginning of the variableHandler. + */ + virtual int enterVariable(Node *); - /** - * Invoked at the end of the variableHandler. - */ + /** + * Invoked at the end of the variableHandler. + */ virtual int exitVariable(Node *) { return SWIG_OK; }; - /** - * Invoked at the beginning of the functionHandler. - */ - virtual int enterFunction(Node *) { - return SWIG_OK; - }; + /** + * Invoked at the beginning of the functionHandler. + */ + virtual int enterFunction(Node *); - /** - * Invoked at the end of the functionHandler. - */ + /** + * Invoked at the end of the functionHandler. + */ virtual int exitFunction(Node *) { return SWIG_OK; }; - /** - * Invoked by functionWrapper callback after call to Language::functionWrapper. - */ + /** + * Invoked by functionWrapper callback after call to Language::functionWrapper. + */ virtual int emitWrapperFunction(Node *n); - /** - * Invoked from constantWrapper after call to Language::constantWrapper. - **/ + /** + * Invoked from constantWrapper after call to Language::constantWrapper. + **/ virtual int emitConstant(Node *n) = 0; - /** - * Registers a given code snippet for a given key name. - * - * This method is called by the fragmentDirective handler - * of the JAVASCRIPT language module. - **/ + /** + * Registers a given code snippet for a given key name. + * + * This method is called by the fragmentDirective handler + * of the JAVASCRIPT language module. + **/ int registerTemplate(const String *name, const String *code); - /** - * Retrieve the code template registered for a given name. - */ + /** + * Retrieve the code template registered for a given name. + */ Template getTemplate(const String *name); void enableDebug(); @@ -137,22 +203,53 @@ public: protected: + /** + * Generates code for a constructor function. + */ virtual int emitCtor(Node *n) = 0; + /** + * Generates code for a destructor function. + */ virtual int emitDtor(Node *n) = 0; + /** + * Generates code for a function. + */ virtual int emitFunction(Node *n, bool is_member) = 0; + /** + * Generates code for a getter function. + */ virtual int emitGetter(Node *n, bool is_member) = 0; + /** + * Generates code for a setter function. + */ virtual int emitSetter(Node *n, bool is_member) = 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); - + + /** + * Helper function to retrieve a certain typemap. + */ const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0); + Parm *skipIgnoredArgs(Parm *p); + + /** + * Enables extra debugging information in typemaps. + * TODO: make this global/static... js_emitter_template_enable_debug + */ void enableDebugTemplates(); protected: @@ -163,132 +260,344 @@ protected: Hash *templates; Wrapper *current_wrapper; + + State state; bool is_static; bool debug; }; -class JSCEmitter:public JSEmitter { +/* factory methods for concrete JSEmitters: */ +JSEmitter *swig_javascript_create_JSCEmitter(); +JSEmitter *swig_javascript_create_V8Emitter(); -private: - - enum MarshallingMode { - Setter, - Getter, - Ctor, - Function - }; +class JAVASCRIPT:public Language { public: - JSCEmitter(); + JAVASCRIPT(): emitter(NULL) {} + + ~JAVASCRIPT() { + delete emitter; + } - virtual ~ JSCEmitter(); - - virtual int initialize(Node *n); - - virtual int dump(Node *n); - - virtual int close(); - - -protected: - - virtual int emitCtor(Node *n); - - virtual int emitDtor(Node *n); - - virtual int enterVariable(Node *n); - - virtual int exitVariable(Node *n); - - virtual int enterFunction(Node *n); - - virtual int exitFunction(Node *n); - - virtual int enterClass(Node *n); - - virtual int exitClass(Node *n); - - virtual int emitFunction(Node *n, bool is_member); - - virtual int emitFunctionDispatcher(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, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static = false); - - void marshalOutput(Node *n, String *actioncode, Wrapper *wrapper); - - Parm *skipIgnoredArgs(Parm *p); - - virtual int switchNamespace(Node *n); - - virtual int createNamespace(String *scope); - - virtual Hash *createNamespaceEntry(const char *name, const char *parent); - - virtual int emitNamespaces(); - - virtual int emitConstant(Node *n); + virtual int functionHandler(Node *n); + virtual int globalfunctionHandler(Node *n); + virtual int variableHandler(Node *n); + virtual int globalvariableHandler(Node *n); + virtual int staticmemberfunctionHandler(Node *n); + virtual int classHandler(Node *n); + virtual int functionWrapper(Node *n); + virtual int constantWrapper(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: - File *f_wrap_cpp; - File *f_runtime; - File *f_header; - File *f_wrappers; - File *f_init; - - String *NULL_STR; - String *VETO_SET; - const char *GLOBAL_STR; - - // contains context specific structs - // to allow generation different class definition tables - // which are switched on namespace change - Hash *namespaces; - Hash *current_namespace; - - // dynamically filled code parts - - String *create_namespaces_code; - String *register_namespaces_code; - - String *current_class_functions; - String *class_variables_code; - String *class_static_functions_code; - String *class_static_variables_code; - - String *ctor_wrappers; - String *ctor_dispatcher_code; - - String *initializer_code; - String *function_dispatcher_code; - - // state variables - String *current_propertyname; - String *current_getter; - String *current_setter; - bool is_immutable; - - String *current_classname; - String *current_classname_mangled; - String *current_classtype; - String *current_classtype_mangled; - String *current_functionwrapper; - String *current_functionname; + JSEmitter *emitter; }; +/* --------------------------------------------------------------------- + * functionWrapper() + * + * Low level code generator for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::functionWrapper(Node *n) { + + // note: the default implementation only prints a message + // Language::functionWrapper(n); + emitter->emitWrapperFunction(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * functionHandler() + * + * Function handler for generating wrappers for functions + * --------------------------------------------------------------------- */ +int JAVASCRIPT::functionHandler(Node *n) { + + if (GetFlag(n, "isextension") == 1) { + SetFlag(n, "ismember"); + } + + emitter->enterFunction(n); + Language::functionHandler(n); + emitter->exitFunction(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * globalfunctionHandler() + * + * Function handler for generating wrappers for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::globalfunctionHandler(Node *n) { + emitter->switchNamespace(n); + Language::globalfunctionHandler(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * staticmemberfunctionHandler() + * + * Function handler for generating wrappers for static member functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { + // workaround: storage=static is not set for static member functions + emitter->setStaticFlag(true); + Language::staticmemberfunctionHandler(n); + emitter->setStaticFlag(false); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * variableHandler() + * + * Function handler for generating wrappers for variables + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::variableHandler(Node *n) { + + if (!is_assignable(n) + // HACK: don't know why this is assignable? + || Equal(Getattr(n, "type"), "a().char")) { + SetFlag(n, "wrap:immutable"); + } + + emitter->enterVariable(n); + Language::variableHandler(n); + emitter->exitVariable(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * globalvariableHandler() + * + * Function handler for generating wrappers for global variables + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::globalvariableHandler(Node *n) { + + emitter->switchNamespace(n); + Language::globalvariableHandler(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * constantHandler() + * + * Function handler for generating wrappers for constants + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::constantWrapper(Node *n) { + + // Note: callbacks trigger this wrapper handler + // TODO: handle callback declarations + if (Equal(Getattr(n, "kind"), "function")) { + return SWIG_OK; + } + + //Language::constantWrapper(n); + emitter->emitConstant(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * classHandler() + * + * Function handler for generating wrappers for class + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::classHandler(Node *n) { + emitter->switchNamespace(n); + + emitter->enterClass(n); + Language::classHandler(n); + emitter->exitClass(n); + + return SWIG_OK; +} + +int JAVASCRIPT::fragmentDirective(Node *n) { + + // catch all fragment directives that have "templates" as location + // and register them at the emitter. + String *section = Getattr(n, "section"); + + if (Equal(section, "templates")) { + emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code")); + } else { + Swig_fragment_register(n); + } + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * top() + * + * Function handler for processing top node of the parse tree + * Wrapper code generation essentially starts from here + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::top(Node *n) { + + emitter->initialize(n); + + Language::top(n); + + emitter->dump(n); + emitter->close(); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * main() + * + * Entry point for the JAVASCRIPT module + * --------------------------------------------------------------------- */ + +void JAVASCRIPT::main(int argc, char *argv[]) { + + // Set javascript subdirectory in SWIG library + SWIG_library_directory("javascript"); + + int mode = -1; + + bool debug_templates = false; + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i], "-v8") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + } else if (strcmp(argv[i], "-jsc") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::JavascriptCore; + SWIG_library_directory("javascript/jsc"); + } else if (strcmp(argv[i], "-qt") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::QtScript; + SWIG_library_directory("javascript/qt"); + } else if (strcmp(argv[i], "-debug-templates") == 0) { + Swig_mark_arg(i); + debug_templates = true; + } + } + } + + switch (mode) { + case JSEmitter::V8: + { + emitter = swig_javascript_create_V8Emitter(); + break; + } + case JSEmitter::JavascriptCore: + { + emitter = swig_javascript_create_JSCEmitter(); + break; + } + case JSEmitter::QtScript: + { + Printf(stderr, "QtScript support is not yet implemented."); + SWIG_exit(-1); + break; + } + default: + { + Printf(stderr, "Unknown emitter type."); + SWIG_exit(-1); + break; + } + } + + if (debug_templates) { + emitter->enableDebug(); + } + + // Add a symbol to the parser for conditional compilation + Preprocessor_define("SWIGJAVASCRIPT 1", 0); + + // Add typemap definitions + SWIG_typemap_lang("javascript"); + + // Set configuration file + SWIG_config_file("javascript.swg"); + + allow_overloading(); +} + +/* ----------------------------------------------------------------------------- + * swig_javascript() - Instantiate module + * ----------------------------------------------------------------------------- */ + +static Language *new_swig_javascript() { + return new JAVASCRIPT(); +} + +extern "C" Language *swig_javascript(void) { + return new_swig_javascript(); +} + +/********************************************************************** + * Emitter implementations + **********************************************************************/ + +/** + * A convenience class that wraps a code snippet used as template for code generation. + */ +class Template { + +public: + Template(const String *code); + + Template(const String *code, const String *templateName, bool debug = false); + + ~Template(); + + String *str(); + + Template& replace(const String *pattern, const String *repl); + + Template& pretty_print(DOH *doh); + +private: + String *code; + String *templateName; + 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), debug(false) { +: empty_string(NewString("")), + current_wrapper(NULL), + is_static(false), + debug(false) +{ templates = NewHash(); } @@ -326,6 +635,10 @@ Template JSEmitter::getTemplate(const String *name) { return t; } +int JSEmitter::initialize(Node *) { + return SWIG_OK; +} + void JSEmitter::enableDebug() { debug = true; } @@ -364,6 +677,17 @@ const String *JSEmitter::typemapLookup(Node *n, const_String_or_char_ptr tmap_me return tm; } +/* --------------------------------------------------------------------- + * skipIgnoredArgs() + * --------------------------------------------------------------------- */ + +Parm *JSEmitter::skipIgnoredArgs(Parm *p) { + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + return p; +} + /* ----------------------------------------------------------------------------- * JSEmitter::getBaseClass() : the node of the base class or NULL * ----------------------------------------------------------------------------- */ @@ -402,10 +726,10 @@ int JSEmitter::emitWrapperFunction(Node *n) { } else if (Cmp(kind, "variable") == 0) { if (isSetterMethod(n)) { - ret = emitSetter(n, is_member); + ret = emitSetter(n, is_member); } else { - ret = emitGetter(n, is_member); + ret = emitGetter(n, is_member); } } else { @@ -436,6 +760,38 @@ int JSEmitter::emitWrapperFunction(Node *n) { return ret; } +int JSEmitter::enterClass(Node *n) { + + state.clazz(true); + state.clazz(__NAME__, Getattr(n, "sym:name")); + state.clazz(NAME_MANGLED, SwigType_manglestr(Getattr(n, "name"))); + state.clazz(TYPE, NewString(Getattr(n, "classtype"))); + + String *type = SwigType_manglestr(Getattr(n, "classtypeobj")); + String *classtype_mangled = NewString(""); + Printf(classtype_mangled, "p%s", type); + Delete(type); + state.clazz(TYPE_MANGLED, classtype_mangled); + + return SWIG_OK; +} + +int JSEmitter::enterFunction(Node *n) { + + state.function(true); + 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(IS_IMMUTABLE, Getattr(n, "wrap:immutable")); + return SWIG_OK; +} + + /* ----------------------------------------------------------------------------- * __swigjs_str_ends_with() : c string helper to check suffix match * ----------------------------------------------------------------------------- */ @@ -464,6 +820,7 @@ bool JSEmitter::isSetterMethod(Node *n) { return (__swigjs_str_ends_with((char *) Data(symname), "_set") != 0); } + /* ----------------------------------------------------------------------------- * Template::Template() : creates a Template class for given template code * ----------------------------------------------------------------------------- */ @@ -526,26 +883,143 @@ String *Template::str() { /* ----------------------------------------------------------------------------- * Template& Template::replace(const String* pattern, const String* repl) : * - * replaces all occurances of a given pattern with a given replacement. + * replaces all occurences of a given pattern with a given replacement. * * - pattern: the pattern to be replaced * - repl: the replacement string * - returns a reference to the Template to allow chaining of methods. * ----------------------------------------------------------------------------- */ -Template & Template::replace(const String *pattern, const String *repl) { - ::Replaceall(code, pattern, repl); +Template& Template::replace(const String *pattern, const String *repl) { + Replaceall(code, pattern, repl); return *this; } +Template& Template::pretty_print(DOH *doh) { + Wrapper_pretty_print(str(), doh); + return *this; +} + +/********************************************************************** + * JavascriptCore: JSEmitter implementation for JavascriptCore engine + **********************************************************************/ + +class JSCEmitter:public JSEmitter { + +private: + + enum MarshallingMode { + Setter, + Getter, + Ctor, + Function + }; + +public: + + JSCEmitter(); + + virtual ~ JSCEmitter(); + + virtual int initialize(Node *n); + + virtual int dump(Node *n); + + virtual int close(); + + +protected: + + virtual int emitCtor(Node *n); + + virtual int emitDtor(Node *n); + + virtual int enterVariable(Node *n); + + virtual int exitVariable(Node *n); + + virtual int enterFunction(Node *n); + + virtual int exitFunction(Node *n); + + virtual int enterClass(Node *n); + + virtual int exitClass(Node *n); + + virtual int emitFunction(Node *n, bool is_member); + + virtual int emitFunctionDispatcher(Node *n, bool is_member); + + virtual int emitGetter(Node *n, bool is_member); + + virtual int emitSetter(Node *n, bool is_member); + + 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 int switchNamespace(Node *n); + + virtual int createNamespace(String *scope); + + virtual Hash *createNamespaceEntry(const char *name, const char *parent); + + virtual int emitNamespaces(); + +private: + + String *NULL_STR; + 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; + File *f_runtime; + File *f_header; + File *f_wrappers; + File *f_init; + +}; + +// keys for global state variables +#define CREATE_NAMESPACES "create_namespaces" +#define REGISTER_NAMESPACES "register_namespaces" +#define INITIALIZER "initializer" + +// keys for class scoped state variables +#define MEMBER_VARIABLES "member_variables" +#define MEMBER_FUNCTIONS "member_functions" +#define STATIC_FUNCTIONS "static_functions" +#define STATIC_VARIABLES "static_variables" +#define CTORS "ctors" +#define CTOR_DISPATCHERS "ctor_dispatchers" + +// keys for function scoped state variables +#define FUNCTION_DISPATCHERS "function_dispatchers" +#define GETTER "getter" +#define SETTER "setter" + JSCEmitter::JSCEmitter() -: -JSEmitter(), NULL_STR(NewString("NULL")), current_classname(NULL), f_header(NULL), current_classtype(NULL), f_runtime(NULL), current_class_functions(NULL), -f_wrappers(NULL), current_getter(NULL), is_immutable(NULL), create_namespaces_code(NULL), current_classname_mangled(NULL), initializer_code(NULL), -register_namespaces_code(NULL), f_wrap_cpp(NULL), current_setter(NULL), ctor_dispatcher_code(NULL), current_functionwrapper(NULL), -class_static_functions_code(NULL), namespaces(NULL), function_dispatcher_code(NULL), namespaces(NULL), GLOBAL_STR(NULL), current_propertyname(NULL), -current_namespace(NULL), ctor_wrappers(NULL), class_static_variables_code(NULL), class_variables_code(NULL), f_init(NULL), current_functionname(NULL), -current_classtype_mangled(NULL), VETO_SET(NewString("JS_veto_set_variable")) { +: JSEmitter(), + 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), + f_wrappers(NULL), + f_init(NULL) +{ } JSCEmitter::~JSCEmitter() { @@ -553,16 +1027,6 @@ JSCEmitter::~JSCEmitter() { Delete(VETO_SET); } -/* --------------------------------------------------------------------- - * skipIgnoredArgs() - * --------------------------------------------------------------------- */ - -Parm *JSCEmitter::skipIgnoredArgs(Parm *p) { - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - return p; -} /* --------------------------------------------------------------------- * marshalInputArgs() @@ -577,9 +1041,9 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma Parm *p; int startIdx = 0; - if (is_member && !is_static) + if (is_member && !is_static) { startIdx = 1; - + } int i = 0; for (p = parms; p; p = nextSibling(p), i++) { @@ -590,17 +1054,17 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma case Getter: case Function: if (is_member && !is_static && i == 0) { - Printv(arg, "thisObject", 0); + Printv(arg, "thisObject", 0); } else { - Printf(arg, "argv[%d]", i - startIdx); + Printf(arg, "argv[%d]", i - startIdx); } break; case Setter: if (is_member && !is_static && i == 0) { - Printv(arg, "thisObject", 0); + Printv(arg, "thisObject", 0); } else { - Printv(arg, "value", 0); + Printv(arg, "value", 0); } break; case Ctor: @@ -616,9 +1080,9 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma Setattr(p, "emit:input", arg); if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) { - Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); + Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN"); } else { - Replaceall(tm, "$disown", "0"); + Replaceall(tm, "$disown", "0"); } Replaceall(tm, "$symname", Getattr(n, "sym:name")); @@ -650,7 +1114,6 @@ void JSCEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { 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))); if (GetFlag(n, "feature:new")) { @@ -659,9 +1122,12 @@ void JSCEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { Replaceall(tm, "$owner", "0"); } - Printf(wrapper->code, "%s", tm); - if (Len(tm)) + 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")); } @@ -669,6 +1135,8 @@ void JSCEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { } int JSCEmitter::initialize(Node *n) { + + JSEmitter::initialize(n); /* Get the output file name */ String *outfile = Getattr(n, "outfile"); @@ -686,9 +1154,9 @@ int JSCEmitter::initialize(Node *n) { f_header = NewString(""); f_wrappers = NewString(""); - create_namespaces_code = NewString(""); - register_namespaces_code = NewString(""); - initializer_code = NewString(""); + state.global(CREATE_NAMESPACES, NewString("")); + state.global(REGISTER_NAMESPACES, NewString("")); + state.global(INITIALIZER, NewString("")); namespaces = NewHash(); Hash *global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); @@ -718,23 +1186,21 @@ int JSCEmitter::dump(Node *n) { Printv(f_wrap_cpp, f_header, "\n", 0); Printv(f_wrap_cpp, f_wrappers, "\n", 0); - emitNamespaces(); // compose the initializer function using a template Template initializer(getTemplate("JS_initializer")); initializer.replace("${modulename}", module) - .replace("${initializercode}", initializer_code) - .replace("${create_namespaces}", create_namespaces_code) - .replace("${register_namespaces}", register_namespaces_code); - Wrapper_pretty_print(initializer.str(), f_init); + .replace("${initializercode}", state.global(INITIALIZER)) + .replace("${create_namespaces}", state.global(CREATE_NAMESPACES)) + .replace("${register_namespaces}", state.global(REGISTER_NAMESPACES)) + .pretty_print(f_init); - Printv(f_wrap_cpp, f_init, "\n", 0); + Printv(f_wrap_cpp, f_init, 0); return SWIG_OK; } - int JSCEmitter::close() { /* strings */ Delete(f_runtime); @@ -742,14 +1208,10 @@ int JSCEmitter::close() { Delete(f_wrappers); Delete(f_init); - Delete(create_namespaces_code); - Delete(register_namespaces_code); - Delete(initializer_code); - Delete(namespaces); /* files */ - ::Close(f_wrap_cpp); + Close(f_wrap_cpp); Delete(f_wrap_cpp); return SWIG_OK; @@ -757,12 +1219,12 @@ int JSCEmitter::close() { int JSCEmitter::enterFunction(Node *n) { + JSEmitter::enterFunction(n); + + /* Initialize DOH for collecting function dispatchers */ bool is_overloaded = GetFlag(n, "sym:overloaded"); - - current_functionname = Getattr(n, "sym:name"); - - if (is_overloaded && function_dispatcher_code == 0) { - function_dispatcher_code = NewString(""); + if (is_overloaded && state.function(FUNCTION_DISPATCHERS) == 0) { + state.function(FUNCTION_DISPATCHERS, NewString("")); } return SWIG_OK; @@ -771,61 +1233,42 @@ int JSCEmitter::enterFunction(Node *n) { int JSCEmitter::exitFunction(Node *n) { Template t_function = getTemplate("JS_functiondecl"); - String *functionname = current_functionname; - String *functionwrapper = current_functionwrapper; - bool is_member = GetFlag(n, "ismember"); - - // handle overloaded functions - // Note: wrappers for overloaded functions are currently - // not made available (e.g., foo_double, foo_int) - // maybe this could be enabled by an extra feature flag bool is_overloaded = GetFlag(n, "sym:overloaded"); + // handle overloaded functions if (is_overloaded) { if (!Getattr(n, "sym:nextSibling")) { - - functionwrapper = Swig_name_wrapper(Getattr(n, "name")); - // note: set this attribute to transfer ownership - Setattr(n, "wrap:dispatcher", functionwrapper); - + state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); // create dispatcher emitFunctionDispatcher(n, is_member); - - Delete(function_dispatcher_code); - function_dispatcher_code = 0; - } else { - //don't register wrappers of overloaded functions in function tables return SWIG_OK; } } - t_function.replace("${functionname}", functionname) - .replace("${functionwrapper}", functionwrapper); + t_function.replace("${functionname}", state.function(__NAME__)) + .replace("${functionwrapper}", state.function(WRAPPER_NAME)); if (is_member) { - if (Equal(Getattr(n, "storage"), "static")) { - Printv(class_static_functions_code, t_function.str(), 0); - + Append(state.clazz(STATIC_FUNCTIONS), t_function.str()); } else { - Printv(current_class_functions, t_function.str(), 0); + Append(state.clazz(MEMBER_FUNCTIONS), t_function.str()); } - } else { - Printv(Getattr(current_namespace, "functions"), t_function.str(), 0); + Append(Getattr(current_namespace, "functions"), t_function.str()); } return SWIG_OK; } int JSCEmitter::enterVariable(Node *n) { - current_getter = NULL_STR; - current_setter = VETO_SET; - current_propertyname = Swig_scopename_last(Getattr(n, "name")); - is_immutable = GetFlag(n, "wrap:immutable"); + JSEmitter::enterVariable(n); + + state.variable(GETTER, NULL_STR); + state.variable(SETTER, VETO_SET); return SWIG_OK; } @@ -833,71 +1276,59 @@ int JSCEmitter::enterVariable(Node *n) { int JSCEmitter::exitVariable(Node *n) { Template t_variable(getTemplate("JS_variabledecl")); - t_variable.replace("${setname}", current_setter) - .replace("${getname}", current_getter) - .replace("${propertyname}", current_propertyname); + t_variable.replace("${setname}", state.variable(SETTER)) + .replace("${getname}", state.variable(GETTER)) + .replace("${propertyname}", state.variable(__NAME__)); if (GetFlag(n, "ismember")) { if (Equal(Getattr(n, "storage"), "static") || (Equal(Getattr(n, "nodeType"), "enumitem"))) { - - Printv(class_static_variables_code, t_variable.str(), 0); - + Append(state.clazz(STATIC_VARIABLES), t_variable.str()); } else { - Printv(class_variables_code, t_variable.str(), 0); + Append(state.clazz(MEMBER_VARIABLES), t_variable.str()); } } else { - Printv(Getattr(current_namespace, "values"), t_variable.str(), 0); + Append(Getattr(current_namespace, "values"), t_variable.str()); } return SWIG_OK; } int JSCEmitter::enterClass(Node *n) { + JSEmitter::enterClass(n); - current_classname = Getattr(n, "sym:name"); - current_classname_mangled = SwigType_manglestr(Getattr(n, "name")); - current_classtype = NewString(Getattr(n, "classtype")); - - String *type = SwigType_manglestr(Getattr(n, "classtypeobj")); - current_classtype_mangled = NewString(""); - Printf(current_classtype_mangled, "p%s", type); - Delete(type); + state.clazz(MEMBER_VARIABLES, NewString("")); + state.clazz(MEMBER_FUNCTIONS, NewString("")); + state.clazz(STATIC_VARIABLES, NewString("")); + state.clazz(STATIC_FUNCTIONS, NewString("")); + state.clazz(CTORS, NewString("")); + state.clazz(CTOR_DISPATCHERS, NewString("")); Template t_class_defn = getTemplate("JS_class_definition"); - t_class_defn.replace("${classname_mangled}", current_classname_mangled); - Wrapper_pretty_print(t_class_defn.str(), f_wrappers); - - class_variables_code = NewString(""); - current_class_functions = NewString(""); - class_static_variables_code = NewString(""); - class_static_functions_code = NewString(""); - ctor_wrappers = NewString(""); - ctor_dispatcher_code = NewString(""); + t_class_defn.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + .pretty_print(f_wrappers); return SWIG_OK; } int JSCEmitter::exitClass(Node *n) { - String *mangled_name = SwigType_manglestr(Getattr(n, "name")); - Template t_class_tables(getTemplate("JS_class_tables")); - t_class_tables.replace("${classname_mangled}", mangled_name) - .replace("${jsclassvariables}", class_variables_code) - .replace("${jsclassfunctions}", current_class_functions) - .replace("${jsstaticclassfunctions}", class_static_functions_code) - .replace("${jsstaticclassvariables}", class_static_variables_code); - Wrapper_pretty_print(t_class_tables.str(), f_wrappers); + t_class_tables.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + .replace("${jsclassvariables}", state.clazz(MEMBER_VARIABLES)) + .replace("${jsclassfunctions}", state.clazz(MEMBER_FUNCTIONS)) + .replace("${jsstaticclassfunctions}", state.clazz(STATIC_FUNCTIONS)) + .replace("${jsstaticclassvariables}", state.clazz(STATIC_VARIABLES)) + .pretty_print(f_wrappers); /* adds the ctor wrappers at this position */ // Note: this is necessary to avoid extra forward declarations. - Printv(f_wrappers, ctor_wrappers, 0); + Append(f_wrappers, state.clazz(CTORS)); /* adds the main constructor wrapper function */ Template t_mainctor(getTemplate("JS_mainctordefn")); - t_mainctor.replace("${classname_mangled}", mangled_name) - .replace("${DISPATCH_CASES}", ctor_dispatcher_code); - Wrapper_pretty_print(t_mainctor.str(), f_wrappers); + t_mainctor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + .replace("${DISPATCH_CASES}", state.clazz(CTOR_DISPATCHERS)) + .pretty_print(f_wrappers); /* adds a class template statement to initializer function */ Template t_classtemplate(getTemplate("JS_create_class_template")); @@ -909,47 +1340,21 @@ int JSCEmitter::exitClass(Node *n) { Delete(base_name_mangled); base_name_mangled = SwigType_manglestr(Getattr(base_class, "name")); } + t_classtemplate.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + .replace("${classtype_mangled}", state.clazz(TYPE_MANGLED)) + .replace("${base_classname}", base_name_mangled) + .pretty_print(state.global(INITIALIZER)); + Delete(base_name_mangled); - t_classtemplate.replace("${classname_mangled}", mangled_name) - .replace("${classtype_mangled}", current_classtype_mangled) - .replace("${base_classname}", base_name_mangled); - Wrapper_pretty_print(t_classtemplate.str(), initializer_code); - -/* - String *clientdata = NewString(""); - Printv(clientdata, mangled_name, "_classRef", 0); - SwigType_remember_clientdata(current_classtype_mangled, clientdata); -*/ - - SwigType_remember_clientdata(current_classtype_mangled, NewString("0")); + /* Note: this makes sure that there is a swig_type added for this class */ + SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); /* adds a class registration statement to initializer function */ Template t_registerclass(getTemplate("JS_register_class")); - t_registerclass.replace("${classname}", current_classname) - .replace("${classname_mangled}", current_classname_mangled) - .replace("${namespace_mangled}", Getattr(current_namespace, "name_mangled")); - - Wrapper_pretty_print(t_registerclass.str(), initializer_code); - - /* clean up all DOHs */ - Delete(class_variables_code); - Delete(current_class_functions); - Delete(class_static_variables_code); - Delete(class_static_functions_code); - Delete(ctor_wrappers); - Delete(mangled_name); - Delete(ctor_dispatcher_code); - class_variables_code = 0; - current_class_functions = 0; - class_static_variables_code = 0; - class_static_functions_code = 0; - ctor_wrappers = 0; - ctor_dispatcher_code = 0; - - Delete(current_classname); - Delete(current_classname_mangled); - Delete(current_classtype); - Delete(current_classtype_mangled); + 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)); return SWIG_OK; } @@ -959,9 +1364,8 @@ int JSCEmitter::emitCtor(Node *n) { Template t_ctor(getTemplate("JS_ctordefn")); String *mangled_name = SwigType_manglestr(Getattr(n, "name")); - String *name = (Getattr(n, "wrap:name")); String *overname = Getattr(n, "sym:overname"); - String *wrap_name = Swig_name_wrapper(name); + String *wrap_name = Swig_name_wrapper(Getattr(n, "wrap:name")); Setattr(n, "wrap:name", wrap_name); ParmList *params = Getattr(n, "parms"); @@ -979,30 +1383,27 @@ int JSCEmitter::emitCtor(Node *n) { .replace("${overloadext}", overname) .replace("${LOCALS}", current_wrapper->locals) .replace("${CODE}", current_wrapper->code) - .replace("${type_mangled}", current_classtype_mangled); - - Wrapper_pretty_print(t_ctor.str(), ctor_wrappers); + .replace("${type_mangled}", state.clazz(TYPE_MANGLED)) + .pretty_print(state.clazz(CTORS)); String *argcount = NewString(""); Printf(argcount, "%d", num_args); - Template t_ctor_case(getTemplate("JS_ctor_dispatch_case")); t_ctor_case.replace("${classname_mangled}", mangled_name) .replace("${overloadext}", overname) .replace("${argcount}", argcount); - Printv(ctor_dispatcher_code, t_ctor_case.str(), 0); + Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); Delete(argcount); return SWIG_OK; - } int JSCEmitter::emitDtor(Node *) { Template t_dtor = getTemplate("JS_destructordefn"); - t_dtor.replace("${classname_mangled}", current_classname_mangled) - .replace("${type}", current_classtype); - Wrapper_pretty_print(t_dtor.str(), f_wrappers); + t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + .replace("${type}", state.clazz(TYPE)) + .pretty_print(f_wrappers); return SWIG_OK; } @@ -1011,10 +1412,9 @@ int JSCEmitter::emitGetter(Node *n, bool is_member) { Template t_getter(getTemplate("JS_getproperty")); bool is_static = Equal(Getattr(n, "storage"), "static"); - String *name = Getattr(n, "wrap:name"); - String *wrap_name = Swig_name_wrapper(name); - current_getter = wrap_name; + String *wrap_name = Swig_name_wrapper(Getattr(n, "wrap:name")); Setattr(n, "wrap:name", wrap_name); + state.variable(GETTER, wrap_name); ParmList *params = Getattr(n, "parms"); emit_parameter_variables(params, current_wrapper); @@ -1027,26 +1427,25 @@ int JSCEmitter::emitGetter(Node *n, bool is_member) { t_getter.replace("${getname}", wrap_name) .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code); - - Wrapper_pretty_print(t_getter.str(), f_wrappers); + .replace("${CODE}", current_wrapper->code) + .pretty_print(f_wrappers); return SWIG_OK; } int JSCEmitter::emitSetter(Node *n, bool is_member) { - // skip variable that are immutable - if (is_immutable) + // skip variables that are immutable + if (State::IsSet(state.variable(IS_IMMUTABLE))) { return SWIG_OK; + } Template t_setter(getTemplate("JS_setproperty")); bool is_static = Equal(Getattr(n, "storage"), "static"); - String *name = Getattr(n, "wrap:name"); - String *wrap_name = Swig_name_wrapper(name); - current_setter = wrap_name; + String *wrap_name = Swig_name_wrapper(Getattr(n, "wrap:name")); Setattr(n, "wrap:name", wrap_name); + state.variable(SETTER, wrap_name); ParmList *params = Getattr(n, "parms"); emit_parameter_variables(params, current_wrapper); @@ -1058,15 +1457,14 @@ int JSCEmitter::emitSetter(Node *n, bool is_member) { t_setter.replace("${setname}", wrap_name) .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code); - - Wrapper_pretty_print(t_setter.str(), f_wrappers); + .replace("${CODE}", current_wrapper->code) + .pretty_print(f_wrappers); return SWIG_OK; } /* ----------------------------------------------------------------------------- - * swig::JSEmitter::emitConstant() : triggers code generation for constants + * JSCEmitter::emitConstant() : triggers code generation for constants * ----------------------------------------------------------------------------- */ int JSCEmitter::emitConstant(Node *n) { @@ -1091,7 +1489,7 @@ int JSCEmitter::emitConstant(Node *n) { Template t_getter(getTemplate("JS_getproperty")); - current_getter = wrap_name; + state.variable(GETTER, wrap_name); Setattr(n, "wrap:name", wrap_name); Printf(action, "result = %s;\n", value); @@ -1102,9 +1500,8 @@ int JSCEmitter::emitConstant(Node *n) { t_getter.replace("${getname}", wrap_name) .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code); - - Wrapper_pretty_print(t_getter.str(), f_wrappers); + .replace("${CODE}", current_wrapper->code) + .pretty_print(f_wrappers); DelWrapper(current_wrapper); current_wrapper = 0; @@ -1125,15 +1522,14 @@ int JSCEmitter::emitFunction(Node *n, bool is_member) { bool is_static = JSEmitter::is_static || Equal(Getattr(n, "storage"), "static"); bool is_overloaded = GetFlag(n, "sym:overloaded"); - String *name = Getattr(n, "sym:name"); - String *wrap_name = Swig_name_wrapper(name); + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); if (is_overloaded) { Append(wrap_name, Getattr(n, "sym:overname")); } - current_functionwrapper = wrap_name; Setattr(n, "wrap:name", wrap_name); + state.function(WRAPPER_NAME, wrap_name); ParmList *params = Getattr(n, "parms"); emit_parameter_variables(params, current_wrapper); @@ -1146,8 +1542,8 @@ int JSCEmitter::emitFunction(Node *n, bool is_member) { t_function.replace("${functionname}", wrap_name) .replace("${LOCALS}", current_wrapper->locals) - .replace("${CODE}", current_wrapper->code); - Wrapper_pretty_print(t_function.str(), f_wrappers); + .replace("${CODE}", current_wrapper->code) + .pretty_print(f_wrappers); if (is_overloaded) { Template t_dispatch_case = getTemplate("JS_function_dispatch_case"); @@ -1157,9 +1553,9 @@ int JSCEmitter::emitFunction(Node *n, bool is_member) { Printf(argcount, "%d", argc); t_dispatch_case.replace("${functionwrapper}", wrap_name) - .replace("${argcount}", argcount); + .replace("${argcount}", argcount); - Printv(function_dispatcher_code, t_dispatch_case.str(), 0); + Append(state.function(FUNCTION_DISPATCHERS), t_dispatch_case.str()); Delete(argcount); } @@ -1177,14 +1573,13 @@ int JSCEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); - Append(wrapper->code, function_dispatcher_code); + Append(wrapper->code, state.function(FUNCTION_DISPATCHERS)); Append(wrapper->code, getTemplate("JS_function_dispatch_case_default").str()); t_function.replace("${functionname}", wrap_name) .replace("${LOCALS}", wrapper->locals) - .replace("${CODE}", wrapper->code); - - Wrapper_pretty_print(t_function.str(), f_wrappers); + .replace("${CODE}", wrapper->code) + .pretty_print(f_wrappers); DelWrapper(wrapper); @@ -1192,22 +1587,18 @@ int JSCEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { } 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); + createNamespace(scope); } - current_namespace = Getattr(namespaces, scope); - } else { current_namespace = Getattr(namespaces, "::"); } @@ -1219,9 +1610,7 @@ int JSCEmitter::switchNamespace(Node *n) { 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)) { @@ -1230,14 +1619,12 @@ int JSCEmitter::createNamespace(String *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; } @@ -1249,9 +1636,8 @@ Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent) { Setattr(entry, "parent", NewString(parent)); Setattr(entry, "functions", NewString("")); Setattr(entry, "values", NewString("")); - + Delete(_name); - return entry; } @@ -1259,7 +1645,6 @@ int JSCEmitter::emitNamespaces() { Iterator it; for (it = First(namespaces); it.item; it = Next(it)) { Hash *entry = it.item; - String *name = Getattr(entry, "name"); String *parent = Getattr(entry, "parent"); String *functions = Getattr(entry, "functions"); @@ -1269,319 +1654,662 @@ int JSCEmitter::emitNamespaces() { Template namespace_definition(getTemplate("JS_globaldefn")); namespace_definition.replace("${jsglobalvariables}", variables) - .replace("${jsglobalfunctions}", functions) - .replace("${namespace}", name_mangled); - Wrapper_pretty_print(namespace_definition.str(), f_wrap_cpp); + .replace("${jsglobalfunctions}", functions) + .replace("${namespace}", name_mangled) + .pretty_print(f_wrap_cpp); Template t_createNamespace(getTemplate("JS_create_namespace")); t_createNamespace.replace("${namespace}", name_mangled); - Printv(create_namespaces_code, t_createNamespace.str(), 0); + Append(state.global(CREATE_NAMESPACES), t_createNamespace.str()); Template t_registerNamespace(getTemplate("JS_register_namespace")); t_registerNamespace.replace("${namespace_mangled}", name_mangled) - .replace("${namespace}", name) - .replace("${parent_namespace}", parent_mangled); - Printv(register_namespaces_code, t_registerNamespace.str(), 0); + .replace("${namespace}", name) + .replace("${parent_namespace}", parent_mangled); + Append(state.global(REGISTER_NAMESPACES), t_registerNamespace.str()); } return SWIG_OK; } -JSEmitter *swig_javascript_create_JSC_emitter() { +JSEmitter *swig_javascript_create_JSCEmitter() { return new JSCEmitter(); } -extern JSEmitter *swig_javascript_create_JSC_emitter(); - -/* ******************************************************************** - * JAVASCRIPT - * ********************************************************************/ - -class JAVASCRIPT:public Language { - +/* +class V8Emitter: public JSEmitter { + public: - JAVASCRIPT() { - emitter = NULL; - } ~JAVASCRIPT() { - } - virtual int functionHandler(Node *n); - virtual int globalfunctionHandler(Node *n); - virtual int variableHandler(Node *n); - virtual int globalvariableHandler(Node *n); - virtual int staticmemberfunctionHandler(Node *n); - virtual int classHandler(Node *n); - virtual int functionWrapper(Node *n); - virtual int constantWrapper(Node *n); - /** - * Registers all %fragments assigned to section "templates" with the Emitter. - **/ - virtual int fragmentDirective(Node *n); + V8Emitter(); - virtual int constantDirective(Node *n); + virtual ~V8Emitter(); + + virtual int Initialize(Node *n); - virtual void main(int argc, char *argv[]); - virtual int top(Node *n); + virtual int Dump(Node *n); + + virtual int Close(); + + virtual int SwitchContext(Node *n); + + virtual int EnterClass(Node *n); + + 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: + + int CreateNamespace(String* scope); + + virtual int EmitCtor(Node *n); + + virtual int EmitDtor(Node *n); + + 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: - JSEmitter * emitter; + 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; }; +*/ -/* --------------------------------------------------------------------- - * functionWrapper() - * - * Low level code generator for functions - * --------------------------------------------------------------------- */ +/* +// name of templates +#define V8_INITIALIZER "v8_initializer" +#define V8_DECL_CLASSTEMPLATE "v8_declare_class_template" +#define V8_DEFINE_CLASSTEMPLATE "v8_define_class_template" +#define V8_CREATE_CLASS_INSTANCE "v8_create_class_instance" +#define V8_INHERIT "v8_inherit" +#define V8_REGISTER_CLASS "v8_register_class" +#define V8_CTOR_WRAPPER "v8_ctor_wrapper" +#define V8_GETTER "v8_getter" +#define V8_SETTER "v8_setter" +#define V8_FUNCTION "v8_function" +#define V8_RETRIEVE_THIS "v8_retrieve_this" +#define V8_REGISTER_MEMBER_FUNCTION "v8_register_member_function" +#define V8_REGISTER_GLOBAL_FUNCTION "v8_register_global_function" +#define V8_REGISTER_MEMBER_VARIABLE "v8_register_member_variable" +#define V8_REGISTER_GLOBAL_VARIABLE "v8_register_global_variable" +#define V8_CREATE_NAMESPACE "v8_create_namespace" +#define V8_REGISTER_NAMESPACE "v8_register_namespace" +#define V8_THIS_PTR "v8_this_ptr" -int JAVASCRIPT::functionWrapper(Node *n) { +// keywords used in templates +#define KW_MODULE_NAME "${MODULE}" +#define KW_MANGLED_NAME "${NAME_MANGLED}" +#define KW_UNQUALIFIED_NAME "${NAME_UNQUALIFIED}" +#define KW_CLASSNAME_MANGLED "${CLASSNAME_MANGLED}" +#define KW_BASE_CLASS "${BASE_CLASS}" +#define KW_CONTEXT "${CONTEXT}" +#define KW_TYPE "${TYPE}" +#define KW_ARG "${ARG}" +#define KW_WRAPPER "${WRAPPER}" +#define KW_GETTER "${GETTER}" +#define KW_SETTER "${SETTER}" - // note: the default implementation only prints a message - // Language::functionWrapper(n); +#define KW_NAME_SPACES "${PART_NAMESPACES}" +#define KW_CLASS_TEMPLATES "${PART_CLASS_TEMPLATES}" +#define KW_WRAPPERS "${PART_WRAPPERS}" +#define KW_INHERITANCE "${PART_INHERITANCE}" +#define KW_CLASS_INSTANCES "${PART_CLASS_INSTANCES}" +#define KW_STATIC_WRAPPERS "${PART_STATIC_WRAPPERS}" +#define KW_REGISTER_CLASSES "${PART_REGISTER_CLASSES}" +#define KW_REGISTER_NS "${PART_REGISTER_NS}" - emitter->emitWrapperFunction(n); +#define KW_LOCALS "${LOCALS}" +#define KW_CODE "${CODE}" +#define KW_MARSHAL_INPUT "${MARSHAL_INPUT}" +#define KW_ACTION "${ACTION}" +#define KW_MARSHAL_OUTPUT "${MARSHAL_OUTPUT}" - return SWIG_OK; +V8Emitter::V8Emitter() + : JSEmitter(), + GLOBAL(NewString("global")), + NULL_STR(NewString("0")), + namespaces(NewHash()) +{ } -/* --------------------------------------------------------------------- - * functionHandler() - * - * Function handler for generating wrappers for functions - * --------------------------------------------------------------------- */ -int JAVASCRIPT::functionHandler(Node *n) { - - if (GetFlag(n, "isextension") == 1) - SetFlag(n, "ismember"); - - emitter->enterFunction(n); - - Language::functionHandler(n); - - emitter->exitFunction(n); - - return SWIG_OK; +V8Emitter::~V8Emitter() +{ + Delete(GLOBAL); + Delete(NULL_STR); + Delete(namespaces); } -/* --------------------------------------------------------------------- - * globalfunctionHandler() - * - * Function handler for generating wrappers for functions - * --------------------------------------------------------------------- */ +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); + } -int JAVASCRIPT::globalfunctionHandler(Node *n) { - emitter->switchNamespace(n); + 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(""); - Language::globalfunctionHandler(n); - return SWIG_OK; -} + // note: this is necessary for built-in generation of swig runtime code + Swig_register_filebyname("runtime", f_runtime); -int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { - // workaround: storage=static is not set for static member functions - emitter->setStaticFlag(true); - Language::staticmemberfunctionHandler(n); - emitter->setStaticFlag(false); - return SWIG_OK; -} - - -/* --------------------------------------------------------------------- - * variableHandler() - * - * Function handler for generating wrappers for variables - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::variableHandler(Node *n) { - - if (!is_assignable(n) - // HACK: don't know why this is assignable? But does not compile - || Equal(Getattr(n, "type"), "a().char")) { - SetFlag(n, "wrap:immutable"); - } - emitter->enterVariable(n); - - Language::variableHandler(n); - - emitter->exitVariable(n); - - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * globalvariableHandler() - * - * Function handler for generating wrappers for global variables - * --------------------------------------------------------------------- */ - -int JAVASCRIPT::globalvariableHandler(Node *n) { - - emitter->switchNamespace(n); - - Language::globalvariableHandler(n); - return SWIG_OK; -} - -/* --------------------------------------------------------------------- - * constantHandler() - * - * Function handler for generating wrappers for constants - * --------------------------------------------------------------------- */ - - -int JAVASCRIPT::constantWrapper(Node *n) { - - // TODO: handle callback declarations - //Note: callbacks trigger this wrapper handler - if (Equal(Getattr(n, "kind"), "function")) { return SWIG_OK; - } - //Language::constantWrapper(n); - emitter->emitConstant(n); - - return SWIG_OK; } -/* --------------------------------------------------------------------- - * classHandler() - * - * Function handler for generating wrappers for class - * --------------------------------------------------------------------- */ +int V8Emitter::dump(Node *n) +{ + // Get the module name + String* module = Getattr(n,"name"); -int JAVASCRIPT::classHandler(Node *n) { - emitter->switchNamespace(n); + // write the swig banner + Swig_banner(f_wrap_cpp); - emitter->enterClass(n); - Language::classHandler(n); - emitter->exitClass(n); + 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); - return SWIG_OK; + // 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); + + return SWIG_OK; } -int JAVASCRIPT::fragmentDirective(Node *n) { - - // catch all fragment directives that have "templates" as location - // and register them at the emitter. - String *section = Getattr(n, "section"); - - if (Cmp(section, "templates") == 0) { - emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code")); - } else { - Swig_fragment_register(n); - } - - 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; } -int JAVASCRIPT::constantDirective(Node *n) { - - Language::constantDirective(n); - - return SWIG_OK; +int V8Emitter::SwitchContext(Node *n) +{ + 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_context = Getattr(namespaces, scope); + } else { + current_context = GLOBAL; + } + + return SWIG_OK; } -/* --------------------------------------------------------------------- - * top() - * - * Function handler for processing top node of the parse tree - * Wrapper code generation essentially starts from here - * --------------------------------------------------------------------- */ +int V8Emitter::CreateNamespace(String* scope) { + String* parent_scope = Swig_scopename_prefix(scope); + String* parent_scope_mangled = 0; -int JAVASCRIPT::top(Node *n) { + if(!parent_scope) { + parent_scope_mangled = NewString("global"); + } else { + parent_scope_mangled = Swig_name_mangle(parent_scope); - emitter->initialize(n); + } + + 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); - Language::top(n); + 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()); - emitter->dump(n); - emitter->close(); - - delete emitter; - - return SWIG_OK; + Delete(parent_scope); + Delete(parent_scope_mangled); + Delete(scope_unqualified); + return SWIG_OK; } -/* --------------------------------------------------------------------- - * main() - * - * Entry point for the JAVASCRIPT module - * --------------------------------------------------------------------- */ +int V8Emitter::EnterClass(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); -void JAVASCRIPT::main(int argc, char *argv[]) { + // 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); - // Set javascript subdirectory in SWIG library - SWIG_library_directory("javascript"); + return SWIG_OK; +} - int mode = -1; +int V8Emitter::ExitClass(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); - bool debug_templates = false; - for (int i = 1; i < argc; i++) { - if (argv[i]) { - if (strcmp(argv[i], "-v8") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::V8; - SWIG_library_directory("javascript/v8"); - } else if (strcmp(argv[i], "-jsc") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::JavascriptCore; - SWIG_library_directory("javascript/jsc"); - } else if (strcmp(argv[i], "-qt") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::QtScript; - SWIG_library_directory("javascript/qt"); - } else if (strcmp(argv[i], "-debug-templates") == 0) { - Swig_mark_arg(i); - debug_templates = true; + Delete(current_classname_mangled); + Delete(current_classname_unqualified); + current_classname_mangled = 0; + current_classname_unqualified = 0; + current_class_type = 0; + + return SWIG_OK; +} + +int V8Emitter::EnterVariable(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); + } else { + current_variable_mangled = Swig_string_mangle(Getattr(n, "name")); + } + + current_getter = NULL_STR; + current_setter = NULL_STR; + + return SWIG_OK; +} + +int V8Emitter::ExitVariable(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; +} + +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) +{ + // 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); + } + } 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); + } + + + Delete(current_function_mangled); + Delete(current_function_unqualified); + current_function_mangled = 0; + current_function_unqualified = 0; + + return SWIG_OK; +} + +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(current_wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"),0)); + + String* action = emit_action(n); + Printv(current_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); + + Wrapper_pretty_print(t.str(), f_wrapper); + + return SWIG_OK; +} + +int V8Emitter::EmitDtor(Node* n) +{ + // TODO: + // find out how to register a dtor in v8 + return SWIG_OK; +} + +int V8Emitter::EmitGetter(Node *n, bool is_member) { + Template t_getter(GetTemplate(V8_GETTER)); + + current_getter = Getattr(n,"wrap:name"); + + ParmList *params = Getattr(n,"parms"); + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_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); + + t_getter.Replace(KW_MANGLED_NAME, current_variable_mangled) + .Replace(KW_LOCALS, current_wrapper->locals) + .Replace(KW_CODE, current_wrapper->code); + + Wrapper_pretty_print(t_getter.str(), f_wrapper); + + return SWIG_OK; +} + +int V8Emitter::EmitSetter(Node* n, bool is_member) +{ + Template t_setter(GetTemplate(V8_SETTER)); + + current_setter = Getattr(n,"wrap:name"); + + ParmList *params = Getattr(n,"parms"); + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_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); + + t_setter.Replace(KW_MANGLED_NAME, current_variable_mangled) + .Replace(KW_LOCALS, current_wrapper->locals) + .Replace(KW_CODE, current_wrapper->code); + + Wrapper_pretty_print(t_setter.str(), f_wrapper); + + return SWIG_OK; +} + + +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); + + ParmList *params = Getattr(n,"parms"); + emit_parameter_variables(params, current_wrapper); + emit_attach_parmmaps(params, current_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); + + t_function.Replace(KW_MANGLED_NAME, current_function_mangled) + .Replace(KW_LOCALS, current_wrapper->locals) + .Replace(KW_CODE, current_wrapper->code); + Wrapper_pretty_print(t_function.str(), f_wrapper); + + 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")); } - } - } - - switch (mode) { - case JSEmitter::V8: - { - // TODO: emitter = create_v8_emitter(); - break; - } - case JSEmitter::JavascriptCore: - { - emitter = swig_javascript_create_JSC_emitter(); - break; - } - case JSEmitter::QtScript: - { - // TODO: emitter = create_qtscript_emitter(); - break; - } - default: - { - Printf(stderr, "Unknown emitter type."); - SWIG_exit(-1); - break; - } - } - - if (debug_templates) { - emitter->enableDebug(); - } - // Add a symbol to the parser for conditional compilation - Preprocessor_define("SWIGJAVASCRIPT 1", 0); - - // Add typemap definitions - SWIG_typemap_lang("javascript"); - - // Set configuration file - SWIG_config_file("javascript.swg"); - - allow_overloading(); + emit_return_variable(n, type, wrapper); } -/* ----------------------------------------------------------------------------- - * swig_JAVASCRIPT() - Instantiate module - * ----------------------------------------------------------------------------- */ - -static Language *new_swig_javascript() { - return new JAVASCRIPT(); +*/ +JSEmitter *swig_javascript_create_V8Emitter() { + return 0; } -extern "C" Language *swig_javascript(void) { - return new_swig_javascript(); -} diff --git a/Source/Modules/javascript_v8.cxx b/Source/Modules/javascript_v8.cxx deleted file mode 100644 index cacceb214..000000000 --- a/Source/Modules/javascript_v8.cxx +++ /dev/null @@ -1,579 +0,0 @@ -#include "javascript_v8.h" -#include "swigmod.h" - -/* ----------------------------------------------------------------------- - * String constants that are used in Lib/javascript/v8/javascriptcode.swg - *------------------------------------------------------------------------ */ - -// name of templates -#define V8_INITIALIZER "v8_initializer" -#define V8_DECL_CLASSTEMPLATE "v8_declare_class_template" -#define V8_DEFINE_CLASSTEMPLATE "v8_define_class_template" -#define V8_CREATE_CLASS_INSTANCE "v8_create_class_instance" -#define V8_INHERIT "v8_inherit" -#define V8_REGISTER_CLASS "v8_register_class" -#define V8_CTOR_WRAPPER "v8_ctor_wrapper" -#define V8_GETTER "v8_getter" -#define V8_SETTER "v8_setter" -#define V8_FUNCTION "v8_function" -#define V8_RETRIEVE_THIS "v8_retrieve_this" -#define V8_REGISTER_MEMBER_FUNCTION "v8_register_member_function" -#define V8_REGISTER_GLOBAL_FUNCTION "v8_register_global_function" -#define V8_REGISTER_MEMBER_VARIABLE "v8_register_member_variable" -#define V8_REGISTER_GLOBAL_VARIABLE "v8_register_global_variable" -#define V8_CREATE_NAMESPACE "v8_create_namespace" -#define V8_REGISTER_NAMESPACE "v8_register_namespace" -#define V8_THIS_PTR "v8_this_ptr" - - -// keywords used in templates -#define KW_MODULE_NAME "${MODULE}" -#define KW_MANGLED_NAME "${NAME_MANGLED}" -#define KW_UNQUALIFIED_NAME "${NAME_UNQUALIFIED}" -#define KW_CLASSNAME_MANGLED "${CLASSNAME_MANGLED}" -#define KW_BASE_CLASS "${BASE_CLASS}" -#define KW_CONTEXT "${CONTEXT}" -#define KW_TYPE "${TYPE}" -#define KW_ARG "${ARG}" -#define KW_WRAPPER "${WRAPPER}" -#define KW_GETTER "${GETTER}" -#define KW_SETTER "${SETTER}" - -#define KW_NAME_SPACES "${PART_NAMESPACES}" -#define KW_CLASS_TEMPLATES "${PART_CLASS_TEMPLATES}" -#define KW_WRAPPERS "${PART_WRAPPERS}" -#define KW_INHERITANCE "${PART_INHERITANCE}" -#define KW_CLASS_INSTANCES "${PART_CLASS_INSTANCES}" -#define KW_STATIC_WRAPPERS "${PART_STATIC_WRAPPERS}" -#define KW_REGISTER_CLASSES "${PART_REGISTER_CLASSES}" -#define KW_REGISTER_NS "${PART_REGISTER_NS}" - -#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()) -{ -} - -V8Emitter::~V8Emitter() -{ - Delete(GLOBAL); - Delete(NULL_STR); - Delete(namespaces); -} - -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); - } - - 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(""); - - // note: this is necessary for built-in generation of swig runtime code - Swig_register_filebyname("runtime", f_runtime); - - return SWIG_OK; -} - -int V8Emitter::Dump(Node *n) -{ - /* Get the module name */ - String* module = Getattr(n,"name"); - - // 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); - - // 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); - - 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; -} - -int V8Emitter::SwitchContext(Node *n) -{ - 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_context = Getattr(namespaces, scope); - } else { - current_context = GLOBAL; - } - - return SWIG_OK; -} - -int V8Emitter::CreateNamespace(String* scope) { - String* parent_scope = Swig_scopename_prefix(scope); - String* parent_scope_mangled = 0; - - if(!parent_scope) { - parent_scope_mangled = NewString("global"); - } else { - parent_scope_mangled = Swig_name_mangle(parent_scope); - - } - - 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; -} - -int V8Emitter::EnterClass(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; -} - -int V8Emitter::ExitClass(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); - - Delete(current_classname_mangled); - Delete(current_classname_unqualified); - current_classname_mangled = 0; - current_classname_unqualified = 0; - current_class_type = 0; - - return SWIG_OK; -} - -int V8Emitter::EnterVariable(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); - } else { - current_variable_mangled = Swig_string_mangle(Getattr(n, "name")); - } - - current_getter = NULL_STR; - current_setter = NULL_STR; - - return SWIG_OK; -} - -int V8Emitter::ExitVariable(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; -} - -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) -{ - // 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); - } - } 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); - } - - - Delete(current_function_mangled); - Delete(current_function_unqualified); - current_function_mangled = 0; - current_function_unqualified = 0; - - return SWIG_OK; -} - -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(current_wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"),0)); - - String* action = emit_action(n); - Printv(current_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); - - Wrapper_pretty_print(t.str(), f_wrapper); - - return SWIG_OK; -} - -int V8Emitter::EmitDtor(Node* n) -{ - // TODO: - // find out how to register a dtor in v8 - - Printv(f_wrapper, "/* TODO: Wrap dtor */\n", 0); - - return SWIG_OK; -} - -int V8Emitter::EmitGetter(Node *n, bool is_member) { - Template t_getter(GetTemplate(V8_GETTER)); - - current_getter = Getattr(n,"wrap:name"); - - ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_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); - - t_getter.Replace(KW_MANGLED_NAME, current_variable_mangled) - .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_CODE, current_wrapper->code); - - Wrapper_pretty_print(t_getter.str(), f_wrapper); - - return SWIG_OK; -} - -int V8Emitter::EmitSetter(Node* n, bool is_member) -{ - Template t_setter(GetTemplate(V8_SETTER)); - - current_setter = Getattr(n,"wrap:name"); - - ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_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); - - t_setter.Replace(KW_MANGLED_NAME, current_variable_mangled) - .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_CODE, current_wrapper->code); - - Wrapper_pretty_print(t_setter.str(), f_wrapper); - - return SWIG_OK; -} - - -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); - - ParmList *params = Getattr(n,"parms"); - emit_parameter_variables(params, current_wrapper); - emit_attach_parmmaps(params, current_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); - - t_function.Replace(KW_MANGLED_NAME, current_function_mangled) - .Replace(KW_LOCALS, current_wrapper->locals) - .Replace(KW_CODE, current_wrapper->code); - Wrapper_pretty_print(t_function.str(), f_wrapper); - - 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); - } -} - -/* --------------------------------------------------------------------- - * marshalOutput() - * - * Process the return value of the C/C++ function call - * and convert them into the Javascript types using the - * supplied typemaps. - * --------------------------------------------------------------------- */ - -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); -} - -Parm* V8Emitter::skipIgnoredArgs(Parm *p) { - while (checkAttribute(p, "tmap:in:numinputs", "0")) { - p = Getattr(p, "tmap:in:next"); - } - return p; -} - - -JSEmitter* create_v8_emitter() -{ - return new V8Emitter(); -} From 9af3c4879bbd2103548afbfbff200eff6a78418a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:58:11 +0000 Subject: [PATCH 033/352] Switch to global variable for enabling code template debug information. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13767 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 1fde3cd0c..4ba83f8f2 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -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 @@ public: */ Template getTemplate(const String *name); - void enableDebug(); - void setStaticFlag(bool is_static = false); protected: @@ -246,12 +249,6 @@ protected: 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 @@ protected: State state; bool is_static; - - bool debug; }; /* factory methods for concrete JSEmitters: */ @@ -525,7 +520,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } if (debug_templates) { - emitter->enableDebug(); + js_template_enable_debug = true; } // Add a symbol to the parser for conditional compilation @@ -595,8 +590,7 @@ private: JSEmitter::JSEmitter() : empty_string(NewString("")), current_wrapper(NULL), - is_static(false), - debug(false) + is_static(false) { templates = NewHash(); } @@ -630,7 +624,7 @@ Template JSEmitter::getTemplate(const String *name) { SWIG_exit(EXIT_FAILURE); } - Template t(templ, name, debug); + Template t(templ, name, js_template_enable_debug); return t; } @@ -639,10 +633,6 @@ int JSEmitter::initialize(Node *) { return SWIG_OK; } -void JSEmitter::enableDebug() { - debug = true; -} - void JSEmitter::setStaticFlag(bool _is_static) { is_static = _is_static; } From b778c4816b63e12e72cb3c2a97e904411465329a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:58:23 +0000 Subject: [PATCH 034/352] Remove a global variable from JSEmitter by making use of JSEmitterState. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13768 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 84 ++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 4ba83f8f2..d8ab2c33c 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -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 @@ private: 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 @@ public: */ Template getTemplate(const String *name); - void setStaticFlag(bool is_static = false); + State &getState(); protected: @@ -259,8 +280,6 @@ protected: Wrapper *current_wrapper; State state; - - bool is_static; }; /* factory methods for concrete JSEmitters: */ @@ -351,9 +370,9 @@ int JAVASCRIPT::globalfunctionHandler(Node *n) { 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 @@ private: 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,12 +639,12 @@ Template JSEmitter::getTemplate(const String *name) { return t; } -int JSEmitter::initialize(Node *) { - return SWIG_OK; +JSEmitterState &JSEmitter::getState() { + return state; } -void JSEmitter::setStaticFlag(bool _is_static) { - is_static = _is_static; +int JSEmitter::initialize(Node *) { + return SWIG_OK; } /* ----------------------------------------------------------------------------- @@ -753,7 +763,7 @@ int JSEmitter::emitWrapperFunction(Node *n) { 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::enterClass(Node *n) { 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 @@ int JSCEmitter::exitFunction(Node *n) { } } - 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 @@ int JSCEmitter::exitVariable(Node *n) { 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 @@ int JSCEmitter::exitClass(Node *n) { /* 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 @@ int JSCEmitter::emitFunction(Node *n, bool is_member) { // 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"); - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + // 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 @@ int JSCEmitter::emitFunction(Node *n, bool is_member) { .replace("${CODE}", current_wrapper->code) .pretty_print(f_wrappers); + // handle function overloading if (is_overloaded) { Template t_dispatch_case = getTemplate("JS_function_dispatch_case"); From 8577ae41791303471a80fde1384f319ef5ababb9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:58:37 +0000 Subject: [PATCH 035/352] Minor clean up. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13769 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 4 +- Source/Modules/javascript.cxx | 410 ++++++++++++++++++---------------- 2 files changed, 225 insertions(+), 189 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 80f807631..afe135964 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -535,7 +535,7 @@ JSCXXFLAGS = @JSCXXFLAGS@ # ---------------------------------------------------------------- javascript: $(SRCS) - $(SWIG) -javascript -jsc -debug-templates $(SWIGOPT) $(INTERFACEPATH) + $(SWIG) -javascript -jsc $(SWIGOPT) $(INTERFACEPATH) $(CC) -c $(CCSHARED) $(JSCFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JS_INCLUDE) $(JSLDSHARED) $(CCSHARED) $(JSCFLAGS) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) @@ -544,7 +544,7 @@ javascript: $(SRCS) # ---------------------------------------------------------------- javascript_cpp: $(SRCS) - $(SWIG) -javascript -jsc -c++ -debug-templates $(SWIGOPT) $(INTERFACEPATH) + $(SWIG) -javascript -jsc -c++ $(SWIGOPT) $(INTERFACEPATH) $(CXX) -c $(CCSHARED) $(JSCXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JS_INCLUDE) $(JSCXXSHARED) $(CCSHARED) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index d8ab2c33c..fd41f90e1 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1,13 +1,5 @@ #include "swigmod.h" -#include -#include -#include - -/********************************************************************** - * JAVASCRIPT: swig module implementation - **********************************************************************/ - /** * Enables extra debugging information in typemaps. */ @@ -15,7 +7,6 @@ bool js_template_enable_debug = false; // keywords used for state variables -#undef NAME #define NAME "name" #define NAME_MANGLED "name_mangled" #define TYPE "type" @@ -33,88 +24,60 @@ class JSEmitterState { public: - JSEmitterState(): - _global(NewHash()) { - // initialize sub-hashes - Setattr(_global, "class", NewHash()); - Setattr(_global, "function", NewHash()); - Setattr(_global, "variable", NewHash()); - } + JSEmitterState(); - ~JSEmitterState() { Delete(_global); } + ~JSEmitterState(); + + DOH *global(); - DOH *getState(const char* key, bool _new = false) { - if (_new) { - Hash *hash = NewHash(); - Setattr(_global, key, hash); - } - return Getattr(_global, key); - } + DOH *global(const char* key, DOH *initial = 0); - DOH *global() { return _global; } - - DOH *global(const char* key, DOH *initial=0) { - if(initial != 0) { - Setattr(_global, key, initial); - } - return Getattr(_global, key); - } - - DOH *clazz(bool _new = false) { - return getState("class", _new); - } + DOH *clazz(bool reset = false); - DOH *clazz(const char* key, DOH *initial=0) { - DOH *c = clazz(); - if(initial != 0) { - Setattr(c, key, initial); - } - return Getattr(c, key); - } + DOH *clazz(const char* key, DOH *initial = 0); - DOH *function(bool _new = false) { - return getState("function", _new); - } + DOH *function(bool reset = false); - DOH *function(const char* key, DOH *initial=0) { - DOH *f = function(); - if(initial != 0) { - Setattr(f, key, initial); - } - return Getattr(f, key); - } + DOH *function(const char* key, DOH *initial = 0); - DOH *variable(bool _new = false) { - return getState("variable", _new); - } + DOH *variable(bool reset = false); - DOH *variable(const char* key, DOH *initial=0) { - DOH *v = variable(); - if(initial != 0) { - Setattr(v, key, initial); - } - return Getattr(v, key); - } + DOH *variable(const char* key, DOH *initial = 0); - static int IsSet(DOH *val) { - if (!val) { - return 0; - } else { - const char *cval = Char(val); - if (!cval) - return 0; - return (strcmp(cval, "0") != 0) ? 1 : 0; - } - } + static int IsSet(DOH *val); private: + DOH *getState(const char* key, bool reset = false); + Hash *_global; }; -/* forward decl: Template is a convenience helper class for dealing with - * code fragments */ -class Template; +/** + * A convenience class that wraps a code snippet used as template + * for code generation. + */ +class Template { + +public: + Template(const String *code); + + Template(const String *code, const String *templateName); + + ~Template(); + + String *str(); + + Template& replace(const String *pattern, const String *repl); + + Template& pretty_print(DOH *doh); + +private: + + String *code; + String *templateName; + +}; /** * JSEmitter represents an abstraction of javascript code generators @@ -134,9 +97,9 @@ public: QtScript }; - JSEmitter(); + JSEmitter(); - virtual ~JSEmitter(); + virtual ~JSEmitter(); /** * Opens output files and temporary output DOHs. @@ -282,6 +245,10 @@ protected: State state; }; +/********************************************************************** + * JAVASCRIPT: swig module implementation + **********************************************************************/ + /* factory methods for concrete JSEmitters: */ JSEmitter *swig_javascript_create_JSCEmitter(); JSEmitter *swig_javascript_create_V8Emitter(); @@ -385,7 +352,8 @@ int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { int JAVASCRIPT::variableHandler(Node *n) { if (!is_assignable(n) - // HACK: don't know why this is assignable? + // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] + // probably some error in char[] typemap || Equal(Getattr(n, "type"), "a().char")) { SetFlag(n, "wrap:immutable"); } @@ -393,6 +361,7 @@ int JAVASCRIPT::variableHandler(Node *n) { emitter->enterVariable(n); Language::variableHandler(n); emitter->exitVariable(n); + return SWIG_OK; } @@ -406,6 +375,7 @@ int JAVASCRIPT::globalvariableHandler(Node *n) { emitter->switchNamespace(n); Language::globalvariableHandler(n); + return SWIG_OK; } @@ -422,9 +392,8 @@ int JAVASCRIPT::constantWrapper(Node *n) { if (Equal(Getattr(n, "kind"), "function")) { return SWIG_OK; } - - //Language::constantWrapper(n); emitter->emitConstant(n); + return SWIG_OK; } @@ -506,7 +475,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) { Swig_mark_arg(i); mode = JSEmitter::QtScript; SWIG_library_directory("javascript/qt"); - } else if (strcmp(argv[i], "-debug-templates") == 0) { + } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { Swig_mark_arg(i); debug_templates = true; } @@ -570,30 +539,6 @@ extern "C" Language *swig_javascript(void) { * Emitter implementations **********************************************************************/ -/** - * A convenience class that wraps a code snippet used as template for code generation. - */ -class Template { - -public: - Template(const String *code); - - Template(const String *code, const String *templateName, bool debug = false); - - ~Template(); - - String *str(); - - Template& replace(const String *pattern, const String *repl); - - Template& pretty_print(DOH *doh); - -private: - String *code; - String *templateName; - bool debug; -}; - /* ----------------------------------------------------------------------------- * JSEmitter() * ----------------------------------------------------------------------------- */ @@ -634,7 +579,7 @@ Template JSEmitter::getTemplate(const String *name) { SWIG_exit(EXIT_FAILURE); } - Template t(templ, name, js_template_enable_debug); + Template t(templ, name); return t; } @@ -820,86 +765,6 @@ bool JSEmitter::isSetterMethod(Node *n) { return (__swigjs_str_ends_with((char *) Data(symname), "_set") != 0); } - -/* ----------------------------------------------------------------------------- - * Template::Template() : creates a Template class for given template code - * ----------------------------------------------------------------------------- */ - -Template::Template(const String *code_) { - - if (!code_) { - Printf(stdout, "Template code was null. Illegal input for template."); - SWIG_exit(EXIT_FAILURE); - } - debug = false; - code = NewString(code_); - templateName = NewString(""); -} - -Template::Template(const String *code_, const String *templateName_, bool debug_) { - - if (!code_) { - Printf(stdout, "Template code was null. Illegal input for template."); - SWIG_exit(EXIT_FAILURE); - } - - code = NewString(code_); - templateName = NewString(templateName_); - debug = debug_; -} - - -/* ----------------------------------------------------------------------------- - * Template::~Template() : cleans up of Template. - * ----------------------------------------------------------------------------- */ - -Template::~Template() { - Delete(code); - Delete(templateName); -} - -/* ----------------------------------------------------------------------------- - * String* Template::str() : retrieves the current content of the template. - * ----------------------------------------------------------------------------- */ - -String *Template::str() { - if (debug) { - String *pre_code = NewString(""); - String *post_code = NewString(""); - String *debug_code = NewString(""); - Printf(pre_code, "//begin fragment(\"%s\")\n", templateName); - Printf(post_code, "//end fragment(\"%s\")\n", templateName); - Printf(debug_code, "%s\n%s\n%s", pre_code, code, post_code); - - Delete(code); - Delete(pre_code); - Delete(post_code); - - code = debug_code; - } - return code; -} - -/* ----------------------------------------------------------------------------- - * Template& Template::replace(const String* pattern, const String* repl) : - * - * replaces all occurences of a given pattern with a given replacement. - * - * - pattern: the pattern to be replaced - * - repl: the replacement string - * - returns a reference to the Template to allow chaining of methods. - * ----------------------------------------------------------------------------- */ - -Template& Template::replace(const String *pattern, const String *repl) { - Replaceall(code, pattern, repl); - return *this; -} - -Template& Template::pretty_print(DOH *doh) { - Wrapper_pretty_print(str(), doh); - return *this; -} - /********************************************************************** * JavascriptCore: JSEmitter implementation for JavascriptCore engine **********************************************************************/ @@ -2315,3 +2180,174 @@ JSEmitter *swig_javascript_create_V8Emitter() { return 0; } + +/********************************************************************** + * Helper implementations + **********************************************************************/ + +JSEmitterState::JSEmitterState() + : _global(NewHash()) +{ + // initialize sub-hashes + Setattr(_global, "class", NewHash()); + Setattr(_global, "function", NewHash()); + Setattr(_global, "variable", NewHash()); +} + +JSEmitterState::~JSEmitterState() +{ + Delete(_global); +} + +DOH *JSEmitterState::getState(const char* key, bool _new) +{ + if (_new) { + Hash *hash = NewHash(); + Setattr(_global, key, hash); + } + return Getattr(_global, key); +} + +DOH *JSEmitterState::global() { + return _global; +} + +DOH *JSEmitterState::global(const char* key, DOH *initial) +{ + if(initial != 0) { + Setattr(_global, key, initial); + } + return Getattr(_global, key); +} + +DOH *JSEmitterState::clazz(bool _new) +{ + return getState("class", _new); +} + +DOH *JSEmitterState::clazz(const char* key, DOH *initial) +{ + DOH *c = clazz(); + if(initial != 0) { + Setattr(c, key, initial); + } + return Getattr(c, key); +} + +DOH *JSEmitterState::function(bool _new) +{ + return getState("function", _new); +} + +DOH *JSEmitterState::function(const char* key, DOH *initial) +{ + DOH *f = function(); + if(initial != 0) { + Setattr(f, key, initial); + } + return Getattr(f, key); +} + +DOH *JSEmitterState::variable(bool _new) +{ + return getState("variable", _new); +} + +DOH *JSEmitterState::variable(const char* key, DOH *initial) +{ + DOH *v = variable(); + if(initial != 0) { + Setattr(v, key, initial); + } + return Getattr(v, key); +} + +/*static*/ +int JSEmitterState::IsSet(DOH *val) +{ + if (!val) { + return 0; + } else { + const char *cval = Char(val); + if (!cval) + return 0; + return (strcmp(cval, "0") != 0) ? 1 : 0; + } +} + +/* ----------------------------------------------------------------------------- + * Template::Template() : creates a Template class for given template code + * ----------------------------------------------------------------------------- */ + +Template::Template(const String *code_) { + + if (!code_) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + code = NewString(code_); + templateName = NewString(""); +} + +Template::Template(const String *code_, const String *templateName_) { + + if (!code_) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + + code = NewString(code_); + templateName = NewString(templateName_); +} + + +/* ----------------------------------------------------------------------------- + * Template::~Template() : cleans up of Template. + * ----------------------------------------------------------------------------- */ + +Template::~Template() { + Delete(code); + Delete(templateName); +} + +/* ----------------------------------------------------------------------------- + * String* Template::str() : retrieves the current content of the template. + * ----------------------------------------------------------------------------- */ + +String *Template::str() { + if (js_template_enable_debug) { + String *pre_code = NewString(""); + String *post_code = NewString(""); + String *debug_code = NewString(""); + Printf(pre_code, "//begin fragment(\"%s\")\n", templateName); + Printf(post_code, "//end fragment(\"%s\")\n", templateName); + Printf(debug_code, "%s\n%s\n%s", pre_code, code, post_code); + + Delete(code); + Delete(pre_code); + Delete(post_code); + + code = debug_code; + } + return code; +} + +/* ----------------------------------------------------------------------------- + * Template& Template::replace(const String* pattern, const String* repl) : + * + * replaces all occurences of a given pattern with a given replacement. + * + * - pattern: the pattern to be replaced + * - repl: the replacement string + * - returns a reference to the Template to allow chaining of methods. + * ----------------------------------------------------------------------------- */ + +Template& Template::replace(const String *pattern, const String *repl) { + Replaceall(code, pattern, repl); + return *this; +} + +Template& Template::pretty_print(DOH *doh) { + Wrapper_pretty_print(str(), doh); + return *this; +} From 46624e24e5b6204ce7fd03be433ec1883fd98f96 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:58:49 +0000 Subject: [PATCH 036/352] Remove member variable current_wrapper from JSEmitter. Instead each emitting function creates local wrapper instance. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13770 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 162 ++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 78 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index fd41f90e1..f4c1e6cff 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -239,8 +239,6 @@ protected: String *empty_string; Hash *templates; - - Wrapper *current_wrapper; State state; }; @@ -544,8 +542,7 @@ extern "C" Language *swig_javascript(void) { * ----------------------------------------------------------------------------- */ JSEmitter::JSEmitter() -: empty_string(NewString("")), - current_wrapper(NULL) +: empty_string(NewString("")) { templates = NewHash(); } @@ -645,10 +642,8 @@ Node *JSEmitter::getBaseClass(Node *n) { while (base.item && GetFlag(base.item, "feature:ignore")) { base = Next(base); } - return base.item; } - return NULL; } @@ -659,9 +654,6 @@ Node *JSEmitter::getBaseClass(Node *n) { 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 @@ int JSEmitter::emitWrapperFunction(Node *n) { } } - DelWrapper(current_wrapper); - current_wrapper = 0; - return ret; } @@ -1225,6 +1214,8 @@ int JSCEmitter::exitClass(Node *n) { } 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 @@ int JSCEmitter::emitCtor(Node *n) { 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 @@ int JSCEmitter::emitCtor(Node *n) { .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::emitDtor(Node *) { } 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 @@ int JSCEmitter::emitGetter(Node *n, bool is_member) { 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 @@ int JSCEmitter::emitSetter(Node *n, bool is_member) { 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 @@ int JSCEmitter::emitSetter(Node *n, bool is_member) { 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::emitSetter(Node *n, bool is_member) { 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 @@ int JSCEmitter::emitConstant(Node *n) { 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 @@ int JSCEmitter::emitFunction(Node *n, bool is_member) { // 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 @@ int JSCEmitter::emitFunction(Node *n, bool is_member) { Delete(argcount); } + + DelWrapper(wrapper); return SWIG_OK; } @@ -1994,15 +2000,15 @@ int V8Emitter::EmitCtor(Node* n) 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 @@ int V8Emitter::EmitGetter(Node *n, bool is_member) { 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 @@ int V8Emitter::EmitSetter(Node* n, bool is_member) 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 @@ int V8Emitter::EmitFunction(Node* n, bool is_member) 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; From c470864d127561d55d36e115ffffffc33cf2ff96 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:59:03 +0000 Subject: [PATCH 037/352] Remove some dead code and an obsolete member variable from JSEmitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13771 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 4 +-- Source/Modules/javascript.cxx | 68 ++++++++++------------------------- 2 files changed, 20 insertions(+), 52 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index afe135964..250ce4e0e 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -535,7 +535,7 @@ JSCXXFLAGS = @JSCXXFLAGS@ # ---------------------------------------------------------------- javascript: $(SRCS) - $(SWIG) -javascript -jsc $(SWIGOPT) $(INTERFACEPATH) + $(SWIG) -javascript -jsc -debug-codetemplates $(SWIGOPT) $(INTERFACEPATH) $(CC) -c $(CCSHARED) $(JSCFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JS_INCLUDE) $(JSLDSHARED) $(CCSHARED) $(JSCFLAGS) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) @@ -544,7 +544,7 @@ javascript: $(SRCS) # ---------------------------------------------------------------- javascript_cpp: $(SRCS) - $(SWIG) -javascript -jsc -c++ $(SWIGOPT) $(INTERFACEPATH) + $(SWIG) -c++ -javascript -jsc -debug-codetemplates $(SWIGOPT) $(INTERFACEPATH) $(CXX) -c $(CCSHARED) $(JSCXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JS_INCLUDE) $(JSCXXSHARED) $(CCSHARED) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index f4c1e6cff..67c145dc7 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -6,7 +6,6 @@ bool js_template_enable_debug = false; // keywords used for state variables - #define NAME "name" #define NAME_MANGLED "name_mangled" #define TYPE "type" @@ -226,18 +225,10 @@ protected: */ Node *getBaseClass(Node *n); - /** - * Helper function to retrieve a certain typemap. - */ - const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0); - Parm *skipIgnoredArgs(Parm *p); protected: - // empty string used at different places in the code - String *empty_string; - Hash *templates; State state; @@ -334,10 +325,14 @@ int JAVASCRIPT::globalfunctionHandler(Node *n) { * --------------------------------------------------------------------- */ int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { - // workaround: storage=static is not set for static member functions - emitter->getState().function(IS_STATIC, NewString("1")); + /* + * Note: storage=static is not set for static member functions. + * It also is not working to set that attribute here. + * Instead the according state variable is set directly. + */ + SetFlag(emitter->getState().function(), IS_STATIC); Language::staticmemberfunctionHandler(n); - emitter->getState().function(IS_STATIC, NULL); + Setattr(emitter->getState().function(), IS_STATIC, 0); return SWIG_OK; } @@ -542,9 +537,8 @@ extern "C" Language *swig_javascript(void) { * ----------------------------------------------------------------------------- */ JSEmitter::JSEmitter() -: empty_string(NewString("")) +: templates(NewHash()) { - templates = NewHash(); } /* ----------------------------------------------------------------------------- @@ -552,7 +546,6 @@ JSEmitter::JSEmitter() * ----------------------------------------------------------------------------- */ JSEmitter::~JSEmitter() { - Delete(empty_string); Delete(templates); } @@ -589,36 +582,6 @@ int JSEmitter::initialize(Node *) { return SWIG_OK; } -/* ----------------------------------------------------------------------------- - * JSEmitter::typemapLookup() - * - * n - for input only and must contain info for Getfile(n) and Getline(n) to work - * tmap_method - typemap method name - * type - typemap type to lookup - * warning - warning number to issue if no typemaps found - * typemap_attributes - the typemap attributes are attached to this node and will - * also be used for temporary storage if non null - * return is never NULL, unlike Swig_typemap_lookup() - * ----------------------------------------------------------------------------- */ - -const String *JSEmitter::typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes) { - Node *node = !typemap_attributes ? NewHash() : typemap_attributes; - Setattr(node, "type", type); - Setfile(node, Getfile(n)); - Setline(node, Getline(n)); - const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); - if (!tm) { - tm = empty_string; - if (warning != WARN_NONE) { - Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); - } - } - if (!typemap_attributes) { - Delete(node); - } - return tm; -} - /* --------------------------------------------------------------------- * skipIgnoredArgs() * --------------------------------------------------------------------- */ @@ -1221,7 +1184,7 @@ int JSCEmitter::emitCtor(Node *n) { String *mangled_name = SwigType_manglestr(Getattr(n, "name")); String *overname = Getattr(n, "sym:overname"); - String *wrap_name = Swig_name_wrapper(Getattr(n, "wrap:name")); + String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); Setattr(n, "wrap:name", wrap_name); ParmList *params = Getattr(n, "parms"); @@ -1272,15 +1235,18 @@ int JSCEmitter::emitGetter(Node *n, bool is_member) { Template t_getter(getTemplate("JS_getproperty")); bool is_static = Equal(Getattr(n, "storage"), "static"); - String *wrap_name = Swig_name_wrapper(Getattr(n, "wrap:name")); + // prepare wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); Setattr(n, "wrap:name", wrap_name); state.variable(GETTER, wrap_name); + // prepare local variables ParmList *params = Getattr(n, "parms"); 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, wrapper, Getter, is_member, is_static); marshalOutput(n, action, wrapper); @@ -1307,14 +1273,17 @@ int JSCEmitter::emitSetter(Node *n, bool is_member) { Template t_setter(getTemplate("JS_setproperty")); bool is_static = Equal(Getattr(n, "storage"), "static"); - String *wrap_name = Swig_name_wrapper(Getattr(n, "wrap:name")); + // prepare wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); Setattr(n, "wrap:name", wrap_name); state.variable(SETTER, wrap_name); + // prepare local variables ParmList *params = Getattr(n, "parms"); emit_parameter_variables(params, wrapper); emit_attach_parmmaps(params, wrapper); + // prepare code part String *action = emit_action(n); marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); Append(wrapper->code, action); @@ -1351,7 +1320,7 @@ int JSCEmitter::emitConstant(Node *n) { // prepare local variables Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); - // prepare action + // prepare code part String *action = NewString(""); String *value = Getattr(n, "rawval"); if (value == NULL) { @@ -1362,7 +1331,6 @@ int JSCEmitter::emitConstant(Node *n) { } Printf(action, "result = %s;\n", value); Setattr(n, "wrap:action", action); - marshalOutput(n, action, wrapper); t_getter.replace("${getname}", wrap_name) From 16077503c86919dbedd3d76318a23323404f4f58 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:59:18 +0000 Subject: [PATCH 038/352] Fix former workaround by concerning static member functions. "storage" attribute is removed by Language::staticmemberfunctionHandler which was resolved by a workaround before. Now, the implementation relies completely on state flags retrieved at a proper point. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13772 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 85 ++++++++--------- Source/Modules/javascript_emitter.h | 139 ---------------------------- Source/Modules/javascript_v8.h | 90 ------------------ 3 files changed, 40 insertions(+), 274 deletions(-) delete mode 100644 Source/Modules/javascript_emitter.h delete mode 100644 Source/Modules/javascript_v8.h diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 67c145dc7..1c6ab7e78 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -202,17 +202,17 @@ protected: /** * Generates code for a function. */ - virtual int emitFunction(Node *n, bool is_member) = 0; + virtual int emitFunction(Node *n, bool is_member, bool is_static) = 0; /** * Generates code for a getter function. */ - virtual int emitGetter(Node *n, bool is_member) = 0; + virtual int emitGetter(Node *n, bool is_member, bool is_static) = 0; /** * Generates code for a setter function. */ - virtual int emitSetter(Node *n, bool is_member) = 0; + 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. @@ -315,6 +315,7 @@ int JAVASCRIPT::functionHandler(Node *n) { int JAVASCRIPT::globalfunctionHandler(Node *n) { emitter->switchNamespace(n); Language::globalfunctionHandler(n); + return SWIG_OK; } @@ -326,13 +327,11 @@ int JAVASCRIPT::globalfunctionHandler(Node *n) { int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { /* - * Note: storage=static is not set for static member functions. - * It also is not working to set that attribute here. - * Instead the according state variable is set directly. + * Note: storage=static is removed by Language::staticmemberfunctionHandler. + * So, don't rely on that after here. Instead use the state variable which is + * set by JSEmitter::enterFunction(). */ - SetFlag(emitter->getState().function(), IS_STATIC); - Language::staticmemberfunctionHandler(n); - Setattr(emitter->getState().function(), IS_STATIC, 0); + Language::staticmemberfunctionHandler(n); return SWIG_OK; } @@ -344,14 +343,7 @@ int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { int JAVASCRIPT::variableHandler(Node *n) { - if (!is_assignable(n) - // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] - // probably some error in char[] typemap - || Equal(Getattr(n, "type"), "a().char")) { - SetFlag(n, "wrap:immutable"); - } - - emitter->enterVariable(n); + emitter->enterVariable(n); Language::variableHandler(n); emitter->exitVariable(n); @@ -622,20 +614,18 @@ int JSEmitter::emitWrapperFunction(Node *n) { if (kind) { bool is_member = GetFlag(n, "ismember"); if (Cmp(kind, "function") == 0) { - ret = emitFunction(n, is_member); - + bool is_static = GetFlag(state.function(), IS_STATIC); + ret = emitFunction(n, is_member, is_static); } else if (Cmp(kind, "variable") == 0) { + bool is_static = GetFlag(state.variable(), IS_STATIC); if (isSetterMethod(n)) { - ret = emitSetter(n, is_member); - + ret = emitSetter(n, is_member, is_static); } else { - ret = emitGetter(n, is_member); - + ret = emitGetter(n, is_member, is_static); } } else { Printf(stderr, "Warning: unsupported wrapper function type\n"); Swig_print_node(n); - ret = SWIG_ERROR; } } else { @@ -643,10 +633,8 @@ int JSEmitter::emitWrapperFunction(Node *n) { if (Cmp(view, "constructorHandler") == 0) { ret = emitCtor(n); - } else if (Cmp(view, "destructorHandler") == 0) { ret = emitDtor(n); - } else { Printf(stderr, "Warning: unsupported wrapper function type"); Swig_print_node(n); @@ -677,14 +665,29 @@ int JSEmitter::enterFunction(Node *n) { state.function(true); state.function(NAME, Getattr(n, "sym:name")); + if(Equal(Getattr(n, "storage"), "static")) { + SetFlag(state.function(), IS_STATIC); + } return SWIG_OK; } int JSEmitter::enterVariable(Node *n) { + state.variable(true); state.variable(NAME, Swig_scopename_last(Getattr(n, "name"))); - state.variable(IS_IMMUTABLE, Getattr(n, "wrap:immutable")); + + if(Equal(Getattr(n, "storage"), "static")) { + SetFlag(state.variable(), IS_STATIC); + } + + if (!Language::instance()->is_assignable(n) + // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] + // probably some error in char[] typemap + || Equal(Getattr(n, "type"), "a().char")) { + SetFlag(state.variable(), IS_IMMUTABLE); + } + return SWIG_OK; } @@ -763,13 +766,13 @@ protected: virtual int exitClass(Node *n); - virtual int emitFunction(Node *n, bool is_member); + virtual int emitFunction(Node *n, bool is_member, bool is_static); virtual int emitFunctionDispatcher(Node *n, bool is_member); - virtual int emitGetter(Node *n, bool is_member); + virtual int emitGetter(Node *n, bool is_member, bool is_static); - virtual int emitSetter(Node *n, bool is_member); + virtual int emitSetter(Node *n, bool is_member, bool is_static); virtual int emitConstant(Node *n); @@ -1069,7 +1072,7 @@ int JSCEmitter::exitFunction(Node *n) { .replace("${functionwrapper}", state.function(WRAPPER_NAME)); if (is_member) { - if (Equal(Getattr(n, "storage"), "static")) { + if (GetFlag(state.function(), IS_STATIC)) { Append(state.clazz(STATIC_FUNCTIONS), t_function.str()); } else { Append(state.clazz(MEMBER_FUNCTIONS), t_function.str()); @@ -1098,7 +1101,8 @@ int JSCEmitter::exitVariable(Node *n) { .replace("${propertyname}", state.variable(NAME)); if (GetFlag(n, "ismember")) { - if (Equal(Getattr(n, "storage"), "static") || (Equal(Getattr(n, "nodeType"), "enumitem"))) { + if (GetFlag(state.function(), IS_STATIC) + || Equal(Getattr(n, "nodeType"), "enumitem")) { Append(state.clazz(STATIC_VARIABLES), t_variable.str()); } else { Append(state.clazz(MEMBER_VARIABLES), t_variable.str()); @@ -1229,12 +1233,10 @@ int JSCEmitter::emitDtor(Node *) { return SWIG_OK; } -int JSCEmitter::emitGetter(Node *n, bool is_member) { +int JSCEmitter::emitGetter(Node *n, bool is_member, bool is_static) { Wrapper *wrapper = NewWrapper(); - Template t_getter(getTemplate("JS_getproperty")); - bool is_static = Equal(Getattr(n, "storage"), "static"); - + // prepare wrapper name String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); Setattr(n, "wrap:name", wrap_name); @@ -1261,7 +1263,7 @@ int JSCEmitter::emitGetter(Node *n, bool is_member) { return SWIG_OK; } -int JSCEmitter::emitSetter(Node *n, bool is_member) { +int JSCEmitter::emitSetter(Node *n, bool is_member, bool is_static) { // skip variables that are immutable if (State::IsSet(state.variable(IS_IMMUTABLE))) { @@ -1271,7 +1273,6 @@ int JSCEmitter::emitSetter(Node *n, bool is_member) { Wrapper *wrapper = NewWrapper(); Template t_setter(getTemplate("JS_setproperty")); - bool is_static = Equal(Getattr(n, "storage"), "static"); // prepare wrapper name String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); @@ -1345,18 +1346,12 @@ int JSCEmitter::emitConstant(Node *n) { return SWIG_OK; } -int JSCEmitter::emitFunction(Node *n, bool is_member) { +int JSCEmitter::emitFunction(Node *n, bool is_member, bool is_static) { Wrapper *wrapper = NewWrapper(); Template t_function(getTemplate("JS_functionwrapper")); - // Note: there is an inconsistency in SWIG with static member functions - // that do not have storage:static - // 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 = State::IsSet(state.function(IS_STATIC)) || Equal(Getattr(n, "storage"), "static"); bool is_overloaded = GetFlag(n, "sym:overloaded"); // prepare the function wrapper name diff --git a/Source/Modules/javascript_emitter.h b/Source/Modules/javascript_emitter.h deleted file mode 100644 index b73bb55b4..000000000 --- a/Source/Modules/javascript_emitter.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef JAVASCRIPT_EMITTER_H -#define JAVASCRIPT_EMITTER_H - -#include "swigmod.h" - -/** - * A class that wraps a code snippet used as template for code generation. - */ -class Template { - -public: - Template(const String* code); - - ~Template(); - - String* str(); - - Template& Replace(const String* pattern, const String* repl); - -private: - String* m_code; -}; - -class JSEmitter { - -public: - - enum JSEmitterType { - JavascriptCore, - V8, - QtScript - }; - - JSEmitter(); - - virtual ~JSEmitter(); - - /** - * Opens output files and temporary output DOHs. - */ - virtual int Initialize(Node *n) = 0; - - /** - * Writes all collected code into the output file(s). - */ - virtual int Dump(Node *n) = 0; - - /** - * Cleans up all open output DOHs. - */ - virtual int Close() = 0; - - /** - * Switches the context for code generation. - * - * Classes, global variables and global functions may need to - * be registered in certain static tables. - * This method should be used to switch output DOHs correspondingly. - */ - virtual int SwitchContext(Node *n) { return SWIG_OK; }; - - /** - * Invoked at the beginning of the classHandler. - */ - virtual int EnterClass(Node *n) { return SWIG_OK; }; - - /** - * Invoked at the end of the classHandler. - */ - virtual int ExitClass(Node *n) { return SWIG_OK; }; - - /** - * Invoked at the beginning of the variableHandler. - */ - virtual int EnterVariable(Node *n) { return SWIG_OK; }; - - /** - * Invoked at the end of the variableHandler. - */ - virtual int ExitVariable(Node *n) { return SWIG_OK; }; - - /** - * Invoked at the beginning of the functionHandler. - */ - virtual int EnterFunction(Node *n) { return SWIG_OK; }; - - /** - * Invoked at the end of the functionHandler. - */ - virtual int ExitFunction(Node *n) { return SWIG_OK; }; - - /** - * Invoked by functionWrapper callback after call to Language::functionWrapper. - */ - virtual int EmitWrapperFunction(Node *n); - - /** - * Registers a given code snippet for a given key name. - * - * This method is called by the fragmentDirective handler - * of the JAVASCRIPT language module. - */ - int RegisterTemplate(const String *name, const String *code); - - /** - * Retrieve the code template registered for a given name. - */ - const String* GetTemplate(const String *name); - -protected: - - virtual int EmitCtor(Node *n) = 0; - - virtual int EmitDtor(Node *n) = 0; - - virtual int EmitFunction(Node *n, bool is_member) = 0; - - virtual int EmitGetter(Node *n, bool is_member) = 0; - - virtual int EmitSetter(Node *n, bool is_member) = 0; - - bool IsSetterMethod(Node *n); - - Node* GetBaseClass(Node *n); - - const String* typemapLookup(Node *n, const_String_or_char_ptr tmap_method, - SwigType *type, int warning, Node *typemap_attributes = 0); - -protected: - - // empty string used at different places in the code - String *empty_string; - - Hash *templates; - - Wrapper* current_wrapper; -}; - -#endif // JAVASCRIPT_EMITTER_H diff --git a/Source/Modules/javascript_v8.h b/Source/Modules/javascript_v8.h deleted file mode 100644 index 8d9e6d0b0..000000000 --- a/Source/Modules/javascript_v8.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef JAVASCRIPT_V8_H -#define JAVASCRIPT_V8_H - -#include "javascript_emitter.h" - -class V8Emitter: public JSEmitter { - -public: - - V8Emitter(); - - virtual ~V8Emitter(); - - virtual int Initialize(Node *n); - - virtual int Dump(Node *n); - - virtual int Close(); - - virtual int SwitchContext(Node *n); - - virtual int EnterClass(Node *n); - - 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: - - int CreateNamespace(String* scope); - - virtual int EmitCtor(Node *n); - - virtual int EmitDtor(Node *n); - - 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; -}; - -#endif // JAVASCRIPT_V8_H From d2debe32703c0d1f6b4ca22623b2d13e206be64b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:59:31 +0000 Subject: [PATCH 039/352] Add more verbose temporary flags for setters in variable wrappers. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13773 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/lang.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx index c797a101e..afa640e56 100644 --- a/Source/Modules/lang.cxx +++ b/Source/Modules/lang.cxx @@ -1451,7 +1451,9 @@ int Language::membervariableHandler(Node *n) { } if (make_set_wrapper) { Setattr(n, "sym:name", mrename_set); + SetFlag(n, "wrap:issetter"); functionWrapper(n); + Delattr(n, "wrap:issetter"); } else { SetFlag(n, "feature:immutable"); } @@ -2910,7 +2912,9 @@ int Language::variableWrapper(Node *n) { Delete(pname0); } if (make_set_wrapper) { + SetFlag(n, "wrap:issetter"); functionWrapper(n); + Delattr(n, "wrap:issetter"); } /* Restore parameters */ Setattr(n, "sym:name", symname); From 66ead9afb2501d02c9ded79309e64a5bc953da5a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:59:43 +0000 Subject: [PATCH 040/352] Simplify implementation using new issetter flag. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13774 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 38 ++--------------------------------- 1 file changed, 2 insertions(+), 36 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 1c6ab7e78..667462091 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -214,12 +214,6 @@ protected: */ 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. */ @@ -618,7 +612,8 @@ int JSEmitter::emitWrapperFunction(Node *n) { 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 @@ int JSEmitter::enterVariable(Node *n) { 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 **********************************************************************/ From 387da69e843e7359ba1fb70f0eadbd077e8cf461 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 00:59:55 +0000 Subject: [PATCH 041/352] Pull namespace implementation up to be shared between js emitters. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13775 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 135 ++++++++++++++++++---------------- 1 file changed, 70 insertions(+), 65 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 667462091..ef878dd9c 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -122,9 +122,7 @@ public: * 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 @@ protected: 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 @@ extern "C" Language *swig_javascript(void) { * ----------------------------------------------------------------------------- */ JSEmitter::JSEmitter() -: templates(NewHash()) +: templates(NewHash()), + namespaces(NULL), + current_namespace(NULL) { } @@ -564,7 +577,16 @@ JSEmitterState &JSEmitter::getState() { 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 @@ int JSEmitter::enterVariable(Node *n) { 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 @@ protected: 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 @@ private: 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 @@ JSCEmitter::JSCEmitter() 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 @@ void JSCEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { } 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 @@ int JSCEmitter::initialize(Node *n) { 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 @@ int JSCEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { 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); From 4d9ca620abcfed848785ca4825f6a61648387829 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:00:15 +0000 Subject: [PATCH 042/352] Refactored JSEmitters to share unified code. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13776 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 1001 +++++++++++++-------------------- 1 file changed, 381 insertions(+), 620 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index ef878dd9c..69c5e4adf 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -88,6 +88,13 @@ protected: typedef JSEmitterState State; + enum MarshallingMode { + Setter, + Getter, + Ctor, + Function + }; + public: enum JSEmitterType { @@ -168,7 +175,7 @@ public: /** * 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,27 +197,33 @@ protected: /** * 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 @@ protected: 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 @@ protected: 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 @@ protected: **********************************************************************/ /* factory methods for concrete JSEmitters: */ + JSEmitter *swig_javascript_create_JSCEmitter(); JSEmitter *swig_javascript_create_V8Emitter(); @@ -265,13 +281,13 @@ public: 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 @@ extern "C" Language *swig_javascript(void) { JSEmitter::JSEmitter() : templates(NewHash()), namespaces(NULL), - current_namespace(NULL) + current_namespace(NULL), + f_wrappers(NULL) { } @@ -557,7 +574,7 @@ int JSEmitter::registerTemplate(const String *name, const String *code) { } /* ----------------------------------------------------------------------------- - * 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 @@ int JSEmitter::initialize(Node * n) { Setattr(namespaces, "::", global_namespace); current_namespace = global_namespace; + f_wrappers = NewString(""); + return SWIG_OK; } @@ -750,6 +769,16 @@ int JSEmitter::createNamespace(String *scope) { 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 @@ int JSEmitter::createNamespace(String *scope) { class JSCEmitter:public JSEmitter { -private: - - enum MarshallingMode { - Setter, - Getter, - Ctor, - Function - }; - public: JSCEmitter(); @@ -781,10 +801,6 @@ public: protected: - virtual int emitCtor(Node *n); - - virtual int emitDtor(Node *n); - virtual int enterVariable(Node *n); virtual int exitVariable(Node *n); @@ -797,19 +813,7 @@ protected: virtual int exitClass(Node *n); - virtual int emitFunction(Node *n, 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 void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); virtual Hash *createNamespaceEntry(const char *name, const char *parent); @@ -826,7 +830,6 @@ private: File *f_wrap_cpp; File *f_runtime; File *f_header; - File *f_wrappers; File *f_init; }; @@ -857,7 +860,6 @@ JSCEmitter::JSCEmitter() f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), - f_wrappers(NULL), f_init(NULL) { } @@ -934,44 +936,6 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma } } -/* --------------------------------------------------------------------- -* 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 @@ int JSCEmitter::initialize(Node *n) { 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 @@ int JSCEmitter::exitClass(Node *n) { return SWIG_OK; } -int JSCEmitter::emitCtor(Node *n) { +int JSEmitter::emitCtor(Node *n) { Wrapper *wrapper = NewWrapper(); @@ -1212,7 +1175,7 @@ int JSCEmitter::emitCtor(Node *n) { 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 @@ int JSCEmitter::emitCtor(Node *n) { 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 @@ int JSCEmitter::emitDtor(Node *) { 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 @@ int JSCEmitter::emitGetter(Node *n, bool is_member, bool is_static) { 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 @@ int JSCEmitter::emitSetter(Node *n, bool is_member, bool is_static) { * JSCEmitter::emitConstant() : triggers code generation for constants * ----------------------------------------------------------------------------- */ -int JSCEmitter::emitConstant(Node *n) { +int JSEmitter::emitConstant(Node *n) { Wrapper *wrapper = NewWrapper(); @@ -1359,10 +1322,9 @@ int JSCEmitter::emitConstant(Node *n) { return SWIG_OK; } -int JSCEmitter::emitFunction(Node *n, bool is_member, bool is_static) { - - Wrapper *wrapper = NewWrapper(); +int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { + Wrapper *wrapper = NewWrapper(); Template t_function(getTemplate("JS_functionwrapper")); bool is_overloaded = GetFlag(n, "sym:overloaded"); @@ -1412,7 +1374,7 @@ int JSCEmitter::emitFunction(Node *n, bool is_member, bool is_static) { 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 @@ int JSCEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { 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 @@ JSEmitter *swig_javascript_create_JSCEmitter() { 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 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); + virtual int emitNamespaces(); 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,151 +1569,301 @@ private: #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); + + // 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); + + 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); + + return SWIG_OK; } -int V8Emitter::CreateNamespace(String* scope) { - String* parent_scope = Swig_scopename_prefix(scope); - String* parent_scope_mangled = 0; +int V8Emitter::exitClass(Node *n) +{ + // 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; +} - if(!parent_scope) { - parent_scope_mangled = NewString("global"); +int V8Emitter::enterVariable(Node* n) +{ + JSEmitter::enterVariable(n); + + state.variable(GETTER, NULL_STR); + state.variable(SETTER, NULL_STR); + + return SWIG_OK; +} + +int V8Emitter::exitVariable(Node* n) +{ + 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 { - parent_scope_mangled = Swig_name_mangle(parent_scope); + 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); + } + + return SWIG_OK; +} +int V8Emitter::enterFunction(Node* n) +{ + JSEmitter::enterFunction(n); + + return SWIG_OK; +} + +int V8Emitter::exitFunction(Node* n) +{ + // 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_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); } - - if (parent_scope && !Getattr(namespaces, parent_scope)) { - CreateNamespace(parent_scope); + } 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); + } + + 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 startIdx = 0; + if (is_member && !is_static) { + startIdx = 1; + } + + 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: + if (is_member && !is_static && i == 0) { + Printv(arg, "args[0]", 0); + } else { + Printf(arg, "args[%d]", i - startIdx); + } + + 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."; } - - String* scope_mangled = Swig_string_mangle(scope); - String* scope_unqualified = Swig_scopename_last(scope); - Setattr(namespaces, scope, scope_mangled); - + + 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)); + } + Delete(arg); + } +} + +int V8Emitter::emitNamespaces() { +// TODO: handle namespaces: +/* // create namespace object and register it to the parent scope - Template t_create_ns(GetTemplate(V8_CREATE_NAMESPACE)); + 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)); + 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); @@ -1766,358 +1871,14 @@ int V8Emitter::CreateNamespace(String* scope) { 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; -} - -int V8Emitter::EnterClass(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; -} - -int V8Emitter::ExitClass(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); - - Delete(current_classname_mangled); - Delete(current_classname_unqualified); - current_classname_mangled = 0; - current_classname_unqualified = 0; - current_class_type = 0; - - return SWIG_OK; -} - -int V8Emitter::EnterVariable(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); - } else { - current_variable_mangled = Swig_string_mangle(Getattr(n, "name")); - } - - current_getter = NULL_STR; - current_setter = NULL_STR; - - return SWIG_OK; -} - -int V8Emitter::ExitVariable(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; -} - -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) -{ - // 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); - } - } 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); - } - - - Delete(current_function_mangled); - Delete(current_function_unqualified); - current_function_mangled = 0; - current_function_unqualified = 0; - - return SWIG_OK; -} - -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; -} - -int V8Emitter::EmitDtor(Node* n) -{ - // TODO: - // find out how to register a dtor in v8 - return SWIG_OK; -} - -int V8Emitter::EmitGetter(Node *n, bool is_member) { - Template t_getter(GetTemplate(V8_GETTER)); - - current_getter = 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); - marshalOutput(n, action, wrapper); - - t_getter.Replace(KW_MANGLED_NAME, current_variable_mangled) - .Replace(KW_LOCALS, wrapper->locals) - .Replace(KW_CODE, wrapper->code); - - Wrapper_pretty_print(t_getter.str(), f_wrapper); - - return SWIG_OK; -} - -int V8Emitter::EmitSetter(Node* n, bool is_member) -{ - Template t_setter(GetTemplate(V8_SETTER)); - - 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; -} - - -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); - - 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); - - 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); -} - */ + + return SWIG_OK; +} + + JSEmitter *swig_javascript_create_V8Emitter() { - return 0; + return new V8Emitter(); } From 548287c600e8bd900e6976158ffe9c007a390e5f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:01:41 +0000 Subject: [PATCH 043/352] Update configuration to detect V8 and allow testing with V8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13777 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 22 +++++-- Examples/javascript/class/Makefile | 11 ++-- Examples/javascript/constant/Makefile | 11 ++-- Examples/javascript/enum/Makefile | 11 ++-- Examples/javascript/exception/Makefile | 11 ++-- Examples/javascript/functor/Makefile | 11 ++-- Examples/javascript/namespace/Makefile | 11 ++-- Examples/javascript/operator/Makefile | 11 ++-- Examples/javascript/overload/Makefile | 11 ++-- Examples/javascript/pointer/Makefile | 11 ++-- Examples/javascript/reference/Makefile | 11 ++-- Examples/javascript/simple/Makefile | 11 ++-- Examples/javascript/template/Makefile | 11 ++-- Examples/javascript/variables/Makefile | 11 ++-- configure.in | 82 ++++++++++++++++++++++++-- 15 files changed, 159 insertions(+), 88 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 250ce4e0e..4f20b83b8 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -519,10 +519,22 @@ java_clean: # You need to set this variable to the jscore[or other javascript engine] directories containing the # files "JavaScript.h" and others -JS_INCLUDE= @JSCOREINC@ + +ifeq (,$(V8)) + JS_INCLUDE = @JSCOREINC@ + JS_DLNK = @JSCOREDYNAMICLINKING@ +else + JS_INCLUDE = @JSV8INC@ + JS_DLNK = @JSCOREDYNAMICLINKING@ +endif + +ifeq (,$(V8)) + SWIGJS = $(SWIG) -javascript -jsc +else + SWIGJS = $(SWIG) -javascript -v8 +endif # Extra JAVASCRIPT specific dynamic linking options -JS_DLNK = @JSCOREDYNAMICLINKING@ JS_LIBPREFIX = @JSCORELIBRARYPREFIX@ JSSO =@JSCORESO@ JSLDSHARED = @JSCORELDSHARED@ @@ -535,7 +547,7 @@ JSCXXFLAGS = @JSCXXFLAGS@ # ---------------------------------------------------------------- javascript: $(SRCS) - $(SWIG) -javascript -jsc -debug-codetemplates $(SWIGOPT) $(INTERFACEPATH) + $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) $(CC) -c $(CCSHARED) $(JSCFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JS_INCLUDE) $(JSLDSHARED) $(CCSHARED) $(JSCFLAGS) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) @@ -544,7 +556,7 @@ javascript: $(SRCS) # ---------------------------------------------------------------- javascript_cpp: $(SRCS) - $(SWIG) -c++ -javascript -jsc -debug-codetemplates $(SWIGOPT) $(INTERFACEPATH) + $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) $(CXX) -c $(CCSHARED) $(JSCXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JS_INCLUDE) $(JSCXXSHARED) $(CCSHARED) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) @@ -559,7 +571,7 @@ javascript_exe: $(SRCS) # ---------------------------------------------------------------- javascript_run: $(SRCS) - env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JAVASCRIPT_EXE) -l $(JAVASCRIPT_MODULE) $(JS_SCRIPT) + env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JAVASCRIPT_EXE) -l $(TARGET) $(JS_SCRIPT) # ----------------------------------------------------------------- # Cleaning the javascript examples diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/class/Makefile +++ b/Examples/javascript/class/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile index 4bc75b1a0..1ac61ec6b 100755 --- a/Examples/javascript/constant/Makefile +++ b/Examples/javascript/constant/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/enum/Makefile +++ b/Examples/javascript/enum/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/exception/Makefile +++ b/Examples/javascript/exception/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/functor/Makefile +++ b/Examples/javascript/functor/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/namespace/Makefile +++ b/Examples/javascript/namespace/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/operator/Makefile +++ b/Examples/javascript/operator/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/overload/Makefile +++ b/Examples/javascript/overload/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/pointer/Makefile +++ b/Examples/javascript/pointer/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/reference/Makefile +++ b/Examples/javascript/reference/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/simple/Makefile +++ b/Examples/javascript/simple/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile index ea41e55ce..1ac61ec6b 100755 --- a/Examples/javascript/template/Makefile +++ b/Examples/javascript/template/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile index e80e370e0..1ac61ec6b 100755 --- a/Examples/javascript/variables/Makefile +++ b/Examples/javascript/variables/Makefile @@ -1,17 +1,16 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.c -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -JAVASCRIPT_MODULE = example +CXXSRCS = example.cpp +JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ -SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean @@ -20,5 +19,5 @@ check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JAVASCRIPT_MODULE='$(JAVASCRIPT_MODULE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run + JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/configure.in b/configure.in index 92955c4c0..f3d7e4ccd 100644 --- a/configure.in +++ b/configure.in @@ -1088,6 +1088,8 @@ AC_MSG_NOTICE([Disabling Javascript]) JAVASCRIPT= else +### JavascriptCore ### + # check for include files AC_MSG_CHECKING(for include file JavaScriptCore/JavaScript.h) AC_ARG_WITH(javascriptincl, [ --with-javascript=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=]) @@ -1153,7 +1155,6 @@ else AC_MSG_RESULT($JSCORELIB) fi - # linking options case $host in *-*-darwin*) @@ -1176,10 +1177,9 @@ case $host in *) JSCORELIBRARYPREFIX="lib";; esac -if "$JS_NO_WARNINGS" == "1"; then +if test "$JS_NO_WARNINGS" == "1"; then case $host in *-*-darwin* | *-*-linux* | *-*-cygwin* | *-*-mingw*) - echo "HHHHHHHHHHHHHHHHHHHHHHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" JSCXXFLAGS="`echo $CXXFLAGS | sed 's/-Wall//g'`" ;; *) @@ -1211,6 +1211,78 @@ AC_SUBST(JSCORELDSHARED) AC_SUBST(JSCORECXXSHARED) AC_SUBST(JSCXXFLAGS) +### V8 ### + +# check for include files +AC_MSG_CHECKING(for include file v8.h) +AC_ARG_WITH(javascriptv8incl, [ --with-javascript-v8=path Set location of Javascript include directory], [JSV8INCDIR="$withval"], [JSV8INCDIR=]) + +if test -z "$JSV8INCDIR"; then + JSV8INCDIR="/usr/include/ /usr/local/include/" + + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) JSV8INCDIR="/usr/include /usr/local/include/ $JSV8INCDIR";; + *-*-darwin*) JSV8INCDIR="$JSV8INCDIR";; #TODO: add configuration for osx + *);; + esac +fi + +for d in $JSV8INCDIR ; do + if test -r "$d/v8.h" ; then + AC_MSG_RESULT($d) + JSV8INCDIR=$d + JSV8INC=-I\"$d\" + break + fi +done + +if test "$JSV8INC" = "" ; then + AC_MSG_RESULT(not found) +fi + + +# check for V8 library +AC_ARG_WITH(jsv8lib,[ --with-jsv8lib =path Set location of V8 library directory],[ + JSV8LIB="-L$withval"], [JSV8LIB=]) +AC_MSG_CHECKING(for V8 library) + +if test -z "$JSV8LIB"; then +dirs="/usr/lib/ /usr/local/lib/" +for i in $dirs ; do + + if test -r $i/libv8.so; then + AC_MSG_RESULT($i) + JSV8LIB="-L$i -lv8" + break + fi +done + +if test "$JSV8LIB" = "" ; then + AC_MSG_RESULT(not found) +fi + +else +AC_MSG_RESULT($JSCORELIB) +fi + + +# linking options +case $host in +*-*-darwin*) + JSV8DYNAMICLINKING="" # TODO: add osx configuration + ;; +*-*-linux*) + JSV8DYNAMICLINKING="$JSV8LIB" + ;; +*) + JSV8DYNAMICLINKING="" + ;; +esac + +AC_SUBST(JSV8INC) +AC_SUBST(JSV8DYNAMICLINKING) + #---------------------------------------------------------------- # Look for gcj #---------------------------------------------------------------- @@ -2372,10 +2444,10 @@ fi AC_SUBST(SKIP_JAVA) SKIP_JAVASCRIPT= -if test -z "$JSCOREINC"; then +if test -z "$JSCOREINC" && test -z "$JSV8INC"; then # Add in default directory for JavaScriptCore headers for Linux and MacOSX case $host in - *-*-linux*) if test -z "$JSCORELIB"; then + *-*-linux*) if test -z "$JSCORELIB" && test -z "$JSV8LIB"; then SKIP_JAVASCRIPT="1" fi ;; From eff094ef3942c026a0711abad56af9a8a54d9b9a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:01:57 +0000 Subject: [PATCH 044/352] Add test "constructor_copy". git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13778 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/constructor_copy.i | 2 +- Examples/test-suite/javascript/Makefile.in | 1 + .../javascript/constructor_copy_runme.js | 41 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 Examples/test-suite/javascript/constructor_copy_runme.js diff --git a/Examples/test-suite/constructor_copy.i b/Examples/test-suite/constructor_copy.i index f6bdcb240..6a0e90c71 100644 --- a/Examples/test-suite/constructor_copy.i +++ b/Examples/test-suite/constructor_copy.i @@ -73,7 +73,7 @@ public: %include "std_vector.i" -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) #define SWIG_GOOD_VECTOR %ignore std::vector::vector(size_type); %ignore std::vector::resize(size_type); diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 38f350cb0..a8e1759f7 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -29,6 +29,7 @@ CPP_TEST_CASES = \ class_scope_weird \ complextest \ constover \ + constructor_copy \ cpp_enum \ cpp_namespace \ cpp_static \ diff --git a/Examples/test-suite/javascript/constructor_copy_runme.js b/Examples/test-suite/javascript/constructor_copy_runme.js new file mode 100644 index 000000000..627b0936b --- /dev/null +++ b/Examples/test-suite/javascript/constructor_copy_runme.js @@ -0,0 +1,41 @@ + +f1 = new constructor_copy.Foo1(3); +f11 = new constructor_copy.Foo1(f1); + +if (f1.x != f11.x) { + throw "error in ctor copy for Foo1"; +} + +var good = 0; + +f8 = new constructor_copy.Foo8() +try { + f81 = new constructor_copy.Foo8(f8); + good = 0; +} catch (err) { + good = 1; +} + +if (good == 0) { + throw "Error: should not allow calling copy ctor for Foo8"; +} + + +bi = new constructor_copy.Bari(5); +bc = new constructor_copy.Bari(bi); + +if (bi.x != bc.x) { + throw "Error in copy ctor of Bari"; +} + +bd = new constructor_copy.Bard(5); +try { + bc = new constructor_copy.Bard(bd); + good = 0; +} catch (err) { + good = 1; +} + +if (good == 0) { + throw "Error: should not allow calling copy ctor for Bard"; +} From 07d5ec24cebcaa7a08425fa4780937b3bca9fae5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:02:16 +0000 Subject: [PATCH 045/352] Add support for type-based dispatching of overloaded functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13779 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptcode.swg | 50 ++++++++++++++++++--------- Source/Modules/javascript.cxx | 27 +++++++++++---- 2 files changed, 54 insertions(+), 23 deletions(-) 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); +} From 52aef2699700c957015c8ce88c5c75f756ffc86f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:02:30 +0000 Subject: [PATCH 046/352] Add examples check list for batch runs. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13780 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/javascript/check.list | 13 +++++++++++++ Makefile.in | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 Examples/javascript/check.list diff --git a/Examples/javascript/check.list b/Examples/javascript/check.list new file mode 100644 index 000000000..146f1800f --- /dev/null +++ b/Examples/javascript/check.list @@ -0,0 +1,13 @@ +class +constant +enum +exception +functor +namespace +operator +overload +pointer +reference +simple +template +variables diff --git a/Makefile.in b/Makefile.in index adc971455..0a485cd33 100644 --- a/Makefile.in +++ b/Makefile.in @@ -175,7 +175,7 @@ cffi_examples := r_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/r/check.list) go_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list) d_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list) -javascript_examples:= +javascript_examples:=$(shell sed '/^\#/d' $(srcdir)/Examples/javascript/check.list) # all examples check-%-examples : From cbb5b711ab8d3038f993dc77f6397419cb7c1f7e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:03:00 +0000 Subject: [PATCH 047/352] Fix examples after regressions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13781 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/javascript/constant/Makefile | 4 +- Examples/javascript/pointer/typemaps.i | 0 Examples/javascript/simple/Makefile | 6 +- .../simple/{example.cpp => example.c} | 10 - Examples/javascript/simple/example.i | 8 - Examples/javascript/variables/Makefile | 6 +- Examples/javascript/variables/example_wrap.c | 2593 +++++++++++++++++ 7 files changed, 2601 insertions(+), 26 deletions(-) create mode 100644 Examples/javascript/pointer/typemaps.i rename Examples/javascript/simple/{example.cpp => example.c} (70%) mode change 100755 => 100644 mode change 100755 => 100644 Examples/javascript/simple/example.i create mode 100644 Examples/javascript/variables/example_wrap.c diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile index 1ac61ec6b..bebb1f302 100755 --- a/Examples/javascript/constant/Makefile +++ b/Examples/javascript/constant/Makefile @@ -1,7 +1,7 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -CXXSRCS = example.cpp +CXXSRCS = JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example @@ -10,7 +10,7 @@ SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean diff --git a/Examples/javascript/pointer/typemaps.i b/Examples/javascript/pointer/typemaps.i new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile index 1ac61ec6b..4fbfa2802 100755 --- a/Examples/javascript/simple/Makefile +++ b/Examples/javascript/simple/Makefile @@ -1,7 +1,7 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -CXXSRCS = example.cpp +SRCS = example.c JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example @@ -9,8 +9,8 @@ INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean diff --git a/Examples/javascript/simple/example.cpp b/Examples/javascript/simple/example.c old mode 100755 new mode 100644 similarity index 70% rename from Examples/javascript/simple/example.cpp rename to Examples/javascript/simple/example.c index e7d3b0f11..1c2af789c --- a/Examples/javascript/simple/example.cpp +++ b/Examples/javascript/simple/example.c @@ -1,9 +1,3 @@ -#include -#include -#include -#include -using namespace std; - /* File : example.c */ /* A global variable */ @@ -22,7 +16,3 @@ int gcd(int x, int y) { } - - - - diff --git a/Examples/javascript/simple/example.i b/Examples/javascript/simple/example.i old mode 100755 new mode 100644 index 7c345964c..24093b9bf --- a/Examples/javascript/simple/example.i +++ b/Examples/javascript/simple/example.i @@ -1,15 +1,7 @@ /* File : example.i */ %module example -%include "std_string.i" - %inline %{ extern int gcd(int x, int y); -extern float gcd(float x, float y); -extern char* helloString(char* s); -extern void delete_helloString(char *newstr); -extern std::string helloString(std::string s); -extern void bar(int x, int y = 3, int z = 4); - extern double Foo; %} diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile index 1ac61ec6b..4fbfa2802 100755 --- a/Examples/javascript/variables/Makefile +++ b/Examples/javascript/variables/Makefile @@ -1,7 +1,7 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript -CXXSRCS = example.cpp +SRCS = example.c JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example @@ -9,8 +9,8 @@ INTERFACE = example.i SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean diff --git a/Examples/javascript/variables/example_wrap.c b/Examples/javascript/variables/example_wrap.c new file mode 100644 index 000000000..7fc9567cd --- /dev/null +++ b/Examples/javascript/variables/example_wrap.c @@ -0,0 +1,2593 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 2.0.6 + * + * This file is not intended to be easily readable and contains a number of + * coding conventions designed to improve portability and efficiency. Do not make + * changes to this file unless you know what you are doing--modify the SWIG + * interface file instead. + * ----------------------------------------------------------------------------- */ +/* ----------------------------------------------------------------------------- + * This section contains generic SWIG labels for method/variable + * declarations/attributes, and other compiler dependent labels. + * ----------------------------------------------------------------------------- */ + +/* template workaround for compilers that cannot correctly implement the C++ standard */ +#ifndef SWIGTEMPLATEDISAMBIGUATOR +# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) +# define SWIGTEMPLATEDISAMBIGUATOR template +# elif defined(__HP_aCC) +/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ +/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ +# define SWIGTEMPLATEDISAMBIGUATOR template +# else +# define SWIGTEMPLATEDISAMBIGUATOR +# endif +#endif + +/* inline attribute */ +#ifndef SWIGINLINE +# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) +# define SWIGINLINE inline +# else +# define SWIGINLINE +# endif +#endif + +/* attribute recognised by some compilers to avoid 'unused' warnings */ +#ifndef SWIGUNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +# elif defined(__ICC) +# define SWIGUNUSED __attribute__ ((__unused__)) +# else +# define SWIGUNUSED +# endif +#endif + +#ifndef SWIG_MSC_UNSUPPRESS_4505 +# if defined(_MSC_VER) +# pragma warning(disable : 4505) /* unreferenced local function has been removed */ +# endif +#endif + +#ifndef SWIGUNUSEDPARM +# ifdef __cplusplus +# define SWIGUNUSEDPARM(p) +# else +# define SWIGUNUSEDPARM(p) p SWIGUNUSED +# endif +#endif + +/* internal SWIG method */ +#ifndef SWIGINTERN +# define SWIGINTERN static SWIGUNUSED +#endif + +/* internal inline SWIG method */ +#ifndef SWIGINTERNINLINE +# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE +#endif + +/* exporting methods */ +#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +# ifndef GCC_HASCLASSVISIBILITY +# define GCC_HASCLASSVISIBILITY +# endif +#endif + +#ifndef SWIGEXPORT +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# if defined(STATIC_LINKED) +# define SWIGEXPORT +# else +# define SWIGEXPORT __declspec(dllexport) +# endif +# else +# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) +# define SWIGEXPORT __attribute__ ((visibility("default"))) +# else +# define SWIGEXPORT +# endif +# endif +#endif + +/* calling conventions for Windows */ +#ifndef SWIGSTDCALL +# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) +# define SWIGSTDCALL __stdcall +# else +# define SWIGSTDCALL +# endif +#endif + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + + +#define SWIG_AsCharPtrAndSize(val, cptr, psize, alloc) SWIG_JSC_AsCharPtrAndSize(context, val, cptr, psize, alloc) +#define SWIG_FromCharPtrAndSize(cptr, size) SWIG_JSC_FromCharPtrAndSize(context, cptr, size) +#define SWIG_FromCharPtr(cptr) SWIG_JSC_FromCharPtr(context, cptr) + + + +#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) + +#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else + + + +#include +#include +#include +#include +#include +#include + +/* ----------------------------------------------------------------------------- + * swigrun.swg + * + * This file contains generic C API SWIG runtime support for pointer + * type checking. + * ----------------------------------------------------------------------------- */ + +/* This should only be incremented when either the layout of swig_type_info changes, + or for whatever reason, the runtime changes incompatibly */ +#define SWIG_RUNTIME_VERSION "4" + +/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ +#ifdef SWIG_TYPE_TABLE +# define SWIG_QUOTE_STRING(x) #x +# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) +# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) +#else +# define SWIG_TYPE_TABLE_NAME +#endif + +/* + You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for + creating a static or dynamic library from the SWIG runtime code. + In 99.9% of the cases, SWIG just needs to declare them as 'static'. + + But only do this if strictly necessary, ie, if you have problems + with your compiler or suchlike. +*/ + +#ifndef SWIGRUNTIME +# define SWIGRUNTIME SWIGINTERN +#endif + +#ifndef SWIGRUNTIMEINLINE +# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE +#endif + +/* Generic buffer size */ +#ifndef SWIG_BUFFER_SIZE +# define SWIG_BUFFER_SIZE 1024 +#endif + +/* Flags for pointer conversions */ +#define SWIG_POINTER_DISOWN 0x1 +#define SWIG_CAST_NEW_MEMORY 0x2 + +/* Flags for new pointer objects */ +#define SWIG_POINTER_OWN 0x1 + + +/* + Flags/methods for returning states. + + The SWIG conversion methods, as ConvertPtr, return an integer + that tells if the conversion was successful or not. And if not, + an error code can be returned (see swigerrors.swg for the codes). + + Use the following macros/flags to set or process the returning + states. + + In old versions of SWIG, code such as the following was usually written: + + if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { + // success code + } else { + //fail code + } + + Now you can be more explicit: + + int res = SWIG_ConvertPtr(obj,vptr,ty.flags); + if (SWIG_IsOK(res)) { + // success code + } else { + // fail code + } + + which is the same really, but now you can also do + + Type *ptr; + int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); + if (SWIG_IsOK(res)) { + // success code + if (SWIG_IsNewObj(res) { + ... + delete *ptr; + } else { + ... + } + } else { + // fail code + } + + I.e., now SWIG_ConvertPtr can return new objects and you can + identify the case and take care of the deallocation. Of course that + also requires SWIG_ConvertPtr to return new result values, such as + + int SWIG_ConvertPtr(obj, ptr,...) { + if () { + if () { + *ptr = ; + return SWIG_NEWOBJ; + } else { + *ptr = ; + return SWIG_OLDOBJ; + } + } else { + return SWIG_BADOBJ; + } + } + + Of course, returning the plain '0(success)/-1(fail)' still works, but you can be + more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the + SWIG errors code. + + Finally, if the SWIG_CASTRANK_MODE is enabled, the result code + allows to return the 'cast rank', for example, if you have this + + int food(double) + int fooi(int); + + and you call + + food(1) // cast rank '1' (1 -> 1.0) + fooi(1) // cast rank '0' + + just use the SWIG_AddCast()/SWIG_CheckState() +*/ + +#define SWIG_OK (0) +#define SWIG_ERROR (-1) +#define SWIG_IsOK(r) (r >= 0) +#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) + +/* The CastRankLimit says how many bits are used for the cast rank */ +#define SWIG_CASTRANKLIMIT (1 << 8) +/* The NewMask denotes the object was created (using new/malloc) */ +#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) +/* The TmpMask is for in/out typemaps that use temporal objects */ +#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) +/* Simple returning values */ +#define SWIG_BADOBJ (SWIG_ERROR) +#define SWIG_OLDOBJ (SWIG_OK) +#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) +#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) +/* Check, add and del mask methods */ +#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) +#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) +#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) +#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) +#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) +#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) + +/* Cast-Rank Mode */ +#if defined(SWIG_CASTRANK_MODE) +# ifndef SWIG_TypeRank +# define SWIG_TypeRank unsigned long +# endif +# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ +# define SWIG_MAXCASTRANK (2) +# endif +# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) +# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) +SWIGINTERNINLINE int SWIG_AddCast(int r) { + return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; +} +SWIGINTERNINLINE int SWIG_CheckState(int r) { + return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; +} +#else /* no cast-rank mode */ +# define SWIG_AddCast +# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) +#endif + + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void *(*swig_converter_func)(void *, int *); +typedef struct swig_type_info *(*swig_dycast_func)(void **); + +/* Structure to store information on one type */ +typedef struct swig_type_info { + const char *name; /* mangled name of this type */ + const char *str; /* human readable name of this type */ + swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ + struct swig_cast_info *cast; /* linked list of types that can cast into this type */ + void *clientdata; /* language specific type data */ + int owndata; /* flag if the structure owns the clientdata */ +} swig_type_info; + +/* Structure to store a type and conversion function used for casting */ +typedef struct swig_cast_info { + swig_type_info *type; /* pointer to type that is equivalent to this type */ + swig_converter_func converter; /* function to cast the void pointers */ + struct swig_cast_info *next; /* pointer to next cast in linked list */ + struct swig_cast_info *prev; /* pointer to the previous cast */ +} swig_cast_info; + +/* Structure used to store module information + * Each module generates one structure like this, and the runtime collects + * all of these structures and stores them in a circularly linked list.*/ +typedef struct swig_module_info { + swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ + size_t size; /* Number of types in this module */ + struct swig_module_info *next; /* Pointer to next element in circularly linked list */ + swig_type_info **type_initial; /* Array of initially generated type structures */ + swig_cast_info **cast_initial; /* Array of initially generated casting structures */ + void *clientdata; /* Language specific module data */ +} swig_module_info; + +/* + Compare two type names skipping the space characters, therefore + "char*" == "char *" and "Class" == "Class", etc. + + Return 0 when the two name types are equivalent, as in + strncmp, but skipping ' '. +*/ +SWIGRUNTIME int +SWIG_TypeNameComp(const char *f1, const char *l1, + const char *f2, const char *l2) { + for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { + while ((*f1 == ' ') && (f1 != l1)) ++f1; + while ((*f2 == ' ') && (f2 != l2)) ++f2; + if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; + } + return (int)((l1 - f1) - (l2 - f2)); +} + +/* + Check type equivalence in a name list like ||... + Return 0 if not equal, 1 if equal +*/ +SWIGRUNTIME int +SWIG_TypeEquiv(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + +/* + Check type equivalence in a name list like ||... + Return 0 if equal, -1 if nb < tb, 1 if nb > tb +*/ +SWIGRUNTIME int +SWIG_TypeCompare(const char *nb, const char *tb) { + int equiv = 0; + const char* te = tb + strlen(tb); + const char* ne = nb; + while (!equiv && *ne) { + for (nb = ne; *ne; ++ne) { + if (*ne == '|') break; + } + equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; + if (*ne) ++ne; + } + return equiv; +} + + +/* + Check the typename +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheck(const char *c, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (strcmp(iter->type->name, c) == 0) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison +*/ +SWIGRUNTIME swig_cast_info * +SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { + if (ty) { + swig_cast_info *iter = ty->cast; + while (iter) { + if (iter->type == from) { + if (iter == ty->cast) + return iter; + /* Move iter to the top of the linked list */ + iter->prev->next = iter->next; + if (iter->next) + iter->next->prev = iter->prev; + iter->next = ty->cast; + iter->prev = 0; + if (ty->cast) ty->cast->prev = iter; + ty->cast = iter; + return iter; + } + iter = iter->next; + } + } + return 0; +} + +/* + Cast a pointer up an inheritance hierarchy +*/ +SWIGRUNTIMEINLINE void * +SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { + return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); +} + +/* + Dynamic pointer casting. Down an inheritance hierarchy +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { + swig_type_info *lastty = ty; + if (!ty || !ty->dcast) return ty; + while (ty && (ty->dcast)) { + ty = (*ty->dcast)(ptr); + if (ty) lastty = ty; + } + return lastty; +} + +/* + Return the name associated with this type +*/ +SWIGRUNTIMEINLINE const char * +SWIG_TypeName(const swig_type_info *ty) { + return ty->name; +} + +/* + Return the pretty name associated with this type, + that is an unmangled type name in a form presentable to the user. +*/ +SWIGRUNTIME const char * +SWIG_TypePrettyName(const swig_type_info *type) { + /* The "str" field contains the equivalent pretty names of the + type, separated by vertical-bar characters. We choose + to print the last name, as it is often (?) the most + specific. */ + if (!type) return NULL; + if (type->str != NULL) { + const char *last_name = type->str; + const char *s; + for (s = type->str; *s; s++) + if (*s == '|') last_name = s+1; + return last_name; + } + else + return type->name; +} + +/* + Set the clientdata field for a type +*/ +SWIGRUNTIME void +SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { + swig_cast_info *cast = ti->cast; + /* if (ti->clientdata == clientdata) return; */ + ti->clientdata = clientdata; + + while (cast) { + if (!cast->converter) { + swig_type_info *tc = cast->type; + if (!tc->clientdata) { + SWIG_TypeClientData(tc, clientdata); + } + } + cast = cast->next; + } +} +SWIGRUNTIME void +SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { + SWIG_TypeClientData(ti, clientdata); + ti->owndata = 1; +} + +/* + Search for a swig_type_info structure only by mangled name + Search is a O(log #types) + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_MangledTypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + swig_module_info *iter = start; + do { + if (iter->size) { + register size_t l = 0; + register size_t r = iter->size - 1; + do { + /* since l+r >= 0, we can (>> 1) instead (/ 2) */ + register size_t i = (l + r) >> 1; + const char *iname = iter->types[i]->name; + if (iname) { + register int compare = strcmp(name, iname); + if (compare == 0) { + return iter->types[i]; + } else if (compare < 0) { + if (i) { + r = i - 1; + } else { + break; + } + } else if (compare > 0) { + l = i + 1; + } + } else { + break; /* should never happen */ + } + } while (l <= r); + } + iter = iter->next; + } while (iter != end); + return 0; +} + +/* + Search for a swig_type_info structure for either a mangled name or a human readable name. + It first searches the mangled names of the types, which is a O(log #types) + If a type is not found it then searches the human readable names, which is O(#types). + + We start searching at module start, and finish searching when start == end. + Note: if start == end at the beginning of the function, we go all the way around + the circular list. +*/ +SWIGRUNTIME swig_type_info * +SWIG_TypeQueryModule(swig_module_info *start, + swig_module_info *end, + const char *name) { + /* STEP 1: Search the name field using binary search */ + swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); + if (ret) { + return ret; + } else { + /* STEP 2: If the type hasn't been found, do a complete search + of the str field (the human readable name) */ + swig_module_info *iter = start; + do { + register size_t i = 0; + for (; i < iter->size; ++i) { + if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) + return iter->types[i]; + } + iter = iter->next; + } while (iter != end); + } + + /* neither found a match */ + return 0; +} + +/* + Pack binary data into a string +*/ +SWIGRUNTIME char * +SWIG_PackData(char *c, void *ptr, size_t sz) { + static const char hex[17] = "0123456789abcdef"; + register const unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register unsigned char uu = *u; + *(c++) = hex[(uu & 0xf0) >> 4]; + *(c++) = hex[uu & 0xf]; + } + return c; +} + +/* + Unpack binary data from a string +*/ +SWIGRUNTIME const char * +SWIG_UnpackData(const char *c, void *ptr, size_t sz) { + register unsigned char *u = (unsigned char *) ptr; + register const unsigned char *eu = u + sz; + for (; u != eu; ++u) { + register char d = *(c++); + register unsigned char uu; + if ((d >= '0') && (d <= '9')) + uu = ((d - '0') << 4); + else if ((d >= 'a') && (d <= 'f')) + uu = ((d - ('a'-10)) << 4); + else + return (char *) 0; + d = *(c++); + if ((d >= '0') && (d <= '9')) + uu |= (d - '0'); + else if ((d >= 'a') && (d <= 'f')) + uu |= (d - ('a'-10)); + else + return (char *) 0; + *u = uu; + } + return c; +} + +/* + Pack 'void *' into a string buffer. +*/ +SWIGRUNTIME char * +SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { + char *r = buff; + if ((2*sizeof(void *) + 2) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,&ptr,sizeof(void *)); + if (strlen(name) + 1 > (bsz - (r - buff))) return 0; + strcpy(r,name); + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + *ptr = (void *) 0; + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sizeof(void *)); +} + +SWIGRUNTIME char * +SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { + char *r = buff; + size_t lname = (name ? strlen(name) : 0); + if ((2*sz + 2 + lname) > bsz) return 0; + *(r++) = '_'; + r = SWIG_PackData(r,ptr,sz); + if (lname) { + strncpy(r,name,lname+1); + } else { + *r = 0; + } + return buff; +} + +SWIGRUNTIME const char * +SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { + if (*c != '_') { + if (strcmp(c,"NULL") == 0) { + memset(ptr,0,sz); + return name; + } else { + return 0; + } + } + return SWIG_UnpackData(++c,ptr,sz); +} + +#ifdef __cplusplus +} +#endif + +/* Errors in SWIG */ +#define SWIG_UnknownError -1 +#define SWIG_IOError -2 +#define SWIG_RuntimeError -3 +#define SWIG_IndexError -4 +#define SWIG_TypeError -5 +#define SWIG_DivisionByZero -6 +#define SWIG_OverflowError -7 +#define SWIG_SyntaxError -8 +#define SWIG_ValueError -9 +#define SWIG_SystemError -10 +#define SWIG_AttributeError -11 +#define SWIG_MemoryError -12 +#define SWIG_NullReferenceError -13 + + + + +#define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_fail goto fail + +#define SWIG_JSC_FROM_DECL_ARGS(arg1) (JSContextRef context, arg1) +#define SWIG_JSC_FROM_CALL_ARGS(arg1) (context, arg1) +#define SWIG_JSC_AS_DECL_ARGS(arg1, arg2) (JSContextRef context, arg1, arg2) +#define SWIG_JSC_AS_CALL_ARGS(arg1, arg2) (context, arg1, arg2) + + +typedef struct { + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; +}SWIG_PRV_DATA; + + + +void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) { + JSStringRef message = JSStringCreateWithUTF8CString(type); + *exception = JSValueMakeString(context, message); + JSStringRelease(message); +} + +void SWIG_JSC_exception(JSContextRef context, JSValueRef *exception, int code, const char* msg) { + SWIG_Javascript_Raise(context, exception, msg); +} + + + + +JSValueRef _wrap_SwigObject_disown(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) JSObjectGetPrivate(obj); + + cdata->swigCMemOwn = false; + + jsresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef _wrap_SwigObject_getCPtr(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + long result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA*) JSObjectGetPrivate(obj); + + result = (long) cdata->swigCObject; + jsresult = JSValueMakeNumber(context, result); + + return jsresult; +} + +JSStaticValue _SwigObject_values[] = { + { + 0, 0, 0, 0 + } +}; + +JSStaticFunction _SwigObject_functions[] = { + { + "disown",_wrap_SwigObject_disown, kJSPropertyAttributeNone + },{ + "getCPtr",_wrap_SwigObject_getCPtr, kJSPropertyAttributeNone + }, + { + 0, 0, 0 + } +}; + +JSClassDefinition _SwigObject_objectDefinition; + +JSClassRef _SwigObject_classRef; + + + +int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef objRef, void** ptr, swig_type_info *info, int flags) { + SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) JSObjectGetPrivate(objRef); + if(cdata == NULL) { + return SWIG_ERROR; + } + if(cdata->info != info) { + bool type_valid = false; + swig_cast_info *t = info->cast; + while(t != NULL) { + if(t->type == cdata->info) { + type_valid = true; + break; + } + t = t->next; + } + if(!type_valid) { + return SWIG_TypeError; + } + } + + *ptr = cdata->swigCObject; + + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + + return SWIG_OK; +} + +int SWIG_JSC_ConvertPtr(JSContextRef context, JSValueRef valRef, void** ptr, swig_type_info *info, int flags) { + if(!JSValueIsObject(context, valRef)) { + return SWIG_TypeError; + } + + JSObjectRef objRef = JSValueToObject(context, valRef, NULL); + if(objRef == NULL) { + return SWIG_ERROR; + } + + return SWIG_JSC_ConvertInstancePtr(context, objRef, ptr, info, flags); +} + +JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_info *info, int flags) { + + JSClassRef classRef; + if(info->clientdata == NULL) { + classRef = _SwigObject_classRef; + } else { + classRef = (JSClassRef) info->clientdata; + } + + JSObjectRef result = JSObjectMake(context, classRef, NULL); + + SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) malloc(sizeof(SWIG_PRV_DATA)); + cdata->swigCObject = ptr; + cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; + cdata->info = info; + + JSObjectSetPrivate(result, cdata); + + return result; +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_JSC_ConvertPtr(context, obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_JSC_NewPointerObj(context, ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) + + + +/* -------- TYPES TABLE (BEGIN) -------- */ + +#define SWIGTYPE_p_Point swig_types[0] +#define SWIGTYPE_p_char swig_types[1] +#define SWIGTYPE_p_int swig_types[2] +static swig_type_info *swig_types[4]; +static swig_module_info swig_module = {swig_types, 3, 0, 0, 0, 0}; +#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) +#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) + +/* -------- TYPES TABLE (END) -------- */ + + + +#define SWIGVERSION 0x020006 +#define SWIG_VERSION SWIGVERSION + + +#define SWIG_as_voidptr(a) (void *)((const void *)(a)) +#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) + + +#include "example.h" + + +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; + + +#include +#if !defined(SWIG_NO_LLONG_MAX) +# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) +# define LLONG_MAX __LONG_LONG_MAX__ +# define LLONG_MIN (-LLONG_MAX - 1LL) +# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +# endif +#endif + + +SWIGINTERN int +SWIG_AsVal_double SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, double *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} + + +#include + + +#include + + +SWIGINTERNINLINE int +SWIG_CanCastAsInteger(double *d, double min, double max) { + double x = *d; + if ((min <= x && x <= max)) { + double fx = floor(x); + double cx = ceil(x); + double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ + if ((errno == EDOM) || (errno == ERANGE)) { + errno = 0; + } else { + double summ, reps, diff; + if (rd < x) { + diff = x - rd; + } else if (rd > x) { + diff = rd - x; + } else { + return 1; + } + summ = rd + x; + reps = diff/summ; + if (reps < 8*DBL_EPSILON) { + *d = rd; + return 1; + } + } + } + return 0; +} + + +SWIGINTERN int +SWIG_AsVal_long SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, long* val) +{ + if (!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = (long) JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} + + +SWIGINTERN int +SWIG_AsVal_int SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, int *val) +{ + long v; + int res = SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(obj, &v); + if (SWIG_IsOK(res)) { + if ((v < INT_MIN || v > INT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (int)(v); + } + } + return res; +} + + +SWIGINTERNINLINE JSValueRef + SWIG_From_int SWIG_JSC_FROM_DECL_ARGS(int value) +{ + return JSValueMakeNumber(context, value); +} + + +SWIGINTERN int +SWIG_AsVal_short SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, short *val) +{ + long v; + int res = SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(obj, &v); + if (SWIG_IsOK(res)) { + if ((v < SHRT_MIN || v > SHRT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (short)(v); + } + } + return res; +} + + +SWIGINTERNINLINE JSValueRef + SWIG_From_long SWIG_JSC_FROM_DECL_ARGS(long value) +{ + return JSValueMakeNumber(context, value); +} + + +SWIGINTERNINLINE JSValueRef +SWIG_From_short SWIG_JSC_FROM_DECL_ARGS(short value) +{ + return SWIG_From_long SWIG_JSC_FROM_CALL_ARGS(value); +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, unsigned long *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + + long longVal = (long) JSValueToNumber(context, obj, NULL); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_int SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, unsigned int *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_CALL_ARGS(obj, &v); + if (SWIG_IsOK(res)) { + if ((v > UINT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (unsigned int)(v); + } + } + return res; +} + + +SWIGINTERNINLINE JSValueRef +SWIG_From_unsigned_SS_long SWIG_JSC_FROM_DECL_ARGS(unsigned long value) +{ + return (value > LONG_MAX) ? + JSValueMakeNumber(context, value) : JSValueMakeNumber(context, (long)(value)); +} + + +SWIGINTERNINLINE JSValueRef +SWIG_From_unsigned_SS_int SWIG_JSC_FROM_DECL_ARGS(unsigned int value) +{ + return SWIG_From_unsigned_SS_long SWIG_JSC_FROM_CALL_ARGS(value); +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_short SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, unsigned short *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_CALL_ARGS(obj, &v); + if (SWIG_IsOK(res)) { + if ((v > USHRT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (unsigned short)(v); + } + } + return res; +} + + +SWIGINTERNINLINE JSValueRef +SWIG_From_unsigned_SS_short SWIG_JSC_FROM_DECL_ARGS(unsigned short value) +{ + return SWIG_From_unsigned_SS_long SWIG_JSC_FROM_CALL_ARGS(value); +} + + +SWIGINTERN int +SWIG_AsVal_signed_SS_char SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, signed char *val) +{ + long v; + int res = SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(obj, &v); + if (SWIG_IsOK(res)) { + if ((v < SCHAR_MIN || v > SCHAR_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (signed char)(v); + } + } + return res; +} + + +SWIGINTERNINLINE JSValueRef +SWIG_From_signed_SS_char SWIG_JSC_FROM_DECL_ARGS(signed char value) +{ + return SWIG_From_long SWIG_JSC_FROM_CALL_ARGS(value); +} + + +SWIGINTERN int +SWIG_AsVal_unsigned_SS_char SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, unsigned char *val) +{ + unsigned long v; + int res = SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_CALL_ARGS(obj, &v); + if (SWIG_IsOK(res)) { + if ((v > UCHAR_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (unsigned char)(v); + } + } + return res; +} + + +SWIGINTERNINLINE JSValueRef +SWIG_From_unsigned_SS_char SWIG_JSC_FROM_DECL_ARGS(unsigned char value) +{ + return SWIG_From_unsigned_SS_long SWIG_JSC_FROM_CALL_ARGS(value); +} + + +SWIGINTERN swig_type_info* +SWIG_pchar_descriptor(void) +{ + static int init = 0; + static swig_type_info* info = 0; + if (!init) { + info = SWIG_TypeQuery("_p_char"); + init = 1; + } + return info; +} + + +SWIGINTERN int +SWIG_JSC_AsCharPtrAndSize(JSContextRef context, JSValueRef valRef, char** cptr, size_t* psize, int *alloc) +{ + if(JSValueIsString(context, valRef)) { + JSStringRef js_str = JSValueToStringCopy(context, valRef, NULL); + size_t len = JSStringGetMaximumUTF8CStringSize(js_str); + size_t abs_len = JSStringGetLength(js_str); + char* cstr = (char*) malloc(len * sizeof(char)); + JSStringGetUTF8CString(js_str, cstr, len); + + if(alloc) *alloc = SWIG_NEWOBJ; + if(psize) *psize = abs_len + 1; + if(cptr) *cptr = cstr; + + return SWIG_OK; + } else { + if(JSValueIsObject(context, valRef)) { + JSObjectRef obj = JSValueToObject(context, valRef, NULL); + // try if the object is a wrapped char[] + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + return SWIG_TypeError; + } else { + return SWIG_TypeError; + } + } +} + + +SWIGINTERN int +SWIG_JSC_AsCharArray(JSContextRef context, JSValueRef obj, char *val, size_t size) +{ + char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ; + int res = SWIG_JSC_AsCharPtrAndSize(context, obj, &cptr, &csize, &alloc); + if (SWIG_IsOK(res)) { + if ((csize == size + 1) && cptr && !(cptr[csize-1])) --csize; + if (csize <= size) { + if (val) { + if (csize) memcpy(val, cptr, csize*sizeof(char)); + if (csize < size) memset(val + csize, 0, (size - csize)*sizeof(char)); + } + if (alloc == SWIG_NEWOBJ) { + free((char*)cptr); + res = SWIG_DelNewMask(res); + } + return res; + } + if (alloc == SWIG_NEWOBJ) free((char*)cptr); + } + return SWIG_TypeError; +} + + + + +SWIGINTERN int +SWIG_AsVal_char SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, char *val) +{ + int res = SWIG_JSC_AsCharArray(context, obj, val, 1); + if (!SWIG_IsOK(res)) { + long v; + res = SWIG_AddCast(SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(obj, &v)); + if (SWIG_IsOK(res)) { + if ((CHAR_MIN <= v) && (v <= CHAR_MAX)) { + if (val) *val = (char)(v); + } else { + res = SWIG_OverflowError; + } + } + } + return res; +} + + +SWIGINTERNINLINE JSValueRef +SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + // TODO: handle extra long strings + //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + //return pchar_descriptor ? + // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); + return JSValueMakeUndefined(context); + } else { + JSStringRef jsstring = JSStringCreateWithUTF8CString(carray); + JSValueRef result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return result; + } + } else { + return JSValueMakeUndefined(context); + } +} + + +SWIGINTERNINLINE JSValueRef +SWIG_From_char SWIG_JSC_FROM_DECL_ARGS(char c) +{ + return SWIG_JSC_FromCharPtrAndSize(context, &c,1); +} + + +SWIGINTERN int +SWIG_AsVal_float SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, float *val) +{ + double v; + int res = SWIG_AsVal_double SWIG_JSC_AS_CALL_ARGS(obj, &v); + if (SWIG_IsOK(res)) { + if ((v < -FLT_MAX || v > FLT_MAX)) { + return SWIG_OverflowError; + } else { + if (val) *val = (float)(v); + } + } + return res; +} + + +SWIGINTERN JSValueRef +SWIG_From_double SWIG_JSC_FROM_DECL_ARGS (double val) +{ + return JSValueMakeNumber(context, val); +} + + +SWIGINTERNINLINE JSValueRef +SWIG_From_float SWIG_JSC_FROM_DECL_ARGS(float value) +{ + return SWIG_From_double SWIG_JSC_FROM_CALL_ARGS(value); +} + + + + + +SWIGINTERNINLINE JSValueRef +SWIG_JSC_FromCharPtr(JSContextRef context, const char *cptr) +{ + return SWIG_JSC_FromCharPtrAndSize(context, cptr, (cptr ? strlen(cptr) : 0)); +} + + +extern int status; +extern char path[256]; + + +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); + + + + +bool JS_registerClass(JSGlobalContextRef context, JSObjectRef parentObject, + const char* className, + JSClassDefinition* definition) { + + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject, + js_className, classObject, + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef context, + JSObjectRef namespaceObj, JSObjectRef parentNamespace, + const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace, + js_name, namespaceObj, + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + + return true; +} + + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context, object, js_functionName, + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} + +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + + return val; +} + + +bool _wrap_ivar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + int arg1 ; + int val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_int SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ivar_set" "', argument " "1"" of type '" "int""'"); + } + arg1 = (int)(val1); + ivar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_ivar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + int result; + + result = (int)ivar; + jsresult = SWIG_From_int SWIG_JSC_FROM_CALL_ARGS((int)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_svar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + short arg1 ; + short val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_short SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "svar_set" "', argument " "1"" of type '" "short""'"); + } + arg1 = (short)(val1); + svar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_svar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + short result; + + result = (short)svar; + jsresult = SWIG_From_short SWIG_JSC_FROM_CALL_ARGS((short)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_lvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + long arg1 ; + long val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "lvar_set" "', argument " "1"" of type '" "long""'"); + } + arg1 = (long)(val1); + lvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_lvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + long result; + + result = (long)lvar; + jsresult = SWIG_From_long SWIG_JSC_FROM_CALL_ARGS((long)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_uivar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + unsigned int arg1 ; + unsigned int val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_unsigned_SS_int SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "uivar_set" "', argument " "1"" of type '" "unsigned int""'"); + } + arg1 = (unsigned int)(val1); + uivar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_uivar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + unsigned int result; + + result = (unsigned int)uivar; + jsresult = SWIG_From_unsigned_SS_int SWIG_JSC_FROM_CALL_ARGS((unsigned int)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_usvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + unsigned short arg1 ; + unsigned short val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_unsigned_SS_short SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "usvar_set" "', argument " "1"" of type '" "unsigned short""'"); + } + arg1 = (unsigned short)(val1); + usvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_usvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + unsigned short result; + + result = (unsigned short)usvar; + jsresult = SWIG_From_unsigned_SS_short SWIG_JSC_FROM_CALL_ARGS((unsigned short)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_ulvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + unsigned long arg1 ; + unsigned long val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ulvar_set" "', argument " "1"" of type '" "unsigned long""'"); + } + arg1 = (unsigned long)(val1); + ulvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_ulvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + unsigned long result; + + result = (unsigned long)ulvar; + jsresult = SWIG_From_unsigned_SS_long SWIG_JSC_FROM_CALL_ARGS((unsigned long)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_scvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + signed char arg1 ; + signed char val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_signed_SS_char SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "scvar_set" "', argument " "1"" of type '" "signed char""'"); + } + arg1 = (signed char)(val1); + scvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_scvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + signed char result; + + result = (signed char)scvar; + jsresult = SWIG_From_signed_SS_char SWIG_JSC_FROM_CALL_ARGS((signed char)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_ucvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + unsigned char arg1 ; + unsigned char val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_unsigned_SS_char SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ucvar_set" "', argument " "1"" of type '" "unsigned char""'"); + } + arg1 = (unsigned char)(val1); + ucvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_ucvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + unsigned char result; + + result = (unsigned char)ucvar; + jsresult = SWIG_From_unsigned_SS_char SWIG_JSC_FROM_CALL_ARGS((unsigned char)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_cvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char arg1 ; + char val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_char SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "cvar_set" "', argument " "1"" of type '" "char""'"); + } + arg1 = (char)(val1); + cvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_cvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + char result; + + result = (char)cvar; + jsresult = SWIG_From_char SWIG_JSC_FROM_CALL_ARGS((char)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_fvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + float arg1 ; + float val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_float SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "fvar_set" "', argument " "1"" of type '" "float""'"); + } + arg1 = (float)(val1); + fvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_fvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + float result; + + result = (float)fvar; + jsresult = SWIG_From_float SWIG_JSC_FROM_CALL_ARGS((float)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_dvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + double arg1 ; + double val1 ; + int ecode1 = 0 ; + + ecode1 = SWIG_AsVal_double SWIG_JSC_AS_CALL_ARGS(value, &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "dvar_set" "', argument " "1"" of type '" "double""'"); + } + arg1 = (double)(val1); + dvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_dvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + double result; + + result = (double)dvar; + jsresult = SWIG_From_double SWIG_JSC_FROM_CALL_ARGS((double)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_strvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char *arg1 = (char *) 0 ; + int res1 ; + char *buf1 = 0 ; + int alloc1 = 0 ; + + res1 = SWIG_JSC_AsCharPtrAndSize(context, value, &buf1, NULL, &alloc1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "strvar_set" "', argument " "1"" of type '" "char *""'"); + } + arg1 = (char *)(buf1); + if (strvar) free((char*)strvar); + if (arg1) { + size_t size = strlen((const char *)((const char *)(arg1))) + 1; + strvar = (char *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg1, sizeof(char)*(size)); + } else { + strvar = 0; + } + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_strvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + char *result = 0 ; + + result = (char *)strvar; + jsresult = SWIG_FromCharPtr((const char *)result); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +JSValueRef _wrap_cstrvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + char *result = 0 ; + + result = (char *)(char *)cstrvar; + jsresult = SWIG_FromCharPtr((const char *)result); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_iptrvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + int *arg1 = (int *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + res1 = SWIG_ConvertPtr(value, &argp1,SWIGTYPE_p_int, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "iptrvar_set" "', argument " "1"" of type '" "int *""'"); + } + arg1 = (int *)(argp1); + iptrvar = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_iptrvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + int *result = 0 ; + + result = (int *)iptrvar; + jsresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 | 0 ); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_name_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char *arg1 ; + char temp1[256] ; + int res1 ; + + res1 = SWIG_JSC_AsCharArray(context, value, temp1, 256); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "name_set" "', argument " "1"" of type '" "char [256]""'"); + } + arg1 = (char *)(temp1); + if (arg1) memcpy(name,arg1,256*sizeof(char)); + else memset(name,0,256*sizeof(char)); + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_name_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + char *result = 0 ; + + result = (char *)(char *)name; + { + size_t size = 256; + + while (size && (result[size - 1] == '\0')) --size; + + jsresult = SWIG_FromCharPtrAndSize(result, size); + } + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_ptptr_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + Point *arg1 = (Point *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + + res1 = SWIG_ConvertPtr(value, &argp1,SWIGTYPE_p_Point, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ptptr_set" "', argument " "1"" of type '" "Point *""'"); + } + arg1 = (Point *)(argp1); + ptptr = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_ptptr_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + Point *result = 0 ; + + result = (Point *)ptptr; + jsresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Point, 0 | 0 ); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +bool _wrap_pt_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + Point arg1 ; + void *argp1 ; + int res1 = 0 ; + + { + res1 = SWIG_ConvertPtr(value, &argp1, SWIGTYPE_p_Point, 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pt_set" "', argument " "1"" of type '" "Point""'"); + } + if (!argp1) { + SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "pt_set" "', argument " "1"" of type '" "Point""'"); + } else { + arg1 = *((Point *)(argp1)); + } + } + pt = arg1; + + + return true; + + goto fail; +fail: + return false; +} + + +JSValueRef _wrap_pt_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + Point result; + + result = pt; + jsresult = SWIG_NewPointerObj((Point *)memcpy((Point *)malloc(sizeof(Point)),&result,sizeof(Point)), SWIGTYPE_p_Point, SWIG_POINTER_OWN | 0 ); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +JSValueRef _wrap_status_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + int result; + + result = (int)status; + jsresult = SWIG_From_int SWIG_JSC_FROM_CALL_ARGS((int)(result)); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +JSValueRef _wrap_path_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + char *result = 0 ; + + result = (char *)(char *)path; + { + size_t size = 256; + + while (size && (result[size - 1] == '\0')) --size; + + jsresult = SWIG_FromCharPtrAndSize(result, size); + } + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +JSValueRef _wrap_print_vars(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + + print_vars(); + jsresult = JSValueMakeUndefined(context); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +JSValueRef _wrap_new_int(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + int arg1 ; + int val1 ; + int ecode1 = 0 ; + JSValueRef jsresult; + int *result = 0 ; + + ecode1 = SWIG_AsVal_int SWIG_JSC_AS_CALL_ARGS(argv[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_int" "', argument " "1"" of type '" "int""'"); + } + arg1 = (int)(val1); + result = (int *)new_int(arg1); + jsresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 | 0 ); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +JSValueRef _wrap_new_Point(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + int arg1 ; + int arg2 ; + int val1 ; + int ecode1 = 0 ; + int val2 ; + int ecode2 = 0 ; + JSValueRef jsresult; + Point *result = 0 ; + + ecode1 = SWIG_AsVal_int SWIG_JSC_AS_CALL_ARGS(argv[0], &val1); + if (!SWIG_IsOK(ecode1)) { + SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_Point" "', argument " "1"" of type '" "int""'"); + } + arg1 = (int)(val1); + ecode2 = SWIG_AsVal_int SWIG_JSC_AS_CALL_ARGS(argv[1], &val2); + if (!SWIG_IsOK(ecode2)) { + SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_Point" "', argument " "2"" of type '" "int""'"); + } + arg2 = (int)(val2); + result = (Point *)new_Point(arg1,arg2); + jsresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Point, 0 | 0 ); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +JSValueRef _wrap_Point_print(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + Point *arg1 = (Point *) 0 ; + void *argp1 = 0 ; + int res1 = 0 ; + JSValueRef jsresult; + char *result = 0 ; + + res1 = SWIG_ConvertPtr(argv[0], &argp1,SWIGTYPE_p_Point, 0 | 0 ); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Point_print" "', argument " "1"" of type '" "Point *""'"); + } + arg1 = (Point *)(argp1); + result = (char *)Point_print(arg1); + jsresult = SWIG_FromCharPtr((const char *)result); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +JSValueRef _wrap_pt_print(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + + pt_print(); + jsresult = JSValueMakeUndefined(context); + + return jsresult; + + goto fail; +fail: + return NULL; +} + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ + +static swig_type_info _swigt__p_Point = {"_p_Point", "Point *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; +static swig_type_info _swigt__p_int = {"_p_int", "int *", 0, 0, (void*)0, 0}; + +static swig_type_info *swig_type_initial[] = { + &_swigt__p_Point, + &_swigt__p_char, + &_swigt__p_int, +}; + +static swig_cast_info _swigc__p_Point[] = { {&_swigt__p_Point, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; +static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; + +static swig_cast_info *swig_cast_initial[] = { + _swigc__p_Point, + _swigc__p_char, + _swigc__p_int, +}; + + +/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ + + + +JSStaticValue example_values[] = { + { + "ivar",_wrap_ivar_get, _wrap_ivar_set,kJSPropertyAttributeNone + },{ + "svar",_wrap_svar_get, _wrap_svar_set,kJSPropertyAttributeNone + },{ + "lvar",_wrap_lvar_get, _wrap_lvar_set,kJSPropertyAttributeNone + },{ + "uivar",_wrap_uivar_get, _wrap_uivar_set,kJSPropertyAttributeNone + },{ + "usvar",_wrap_usvar_get, _wrap_usvar_set,kJSPropertyAttributeNone + },{ + "ulvar",_wrap_ulvar_get, _wrap_ulvar_set,kJSPropertyAttributeNone + },{ + "scvar",_wrap_scvar_get, _wrap_scvar_set,kJSPropertyAttributeNone + },{ + "ucvar",_wrap_ucvar_get, _wrap_ucvar_set,kJSPropertyAttributeNone + },{ + "cvar",_wrap_cvar_get, _wrap_cvar_set,kJSPropertyAttributeNone + },{ + "fvar",_wrap_fvar_get, _wrap_fvar_set,kJSPropertyAttributeNone + },{ + "dvar",_wrap_dvar_get, _wrap_dvar_set,kJSPropertyAttributeNone + },{ + "strvar",_wrap_strvar_get, _wrap_strvar_set,kJSPropertyAttributeNone + },{ + "cstrvar",_wrap_cstrvar_get, JS_veto_set_variable,kJSPropertyAttributeNone + },{ + "iptrvar",_wrap_iptrvar_get, _wrap_iptrvar_set,kJSPropertyAttributeNone + },{ + "name",_wrap_name_get, _wrap_name_set,kJSPropertyAttributeNone + },{ + "ptptr",_wrap_ptptr_get, _wrap_ptptr_set,kJSPropertyAttributeNone + },{ + "pt",_wrap_pt_get, _wrap_pt_set,kJSPropertyAttributeNone + },{ + "status",_wrap_status_get, JS_veto_set_variable,kJSPropertyAttributeNone + },{ + "path",_wrap_path_get, JS_veto_set_variable,kJSPropertyAttributeNone + }, + { + 0, 0, 0, 0 + } +}; + +JSStaticFunction example_functions[] = { + { + "print_vars",_wrap_print_vars, kJSPropertyAttributeNone + },{ + "new_int",_wrap_new_int, kJSPropertyAttributeNone + },{ + "new_Point",_wrap_new_Point, kJSPropertyAttributeNone + },{ + "Point_print",_wrap_Point_print, kJSPropertyAttributeNone + },{ + "pt_print",_wrap_pt_print, kJSPropertyAttributeNone + }, + { + 0, 0, 0 + } +}; + +JSClassDefinition example_classDefinition; + + +SWIGRUNTIME void +SWIG_JSC_SetModule(swig_module_info *swig_module) {} + +SWIGRUNTIME swig_module_info * +SWIG_JSC_GetModule(void) { + return 0; +} + +#define SWIG_GetModule(clientdata) SWIG_JSC_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_JSC_SetModule(pointer) + + +/* ----------------------------------------------------------------------------- + * Type initialization: + * This problem is tough by the requirement that no dynamic + * memory is used. Also, since swig_type_info structures store pointers to + * swig_cast_info structures and swig_cast_info structures store pointers back + * to swig_type_info structures, we need some lookup code at initialization. + * The idea is that swig generates all the structures that are needed. + * The runtime then collects these partially filled structures. + * The SWIG_InitializeModule function takes these initial arrays out of + * swig_module, and does all the lookup, filling in the swig_module.types + * array with the correct data and linking the correct swig_cast_info + * structures together. + * + * The generated swig_type_info structures are assigned staticly to an initial + * array. We just loop through that array, and handle each type individually. + * First we lookup if this type has been already loaded, and if so, use the + * loaded structure instead of the generated one. Then we have to fill in the + * cast linked list. The cast data is initially stored in something like a + * two-dimensional array. Each row corresponds to a type (there are the same + * number of rows as there are in the swig_type_initial array). Each entry in + * a column is one of the swig_cast_info structures for that type. + * The cast_initial array is actually an array of arrays, because each row has + * a variable number of columns. So to actually build the cast linked list, + * we find the array of casts associated with the type, and loop through it + * adding the casts to the list. The one last trick we need to do is making + * sure the type pointer in the swig_cast_info struct is correct. + * + * First off, we lookup the cast->type name to see if it is already loaded. + * There are three cases to handle: + * 1) If the cast->type has already been loaded AND the type we are adding + * casting info to has not been loaded (it is in this module), THEN we + * replace the cast->type pointer with the type pointer that has already + * been loaded. + * 2) If BOTH types (the one we are adding casting info to, and the + * cast->type) are loaded, THEN the cast info has already been loaded by + * the previous module so we just ignore it. + * 3) Finally, if cast->type has not already been loaded, then we add that + * swig_cast_info to the linked list (because the cast->type) pointer will + * be correct. + * ----------------------------------------------------------------------------- */ + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* c-mode */ +#endif +#endif + +#if 0 +#define SWIGRUNTIME_DEBUG +#endif + + +SWIGRUNTIME void +SWIG_InitializeModule(void *clientdata) { + size_t i; + swig_module_info *module_head, *iter; + int found, init; + + clientdata = clientdata; + + /* check to see if the circular list has been setup, if not, set it up */ + if (swig_module.next==0) { + /* Initialize the swig_module */ + swig_module.type_initial = swig_type_initial; + swig_module.cast_initial = swig_cast_initial; + swig_module.next = &swig_module; + init = 1; + } else { + init = 0; + } + + /* Try and load any already created modules */ + module_head = SWIG_GetModule(clientdata); + if (!module_head) { + /* This is the first module loaded for this interpreter */ + /* so set the swig module into the interpreter */ + SWIG_SetModule(clientdata, &swig_module); + module_head = &swig_module; + } else { + /* the interpreter has loaded a SWIG module, but has it loaded this one? */ + found=0; + iter=module_head; + do { + if (iter==&swig_module) { + found=1; + break; + } + iter=iter->next; + } while (iter!= module_head); + + /* if the is found in the list, then all is done and we may leave */ + if (found) return; + /* otherwise we must add out module into the list */ + swig_module.next = module_head->next; + module_head->next = &swig_module; + } + + /* When multiple interpeters are used, a module could have already been initialized in + a different interpreter, but not yet have a pointer in this interpreter. + In this case, we do not want to continue adding types... everything should be + set up already */ + if (init == 0) return; + + /* Now work on filling in swig_module.types */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: size %d\n", swig_module.size); +#endif + for (i = 0; i < swig_module.size; ++i) { + swig_type_info *type = 0; + swig_type_info *ret; + swig_cast_info *cast; + +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); +#endif + + /* if there is another module already loaded */ + if (swig_module.next != &swig_module) { + type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); + } + if (type) { + /* Overwrite clientdata field */ +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found type %s\n", type->name); +#endif + if (swig_module.type_initial[i]->clientdata) { + type->clientdata = swig_module.type_initial[i]->clientdata; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); +#endif + } + } else { + type = swig_module.type_initial[i]; + } + + /* Insert casting types */ + cast = swig_module.cast_initial[i]; + while (cast->type) { + + /* Don't need to add information already in the list */ + ret = 0; +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); +#endif + if (swig_module.next != &swig_module) { + ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); +#ifdef SWIGRUNTIME_DEBUG + if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); +#endif + } + if (ret) { + if (type == swig_module.type_initial[i]) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: skip old type %s\n", ret->name); +#endif + cast->type = ret; + ret = 0; + } else { + /* Check for casting already in the list */ + swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); +#ifdef SWIGRUNTIME_DEBUG + if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); +#endif + if (!ocast) ret = 0; + } + } + + if (!ret) { +#ifdef SWIGRUNTIME_DEBUG + printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); +#endif + if (type->cast) { + type->cast->prev = cast; + cast->next = type->cast; + } + type->cast = cast; + } + cast++; + } + /* Set entry in modules->types array equal to the type */ + swig_module.types[i] = type; + } + swig_module.types[i] = 0; + +#ifdef SWIGRUNTIME_DEBUG + printf("**** SWIG_InitializeModule: Cast List ******\n"); + for (i = 0; i < swig_module.size; ++i) { + int j = 0; + swig_cast_info *cast = swig_module.cast_initial[i]; + printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); + while (cast->type) { + printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); + cast++; + ++j; + } + printf("---- Total casts: %d\n",j); + } + printf("**** SWIG_InitializeModule: Cast List ******\n"); +#endif +} + +/* This function will propagate the clientdata field of type to +* any new swig_type_info structures that have been added into the list +* of equivalent types. It is like calling +* SWIG_TypeClientData(type, clientdata) a second time. +*/ +SWIGRUNTIME void +SWIG_PropagateClientData(void) { + size_t i; + swig_cast_info *equiv; + static int init_run = 0; + + if (init_run) return; + init_run = 1; + + for (i = 0; i < swig_module.size; i++) { + if (swig_module.types[i]->clientdata) { + equiv = swig_module.types[i]->cast; + while (equiv) { + if (!equiv->converter) { + if (equiv->type && !equiv->type->clientdata) + SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); + } + equiv = equiv->next; + } + } + } +} + +#ifdef __cplusplus +#if 0 +{ /* c-mode */ +#endif +} +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + bool example_initialize(JSGlobalContextRef context) { + SWIG_InitializeModule(0); + + JSObjectRef global_object = JSContextGetGlobalObject(context); + + /* Initialize the base swig type object */ + _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; + _SwigObject_objectDefinition.staticValues = _SwigObject_values; + _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + + /* Create objects for namespaces */ + example_classDefinition.staticFunctions = example_functions; + example_classDefinition.staticValues = example_values; + JSObjectRef example_object = JSObjectMake(context, JSClassCreate(&example_classDefinition), NULL); + + + /* Create classes */ + + + /* Register namespaces */ + + JS_registerNamespace(context, example_object, global_object, "example"); + + return true; + } + +#ifdef __cplusplus +} +#endif + + From 672208d8d20eef3214bf4f48fce009eb3f053a81 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:03:17 +0000 Subject: [PATCH 048/352] Adapt overload example to reflect changes in module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13782 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/javascript/overload/example.i | 4 ---- Examples/javascript/overload/runme.js | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/Examples/javascript/overload/example.i b/Examples/javascript/overload/example.i index c4f652c0a..b86689f8a 100644 --- a/Examples/javascript/overload/example.i +++ b/Examples/javascript/overload/example.i @@ -11,10 +11,6 @@ for dispatching. To solve the problem one has to rename such conflicting methods. */ - -%rename(f_string) f(const char* s); -%rename(f_bool) f(bool val); -%rename(f_long) f(long val); %rename(f_double) f(double val); %include "example.h" diff --git a/Examples/javascript/overload/runme.js b/Examples/javascript/overload/runme.js index c6d4ef68d..6b822f107 100644 --- a/Examples/javascript/overload/runme.js +++ b/Examples/javascript/overload/runme.js @@ -1,7 +1,7 @@ example.f(); example.f(1); example.f(1, 2); -example.f_string("bla"); -example.f_bool(false); -example.f_long(11111111111); +example.f("bla"); +example.f(false); +example.f(11111111111); example.f_double(1.0); From 10dc758cadc7e0f27eee867a071ba199678e8a0a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:03:42 +0000 Subject: [PATCH 049/352] Refactored javascript shell implementation to support JSC and v8. Also changed configuration in examples Makefile.in to allow switching modes. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13783 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 19 ++- Tools/javascript/javascript.cxx | 276 +++++++++----------------------- Tools/javascript/js_shell.cxx | 95 +++++++++++ Tools/javascript/js_shell.h | 49 ++++++ Tools/javascript/jsc_shell.cxx | 171 ++++++++++++++++++++ Tools/javascript/v8_shell.cxx | 222 +++++++++++++++++++++++++ 6 files changed, 632 insertions(+), 200 deletions(-) create mode 100644 Tools/javascript/js_shell.cxx create mode 100644 Tools/javascript/js_shell.h create mode 100644 Tools/javascript/jsc_shell.cxx create mode 100755 Tools/javascript/v8_shell.cxx diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 4f20b83b8..027ce795e 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -525,7 +525,7 @@ ifeq (,$(V8)) JS_DLNK = @JSCOREDYNAMICLINKING@ else JS_INCLUDE = @JSV8INC@ - JS_DLNK = @JSCOREDYNAMICLINKING@ + JS_DLNK = @JSV8DYNAMICLINKING@ endif ifeq (,$(V8)) @@ -542,6 +542,19 @@ JSCXXSHARED = @JSCORECXXSHARED@ JSCFLAGS = @JSCORECFLAGS@ JSCXXFLAGS = @JSCXXFLAGS@ +JSEXE_SRC_DIR = $(TOP)/../Tools/javascript +JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx +JSEXE = $(TOP)/../Tools/javascript/javascript +ifeq (,$(V8)) + JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx $(JSEXE_SRC_DIR)/jsc_shell.cxx + JSEXE_OPTS = -jsc + JSEXE_FLAGS = -DUSE_JSC +else + JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx $(JSEXE_SRC_DIR)/v8_shell.cxx + JSEXE_OPTS = -v8 + JSEXE_FLAG = -DUSE_V8 +endif + # ---------------------------------------------------------------- # Build a javascript dynamically loadable module (C) # ---------------------------------------------------------------- @@ -564,14 +577,14 @@ javascript_cpp: $(SRCS) # Compile a javascript executable # ---------------------------------------------------------------- javascript_exe: $(SRCS) - $(CXX) $(CXXFLAGS) $(JS_INCLUDE) $(JSCXXSRCS) $(LIBS) $(JS_DLNK) -o $(JAVASCRIPT_EXE) + $(CXX) $(CXXFLAGS) $(JSEXE_FLAGS) $(JS_INCLUDE) $(LIBS) $(JSEXE_SRC) $(JS_DLNK) -o $(JSEXE) # ---------------------------------------------------------------- # Run the Compile a javascript executable # ---------------------------------------------------------------- javascript_run: $(SRCS) - env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JAVASCRIPT_EXE) -l $(TARGET) $(JS_SCRIPT) + env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JSEXE) $(JSEXE_OPTS) -l $(TARGET) $(JS_SCRIPT) # ----------------------------------------------------------------- # Cleaning the javascript examples diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx index 9e7dd2809..798158ff0 100644 --- a/Tools/javascript/javascript.cxx +++ b/Tools/javascript/javascript.cxx @@ -1,217 +1,99 @@ - -#include #include +#include #include - #include #include #include -#include +#include "js_shell.h" -#include +#ifdef USE_JSC +extern JSShell* create_jsc_shell(); +#endif -using namespace std; - -static JSValueRef jsc_printstring(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); -static char* jsccreateStringWithContentsOfFile(const char* fileName); -bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* FunctionName,JSObjectCallAsFunctionCallback cbFunction); - -typedef void* HANDLE; -typedef int (*JSCIntializer)(JSGlobalContextRef context); - -void jsc_printError(JSContextRef, JSValueRef, const std::string&); +#ifdef USE_V8 +extern JSShell* create_v8_shell(); +#endif void print_usage() { - std::cout << "javascript [-l module] " << std::endl; + std::cout << "javascript [-i] [-jsc|-v8] [-l module] " << std::endl; } int main(int argc, char* argv[]) { - std::string scriptPath; - - std::vector module_names; - - std::vector loaded_modules; - std::vector module_initializers; + std::string scriptPath = ""; + std::vector module_names; - for (int idx = 1; idx < argc; ++idx) { - if(strcmp(argv[idx], "-l") == 0) { - idx++; - if(idx > argc) { - print_usage(); - exit(-1); - } - std::string module_name(argv[idx]); - module_names.push_back(module_name); - } else { - scriptPath = argv[idx]; + bool interactive = false; + JSShell* shell = 0; + + for (int idx = 1; idx < argc; ++idx) { + if(strcmp(argv[idx], "-l") == 0) { + idx++; + if(idx > argc) { + print_usage(); + exit(-1); } + std::string module_name(argv[idx]); + module_names.push_back(module_name); + } else if(strcmp(argv[idx], "-v8") == 0) { +#ifdef USE_V8 + shell = create_v8_shell(); +#else + std::cerr << "V8 support is not enabled" << std::endl; + exit(-1); +#endif + } else if(strcmp(argv[idx], "-jsc") == 0) { +#ifdef USE_JSC + shell = create_jsc_shell(); +#else + std::cerr << "JSC support is not enabled" << std::endl; + exit(-1); +#endif + } else if(strcmp(argv[idx], "-i") == 0) { + interactive = true; + } else { + scriptPath = argv[idx]; } - - for(std::vector::iterator it = module_names.begin(); - it != module_names.end(); ++it) { - std::string module_name = *it; - std::string lib_name = std::string("lib").append(module_name).append(".so"); - - HANDLE handle = dlopen(lib_name.c_str(), RTLD_LAZY); - if(handle == 0) { - std::cout << "Could not load library " << lib_name << ":" - << std::endl << dlerror() << std::endl; - continue; - } - - std::string symname; - symname.append(module_name).append("_initialize"); - - JSCIntializer init_function = reinterpret_cast((long) dlsym(handle, symname.c_str())); - if(init_function == 0) { - std::cout << "Could not find initializer function in module " << module_name << std::endl; - dlclose(handle); - continue; - } - - loaded_modules.push_back(handle); - module_initializers.push_back(init_function); - } - - static int failed; - - JSGlobalContextRef context = JSGlobalContextCreate(NULL); - JSObjectRef globalObject = JSContextGetGlobalObject(context); - - jsc_registerFunction(context, globalObject, "print", jsc_printstring); // Utility print function - - // Call module initializers - for(std::vector::iterator it = module_initializers.begin(); - it != module_initializers.end(); ++it) { - JSCIntializer init_function = *it; - init_function(context); - } - - // Evaluate the javascript - char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); - JSStringRef jsScript; - - if(!scriptContent) { - printf("FAIL: runme script could not be loaded.\n"); - failed = 1; - } - else { - JSValueRef ex; - jsScript = JSStringCreateWithUTF8CString(scriptContent); - JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); - - if (!jsResult && ex) { - jsc_printError(context, ex, scriptPath); - failed = 1; - } - } - - if (scriptContent != NULL) { - free(scriptContent); - } - - JSStringRelease(jsScript); - - JSGlobalContextRelease(context); - globalObject = 0; - - for(std::vector::iterator it = loaded_modules.begin(); - it != loaded_modules.end(); ++it) { - HANDLE handle = *it; - dlclose(handle); - } - - if (failed) { - printf("FAIL: Some tests failed.\n"); - return 1; - } -} - -static JSValueRef jsc_printstring(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex) -{ - if (argc > 0) - { - JSStringRef string = JSValueToStringCopy(context, args[0], NULL); - size_t numChars = JSStringGetMaximumUTF8CStringSize(string); - char *stringUTF8 = new char[numChars]; - JSStringGetUTF8CString(string, stringUTF8, numChars); - printf("%s\n", stringUTF8); - - delete[] stringUTF8; - } - - return JSValueMakeUndefined(context); -} - -static char* jsccreateStringWithContentsOfFile(const char* fileName) -{ - char* buffer; - - size_t buffer_size = 0; - size_t buffer_capacity = 1024; - buffer = (char*)malloc(buffer_capacity); - - FILE* f = fopen(fileName, "r"); - if (!f) - { - fprintf(stderr, "Could not open file: %s\n", fileName); - return 0; - } - - while (!feof(f) && !ferror(f)) - { - buffer_size += fread(buffer + buffer_size, 1, buffer_capacity - buffer_size, f); - if (buffer_size == buffer_capacity) - { - // guarantees space for trailing '\0' - buffer_capacity *= 2; - buffer = (char*)realloc(buffer, buffer_capacity); - } - } - fclose(f); - buffer[buffer_size] = '\0'; - - return buffer; -} - -bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, - const char* functionName, JSObjectCallAsFunctionCallback callback) -{ - JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); - JSObjectSetProperty(context, object, js_functionName, - JSObjectMakeFunctionWithCallback(context, js_functionName, callback), - kJSPropertyAttributeNone, NULL); - JSStringRelease(js_functionName); - return true; -} - -void jsc_printError(JSContextRef ctx, JSValueRef err, const std::string& sourceUrl) -{ - char *buffer; - - JSStringRef string = JSValueToStringCopy(ctx, err, 0); - size_t length = JSStringGetLength(string); - - buffer = (char*) malloc(length+1); - JSStringGetUTF8CString(string, buffer, length+1); - std::string errMsg(buffer); - JSStringRelease(string); - free(buffer); - - JSObjectRef errObj = JSValueToObject(ctx, err, 0); - - if(errObj == 0) { - return; } - // Note: usually you would also retrieve the property "sourceURL" - // though, it happened that this was always "" - JSStringRef lineKey = JSStringCreateWithUTF8CString("line"); - JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0); - int line = (int) JSValueToNumber(ctx, jsLine, 0); - JSStringRelease(lineKey); + + if (shell == 0) { +#ifdef USE_JSC + shell = create_jsc_shell(); +#else + std::cerr << "JSC support is not enabled" << std::endl; + exit(-1); +#endif + } + + bool failed = false; + for(std::vector::iterator it = module_names.begin(); + it != module_names.end(); ++it) { + std::string module_name = *it; - std::cerr << sourceUrl << ":" << line << ":" << errMsg << std::endl; - + bool success = shell->ImportModule(module_name); + failed |= !success; + } + + if (failed) { + delete shell; + printf("FAIL: Some modules could not be loaded.\n"); + return -1; + } + + if(interactive) { + failed = !(shell->RunShell()); + } else { + failed = !(shell->RunScript(scriptPath)); + } + + if (failed) { + delete shell; + printf("FAIL: Error during execution of script.\n"); + return 1; + } + + delete shell; + + return 0; } diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx new file mode 100644 index 000000000..b2b8672a6 --- /dev/null +++ b/Tools/javascript/js_shell.cxx @@ -0,0 +1,95 @@ +#include "js_shell.h" + +#include +#include +#include +#include + +#ifdef __GNUC__ +#include +#define LOAD_LIBRARY(name) dlopen(name, RTLD_LAZY) +#define CLOSE_LIBRARY(handle) dlclose(handle) +#define LIBRARY_ERROR dlerror +#define LIBRARYFILE(name) std::string("lib").append(name).append(".so") +#else +#error "implement dll loading" +#endif + +JSShell::~JSShell() { + + for(std::vector::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + CLOSE_LIBRARY(handle); + } + +} + +bool JSShell::ImportModule(const std::string& name) { + + std::string lib_name = LIBRARYFILE(name); + + HANDLE handle = LOAD_LIBRARY(lib_name.c_str()); + if(handle == 0) { + std::cout << "Could not load library " << lib_name << ":" + << std::endl << LIBRARY_ERROR() << std::endl; + return false; + } + + if(!RegisterModule(handle, name)) { + std::cout << "Could not find initializer function in " << lib_name << std::endl; + CLOSE_LIBRARY(handle); + return false; + } + + loaded_modules.push_back(handle); + + return true; +} + +bool JSShell::RunScript(const std::string& scriptPath) { + std::string source = ReadFile(scriptPath); + if(!InitializeEngine()) return false; + + if(!ExecuteScript(source, scriptPath)) { + return false; + } + + return DisposeEngine(); +} + +bool JSShell::RunShell() { + + if(!InitializeEngine()) return false; + + static const int kBufferSize = 1024; + while (true) { + char buffer[kBufferSize]; + printf("> "); + char* str = fgets(buffer, kBufferSize, stdin); + if (str == NULL) break; + std::string source(str); + ExecuteScript(source, "(shell)"); + } + printf("\n"); +} + +std::string JSShell::ReadFile(const std::string& fileName) +{ + std::string script; + + std::ifstream file(fileName.c_str()); + if (file.is_open()) { + while ( file.good() ) { + std::string line; + getline(file, line); + script.append(line); + script.append("\n"); + } + file.close(); + } else { + std::cout << "Unable to open file " << fileName << "." << std::endl; + } + + return script; +} diff --git a/Tools/javascript/js_shell.h b/Tools/javascript/js_shell.h new file mode 100644 index 000000000..96535a4c0 --- /dev/null +++ b/Tools/javascript/js_shell.h @@ -0,0 +1,49 @@ +#ifndef JS_SHELL_H +#define JS_SHELL_H + +#include +#include + +typedef void* HANDLE; + +class JSShell { + +public: + enum Engine { + JSC, + V8 + }; + +public: + + JSShell() {} + + virtual ~JSShell(); + + bool ImportModule(const std::string& name); + + virtual bool RunScript(const std::string& scriptPath); + + virtual bool RunShell(); + +protected: + + virtual bool RegisterModule(HANDLE library, const std::string& module_name) = 0; + + virtual bool InitializeEngine() = 0; + + virtual bool ExecuteScript(const std::string& source, const std::string& name) = 0; + + virtual bool DisposeEngine() = 0; + + static std::string ReadFile(const std::string& fileName); + +protected: + + std::vector loaded_modules; + +}; + +typedef JSShell* (*JSShellFactory)(); + +#endif // JS_SHELL_H diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx new file mode 100644 index 000000000..3fa704440 --- /dev/null +++ b/Tools/javascript/jsc_shell.cxx @@ -0,0 +1,171 @@ +#include + +#include "js_shell.h" + +#include +#include + +#ifdef __GNUC__ +#include +#define LOAD_SYMBOL(handle, name) dlsym(handle, name) +#else +#error "implement dll loading" +#endif + +JSValueRef JSCShell_Print(JSContextRef context, JSObjectRef object, + JSObjectRef globalobj, size_t argc, + const JSValueRef args[], JSValueRef* ex); + +class JSCShell: public JSShell { + +typedef int (*JSCIntializer)(JSGlobalContextRef context); + +public: + + JSCShell() {}; + + virtual ~JSCShell(); + +protected: + + virtual bool RegisterModule(HANDLE library, const std::string& module_name); + + virtual bool InitializeEngine(); + + virtual bool ExecuteScript(const std::string& source, const std::string& name); + + virtual bool DisposeEngine(); + +private: + + //static JSValueRef Print(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + + static bool RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback cbFunction); + + static void PrintError(JSContextRef, JSValueRef, const std::string&); + +private: + + std::vector module_initializers; + + JSGlobalContextRef context; +}; + +using namespace std; + +JSCShell::~JSCShell() { + if(context != 0) { + JSGlobalContextRelease(context); + context = 0; + } +} + +bool JSCShell::RegisterModule(HANDLE library, const std::string& module_name) { + std::string symname = std::string(module_name).append("_initialize"); + + JSCIntializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); + if(init_function == 0) return false; + + module_initializers.push_back(init_function); + return true; +} + +bool JSCShell::InitializeEngine() { + if(context != 0) { + JSGlobalContextRelease(context); + context = 0; + } + // TODO: check for initialization errors + context = JSGlobalContextCreate(NULL); + if(context == 0) return false; + JSObjectRef globalObject = JSContextGetGlobalObject(context); + JSCShell::RegisterFunction(context, globalObject, "print", JSCShell_Print); + // Call module initializers + for(std::vector::iterator it = module_initializers.begin(); + it != module_initializers.end(); ++it) { + JSCIntializer init_function = *it; + if(!init_function(context)) { + return false; + } + } + return true; +} + +bool JSCShell::ExecuteScript(const std::string& source, const std::string& name) { + JSStringRef jsScript; + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(source.c_str()); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + JSStringRelease(jsScript); + if (jsResult == NULL && ex != NULL) { + JSCShell::PrintError(context, ex, name); + return false; + } + return true; +} + +bool JSCShell::DisposeEngine() { + JSGlobalContextRelease(context); + context = 0; + return true; +} + +JSValueRef JSCShell_Print(JSContextRef context, JSObjectRef object, + JSObjectRef globalobj, size_t argc, + const JSValueRef args[], JSValueRef* ex) { + if (argc > 0) + { + JSStringRef string = JSValueToStringCopy(context, args[0], NULL); + size_t numChars = JSStringGetMaximumUTF8CStringSize(string); + char *stringUTF8 = new char[numChars]; + JSStringGetUTF8CString(string, stringUTF8, numChars); + printf("%s\n", stringUTF8); + + delete[] stringUTF8; + } + + return JSValueMakeUndefined(context); +} + +bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) { + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context, object, js_functionName, + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} + +void JSCShell::PrintError(JSContextRef ctx, JSValueRef err, const std::string& name) { + char *buffer; + + JSStringRef string = JSValueToStringCopy(ctx, err, 0); + size_t length = JSStringGetLength(string); + + buffer = new char[length+1]; + JSStringGetUTF8CString(string, buffer, length+1); + std::string errMsg(buffer); + JSStringRelease(string); + delete[] buffer; + + JSObjectRef errObj = JSValueToObject(ctx, err, 0); + + if(errObj == 0) { + std::cerr << errMsg << std::endl; + return; + } + + // Note: usually you would also retrieve the property "sourceURL" + // though, it happened that this was always "" + JSStringRef lineKey = JSStringCreateWithUTF8CString("line"); + JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0); + int line = (int) JSValueToNumber(ctx, jsLine, 0); + JSStringRelease(lineKey); + + std::cerr << name << ":" << line << ":" << errMsg << std::endl; +} + +JSShell* create_jsc_shell() { + return new JSCShell(); +} diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx new file mode 100755 index 000000000..940609ec3 --- /dev/null +++ b/Tools/javascript/v8_shell.cxx @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include "js_shell.h" + +typedef int (*V8ExtensionRegistrar) (v8::Handle); + +class V8Shell: public JSShell { + +public: + V8Shell(); + + virtual ~V8Shell(); + +protected: + + virtual bool RegisterModule(HANDLE library, const std::string& module_name); + + virtual bool InitializeEngine(); + + virtual bool ExecuteScript(const std::string& source, const std::string& name); + + virtual bool DisposeEngine(); + +private: + + v8::Persistent CreateShellContext(); + + void ReportException(v8::TryCatch* handler); + + static v8::Handle Print(const v8::Arguments& args); + + static v8::Handle Quit(const v8::Arguments& args); + + static v8::Handle Version(const v8::Arguments& args); + + static const char* ToCString(const v8::String::Utf8Value& value); + +protected: + + std::vector module_initializers; + + v8::Persistent context; + +}; + +#ifdef __GNUC__ +#include +#define LOAD_SYMBOL(handle, name) dlsym(handle, name) +#else +#error "implement dll loading" +#endif + +// Extracts a C string from a V8 Utf8Value. +const char* V8Shell::ToCString(const v8::String::Utf8Value& value) { + return *value ? *value : ""; +} + +V8Shell::V8Shell() +{ +} + +V8Shell::~V8Shell() { + context.Dispose(); + v8::V8::Dispose(); +} + +bool V8Shell::RegisterModule(HANDLE library, const std::string& module_name) { + std::string symname = std::string(module_name).append("_initialize"); + + V8ExtensionRegistrar init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); + if(init_function == 0) return false; + + module_initializers.push_back(init_function); + return true; +} + +bool V8Shell::InitializeEngine() { + if (!context.IsEmpty()) { + context.Dispose(); + } + + context = CreateShellContext(); + if (context.IsEmpty()) { + printf("Could not create context.\n"); + return 1; + } + + context->Enter(); +} + +bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) { + // Enter the execution environment before evaluating any code. + v8::Context::Scope context_scope(context); + + v8::HandleScope handle_scope; + v8::TryCatch try_catch; + v8::Handle script = v8::Script::Compile(v8::String::New(source.c_str()), v8::String::New(name.c_str())); + if (script.IsEmpty()) { + // Print errors that happened during compilation. + ReportException(&try_catch); + return false; + } else { + v8::Handle result = script->Run(); + if (result.IsEmpty()) { + assert(try_catch.HasCaught()); + // Print errors that happened during execution. + ReportException(&try_catch); + return false; + } else { + assert(!try_catch.HasCaught()); + if (!result->IsUndefined()) { + // If all went well and the result wasn't undefined then print + // the returned value. + v8::String::Utf8Value str(result); + const char* cstr = V8Shell::ToCString(str); + printf("%s\n", cstr); + } + return true; + } + } +} + +bool V8Shell::DisposeEngine() { + context->Exit(); + context.Dispose(); + v8::V8::Dispose(); +} + +v8::Persistent V8Shell::CreateShellContext() { + // Create a template for the global object. + v8::Handle global = v8::ObjectTemplate::New(); + + // Bind global functions + global->Set(v8::String::New("print"), v8::FunctionTemplate::New(V8Shell::Print)); + global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(V8Shell::Quit)); + global->Set(v8::String::New("version"), v8::FunctionTemplate::New(V8Shell::Version)); + + v8::Persistent _context = v8::Context::New(NULL, global); + + // register extensions + for(std::vector::iterator it=module_initializers.begin(); + it != module_initializers.end(); ++it) { + (*it)(_context); + } + + return _context; +} + + +v8::Handle V8Shell::Print(const v8::Arguments& args) { + bool first = true; + for (int i = 0; i < args.Length(); i++) { + v8::HandleScope handle_scope; + if (first) { + first = false; + } else { + printf(" "); + } + v8::String::Utf8Value str(args[i]); + const char* cstr = V8Shell::ToCString(str); + printf("%s", cstr); + } + printf("\n"); + fflush(stdout); + return v8::Undefined(); +} + +v8::Handle V8Shell::Quit(const v8::Arguments& args) { + int exit_code = args[0]->Int32Value(); + fflush(stdout); + fflush(stderr); + exit(exit_code); + return v8::Undefined(); +} + +v8::Handle V8Shell::Version(const v8::Arguments& args) { + return v8::String::New(v8::V8::GetVersion()); +} + +void V8Shell::ReportException(v8::TryCatch* try_catch) { + v8::HandleScope handle_scope; + v8::String::Utf8Value exception(try_catch->Exception()); + const char* exception_string = V8Shell::ToCString(exception); + v8::Handle message = try_catch->Message(); + if (message.IsEmpty()) { + // V8 didn't provide any extra information about this error; just + // print the exception. + printf("%s\n", exception_string); + } else { + // Print (filename):(line number): (message). + v8::String::Utf8Value filename(message->GetScriptResourceName()); + const char* filename_string = V8Shell::ToCString(filename); + int linenum = message->GetLineNumber(); + printf("%s:%i: %s\n", filename_string, linenum, exception_string); + // Print line of source code. + v8::String::Utf8Value sourceline(message->GetSourceLine()); + const char* sourceline_string = V8Shell::ToCString(sourceline); + printf("%s\n", sourceline_string); + // Print wavy underline (GetUnderline is deprecated). + int start = message->GetStartColumn(); + for (int i = 0; i < start; i++) { + printf(" "); + } + int end = message->GetEndColumn(); + for (int i = start; i < end; i++) { + printf("^"); + } + printf("\n"); + v8::String::Utf8Value stack_trace(try_catch->StackTrace()); + if (stack_trace.length() > 0) { + const char* stack_trace_string = V8Shell::ToCString(stack_trace); + printf("%s\n", stack_trace_string); + } + } +} From 0341e6b14c9f118ca2bfe853385df88779f0521b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:04:26 +0000 Subject: [PATCH 050/352] Clean up example Makefiles. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13784 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/javascript/class/Makefile | 12 +++++------- Examples/javascript/constant/Makefile | 12 +++++------- Examples/javascript/enum/Makefile | 12 +++++------- Examples/javascript/exception/Makefile | 12 +++++------- Examples/javascript/exception/runme.js | 15 +++++++++++++-- Examples/javascript/functor/Makefile | 12 +++++------- Examples/javascript/namespace/Makefile | 12 +++++------- Examples/javascript/operator/Makefile | 12 +++++------- Examples/javascript/overload/Makefile | 12 +++++------- Examples/javascript/pointer/Makefile | 12 +++++------- Examples/javascript/reference/Makefile | 12 +++++------- Examples/javascript/simple/Makefile | 12 +++++------- Examples/javascript/template/Makefile | 12 +++++------- Examples/javascript/variables/Makefile | 12 +++++------- 14 files changed, 78 insertions(+), 93 deletions(-) diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/class/Makefile +++ b/Examples/javascript/class/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile index bebb1f302..dbf2f6660 100755 --- a/Examples/javascript/constant/Makefile +++ b/Examples/javascript/constant/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/enum/Makefile +++ b/Examples/javascript/enum/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/exception/Makefile +++ b/Examples/javascript/exception/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js index dfa561993..936b37883 100644 --- a/Examples/javascript/exception/runme.js +++ b/Examples/javascript/exception/runme.js @@ -1,6 +1,7 @@ //file: runme.js // Throw a lot of exceptions +print("Trying to catch some exceptions."); t = new example.Test(); try{ t.unknown(); @@ -9,6 +10,8 @@ try{ { if(error == -1) { print("t.unknown() didn't throw"); + } else { + print("successfully catched throw in Test::unknown()."); } } @@ -19,6 +22,8 @@ try{ catch(error){ if(error == -1) { print("t.simple() did not throw"); + } else { + print("successfully catched throw in Test::simple()."); } } @@ -28,6 +33,8 @@ try{ } catch(error){ if(error == -1) { print("t.message() did not throw"); + } else { + print("successfully catched throw in Test::message()."); } } @@ -38,6 +45,8 @@ try{ catch(error){ if(error == -1) { print("t.hosed() did not throw"); + } else { + print("successfully catched throw in Test::hosed()."); } } @@ -48,7 +57,9 @@ for (var i=1; i<4; i++) { } catch(error){ if(error == -1) { - print("t.mulit(" + i + ") did not throw"); + print("t.multi(" + i + ") did not throw"); + } else { + print("successfully catched throw in Test::multi()."); } } -} +} diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/functor/Makefile +++ b/Examples/javascript/functor/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/namespace/Makefile +++ b/Examples/javascript/namespace/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/operator/Makefile +++ b/Examples/javascript/operator/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/overload/Makefile +++ b/Examples/javascript/overload/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/pointer/Makefile +++ b/Examples/javascript/pointer/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/reference/Makefile +++ b/Examples/javascript/reference/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile index 4fbfa2802..fb4669329 100755 --- a/Examples/javascript/simple/Makefile +++ b/Examples/javascript/simple/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript SRCS = example.c -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile index 1ac61ec6b..180e99cae 100755 --- a/Examples/javascript/template/Makefile +++ b/Examples/javascript/template/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript CXXSRCS = example.cpp -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile index 4fbfa2802..fb4669329 100755 --- a/Examples/javascript/variables/Makefile +++ b/Examples/javascript/variables/Makefile @@ -1,12 +1,9 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -JAVASCRIPT_EXE = $(TOP)/../Tools/javascript/javascript SRCS = example.c -JSCXXSRCS = $(TOP)/../Tools/javascript/javascript.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -SWIGOPT = -I$(TOP)/../Lib/javascript -I$(TOP)/../Lib/javascript/jsc all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ @@ -15,9 +12,10 @@ all:: clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean +javascript_exe:: + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' javascript_exe + check:: all $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' javascript_exe - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - JAVASCRIPT_EXE='$(JAVASCRIPT_EXE)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run - + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run From 5fab9c8a3857f2c0499790461160bdb4bc9d3602 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:04:40 +0000 Subject: [PATCH 051/352] Minor cleanup in javascript shell implementation. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13785 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Tools/javascript/jsc_shell.cxx | 12 +++--------- Tools/javascript/v8_shell.cxx | 10 +++++----- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx index 3fa704440..a21fb3f1a 100644 --- a/Tools/javascript/jsc_shell.cxx +++ b/Tools/javascript/jsc_shell.cxx @@ -12,10 +12,6 @@ #error "implement dll loading" #endif -JSValueRef JSCShell_Print(JSContextRef context, JSObjectRef object, - JSObjectRef globalobj, size_t argc, - const JSValueRef args[], JSValueRef* ex); - class JSCShell: public JSShell { typedef int (*JSCIntializer)(JSGlobalContextRef context); @@ -38,7 +34,7 @@ protected: private: - //static JSValueRef Print(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + static JSValueRef Print(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); static bool RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback cbFunction); @@ -51,8 +47,6 @@ private: JSGlobalContextRef context; }; -using namespace std; - JSCShell::~JSCShell() { if(context != 0) { JSGlobalContextRelease(context); @@ -79,7 +73,7 @@ bool JSCShell::InitializeEngine() { context = JSGlobalContextCreate(NULL); if(context == 0) return false; JSObjectRef globalObject = JSContextGetGlobalObject(context); - JSCShell::RegisterFunction(context, globalObject, "print", JSCShell_Print); + JSCShell::RegisterFunction(context, globalObject, "print", JSCShell::Print); // Call module initializers for(std::vector::iterator it = module_initializers.begin(); it != module_initializers.end(); ++it) { @@ -110,7 +104,7 @@ bool JSCShell::DisposeEngine() { return true; } -JSValueRef JSCShell_Print(JSContextRef context, JSObjectRef object, +JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex) { if (argc > 0) diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 940609ec3..e124ebd7d 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -57,11 +57,6 @@ protected: #error "implement dll loading" #endif -// Extracts a C string from a V8 Utf8Value. -const char* V8Shell::ToCString(const v8::String::Utf8Value& value) { - return *value ? *value : ""; -} - V8Shell::V8Shell() { } @@ -220,3 +215,8 @@ void V8Shell::ReportException(v8::TryCatch* try_catch) { } } } + +// Extracts a C string from a V8 Utf8Value. +const char* V8Shell::ToCString(const v8::String::Utf8Value& value) { + return *value ? *value : ""; +} From cdd450fbe4b9fa9a756cb464dbb3f54e2791106a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:04:51 +0000 Subject: [PATCH 052/352] Delete obsolete source file. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13786 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript_emitter.cxx | 198 -------------------------- 1 file changed, 198 deletions(-) delete mode 100644 Source/Modules/javascript_emitter.cxx diff --git a/Source/Modules/javascript_emitter.cxx b/Source/Modules/javascript_emitter.cxx deleted file mode 100644 index b9446663a..000000000 --- a/Source/Modules/javascript_emitter.cxx +++ /dev/null @@ -1,198 +0,0 @@ -#include "javascript_emitter.h" - -#include "swigmod.h" - -/* ----------------------------------------------------------------------------- - * JSEmitter() - * ----------------------------------------------------------------------------- */ - -JSEmitter::JSEmitter() - : empty_string(NewString("")) -{ - templates = NewHash(); -} - -/* ----------------------------------------------------------------------------- - * ~JSEmitter() - * ----------------------------------------------------------------------------- */ - -JSEmitter::~JSEmitter() -{ - Delete(empty_string); - Delete(templates); -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::RegisterTemplate() : Registers a code template - * ----------------------------------------------------------------------------- */ - -int JSEmitter::RegisterTemplate(const String *name, const String *code) -{ - return Setattr(templates, name, code); -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::GetTemplate() : Retrieves a registered a code template - * ----------------------------------------------------------------------------- */ - -const String* JSEmitter::GetTemplate(const String *name) -{ - String* templ = Getattr(templates, name); - - if(!templ) { - Printf(stderr, "Could not find template %s\n.", name); - SWIG_exit(EXIT_FAILURE); - } - - return templ; -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::typemapLookup() - * n - for input only and must contain info for Getfile(n) and Getline(n) to work - * tmap_method - typemap method name - * type - typemap type to lookup - * warning - warning number to issue if no typemaps found - * typemap_attributes - the typemap attributes are attached to this node and will - * also be used for temporary storage if non null - * return is never NULL, unlike Swig_typemap_lookup() - * ----------------------------------------------------------------------------- */ - -const String *JSEmitter::typemapLookup(Node *n, const_String_or_char_ptr tmap_method, - SwigType *type, int warning, Node *typemap_attributes) { - Node *node = !typemap_attributes ? NewHash() : typemap_attributes; - Setattr(node, "type", type); - Setfile(node, Getfile(n)); - Setline(node, Getline(n)); - const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0); - if (!tm) { - tm = empty_string; - if (warning != WARN_NONE) { - Swig_warning(warning, Getfile(n), Getline(n), - "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0)); - } - } - if (!typemap_attributes) { - Delete(node); - } - return tm; -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::GetBaseClass() : the node of the base class or NULL - * ----------------------------------------------------------------------------- */ - -Node* JSEmitter::GetBaseClass(Node* n) -{ - // retrieve the first base class that is not %ignored - List *baselist = Getattr(n, "bases"); - if (baselist) { - Iterator base = First(baselist); - while (base.item && GetFlag(base.item, "feature:ignore")) { - base = Next(base); - } - - return base.item; - } - - return NULL; -} - -/* ----------------------------------------------------------------------------- - * JSEmitter::EmitWrapperFunction() : dispatches emitter functions - * ----------------------------------------------------------------------------- */ - -int JSEmitter::EmitWrapperFunction(Node* n) -{ - int ret = SWIG_OK; - - current_wrapper = NewWrapper(); - Setattr(n, "wrap:name", NewString(Getattr(n, "sym:name"))); - - String* kind = Getattr(n, "kind"); - - if(kind) { - bool is_member = GetFlag(n, "ismember"); - if( Cmp(kind, "function") == 0 ) { - ret = EmitFunction(n, is_member); - } else if (Cmp(kind, "variable") == 0) { - if(IsSetterMethod(n)) { - ret = EmitSetter(n, is_member); - } else { - ret = EmitGetter(n, is_member); - } - } else { - Printf(stderr, "Warning: unsupported wrapper function type\n"); - Swig_print_node(n); - } - } else { - String *view = Getattr(n, "view"); - - if( Cmp(view, "constructorHandler") == 0 ) { - ret = EmitCtor(n); - - } else if( Cmp(view, "destructorHandler") == 0 ) { - ret = EmitDtor(n); - - } else { - Printf(stderr, "Warning: unsupported wrapper function type"); - Swig_print_node(n); - } - } - - DelWrapper(current_wrapper); - current_wrapper = 0; - - return ret; -} - -/* ----------------------------------------------------------------------------- - * str_ends_with() : c string helper to check suffix match - * ----------------------------------------------------------------------------- */ - -// TODO: shift this to DOH string API -int 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 ( str_ends_with( (char*) Data(symname), "_set") != 0 ); -} - -Template::Template(const String* code) -{ - if(!code) { - Printf(stdout, "Template code was null. Illegal input for template."); - SWIG_exit(EXIT_FAILURE); - } - - m_code = NewString(code); -} - -Template::~Template() { - Delete(m_code); -} - -String* Template::str() { - return m_code; -} - -Template& Template::Replace(const String* pattern, const String* repl) { - ::Replaceall(m_code, pattern, repl); - return *this; -} From 8d72616e6598dac37109fce3562c32c31188beb1 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:05:11 +0000 Subject: [PATCH 053/352] Refactor emitter and code templates to use defined template variables. Also switched from "${...}" to $..., which is swig's common notation of typemap variables. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13787 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptcode.swg | 154 +++++++++++----------- Source/Modules/javascript.cxx | 178 +++++++++++++++----------- 2 files changed, 175 insertions(+), 157 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 51b49039c..194181125 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -6,10 +6,12 @@ %fragment ("JS_getproperty", "templates") %{ -JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +JSValueRef $jsgetter(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) { - ${LOCALS} - ${CODE} + $jslocals + JSValueRef jsresult; + + $jscode return jsresult; goto fail; @@ -26,10 +28,10 @@ JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef %fragment ("JS_setproperty", "templates") %{ -bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +bool $jssetter(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) { - ${LOCALS} - ${CODE} + $jslocals + $jscode return true; @@ -46,10 +48,12 @@ bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef proper ************************************************************************************/ %fragment ("JS_functionwrapper", "templates") %{ -JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { - ${LOCALS} - ${CODE} + $jslocals + JSValueRef jsresult; + + $jscode return jsresult; goto fail; @@ -60,10 +64,12 @@ JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectR %fragment ("JS_functionwrapper_overload", "templates") %{ -int ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* result) +int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* result) { - ${LOCALS} - ${CODE} + $jslocals + JSValueRef jsresult; + + $jscode *result = jsresult; return SWIG_OK; @@ -80,83 +86,81 @@ int ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef this ***********************************************************************/ %fragment ("JS_function_dispatch_case", "templates") -%{if(argc == ${argcount}) { - res = ${functionwrapper}(context, function, thisObject, argc, argv, exception, &jsresult); +%{if(argc == $jsargcount) { + res = $jswrapper(context, function, thisObject, argc, argv, exception, &jsresult); if(res == SWIG_OK) { *exception = 0; return jsresult; } } %} %fragment ("JS_function_dispatch_case_default", "templates") %{ - SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function ${functionname}."); + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); %} /* Added template for function declaration */ %fragment ("JS_variabledecl", "templates") -%{{"${propertyname}",${getname}, ${setname},kJSPropertyAttributeNone},%} +%{{"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone},%} /* Added template for function declaration */ %fragment ("JS_functiondecl", "templates") -%{{"${functionname}",${functionwrapper}, kJSPropertyAttributeNone},%} +%{{"$jsname",$jswrapper, kJSPropertyAttributeNone},%} %fragment ("JS_globaldefn", "templates") %{ -JSStaticValue ${namespace}_values[] = { - ${jsglobalvariables} +JSStaticValue $jsnspace_values[] = { + $jsglobalvariables { 0, 0, 0, 0 } }; -JSStaticFunction ${namespace}_functions[] = { - ${jsglobalfunctions} +JSStaticFunction $jsnspace_functions[] = { + $jsglobalfunctions { 0, 0, 0 } }; -JSClassDefinition ${namespace}_classDefinition; +JSClassDefinition $jsnspace_classDefinition; %} -/****************************************************************************************** - * class_definition: - * This code template is used for wrapper of classes definition. - * ${classname_mangled}:the mangled name of the qualified class name, e.g., foo::A -> foo_A - *****************************************************************************************/ +/*********************************************************************** + * class_definition: + * declarations of javascript class definition objects. + ***********************************************************************/ %fragment ("JS_class_definition", "templates") %{ -JSClassDefinition ${classname_mangled}_classDefinition; +JSClassDefinition $jsmangledname_classDefinition; -JSClassDefinition ${classname_mangled}_objectDefinition; +JSClassDefinition $jsmangledname_objectDefinition; -JSClassRef ${classname_mangled}_classRef; +JSClassRef $jsmangledname_classRef; %} -/********************************************************************* - * class_table: - * This code template is used to add the wrapper for class declaration - * ${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A +/*********************************************************************** + * class_table: + * function and variable tables for class and object creation. ***********************************************************************/ %fragment ("JS_class_tables", "templates") %{ -JSStaticValue ${classname_mangled}_staticValues[] = { - ${jsstaticclassvariables} +JSStaticValue $jsmangledname_staticValues[] = { + $jsstaticclassvariables { 0, 0, 0, 0 } }; -JSStaticFunction ${classname_mangled}_staticFunctions[] = { - ${jsstaticclassfunctions} +JSStaticFunction $jsmangledname_staticFunctions[] = { + $jsstaticclassfunctions { 0, 0, 0 } }; -JSStaticValue ${classname_mangled}_values[] = { - ${jsclassvariables} +JSStaticValue $jsmangledname_values[] = { + $jsclassvariables { 0, 0, 0, 0 } }; -JSStaticFunction ${classname_mangled}_functions[] = { - ${jsclassfunctions} +JSStaticFunction $jsmangledname_functions[] = { + $jsclassfunctions { 0, 0, 0 } }; %} @@ -164,15 +168,14 @@ JSStaticFunction ${classname_mangled}_functions[] = { /********************************************************************* * destructordefn: * This code template is used to adds the destructor wrapper function - * ${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A ***********************************************************************/ %fragment ("JS_destructordefn", "templates") %{ -void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) +void _wrap_$jsmangledname_finalize(JSObjectRef thisObject) { SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); - if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject); + if(t && t->swigCMemOwn) free (($jstype*)t->swigCObject); if(t) free(t); } %} @@ -180,22 +183,21 @@ void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) /********************************************************************* * constructor_definition: * This code template is used to adds the main constructor wrapper function - * ${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A ***********************************************************************/ %fragment ("JS_mainctordefn", "templates") %{ -JSObjectRef _wrap_create_${classname_mangled}(JSContextRef context, JSObjectRef ctorObject, +JSObjectRef _wrap_create_$jsmangledname(JSContextRef context, JSObjectRef ctorObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { JSObjectRef thisObject = NULL; // switch all cases by means of series of if-returns. - ${DISPATCH_CASES} + $jsdispatchcases // default: - SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of ${classname_mangled}"); + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); fail: return thisObject; @@ -207,8 +209,8 @@ 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); +%{if(argc == $jsargcount) { + thisObject = _wrap_create_$jsmangledname$jsoverloadext(context, NULL, argc, argv, exception); if(thisObject != NULL) { *exception=0; return thisObject; } /* reset exception and return */ } %} @@ -216,12 +218,12 @@ ctor_dispatch_case: This template is used for the constructor which is overloade %fragment ("JS_ctordefn", "templates") %{ -JSObjectRef _wrap_create_${classname_mangled}${overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +JSObjectRef _wrap_create_$jsmangledname$jsoverloadext(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { - ${LOCALS} - ${CODE} + $jslocals + $jscode - return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN); + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); goto fail; fail: @@ -237,7 +239,7 @@ initializer:This template is dynamic growing and aggregates everything extern "C" { #endif -bool ${modulename}_initialize(JSGlobalContextRef context) { +bool $jsname_initialize(JSGlobalContextRef context) { SWIG_InitializeModule(0); JSObjectRef global_object = JSContextGetGlobalObject(context); @@ -248,13 +250,13 @@ bool ${modulename}_initialize(JSGlobalContextRef context) { _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); /* Create objects for namespaces */ - ${create_namespaces} + $jscreatenamespaces /* Create classes */ - ${initializercode} + $jsinitializercode /* Register namespaces */ - ${register_namespaces} + $jsregisternamespaces return true; } @@ -268,41 +270,35 @@ bool ${modulename}_initialize(JSGlobalContextRef context) { /***************************************************************************************** *create_class_template: *This template is used to add a Static references to class templates. - *${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A *****************************************************************************************/ %fragment ("JS_create_class_template", "templates") -%{ ${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; - ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; - ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; - ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; - ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; - ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; - JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}_objectDefinition); - SWIGTYPE_${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%} +%{ $jsmangledname_classDefinition.staticFunctions = $jsmangledname_staticFunctions; + $jsmangledname_classDefinition.staticValues = $jsmangledname_staticValues; + $jsmangledname_classDefinition.callAsConstructor = _wrap_create_$jsmangledname; + $jsmangledname_objectDefinition.staticValues = $jsmangledname_values; + $jsmangledname_objectDefinition.staticFunctions = $jsmangledname_functions; + $jsmangledname_objectDefinition.parentClass = $jsbaseclass_classRef; + JSClassRef $jsmangledname_classRef = JSClassCreate(&$jsmangledname_objectDefinition); + SWIGTYPE_$jsmangledtype->clientdata = $jsmangledname_classRef;%} /***************************************************************************************** *register_class: - *This template is used to adds a class registration statement to initializer function - *${classname_mangled}: The mangled name of the qualified class name, e.g., foo::A -> foo_A + * This template is used to adds a class registration statement to initializer function *****************************************************************************************/ %fragment ("JS_register_class", "templates") -%{JS_registerClass(context, ${namespace_mangled}_object, "${classname}", &${classname_mangled}_classDefinition);%} - -/* register global function */ -%fragment ("JS_register_global_function", "templates") -%{JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper});%} +%{JS_registerClass(context, $jsnspace_object, "$jsname", &$jsmangledname_classDefinition);%} /* create and register namespaces */ %fragment ("JS_create_namespace", "templates") -%{ ${namespace}_classDefinition.staticFunctions = ${namespace}_functions; - ${namespace}_classDefinition.staticValues = ${namespace}_values; - JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL); +%{ $jsmangledname_classDefinition.staticFunctions = $jsmangledname_functions; + $jsmangledname_classDefinition.staticValues = $jsmangledname_values; + JSObjectRef $jsmangledname_object = JSObjectMake(context, JSClassCreate(&$jsmangledname_classDefinition), NULL); %} %fragment ("JS_register_namespace", "templates") %{ -JS_registerNamespace(context, ${namespace_mangled}_object, ${parent_namespace}_object, "${namespace}"); %} +JS_registerNamespace(context, $jsmangledname_object, $jsparent_object, "$jsname"); %} diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 72be9b4f0..f4441f0d9 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -13,6 +13,27 @@ bool js_template_enable_debug = false; #define WRAPPER_NAME "wrapper" #define IS_IMMUTABLE "is_immutable" #define IS_STATIC "is_static" +#define GETTER "getter" +#define SETTER "setter" +#define PARENT "parent" + +// variables used in code templates +// ATTENTION: be aware of prefix collisions when defining those variables +#define T_NAME "$jsname" +#define T_NAME_MANGLED "$jsmangledname" +#define T_TYPE "$jstype" +#define T_TYPE_MANGLED "$jsmangledtype" +#define T_WRAPPER "$jswrapper" +#define T_GETTER "$jsgetter" +#define T_SETTER "$jssetter" +#define T_DISPATCH_CASES "$jsdispatchcases" +#define T_BASECLASS "$jsbaseclass" +#define T_NAMESPACE "$jsnspace" +#define T_PARENT "$jsparent" +#define T_OVERLOAD "$jsoverloadext" +#define T_ARGCOUNT "$jsargcount" +#define T_LOCALS "$jslocals" +#define T_CODE "$jscode" /** * A convenience class to manage state variables for emitters. @@ -569,6 +590,8 @@ JSEmitter::~JSEmitter() { /* ----------------------------------------------------------------------------- * JSEmitter::RegisterTemplate() : Registers a code template + * + * Note: this is used only by JAVASCRIPT::fragmentDirective(). * ----------------------------------------------------------------------------- */ int JSEmitter::registerTemplate(const String *name, const String *code) { @@ -576,7 +599,7 @@ int JSEmitter::registerTemplate(const String *name, const String *code) { } /* ----------------------------------------------------------------------------- - * JSEmitter::getTemplate() : Retrieves a registered a code template + * JSEmitter::getTemplate() : Provides a registered code template * ----------------------------------------------------------------------------- */ Template JSEmitter::getTemplate(const String *name) { @@ -624,6 +647,9 @@ Parm *JSEmitter::skipIgnoredArgs(Parm *p) { /* ----------------------------------------------------------------------------- * JSEmitter::getBaseClass() : the node of the base class or NULL + * + * Note: the first base class is provided. Multiple inheritance is not + * supported. * ----------------------------------------------------------------------------- */ Node *JSEmitter::getBaseClass(Node *n) { @@ -640,7 +666,10 @@ Node *JSEmitter::getBaseClass(Node *n) { } /* ----------------------------------------------------------------------------- - * JSEmitter::emitWrapperFunction() : dispatches emitter functions + * JSEmitter::emitWrapperFunction() : dispatches emitter functions. + * + * This allows to have small sized, dedicated emitting functions. + * All state dependent branching is done here. * ----------------------------------------------------------------------------- */ int JSEmitter::emitWrapperFunction(Node *n) { @@ -737,7 +766,7 @@ int JSEmitter::switchNamespace(Node *n) { String *scope = Swig_scopename_prefix(Getattr(n, "name")); if (scope) { // if the scope is not yet registered - // create all scopes/namespaces recursively + // create (parent) namespaces recursively if (!Getattr(namespaces, scope)) { createNamespace(scope); } @@ -774,9 +803,9 @@ int JSEmitter::createNamespace(String *scope) { 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)); + Setattr(entry, NAME, Swig_scopename_last(name)); + Setattr(entry, NAME_MANGLED, Swig_name_mangle(name)); + Setattr(entry, PARENT, NewString(parent)); Delete(name); return entry; @@ -851,8 +880,6 @@ private: // keys for function scoped state variables #define FUNCTION_DISPATCHERS "function_dispatchers" -#define GETTER "getter" -#define SETTER "setter" JSCEmitter::JSCEmitter() : JSEmitter(), @@ -988,10 +1015,10 @@ int JSCEmitter::dump(Node *n) { // compose the initializer function using a template Template initializer(getTemplate("JS_initializer")); - initializer.replace("${modulename}", module) - .replace("${initializercode}", state.global(INITIALIZER)) - .replace("${create_namespaces}", state.global(CREATE_NAMESPACES)) - .replace("${register_namespaces}", state.global(REGISTER_NAMESPACES)) + initializer.replace(T_NAME, module) + .replace("$jsinitializercode", state.global(INITIALIZER)) + .replace("$jscreatenamespaces", state.global(CREATE_NAMESPACES)) + .replace("$jsregisternamespaces", state.global(REGISTER_NAMESPACES)) .pretty_print(f_init); Printv(f_wrap_cpp, f_init, 0); @@ -1046,8 +1073,8 @@ int JSCEmitter::exitFunction(Node *n) { } } - t_function.replace("${functionname}", state.function(NAME)) - .replace("${functionwrapper}", state.function(WRAPPER_NAME)); + t_function.replace(T_NAME, state.function(NAME)) + .replace(T_WRAPPER, state.function(WRAPPER_NAME)); if (is_member) { if (GetFlag(state.function(), IS_STATIC)) { @@ -1074,9 +1101,9 @@ int JSCEmitter::enterVariable(Node *n) { int JSCEmitter::exitVariable(Node *n) { Template t_variable(getTemplate("JS_variabledecl")); - t_variable.replace("${setname}", state.variable(SETTER)) - .replace("${getname}", state.variable(GETTER)) - .replace("${propertyname}", state.variable(NAME)); + t_variable.replace(T_NAME, state.variable(NAME)) + .replace(T_GETTER, state.variable(GETTER)) + .replace(T_SETTER, state.variable(SETTER)); if (GetFlag(n, "ismember")) { if (GetFlag(state.function(), IS_STATIC) @@ -1103,7 +1130,7 @@ int JSCEmitter::enterClass(Node *n) { state.clazz(CTOR_DISPATCHERS, NewString("")); Template t_class_defn = getTemplate("JS_class_definition"); - t_class_defn.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + t_class_defn.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .pretty_print(f_wrappers); return SWIG_OK; @@ -1112,11 +1139,11 @@ int JSCEmitter::enterClass(Node *n) { int JSCEmitter::exitClass(Node *n) { Template t_class_tables(getTemplate("JS_class_tables")); - t_class_tables.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) - .replace("${jsclassvariables}", state.clazz(MEMBER_VARIABLES)) - .replace("${jsclassfunctions}", state.clazz(MEMBER_FUNCTIONS)) - .replace("${jsstaticclassfunctions}", state.clazz(STATIC_FUNCTIONS)) - .replace("${jsstaticclassvariables}", state.clazz(STATIC_VARIABLES)) + t_class_tables.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES)) + .replace("$jsclassfunctions", state.clazz(MEMBER_FUNCTIONS)) + .replace("$jsstaticclassfunctions", state.clazz(STATIC_FUNCTIONS)) + .replace("$jsstaticclassvariables", state.clazz(STATIC_VARIABLES)) .pretty_print(f_wrappers); /* adds the ctor wrappers at this position */ @@ -1125,8 +1152,8 @@ int JSCEmitter::exitClass(Node *n) { /* adds the main constructor wrapper function */ Template t_mainctor(getTemplate("JS_mainctordefn")); - t_mainctor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) - .replace("${DISPATCH_CASES}", state.clazz(CTOR_DISPATCHERS)) + t_mainctor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) .pretty_print(f_wrappers); /* adds a class template statement to initializer function */ @@ -1139,9 +1166,9 @@ int JSCEmitter::exitClass(Node *n) { Delete(base_name_mangled); base_name_mangled = SwigType_manglestr(Getattr(base_class, "name")); } - t_classtemplate.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) - .replace("${classtype_mangled}", state.clazz(TYPE_MANGLED)) - .replace("${base_classname}", base_name_mangled) + t_classtemplate.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) + .replace(T_BASECLASS, base_name_mangled) .pretty_print(state.global(INITIALIZER)); Delete(base_name_mangled); @@ -1150,9 +1177,9 @@ int JSCEmitter::exitClass(Node *n) { /* adds a class registration statement to initializer function */ Template t_registerclass(getTemplate("JS_register_class")); - t_registerclass.replace("${classname}", state.clazz(NAME)) - .replace("${classname_mangled}", state.clazz(NAME_MANGLED)) - .replace("${namespace_mangled}", Getattr(current_namespace, "name_mangled")) + t_registerclass.replace(T_NAME, state.clazz(NAME)) + .replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(T_NAMESPACE, Getattr(current_namespace, NAME_MANGLED)) .pretty_print(state.global(INITIALIZER)); return SWIG_OK; @@ -1180,19 +1207,19 @@ int JSEmitter::emitCtor(Node *n) { marshalInputArgs(n, params, wrapper, Ctor, true, false); Printv(wrapper->code, action, "\n", 0); - t_ctor.replace("${classname_mangled}", mangled_name) - .replace("${overloadext}", overname) - .replace("${LOCALS}", wrapper->locals) - .replace("${CODE}", wrapper->code) - .replace("${type_mangled}", state.clazz(TYPE_MANGLED)) + t_ctor.replace(T_NAME_MANGLED, mangled_name) + .replace(T_OVERLOAD, overname) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) + .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) .pretty_print(state.clazz(CTORS)); String *argcount = NewString(""); Printf(argcount, "%d", num_args); Template t_ctor_case(getTemplate("JS_ctor_dispatch_case")); - t_ctor_case.replace("${classname_mangled}", mangled_name) - .replace("${overloadext}", overname) - .replace("${argcount}", argcount); + t_ctor_case.replace(T_NAME_MANGLED, mangled_name) + .replace(T_OVERLOAD, overname) + .replace(T_ARGCOUNT, argcount); Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); Delete(argcount); @@ -1204,8 +1231,8 @@ int JSEmitter::emitCtor(Node *n) { int JSEmitter::emitDtor(Node *) { Template t_dtor = getTemplate("JS_destructordefn"); - t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) - .replace("${type}", state.clazz(TYPE)) + t_dtor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(T_TYPE, state.clazz(TYPE)) .pretty_print(f_wrappers); return SWIG_OK; @@ -1224,16 +1251,15 @@ int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { ParmList *params = Getattr(n, "parms"); 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, wrapper, Getter, is_member, is_static); marshalOutput(n, action, wrapper); - t_getter.replace("${getname}", wrap_name) - .replace("${LOCALS}", wrapper->locals) - .replace("${CODE}", wrapper->code) + t_getter.replace(T_GETTER, wrap_name) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) .pretty_print(f_wrappers); DelWrapper(wrapper); @@ -1267,9 +1293,9 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); Append(wrapper->code, action); - t_setter.replace("${setname}", wrap_name) - .replace("${LOCALS}", wrapper->locals) - .replace("${CODE}", wrapper->code) + t_setter.replace(T_SETTER, wrap_name) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) .pretty_print(f_wrappers); DelWrapper(wrapper); @@ -1296,9 +1322,6 @@ int JSEmitter::emitConstant(Node *n) { state.variable(GETTER, wrap_name); Setattr(n, "wrap:name", wrap_name); - // prepare local variables - Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); - // prepare code part String *action = NewString(""); String *value = Getattr(n, "rawval"); @@ -1312,9 +1335,9 @@ int JSEmitter::emitConstant(Node *n) { Setattr(n, "wrap:action", action); marshalOutput(n, action, wrapper); - t_getter.replace("${getname}", wrap_name) - .replace("${LOCALS}", wrapper->locals) - .replace("${CODE}", wrapper->code) + t_getter.replace(T_GETTER, wrap_name) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) .pretty_print(f_wrappers); exitVariable(n); @@ -1334,8 +1357,8 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { // 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")); t_function = getTemplate("JS_functionwrapper_overload"); + Append(wrap_name, Getattr(n, "sym:overname")); } Setattr(n, "wrap:name", wrap_name); state.function(WRAPPER_NAME, wrap_name); @@ -1344,16 +1367,15 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { ParmList *params = Getattr(n, "parms"); 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, wrapper, Function, is_member, is_static); marshalOutput(n, action, wrapper); - t_function.replace("${functionname}", wrap_name) - .replace("${LOCALS}", wrapper->locals) - .replace("${CODE}", wrapper->code) + t_function.replace(T_WRAPPER, wrap_name) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) .pretty_print(f_wrappers); // handle function overloading @@ -1364,8 +1386,8 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { String *argcount = NewString(""); Printf(argcount, "%d", argc); - t_dispatch_case.replace("${functionwrapper}", wrap_name) - .replace("${argcount}", argcount); + t_dispatch_case.replace(T_WRAPPER, wrap_name) + .replace(T_ARGCOUNT, argcount); Append(state.global(FUNCTION_DISPATCHERS), t_dispatch_case.str()); @@ -1386,16 +1408,16 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { Setattr(n, "wrap:name", wrap_name); Wrapper_add_local(wrapper, "res", "int res"); - Wrapper_add_local(wrapper, "jsresult", "JSValueRef jsresult"); 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); + t_function.replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code); // call this here, to replace all variables - t_function.replace("${functionname}", wrap_name) + t_function.replace(T_WRAPPER, wrap_name) + .replace(T_NAME, state.function(NAME)) .pretty_print(f_wrappers); // Delete the state variable @@ -1446,27 +1468,27 @@ int JSCEmitter::emitNamespaces() { Iterator it; for (it = First(namespaces); it.item; it = Next(it)) { Hash *entry = it.item; - String *name = Getattr(entry, "name"); - String *parent = Getattr(entry, "parent"); + String *name = Getattr(entry, NAME); + String *name_mangled = Getattr(entry, NAME_MANGLED); + String *parent = Getattr(entry, PARENT); + String *parent_mangled = Swig_name_mangle(parent); String *functions = Getattr(entry, "functions"); String *variables = Getattr(entry, "values"); - String *name_mangled = Getattr(entry, "name_mangled"); - String *parent_mangled = Swig_name_mangle(parent); Template namespace_definition(getTemplate("JS_globaldefn")); - namespace_definition.replace("${jsglobalvariables}", variables) - .replace("${jsglobalfunctions}", functions) - .replace("${namespace}", name_mangled) + namespace_definition.replace("$jsglobalvariables", variables) + .replace("$jsglobalfunctions", functions) + .replace(T_NAMESPACE, name_mangled) .pretty_print(f_wrap_cpp); Template t_createNamespace(getTemplate("JS_create_namespace")); - t_createNamespace.replace("${namespace}", name_mangled); + t_createNamespace.replace(T_NAME_MANGLED, name_mangled); Append(state.global(CREATE_NAMESPACES), t_createNamespace.str()); Template t_registerNamespace(getTemplate("JS_register_namespace")); - t_registerNamespace.replace("${namespace_mangled}", name_mangled) - .replace("${namespace}", name) - .replace("${parent_namespace}", parent_mangled); + t_registerNamespace.replace(T_NAME_MANGLED, name_mangled) + .replace(T_NAME, name) + .replace(T_PARENT, parent_mangled); Append(state.global(REGISTER_NAMESPACES), t_registerNamespace.str()); } @@ -1575,8 +1597,8 @@ private: #define KW_REGISTER_CLASSES "${PART_REGISTER_CLASSES}" #define KW_REGISTER_NS "${PART_REGISTER_NS}" -#define KW_LOCALS "${LOCALS}" -#define KW_CODE "${CODE}" +#define KW_LOCALS T_LOCALS +#define KW_CODE T_CODE V8Emitter::V8Emitter() : JSEmitter(), From 78442b27647e2a3d7e45516c709632f8419b7fd6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:05:37 +0000 Subject: [PATCH 054/352] Several adaptations and fixes on the way to get V8 emitter running. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13788 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 192 +++++++++++--------- Lib/javascript/v8/javascripthelpers.swg | 8 +- Lib/javascript/v8/javascriptprimitives.swg | 2 +- Lib/javascript/v8/javascriptruntime.swg | 12 +- Lib/javascript/v8/javascriptstrings.swg | 0 Source/Modules/javascript.cxx | 201 +++++++++------------ 6 files changed, 209 insertions(+), 206 deletions(-) create mode 100644 Lib/javascript/v8/javascriptstrings.swg diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index e5a1f1eba..59b071c89 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -1,101 +1,131 @@ -%fragment("v8_initializer", "templates") %{ -void ${MODULE}_Initialize(v8::Handle context) +%fragment("JS_ctordefn", "templates") %{ +v8::Handle $jsmangledname_new(const v8::Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + $jslocals + $jscode + self->SetInternalField(0, v8::External::New(result)); + return scope.Close(self); + goto fail; +fail: + return scope.Close(v8::Undefined); +}%} + +%fragment("JS_getproperty", "templates") %{ +v8::Handle $jsgetter(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle jsresult; + $jslocals + $jscode + return scope.Close(jsresult); + goto fail; +fail: + return scope.Close(v8::Undefined()); +}%} + +%fragment("JS_setproperty", "templates") %{ +void $jssetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + $jslocals + $jscode + goto fail; +fail: + return; +}%} + +%fragment("JS_functionwrapper", "templates") %{ +v8::Handle $jswrapper(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle jsresult; + $jslocals + $jscode + return scope.Close(jsresult); + goto fail; +fail: + return scope.Close(v8::Undefined()); +}%} + +// TODO: implement ctor overloading properly! +%fragment ("JS_mainctordefn", "templates") +%{ + // TODO: implement JS_mainctordefn +%} + +%fragment ("JS_ctor_dispatch_case", "templates") +%{ + // TODO: implement JS_ctor_dispatch_case +%} + +%fragment ("JS_destructordefn", "templates") +%{ + // TODO: implement JS_destructordefn +%} + +%fragment("jsv8_declare_class_template", "templates") %{ +v8::Persistent SWIGV8_$jsmangledname;%} + +%fragment("jsv8_define_class_template", "templates") %{ +SWIGV8_$jsmangledname = SWIGV8_CreateClassTemplate("$jsname" , $jsmangledname_new);%} + +%fragment("jsv8_create_class_instance", "templates") %{ +v8::Handle class_$jsmangledname = SWIGV8_$jsmangledname->GetFunction();%} + +%fragment("jsv8_inherit", "templates") %{ +SWIGV8_$jsmangledname->Inherit(SWIGV8_$jsbaseclass);%} + +%fragment("jsv8_register_class", "templates") %{ +$jsparent->Set(v8::String::NewSymbol("$jsname"), class_$jsmangledname);%} + +%fragment("jsv8_create_namespace", "templates") %{ +v8::Handle $jsmangledname = v8::ObjectTemplate::New();%} + +%fragment("jsv8_register_member_function", "templates") %{ +SWIGV8_AddMemberFunction(SWIGV8_$jsmangledname, "$jsname", $jswrapper);%} + +%fragment("jsv8_register_static_function", "templates") %{ +SWIGV8_AddGlobalFunction($jsparent, "$jsname", $jswrapper);%} + +%fragment("jsv8_register_member_variable", "templates") %{ +SWIGV8_AddMemberVariable(SWIGV8_$jsmangledname, "$jsname", $jsgetter, $jssetter);%} + +%fragment("jsv8_register_static_variable", "templates") %{ +SWIGV8_AddGlobalVariable($jsparent, "$jsname", $jsgetter, $jssetter);%} + +%fragment("jsv8_register_namespace", "templates") %{ +$jsparent->Set(v8::String::NewSymbol("$jsname", $jsmangledname->NewInstance()));%} + +%fragment("JS_initializer", "templates") %{ + +extern "C" { + +void $jsname_initialize(v8::Handle context) { v8::HandleScope scope; v8::Local global = context->Global(); /* create object templates for namespaces */ - ${PART_NAMESPACES} + $jsv8nspaces /* create class templates */ - ${PART_CLASS_TEMPLATES} + $jsv8classtemplates /* register wrapper functions */ - ${PART_WRAPPERS} + $jsv8wrappers /* setup inheritances */ - ${PART_INHERITANCE} + $jsv8inheritance /* class instances */ - ${PART_CLASS_INSTANCES} + $jsv8classinstances /* add static class functions and variables */ - ${PART_STATIC_WRAPPERS} + $jsv8staticwrappers /* register classes */ - ${PART_REGISTER_CLASSES} + $jsv8registerclasses /* create and register namespace objects */ - ${PART_REGISTER_NS} + $jsv8registernspaces +} + }%} - -%fragment("v8_declare_class_template", "templates") %{ -v8::Persistent SWIGV8_${NAME_MANGLED};%} - -%fragment("v8_define_class_template", "templates") %{ -SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new);%} - -%fragment("v8_create_class_instance", "templates") %{ -v8::Handle class_${NAME_MANGLED} = SWIGV8_${NAME_MANGLED}->GetFunction();%} - -%fragment("v8_inherit", "templates") %{ -SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS});%} - -%fragment("v8_register_class", "templates") %{ -${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), class_${NAME_MANGLED});%} - -%fragment("v8_ctor_wrapper", "templates") %{ -v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { - v8::HandleScope scope; - v8::Handle self = args.Holder(); - ${LOCALS} - ${CODE} - self->SetInternalField(0, v8::External::New(result)); - return self; -}%} - -%fragment("v8_getter", "templates") %{ -v8::Handle ${NAME_MANGLED}_get(v8::Local property, const v8::AccessorInfo& info) { - v8::HandleScope scope; - v8::Handle jsresult; - ${LOCALS} - ${CODE} - return scope.Close(jsresult); -}%} - -%fragment("v8_setter", "templates") %{ -void ${NAME_MANGLED}_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - ${LOCALS} - ${CODE} -}%} - -%fragment("v8_function", "templates") %{ -v8::Handle wrap_${NAME_MANGLED}(const Arguments &args) { - v8::HandleScope scope; - v8::Handle jsresult; - ${LOCALS} - ${CODE} - return scope.Close(jsresult); -}%} - -%fragment("v8_create_namespace", "templates") %{ -v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New();%} - -%fragment("v8_register_member_function", "templates") %{ -SWIGV8_AddMemberFunction(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} - -%fragment("v8_register_global_function", "templates") %{ -SWIGV8_AddGlobalFunction(${CONTEXT}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED});%} - -%fragment("v8_register_member_variable", "templates") %{ -SWIGV8_AddMemberVariable(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER});%} - -%fragment("v8_register_global_variable", "templates") %{ -SWIGV8_AddGlobalVariable(${CONTEXT}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER});%} - -%fragment("v8_register_namespace", "templates") %{ -${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance()));%} - -%fragment("v8_this_ptr", "templates") %{ -arg1 = SWIGV8_UnwrapThisPointer<${TYPE}>(${ARG}.Holder()); -%} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index b5b462b96..1159f7ef3 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -13,10 +13,6 @@ v8::Persistent SWIGV8_CreateClassTemplate(const char* symb return v8::Persistent::New(class_templ); } -v8::Handle SWIGV8_CreateNamespace(const char* name, v8::Handle parentContext) { - Handle namespace = ObjectTemplate::New(); -} - /** * Registers a class method with given name for a given class template. */ @@ -29,7 +25,7 @@ void SWIGV8_AddMemberFunction(v8::Handle class_templ, cons * Registers a class method with given name for a given class template. */ void SWIGV8_AddGlobalFunction(v8::Handle obj_templ, const char* symbol, v8::InvocationCallback _func) { - obj_templ->Set(String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); + obj_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); } /** @@ -44,6 +40,6 @@ void SWIGV8_AddMemberVariable(v8::Handle class_templ, cons * Registers a class method with given name for a given class template. */ void SWIGV8_AddGlobalVariable(v8::Handle obj_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { - obj_templ->SetAccessor(String::NewSymbol(symbol), getter, setter); + obj_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } %} // v8_helper_functions diff --git a/Lib/javascript/v8/javascriptprimitives.swg b/Lib/javascript/v8/javascriptprimitives.swg index 09e1ae9f9..d3dba485d 100644 --- a/Lib/javascript/v8/javascriptprimitives.swg +++ b/Lib/javascript/v8/javascriptprimitives.swg @@ -42,7 +42,7 @@ v8::Handle SWIG_From_dec(long)(long value) SWIGINTERN int SWIG_AsVal_dec(long)(v8::Handle obj, long* val) { - if (!obj->IsInteger()) { + if (!obj->IsNumber()) { return SWIG_TypeError; } if(val) *val = (long) obj->IntegerValue(); diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 4440fa6d6..15d8a35fc 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -6,6 +6,8 @@ %insert(runtime) %{ #include +#include +#include %} %insert(runtime) "swigrun.swg"; /* SWIG API */ @@ -39,12 +41,12 @@ void SWIG_V8_exception(int code, const char* msg) { %insert(runtime) %{ -int SWIG_JSC_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { +int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { if(objRef->InternalFieldCount() < 1) { return SWIG_ERROR; } - Handle cdataRef = objRef->GetInternalField(0); + v8::Handle cdataRef = objRef->GetInternalField(0); SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) v8::External::Unwrap(cdataRef); if(cdata == NULL) { @@ -80,14 +82,14 @@ int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info return SWIG_TypeError; } - v8::Handle objRef = valRef->ToObject(); + v8::Handle objRef = valRef->ToObject(); - return SWIG_V8_ConvertInstancePtr(context, objRef, ptr, info, flags); + return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags); } v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { // TODO: wrap ptr into an v8 object - return 0; + return v8::Undefined(); } #define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_V8_ConvertPtr(obj, ptr, info, flags) diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg new file mode 100644 index 000000000..e69de29bb diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index f4441f0d9..c6e48997c 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -16,6 +16,8 @@ bool js_template_enable_debug = false; #define GETTER "getter" #define SETTER "setter" #define PARENT "parent" +#define CTORS "ctors" +#define CTOR_DISPATCHERS "ctor_dispatchers" // variables used in code templates // ATTENTION: be aware of prefix collisions when defining those variables @@ -35,6 +37,16 @@ bool js_template_enable_debug = false; #define T_LOCALS "$jslocals" #define T_CODE "$jscode" +// v8 specific variables used in templates +#define V8_NAME_SPACES "$jsv8nspaces" +#define V8_CLASS_TEMPLATES "$jsv8classtemplates" +#define V8_WRAPPERS "$jsv8wrappers" +#define V8_INHERITANCE "$jsv8inheritance" +#define V8_CLASS_INSTANCES "$jsv8classinstances" +#define V8_STATIC_WRAPPERS "$jsv8staticwrappers" +#define V8_REGISTER_CLASSES "$jsv8registerclasses" +#define V8_REGISTER_NS "$jsv8registernspaces" + /** * A convenience class to manage state variables for emitters. * The implementation delegates to swig Hash DOHs and provides @@ -725,6 +737,9 @@ int JSEmitter::enterClass(Node *n) { Delete(type); state.clazz(TYPE_MANGLED, classtype_mangled); + state.clazz(CTORS, NewString("")); + state.clazz(CTOR_DISPATCHERS, NewString("")); + return SWIG_OK; } @@ -875,8 +890,6 @@ private: #define MEMBER_FUNCTIONS "member_functions" #define STATIC_FUNCTIONS "static_functions" #define STATIC_VARIABLES "static_variables" -#define CTORS "ctors" -#define CTOR_DISPATCHERS "ctor_dispatchers" // keys for function scoped state variables #define FUNCTION_DISPATCHERS "function_dispatchers" @@ -1126,8 +1139,6 @@ int JSCEmitter::enterClass(Node *n) { state.clazz(MEMBER_FUNCTIONS, NewString("")); state.clazz(STATIC_VARIABLES, NewString("")); state.clazz(STATIC_FUNCTIONS, NewString("")); - state.clazz(CTORS, NewString("")); - state.clazz(CTOR_DISPATCHERS, NewString("")); Template t_class_defn = getTemplate("JS_class_definition"); t_class_defn.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) @@ -1536,7 +1547,6 @@ private: File *f_runtime; File *f_header; File *f_class_templates; - File *f_wrapper; File *f_init; File *f_init_namespaces; @@ -1555,51 +1565,6 @@ private: String* NULL_STR; }; -// name of templates -#define V8_INITIALIZER "v8_initializer" -#define V8_DECL_CLASSTEMPLATE "v8_declare_class_template" -#define V8_DEFINE_CLASSTEMPLATE "v8_define_class_template" -#define V8_CREATE_CLASS_INSTANCE "v8_create_class_instance" -#define V8_INHERIT "v8_inherit" -#define V8_REGISTER_CLASS "v8_register_class" -#define V8_CTOR_WRAPPER "v8_ctor_wrapper" -#define V8_GETTER "v8_getter" -#define V8_SETTER "v8_setter" -#define V8_FUNCTION "v8_function" -#define V8_RETRIEVE_THIS "v8_retrieve_this" -#define V8_REGISTER_MEMBER_FUNCTION "v8_register_member_function" -#define V8_REGISTER_GLOBAL_FUNCTION "v8_register_global_function" -#define V8_REGISTER_MEMBER_VARIABLE "v8_register_member_variable" -#define V8_REGISTER_GLOBAL_VARIABLE "v8_register_global_variable" -#define V8_CREATE_NAMESPACE "v8_create_namespace" -#define V8_REGISTER_NAMESPACE "v8_register_namespace" -#define V8_THIS_PTR "v8_this_ptr" - -// keywords used in templates -#define KW_MODULE_NAME "${MODULE}" -#define KW_MANGLED_NAME "${NAME_MANGLED}" -#define KW_UNQUALIFIED_NAME "${NAME_UNQUALIFIED}" -#define KW_CLASSNAME_MANGLED "${CLASSNAME_MANGLED}" -#define KW_BASE_CLASS "${BASE_CLASS}" -#define KW_CONTEXT "${CONTEXT}" -#define KW_TYPE "${TYPE}" -#define KW_ARG "${ARG}" -#define KW_WRAPPER "${WRAPPER}" -#define KW_GETTER "${GETTER}" -#define KW_SETTER "${SETTER}" - -#define KW_NAME_SPACES "${PART_NAMESPACES}" -#define KW_CLASS_TEMPLATES "${PART_CLASS_TEMPLATES}" -#define KW_WRAPPERS "${PART_WRAPPERS}" -#define KW_INHERITANCE "${PART_INHERITANCE}" -#define KW_CLASS_INSTANCES "${PART_CLASS_INSTANCES}" -#define KW_STATIC_WRAPPERS "${PART_STATIC_WRAPPERS}" -#define KW_REGISTER_CLASSES "${PART_REGISTER_CLASSES}" -#define KW_REGISTER_NS "${PART_REGISTER_NS}" - -#define KW_LOCALS T_LOCALS -#define KW_CODE T_CODE - V8Emitter::V8Emitter() : JSEmitter(), GLOBAL(NewString("global")), @@ -1628,7 +1593,6 @@ int V8Emitter::initialize(Node *n) f_runtime = NewString(""); f_header = NewString(""); f_class_templates = NewString(""); - f_wrapper = NewString(""); f_init = NewString(""); f_init_namespaces = NewString(""); @@ -1644,7 +1608,6 @@ int V8Emitter::initialize(Node *n) 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; } @@ -1657,23 +1620,27 @@ int V8Emitter::dump(Node *n) // write the swig banner Swig_banner(f_wrap_cpp); + SwigType_emit_type_table(f_runtime, f_wrappers); + 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_wrappers, "\n", 0); + + emitNamespaces(); // 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) + Template initializer(getTemplate("JS_initializer")); + initializer.replace(T_NAME, module) + .replace(V8_NAME_SPACES, f_init_namespaces) + .replace(V8_CLASS_TEMPLATES, f_init_class_templates) + .replace(V8_WRAPPERS, f_init_wrappers) + .replace(V8_INHERITANCE, f_init_inheritance) + .replace(V8_CLASS_INSTANCES, f_init_class_instances) + .replace(V8_STATIC_WRAPPERS, f_init_static_wrappers) + .replace(V8_REGISTER_CLASSES, f_init_register_classes) + .replace(V8_REGISTER_NS, f_init_register_namespaces) .pretty_print(f_wrap_cpp); return SWIG_OK; @@ -1685,7 +1652,6 @@ int V8Emitter::close() 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); @@ -1707,18 +1673,18 @@ int V8Emitter::enterClass(Node *n) JSEmitter::enterClass(n); // 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)) + Template t_decl_class(getTemplate("jsv8_declare_class_template")); + t_decl_class.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .pretty_print(f_class_templates); // 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)) + 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)) .pretty_print(f_init_class_templates); - Template t_class_instance(getTemplate(V8_CREATE_CLASS_INSTANCE)); - t_class_instance.replace(KW_MANGLED_NAME, state.clazz(NAME_MANGLED)) + Template t_class_instance(getTemplate("jsv8_create_class_instance")); + t_class_instance.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .pretty_print(f_init_class_instances); return SWIG_OK; @@ -1729,19 +1695,19 @@ int V8Emitter::exitClass(Node *n) // emit inheritance setup Node* baseClass = getBaseClass(n); if(baseClass) { - Template t_inherit(getTemplate(V8_INHERIT)); + Template t_inherit(getTemplate("jsv8_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) + t_inherit.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(T_BASECLASS, 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")) + 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")) .pretty_print(f_init_register_classes); return SWIG_OK; @@ -1761,29 +1727,31 @@ int V8Emitter::exitVariable(Node* n) { if(GetFlag(n, "ismember")) { if(GetFlag(state.variable(), IS_STATIC)) { - Template t_register(getTemplate(V8_REGISTER_GLOBAL_VARIABLE)); + Template t_register(getTemplate("jsv8_register_static_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)) + t_register.replace(T_PARENT, class_instance) + .replace(T_NAME, state.variable(NAME)) + .replace(T_GETTER, state.variable(GETTER)) + .replace(T_SETTER, state.variable(SETTER)) .pretty_print(f_init_static_wrappers); Delete(class_instance); } else { - 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)) + Template t_register(getTemplate("jsv8_register_member_variable")); + t_register.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(T_NAME, state.clazz(NAME)) + .replace(T_GETTER, state.variable(GETTER)) + .replace(T_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)) + // 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")); + 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)) .pretty_print(f_init_wrappers); } @@ -1802,26 +1770,28 @@ int V8Emitter::exitFunction(Node* n) // 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)); + Template t_register(getTemplate("jsv8_register_static_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")); + t_register.replace(T_PARENT, class_instance) + .replace(T_NAME, state.function(NAME)) + .replace(T_WRAPPER, 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, state.clazz(NAME_MANGLED)) - .replace(KW_UNQUALIFIED_NAME, state.function(NAME)) - .replace(KW_MANGLED_NAME, Getattr(n, "wrap:name")); + Template t_register(getTemplate("jsv8_register_member_function")); + t_register.replace(T_PARENT, state.clazz(NAME_MANGLED)) + .replace(T_NAME, state.function(NAME)) + .replace(T_WRAPPER, Getattr(n, "wrap:name")); Printv(f_init_wrappers, t_register.str(), "\n", 0); } } 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")); + // 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")); + t_register.replace(T_PARENT, Getattr(current_namespace, "name")) + .replace(T_NAME, state.function(NAME)) + .replace(T_WRAPPER, Getattr(n, "wrap:name")); Printv(f_init_wrappers, t_register.str(), 0); } @@ -1844,17 +1814,22 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar switch (mode) { case Getter: - case Function: if (is_member && !is_static && i == 0) { - Printv(arg, "args[0]", 0); + Printv(arg, "info.Holder()", 0); + } else { + Printf(arg, "args[%d]", i - startIdx); + } + break; + case Function: + if (is_member && !is_static && i == 0) { + Printv(arg, "args.Holder()", 0); } else { Printf(arg, "args[%d]", i - startIdx); } - break; case Setter: if (is_member && !is_static && i == 0) { - Printv(arg, "args[0]", 0); + Printv(arg, "value", 0); } else { Printv(arg, "value", 0); } @@ -1891,12 +1866,12 @@ int V8Emitter::emitNamespaces() { /* // 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); + t_create_ns.Replace(V8_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); + t_register_ns.Replace(V8_MANGLED_NAME, scope_mangled) + .Replace(V8_CONTEXT, parent_scope_mangled) + .Replace(V8_UNQUALIFIED_NAME, scope_unqualified); Printv(f_init_namespaces, t_create_ns.str(), 0); // prepend in order to achieve reversed order of registration statements From 72002392770b42c3c1a15a4167426635bf9128db Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:05:51 +0000 Subject: [PATCH 055/352] Fix regression in javascript's test-suite configuration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13789 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/javascript/Makefile.in | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index a8e1759f7..22a3a8a3e 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -3,8 +3,6 @@ ####################################################################### LANGUAGE = javascript -JAVASCRIPT_EXE = ../../../Tools/javascript/javascript -JAVASCRIPT_EXE_SRC = ../../../Tools/javascript/javascript.cxx SCRIPTSUFFIX = _runme.js srcdir = @srcdir@ top_srcdir = @top_srcdir@ @@ -12,6 +10,7 @@ top_builddir = @top_builddir@ JS_INCLUDE = @JSCOREINC@ JS_DLNK = @JSCOREDYNAMICLINKING@ JSCXXFLAGS = @JSCXXFLAGS@ +JAVASCRIPT_EXE = $(top_srcdir)/Tools/javascript/javascript C_TEST_CASES = \ preproc \ @@ -62,7 +61,7 @@ include $(srcdir)/../common.mk # Custom tests - tests with additional commandline options javascript_exe: - $(CXX) $(JSCXXFLAGS) $(JS_INCLUDE) $(JAVASCRIPT_EXE_SRC) $(LIBS) $(JS_DLNK) -o $(JAVASCRIPT_EXE) + $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TOP='$(top_builddir)/$(EXAMPLES)' javascript_exe # Rules for the different types of tests %.cpptest: javascript_exe From d5c5f7ebeebeef78bb847dea31bda75e65d5d197 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:06:08 +0000 Subject: [PATCH 056/352] Generalize ctor overloading. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13790 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptcode.swg | 18 ++++-- Source/Modules/javascript.cxx | 87 ++++++++++++++++----------- 2 files changed, 65 insertions(+), 40 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 194181125..68b72e7b8 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -188,7 +188,7 @@ void _wrap_$jsmangledname_finalize(JSObjectRef thisObject) %fragment ("JS_mainctordefn", "templates") %{ -JSObjectRef _wrap_create_$jsmangledname(JSContextRef context, JSObjectRef ctorObject, +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { JSObjectRef thisObject = NULL; @@ -204,13 +204,23 @@ JSObjectRef _wrap_create_$jsmangledname(JSContextRef context, JSObjectRef ctorOb } %} +%fragment ("JS_veto_ctor", "templates") +%{ +JSObjectRef $jsctor(JSContextRef context, JSObjectRef ctorObject, + size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); + return 0; +} +%} + /************************************************************************************** ctor_dispatch_case: This template is used for the constructor which is overloaded ***************************************************************************************/ %fragment ("JS_ctor_dispatch_case", "templates") %{if(argc == $jsargcount) { - thisObject = _wrap_create_$jsmangledname$jsoverloadext(context, NULL, argc, argv, exception); + thisObject = $jswrapper(context, NULL, argc, argv, exception); if(thisObject != NULL) { *exception=0; return thisObject; } /* reset exception and return */ } %} @@ -218,7 +228,7 @@ ctor_dispatch_case: This template is used for the constructor which is overloade %fragment ("JS_ctordefn", "templates") %{ -JSObjectRef _wrap_create_$jsmangledname$jsoverloadext(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { $jslocals $jscode @@ -275,7 +285,7 @@ bool $jsname_initialize(JSGlobalContextRef context) { %fragment ("JS_create_class_template", "templates") %{ $jsmangledname_classDefinition.staticFunctions = $jsmangledname_staticFunctions; $jsmangledname_classDefinition.staticValues = $jsmangledname_staticValues; - $jsmangledname_classDefinition.callAsConstructor = _wrap_create_$jsmangledname; + $jsmangledname_classDefinition.callAsConstructor = $jsctor; $jsmangledname_objectDefinition.staticValues = $jsmangledname_values; $jsmangledname_objectDefinition.staticFunctions = $jsmangledname_functions; $jsmangledname_objectDefinition.parentClass = $jsbaseclass_classRef; diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index c6e48997c..bab7d8b88 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -13,11 +13,14 @@ bool js_template_enable_debug = false; #define WRAPPER_NAME "wrapper" #define IS_IMMUTABLE "is_immutable" #define IS_STATIC "is_static" +#define IS_ABSTRACT "is_abstract" #define GETTER "getter" #define SETTER "setter" #define PARENT "parent" -#define CTORS "ctors" +#define CTOR "ctor" +#define CTOR_WRAPPERS "ctor_wrappers" #define CTOR_DISPATCHERS "ctor_dispatchers" +#define ARGCOUNT "wrap:argc" // variables used in code templates // ATTENTION: be aware of prefix collisions when defining those variables @@ -26,6 +29,7 @@ bool js_template_enable_debug = false; #define T_TYPE "$jstype" #define T_TYPE_MANGLED "$jsmangledtype" #define T_WRAPPER "$jswrapper" +#define T_CTOR "$jsctor" #define T_GETTER "$jsgetter" #define T_SETTER "$jssetter" #define T_DISPATCH_CASES "$jsdispatchcases" @@ -737,9 +741,15 @@ int JSEmitter::enterClass(Node *n) { Delete(type); state.clazz(TYPE_MANGLED, classtype_mangled); - state.clazz(CTORS, NewString("")); + String *ctor_wrapper = NewString("_wrap_new_veto_"); + Append(ctor_wrapper, state.clazz(NAME)); + state.clazz(CTOR, ctor_wrapper); state.clazz(CTOR_DISPATCHERS, NewString("")); + // HACK: assume that a class is abstract + // this is resolved by emitCtor (which is only called for non abstract classes) + SetFlag(state.clazz(), IS_ABSTRACT); + return SWIG_OK; } @@ -924,6 +934,11 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma String *tm; Parm *p; + int num_args = emit_num_arguments(parms); + String *argcount = NewString(""); + Printf(argcount, "%d", num_args); + Setattr(n, ARGCOUNT, argcount); + int startIdx = 0; if (is_member && !is_static) { startIdx = 1; @@ -1104,10 +1119,8 @@ int JSCEmitter::exitFunction(Node *n) { int JSCEmitter::enterVariable(Node *n) { JSEmitter::enterVariable(n); - state.variable(GETTER, NULL_STR); state.variable(SETTER, VETO_SET); - return SWIG_OK; } @@ -1134,7 +1147,6 @@ int JSCEmitter::exitVariable(Node *n) { int JSCEmitter::enterClass(Node *n) { JSEmitter::enterClass(n); - state.clazz(MEMBER_VARIABLES, NewString("")); state.clazz(MEMBER_FUNCTIONS, NewString("")); state.clazz(STATIC_VARIABLES, NewString("")); @@ -1148,7 +1160,6 @@ int JSCEmitter::enterClass(Node *n) { } int JSCEmitter::exitClass(Node *n) { - Template t_class_tables(getTemplate("JS_class_tables")); t_class_tables.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES)) @@ -1159,13 +1170,15 @@ int JSCEmitter::exitClass(Node *n) { /* adds the ctor wrappers at this position */ // Note: this is necessary to avoid extra forward declarations. - Append(f_wrappers, state.clazz(CTORS)); + //Append(f_wrappers, state.clazz(CTOR_WRAPPERS)); - /* adds the main constructor wrapper function */ - Template t_mainctor(getTemplate("JS_mainctordefn")); - t_mainctor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) + // for abstract classes add a vetoing ctor + if(GetFlag(state.clazz(), IS_ABSTRACT)) { + Template t_veto_ctor(getTemplate("JS_veto_ctor")); + t_veto_ctor.replace(T_CTOR, state.clazz(CTOR)) + .replace(T_NAME, state.clazz(NAME)) .pretty_print(f_wrappers); + } /* adds a class template statement to initializer function */ Template t_classtemplate(getTemplate("JS_create_class_template")); @@ -1180,6 +1193,7 @@ int JSCEmitter::exitClass(Node *n) { t_classtemplate.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) .replace(T_BASECLASS, base_name_mangled) + .replace(T_CTOR, state.clazz(CTOR)) .pretty_print(state.global(INITIALIZER)); Delete(base_name_mangled); @@ -1197,15 +1211,18 @@ int JSCEmitter::exitClass(Node *n) { } int JSEmitter::emitCtor(Node *n) { - + Wrapper *wrapper = NewWrapper(); - + Template t_ctor(getTemplate("JS_ctordefn")); - String *mangled_name = SwigType_manglestr(Getattr(n, "name")); - String *overname = Getattr(n, "sym:overname"); - String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); + //String *mangled_name = SwigType_manglestr(Getattr(n, "name")); + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Append(wrap_name, Getattr(n, "sym:overname")); Setattr(n, "wrap:name", wrap_name); + // note: removing the is_abstract flag, as this emitter + // is supposed to be called for non-abstract classes only. + Setattr(state.clazz(), IS_ABSTRACT, 0); ParmList *params = Getattr(n, "parms"); emit_parameter_variables(params, wrapper); @@ -1213,29 +1230,35 @@ int JSEmitter::emitCtor(Node *n) { 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, wrapper, Ctor, true, false); Printv(wrapper->code, action, "\n", 0); - t_ctor.replace(T_NAME_MANGLED, mangled_name) - .replace(T_OVERLOAD, overname) + t_ctor.replace(T_WRAPPER, wrap_name) + .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) - .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) - .pretty_print(state.clazz(CTORS)); + .pretty_print(f_wrappers); - String *argcount = NewString(""); - Printf(argcount, "%d", num_args); Template t_ctor_case(getTemplate("JS_ctor_dispatch_case")); - t_ctor_case.replace(T_NAME_MANGLED, mangled_name) - .replace(T_OVERLOAD, overname) - .replace(T_ARGCOUNT, argcount); + t_ctor_case.replace(T_WRAPPER, wrap_name) + .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); - Delete(argcount); DelWrapper(wrapper); + // create a dispatching ctor (if necessary) + if (!Getattr(n, "sym:nextSibling")) { + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Template t_mainctor(getTemplate("JS_mainctordefn")); + t_mainctor.replace(T_WRAPPER, wrap_name) + .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) + .pretty_print(f_wrappers); + state.clazz(CTOR, wrap_name); + } else { + state.clazz(CTOR, wrap_name); + } + return SWIG_OK; } @@ -1392,17 +1415,9 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { // handle function overloading if (is_overloaded) { Template t_dispatch_case = getTemplate("JS_function_dispatch_case"); - - int argc = emit_num_arguments(params); - String *argcount = NewString(""); - Printf(argcount, "%d", argc); - t_dispatch_case.replace(T_WRAPPER, wrap_name) - .replace(T_ARGCOUNT, argcount); - + .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); Append(state.global(FUNCTION_DISPATCHERS), t_dispatch_case.str()); - - Delete(argcount); } DelWrapper(wrapper); From 9b0c8dae839def6e83b447230923630e819b64b4 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:06:26 +0000 Subject: [PATCH 057/352] Add argcount checking to functions and ctors. Before argument counts were only checked for overloaded functions/ctors. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13791 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptcode.swg | 8 +++++ Source/Modules/javascript.cxx | 43 +++++++++++++++++---------- 2 files changed, 35 insertions(+), 16 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 68b72e7b8..7f425c44a 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -52,6 +52,8 @@ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef th { $jslocals JSValueRef jsresult; + + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode return jsresult; @@ -68,6 +70,8 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec { $jslocals JSValueRef jsresult; + + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode *result = jsresult; @@ -231,6 +235,9 @@ ctor_dispatch_case: This template is used for the constructor which is overloade JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { $jslocals + + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + $jscode return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); @@ -240,6 +247,7 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc return NULL; } %} + /********************************************************************** initializer:This template is dynamic growing and aggregates everything **********************************************************************/ diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index bab7d8b88..de43af246 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -934,16 +934,20 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma String *tm; Parm *p; - int num_args = emit_num_arguments(parms); + // determine an offset index, as members have an extra 'this' argument + // except: static members and ctors. + int startIdx = 0; + if (is_member && !is_static && mode!=Ctor) { + 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 startIdx = 0; - if (is_member && !is_static) { - startIdx = 1; - } - + // process arguments int i = 0; for (p = parms; p; p = nextSibling(p), i++) { SwigType *pt = Getattr(p, "type"); @@ -957,7 +961,6 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma } else { Printf(arg, "argv[%d]", i - startIdx); } - break; case Setter: if (is_member && !is_static && i == 0) { @@ -1213,12 +1216,16 @@ int JSCEmitter::exitClass(Node *n) { int JSEmitter::emitCtor(Node *n) { Wrapper *wrapper = NewWrapper(); + + bool is_overloaded = GetFlag(n, "sym:overloaded"); Template t_ctor(getTemplate("JS_ctordefn")); //String *mangled_name = SwigType_manglestr(Getattr(n, "name")); String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Append(wrap_name, Getattr(n, "sym:overname")); + if(is_overloaded) { + Append(wrap_name, Getattr(n, "sym:overname")); + } Setattr(n, "wrap:name", wrap_name); // note: removing the is_abstract flag, as this emitter // is supposed to be called for non-abstract classes only. @@ -1238,6 +1245,7 @@ int JSEmitter::emitCtor(Node *n) { .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) + .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) .pretty_print(f_wrappers); Template t_ctor_case(getTemplate("JS_ctor_dispatch_case")); @@ -1247,14 +1255,16 @@ int JSEmitter::emitCtor(Node *n) { DelWrapper(wrapper); - // create a dispatching ctor (if necessary) - if (!Getattr(n, "sym:nextSibling")) { - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Template t_mainctor(getTemplate("JS_mainctordefn")); - t_mainctor.replace(T_WRAPPER, wrap_name) - .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) - .pretty_print(f_wrappers); - state.clazz(CTOR, wrap_name); + // create a dispatching ctor + if(is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Template t_mainctor(getTemplate("JS_mainctordefn")); + t_mainctor.replace(T_WRAPPER, wrap_name) + .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) + .pretty_print(f_wrappers); + state.clazz(CTOR, wrap_name); + } } else { state.clazz(CTOR, wrap_name); } @@ -1410,6 +1420,7 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { t_function.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) + .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) .pretty_print(f_wrappers); // handle function overloading From 0cae8fccd0cfdbcc6dc426c75102ac8a08430b5d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:06:39 +0000 Subject: [PATCH 058/352] Minor refactor of marshalInputArgs for generalization. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13792 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 71 ++++++++++++++++------------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index de43af246..3ccc9ffa4 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -261,6 +261,8 @@ protected: 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 @@ JSCEmitter::~JSCEmitter() { * --------------------------------------------------------------------- */ 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 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma // 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 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma 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 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { 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 @@ int V8Emitter::exitFunction(Node* n) } 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 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar 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 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar 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); } } From cda09239ad4b7f5367ea3382e4497cc8d830338b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:06:58 +0000 Subject: [PATCH 059/352] Several fixes in v8 emitter and code templates. Achieves first compile of example "class" after re-integration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13793 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 71 ++++++++++++---------- Lib/javascript/v8/javascripthelpers.swg | 11 ++-- Lib/javascript/v8/javascriptruntime.swg | 25 +++++++- Source/Modules/javascript.cxx | 80 ++++++++++++++----------- 4 files changed, 112 insertions(+), 75 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 59b071c89..c2b6819d3 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -1,5 +1,5 @@ %fragment("JS_ctordefn", "templates") %{ -v8::Handle $jsmangledname_new(const v8::Arguments& args) { +v8::Handle $jswrapper(const v8::Arguments& args) { v8::HandleScope scope; v8::Handle self = args.Holder(); $jslocals @@ -8,13 +8,21 @@ v8::Handle $jsmangledname_new(const v8::Arguments& args) { return scope.Close(self); goto fail; fail: - return scope.Close(v8::Undefined); + return scope.Close(v8::Undefined()); +}%} + +%fragment ("JS_veto_ctor", "templates") +%{ +v8::Handle $jsctor(const v8::Arguments& args) { + v8::HandleScope scope; + SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); + return scope.Close(v8::Undefined()); }%} %fragment("JS_getproperty", "templates") %{ v8::Handle $jsgetter(v8::Local property, const v8::AccessorInfo& info) { v8::HandleScope scope; - v8::Handle jsresult; + v8::Handle jsresult; $jslocals $jscode return scope.Close(jsresult); @@ -36,7 +44,7 @@ fail: %fragment("JS_functionwrapper", "templates") %{ v8::Handle $jswrapper(const v8::Arguments &args) { v8::HandleScope scope; - v8::Handle jsresult; + v8::Handle jsresult; $jslocals $jscode return scope.Close(jsresult); @@ -45,7 +53,6 @@ fail: return scope.Close(v8::Undefined()); }%} -// TODO: implement ctor overloading properly! %fragment ("JS_mainctordefn", "templates") %{ // TODO: implement JS_mainctordefn @@ -61,41 +68,41 @@ fail: // TODO: implement JS_destructordefn %} -%fragment("jsv8_declare_class_template", "templates") %{ -v8::Persistent SWIGV8_$jsmangledname;%} +%fragment("jsv8_declare_class_template", "templates") +%{v8::Persistent SWIGV8_$jsmangledname;%} -%fragment("jsv8_define_class_template", "templates") %{ -SWIGV8_$jsmangledname = SWIGV8_CreateClassTemplate("$jsname" , $jsmangledname_new);%} +%fragment("jsv8_define_class_template", "templates") +%{SWIGV8_$jsmangledname = SWIGV8_CreateClassTemplate("$jsname" , $jsctor);%} -%fragment("jsv8_create_class_instance", "templates") %{ -v8::Handle class_$jsmangledname = SWIGV8_$jsmangledname->GetFunction();%} +%fragment("jsv8_create_class_instance", "templates") +%{v8::Handle class_$jsmangledname = SWIGV8_$jsmangledname->GetFunction();%} -%fragment("jsv8_inherit", "templates") %{ -SWIGV8_$jsmangledname->Inherit(SWIGV8_$jsbaseclass);%} +%fragment("jsv8_inherit", "templates") +%{SWIGV8_$jsmangledname->Inherit(SWIGV8_$jsbaseclass);%} -%fragment("jsv8_register_class", "templates") %{ -$jsparent->Set(v8::String::NewSymbol("$jsname"), class_$jsmangledname);%} +%fragment("jsv8_register_class", "templates") +%{$jsparent->Set(v8::String::NewSymbol("$jsname"), class_$jsmangledname);%} -%fragment("jsv8_create_namespace", "templates") %{ -v8::Handle $jsmangledname = v8::ObjectTemplate::New();%} +%fragment("jsv8_create_namespace", "templates") +%{v8::Handle $jsmangledname = v8::ObjectTemplate::New();%} -%fragment("jsv8_register_member_function", "templates") %{ -SWIGV8_AddMemberFunction(SWIGV8_$jsmangledname, "$jsname", $jswrapper);%} +%fragment("jsv8_register_member_function", "templates") +%{SWIGV8_AddMemberFunction(SWIGV8_$jsmangledname, "$jsname", $jswrapper);%} -%fragment("jsv8_register_static_function", "templates") %{ -SWIGV8_AddGlobalFunction($jsparent, "$jsname", $jswrapper);%} +%fragment("jsv8_register_static_function", "templates") +%{SWIGV8_AddGlobalFunction(SWIGV8_$jsparent, "$jsname", $jswrapper);%} -%fragment("jsv8_register_member_variable", "templates") %{ -SWIGV8_AddMemberVariable(SWIGV8_$jsmangledname, "$jsname", $jsgetter, $jssetter);%} +%fragment("jsv8_register_member_variable", "templates") +%{SWIGV8_AddMemberVariable(SWIGV8_$jsmangledname, "$jsname", $jsgetter, $jssetter);%} -%fragment("jsv8_register_static_variable", "templates") %{ -SWIGV8_AddGlobalVariable($jsparent, "$jsname", $jsgetter, $jssetter);%} +%fragment("jsv8_register_static_variable", "templates") +%{SWIGV8_AddGlobalVariable(SWIGV8_$jsparent, "$jsname", $jsgetter, $jssetter);%} -%fragment("jsv8_register_namespace", "templates") %{ -$jsparent->Set(v8::String::NewSymbol("$jsname", $jsmangledname->NewInstance()));%} - -%fragment("JS_initializer", "templates") %{ +%fragment("jsv8_register_namespace", "templates") +%{$jsparent->Set(v8::String::NewSymbol("$jsname"), $jsmangledname->NewInstance());%} +%fragment("JS_initializer", "templates") +%{ extern "C" { void $jsname_initialize(v8::Handle context) @@ -115,12 +122,12 @@ void $jsname_initialize(v8::Handle context) /* setup inheritances */ $jsv8inheritance - /* class instances */ - $jsv8classinstances - /* add static class functions and variables */ $jsv8staticwrappers + /* class instances */ + $jsv8classinstances + /* register classes */ $jsv8registerclasses diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index 1159f7ef3..bd103702c 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -24,10 +24,12 @@ void SWIGV8_AddMemberFunction(v8::Handle class_templ, cons /** * Registers a class method with given name for a given class template. */ -void SWIGV8_AddGlobalFunction(v8::Handle obj_templ, const char* symbol, v8::InvocationCallback _func) { - obj_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); +void SWIGV8_AddGlobalFunction(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { + v8::Handle obj_templ = class_templ->InstanceTemplate(); + obj_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); } + /** * Registers a class property with given name for a given class template. */ @@ -39,7 +41,8 @@ void SWIGV8_AddMemberVariable(v8::Handle class_templ, cons /** * Registers a class method with given name for a given class template. */ -void SWIGV8_AddGlobalVariable(v8::Handle obj_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { - obj_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); +void SWIGV8_AddGlobalVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { + v8::Handle obj_templ = class_templ->InstanceTemplate(); + obj_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } %} // v8_helper_functions diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 15d8a35fc..e8b26892c 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -24,7 +24,7 @@ typedef struct { bool swigCMemOwn; void *swigCObject; swig_type_info *info; -}SWIG_PRV_DATA; +} SWIG_PRV_DATA; %} %insert(runtime) %{ @@ -88,8 +88,27 @@ int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info } v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { - // TODO: wrap ptr into an v8 object - return v8::Undefined(); + v8::HandleScope scope; + + v8::Local class_templ; + if(info->clientdata == NULL) { + // TODO: get class template for unknown types + //class_templ = _SwigObject_classRef; + } else { + class_templ = *((v8::Local*) info->clientdata); + } + + v8::Handle inst_templ = class_templ->InstanceTemplate(); + v8::Local result = inst_templ->NewInstance(); + + SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) new SWIG_PRV_DATA; + cdata->swigCObject = ptr; + cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; + cdata->info = info; + + result->SetInternalField(0, v8::External::New(cdata)); + + return scope.Close(result); } #define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_V8_ConvertPtr(obj, ptr, info, flags) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 3ccc9ffa4..14b2e7859 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1708,21 +1708,29 @@ int V8Emitter::enterClass(Node *n) t_decl_class.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .pretty_print(f_class_templates); - // emit definition of v8 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)) - .pretty_print(f_init_class_templates); - - Template t_class_instance(getTemplate("jsv8_create_class_instance")); - t_class_instance.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .pretty_print(f_init_class_instances); - return SWIG_OK; } int V8Emitter::exitClass(Node *n) { + if(GetFlag(state.clazz(), IS_ABSTRACT)) { + Template t_veto_ctor(getTemplate("JS_veto_ctor")); + t_veto_ctor.replace(T_CTOR, state.clazz(CTOR)) + .replace(T_NAME, state.clazz(NAME)) + .pretty_print(f_wrappers); + } + + // emit definition of v8 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_CTOR, state.clazz(CTOR)) + .pretty_print(f_init_class_templates); + + Template t_class_instance(getTemplate("jsv8_create_class_instance")); + t_class_instance.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .pretty_print(f_init_class_instances); + // emit inheritance setup Node* baseClass = getBaseClass(n); if(baseClass) { @@ -1759,14 +1767,11 @@ int V8Emitter::exitVariable(Node* n) if(GetFlag(n, "ismember")) { if(GetFlag(state.variable(), IS_STATIC)) { Template t_register(getTemplate("jsv8_register_static_variable")); - String *class_instance = NewString(""); - Printf(class_instance, "class_%s", state.clazz(NAME_MANGLED)); - t_register.replace(T_PARENT, class_instance) + 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)) .pretty_print(f_init_static_wrappers); - Delete(class_instance); } else { Template t_register(getTemplate("jsv8_register_member_variable")); t_register.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) @@ -1779,7 +1784,7 @@ int V8Emitter::exitVariable(Node* n) // 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")); - t_register.replace(T_PARENT, Getattr(current_namespace, "name")) + 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)) @@ -1802,16 +1807,13 @@ int V8Emitter::exitFunction(Node* n) if(GetFlag(n, "ismember")) { if(GetFlag(state.function(), IS_STATIC)) { Template t_register(getTemplate("jsv8_register_static_function")); - String *class_instance = NewString(""); - Printf(class_instance, "class_%s", state.clazz(NAME_MANGLED)); - t_register.replace(T_PARENT, class_instance) + t_register.replace(T_PARENT, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.function(NAME)) .replace(T_WRAPPER, Getattr(n, "wrap:name")); Printv(f_init_static_wrappers, t_register.str(), 0); - Delete(class_instance); } else { Template t_register(getTemplate("jsv8_register_member_function")); - t_register.replace(T_PARENT, state.clazz(NAME_MANGLED)) + t_register.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.function(NAME)) .replace(T_WRAPPER, Getattr(n, "wrap:name")); Printv(f_init_wrappers, t_register.str(), "\n", 0); @@ -1820,7 +1822,7 @@ int V8Emitter::exitFunction(Node* n) // 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")); - t_register.replace(T_PARENT, Getattr(current_namespace, "name")) + t_register.replace(T_PARENT, Getattr(current_namespace, NAME)) .replace(T_NAME, state.function(NAME)) .replace(T_WRAPPER, Getattr(n, "wrap:name")); Printv(f_init_wrappers, t_register.str(), 0); @@ -1881,21 +1883,27 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar } 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(V8_MANGLED_NAME, scope_mangled); - - Template t_register_ns(getTemplate(V8_REGISTER_NAMESPACE)); - t_register_ns.Replace(V8_MANGLED_NAME, scope_mangled) - .Replace(V8_CONTEXT, parent_scope_mangled) - .Replace(V8_UNQUALIFIED_NAME, scope_unqualified); + Iterator it; + for (it = First(namespaces); it.item; it = Next(it)) { + Hash *entry = it.item; + String *name = Getattr(entry, NAME); + String *name_mangled = Getattr(entry, NAME_MANGLED); + String *parent = Getattr(entry, PARENT); + String *parent_mangled = Swig_name_mangle(parent); - Printv(f_init_namespaces, t_create_ns.str(), 0); + // create namespace object and register it to the parent scope + Template t_create_ns(getTemplate("jsv8_create_namespace")); + t_create_ns.replace(T_NAME_MANGLED, name_mangled) + .pretty_print(f_init_namespaces); + + 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); + // prepend in order to achieve reversed order of registration statements Insert(f_init_register_namespaces, 0, t_register_ns.str()); -*/ + } return SWIG_OK; } @@ -2044,9 +2052,9 @@ String *Template::str() { String *pre_code = NewString(""); String *post_code = NewString(""); String *debug_code = NewString(""); - Printf(pre_code, "//begin fragment(\"%s\")\n", templateName); - Printf(post_code, "//end fragment(\"%s\")\n", templateName); - Printf(debug_code, "%s\n%s\n%s", pre_code, code, post_code); + Printf(pre_code, "/* begin fragment(\"%s\") */", templateName); + Printf(post_code, "/* end fragment(\"%s\") */", templateName); + Printf(debug_code, "%s\n%s\n%s\n", pre_code, code, post_code); Delete(code); Delete(pre_code); From 022c274256d5f61daa6a880d781b903cb82af677 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:07:21 +0000 Subject: [PATCH 060/352] Minor fixes in v8 javascript shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13794 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 2 +- Tools/javascript/v8_shell.cxx | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 027ce795e..8bf1f1498 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -552,7 +552,7 @@ ifeq (,$(V8)) else JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx $(JSEXE_SRC_DIR)/v8_shell.cxx JSEXE_OPTS = -v8 - JSEXE_FLAG = -DUSE_V8 + JSEXE_FLAGS = -DUSE_V8 endif # ---------------------------------------------------------------- diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index e124ebd7d..c4cbcecc5 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -220,3 +220,7 @@ void V8Shell::ReportException(v8::TryCatch* try_catch) { const char* V8Shell::ToCString(const v8::String::Utf8Value& value) { return *value ? *value : ""; } + +JSShell* create_v8_shell() { + return new V8Shell(); +} From 78f5b46381e4c93f3d1227a702761a8eda01f4ca Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:07:43 +0000 Subject: [PATCH 061/352] Fix class example. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13795 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/javascript/class/{example.cpp => example.cxx} | 0 Examples/javascript/class/example.h | 1 - 2 files changed, 1 deletion(-) rename Examples/javascript/class/{example.cpp => example.cxx} (100%) diff --git a/Examples/javascript/class/example.cpp b/Examples/javascript/class/example.cxx similarity index 100% rename from Examples/javascript/class/example.cpp rename to Examples/javascript/class/example.cxx diff --git a/Examples/javascript/class/example.h b/Examples/javascript/class/example.h index 9d19e340a..64b7684fa 100755 --- a/Examples/javascript/class/example.h +++ b/Examples/javascript/class/example.h @@ -12,7 +12,6 @@ public: void move(double dx, double dy); virtual double area(void) = 0; virtual double perimeter(void) = 0; - static void printMe(void); static int nshapes; }; From 46cff47ada4ec3197798359425c165e09d4498a5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:08:03 +0000 Subject: [PATCH 062/352] Several fixes in generator for v8 initializer function. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13796 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 76 ++++++++++++------------- Lib/javascript/v8/javascripthelpers.swg | 28 +++++---- Source/Modules/javascript.cxx | 17 +++--- 3 files changed, 60 insertions(+), 61 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index c2b6819d3..8ba811354 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -69,37 +69,37 @@ fail: %} %fragment("jsv8_declare_class_template", "templates") -%{v8::Persistent SWIGV8_$jsmangledname;%} +%{v8::Persistent $jsmangledname_class;%} %fragment("jsv8_define_class_template", "templates") -%{SWIGV8_$jsmangledname = SWIGV8_CreateClassTemplate("$jsname" , $jsctor);%} +%{$jsmangledname_class = SWIGV8_CreateClassTemplate("$jsname" , $jsctor);%} %fragment("jsv8_create_class_instance", "templates") -%{v8::Handle class_$jsmangledname = SWIGV8_$jsmangledname->GetFunction();%} +%{v8::Handle $jsmangledname = $jsmangledname_class->GetFunction();%} %fragment("jsv8_inherit", "templates") -%{SWIGV8_$jsmangledname->Inherit(SWIGV8_$jsbaseclass);%} +%{$jsmangledname_class->Inherit($jsbaseclass_class);%} %fragment("jsv8_register_class", "templates") -%{$jsparent->Set(v8::String::NewSymbol("$jsname"), class_$jsmangledname);%} +%{$jsparent->Set(v8::String::NewSymbol("$jsname"), $jsmangledname);%} %fragment("jsv8_create_namespace", "templates") -%{v8::Handle $jsmangledname = v8::ObjectTemplate::New();%} +%{v8::Handle $jsmangledname = v8::Object::New();%} %fragment("jsv8_register_member_function", "templates") -%{SWIGV8_AddMemberFunction(SWIGV8_$jsmangledname, "$jsname", $jswrapper);%} - -%fragment("jsv8_register_static_function", "templates") -%{SWIGV8_AddGlobalFunction(SWIGV8_$jsparent, "$jsname", $jswrapper);%} +%{SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper);%} %fragment("jsv8_register_member_variable", "templates") -%{SWIGV8_AddMemberVariable(SWIGV8_$jsmangledname, "$jsname", $jsgetter, $jssetter);%} +%{SWIGV8_AddMemberVariable($jsmangledname_class, "$jsname", $jsgetter, $jssetter);%} + +%fragment("jsv8_register_static_function", "templates") +%{SWIGV8_AddStaticFunction($jsparent, "$jsname", $jswrapper);%} %fragment("jsv8_register_static_variable", "templates") -%{SWIGV8_AddGlobalVariable(SWIGV8_$jsparent, "$jsname", $jsgetter, $jssetter);%} +%{SWIGV8_AddStaticVariable($jsparent, "$jsname", $jsgetter, $jssetter);%} %fragment("jsv8_register_namespace", "templates") -%{$jsparent->Set(v8::String::NewSymbol("$jsname"), $jsmangledname->NewInstance());%} +%{$jsparent->Set(v8::String::NewSymbol("$jsname"), $jsmangledname);%} %fragment("JS_initializer", "templates") %{ @@ -107,32 +107,32 @@ extern "C" { void $jsname_initialize(v8::Handle context) { - v8::HandleScope scope; - v8::Local global = context->Global(); + v8::HandleScope scope; + v8::Local global = context->Global(); - /* create object templates for namespaces */ - $jsv8nspaces - - /* create class templates */ - $jsv8classtemplates - - /* register wrapper functions */ - $jsv8wrappers - - /* setup inheritances */ - $jsv8inheritance - - /* add static class functions and variables */ - $jsv8staticwrappers - - /* class instances */ - $jsv8classinstances - - /* register classes */ - $jsv8registerclasses - - /* create and register namespace objects */ - $jsv8registernspaces + /* create objects for namespaces */ + $jsv8nspaces + + /* create class templates */ + $jsv8classtemplates + + /* register wrapper functions */ + $jsv8wrappers + + /* setup inheritances */ + $jsv8inheritance + + /* class instances */ + $jsv8classinstances + + /* add static class functions and variables */ + $jsv8staticwrappers + + /* register classes */ + $jsv8registerclasses + + /* create and register namespace objects */ + $jsv8registernspaces } }%} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index bd103702c..5de11feb3 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -21,28 +21,26 @@ void SWIGV8_AddMemberFunction(v8::Handle class_templ, cons proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); } -/** - * Registers a class method with given name for a given class template. - */ -void SWIGV8_AddGlobalFunction(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { - v8::Handle obj_templ = class_templ->InstanceTemplate(); - obj_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); -} - - /** * Registers a class property with given name for a given class template. */ void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { - v8::Handle proto_templ = class_templ->InstanceTemplate(); - proto_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); + v8::Handle proto_templ = class_templ->InstanceTemplate(); + proto_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } /** - * Registers a class method with given name for a given class template. + * Registers a class method with given name for a given object. */ -void SWIGV8_AddGlobalVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { - v8::Handle obj_templ = class_templ->InstanceTemplate(); - obj_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); +void SWIGV8_AddStaticFunction(v8::Handle obj, const char* symbol, v8::InvocationCallback _func) { + obj->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); } + +/** + * Registers a class method with given name for a given object. + */ +void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { + obj->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); +} + %} // v8_helper_functions diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 14b2e7859..a415e8371 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1728,7 +1728,8 @@ int V8Emitter::exitClass(Node *n) .pretty_print(f_init_class_templates); Template t_class_instance(getTemplate("jsv8_create_class_instance")); - t_class_instance.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + t_class_instance.replace(T_NAME, state.clazz(NAME)) + .replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .pretty_print(f_init_class_instances); // emit inheritance setup @@ -1790,7 +1791,7 @@ int V8Emitter::exitVariable(Node* n) .replace(T_SETTER, state.variable(SETTER)) .pretty_print(f_init_wrappers); } - + return SWIG_OK; } @@ -1809,14 +1810,14 @@ int V8Emitter::exitFunction(Node* n) 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, Getattr(n, "wrap:name")); - Printv(f_init_static_wrappers, t_register.str(), 0); + .replace(T_WRAPPER, Getattr(n, "wrap:name")) + .pretty_print(f_init_static_wrappers); } else { 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, Getattr(n, "wrap:name")); - Printv(f_init_wrappers, t_register.str(), "\n", 0); + .replace(T_WRAPPER, Getattr(n, "wrap:name")) + .pretty_print(f_init_wrappers); } } else { // Note: a global function is treated like a static function @@ -1824,8 +1825,8 @@ int V8Emitter::exitFunction(Node* n) 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, Getattr(n, "wrap:name")); - Printv(f_init_wrappers, t_register.str(), 0); + .replace(T_WRAPPER, Getattr(n, "wrap:name")) + .pretty_print(f_init_wrappers); } return SWIG_OK; From 9a914af2b787b336228f779c519b39147e536a68 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:08:16 +0000 Subject: [PATCH 063/352] Fix v8 shell to initialize v8 context in proper order. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13797 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Tools/javascript/v8_shell.cxx | 91 ++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index c4cbcecc5..62620a72a 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -14,9 +14,14 @@ typedef int (*V8ExtensionRegistrar) (v8::Handle); class V8Shell: public JSShell { public: - V8Shell(); - - virtual ~V8Shell(); + V8Shell(); + + virtual ~V8Shell(); + + virtual bool RunScript(const std::string& scriptPath); + + virtual bool RunShell(); + protected: @@ -41,6 +46,8 @@ private: static v8::Handle Version(const v8::Arguments& args); static const char* ToCString(const v8::String::Utf8Value& value); + + void ExtendEngine(); protected: @@ -76,24 +83,81 @@ bool V8Shell::RegisterModule(HANDLE library, const std::string& module_name) { return true; } -bool V8Shell::InitializeEngine() { +bool V8Shell::RunScript(const std::string& scriptPath) { + if (!context.IsEmpty()) { context.Dispose(); } + + std::string source = ReadFile(scriptPath); context = CreateShellContext(); if (context.IsEmpty()) { printf("Could not create context.\n"); - return 1; + return false; + } + context->Enter(); + + v8::Context::Scope context_scope(context); + ExtendEngine(); + + if(!ExecuteScript(source, scriptPath)) { + return false; + } + + context->Exit(); + context.Dispose(); + v8::V8::Dispose(); +} + +bool V8Shell::RunShell() { + + if (!context.IsEmpty()) { + context.Dispose(); + } + + context = CreateShellContext(); + if (context.IsEmpty()) { + printf("Could not create context.\n"); + return false; } context->Enter(); + + v8::Context::Scope context_scope(context); + ExtendEngine(); + + static const int kBufferSize = 1024; + while (true) { + char buffer[kBufferSize]; + printf("> "); + char* str = fgets(buffer, kBufferSize, stdin); + if (str == NULL) break; + std::string source(str); + ExecuteScript(source, "(shell)"); + } + printf("\n"); + + context->Exit(); + context.Dispose(); + v8::V8::Dispose(); +} + + +bool V8Shell::InitializeEngine() { +} + +void V8Shell::ExtendEngine() { + + // register extensions + for(std::vector::iterator it=module_initializers.begin(); + it != module_initializers.end(); ++it) { + (*it)(context); + } + } bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) { - // Enter the execution environment before evaluating any code. - v8::Context::Scope context_scope(context); - v8::HandleScope handle_scope; v8::TryCatch try_catch; v8::Handle script = v8::Script::Compile(v8::String::New(source.c_str()), v8::String::New(name.c_str())); @@ -123,12 +187,11 @@ bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) } bool V8Shell::DisposeEngine() { - context->Exit(); - context.Dispose(); - v8::V8::Dispose(); } v8::Persistent V8Shell::CreateShellContext() { + v8::HandleScope scope; + // Create a template for the global object. v8::Handle global = v8::ObjectTemplate::New(); @@ -139,12 +202,6 @@ v8::Persistent V8Shell::CreateShellContext() { v8::Persistent _context = v8::Context::New(NULL, global); - // register extensions - for(std::vector::iterator it=module_initializers.begin(); - it != module_initializers.end(); ++it) { - (*it)(_context); - } - return _context; } From 21bdb78f1ca2f016afb73c84b4286312f47d3175 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:08:33 +0000 Subject: [PATCH 064/352] Activate SwigModuleInitializer for in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13798 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 2 ++ Source/Modules/javascript.cxx | 32 +++++++++++++++++----------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 8ba811354..ef16478d8 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -107,6 +107,8 @@ extern "C" { void $jsname_initialize(v8::Handle context) { + SWIG_InitializeModule(0); + v8::HandleScope scope; v8::Local global = context->Global(); diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index a415e8371..f114c74c9 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1575,19 +1575,23 @@ protected: private: - File *f_runtime; - File *f_header; - File *f_class_templates; - File *f_init; + /* built-in parts */ + String *f_runtime; + String *f_header; + String *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; + /* part for class templates */ + String *f_class_templates; + + /* parts for initilizer */ + String *f_init_namespaces; + String *f_init_class_templates; + String *f_init_wrappers; + String *f_init_inheritance; + String *f_init_class_instances; + String *f_init_static_wrappers; + String *f_init_register_classes; + String *f_init_register_namespaces; // the output cpp file File *f_wrap_cpp; @@ -1672,7 +1676,9 @@ int V8Emitter::dump(Node *n) .replace(V8_STATIC_WRAPPERS, f_init_static_wrappers) .replace(V8_REGISTER_CLASSES, f_init_register_classes) .replace(V8_REGISTER_NS, f_init_register_namespaces) - .pretty_print(f_wrap_cpp); + .pretty_print(f_init); + + Printv(f_wrap_cpp, f_init, 0); return SWIG_OK; } From f1e9b21dfd63df4b694bac471daa1f9359c88378 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:08:50 +0000 Subject: [PATCH 065/352] Add missing swig_type_info registration in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13799 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 8 +- Source/Modules/javascript.cxx | 626 +++++++++++++-------------- 2 files changed, 314 insertions(+), 320 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index ef16478d8..2adbd1307 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -4,8 +4,9 @@ v8::Handle $jswrapper(const v8::Arguments& args) { v8::Handle self = args.Holder(); $jslocals $jscode - self->SetInternalField(0, v8::External::New(result)); - return scope.Close(self); + + return SWIG_V8_NewPointerObj(result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + goto fail; fail: return scope.Close(v8::Undefined()); @@ -72,7 +73,8 @@ fail: %{v8::Persistent $jsmangledname_class;%} %fragment("jsv8_define_class_template", "templates") -%{$jsmangledname_class = SWIGV8_CreateClassTemplate("$jsname" , $jsctor);%} +%{$jsmangledname_class = SWIGV8_CreateClassTemplate("$jsname" , $jsctor); + SWIGTYPE_$jsmangledtype->clientdata = &$jsmangledname_class;%} %fragment("jsv8_create_class_instance", "templates") %{v8::Handle $jsmangledname = $jsmangledname_class->GetFunction();%} diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index f114c74c9..388f037e7 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -21,6 +21,7 @@ bool js_template_enable_debug = false; #define CTOR_WRAPPERS "ctor_wrappers" #define CTOR_DISPATCHERS "ctor_dispatchers" #define ARGCOUNT "wrap:argc" +#define FUNCTION_DISPATCHERS "function_dispatchers" // variables used in code templates // ATTENTION: be aware of prefix collisions when defining those variables @@ -785,6 +786,309 @@ int JSEmitter::enterVariable(Node *n) { return SWIG_OK; } +int JSEmitter::emitCtor(Node *n) { + + Wrapper *wrapper = NewWrapper(); + + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + Template t_ctor(getTemplate("JS_ctordefn")); + + //String *mangled_name = SwigType_manglestr(Getattr(n, "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); + // note: removing the is_abstract flag, as this emitter + // is supposed to be called for non-abstract classes only. + Setattr(state.clazz(), IS_ABSTRACT, 0); + + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + + Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0)); + + String *action = emit_action(n); + marshalInputArgs(n, params, wrapper, Ctor, true, false); + + Printv(wrapper->code, action, "\n", 0); + t_ctor.replace(T_WRAPPER, wrap_name) + .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) + .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) + .pretty_print(f_wrappers); + + Template t_ctor_case(getTemplate("JS_ctor_dispatch_case")); + t_ctor_case.replace(T_WRAPPER, wrap_name) + .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); + Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); + + DelWrapper(wrapper); + + // create a dispatching ctor + if(is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Template t_mainctor(getTemplate("JS_mainctordefn")); + t_mainctor.replace(T_WRAPPER, wrap_name) + .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) + .pretty_print(f_wrappers); + state.clazz(CTOR, wrap_name); + } + } else { + state.clazz(CTOR, wrap_name); + } + + return SWIG_OK; +} + +int JSEmitter::emitDtor(Node *) { + + Template t_dtor = getTemplate("JS_destructordefn"); + t_dtor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + .replace(T_TYPE, state.clazz(TYPE)) + .pretty_print(f_wrappers); + + return SWIG_OK; +} + +int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { + Wrapper *wrapper = NewWrapper(); + Template t_getter(getTemplate("JS_getproperty")); + + // prepare wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Setattr(n, "wrap:name", wrap_name); + state.variable(GETTER, wrap_name); + + // prepare local variables + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + + // prepare code part + String *action = emit_action(n); + marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); + marshalOutput(n, action, wrapper); + + t_getter.replace(T_GETTER, wrap_name) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) + .pretty_print(f_wrappers); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { + + // skip variables that are immutable + if (State::IsSet(state.variable(IS_IMMUTABLE))) { + return SWIG_OK; + } + + Wrapper *wrapper = NewWrapper(); + + Template t_setter(getTemplate("JS_setproperty")); + + // prepare wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Setattr(n, "wrap:name", wrap_name); + state.variable(SETTER, wrap_name); + + // prepare local variables + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + + // prepare code part + String *action = emit_action(n); + marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); + Append(wrapper->code, action); + + t_setter.replace(T_SETTER, wrap_name) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) + .pretty_print(f_wrappers); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::emitConstant() : triggers code generation for constants + * ----------------------------------------------------------------------------- */ + +int JSEmitter::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); + + // 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 code part + String *action = NewString(""); + String *value = Getattr(n, "rawval"); + if (value == NULL) { + value = Getattr(n, "rawvalue"); + } + if (value == NULL) { + value = Getattr(n, "value"); + } + Printf(action, "result = %s;\n", value); + Setattr(n, "wrap:action", action); + marshalOutput(n, action, wrapper); + + t_getter.replace(T_GETTER, wrap_name) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) + .pretty_print(f_wrappers); + + exitVariable(n); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { + + Wrapper *wrapper = NewWrapper(); + Template t_function(getTemplate("JS_functionwrapper")); + + 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) { + t_function = getTemplate("JS_functionwrapper_overload"); + 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, wrapper); + emit_attach_parmmaps(params, wrapper); + + // prepare code part + String *action = emit_action(n); + marshalInputArgs(n, params, wrapper, Function, is_member, is_static); + marshalOutput(n, action, wrapper); + + t_function.replace(T_WRAPPER, wrap_name) + .replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code) + .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) + .pretty_print(f_wrappers); + + // handle function overloading + if (is_overloaded) { + Template t_dispatch_case = getTemplate("JS_function_dispatch_case"); + t_dispatch_case.replace(T_WRAPPER, wrap_name) + .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); + Append(state.global(FUNCTION_DISPATCHERS), t_dispatch_case.str()); + } + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { + + Template t_function(getTemplate("JS_functionwrapper")); + + Wrapper *wrapper = NewWrapper(); + String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); + Setattr(n, "wrap:name", wrap_name); + + Wrapper_add_local(wrapper, "res", "int res"); + + Append(wrapper->code, state.global(FUNCTION_DISPATCHERS)); + Append(wrapper->code, getTemplate("JS_function_dispatch_case_default").str()); + + t_function.replace(T_LOCALS, wrapper->locals) + .replace(T_CODE, wrapper->code); + + // call this here, to replace all variables + t_function.replace(T_WRAPPER, wrap_name) + .replace(T_NAME, state.function(NAME)) + .pretty_print(f_wrappers); + + // Delete the state variable + state.global(FUNCTION_DISPATCHERS, 0); + DelWrapper(wrapper); + + 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); + 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 JSEmitter::switchNamespace(Node *n) { if (!GetFlag(n, "feature:nspace")) { @@ -903,9 +1207,6 @@ private: #define STATIC_FUNCTIONS "static_functions" #define STATIC_VARIABLES "static_variables" -// keys for function scoped state variables -#define FUNCTION_DISPATCHERS "function_dispatchers" - JSCEmitter::JSCEmitter() : JSEmitter(), NULL_STR(NewString("NULL")), @@ -1196,309 +1497,6 @@ int JSCEmitter::exitClass(Node *n) { return SWIG_OK; } -int JSEmitter::emitCtor(Node *n) { - - Wrapper *wrapper = NewWrapper(); - - bool is_overloaded = GetFlag(n, "sym:overloaded"); - - Template t_ctor(getTemplate("JS_ctordefn")); - - //String *mangled_name = SwigType_manglestr(Getattr(n, "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); - // note: removing the is_abstract flag, as this emitter - // is supposed to be called for non-abstract classes only. - Setattr(state.clazz(), IS_ABSTRACT, 0); - - ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - - Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0)); - - String *action = emit_action(n); - marshalInputArgs(n, params, wrapper, Ctor, true, false); - - Printv(wrapper->code, action, "\n", 0); - t_ctor.replace(T_WRAPPER, wrap_name) - .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) - .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) - .pretty_print(f_wrappers); - - Template t_ctor_case(getTemplate("JS_ctor_dispatch_case")); - t_ctor_case.replace(T_WRAPPER, wrap_name) - .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); - Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); - - DelWrapper(wrapper); - - // create a dispatching ctor - if(is_overloaded) { - if (!Getattr(n, "sym:nextSibling")) { - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Template t_mainctor(getTemplate("JS_mainctordefn")); - t_mainctor.replace(T_WRAPPER, wrap_name) - .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) - .pretty_print(f_wrappers); - state.clazz(CTOR, wrap_name); - } - } else { - state.clazz(CTOR, wrap_name); - } - - return SWIG_OK; -} - -int JSEmitter::emitDtor(Node *) { - - Template t_dtor = getTemplate("JS_destructordefn"); - t_dtor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_TYPE, state.clazz(TYPE)) - .pretty_print(f_wrappers); - - return SWIG_OK; -} - -int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { - Wrapper *wrapper = NewWrapper(); - Template t_getter(getTemplate("JS_getproperty")); - - // prepare wrapper name - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Setattr(n, "wrap:name", wrap_name); - state.variable(GETTER, wrap_name); - - // prepare local variables - ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - - // prepare code part - String *action = emit_action(n); - marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); - marshalOutput(n, action, wrapper); - - t_getter.replace(T_GETTER, wrap_name) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) - .pretty_print(f_wrappers); - - DelWrapper(wrapper); - - return SWIG_OK; -} - -int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { - - // skip variables that are immutable - if (State::IsSet(state.variable(IS_IMMUTABLE))) { - return SWIG_OK; - } - - Wrapper *wrapper = NewWrapper(); - - Template t_setter(getTemplate("JS_setproperty")); - - // prepare wrapper name - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Setattr(n, "wrap:name", wrap_name); - state.variable(SETTER, wrap_name); - - // prepare local variables - ParmList *params = Getattr(n, "parms"); - emit_parameter_variables(params, wrapper); - emit_attach_parmmaps(params, wrapper); - - // prepare code part - String *action = emit_action(n); - marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); - Append(wrapper->code, action); - - t_setter.replace(T_SETTER, wrap_name) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) - .pretty_print(f_wrappers); - - DelWrapper(wrapper); - - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * JSCEmitter::emitConstant() : triggers code generation for constants - * ----------------------------------------------------------------------------- */ - -int JSEmitter::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); - - // 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 code part - String *action = NewString(""); - String *value = Getattr(n, "rawval"); - if (value == NULL) { - value = Getattr(n, "rawvalue"); - } - if (value == NULL) { - value = Getattr(n, "value"); - } - Printf(action, "result = %s;\n", value); - Setattr(n, "wrap:action", action); - marshalOutput(n, action, wrapper); - - t_getter.replace(T_GETTER, wrap_name) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) - .pretty_print(f_wrappers); - - exitVariable(n); - - DelWrapper(wrapper); - - return SWIG_OK; -} - -int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { - - Wrapper *wrapper = NewWrapper(); - Template t_function(getTemplate("JS_functionwrapper")); - - 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) { - t_function = getTemplate("JS_functionwrapper_overload"); - 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, wrapper); - emit_attach_parmmaps(params, wrapper); - - // prepare code part - String *action = emit_action(n); - marshalInputArgs(n, params, wrapper, Function, is_member, is_static); - marshalOutput(n, action, wrapper); - - t_function.replace(T_WRAPPER, wrap_name) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) - .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) - .pretty_print(f_wrappers); - - // handle function overloading - if (is_overloaded) { - Template t_dispatch_case = getTemplate("JS_function_dispatch_case"); - t_dispatch_case.replace(T_WRAPPER, wrap_name) - .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); - Append(state.global(FUNCTION_DISPATCHERS), t_dispatch_case.str()); - } - - DelWrapper(wrapper); - - return SWIG_OK; -} - -int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { - - Template t_function(getTemplate("JS_functionwrapper")); - - Wrapper *wrapper = NewWrapper(); - String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); - Setattr(n, "wrap:name", wrap_name); - - Wrapper_add_local(wrapper, "res", "int res"); - - Append(wrapper->code, state.global(FUNCTION_DISPATCHERS)); - Append(wrapper->code, getTemplate("JS_function_dispatch_case_default").str()); - - t_function.replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code); - - // call this here, to replace all variables - t_function.replace(T_WRAPPER, wrap_name) - .replace(T_NAME, state.function(NAME)) - .pretty_print(f_wrappers); - - // Delete the state variable - state.global(FUNCTION_DISPATCHERS, 0); - DelWrapper(wrapper); - - 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); - 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 = JSEmitter::createNamespaceEntry(name, parent); Setattr(entry, "functions", NewString("")); @@ -1541,6 +1539,10 @@ JSEmitter *swig_javascript_create_JSCEmitter() { return new JSCEmitter(); } +/********************************************************************** + * V8: JSEmitter implementation for V8 engine + **********************************************************************/ + class V8Emitter: public JSEmitter { public: @@ -1548,29 +1550,19 @@ public: V8Emitter(); virtual ~V8Emitter(); - virtual int initialize(Node *n); - virtual int dump(Node *n); - virtual int close(); - virtual int enterClass(Node *n); - 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: virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); - virtual int emitNamespaces(); private: @@ -1731,6 +1723,7 @@ int V8Emitter::exitClass(Node *n) t_def_class.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.clazz(NAME)) .replace(T_CTOR, state.clazz(CTOR)) + .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) .pretty_print(f_init_class_templates); Template t_class_instance(getTemplate("jsv8_create_class_instance")); @@ -1804,7 +1797,6 @@ int V8Emitter::exitVariable(Node* n) int V8Emitter::enterFunction(Node* n) { JSEmitter::enterFunction(n); - return SWIG_OK; } From 1862f43cfcd93a3f79cf652da70f22a438de4cf9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:09:05 +0000 Subject: [PATCH 066/352] Minor clean up in class example. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13800 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/javascript/class/Makefile | 2 +- Examples/javascript/class/runme.js | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile index 180e99cae..507289ed1 100755 --- a/Examples/javascript/class/Makefile +++ b/Examples/javascript/class/Makefile @@ -1,6 +1,6 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js index 922876fc5..50261d868 100755 --- a/Examples/javascript/class/runme.js +++ b/Examples/javascript/class/runme.js @@ -21,15 +21,10 @@ c.y = 30; s.x = -10; s.y = 5; -print("\nHere is their current position:"); -print("Circle = (" + c.x + "," + c.y + ")"); -print("Square = (" + s.x + "," + s.y + ")"); - print("\nHere is their new position:"); print("Circle = (" + c.x + "," + c.y + ")"); print("Square = (" + s.x + "," + s.y + ")"); - // ----- Call some methods ----- print("\nHere are some properties of the shapes:"); print("Circle:"); From bd752ff86b94a082235d0ff424729c7d5e043715 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:09:18 +0000 Subject: [PATCH 067/352] In example Makefiles for v8 forward to CPP target. As v8 is C++ it is not possible to build wrappers in C. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13801 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 8bf1f1498..008ae817f 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -559,10 +559,15 @@ endif # Build a javascript dynamically loadable module (C) # ---------------------------------------------------------------- +# Note: for v8 there is no C support, so forwarding to javascript_cpp +ifeq (,$(V8)) javascript: $(SRCS) $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) $(CC) -c $(CCSHARED) $(JSCFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JS_INCLUDE) $(JSLDSHARED) $(CCSHARED) $(JSCFLAGS) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) +else +javascript: $(SRCS) javascript_cpp +endif # ---------------------------------------------------------------- # Build a javascript dynamically loadable module (C++) From c3918f3f822a09b297f30ef060c9269dc97e0f39 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:09:31 +0000 Subject: [PATCH 068/352] Add string support to v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13802 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptstrings.swg | 64 +++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg index e69de29bb..6bba0436e 100644 --- a/Lib/javascript/v8/javascriptstrings.swg +++ b/Lib/javascript/v8/javascriptstrings.swg @@ -0,0 +1,64 @@ + +/* ------------------------------------------------------------ + * utility methods for char strings + * ------------------------------------------------------------ */ +%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERN int +SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, int *alloc) +{ + if(valRef->IsString()) { + v8::Handle js_str = valRef->toString(); + + size_t len = js_str->Utf8Length(); + size_t abs_len = js_str->Length(); + char* cstr = new char[len]; + js_str->WriteUtf8(cstr, len); + JSStringGetUTF8CString(js_str, cstr, len); + + if(alloc) *alloc = SWIG_NEWOBJ; + if(psize) *psize = abs_len + 1; + if(cptr) *cptr = cstr; + + return SWIG_OK; + } else { + if(valRef->IsObject()) { + v8::Handle obj = valRef->ToObject(); + // try if the object is a wrapped char[] + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + return SWIG_TypeError; + } else { + return SWIG_TypeError; + } + } +} +} + +%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERNINLINE v8::Handle +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + // TODO: handle extra long strings + //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + //return pchar_descriptor ? + // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); + return v8::Undefined(); + } else { + v8::Handle js_str = v8::String::New(carray, size); + return js_str; + } + } else { + return v8::Undefined(); + } +} +} From 915e65135cdf90a484bd1078eb3cfe15f192e50e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:09:43 +0000 Subject: [PATCH 069/352] Minor fix in v8 shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13803 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Tools/javascript/v8_shell.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 62620a72a..6c84fe758 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -108,6 +108,8 @@ bool V8Shell::RunScript(const std::string& scriptPath) { context->Exit(); context.Dispose(); v8::V8::Dispose(); + + return true; } bool V8Shell::RunShell() { @@ -141,6 +143,8 @@ bool V8Shell::RunShell() { context->Exit(); context.Dispose(); v8::V8::Dispose(); + + return true; } From 58e4f9703c78052ee60f3021724bc3274f3d329a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:09:57 +0000 Subject: [PATCH 070/352] Fix handling of Char constants in JSC typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13804 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptstrings.swg | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg index f97e84cd0..f83c7533d 100644 --- a/Lib/javascript/jsc/javascriptstrings.swg +++ b/Lib/javascript/jsc/javascriptstrings.swg @@ -51,7 +51,18 @@ SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t siz // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); return JSValueMakeUndefined(context); } else { - JSStringRef jsstring = JSStringCreateWithUTF8CString(carray); + JSStringRef jsstring; + if(size < 2) { + char c[size+1]; + int i; + for(i=0;i Date: Sat, 8 Sep 2012 01:10:10 +0000 Subject: [PATCH 071/352] 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. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13805 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 37 +++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 388f037e7..b268223df 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -265,7 +265,7 @@ protected: 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 @@ protected: // which are switched on namespace change Hash *namespaces; Hash *current_namespace; + + String *defaultResultName; File *f_wrappers; @@ -595,6 +597,7 @@ JSEmitter::JSEmitter() : templates(NewHash()), namespaces(NULL), current_namespace(NULL), + defaultResultName(NewString("result")), f_wrappers(NULL) { } @@ -872,7 +875,7 @@ int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { // 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::emitSetter(Node *n, bool is_member, bool is_static) { 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 @@ int JSEmitter::emitConstant(Node *n) { 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 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { // 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::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg } } -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 @@ void JSEmitter::marshalOutput(Node *n, String *actioncode, Wrapper *wrapper) { } 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) { From 2893df9f7394ef48424f0b88e44af702a11fdd95 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:10:27 +0000 Subject: [PATCH 072/352] Several fixes in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13806 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptruntime.swg | 9 ++++++--- Source/Modules/javascript.cxx | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index e8b26892c..d94587419 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -91,14 +91,17 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in v8::HandleScope scope; v8::Local class_templ; + v8::Handle inst_templ; if(info->clientdata == NULL) { - // TODO: get class template for unknown types - //class_templ = _SwigObject_classRef; + class_templ = v8::FunctionTemplate::New(); + class_templ->SetClassName(v8::String::NewSymbol(info->name)); + inst_templ = class_templ->InstanceTemplate(); + inst_templ->SetInternalFieldCount(1); } else { class_templ = *((v8::Local*) info->clientdata); + inst_templ = class_templ->InstanceTemplate(); } - v8::Handle inst_templ = class_templ->InstanceTemplate(); v8::Local result = inst_templ->NewInstance(); SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) new SWIG_PRV_DATA; diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index b268223df..e7fa8801a 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1720,6 +1720,9 @@ int V8Emitter::exitClass(Node *n) .replace(T_NAME, state.clazz(NAME)) .pretty_print(f_wrappers); } + + /* Note: this makes sure that there is a swig_type added for this class */ + SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); // emit definition of v8 class template Template t_def_class(getTemplate("jsv8_define_class_template")); @@ -1768,7 +1771,7 @@ int V8Emitter::enterVariable(Node* n) int V8Emitter::exitVariable(Node* n) { if(GetFlag(n, "ismember")) { - if(GetFlag(state.variable(), IS_STATIC)) { + if(GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem") ) { Template t_register(getTemplate("jsv8_register_static_variable")); t_register.replace(T_PARENT, state.clazz(NAME_MANGLED)) .replace(T_NAME, state.variable(NAME)) @@ -1778,7 +1781,7 @@ int V8Emitter::exitVariable(Node* n) } else { Template t_register(getTemplate("jsv8_register_member_variable")); t_register.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_NAME, state.clazz(NAME)) + .replace(T_NAME, state.variable(NAME)) .replace(T_GETTER, state.variable(GETTER)) .replace(T_SETTER, state.variable(SETTER)) .pretty_print(f_init_wrappers); @@ -1868,7 +1871,7 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar break; case Setter: if (is_member && !is_static && i == 0) { - Printv(arg, "value", 0); + Printv(arg, "info.Holder()", 0); } else { Printv(arg, "value", 0); } From a4f8e4c1c3bbcd36a771313f2516717aa113b771 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:10:42 +0000 Subject: [PATCH 073/352] Fix bug in v8 ctor emitter. This bug leaded to flaky crashes of v8 engine. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13807 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 5 ++++- Lib/javascript/v8/javascriptruntime.swg | 18 +++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 2adbd1307..070ef2e2d 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -5,7 +5,8 @@ v8::Handle $jswrapper(const v8::Arguments& args) { $jslocals $jscode - return SWIG_V8_NewPointerObj(result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + SWIG_V8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + return scope.Close(self); goto fail; fail: @@ -54,10 +55,12 @@ fail: return scope.Close(v8::Undefined()); }%} +/* %fragment ("JS_mainctordefn", "templates") %{ // TODO: implement JS_mainctordefn %} +*/ %fragment ("JS_ctor_dispatch_case", "templates") %{ diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index d94587419..ce1367070 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -77,6 +77,15 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t return SWIG_OK; } +void SWIG_V8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { + SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) new SWIG_PRV_DATA; + cdata->swigCObject = ptr; + cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; + cdata->info = info; + + obj->SetInternalField(0, v8::External::New(cdata)); +} + int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { if(!valRef->IsObject()) { return SWIG_TypeError; @@ -103,14 +112,9 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in } v8::Local result = inst_templ->NewInstance(); - - SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) new SWIG_PRV_DATA; - cdata->swigCObject = ptr; - cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; - cdata->info = info; - - result->SetInternalField(0, v8::External::New(cdata)); + SWIG_V8_SetPrivateData(result, ptr, info, flags); + return scope.Close(result); } From 84e5476147cd141d1178cd25be35df6b01c5b92e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:10:57 +0000 Subject: [PATCH 074/352] Add std::string support to v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13808 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptstrings.swg | 3 +- Lib/javascript/v8/std_string.i | 68 +++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 2 deletions(-) create mode 100755 Lib/javascript/v8/std_string.i diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg index 6bba0436e..14a96c63e 100644 --- a/Lib/javascript/v8/javascriptstrings.swg +++ b/Lib/javascript/v8/javascriptstrings.swg @@ -7,13 +7,12 @@ SWIGINTERN int SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, int *alloc) { if(valRef->IsString()) { - v8::Handle js_str = valRef->toString(); + v8::Handle js_str = valRef->ToString(); size_t len = js_str->Utf8Length(); size_t abs_len = js_str->Length(); char* cstr = new char[len]; js_str->WriteUtf8(cstr, len); - JSStringGetUTF8CString(js_str, cstr, len); if(alloc) *alloc = SWIG_NEWOBJ; if(psize) *psize = abs_len + 1; diff --git a/Lib/javascript/v8/std_string.i b/Lib/javascript/v8/std_string.i new file mode 100755 index 000000000..0d6143319 --- /dev/null +++ b/Lib/javascript/v8/std_string.i @@ -0,0 +1,68 @@ +/* ----------------------------------------------------------------------------- + * std_string.i + * + * Typemaps for std::string and const std::string& + * These are mapped to a JSCore String and are passed around by value. + * + * To use non-const std::string references use the following %apply. Note + * that they are passed by value. + * %apply const std::string & {std::string &}; + * ----------------------------------------------------------------------------- */ + +%{ +#include +%} + +namespace std { + +%naturalvar string; + +class string; + +// string + +%typemap(in) string +%{ + if(!$input->IsString()) { + // TODO: Throw exception? + return NULL; + } + + size_t $1_strsize = js_str->Utf8Length(); + char* 1_cstr = new char[1_strsize]; + js_str->WriteUtf8(1_cstr, 1_strsize); + $1 = std::string($1_cstr); +%} + +%typemap(out) string %{ + $result = v8::String::New($1.c_str(), $1.size()); +%} + +%typemap(freearg) string +%{%} + +// const string & +%typemap(in) const string & +%{ + + if(!$input->IsString()) { + // TODO: Throw exception? + return NULL; + } + + size_t $1_strsize = js_str->Utf8Length(); + char* 1_cstr = new char[1_strsize]; + js_str->WriteUtf8(1_cstr, 1_strsize); + $1 = newstd::string($1_cstr); +%} + +%typemap(out) const string & %{ + $result = v8::String::New($1.c_str(), $1.size()); +%} + +%typemap(freearg) const string & //TODO: Not working: A memory leak +%{ free($1_cstr); %} + +//%typemap(typecheck) const string & = char *; + +} From 70383a1b61aacfb475f72652cf120515f11de2c1 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:11:11 +0000 Subject: [PATCH 075/352] Enable string exceptions in v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13809 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptruntime.swg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index ce1367070..3305bd6ad 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -29,8 +29,8 @@ typedef struct { %insert(runtime) %{ -void SWIG_V8_Raise(const char* type) { - // TODO: throw v8 exception +void SWIG_V8_Raise(const char* msg) { + v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); } void SWIG_V8_exception(int code, const char* msg) { From da6307a19ea5668757ab59f95e670f99bd64b61a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:11:32 +0000 Subject: [PATCH 076/352] Enable overloading ctors for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13810 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 28 +++++++++++++++++++++------- Source/Modules/javascript.cxx | 3 ++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 070ef2e2d..527efe115 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -55,16 +55,30 @@ fail: return scope.Close(v8::Undefined()); }%} -/* -%fragment ("JS_mainctordefn", "templates") -%{ - // TODO: implement JS_mainctordefn +%fragment ("JS_mainctordefn", "templates") %{ +v8::Handle $jswrapper(const v8::Arguments& args) { + v8::HandleScope scope; + + v8::TryCatch tryCatch; + // switch all cases by means of series of if-returns. + $jsdispatchcases + + // default: + if(!tryCatch.HasCaught()) + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); + +fail: + scope.Close(v8::Undefined()); +} %} -*/ %fragment ("JS_ctor_dispatch_case", "templates") -%{ - // TODO: implement JS_ctor_dispatch_case +%{if(args.Length() == $jsargcount) { + v8::Handle self = $jswrapper(args); + if(!self->IsUndefined()) { + tryCatch.Reset(); return scope.Close(self); /* reset exception and return */ + } + } %} %fragment ("JS_destructordefn", "templates") diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index e7fa8801a..a6261394f 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -837,6 +837,7 @@ int JSEmitter::emitCtor(Node *n) { String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); Template t_mainctor(getTemplate("JS_mainctordefn")); t_mainctor.replace(T_WRAPPER, wrap_name) + .replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) .pretty_print(f_wrappers); state.clazz(CTOR, wrap_name); @@ -1845,7 +1846,7 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar } // store number of arguments for argument checks - int num_args = emit_num_arguments(parms) - startIdx; + int num_args = emit_num_arguments(parms); String *argcount = NewString(""); Printf(argcount, "%d", num_args); Setattr(n, ARGCOUNT, argcount); From 68f0f859f887f7be4c61d53b37ec8989c02833b9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:11:51 +0000 Subject: [PATCH 077/352] Fix name collision in generated v8 initializer. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13811 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 527efe115..497392780 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -94,16 +94,16 @@ fail: SWIGTYPE_$jsmangledtype->clientdata = &$jsmangledname_class;%} %fragment("jsv8_create_class_instance", "templates") -%{v8::Handle $jsmangledname = $jsmangledname_class->GetFunction();%} +%{v8::Handle $jsmangledname_obj = $jsmangledname_class->GetFunction();%} %fragment("jsv8_inherit", "templates") %{$jsmangledname_class->Inherit($jsbaseclass_class);%} %fragment("jsv8_register_class", "templates") -%{$jsparent->Set(v8::String::NewSymbol("$jsname"), $jsmangledname);%} +%{$jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj);%} %fragment("jsv8_create_namespace", "templates") -%{v8::Handle $jsmangledname = v8::Object::New();%} +%{v8::Handle $jsmangledname_obj = v8::Object::New();%} %fragment("jsv8_register_member_function", "templates") %{SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper);%} @@ -112,13 +112,13 @@ fail: %{SWIGV8_AddMemberVariable($jsmangledname_class, "$jsname", $jsgetter, $jssetter);%} %fragment("jsv8_register_static_function", "templates") -%{SWIGV8_AddStaticFunction($jsparent, "$jsname", $jswrapper);%} +%{SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper);%} %fragment("jsv8_register_static_variable", "templates") -%{SWIGV8_AddStaticVariable($jsparent, "$jsname", $jsgetter, $jssetter);%} +%{SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter);%} %fragment("jsv8_register_namespace", "templates") -%{$jsparent->Set(v8::String::NewSymbol("$jsname"), $jsmangledname);%} +%{$jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj);%} %fragment("JS_initializer", "templates") %{ @@ -129,7 +129,7 @@ void $jsname_initialize(v8::Handle context) SWIG_InitializeModule(0); v8::HandleScope scope; - v8::Local global = context->Global(); + v8::Local global_obj = context->Global(); /* create objects for namespaces */ $jsv8nspaces From d13289cc918061b9ffea6aeb9fe1dba9990727e5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:12:18 +0000 Subject: [PATCH 078/352] Fix function dispatching for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13812 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptcode.swg | 23 ++++-- Lib/javascript/v8/javascriptcode.swg | 99 ++++++++++++++++++------- Lib/javascript/v8/javascriptruntime.swg | 55 ++++++++++---- Source/Modules/javascript.cxx | 43 +++++++---- 4 files changed, 160 insertions(+), 60 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 7f425c44a..4a83b87d2 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -64,6 +64,24 @@ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef th } %} +%fragment ("JS_function_dispatcher", "templates") +%{ +JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + JSValueRef jsresult; + int res; + $jscode + + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + %fragment ("JS_functionwrapper_overload", "templates") %{ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* result) @@ -96,11 +114,6 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec } %} -%fragment ("JS_function_dispatch_case_default", "templates") -%{ - SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); -%} - /* Added template for function declaration */ %fragment ("JS_variabledecl", "templates") diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 497392780..b7b2c195f 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -19,7 +19,38 @@ v8::Handle $jsctor(const v8::Arguments& args) { v8::HandleScope scope; SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); return scope.Close(v8::Undefined()); -}%} +} +%} + +%fragment ("JS_mainctordefn", "templates") %{ +v8::Handle $jswrapper(const v8::Arguments& args) { + v8::HandleScope scope; + + // switch all cases by means of series of if-returns. + $jsdispatchcases + + // default: + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); + +fail: + scope.Close(v8::Undefined()); +} +%} + +%fragment ("JS_ctor_dispatch_case", "templates") +%{if(args.Length() == $jsargcount) { + v8::Handle self = $jswrapper(args); + if(!self->IsUndefined()) { + return scope.Close(self); + } + } +%} + +%fragment ("JS_destructordefn", "templates") +%{ + // TODO: implement JS_destructordefn +%} + %fragment("JS_getproperty", "templates") %{ v8::Handle $jsgetter(v8::Local property, const v8::AccessorInfo& info) { @@ -53,37 +84,55 @@ v8::Handle $jswrapper(const v8::Arguments &args) { goto fail; fail: return scope.Close(v8::Undefined()); -}%} - -%fragment ("JS_mainctordefn", "templates") %{ -v8::Handle $jswrapper(const v8::Arguments& args) { - v8::HandleScope scope; - - v8::TryCatch tryCatch; - // switch all cases by means of series of if-returns. - $jsdispatchcases - - // default: - if(!tryCatch.HasCaught()) - SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); - -fail: - scope.Close(v8::Undefined()); } %} -%fragment ("JS_ctor_dispatch_case", "templates") -%{if(args.Length() == $jsargcount) { - v8::Handle self = $jswrapper(args); - if(!self->IsUndefined()) { - tryCatch.Reset(); return scope.Close(self); /* reset exception and return */ - } +%fragment("JS_function_dispatcher", "templates") %{ +v8::Handle $jswrapper(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle jsresult; + OverloadErrorHandler errorHandler; + $jscode + + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); + + goto fail; +fail: + return scope.Close(v8::Undefined()); +} +%} + +%fragment ("JS_functionwrapper_overload", "templates") +%{ +v8::Handle $jswrapper(const v8::Arguments &args, V8ErrorHandler& SWIGV8_ErrorHandler) +{ + v8::HandleScope scope; + + v8::Handle jsresult; + $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + $jscode + return scope.Close(jsresult); + goto fail; +fail: + return scope.Close(jsresult); +} +%} + +%fragment ("JS_function_dispatch_case", "templates") +%{ + if(args.Length() == $jsargcount) { + errorHandler.err.Clear(); + jsresult = $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return scope.Close(jsresult); + } } %} -%fragment ("JS_destructordefn", "templates") +%fragment ("JS_function_dispatch_case_default", "templates") %{ - // TODO: implement JS_destructordefn + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); %} %fragment("jsv8_declare_class_template", "templates") diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 3305bd6ad..2eb9c82cc 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -14,9 +14,48 @@ %insert(runtime) "swigerrors.swg"; /* SWIG errors */ %insert(runtime) %{ -#define SWIG_Error(code, msg) SWIG_V8_exception(code, msg) -#define SWIG_exception(code, msg) SWIG_V8_exception(code, msg) +#define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) +#define SWIG_exception(code, msg) SWIGV8_ErrorHandler.error(code, msg) #define SWIG_fail goto fail +#define SWIGV8_OVERLOAD false + +void SWIG_V8_Raise(const char* msg) { + v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); +} + +/* + Note: There are two contexts for handling errors. + A static V8ErrorHandler is used in not overloaded methods. + For overloaded methods the throwing type checking mechanism is used + during dispatching. As V8 exceptions can not be resetted properly + the trick is to use a dynamic ErrorHandler with same local name as the global + one. + + - See defintion of SWIG_Error above. + - See code templates 'JS_function_dispatcher', 'JS_functionwrapper_overload', + and 'JS_function_dispatch_case' in javascriptcode.swg + +*/ +class V8ErrorHandler { +public: + virtual void error(int code, const char* msg) { + SWIG_V8_Raise(msg); + } +}; +// this is used in usually +V8ErrorHandler SWIGV8_ErrorHandler; + +// instances of this are used in overloaded functions +class OverloadErrorHandler: public V8ErrorHandler { +public: + virtual void error(int code, const char* msg) { + err = v8::Exception::Error(v8::String::New(msg)); + if(code != SWIG_TypeError) { + v8::ThrowException(err); + } + } + v8::Handle err; +}; %} %insert(runtime) %{ @@ -27,18 +66,6 @@ typedef struct { } SWIG_PRV_DATA; %} -%insert(runtime) %{ - -void SWIG_V8_Raise(const char* msg) { - v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); -} - -void SWIG_V8_exception(int code, const char* msg) { - SWIG_V8_Raise(msg); -} - -%} - %insert(runtime) %{ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index a6261394f..5f3e01a42 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -766,6 +766,12 @@ int JSEmitter::enterFunction(Node *n) { if(Equal(Getattr(n, "storage"), "static")) { SetFlag(state.function(), IS_STATIC); } + + /* Initialize DOH for collecting function dispatchers */ + bool is_overloaded = GetFlag(n, "sym:overloaded"); + if (is_overloaded && state.global(FUNCTION_DISPATCHERS) == 0) { + state.global(FUNCTION_DISPATCHERS, NewString("")); + } return SWIG_OK; } @@ -1012,16 +1018,13 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { - Template t_function(getTemplate("JS_functionwrapper")); + Template t_function(getTemplate("JS_function_dispatcher")); Wrapper *wrapper = NewWrapper(); String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); Setattr(n, "wrap:name", wrap_name); - Wrapper_add_local(wrapper, "res", "int res"); - Append(wrapper->code, state.global(FUNCTION_DISPATCHERS)); - Append(wrapper->code, getTemplate("JS_function_dispatch_case_default").str()); t_function.replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code); @@ -1365,12 +1368,6 @@ int JSCEmitter::enterFunction(Node *n) { JSEmitter::enterFunction(n); - /* Initialize DOH for collecting function dispatchers */ - bool is_overloaded = GetFlag(n, "sym:overloaded"); - if (is_overloaded && state.global(FUNCTION_DISPATCHERS) == 0) { - state.global(FUNCTION_DISPATCHERS, NewString("")); - } - return SWIG_OK; } @@ -1808,20 +1805,34 @@ int V8Emitter::enterFunction(Node* n) } int V8Emitter::exitFunction(Node* n) -{ +{ + bool is_member = GetFlag(n, "ismember"); + + // create a dispatcher for overloaded functions + bool is_overloaded = GetFlag(n, "sym:overloaded"); + if (is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); + emitFunctionDispatcher(n, is_member); + } else { + //don't register wrappers of overloaded functions in function tables + return SWIG_OK; + } + } + // register the function at the specific context - if(GetFlag(n, "ismember")) { + if(is_member) { if(GetFlag(state.function(), IS_STATIC)) { 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, Getattr(n, "wrap:name")) + .replace(T_WRAPPER, state.function(WRAPPER_NAME)) .pretty_print(f_init_static_wrappers); } else { 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, Getattr(n, "wrap:name")) + .replace(T_WRAPPER, state.function(WRAPPER_NAME)) .pretty_print(f_init_wrappers); } } else { @@ -1830,8 +1841,8 @@ int V8Emitter::exitFunction(Node* n) 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, Getattr(n, "wrap:name")) - .pretty_print(f_init_wrappers); + .replace(T_WRAPPER, state.function(WRAPPER_NAME)) + .pretty_print(f_init_static_wrappers); } return SWIG_OK; From 843c8a408cb76e22efc10ede577f17e2e5b7deb2 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:12:33 +0000 Subject: [PATCH 079/352] Fix AsVal macros of long and int for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13813 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptprimitives.swg | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Lib/javascript/v8/javascriptprimitives.swg b/Lib/javascript/v8/javascriptprimitives.swg index d3dba485d..bd0295478 100644 --- a/Lib/javascript/v8/javascriptprimitives.swg +++ b/Lib/javascript/v8/javascriptprimitives.swg @@ -29,11 +29,25 @@ v8::Handle SWIG_From_dec(int)(int value) } } +%fragment(SWIG_AsVal_frag(int),"header") { +SWIGINTERN +int SWIG_AsVal_dec(int)(v8::Handle valRef, int* val) +{ + if (!valRef->IsInt32()) { + return SWIG_TypeError; + } + if(val) *val = valRef->IntegerValue(); + + return SWIG_OK; +} +} + + %fragment(SWIG_From_frag(long),"header") { SWIGINTERNINLINE v8::Handle SWIG_From_dec(long)(long value) { - return v8::Integer::New(value); + return v8::Number::New(value); } } From a82e0a6e8f7ba258f29de6f8680e406a8b102ae5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:12:46 +0000 Subject: [PATCH 080/352] Fix c++ linking problem in example 'variables'. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13814 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/javascript/variables/example.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Examples/javascript/variables/example.c b/Examples/javascript/variables/example.c index aa4ffe9b3..3ad4c2323 100755 --- a/Examples/javascript/variables/example.c +++ b/Examples/javascript/variables/example.c @@ -23,7 +23,12 @@ char cvar = 0; float fvar = 0; double dvar = 0; char *strvar = 0; -const char cstrvar[] = "Goodbye"; +#ifdef __cplusplus // Note: for v8 this must be linkable with g++, without extern cstrvar is mangled +extern const char cstrvar[] = "Goodbye"; +#else +const char cstrvar[] = "Goodbye"; +#endif +const int *iptrvar = 0; char name[256] = "Dave"; char path[256] = "/home/beazley"; From 91fc0ff205f6f6679a0cb51716adc91a21524929 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:13:03 +0000 Subject: [PATCH 081/352] Use a throwing default setter in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13815 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascripthelpers.swg | 16 ++++++++++++++++ Source/Modules/javascript.cxx | 8 ++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index 5de11feb3..9a80a6552 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -43,4 +43,20 @@ void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, v8 obj->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } +void JS_veto_set_variable(v8::Local property, v8::Local value, const v8::AccessorInfo& info) +{ + char buffer[256]; + char msg[512]; + int res; + + property->WriteUtf8(buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } +} + %} // v8_helper_functions diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 5f3e01a42..28c4b96b7 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1591,12 +1591,15 @@ private: String* GLOBAL; String* NULL_STR; + String *VETO_SET; + }; V8Emitter::V8Emitter() : JSEmitter(), GLOBAL(NewString("global")), - NULL_STR(NewString("0")) + NULL_STR(NewString("0")), + VETO_SET(NewString("JS_veto_set_variable")) { } @@ -1604,6 +1607,7 @@ V8Emitter::~V8Emitter() { Delete(GLOBAL); Delete(NULL_STR); + Delete(VETO_SET); } int V8Emitter::initialize(Node *n) @@ -1761,7 +1765,7 @@ int V8Emitter::enterVariable(Node* n) JSEmitter::enterVariable(n); state.variable(GETTER, NULL_STR); - state.variable(SETTER, NULL_STR); + state.variable(SETTER, VETO_SET); return SWIG_OK; } From da109ee764b0c48f93554f4cc093997fe530ec28 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:13:17 +0000 Subject: [PATCH 082/352] Fix input string handling in v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13816 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptstrings.swg | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg index 14a96c63e..e955bee3a 100644 --- a/Lib/javascript/v8/javascriptstrings.swg +++ b/Lib/javascript/v8/javascriptstrings.swg @@ -9,13 +9,12 @@ SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, if(valRef->IsString()) { v8::Handle js_str = valRef->ToString(); - size_t len = js_str->Utf8Length(); - size_t abs_len = js_str->Length(); + size_t len = js_str->Utf8Length() + 1; char* cstr = new char[len]; js_str->WriteUtf8(cstr, len); if(alloc) *alloc = SWIG_NEWOBJ; - if(psize) *psize = abs_len + 1; + if(psize) *psize = len; if(cptr) *cptr = cstr; return SWIG_OK; From 5425edc50894d32724b7cde8d11bce9fbd3fcdf8 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:13:29 +0000 Subject: [PATCH 083/352] Add library flag for building v8 shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13817 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 008ae817f..a6ed5157e 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -582,7 +582,7 @@ javascript_cpp: $(SRCS) # Compile a javascript executable # ---------------------------------------------------------------- javascript_exe: $(SRCS) - $(CXX) $(CXXFLAGS) $(JSEXE_FLAGS) $(JS_INCLUDE) $(LIBS) $(JSEXE_SRC) $(JS_DLNK) -o $(JSEXE) + $(CXX) $(CXXFLAGS) $(JSEXE_FLAGS) $(JS_INCLUDE) $(LIBS) $(JSEXE_SRC) $(JS_DLNK) -ldl -o $(JSEXE) # ---------------------------------------------------------------- # Run the Compile a javascript executable From 8db76ddee10085765c41be3c5829ec0cce1e0933 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:13:42 +0000 Subject: [PATCH 084/352] Remove generated file from repository. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13818 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/javascript/variables/example_wrap.c | 2593 ------------------ 1 file changed, 2593 deletions(-) delete mode 100644 Examples/javascript/variables/example_wrap.c diff --git a/Examples/javascript/variables/example_wrap.c b/Examples/javascript/variables/example_wrap.c deleted file mode 100644 index 7fc9567cd..000000000 --- a/Examples/javascript/variables/example_wrap.c +++ /dev/null @@ -1,2593 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 2.0.6 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# elif defined(__HP_aCC) -/* Needed even with `aCC -AA' when `aCC -V' reports HP ANSI C++ B3910B A.03.55 */ -/* If we find a maximum version that requires this, the test would be __HP_aCC <= 35500 for A.03.55 */ -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIG_MSC_UNSUPPRESS_4505 -# if defined(_MSC_VER) -# pragma warning(disable : 4505) /* unreferenced local function has been removed */ -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* exporting methods */ -#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - -/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ -#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) -# define _SCL_SECURE_NO_DEPRECATE -#endif - - - -#define SWIG_AsCharPtrAndSize(val, cptr, psize, alloc) SWIG_JSC_AsCharPtrAndSize(context, val, cptr, psize, alloc) -#define SWIG_FromCharPtrAndSize(cptr, size) SWIG_JSC_FromCharPtrAndSize(context, cptr, size) -#define SWIG_FromCharPtr(cptr) SWIG_JSC_FromCharPtr(context, cptr) - - - -#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) - -#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else - - - -#include -#include -#include -#include -#include -#include - -/* ----------------------------------------------------------------------------- - * swigrun.swg - * - * This file contains generic C API SWIG runtime support for pointer - * type checking. - * ----------------------------------------------------------------------------- */ - -/* This should only be incremented when either the layout of swig_type_info changes, - or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "4" - -/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ -#ifdef SWIG_TYPE_TABLE -# define SWIG_QUOTE_STRING(x) #x -# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) -# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) -#else -# define SWIG_TYPE_TABLE_NAME -#endif - -/* - You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the SWIG runtime code. - In 99.9% of the cases, SWIG just needs to declare them as 'static'. - - But only do this if strictly necessary, ie, if you have problems - with your compiler or suchlike. -*/ - -#ifndef SWIGRUNTIME -# define SWIGRUNTIME SWIGINTERN -#endif - -#ifndef SWIGRUNTIMEINLINE -# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -/* Generic buffer size */ -#ifndef SWIG_BUFFER_SIZE -# define SWIG_BUFFER_SIZE 1024 -#endif - -/* Flags for pointer conversions */ -#define SWIG_POINTER_DISOWN 0x1 -#define SWIG_CAST_NEW_MEMORY 0x2 - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The SWIG conversion methods, as ConvertPtr, return an integer - that tells if the conversion was successful or not. And if not, - an error code can be returned (see swigerrors.swg for the codes). - - Use the following macros/flags to set or process the returning - states. - - In old versions of SWIG, code such as the following was usually written: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - which is the same really, but now you can also do - - Type *ptr; - int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); - if (SWIG_IsOK(res)) { - // success code - if (SWIG_IsNewObj(res) { - ... - delete *ptr; - } else { - ... - } - } else { - // fail code - } - - I.e., now SWIG_ConvertPtr can return new objects and you can - identify the case and take care of the deallocation. Of course that - also requires SWIG_ConvertPtr to return new result values, such as - - int SWIG_ConvertPtr(obj, ptr,...) { - if () { - if () { - *ptr = ; - return SWIG_NEWOBJ; - } else { - *ptr = ; - return SWIG_OLDOBJ; - } - } else { - return SWIG_BADOBJ; - } - } - - Of course, returning the plain '0(success)/-1(fail)' still works, but you can be - more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - SWIG errors code. - - Finally, if the SWIG_CASTRANK_MODE is enabled, the result code - allows to return the 'cast rank', for example, if you have this - - int food(double) - int fooi(int); - - and you call - - food(1) // cast rank '1' (1 -> 1.0) - fooi(1) // cast rank '0' - - just use the SWIG_AddCast()/SWIG_CheckState() -*/ - -#define SWIG_OK (0) -#define SWIG_ERROR (-1) -#define SWIG_IsOK(r) (r >= 0) -#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) - -/* The CastRankLimit says how many bits are used for the cast rank */ -#define SWIG_CASTRANKLIMIT (1 << 8) -/* The NewMask denotes the object was created (using new/malloc) */ -#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) -/* The TmpMask is for in/out typemaps that use temporal objects */ -#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) -/* Simple returning values */ -#define SWIG_BADOBJ (SWIG_ERROR) -#define SWIG_OLDOBJ (SWIG_OK) -#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) -#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) -/* Check, add and del mask methods */ -#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) -#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) -#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) -#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) -#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) -#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - -/* Cast-Rank Mode */ -#if defined(SWIG_CASTRANK_MODE) -# ifndef SWIG_TypeRank -# define SWIG_TypeRank unsigned long -# endif -# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ -# define SWIG_MAXCASTRANK (2) -# endif -# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) -# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) -SWIGINTERNINLINE int SWIG_AddCast(int r) { - return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; -} -SWIGINTERNINLINE int SWIG_CheckState(int r) { - return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; -} -#else /* no cast-rank mode */ -# define SWIG_AddCast -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *, int *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store information on one type */ -typedef struct swig_type_info { - const char *name; /* mangled name of this type */ - const char *str; /* human readable name of this type */ - swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ - struct swig_cast_info *cast; /* linked list of types that can cast into this type */ - void *clientdata; /* language specific type data */ - int owndata; /* flag if the structure owns the clientdata */ -} swig_type_info; - -/* Structure to store a type and conversion function used for casting */ -typedef struct swig_cast_info { - swig_type_info *type; /* pointer to type that is equivalent to this type */ - swig_converter_func converter; /* function to cast the void pointers */ - struct swig_cast_info *next; /* pointer to next cast in linked list */ - struct swig_cast_info *prev; /* pointer to the previous cast */ -} swig_cast_info; - -/* Structure used to store module information - * Each module generates one structure like this, and the runtime collects - * all of these structures and stores them in a circularly linked list.*/ -typedef struct swig_module_info { - swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ - size_t size; /* Number of types in this module */ - struct swig_module_info *next; /* Pointer to next element in circularly linked list */ - swig_type_info **type_initial; /* Array of initially generated type structures */ - swig_cast_info **cast_initial; /* Array of initially generated casting structures */ - void *clientdata; /* Language specific module data */ -} swig_module_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -SWIGRUNTIME int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; - } - return (int)((l1 - f1) - (l2 - f2)); -} - -/* - Check type equivalence in a name list like ||... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like ||... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCompare(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - if (ty) { - swig_cast_info *iter = ty->cast; - while (iter) { - if (strcmp(iter->type->name, c) == 0) { - if (iter == ty->cast) - return iter; - /* Move iter to the top of the linked list */ - iter->prev->next = iter->next; - if (iter->next) - iter->next->prev = iter->prev; - iter->next = ty->cast; - iter->prev = 0; - if (ty->cast) ty->cast->prev = iter; - ty->cast = iter; - return iter; - } - iter = iter->next; - } - } - return 0; -} - -/* - Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) { - if (ty) { - swig_cast_info *iter = ty->cast; - while (iter) { - if (iter->type == from) { - if (iter == ty->cast) - return iter; - /* Move iter to the top of the linked list */ - iter->prev->next = iter->next; - if (iter->next) - iter->next->prev = iter->prev; - iter->next = ty->cast; - iter->prev = 0; - if (ty->cast) ty->cast->prev = iter; - ty->cast = iter; - return iter; - } - iter = iter->next; - } - } - return 0; -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr, int *newmemory) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr, newmemory); -} - -/* - Dynamic pointer casting. Down an inheritance hierarchy -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { - swig_type_info *lastty = ty; - if (!ty || !ty->dcast) return ty; - while (ty && (ty->dcast)) { - ty = (*ty->dcast)(ptr); - if (ty) lastty = ty; - } - return lastty; -} - -/* - Return the name associated with this type -*/ -SWIGRUNTIMEINLINE const char * -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Return the pretty name associated with this type, - that is an unmangled type name in a form presentable to the user. -*/ -SWIGRUNTIME const char * -SWIG_TypePrettyName(const swig_type_info *type) { - /* The "str" field contains the equivalent pretty names of the - type, separated by vertical-bar characters. We choose - to print the last name, as it is often (?) the most - specific. */ - if (!type) return NULL; - if (type->str != NULL) { - const char *last_name = type->str; - const char *s; - for (s = type->str; *s; s++) - if (*s == '|') last_name = s+1; - return last_name; - } - else - return type->name; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_cast_info *cast = ti->cast; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - - while (cast) { - if (!cast->converter) { - swig_type_info *tc = cast->type; - if (!tc->clientdata) { - SWIG_TypeClientData(tc, clientdata); - } - } - cast = cast->next; - } -} -SWIGRUNTIME void -SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { - SWIG_TypeClientData(ti, clientdata); - ti->owndata = 1; -} - -/* - Search for a swig_type_info structure only by mangled name - Search is a O(log #types) - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_MangledTypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - swig_module_info *iter = start; - do { - if (iter->size) { - register size_t l = 0; - register size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - register size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - register int compare = strcmp(name, iname); - if (compare == 0) { - return iter->types[i]; - } else if (compare < 0) { - if (i) { - r = i - 1; - } else { - break; - } - } else if (compare > 0) { - l = i + 1; - } - } else { - break; /* should never happen */ - } - } while (l <= r); - } - iter = iter->next; - } while (iter != end); - return 0; -} - -/* - Search for a swig_type_info structure for either a mangled name or a human readable name. - It first searches the mangled names of the types, which is a O(log #types) - If a type is not found it then searches the human readable names, which is O(#types). - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - /* STEP 1: Search the name field using binary search */ - swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); - if (ret) { - return ret; - } else { - /* STEP 2: If the type hasn't been found, do a complete search - of the str field (the human readable name) */ - swig_module_info *iter = start; - do { - register size_t i = 0; - for (; i < iter->size; ++i) { - if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) - return iter->types[i]; - } - iter = iter->next; - } while (iter != end); - } - - /* neither found a match */ - return 0; -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - register const unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* - Unpack binary data from a string -*/ -SWIGRUNTIME const char * -SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - register unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register char d = *(c++); - register unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = ((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = ((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} - -/* - Pack 'void *' into a string buffer. -*/ -SWIGRUNTIME char * -SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { - char *r = buff; - if ((2*sizeof(void *) + 2) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - if (strlen(name) + 1 > (bsz - (r - buff))) return 0; - strcpy(r,name); - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - *ptr = (void *) 0; - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sizeof(void *)); -} - -SWIGRUNTIME char * -SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { - char *r = buff; - size_t lname = (name ? strlen(name) : 0); - if ((2*sz + 2 + lname) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,ptr,sz); - if (lname) { - strncpy(r,name,lname+1); - } else { - *r = 0; - } - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - memset(ptr,0,sz); - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sz); -} - -#ifdef __cplusplus -} -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -#define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) -#define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) -#define SWIG_fail goto fail - -#define SWIG_JSC_FROM_DECL_ARGS(arg1) (JSContextRef context, arg1) -#define SWIG_JSC_FROM_CALL_ARGS(arg1) (context, arg1) -#define SWIG_JSC_AS_DECL_ARGS(arg1, arg2) (JSContextRef context, arg1, arg2) -#define SWIG_JSC_AS_CALL_ARGS(arg1, arg2) (context, arg1, arg2) - - -typedef struct { - bool swigCMemOwn; - void *swigCObject; - swig_type_info *info; -}SWIG_PRV_DATA; - - - -void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) { - JSStringRef message = JSStringCreateWithUTF8CString(type); - *exception = JSValueMakeString(context, message); - JSStringRelease(message); -} - -void SWIG_JSC_exception(JSContextRef context, JSValueRef *exception, int code, const char* msg) { - SWIG_Javascript_Raise(context, exception, msg); -} - - - - -JSValueRef _wrap_SwigObject_disown(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - JSValueRef jsresult; - - JSObjectRef obj = JSValueToObject(context, thisObject, NULL); - SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) JSObjectGetPrivate(obj); - - cdata->swigCMemOwn = false; - - jsresult = JSValueMakeUndefined(context); - return jsresult; -} - -JSValueRef _wrap_SwigObject_getCPtr(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - JSValueRef jsresult; - long result; - - JSObjectRef obj = JSValueToObject(context, thisObject, NULL); - SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA*) JSObjectGetPrivate(obj); - - result = (long) cdata->swigCObject; - jsresult = JSValueMakeNumber(context, result); - - return jsresult; -} - -JSStaticValue _SwigObject_values[] = { - { - 0, 0, 0, 0 - } -}; - -JSStaticFunction _SwigObject_functions[] = { - { - "disown",_wrap_SwigObject_disown, kJSPropertyAttributeNone - },{ - "getCPtr",_wrap_SwigObject_getCPtr, kJSPropertyAttributeNone - }, - { - 0, 0, 0 - } -}; - -JSClassDefinition _SwigObject_objectDefinition; - -JSClassRef _SwigObject_classRef; - - - -int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef objRef, void** ptr, swig_type_info *info, int flags) { - SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) JSObjectGetPrivate(objRef); - if(cdata == NULL) { - return SWIG_ERROR; - } - if(cdata->info != info) { - bool type_valid = false; - swig_cast_info *t = info->cast; - while(t != NULL) { - if(t->type == cdata->info) { - type_valid = true; - break; - } - t = t->next; - } - if(!type_valid) { - return SWIG_TypeError; - } - } - - *ptr = cdata->swigCObject; - - if(flags & SWIG_POINTER_DISOWN) { - cdata->swigCMemOwn = false; - } - - return SWIG_OK; -} - -int SWIG_JSC_ConvertPtr(JSContextRef context, JSValueRef valRef, void** ptr, swig_type_info *info, int flags) { - if(!JSValueIsObject(context, valRef)) { - return SWIG_TypeError; - } - - JSObjectRef objRef = JSValueToObject(context, valRef, NULL); - if(objRef == NULL) { - return SWIG_ERROR; - } - - return SWIG_JSC_ConvertInstancePtr(context, objRef, ptr, info, flags); -} - -JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_info *info, int flags) { - - JSClassRef classRef; - if(info->clientdata == NULL) { - classRef = _SwigObject_classRef; - } else { - classRef = (JSClassRef) info->clientdata; - } - - JSObjectRef result = JSObjectMake(context, classRef, NULL); - - SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) malloc(sizeof(SWIG_PRV_DATA)); - cdata->swigCObject = ptr; - cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; - cdata->info = info; - - JSObjectSetPrivate(result, cdata); - - return result; -} - -#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_JSC_ConvertPtr(context, obj, ptr, info, flags) -#define SWIG_NewPointerObj(ptr, info, flags) SWIG_JSC_NewPointerObj(context, ptr, info, flags) - -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) -#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_Point swig_types[0] -#define SWIGTYPE_p_char swig_types[1] -#define SWIGTYPE_p_int swig_types[2] -static swig_type_info *swig_types[4]; -static swig_module_info swig_module = {swig_types, 3, 0, 0, 0, 0}; -#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) -#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) - -/* -------- TYPES TABLE (END) -------- */ - - - -#define SWIGVERSION 0x020006 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - -#include "example.h" - - -extern int ivar; -extern short svar; -extern long lvar; -extern unsigned int uivar; -extern unsigned short usvar; -extern unsigned long ulvar; -extern signed char scvar; -extern unsigned char ucvar; -extern char cvar; -extern float fvar; -extern double dvar; -extern char *strvar; -extern const char cstrvar[]; -extern int *iptrvar; -extern char name[256]; - -extern Point *ptptr; -extern Point pt; - - -#include -#if !defined(SWIG_NO_LLONG_MAX) -# if !defined(LLONG_MAX) && defined(__GNUC__) && defined (__LONG_LONG_MAX__) -# define LLONG_MAX __LONG_LONG_MAX__ -# define LLONG_MIN (-LLONG_MAX - 1LL) -# define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) -# endif -#endif - - -SWIGINTERN int -SWIG_AsVal_double SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, double *val) -{ - if(!JSValueIsNumber(context, obj)) { - return SWIG_TypeError; - } - if(val) *val = JSValueToNumber(context, obj, NULL); - - return SWIG_OK; -} - - -#include - - -#include - - -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} - - -SWIGINTERN int -SWIG_AsVal_long SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, long* val) -{ - if (!JSValueIsNumber(context, obj)) { - return SWIG_TypeError; - } - if(val) *val = (long) JSValueToNumber(context, obj, NULL); - - return SWIG_OK; -} - - -SWIGINTERN int -SWIG_AsVal_int SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, int *val) -{ - long v; - int res = SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (int)(v); - } - } - return res; -} - - -SWIGINTERNINLINE JSValueRef - SWIG_From_int SWIG_JSC_FROM_DECL_ARGS(int value) -{ - return JSValueMakeNumber(context, value); -} - - -SWIGINTERN int -SWIG_AsVal_short SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, short *val) -{ - long v; - int res = SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(obj, &v); - if (SWIG_IsOK(res)) { - if ((v < SHRT_MIN || v > SHRT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (short)(v); - } - } - return res; -} - - -SWIGINTERNINLINE JSValueRef - SWIG_From_long SWIG_JSC_FROM_DECL_ARGS(long value) -{ - return JSValueMakeNumber(context, value); -} - - -SWIGINTERNINLINE JSValueRef -SWIG_From_short SWIG_JSC_FROM_DECL_ARGS(short value) -{ - return SWIG_From_long SWIG_JSC_FROM_CALL_ARGS(value); -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, unsigned long *val) -{ - if(!JSValueIsNumber(context, obj)) { - return SWIG_TypeError; - } - - long longVal = (long) JSValueToNumber(context, obj, NULL); - - if(longVal < 0) { - return SWIG_OverflowError; - } - - if(val) *val = longVal; - - return SWIG_OK; -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_int SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, unsigned int *val) -{ - unsigned long v; - int res = SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_CALL_ARGS(obj, &v); - if (SWIG_IsOK(res)) { - if ((v > UINT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (unsigned int)(v); - } - } - return res; -} - - -SWIGINTERNINLINE JSValueRef -SWIG_From_unsigned_SS_long SWIG_JSC_FROM_DECL_ARGS(unsigned long value) -{ - return (value > LONG_MAX) ? - JSValueMakeNumber(context, value) : JSValueMakeNumber(context, (long)(value)); -} - - -SWIGINTERNINLINE JSValueRef -SWIG_From_unsigned_SS_int SWIG_JSC_FROM_DECL_ARGS(unsigned int value) -{ - return SWIG_From_unsigned_SS_long SWIG_JSC_FROM_CALL_ARGS(value); -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_short SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, unsigned short *val) -{ - unsigned long v; - int res = SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_CALL_ARGS(obj, &v); - if (SWIG_IsOK(res)) { - if ((v > USHRT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (unsigned short)(v); - } - } - return res; -} - - -SWIGINTERNINLINE JSValueRef -SWIG_From_unsigned_SS_short SWIG_JSC_FROM_DECL_ARGS(unsigned short value) -{ - return SWIG_From_unsigned_SS_long SWIG_JSC_FROM_CALL_ARGS(value); -} - - -SWIGINTERN int -SWIG_AsVal_signed_SS_char SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, signed char *val) -{ - long v; - int res = SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(obj, &v); - if (SWIG_IsOK(res)) { - if ((v < SCHAR_MIN || v > SCHAR_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (signed char)(v); - } - } - return res; -} - - -SWIGINTERNINLINE JSValueRef -SWIG_From_signed_SS_char SWIG_JSC_FROM_DECL_ARGS(signed char value) -{ - return SWIG_From_long SWIG_JSC_FROM_CALL_ARGS(value); -} - - -SWIGINTERN int -SWIG_AsVal_unsigned_SS_char SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, unsigned char *val) -{ - unsigned long v; - int res = SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_CALL_ARGS(obj, &v); - if (SWIG_IsOK(res)) { - if ((v > UCHAR_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (unsigned char)(v); - } - } - return res; -} - - -SWIGINTERNINLINE JSValueRef -SWIG_From_unsigned_SS_char SWIG_JSC_FROM_DECL_ARGS(unsigned char value) -{ - return SWIG_From_unsigned_SS_long SWIG_JSC_FROM_CALL_ARGS(value); -} - - -SWIGINTERN swig_type_info* -SWIG_pchar_descriptor(void) -{ - static int init = 0; - static swig_type_info* info = 0; - if (!init) { - info = SWIG_TypeQuery("_p_char"); - init = 1; - } - return info; -} - - -SWIGINTERN int -SWIG_JSC_AsCharPtrAndSize(JSContextRef context, JSValueRef valRef, char** cptr, size_t* psize, int *alloc) -{ - if(JSValueIsString(context, valRef)) { - JSStringRef js_str = JSValueToStringCopy(context, valRef, NULL); - size_t len = JSStringGetMaximumUTF8CStringSize(js_str); - size_t abs_len = JSStringGetLength(js_str); - char* cstr = (char*) malloc(len * sizeof(char)); - JSStringGetUTF8CString(js_str, cstr, len); - - if(alloc) *alloc = SWIG_NEWOBJ; - if(psize) *psize = abs_len + 1; - if(cptr) *cptr = cstr; - - return SWIG_OK; - } else { - if(JSValueIsObject(context, valRef)) { - JSObjectRef obj = JSValueToObject(context, valRef, NULL); - // try if the object is a wrapped char[] - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - void* vptr = 0; - if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = (char *) vptr; - if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - return SWIG_TypeError; - } else { - return SWIG_TypeError; - } - } -} - - -SWIGINTERN int -SWIG_JSC_AsCharArray(JSContextRef context, JSValueRef obj, char *val, size_t size) -{ - char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ; - int res = SWIG_JSC_AsCharPtrAndSize(context, obj, &cptr, &csize, &alloc); - if (SWIG_IsOK(res)) { - if ((csize == size + 1) && cptr && !(cptr[csize-1])) --csize; - if (csize <= size) { - if (val) { - if (csize) memcpy(val, cptr, csize*sizeof(char)); - if (csize < size) memset(val + csize, 0, (size - csize)*sizeof(char)); - } - if (alloc == SWIG_NEWOBJ) { - free((char*)cptr); - res = SWIG_DelNewMask(res); - } - return res; - } - if (alloc == SWIG_NEWOBJ) free((char*)cptr); - } - return SWIG_TypeError; -} - - - - -SWIGINTERN int -SWIG_AsVal_char SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, char *val) -{ - int res = SWIG_JSC_AsCharArray(context, obj, val, 1); - if (!SWIG_IsOK(res)) { - long v; - res = SWIG_AddCast(SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(obj, &v)); - if (SWIG_IsOK(res)) { - if ((CHAR_MIN <= v) && (v <= CHAR_MAX)) { - if (val) *val = (char)(v); - } else { - res = SWIG_OverflowError; - } - } - } - return res; -} - - -SWIGINTERNINLINE JSValueRef -SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t size) -{ - if (carray) { - if (size > INT_MAX) { - // TODO: handle extra long strings - //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - //return pchar_descriptor ? - // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); - return JSValueMakeUndefined(context); - } else { - JSStringRef jsstring = JSStringCreateWithUTF8CString(carray); - JSValueRef result = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); - return result; - } - } else { - return JSValueMakeUndefined(context); - } -} - - -SWIGINTERNINLINE JSValueRef -SWIG_From_char SWIG_JSC_FROM_DECL_ARGS(char c) -{ - return SWIG_JSC_FromCharPtrAndSize(context, &c,1); -} - - -SWIGINTERN int -SWIG_AsVal_float SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, float *val) -{ - double v; - int res = SWIG_AsVal_double SWIG_JSC_AS_CALL_ARGS(obj, &v); - if (SWIG_IsOK(res)) { - if ((v < -FLT_MAX || v > FLT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (float)(v); - } - } - return res; -} - - -SWIGINTERN JSValueRef -SWIG_From_double SWIG_JSC_FROM_DECL_ARGS (double val) -{ - return JSValueMakeNumber(context, val); -} - - -SWIGINTERNINLINE JSValueRef -SWIG_From_float SWIG_JSC_FROM_DECL_ARGS(float value) -{ - return SWIG_From_double SWIG_JSC_FROM_CALL_ARGS(value); -} - - - - - -SWIGINTERNINLINE JSValueRef -SWIG_JSC_FromCharPtr(JSContextRef context, const char *cptr) -{ - return SWIG_JSC_FromCharPtrAndSize(context, cptr, (cptr ? strlen(cptr) : 0)); -} - - -extern int status; -extern char path[256]; - - -extern void print_vars(); -extern int *new_int(int value); -extern Point *new_Point(int x, int y); -extern char *Point_print(Point *p); -extern void pt_print(); - - - - -bool JS_registerClass(JSGlobalContextRef context, JSObjectRef parentObject, - const char* className, - JSClassDefinition* definition) { - - JSStringRef js_className = JSStringCreateWithUTF8CString(className); - JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); - JSObjectSetProperty(context, parentObject, - js_className, classObject, - kJSPropertyAttributeNone, NULL); - JSStringRelease(js_className); - - return true; -} - -bool JS_registerNamespace(JSGlobalContextRef context, - JSObjectRef namespaceObj, JSObjectRef parentNamespace, - const char* name) -{ - JSStringRef js_name = JSStringCreateWithUTF8CString(name); - JSObjectSetProperty(context, parentNamespace, - js_name, namespaceObj, - kJSPropertyAttributeNone, NULL); - JSStringRelease(js_name); - - return true; -} - - -bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, - const char* functionName, JSObjectCallAsFunctionCallback callback) -{ - JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); - JSObjectSetProperty(context, object, js_functionName, - JSObjectMakeFunctionWithCallback(context, js_functionName, callback), - kJSPropertyAttributeNone, NULL); - JSStringRelease(js_functionName); - return true; -} - -bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - char buffer[256]; - char msg[512]; - int res; - - JSStringGetUTF8CString(propertyName, buffer, 256); - res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); - - if(res<0) { - SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); - } else { - SWIG_exception(SWIG_ERROR, msg); - } - - return false; -} - -JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { - JSValueRef val; - - JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); - val = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); - - return val; -} - - -bool _wrap_ivar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - int arg1 ; - int val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_int SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ivar_set" "', argument " "1"" of type '" "int""'"); - } - arg1 = (int)(val1); - ivar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_ivar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - int result; - - result = (int)ivar; - jsresult = SWIG_From_int SWIG_JSC_FROM_CALL_ARGS((int)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_svar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - short arg1 ; - short val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_short SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "svar_set" "', argument " "1"" of type '" "short""'"); - } - arg1 = (short)(val1); - svar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_svar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - short result; - - result = (short)svar; - jsresult = SWIG_From_short SWIG_JSC_FROM_CALL_ARGS((short)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_lvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - long arg1 ; - long val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_long SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "lvar_set" "', argument " "1"" of type '" "long""'"); - } - arg1 = (long)(val1); - lvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_lvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - long result; - - result = (long)lvar; - jsresult = SWIG_From_long SWIG_JSC_FROM_CALL_ARGS((long)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_uivar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - unsigned int arg1 ; - unsigned int val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_unsigned_SS_int SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "uivar_set" "', argument " "1"" of type '" "unsigned int""'"); - } - arg1 = (unsigned int)(val1); - uivar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_uivar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - unsigned int result; - - result = (unsigned int)uivar; - jsresult = SWIG_From_unsigned_SS_int SWIG_JSC_FROM_CALL_ARGS((unsigned int)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_usvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - unsigned short arg1 ; - unsigned short val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_unsigned_SS_short SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "usvar_set" "', argument " "1"" of type '" "unsigned short""'"); - } - arg1 = (unsigned short)(val1); - usvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_usvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - unsigned short result; - - result = (unsigned short)usvar; - jsresult = SWIG_From_unsigned_SS_short SWIG_JSC_FROM_CALL_ARGS((unsigned short)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_ulvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - unsigned long arg1 ; - unsigned long val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_unsigned_SS_long SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ulvar_set" "', argument " "1"" of type '" "unsigned long""'"); - } - arg1 = (unsigned long)(val1); - ulvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_ulvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - unsigned long result; - - result = (unsigned long)ulvar; - jsresult = SWIG_From_unsigned_SS_long SWIG_JSC_FROM_CALL_ARGS((unsigned long)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_scvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - signed char arg1 ; - signed char val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_signed_SS_char SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "scvar_set" "', argument " "1"" of type '" "signed char""'"); - } - arg1 = (signed char)(val1); - scvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_scvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - signed char result; - - result = (signed char)scvar; - jsresult = SWIG_From_signed_SS_char SWIG_JSC_FROM_CALL_ARGS((signed char)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_ucvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - unsigned char arg1 ; - unsigned char val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_unsigned_SS_char SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "ucvar_set" "', argument " "1"" of type '" "unsigned char""'"); - } - arg1 = (unsigned char)(val1); - ucvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_ucvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - unsigned char result; - - result = (unsigned char)ucvar; - jsresult = SWIG_From_unsigned_SS_char SWIG_JSC_FROM_CALL_ARGS((unsigned char)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_cvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - char arg1 ; - char val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_char SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "cvar_set" "', argument " "1"" of type '" "char""'"); - } - arg1 = (char)(val1); - cvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_cvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - char result; - - result = (char)cvar; - jsresult = SWIG_From_char SWIG_JSC_FROM_CALL_ARGS((char)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_fvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - float arg1 ; - float val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_float SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "fvar_set" "', argument " "1"" of type '" "float""'"); - } - arg1 = (float)(val1); - fvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_fvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - float result; - - result = (float)fvar; - jsresult = SWIG_From_float SWIG_JSC_FROM_CALL_ARGS((float)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_dvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - double arg1 ; - double val1 ; - int ecode1 = 0 ; - - ecode1 = SWIG_AsVal_double SWIG_JSC_AS_CALL_ARGS(value, &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "dvar_set" "', argument " "1"" of type '" "double""'"); - } - arg1 = (double)(val1); - dvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_dvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - double result; - - result = (double)dvar; - jsresult = SWIG_From_double SWIG_JSC_FROM_CALL_ARGS((double)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_strvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - char *arg1 = (char *) 0 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - - res1 = SWIG_JSC_AsCharPtrAndSize(context, value, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "strvar_set" "', argument " "1"" of type '" "char *""'"); - } - arg1 = (char *)(buf1); - if (strvar) free((char*)strvar); - if (arg1) { - size_t size = strlen((const char *)((const char *)(arg1))) + 1; - strvar = (char *)(char *)memcpy((char *)malloc((size)*sizeof(char)), arg1, sizeof(char)*(size)); - } else { - strvar = 0; - } - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_strvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - char *result = 0 ; - - result = (char *)strvar; - jsresult = SWIG_FromCharPtr((const char *)result); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -JSValueRef _wrap_cstrvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - char *result = 0 ; - - result = (char *)(char *)cstrvar; - jsresult = SWIG_FromCharPtr((const char *)result); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_iptrvar_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - int *arg1 = (int *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - - res1 = SWIG_ConvertPtr(value, &argp1,SWIGTYPE_p_int, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "iptrvar_set" "', argument " "1"" of type '" "int *""'"); - } - arg1 = (int *)(argp1); - iptrvar = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_iptrvar_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - int *result = 0 ; - - result = (int *)iptrvar; - jsresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 | 0 ); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_name_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - char *arg1 ; - char temp1[256] ; - int res1 ; - - res1 = SWIG_JSC_AsCharArray(context, value, temp1, 256); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "name_set" "', argument " "1"" of type '" "char [256]""'"); - } - arg1 = (char *)(temp1); - if (arg1) memcpy(name,arg1,256*sizeof(char)); - else memset(name,0,256*sizeof(char)); - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_name_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - char *result = 0 ; - - result = (char *)(char *)name; - { - size_t size = 256; - - while (size && (result[size - 1] == '\0')) --size; - - jsresult = SWIG_FromCharPtrAndSize(result, size); - } - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_ptptr_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - Point *arg1 = (Point *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - - res1 = SWIG_ConvertPtr(value, &argp1,SWIGTYPE_p_Point, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "ptptr_set" "', argument " "1"" of type '" "Point *""'"); - } - arg1 = (Point *)(argp1); - ptptr = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_ptptr_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - Point *result = 0 ; - - result = (Point *)ptptr; - jsresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Point, 0 | 0 ); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -bool _wrap_pt_set(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - Point arg1 ; - void *argp1 ; - int res1 = 0 ; - - { - res1 = SWIG_ConvertPtr(value, &argp1, SWIGTYPE_p_Point, 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pt_set" "', argument " "1"" of type '" "Point""'"); - } - if (!argp1) { - SWIG_exception_fail(SWIG_ValueError, "invalid null reference " "in method '" "pt_set" "', argument " "1"" of type '" "Point""'"); - } else { - arg1 = *((Point *)(argp1)); - } - } - pt = arg1; - - - return true; - - goto fail; -fail: - return false; -} - - -JSValueRef _wrap_pt_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - Point result; - - result = pt; - jsresult = SWIG_NewPointerObj((Point *)memcpy((Point *)malloc(sizeof(Point)),&result,sizeof(Point)), SWIGTYPE_p_Point, SWIG_POINTER_OWN | 0 ); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -JSValueRef _wrap_status_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - int result; - - result = (int)status; - jsresult = SWIG_From_int SWIG_JSC_FROM_CALL_ARGS((int)(result)); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -JSValueRef _wrap_path_get(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - char *result = 0 ; - - result = (char *)(char *)path; - { - size_t size = 256; - - while (size && (result[size - 1] == '\0')) --size; - - jsresult = SWIG_FromCharPtrAndSize(result, size); - } - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -JSValueRef _wrap_print_vars(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - JSValueRef jsresult; - - print_vars(); - jsresult = JSValueMakeUndefined(context); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -JSValueRef _wrap_new_int(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - int arg1 ; - int val1 ; - int ecode1 = 0 ; - JSValueRef jsresult; - int *result = 0 ; - - ecode1 = SWIG_AsVal_int SWIG_JSC_AS_CALL_ARGS(argv[0], &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_int" "', argument " "1"" of type '" "int""'"); - } - arg1 = (int)(val1); - result = (int *)new_int(arg1); - jsresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_int, 0 | 0 ); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -JSValueRef _wrap_new_Point(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - int arg1 ; - int arg2 ; - int val1 ; - int ecode1 = 0 ; - int val2 ; - int ecode2 = 0 ; - JSValueRef jsresult; - Point *result = 0 ; - - ecode1 = SWIG_AsVal_int SWIG_JSC_AS_CALL_ARGS(argv[0], &val1); - if (!SWIG_IsOK(ecode1)) { - SWIG_exception_fail(SWIG_ArgError(ecode1), "in method '" "new_Point" "', argument " "1"" of type '" "int""'"); - } - arg1 = (int)(val1); - ecode2 = SWIG_AsVal_int SWIG_JSC_AS_CALL_ARGS(argv[1], &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "new_Point" "', argument " "2"" of type '" "int""'"); - } - arg2 = (int)(val2); - result = (Point *)new_Point(arg1,arg2); - jsresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Point, 0 | 0 ); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -JSValueRef _wrap_Point_print(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - Point *arg1 = (Point *) 0 ; - void *argp1 = 0 ; - int res1 = 0 ; - JSValueRef jsresult; - char *result = 0 ; - - res1 = SWIG_ConvertPtr(argv[0], &argp1,SWIGTYPE_p_Point, 0 | 0 ); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Point_print" "', argument " "1"" of type '" "Point *""'"); - } - arg1 = (Point *)(argp1); - result = (char *)Point_print(arg1); - jsresult = SWIG_FromCharPtr((const char *)result); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -JSValueRef _wrap_pt_print(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - JSValueRef jsresult; - - pt_print(); - jsresult = JSValueMakeUndefined(context); - - return jsresult; - - goto fail; -fail: - return NULL; -} - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static swig_type_info _swigt__p_Point = {"_p_Point", "Point *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_int = {"_p_int", "int *", 0, 0, (void*)0, 0}; - -static swig_type_info *swig_type_initial[] = { - &_swigt__p_Point, - &_swigt__p_char, - &_swigt__p_int, -}; - -static swig_cast_info _swigc__p_Point[] = { {&_swigt__p_Point, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_int[] = { {&_swigt__p_int, 0, 0, 0},{0, 0, 0, 0}}; - -static swig_cast_info *swig_cast_initial[] = { - _swigc__p_Point, - _swigc__p_char, - _swigc__p_int, -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - - - -JSStaticValue example_values[] = { - { - "ivar",_wrap_ivar_get, _wrap_ivar_set,kJSPropertyAttributeNone - },{ - "svar",_wrap_svar_get, _wrap_svar_set,kJSPropertyAttributeNone - },{ - "lvar",_wrap_lvar_get, _wrap_lvar_set,kJSPropertyAttributeNone - },{ - "uivar",_wrap_uivar_get, _wrap_uivar_set,kJSPropertyAttributeNone - },{ - "usvar",_wrap_usvar_get, _wrap_usvar_set,kJSPropertyAttributeNone - },{ - "ulvar",_wrap_ulvar_get, _wrap_ulvar_set,kJSPropertyAttributeNone - },{ - "scvar",_wrap_scvar_get, _wrap_scvar_set,kJSPropertyAttributeNone - },{ - "ucvar",_wrap_ucvar_get, _wrap_ucvar_set,kJSPropertyAttributeNone - },{ - "cvar",_wrap_cvar_get, _wrap_cvar_set,kJSPropertyAttributeNone - },{ - "fvar",_wrap_fvar_get, _wrap_fvar_set,kJSPropertyAttributeNone - },{ - "dvar",_wrap_dvar_get, _wrap_dvar_set,kJSPropertyAttributeNone - },{ - "strvar",_wrap_strvar_get, _wrap_strvar_set,kJSPropertyAttributeNone - },{ - "cstrvar",_wrap_cstrvar_get, JS_veto_set_variable,kJSPropertyAttributeNone - },{ - "iptrvar",_wrap_iptrvar_get, _wrap_iptrvar_set,kJSPropertyAttributeNone - },{ - "name",_wrap_name_get, _wrap_name_set,kJSPropertyAttributeNone - },{ - "ptptr",_wrap_ptptr_get, _wrap_ptptr_set,kJSPropertyAttributeNone - },{ - "pt",_wrap_pt_get, _wrap_pt_set,kJSPropertyAttributeNone - },{ - "status",_wrap_status_get, JS_veto_set_variable,kJSPropertyAttributeNone - },{ - "path",_wrap_path_get, JS_veto_set_variable,kJSPropertyAttributeNone - }, - { - 0, 0, 0, 0 - } -}; - -JSStaticFunction example_functions[] = { - { - "print_vars",_wrap_print_vars, kJSPropertyAttributeNone - },{ - "new_int",_wrap_new_int, kJSPropertyAttributeNone - },{ - "new_Point",_wrap_new_Point, kJSPropertyAttributeNone - },{ - "Point_print",_wrap_Point_print, kJSPropertyAttributeNone - },{ - "pt_print",_wrap_pt_print, kJSPropertyAttributeNone - }, - { - 0, 0, 0 - } -}; - -JSClassDefinition example_classDefinition; - - -SWIGRUNTIME void -SWIG_JSC_SetModule(swig_module_info *swig_module) {} - -SWIGRUNTIME swig_module_info * -SWIG_JSC_GetModule(void) { - return 0; -} - -#define SWIG_GetModule(clientdata) SWIG_JSC_GetModule() -#define SWIG_SetModule(clientdata, pointer) SWIG_JSC_SetModule(pointer) - - -/* ----------------------------------------------------------------------------- - * Type initialization: - * This problem is tough by the requirement that no dynamic - * memory is used. Also, since swig_type_info structures store pointers to - * swig_cast_info structures and swig_cast_info structures store pointers back - * to swig_type_info structures, we need some lookup code at initialization. - * The idea is that swig generates all the structures that are needed. - * The runtime then collects these partially filled structures. - * The SWIG_InitializeModule function takes these initial arrays out of - * swig_module, and does all the lookup, filling in the swig_module.types - * array with the correct data and linking the correct swig_cast_info - * structures together. - * - * The generated swig_type_info structures are assigned staticly to an initial - * array. We just loop through that array, and handle each type individually. - * First we lookup if this type has been already loaded, and if so, use the - * loaded structure instead of the generated one. Then we have to fill in the - * cast linked list. The cast data is initially stored in something like a - * two-dimensional array. Each row corresponds to a type (there are the same - * number of rows as there are in the swig_type_initial array). Each entry in - * a column is one of the swig_cast_info structures for that type. - * The cast_initial array is actually an array of arrays, because each row has - * a variable number of columns. So to actually build the cast linked list, - * we find the array of casts associated with the type, and loop through it - * adding the casts to the list. The one last trick we need to do is making - * sure the type pointer in the swig_cast_info struct is correct. - * - * First off, we lookup the cast->type name to see if it is already loaded. - * There are three cases to handle: - * 1) If the cast->type has already been loaded AND the type we are adding - * casting info to has not been loaded (it is in this module), THEN we - * replace the cast->type pointer with the type pointer that has already - * been loaded. - * 2) If BOTH types (the one we are adding casting info to, and the - * cast->type) are loaded, THEN the cast info has already been loaded by - * the previous module so we just ignore it. - * 3) Finally, if cast->type has not already been loaded, then we add that - * swig_cast_info to the linked list (because the cast->type) pointer will - * be correct. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* c-mode */ -#endif -#endif - -#if 0 -#define SWIGRUNTIME_DEBUG -#endif - - -SWIGRUNTIME void -SWIG_InitializeModule(void *clientdata) { - size_t i; - swig_module_info *module_head, *iter; - int found, init; - - clientdata = clientdata; - - /* check to see if the circular list has been setup, if not, set it up */ - if (swig_module.next==0) { - /* Initialize the swig_module */ - swig_module.type_initial = swig_type_initial; - swig_module.cast_initial = swig_cast_initial; - swig_module.next = &swig_module; - init = 1; - } else { - init = 0; - } - - /* Try and load any already created modules */ - module_head = SWIG_GetModule(clientdata); - if (!module_head) { - /* This is the first module loaded for this interpreter */ - /* so set the swig module into the interpreter */ - SWIG_SetModule(clientdata, &swig_module); - module_head = &swig_module; - } else { - /* the interpreter has loaded a SWIG module, but has it loaded this one? */ - found=0; - iter=module_head; - do { - if (iter==&swig_module) { - found=1; - break; - } - iter=iter->next; - } while (iter!= module_head); - - /* if the is found in the list, then all is done and we may leave */ - if (found) return; - /* otherwise we must add out module into the list */ - swig_module.next = module_head->next; - module_head->next = &swig_module; - } - - /* When multiple interpeters are used, a module could have already been initialized in - a different interpreter, but not yet have a pointer in this interpreter. - In this case, we do not want to continue adding types... everything should be - set up already */ - if (init == 0) return; - - /* Now work on filling in swig_module.types */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: size %d\n", swig_module.size); -#endif - for (i = 0; i < swig_module.size; ++i) { - swig_type_info *type = 0; - swig_type_info *ret; - swig_cast_info *cast; - -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); -#endif - - /* if there is another module already loaded */ - if (swig_module.next != &swig_module) { - type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); - } - if (type) { - /* Overwrite clientdata field */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found type %s\n", type->name); -#endif - if (swig_module.type_initial[i]->clientdata) { - type->clientdata = swig_module.type_initial[i]->clientdata; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); -#endif - } - } else { - type = swig_module.type_initial[i]; - } - - /* Insert casting types */ - cast = swig_module.cast_initial[i]; - while (cast->type) { - - /* Don't need to add information already in the list */ - ret = 0; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); -#endif - if (swig_module.next != &swig_module) { - ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); -#ifdef SWIGRUNTIME_DEBUG - if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); -#endif - } - if (ret) { - if (type == swig_module.type_initial[i]) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: skip old type %s\n", ret->name); -#endif - cast->type = ret; - ret = 0; - } else { - /* Check for casting already in the list */ - swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); -#ifdef SWIGRUNTIME_DEBUG - if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); -#endif - if (!ocast) ret = 0; - } - } - - if (!ret) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); -#endif - if (type->cast) { - type->cast->prev = cast; - cast->next = type->cast; - } - type->cast = cast; - } - cast++; - } - /* Set entry in modules->types array equal to the type */ - swig_module.types[i] = type; - } - swig_module.types[i] = 0; - -#ifdef SWIGRUNTIME_DEBUG - printf("**** SWIG_InitializeModule: Cast List ******\n"); - for (i = 0; i < swig_module.size; ++i) { - int j = 0; - swig_cast_info *cast = swig_module.cast_initial[i]; - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); - while (cast->type) { - printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); - cast++; - ++j; - } - printf("---- Total casts: %d\n",j); - } - printf("**** SWIG_InitializeModule: Cast List ******\n"); -#endif -} - -/* This function will propagate the clientdata field of type to -* any new swig_type_info structures that have been added into the list -* of equivalent types. It is like calling -* SWIG_TypeClientData(type, clientdata) a second time. -*/ -SWIGRUNTIME void -SWIG_PropagateClientData(void) { - size_t i; - swig_cast_info *equiv; - static int init_run = 0; - - if (init_run) return; - init_run = 1; - - for (i = 0; i < swig_module.size; i++) { - if (swig_module.types[i]->clientdata) { - equiv = swig_module.types[i]->cast; - while (equiv) { - if (!equiv->converter) { - if (equiv->type && !equiv->type->clientdata) - SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); - } - equiv = equiv->next; - } - } - } -} - -#ifdef __cplusplus -#if 0 -{ /* c-mode */ -#endif -} -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - - bool example_initialize(JSGlobalContextRef context) { - SWIG_InitializeModule(0); - - JSObjectRef global_object = JSContextGetGlobalObject(context); - - /* Initialize the base swig type object */ - _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; - _SwigObject_objectDefinition.staticValues = _SwigObject_values; - _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); - - /* Create objects for namespaces */ - example_classDefinition.staticFunctions = example_functions; - example_classDefinition.staticValues = example_values; - JSObjectRef example_object = JSObjectMake(context, JSClassCreate(&example_classDefinition), NULL); - - - /* Create classes */ - - - /* Register namespaces */ - - JS_registerNamespace(context, example_object, global_object, "example"); - - return true; - } - -#ifdef __cplusplus -} -#endif - - From f814a8e702dcfe2ae2f2480de372e78c5a997eb5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:14:02 +0000 Subject: [PATCH 085/352] Fix errors concerning object wrapping and cleanup in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13819 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 30 ++++++++--- Lib/javascript/v8/javascripthelpers.swg | 4 +- Lib/javascript/v8/javascriptinit.swg | 2 + Lib/javascript/v8/javascriptruntime.swg | 71 +++++++++++++------------ Source/Modules/javascript.cxx | 64 +++++++++++++++++++--- 5 files changed, 122 insertions(+), 49 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index b7b2c195f..8f3d8cff2 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -5,7 +5,7 @@ v8::Handle $jswrapper(const v8::Arguments& args) { $jslocals $jscode - SWIG_V8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); return scope.Close(self); goto fail; @@ -48,7 +48,14 @@ fail: %fragment ("JS_destructordefn", "templates") %{ - // TODO: implement JS_destructordefn +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; + } + delete proxy; +} %} @@ -136,18 +143,25 @@ fail: %} %fragment("jsv8_declare_class_template", "templates") -%{v8::Persistent $jsmangledname_class;%} +%{SWIGV8_ClientData $jsmangledname_clientData; +%} %fragment("jsv8_define_class_template", "templates") -%{$jsmangledname_class = SWIGV8_CreateClassTemplate("$jsname" , $jsctor); - SWIGTYPE_$jsmangledtype->clientdata = &$jsmangledname_class;%} - -%fragment("jsv8_create_class_instance", "templates") -%{v8::Handle $jsmangledname_obj = $jsmangledname_class->GetFunction();%} +%{v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); + $jsmangledname_clientData.class_templ = $jsmangledname_class; + $jsmangledname_clientData.dtor = $jsdtor; + SWIGTYPE_p$jsmangledtype->clientdata = &$jsmangledname_clientData;%} %fragment("jsv8_inherit", "templates") %{$jsmangledname_class->Inherit($jsbaseclass_class);%} +%fragment("jsv8_create_class_instance", "templates") +%{v8::Handle $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); + $jsmangledname_class_0->SetCallHandler($jsctor); + $jsmangledname_class_0->Inherit($jsmangledname_class); + $jsmangledname_class_0->SetHiddenPrototype(true); + v8::Handle $jsmangledname_obj = $jsmangledname_class_0->GetFunction();%} + %fragment("jsv8_register_class", "templates") %{$jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj);%} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index 9a80a6552..4fcf0e447 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -3,8 +3,8 @@ /** * Creates a class template for a class with specified initialization function. */ -v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol, v8::InvocationCallback _func) { - v8::Local class_templ = v8::FunctionTemplate::New(_func); +v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol) { + v8::Local class_templ = v8::FunctionTemplate::New(); class_templ->SetClassName(v8::String::NewSymbol(symbol)); v8::Handle inst_templ = class_templ->InstanceTemplate(); diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg index 1186b33bc..1bca4c244 100644 --- a/Lib/javascript/v8/javascriptinit.swg +++ b/Lib/javascript/v8/javascriptinit.swg @@ -12,4 +12,6 @@ SWIG_V8_GetModule(void) { %} +%insert(init) %{/************ BEGIN: "swiginit.swg" *******************/ %} %insert(init) "swiginit.swg" +%insert(init) %{/************ END: "swiginit.swg" *******************/ %} diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 2eb9c82cc..b9f24a562 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -8,6 +8,7 @@ #include #include #include +#include %} %insert(runtime) "swigrun.swg"; /* SWIG API */ @@ -59,27 +60,45 @@ public: %} %insert(runtime) %{ -typedef struct { + +// Note: to trigger the c8 gc more often one can tell v8 about the memory consumption +// TODO: we could add a v8 specific parameter to control this value +#define SWIGV8_AVG_OBJ_SIZE 1000 + +class SWIGV8_Proxy { +public: + SWIGV8_Proxy(): swigCMemOwn(false), swigCObject(0), info(0) { + v8::V8::AdjustAmountOfExternalAllocatedMemory(SWIGV8_AVG_OBJ_SIZE); + }; + + ~SWIGV8_Proxy() { + v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); + } + bool swigCMemOwn; void *swigCObject; swig_type_info *info; -} SWIG_PRV_DATA; +}; + +class SWIGV8_ClientData { +public: + v8::Handle class_templ; + void (*dtor) (v8::Persistent< v8::Value > object, void *parameter); +}; + %} %insert(runtime) %{ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; - if(objRef->InternalFieldCount() < 1) { - return SWIG_ERROR; - } + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; v8::Handle cdataRef = objRef->GetInternalField(0); - - SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) v8::External::Unwrap(cdataRef); + SWIGV8_Proxy *cdata = (SWIGV8_Proxy *) v8::External::Unwrap(cdataRef); if(cdata == NULL) { return SWIG_ERROR; } - if(cdata->info != info) { bool type_valid = false; swig_cast_info *t = info->cast; @@ -94,53 +113,39 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t return SWIG_TypeError; } } - *ptr = cdata->swigCObject; - if(flags & SWIG_POINTER_DISOWN) { cdata->swigCMemOwn = false; } - return SWIG_OK; } -void SWIG_V8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { - SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) new SWIG_PRV_DATA; +void SWIGV8_SetPrivateData(v8::Handle 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->SetInternalField(0, v8::External::New(cdata)); + obj->SetPointerInInternalField(0, cdata); + v8::Persistent weakptr = v8::Persistent::New(obj); + weakptr.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); } int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + if(!valRef->IsObject()) { return SWIG_TypeError; } - v8::Handle objRef = valRef->ToObject(); - return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags); } v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { v8::HandleScope scope; - - v8::Local class_templ; - v8::Handle inst_templ; - if(info->clientdata == NULL) { - class_templ = v8::FunctionTemplate::New(); - class_templ->SetClassName(v8::String::NewSymbol(info->name)); - inst_templ = class_templ->InstanceTemplate(); - inst_templ->SetInternalFieldCount(1); - } else { - class_templ = *((v8::Local*) info->clientdata); - inst_templ = class_templ->InstanceTemplate(); - } - - v8::Local result = inst_templ->NewInstance(); - - SWIG_V8_SetPrivateData(result, ptr, info, flags); + + v8::Handle class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; + v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); + SWIGV8_SetPrivateData(result, ptr, info, flags); return scope.Close(result); } diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 28c4b96b7..f54d470f1 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -20,6 +20,7 @@ bool js_template_enable_debug = false; #define CTOR "ctor" #define CTOR_WRAPPERS "ctor_wrappers" #define CTOR_DISPATCHERS "ctor_dispatchers" +#define DTOR "dtor" #define ARGCOUNT "wrap:argc" #define FUNCTION_DISPATCHERS "function_dispatchers" @@ -31,6 +32,7 @@ bool js_template_enable_debug = false; #define T_TYPE_MANGLED "$jsmangledtype" #define T_WRAPPER "$jswrapper" #define T_CTOR "$jsctor" +#define T_DTOR "$jsdtor" #define T_GETTER "$jsgetter" #define T_SETTER "$jssetter" #define T_DISPATCH_CASES "$jsdispatchcases" @@ -292,6 +294,8 @@ protected: Hash *namespaces; Hash *current_namespace; + Hash *undefined_types; + String *defaultResultName; File *f_wrappers; @@ -597,6 +601,7 @@ JSEmitter::JSEmitter() : templates(NewHash()), namespaces(NULL), current_namespace(NULL), + undefined_types(NewHash()), defaultResultName(NewString("result")), f_wrappers(NULL) { @@ -751,6 +756,7 @@ int JSEmitter::enterClass(Node *n) { Append(ctor_wrapper, state.clazz(NAME)); state.clazz(CTOR, ctor_wrapper); state.clazz(CTOR_DISPATCHERS, NewString("")); + state.clazz(DTOR, NewString("0")); // HACK: assume that a class is abstract // this is resolved by emitCtor (which is only called for non abstract classes) @@ -855,10 +861,13 @@ int JSEmitter::emitCtor(Node *n) { return SWIG_OK; } -int JSEmitter::emitDtor(Node *) { +int JSEmitter::emitDtor(Node *n) { Template t_dtor = getTemplate("JS_destructordefn"); + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + 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)) .pretty_print(f_wrappers); @@ -1068,8 +1077,11 @@ void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, co 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")); + // 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); @@ -1565,6 +1577,7 @@ protected: virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); virtual int emitNamespaces(); + virtual void emitUndefined(); private: @@ -1654,6 +1667,8 @@ int V8Emitter::dump(Node *n) SwigType_emit_type_table(f_runtime, f_wrappers); + emitUndefined(); + 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); @@ -1724,19 +1739,22 @@ int V8Emitter::exitClass(Node *n) } /* Note: this makes sure that there is a swig_type added for this class */ - SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); + String *clientData = NewString(""); + Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED)); + SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), clientData); // emit definition of v8 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_CTOR, state.clazz(CTOR)) - .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) + .replace(T_TYPE_MANGLED, SwigType_manglestr(Getattr(n, "classtype"))) + .replace(T_DTOR, state.clazz(DTOR)) .pretty_print(f_init_class_templates); 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)) .pretty_print(f_init_class_instances); // emit inheritance setup @@ -1929,6 +1947,40 @@ int V8Emitter::emitNamespaces() { return SWIG_OK; } +void V8Emitter::emitUndefined() { + Iterator ki; + for (ki = First(undefined_types); ki.item; ki = Next(ki)) { + String *mangled_name = ki.key; + String *dtor = Swig_name_destroy("", mangled_name); + SwigType *deref = SwigType_del_pointer(ki.item); + String *type_mangled = SwigType_manglestr(ki.item); + + // emit clientData declaration + Template clientDataDecl = getTemplate("jsv8_declare_class_template"); + clientDataDecl.replace(T_NAME_MANGLED, mangled_name) + .pretty_print(f_class_templates); + + // emit an extra dtor for unknown types + Template t_dtor = getTemplate("JS_destructordefn"); + t_dtor.replace(T_NAME_MANGLED, mangled_name) + .replace(T_WRAPPER, dtor) + .replace(T_TYPE, deref) + .pretty_print(f_wrappers); + + // create a class template and initialize clientData + Template clientDataDef = getTemplate("jsv8_define_class_template"); + clientDataDef.replace(T_NAME_MANGLED, mangled_name) + .replace(T_NAME, mangled_name) + .replace(T_TYPE_MANGLED, type_mangled) + .replace(T_DTOR, dtor) + .pretty_print(f_init_class_templates); + + Delete(dtor); + Delete(deref); + Delete(type_mangled); + + } +} JSEmitter *swig_javascript_create_V8Emitter() { return new V8Emitter(); From 20927938681c14e4f812879973f8e677c08d77b0 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:14:14 +0000 Subject: [PATCH 086/352] Make v8 shell more quiet. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13820 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Tools/javascript/v8_shell.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 6c84fe758..27923dd86 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -181,9 +181,9 @@ bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) if (!result->IsUndefined()) { // If all went well and the result wasn't undefined then print // the returned value. - v8::String::Utf8Value str(result); - const char* cstr = V8Shell::ToCString(str); - printf("%s\n", cstr); + //v8::String::Utf8Value str(result); + //const char* cstr = V8Shell::ToCString(str); + //printf("%s\n", cstr); } return true; } From 8948360725e853f2232188edd38a834ac1f87666 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:14:23 +0000 Subject: [PATCH 087/352] Fix configuration_in for detecting v8 include and lib. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13821 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- configure.in | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/configure.in b/configure.in index f3d7e4ccd..5a00636a2 100644 --- a/configure.in +++ b/configure.in @@ -1215,11 +1215,9 @@ AC_SUBST(JSCXXFLAGS) # check for include files AC_MSG_CHECKING(for include file v8.h) -AC_ARG_WITH(javascriptv8incl, [ --with-javascript-v8=path Set location of Javascript include directory], [JSV8INCDIR="$withval"], [JSV8INCDIR=]) +AC_ARG_WITH(v8inc, [ --with-v8inc=path Set location of Javascript include directory], [JSV8INCDIR="$withval"]) if test -z "$JSV8INCDIR"; then - JSV8INCDIR="/usr/include/ /usr/local/include/" - # Add in default directory for JavaScriptCore headers for Linux and MacOSX case $host in *-*-linux*) JSV8INCDIR="/usr/include /usr/local/include/ $JSV8INCDIR";; @@ -1243,27 +1241,21 @@ fi # check for V8 library -AC_ARG_WITH(jsv8lib,[ --with-jsv8lib =path Set location of V8 library directory],[ - JSV8LIB="-L$withval"], [JSV8LIB=]) -AC_MSG_CHECKING(for V8 library) +AC_MSG_CHECKING(for v8 library) +AC_ARG_WITH(v8lib,[ --with-v8lib=path Set location of V8 library directory],[JSV8LIBDIR="$withval"], [JSV8LIB=]) -if test -z "$JSV8LIB"; then -dirs="/usr/lib/ /usr/local/lib/" -for i in $dirs ; do - - if test -r $i/libv8.so; then - AC_MSG_RESULT($i) - JSV8LIB="-L$i -lv8" - break - fi +v8libdirs="$JSV8LIBDIR /usr/lib/ /usr/local/lib/" +for i in $v8libdirs ; do + if test -r $i/libv8.so; then + JSV8LIB="-L$i -lv8" + break + fi done if test "$JSV8LIB" = "" ; then - AC_MSG_RESULT(not found) -fi - + AC_MSG_RESULT(not found) else -AC_MSG_RESULT($JSCORELIB) + AC_MSG_RESULT($JSV8LIB) fi From 4616f9643ff5ce8aefe0594289c9a97230cabf09 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:14:37 +0000 Subject: [PATCH 088/352] Adapt test-suite configuration to allow switching between js engines. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13822 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/test-suite/javascript/Makefile.in | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 22a3a8a3e..d59f3d60e 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -56,6 +56,12 @@ SKIP_MULTI_CPP_CASES = @SKIP_MULTI_CPP_CASES@ include $(srcdir)/../common.mk +ifeq (,$(V8)) +JSENGINEFLAG = -jsc +else +JSENGINEFLAG = -v8 +endif + # Overridden variables here # Custom tests - tests with additional commandline options @@ -83,7 +89,7 @@ javascript_exe: # a file is found which has _runme.js appended after the testcase name. run_testcase = \ if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ - env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(JAVASCRIPT_EXE) -l $* $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \ + env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(JAVASCRIPT_EXE) $(JSENGINEFLAG) -l $* $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \ fi # Clean From 296a5d028547c0a0a013a24e65cdcb9c3086fb52 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:14:48 +0000 Subject: [PATCH 089/352] Minor change in javascript example Makefile configuration. Propagate global CFLAGS and CXXFLAGS to inner javascript targets. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13823 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Examples/Makefile.in | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index a6ed5157e..bf9fe5cd8 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -543,8 +543,7 @@ JSCFLAGS = @JSCORECFLAGS@ JSCXXFLAGS = @JSCXXFLAGS@ JSEXE_SRC_DIR = $(TOP)/../Tools/javascript -JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx -JSEXE = $(TOP)/../Tools/javascript/javascript +JSEXE = $(JSEXE_SRC_DIR)/javascript ifeq (,$(V8)) JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx $(JSEXE_SRC_DIR)/jsc_shell.cxx JSEXE_OPTS = -jsc @@ -563,8 +562,8 @@ endif ifeq (,$(V8)) javascript: $(SRCS) $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) - $(CC) -c $(CCSHARED) $(JSCFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JS_INCLUDE) - $(JSLDSHARED) $(CCSHARED) $(JSCFLAGS) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) + $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JS_INCLUDE) + $(JSLDSHARED) $(CCSHARED) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) else javascript: $(SRCS) javascript_cpp endif @@ -575,7 +574,7 @@ endif javascript_cpp: $(SRCS) $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) - $(CXX) -c $(CCSHARED) $(JSCXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JS_INCLUDE) + $(CXX) -c $(CCSHARED) $(CXXFLAGS) $(JSCXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JS_INCLUDE) $(JSCXXSHARED) $(CCSHARED) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) # ---------------------------------------------------------------- From 7c7d1cf3b9e8a1dfd92b3ca199e2ee0b8bf1cc6f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:15:12 +0000 Subject: [PATCH 090/352] 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 --- Lib/javascript/v8/javascriptcode.swg | 6 +- Lib/javascript/v8/javascriptruntime.swg | 28 +++++++-- Source/Modules/javascript.cxx | 81 +++++++++++++++++++------ 3 files changed, 87 insertions(+), 28 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 8f3d8cff2..b46bacfa9 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -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 $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 context) v8::HandleScope scope; v8::Local global_obj = context->Global(); + SWIGV8_SWIGTYPE_Proxy_class_templ = SWIGV8_CreateClassTemplate("SwigProxy"); + /* create objects for namespaces */ $jsv8nspaces diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index b9f24a562..b6ef55d90 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -86,10 +86,8 @@ public: void (*dtor) (v8::Persistent< v8::Value > object, void *parameter); }; -%} +v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; - -%insert(runtime) %{ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { v8::HandleScope scope; @@ -120,14 +118,27 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle 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 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 weakptr = v8::Persistent::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 valRef, void** ptr, swig_type_info *info, int flags) { @@ -142,8 +153,13 @@ int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { v8::HandleScope scope; - - v8::Handle class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; + + v8::Handle class_templ; + if(info->clientdata != 0) { + class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; + } else { + class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ; + } v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); SWIGV8_SetPrivateData(result, ptr, info, flags); diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index f54d470f1..db4972310 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -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); } } From 8b7a9fec2519aa5faac9c3bb26f7612ee1f5aefb Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:15:29 +0000 Subject: [PATCH 091/352] Add complex support to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13825 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcomplex.swg | 79 +++++++++---------------- 1 file changed, 28 insertions(+), 51 deletions(-) diff --git a/Lib/javascript/v8/javascriptcomplex.swg b/Lib/javascript/v8/javascriptcomplex.swg index 7d165dce4..70c5baffb 100644 --- a/Lib/javascript/v8/javascriptcomplex.swg +++ b/Lib/javascript/v8/javascriptcomplex.swg @@ -12,13 +12,15 @@ %fragment(SWIG_From_frag(Type),"header", fragment=SWIG_From_frag(double)) { -SWIGINTERNINLINE JSObjectRef +SWIGINTERNINLINE v8::Handle SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) { - JSValueRef vals[2]; - vals[0] = SWIG_From(double)(Real(c)); - vals[1] = SWIG_From(double)(Imag(c)); - return JSObjectMakeArray(context, 2, vals, NULL); + v8::HandleScope scope; + v8::Local vals = v8::Array::New(2); + + vals->Set(0, SWIG_From(double)(Real(c))); + vals->Set(1, SWIG_From(double)(Imag(c))); + return scope.Close(vals); } } %enddef @@ -29,42 +31,30 @@ SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) fragment=SWIG_AsVal_frag(double)) { SWIGINTERN int -SWIG_AsVal_dec(Type) (JSValueRef o, Type* val) +SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) { - if (JSValueIsObject(context, o)) { - JSObjectRef array; - JSValueRef exception, js_re, js_im; + v8::HandleScope scope; + + if (o->IsArray()) { + v8::Handle array = v8::Handle::Cast(o); + + if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); double re, im; int res; - - exception = 0; - res = 0; - array = JSValueToObject(context, o, &exception); - if(exception != 0) - return SWIG_TypeError; - - js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); - if(exception != 0) - return SWIG_TypeError; - - js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); - if(exception != 0) - return SWIG_TypeError; - - res = SWIG_AsVal(double)(js_re, &re); + res = SWIG_AsVal(double)(array->Get(0), &re); if(!SWIG_IsOK(res)) { return SWIG_TypeError; } - res = SWIG_AsVal(double)(js_im, &im); + res = SWIG_AsVal(double)(array->Get(1), &im); if(!SWIG_IsOK(res)) { return SWIG_TypeError; } if (val) *val = Constructor(re, im); return SWIG_OK; - } else { + } else if(o->IsNumber()){ double d; int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); if (SWIG_IsOK(res)) { @@ -83,39 +73,27 @@ SWIG_AsVal_dec(Type) (JSValueRef o, Type* val) %fragment(SWIG_AsVal_frag(Type),"header", fragment=SWIG_AsVal_frag(float)) { SWIGINTERN int -SWIG_AsVal_dec(Type)(JSValueRef o, Type *val) +SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) { - if (JSValueIsObject(context, o)) { - JSObjectRef array; - JSValueRef exception, js_re, js_im; + v8::HandleScope scope; + + if (o->IsArray()) { + v8::Handle array = v8::Handle::Cast(o); + + if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); double re, im; int res; - - exception = 0; - res = 0; - array = JSValueToObject(context, o, &exception); - if(exception != 0) - return SWIG_TypeError; - - js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); - if(exception != 0) - return SWIG_TypeError; - - js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); - if(exception != 0) - return SWIG_TypeError; - - res = SWIG_AsVal(double)(js_re, &re); + res = SWIG_AsVal(double)(array->Get(0), &re); if(!SWIG_IsOK(res)) { return SWIG_TypeError; } - res = SWIG_AsVal(double)(js_im, &im); + res = SWIG_AsVal(double)(array->Get(1), &im); if(!SWIG_IsOK(res)) { return SWIG_TypeError; } - + if ((-FLT_MAX <= re && re <= FLT_MAX) && (-FLT_MAX <= im && im <= FLT_MAX)) { if (val) *val = Constructor(%numeric_cast(re, float), %numeric_cast(im, float)); @@ -123,7 +101,7 @@ SWIG_AsVal_dec(Type)(JSValueRef o, Type *val) } else { return SWIG_OverflowError; } - } else { + } else if(o->IsNumber()){ float re; int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); if (SWIG_IsOK(res)) { @@ -134,7 +112,6 @@ SWIG_AsVal_dec(Type)(JSValueRef o, Type *val) return SWIG_TypeError; } } - %swig_fromcplx_conv(Type, Real, Imag); %enddef From 131a106204e060ac15bd2474c8a5501f82868284 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:15:51 +0000 Subject: [PATCH 092/352] Improve names and comments of code templates for javascript emitters. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13826 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptcode.swg | 471 +++++++++++++++----------- Lib/javascript/v8/javascriptcode.swg | 120 ++++--- Source/Modules/javascript.cxx | 113 +++--- 3 files changed, 428 insertions(+), 276 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 4a83b87d2..9a91c874a 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -1,12 +1,108 @@ -/********************************************************************* - *getproperty: This template gives name to generated wrapper for the getproperty - *{LOCALS}: declarations for input arguments - *{CODE}: contains input marshalling, and the action -*********************************************************************/ - -%fragment ("JS_getproperty", "templates") +/* ----------------------------------------------------------------------------- + * js_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor", "templates") %{ -JSValueRef $jsgetter(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_veto_ctor: a vetoing ctor for abstract classes + * - $jswrapper: name of wrapper + * - $jsname: class name + * ----------------------------------------------------------------------------- */ +%fragment ("js_veto_ctor", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, + size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); + return 0; +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatcher: dispatcher for overloaded constructors + * - $jswrapper: name of wrapper + * - $jsname: class name + * - $jsdispatchcases: part containing code for dispatching + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatcher", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, + size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSObjectRef thisObject = NULL; + + // switch all cases by means of series of if-returns. + $jsdispatchcases + + // default: + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsname"); + + fail: + return thisObject; +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatch_case: template for a dispatch case for calling an overloaded ctor. + * - $jsargcount: number of arguments of called ctor + * - $jswrapper: wrapper of called ctor + * + * Note: a try-catch-like mechanism is used to switch cases + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatch_case", "templates") +%{ + if(argc == $jsargcount) { + thisObject = $jswrapper(context, NULL, argc, argv, exception); + if(thisObject != NULL) { *exception=0; return thisObject; } /* reset exception and return */ + } +%} + + +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtor", "templates") +%{ +void $jswrapper(JSObjectRef thisObject) +{ + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*) JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) free (($jstype*)t->swigCObject); + if(t) free(t); +} +%} + +/* ----------------------------------------------------------------------------- + * js_getter: template for getter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_getter", "templates") +%{ +JSValueRef $jswrapper(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) { $jslocals JSValueRef jsresult; @@ -20,15 +116,15 @@ JSValueRef $jsgetter(JSContextRef context, JSObjectRef thisObject, JSStringRef p } %} -/********************************************************************** - *setproperty: This template gives name to generated wrapper for the setproperty - *{LOCALS}: declarations for input arguments - *{CODE}: contains input marshalling, and the action -**********************************************************************/ - -%fragment ("JS_setproperty", "templates") +/* ----------------------------------------------------------------------------- + * js_setter: template for setter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_setter", "templates") %{ -bool $jssetter(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +bool $jswrapper(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) { $jslocals $jscode @@ -41,12 +137,13 @@ bool $jssetter(JSContextRef context, JSObjectRef thisObject, JSStringRef propert } %} -/************************************************************************************ - *functionwrapper: This template gives name to generated wrapper for the function - *{LOCALS}: declarations for input arguments - *{CODE} contains input marshalling, and the action -************************************************************************************/ -%fragment ("JS_functionwrapper", "templates") +/* ----------------------------------------------------------------------------- + * js_function: template for function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function", "templates") %{ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { @@ -64,7 +161,14 @@ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef th } %} -%fragment ("JS_function_dispatcher", "templates") +/* ----------------------------------------------------------------------------- + * js_function_dispatcher: template for a function dispatcher for overloaded functions + * - $jswrapper: wrapper function name + * - $jsname: name of the wrapped function + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function_dispatcher", "templates") %{ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { @@ -82,7 +186,13 @@ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef th } %} -%fragment ("JS_functionwrapper_overload", "templates") +/* ----------------------------------------------------------------------------- + * js_overloaded_function: template for a overloaded function + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_overloaded_function", "templates") %{ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* result) { @@ -101,51 +211,87 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec } %} -/*********************************************************************** - * 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 == $jsargcount) { +/* ----------------------------------------------------------------------------- + * js_function_dispatch_case: template for a case used in the function dispatcher + * - $jswrapper: wrapper function name + * - $jsargcount: number of arguments of overloaded function + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function_dispatch_case", "templates") +%{ + if(argc == $jsargcount) { res = $jswrapper(context, function, thisObject, argc, argv, exception, &jsresult); if(res == SWIG_OK) { *exception = 0; return jsresult; } } %} -/* Added template for function declaration */ +/* ----------------------------------------------------------------------------- + * js_initializer: template for the module initializer function + * - $jsname: module name + * - $jscreatenamespaces: part with code for creating namespace objects + * - $jscreateclasses: part with code for creating classes + * - $jsregisternamespaces: part with code for registration of namespaces + * ----------------------------------------------------------------------------- */ +%fragment ("js_initializer", "templates") %{ +#ifdef __cplusplus +extern "C" { +#endif -%fragment ("JS_variabledecl", "templates") -%{{"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone},%} +bool $jsname_initialize(JSGlobalContextRef context) { + SWIG_InitializeModule(0); + JSObjectRef global_object = JSContextGetGlobalObject(context); + + /* Initialize the base swig type object */ + _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; + _SwigObject_objectDefinition.staticValues = _SwigObject_values; + _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + + /* Create objects for namespaces */ + $jscreatenamespaces -/* Added template for function declaration */ + /* Register classes */ + $jsregisterclasses -%fragment ("JS_functiondecl", "templates") -%{{"$jsname",$jswrapper, kJSPropertyAttributeNone},%} + /* Register namespaces */ + $jsregisternamespaces -%fragment ("JS_globaldefn", "templates") -%{ -JSStaticValue $jsnspace_values[] = { - $jsglobalvariables - { 0, 0, 0, 0 } -}; + return true; +} -JSStaticFunction $jsnspace_functions[] = { - $jsglobalfunctions - { 0, 0, 0 } -}; +#ifdef __cplusplus +} +#endif -JSClassDefinition $jsnspace_classDefinition; %} -/*********************************************************************** - * class_definition: - * declarations of javascript class definition objects. - ***********************************************************************/ +/* ----------------------------------------------------------------------------- + * jsc_variable_declaration: template for a variable table entry + * - $jsname: name of the variable + * - $jsgetter: wrapper of getter function + * - $jssetter: wrapper of setter function + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_variable_declaration", "templates") +%{ + {"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone}, +%} -%fragment ("JS_class_definition", "templates") + +/* ----------------------------------------------------------------------------- + * jsc_function_declaration: template for a function table entry + * - $jsname: name of the variable + * - $jswrapper: wrapper function + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_function_declaration", "templates") +%{ + {"$jsname", $jswrapper, kJSPropertyAttributeNone}, +%} + +/* ----------------------------------------------------------------------------- + * jsc_classtemplate_declaration: template for a namespace declaration + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_declaration", "templates") %{ JSClassDefinition $jsmangledname_classDefinition; @@ -154,12 +300,15 @@ JSClassDefinition $jsmangledname_objectDefinition; JSClassRef $jsmangledname_classRef; %} -/*********************************************************************** - * class_table: - * function and variable tables for class and object creation. -***********************************************************************/ - -%fragment ("JS_class_tables", "templates") +/* ----------------------------------------------------------------------------- + * jsc_class_tables: template for a namespace declaration + * - $jsmangledname: mangled class name + * - $jsstaticclassvariables: list of static variable entries + * - $jsstaticclassfunctions: list of static function entries + * - $jsclassvariables: list of member variable entries + * - $jsclassfunctions: list of member function entries + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_tables", "templates") %{ JSStaticValue $jsmangledname_staticValues[] = { $jsstaticclassvariables @@ -182,154 +331,76 @@ JSStaticFunction $jsmangledname_functions[] = { }; %} -/********************************************************************* - * destructordefn: - * This code template is used to adds the destructor wrapper function -***********************************************************************/ +/* ----------------------------------------------------------------------------- + * jsc_define_class_template: template for defining a class template + * - $jsmangledname: mangled class name + * - $jsmangledtype: mangled class type + * - $jsctor: wrapper of ctor + * - $jsbaseclass: mangled name of base class + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_definition", "templates") +%{ + $jsmangledname_classDefinition.staticFunctions = $jsmangledname_staticFunctions; + $jsmangledname_classDefinition.staticValues = $jsmangledname_staticValues; + $jsmangledname_classDefinition.callAsConstructor = $jsctor; + $jsmangledname_objectDefinition.staticValues = $jsmangledname_values; + $jsmangledname_objectDefinition.staticFunctions = $jsmangledname_functions; + $jsmangledname_objectDefinition.parentClass = $jsbaseclass_classRef; + JSClassRef $jsmangledname_classRef = JSClassCreate(&$jsmangledname_objectDefinition); + SWIGTYPE_$jsmangledtype->clientdata = $jsmangledname_classRef; +%} -%fragment ("JS_destructordefn", "templates") +/* ----------------------------------------------------------------------------- + * jsc_register_class: template for registration of a class + * - $jsname: class name + * - $jsmangledname: mangled class name + * - $jsnspace: mangled name of namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_registration", "templates") %{ -void _wrap_$jsmangledname_finalize(JSObjectRef thisObject) -{ - SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); - if(t && t->swigCMemOwn) free (($jstype*)t->swigCObject); - if(t) free(t); -} + JS_registerClass(context, $jsnspace_object, "$jsname", &$jsmangledname_classDefinition); %} -/********************************************************************* - * constructor_definition: - * This code template is used to adds the main constructor wrapper function -***********************************************************************/ - -%fragment ("JS_mainctordefn", "templates") +/* ----------------------------------------------------------------------------- + * jsc_nspace_declaration: template for a namespace declaration + * - $jsnspace: mangled name of the namespace + * - $jsglobalvariables: list of variable entries + * - $jsglobalfunctions: list if fuction entries + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_declaration", "templates") %{ -JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, - size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - JSObjectRef thisObject = NULL; - - // switch all cases by means of series of if-returns. - $jsdispatchcases +JSStaticValue $jsnspace_values[] = { + $jsglobalvariables + { 0, 0, 0, 0 } +}; - // default: - SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); - - fail: - return thisObject; -} +JSStaticFunction $jsnspace_functions[] = { + $jsglobalfunctions + { 0, 0, 0 } +}; + +JSClassDefinition $jsnspace_classDefinition; %} -%fragment ("JS_veto_ctor", "templates") +/* ----------------------------------------------------------------------------- + * jsc_nspace_definition: template for definition of a namespace object + * - $jsmangledname: mangled name of namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_definition", "templates") +%{ + $jsmangledname_classDefinition.staticFunctions = $jsmangledname_functions; + $jsmangledname_classDefinition.staticValues = $jsmangledname_values; + JSObjectRef $jsmangledname_object = JSObjectMake(context, JSClassCreate(&$jsmangledname_classDefinition), NULL); +%} + +/* ----------------------------------------------------------------------------- + * jsc_nspace_registration: template for registration of a namespace object + * - $jsname: name of namespace + * - $jsmangledname: mangled name of namespace + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_registration", "templates") %{ -JSObjectRef $jsctor(JSContextRef context, JSObjectRef ctorObject, - size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); - return 0; -} + JS_registerNamespace(context, $jsmangledname_object, $jsparent_object, "$jsname"); %} - -/************************************************************************************** -ctor_dispatch_case: This template is used for the constructor which is overloaded -***************************************************************************************/ - -%fragment ("JS_ctor_dispatch_case", "templates") -%{if(argc == $jsargcount) { - thisObject = $jswrapper(context, NULL, argc, argv, exception); - if(thisObject != NULL) { *exception=0; return thisObject; } /* reset exception and return */ - } -%} - - -%fragment ("JS_ctordefn", "templates") -%{ -JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - $jslocals - - if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); - - $jscode - - return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); - - goto fail; - fail: - return NULL; -} -%} - -/********************************************************************** -initializer:This template is dynamic growing and aggregates everything -**********************************************************************/ - -%fragment ("JS_initializer", "templates") %{ -#ifdef __cplusplus -extern "C" { -#endif - -bool $jsname_initialize(JSGlobalContextRef context) { - SWIG_InitializeModule(0); - - JSObjectRef global_object = JSContextGetGlobalObject(context); - - /* Initialize the base swig type object */ - _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; - _SwigObject_objectDefinition.staticValues = _SwigObject_values; - _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); - - /* Create objects for namespaces */ - $jscreatenamespaces - - /* Create classes */ - $jsinitializercode - - /* Register namespaces */ - $jsregisternamespaces - - return true; -} - -#ifdef __cplusplus -} -#endif - -%} - -/***************************************************************************************** - *create_class_template: - *This template is used to add a Static references to class templates. -*****************************************************************************************/ - -%fragment ("JS_create_class_template", "templates") -%{ $jsmangledname_classDefinition.staticFunctions = $jsmangledname_staticFunctions; - $jsmangledname_classDefinition.staticValues = $jsmangledname_staticValues; - $jsmangledname_classDefinition.callAsConstructor = $jsctor; - $jsmangledname_objectDefinition.staticValues = $jsmangledname_values; - $jsmangledname_objectDefinition.staticFunctions = $jsmangledname_functions; - $jsmangledname_objectDefinition.parentClass = $jsbaseclass_classRef; - JSClassRef $jsmangledname_classRef = JSClassCreate(&$jsmangledname_objectDefinition); - SWIGTYPE_$jsmangledtype->clientdata = $jsmangledname_classRef;%} - -/***************************************************************************************** - *register_class: - * This template is used to adds a class registration statement to initializer function -*****************************************************************************************/ - -%fragment ("JS_register_class", "templates") -%{JS_registerClass(context, $jsnspace_object, "$jsname", &$jsmangledname_classDefinition);%} - - -/* create and register namespaces */ - -%fragment ("JS_create_namespace", "templates") -%{ $jsmangledname_classDefinition.staticFunctions = $jsmangledname_functions; - $jsmangledname_classDefinition.staticValues = $jsmangledname_values; - JSObjectRef $jsmangledname_object = JSObjectMake(context, JSClassCreate(&$jsmangledname_classDefinition), NULL); -%} - -%fragment ("JS_register_namespace", "templates") -%{ -JS_registerNamespace(context, $jsmangledname_object, $jsparent_object, "$jsname"); %} diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index b46bacfa9..5e092528b 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -1,4 +1,4 @@ -%fragment("JS_ctordefn", "templates") %{ +%fragment("js_ctor", "templates") %{ v8::Handle $jswrapper(const v8::Arguments& args) { v8::HandleScope scope; v8::Handle self = args.Holder(); @@ -11,18 +11,36 @@ v8::Handle $jswrapper(const v8::Arguments& args) { goto fail; fail: return scope.Close(v8::Undefined()); -}%} +} +%} -%fragment ("JS_veto_ctor", "templates") +%fragment ("js_veto_ctor", "templates") %{ -v8::Handle $jsctor(const v8::Arguments& args) { +v8::Handle $jswrapper(const v8::Arguments& args) { v8::HandleScope scope; SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); return scope.Close(v8::Undefined()); } %} -%fragment ("JS_mainctordefn", "templates") %{ +%fragment("js_overloaded_ctor", "templates") %{ +v8::Handle $jswrapper(const v8::Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + $jslocals + $jscode + + SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + return scope.Close(self); + + goto fail; +fail: + return scope.Close(v8::Undefined()); +} +%} + +%fragment ("js_ctor_dispatcher", "templates") +%{ v8::Handle $jswrapper(const v8::Arguments& args) { v8::HandleScope scope; @@ -37,8 +55,9 @@ fail: } %} -%fragment ("JS_ctor_dispatch_case", "templates") -%{if(args.Length() == $jsargcount) { +%fragment ("js_ctor_dispatch_case", "templates") +%{ + if(args.Length() == $jsargcount) { v8::Handle self = $jswrapper(args); if(!self->IsUndefined()) { return scope.Close(self); @@ -46,7 +65,7 @@ fail: } %} -%fragment ("JS_destructordefn", "templates") +%fragment ("js_dtor", "templates") %{ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { SWIGV8_Proxy* proxy = (SWIGV8_Proxy*) parameter; @@ -59,8 +78,9 @@ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { %} -%fragment("JS_getproperty", "templates") %{ -v8::Handle $jsgetter(v8::Local property, const v8::AccessorInfo& info) { +%fragment("js_getter", "templates") +%{ +v8::Handle $jswrapper(v8::Local property, const v8::AccessorInfo& info) { v8::HandleScope scope; v8::Handle jsresult; $jslocals @@ -69,19 +89,23 @@ v8::Handle $jsgetter(v8::Local property, const v8::Access goto fail; fail: return scope.Close(v8::Undefined()); -}%} +} +%} -%fragment("JS_setproperty", "templates") %{ -void $jssetter(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { +%fragment("js_setter", "templates") +%{ +void $jswrapper(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { v8::HandleScope scope; $jslocals $jscode goto fail; fail: return; -}%} +} +%} -%fragment("JS_functionwrapper", "templates") %{ +%fragment("js_function", "templates") +%{ v8::Handle $jswrapper(const v8::Arguments &args) { v8::HandleScope scope; v8::Handle jsresult; @@ -94,7 +118,8 @@ fail: } %} -%fragment("JS_function_dispatcher", "templates") %{ +%fragment("js_function_dispatcher", "templates") +%{ v8::Handle $jswrapper(const v8::Arguments &args) { v8::HandleScope scope; v8::Handle jsresult; @@ -109,7 +134,7 @@ fail: } %} -%fragment ("JS_functionwrapper_overload", "templates") +%fragment ("js_overloaded_function", "templates") %{ v8::Handle $jswrapper(const v8::Arguments &args, V8ErrorHandler& SWIGV8_ErrorHandler) { @@ -126,7 +151,7 @@ fail: } %} -%fragment ("JS_function_dispatch_case", "templates") +%fragment ("js_function_dispatch_case", "templates") %{ if(args.Length() == $jsargcount) { errorHandler.err.Clear(); @@ -137,53 +162,69 @@ fail: } %} -%fragment ("JS_function_dispatch_case_default", "templates") -%{ - SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); -%} - %fragment("jsv8_declare_class_template", "templates") -%{SWIGV8_ClientData $jsmangledname_clientData; +%{ + SWIGV8_ClientData $jsmangledname_clientData; %} %fragment("jsv8_define_class_template", "templates") -%{v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); +%{ + v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); $jsmangledname_clientData.class_templ = $jsmangledname_class; $jsmangledname_clientData.dtor = $jsdtor; - SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData;%} + SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData; +%} %fragment("jsv8_inherit", "templates") -%{$jsmangledname_class->Inherit($jsbaseclass_class);%} +%{ + $jsmangledname_class->Inherit($jsbaseclass_class); +%} %fragment("jsv8_create_class_instance", "templates") -%{v8::Handle $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); +%{ + v8::Handle $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); $jsmangledname_class_0->SetCallHandler($jsctor); $jsmangledname_class_0->Inherit($jsmangledname_class); $jsmangledname_class_0->SetHiddenPrototype(true); - v8::Handle $jsmangledname_obj = $jsmangledname_class_0->GetFunction();%} + v8::Handle $jsmangledname_obj = $jsmangledname_class_0->GetFunction(); +%} %fragment("jsv8_register_class", "templates") -%{$jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj);%} +%{ + $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); +%} %fragment("jsv8_create_namespace", "templates") -%{v8::Handle $jsmangledname_obj = v8::Object::New();%} +%{ + v8::Handle $jsmangledname_obj = v8::Object::New(); +%} %fragment("jsv8_register_member_function", "templates") -%{SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper);%} +%{ + SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper); +%} %fragment("jsv8_register_member_variable", "templates") -%{SWIGV8_AddMemberVariable($jsmangledname_class, "$jsname", $jsgetter, $jssetter);%} +%{ + SWIGV8_AddMemberVariable($jsmangledname_class, "$jsname", $jsgetter, $jssetter); +%} %fragment("jsv8_register_static_function", "templates") -%{SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper);%} +%{ + SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper); +%} %fragment("jsv8_register_static_variable", "templates") -%{SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter);%} +%{ + SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter); +%} %fragment("jsv8_register_namespace", "templates") -%{$jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj);%} +%{ + $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); +%} -%fragment("JS_initializer", "templates") +%fragment("js_initializer", "templates") %{ extern "C" { @@ -194,6 +235,7 @@ void $jsname_initialize(v8::Handle context) v8::HandleScope scope; v8::Local global_obj = context->Global(); + // a class template for creating proxies of undefined types SWIGV8_SWIGTYPE_Proxy_class_templ = SWIGV8_CreateClassTemplate("SwigProxy"); /* create objects for namespaces */ @@ -219,6 +261,8 @@ void $jsname_initialize(v8::Handle context) /* create and register namespace objects */ $jsv8registernspaces + } -}%} +} // extern "C" +%} diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index db4972310..76d8b389d 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -114,6 +114,10 @@ public: void operator=(const Template& t); +protected: + + void trim(); + private: String *code; @@ -518,7 +522,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { int mode = -1; - bool debug_templates = false; for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i], "-v8") == 0) { @@ -535,7 +538,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) { SWIG_library_directory("javascript/qt"); } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { Swig_mark_arg(i); - debug_templates = true; + js_template_enable_debug = true; } } } @@ -565,10 +568,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } } - if (debug_templates) { - js_template_enable_debug = true; - } - // Add a symbol to the parser for conditional compilation Preprocessor_define("SWIGJAVASCRIPT 1", 0); @@ -811,7 +810,7 @@ int JSEmitter::emitCtor(Node *n) { bool is_overloaded = GetFlag(n, "sym:overloaded"); - Template t_ctor(getTemplate("JS_ctordefn")); + Template t_ctor(getTemplate("js_ctor")); //String *mangled_name = SwigType_manglestr(Getattr(n, "name")); String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); @@ -840,7 +839,7 @@ int JSEmitter::emitCtor(Node *n) { .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) .pretty_print(f_wrappers); - Template t_ctor_case(getTemplate("JS_ctor_dispatch_case")); + Template t_ctor_case(getTemplate("js_ctor_dispatch_case")); t_ctor_case.replace(T_WRAPPER, wrap_name) .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); @@ -851,7 +850,7 @@ int JSEmitter::emitCtor(Node *n) { if(is_overloaded) { if (!Getattr(n, "sym:nextSibling")) { String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - Template t_mainctor(getTemplate("JS_mainctordefn")); + Template t_mainctor(getTemplate("js_ctor_dispatcher")); t_mainctor.replace(T_WRAPPER, wrap_name) .replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) @@ -867,13 +866,16 @@ int JSEmitter::emitCtor(Node *n) { int JSEmitter::emitDtor(Node *n) { - Template t_dtor = getTemplate("JS_destructordefn"); + Template t_dtor = getTemplate("js_dtor"); 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(""); + + // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node + // TODO: generate dtors more similar to other wrappers if(SwigType_isarray(type)) { Printf(free, "delete [] (%s)", ctype); } else { @@ -884,6 +886,7 @@ int JSEmitter::emitDtor(Node *n) { t_dtor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_WRAPPER, wrap_name) .replace(T_FREE, free) + .replace(T_TYPE, ctype) .pretty_print(f_wrappers); Delete(p_classtype); @@ -895,7 +898,7 @@ int JSEmitter::emitDtor(Node *n) { int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { Wrapper *wrapper = NewWrapper(); - Template t_getter(getTemplate("JS_getproperty")); + Template t_getter(getTemplate("js_getter")); // prepare wrapper name String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); @@ -912,7 +915,7 @@ int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); marshalOutput(n, wrapper, action); - t_getter.replace(T_GETTER, wrap_name) + t_getter.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) .pretty_print(f_wrappers); @@ -931,7 +934,7 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { Wrapper *wrapper = NewWrapper(); - Template t_setter(getTemplate("JS_setproperty")); + Template t_setter(getTemplate("js_setter")); // prepare wrapper name String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); @@ -948,7 +951,7 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); Append(wrapper->code, action); - t_setter.replace(T_SETTER, wrap_name) + t_setter.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) .pretty_print(f_wrappers); @@ -966,7 +969,7 @@ int JSEmitter::emitConstant(Node *n) { Wrapper *wrapper = NewWrapper(); - Template t_getter(getTemplate("JS_getproperty")); + Template t_getter(getTemplate("js_getter")); // call the variable methods as a constants are // registred in same way @@ -987,7 +990,7 @@ int JSEmitter::emitConstant(Node *n) { assert(value != NULL); marshalOutput(n, wrapper, action, value, false); - t_getter.replace(T_GETTER, wrap_name) + t_getter.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) .pretty_print(f_wrappers); @@ -1002,14 +1005,14 @@ int JSEmitter::emitConstant(Node *n) { int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { Wrapper *wrapper = NewWrapper(); - Template t_function(getTemplate("JS_functionwrapper")); + Template t_function(getTemplate("js_function")); 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) { - t_function = getTemplate("JS_functionwrapper_overload"); + t_function = getTemplate("js_overloaded_function"); Append(wrap_name, Getattr(n, "sym:overname")); } Setattr(n, "wrap:name", wrap_name); @@ -1033,7 +1036,7 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { // handle function overloading if (is_overloaded) { - Template t_dispatch_case = getTemplate("JS_function_dispatch_case"); + Template t_dispatch_case = getTemplate("js_function_dispatch_case"); t_dispatch_case.replace(T_WRAPPER, wrap_name) .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); Append(state.global(FUNCTION_DISPATCHERS), t_dispatch_case.str()); @@ -1046,7 +1049,7 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { - Template t_function(getTemplate("JS_function_dispatcher")); + Template t_function(getTemplate("js_function_dispatcher")); Wrapper *wrapper = NewWrapper(); String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); @@ -1378,9 +1381,9 @@ int JSCEmitter::dump(Node *n) { emitNamespaces(); // compose the initializer function using a template - Template initializer(getTemplate("JS_initializer")); + Template initializer(getTemplate("js_initializer")); initializer.replace(T_NAME, module) - .replace("$jsinitializercode", state.global(INITIALIZER)) + .replace("$jsregisterclasses", state.global(INITIALIZER)) .replace("$jscreatenamespaces", state.global(CREATE_NAMESPACES)) .replace("$jsregisternamespaces", state.global(REGISTER_NAMESPACES)) .pretty_print(f_init); @@ -1414,7 +1417,7 @@ int JSCEmitter::enterFunction(Node *n) { } int JSCEmitter::exitFunction(Node *n) { - Template t_function = getTemplate("JS_functiondecl"); + Template t_function = getTemplate("jsc_function_declaration"); bool is_member = GetFlag(n, "ismember"); bool is_overloaded = GetFlag(n, "sym:overloaded"); @@ -1456,7 +1459,7 @@ int JSCEmitter::enterVariable(Node *n) { int JSCEmitter::exitVariable(Node *n) { - Template t_variable(getTemplate("JS_variabledecl")); + Template t_variable(getTemplate("jsc_variable_declaration")); t_variable.replace(T_NAME, state.variable(NAME)) .replace(T_GETTER, state.variable(GETTER)) .replace(T_SETTER, state.variable(SETTER)); @@ -1482,15 +1485,15 @@ int JSCEmitter::enterClass(Node *n) { state.clazz(STATIC_VARIABLES, NewString("")); state.clazz(STATIC_FUNCTIONS, NewString("")); - Template t_class_defn = getTemplate("JS_class_definition"); - t_class_defn.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + Template t_class_decl = getTemplate("jsc_class_declaration"); + t_class_decl.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .pretty_print(f_wrappers); return SWIG_OK; } int JSCEmitter::exitClass(Node *n) { - Template t_class_tables(getTemplate("JS_class_tables")); + Template t_class_tables(getTemplate("jsc_class_tables")); t_class_tables.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES)) .replace("$jsclassfunctions", state.clazz(MEMBER_FUNCTIONS)) @@ -1504,14 +1507,14 @@ int JSCEmitter::exitClass(Node *n) { // for abstract classes add a vetoing ctor if(GetFlag(state.clazz(), IS_ABSTRACT)) { - Template t_veto_ctor(getTemplate("JS_veto_ctor")); - t_veto_ctor.replace(T_CTOR, state.clazz(CTOR)) + Template t_veto_ctor(getTemplate("js_veto_ctor")); + t_veto_ctor.replace(T_WRAPPER, state.clazz(CTOR)) .replace(T_NAME, state.clazz(NAME)) .pretty_print(f_wrappers); } /* adds a class template statement to initializer function */ - Template t_classtemplate(getTemplate("JS_create_class_template")); + Template t_classtemplate(getTemplate("jsc_class_definition")); /* prepare registration of base class */ String *base_name_mangled = NewString("_SwigObject"); @@ -1531,7 +1534,7 @@ int JSCEmitter::exitClass(Node *n) { SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); /* adds a class registration statement to initializer function */ - Template t_registerclass(getTemplate("JS_register_class")); + Template t_registerclass(getTemplate("jsc_class_registration")); t_registerclass.replace(T_NAME, state.clazz(NAME)) .replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_NAMESPACE, Getattr(current_namespace, NAME_MANGLED)) @@ -1558,17 +1561,17 @@ int JSCEmitter::emitNamespaces() { String *functions = Getattr(entry, "functions"); String *variables = Getattr(entry, "values"); - Template namespace_definition(getTemplate("JS_globaldefn")); + Template namespace_definition(getTemplate("jsc_nspace_declaration")); namespace_definition.replace("$jsglobalvariables", variables) .replace("$jsglobalfunctions", functions) .replace(T_NAMESPACE, name_mangled) .pretty_print(f_wrap_cpp); - Template t_createNamespace(getTemplate("JS_create_namespace")); + Template t_createNamespace(getTemplate("jsc_nspace_definition")); t_createNamespace.replace(T_NAME_MANGLED, name_mangled); Append(state.global(CREATE_NAMESPACES), t_createNamespace.str()); - Template t_registerNamespace(getTemplate("JS_register_namespace")); + Template t_registerNamespace(getTemplate("jsc_nspace_registration")); t_registerNamespace.replace(T_NAME_MANGLED, name_mangled) .replace(T_NAME, name) .replace(T_PARENT, parent_mangled); @@ -1708,7 +1711,7 @@ int V8Emitter::dump(Node *n) // compose the initializer function using a template // filled with sub-parts - Template initializer(getTemplate("JS_initializer")); + Template initializer(getTemplate("js_initializer")); initializer.replace(T_NAME, module) .replace(V8_NAME_SPACES, f_init_namespaces) .replace(V8_CLASS_TEMPLATES, f_init_class_templates) @@ -1762,8 +1765,8 @@ int V8Emitter::enterClass(Node *n) int V8Emitter::exitClass(Node *n) { if(GetFlag(state.clazz(), IS_ABSTRACT)) { - Template t_veto_ctor(getTemplate("JS_veto_ctor")); - t_veto_ctor.replace(T_CTOR, state.clazz(CTOR)) + Template t_veto_ctor(getTemplate("js_veto_ctor")); + t_veto_ctor.replace(T_WRAPPER, state.clazz(CTOR)) .replace(T_NAME, state.clazz(NAME)) .pretty_print(f_wrappers); } @@ -2001,7 +2004,7 @@ void V8Emitter::emitUndefined() { .pretty_print(f_class_templates); // emit an extra dtor for unknown types - Template t_dtor = getTemplate("JS_destructordefn"); + Template t_dtor = getTemplate("js_dtor"); t_dtor.replace(T_NAME_MANGLED, mangled_name) .replace(T_WRAPPER, dtor) .replace(T_FREE, free) @@ -2134,6 +2137,8 @@ Template::Template(const String *code_) { } code = NewString(code_); templateName = NewString(""); + + trim(); } Template::Template(const String *code_, const String *templateName_) { @@ -2145,6 +2150,8 @@ Template::Template(const String *code_, const String *templateName_) { code = NewString(code_); templateName = NewString(templateName_); + + trim(); } @@ -2179,6 +2186,36 @@ String *Template::str() { return code; } +void Template::trim() { + const char* str = Char(code); + if (str == 0) return; + + int length = Len(code); + if (length == 0) return; + + int idx; + for(idx=0; idx < length; ++idx) { + 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') + break; + } + int end_pos = idx; + + int new_length = end_pos-start_pos+1; + char* newstr = new char[new_length+1]; + memcpy(newstr, str+start_pos, new_length); + newstr[new_length] = 0; + + Delete(code); + code = NewString(newstr); + delete[] newstr; +} + /* ----------------------------------------------------------------------------- * Template& Template::replace(const String* pattern, const String* repl) : * From 9b06144d39f3f1b820ee90ad0bf1c2cf96cbaf6a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:16:09 +0000 Subject: [PATCH 093/352] Fix handling of overloaded ctors in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13827 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/v8/javascriptcode.swg | 49 +++++++++++++++------------- Source/Modules/javascript.cxx | 6 ++-- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 5e092528b..78316c80b 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -3,6 +3,7 @@ v8::Handle $jswrapper(const v8::Arguments& args) { v8::HandleScope scope; v8::Handle self = args.Holder(); $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); @@ -23,11 +24,30 @@ v8::Handle $jswrapper(const v8::Arguments& args) { } %} -%fragment("js_overloaded_ctor", "templates") %{ +%fragment ("js_ctor_dispatcher", "templates") +%{ v8::Handle $jswrapper(const v8::Arguments& args) { + v8::HandleScope scope; + OverloadErrorHandler errorHandler; + v8::Handle self; + + // switch all cases by means of series of if-returns. + $jsdispatchcases + + // default: + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); + +fail: + scope.Close(v8::Undefined()); +} +%} + +%fragment("js_overloaded_ctor", "templates") %{ +v8::Handle $jswrapper(const v8::Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) { v8::HandleScope scope; v8::Handle self = args.Holder(); $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); @@ -39,27 +59,12 @@ fail: } %} -%fragment ("js_ctor_dispatcher", "templates") -%{ -v8::Handle $jswrapper(const v8::Arguments& args) { - v8::HandleScope scope; - - // switch all cases by means of series of if-returns. - $jsdispatchcases - - // default: - SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); - -fail: - scope.Close(v8::Undefined()); -} -%} - %fragment ("js_ctor_dispatch_case", "templates") %{ if(args.Length() == $jsargcount) { - v8::Handle self = $jswrapper(args); - if(!self->IsUndefined()) { + errorHandler.err.Clear(); + self = $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { return scope.Close(self); } } @@ -110,6 +115,8 @@ v8::Handle $jswrapper(const v8::Arguments &args) { v8::HandleScope scope; v8::Handle jsresult; $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + $jscode return scope.Close(jsresult); goto fail; @@ -138,11 +145,9 @@ fail: %{ v8::Handle $jswrapper(const v8::Arguments &args, V8ErrorHandler& SWIGV8_ErrorHandler) { - v8::HandleScope scope; - + v8::HandleScope scope; v8::Handle jsresult; $jslocals - if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode return scope.Close(jsresult); goto fail; diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 76d8b389d..a713d8fa7 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -815,6 +815,7 @@ int JSEmitter::emitCtor(Node *n) { //String *mangled_name = SwigType_manglestr(Getattr(n, "name")); String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); if(is_overloaded) { + t_ctor = getTemplate("js_overloaded_ctor"); Append(wrap_name, Getattr(n, "sym:overname")); } Setattr(n, "wrap:name", wrap_name); @@ -1909,12 +1910,12 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar Parm *p; int startIdx = 0; - if (is_member && !is_static) { + if (is_member && !is_static && mode!=Ctor) { startIdx = 1; } // store number of arguments for argument checks - int num_args = emit_num_arguments(parms); + int num_args = emit_num_arguments(parms) - startIdx; String *argcount = NewString(""); Printf(argcount, "%d", num_args); Setattr(n, ARGCOUNT, argcount); @@ -1922,7 +1923,6 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar int i = 0; for (p = parms; p; p = nextSibling(p), i++) { String *arg = NewString(""); - switch (mode) { case Getter: if (is_member && !is_static && i == 0) { From 217ffb11d0cbcfbcfbaa679bd815a80b897b1c8b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:16:26 +0000 Subject: [PATCH 094/352] Fix regressions of latest commits. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13828 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptcode.swg | 17 +++++++++++++--- Source/Modules/javascript.cxx | 28 +++++++++++++-------------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 9a91c874a..73c127103 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -11,13 +11,10 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { $jslocals - if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode - return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); - goto fail; fail: return NULL; @@ -63,6 +60,20 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, } %} +%fragment ("js_overloaded_ctor", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + $jscode + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + + goto fail; + fail: + return NULL; +} +%} + /* ----------------------------------------------------------------------------- * js_ctor_dispatch_case: template for a dispatch case for calling an overloaded ctor. * - $jsargcount: number of arguments of called ctor diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index a713d8fa7..3c2c872c8 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1075,18 +1075,16 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { void JSEmitter::registerProxyType(SwigType* type) { SwigType *ftype = SwigType_typedef_resolve_all(type); + if(Language::instance()->classLookup(ftype)) return; + + // TODO: confused... more try and error... understand and fix eventually + SwigType *p_ftype = SwigType_add_pointer(ftype); // 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); - } + SwigType_remember_clientdata(p_ftype, 0); + Setattr(undefined_types, SwigType_manglestr(p_ftype), p_ftype); + Delete(ftype); } void JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) { @@ -1119,7 +1117,9 @@ void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, co if(cresult == 0) cresult = defaultResultName; tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode); - if(GetFlag(n, "feature:new")) { + bool should_own = GetFlag(n, "feature:new"); + bool needs_proxy = GetFlag(n, "tmap:out:SWIGTYPE"); + if(needs_proxy) { registerProxyType(type); } @@ -1127,7 +1127,7 @@ void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, co Replaceall(tm, "$result", "jsresult"); Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); - if (GetFlag(n, "feature:new")) { + if (should_own) { Replaceall(tm, "$owner", "SWIG_POINTER_OWN"); } else { Replaceall(tm, "$owner", "0"); @@ -1985,10 +1985,10 @@ int V8Emitter::emitNamespaces() { void V8Emitter::emitUndefined() { Iterator ki; for (ki = First(undefined_types); ki.item; ki = Next(ki)) { - String *mangled_name = ki.key; + String *mangled_name = NewStringf("SWIGTYPE%s", ki.key); SwigType *type = ki.item; String *dtor = Swig_name_destroy("", mangled_name); - String *type_mangled = SwigType_manglestr(type); + String *type_mangled = ki.key; String *ctype = SwigType_lstr(type, ""); String *free = NewString(""); @@ -2018,9 +2018,9 @@ void V8Emitter::emitUndefined() { .replace(T_DTOR, dtor) .pretty_print(f_init_class_templates); + Delete(mangled_name); Delete(dtor); Delete(free); - Delete(type_mangled); Delete(ctype); } From 86cb62146661f89f9cd3dd76c721ddfed529b99d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:16:42 +0000 Subject: [PATCH 095/352] Add comments to v8 code templates. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13829 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Lib/javascript/jsc/javascriptcode.swg | 8 ++ Lib/javascript/v8/javascriptcode.swg | 195 +++++++++++++++++++++++--- 2 files changed, 182 insertions(+), 21 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 73c127103..34245ed14 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -60,6 +60,14 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, } %} +/* ----------------------------------------------------------------------------- + * js_overloaded_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ %fragment ("js_overloaded_ctor", "templates") %{ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 78316c80b..eb95cb1bf 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -1,3 +1,11 @@ +/* ----------------------------------------------------------------------------- + * js_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ %fragment("js_ctor", "templates") %{ v8::Handle $jswrapper(const v8::Arguments& args) { v8::HandleScope scope; @@ -15,6 +23,11 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_veto_ctor: a vetoing ctor for abstract classes + * - $jswrapper: name of wrapper + * - $jsname: class name + * ----------------------------------------------------------------------------- */ %fragment ("js_veto_ctor", "templates") %{ v8::Handle $jswrapper(const v8::Arguments& args) { @@ -24,6 +37,12 @@ v8::Handle $jswrapper(const v8::Arguments& args) { } %} +/* ----------------------------------------------------------------------------- + * js_ctor_dispatcher: dispatcher for overloaded constructors + * - $jswrapper: name of wrapper + * - $jsname: class name + * - $jsdispatchcases: part containing code for dispatching + * ----------------------------------------------------------------------------- */ %fragment ("js_ctor_dispatcher", "templates") %{ v8::Handle $jswrapper(const v8::Arguments& args) { @@ -42,6 +61,14 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_overloaded_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ %fragment("js_overloaded_ctor", "templates") %{ v8::Handle $jswrapper(const v8::Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) { v8::HandleScope scope; @@ -59,6 +86,13 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_ctor_dispatch_case: template for a dispatch case for calling an overloaded ctor. + * - $jsargcount: number of arguments of called ctor + * - $jswrapper: wrapper of called ctor + * + * Note: a try-catch-like mechanism is used to switch cases + * ----------------------------------------------------------------------------- */ %fragment ("js_ctor_dispatch_case", "templates") %{ if(args.Length() == $jsargcount) { @@ -70,6 +104,11 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * ----------------------------------------------------------------------------- */ %fragment ("js_dtor", "templates") %{ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { @@ -82,7 +121,12 @@ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { } %} - +/* ----------------------------------------------------------------------------- + * js_getter: template for getter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ %fragment("js_getter", "templates") %{ v8::Handle $jswrapper(v8::Local property, const v8::AccessorInfo& info) { @@ -97,6 +141,12 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_setter: template for setter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ %fragment("js_setter", "templates") %{ void $jswrapper(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { @@ -109,6 +159,12 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_function: template for function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ %fragment("js_function", "templates") %{ v8::Handle $jswrapper(const v8::Arguments &args) { @@ -125,6 +181,13 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_function_dispatcher: template for a function dispatcher for overloaded functions + * - $jswrapper: wrapper function name + * - $jsname: name of the wrapped function + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ %fragment("js_function_dispatcher", "templates") %{ v8::Handle $jswrapper(const v8::Arguments &args) { @@ -141,6 +204,12 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_overloaded_function: template for a overloaded function + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ %fragment ("js_overloaded_function", "templates") %{ v8::Handle $jswrapper(const v8::Arguments &args, V8ErrorHandler& SWIGV8_ErrorHandler) @@ -156,6 +225,12 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * js_function_dispatch_case: template for a case used in the function dispatcher + * - $jswrapper: wrapper function name + * - $jsargcount: number of arguments of overloaded function + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ %fragment ("js_function_dispatch_case", "templates") %{ if(args.Length() == $jsargcount) { @@ -167,11 +242,21 @@ fail: } %} +/* ----------------------------------------------------------------------------- + * jsv8_declare_class_template: template for a class template declaration. + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ %fragment("jsv8_declare_class_template", "templates") %{ SWIGV8_ClientData $jsmangledname_clientData; %} +/* ----------------------------------------------------------------------------- + * jsv8_define_class_template: template for a class template definition. + * - $jsmangledname: mangled class name + * - $jsmangledtype: mangled class type + * - $jsdtor: the dtor wrapper + * ----------------------------------------------------------------------------- */ %fragment("jsv8_define_class_template", "templates") %{ v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); @@ -180,11 +265,21 @@ fail: SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData; %} +/* ----------------------------------------------------------------------------- + * jsv8_inherit: template for an class inherit statement. + * - $jsmangledname: mangled class name + * - $jsbaseclass: mangled name of the base class + * ----------------------------------------------------------------------------- */ %fragment("jsv8_inherit", "templates") %{ $jsmangledname_class->Inherit($jsbaseclass_class); %} +/* ----------------------------------------------------------------------------- + * jsv8_create_class_instance: template for creating an class object. + * - $jsname: class name + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ %fragment("jsv8_create_class_instance", "templates") %{ v8::Handle $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); @@ -194,41 +289,99 @@ fail: v8::Handle $jsmangledname_obj = $jsmangledname_class_0->GetFunction(); %} +/* ----------------------------------------------------------------------------- + * jsv8_register_class: template for a statement that registers a class in a parent namespace. + * - $jsname: class name + * - $jsmangledname: mangled class name + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ %fragment("jsv8_register_class", "templates") %{ $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); %} +/* ----------------------------------------------------------------------------- + * jsv8_create_namespace: template for a statement that creates a namespace object. + * - $jsmangledname: mangled namespace name + * ----------------------------------------------------------------------------- */ %fragment("jsv8_create_namespace", "templates") %{ v8::Handle $jsmangledname_obj = v8::Object::New(); %} -%fragment("jsv8_register_member_function", "templates") -%{ - SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper); -%} - -%fragment("jsv8_register_member_variable", "templates") -%{ - SWIGV8_AddMemberVariable($jsmangledname_class, "$jsname", $jsgetter, $jssetter); -%} - -%fragment("jsv8_register_static_function", "templates") -%{ - SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper); -%} - -%fragment("jsv8_register_static_variable", "templates") -%{ - SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter); -%} - +/* ----------------------------------------------------------------------------- + * jsv8_register_namespace: template for a statement that registers a namespace in a parent namespace. + * - $jsname: name of namespace + * - $jsmangledname: mangled name of namespace + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ %fragment("jsv8_register_namespace", "templates") %{ $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); %} +/* ----------------------------------------------------------------------------- + * jsv8_register_member_function: template for a statement that registers a member function. + * - $jsmangledname: mangled class name + * - $jsname: name of the function + * - $jswrapper: wrapper of the member function + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_member_function", "templates") +%{ + SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_member_variable: template for a statement that registers a member variable. + * - $jsmangledname: mangled class name + * - $jsname: name of the function + * - $jsgetter: wrapper of the getter function + * - $jssetter: wrapper of the setter function + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_member_variable", "templates") +%{ + SWIGV8_AddMemberVariable($jsmangledname_class, "$jsname", $jsgetter, $jssetter); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_static_function: template for a statement that registers a static class function. + * - $jsname: function name + * - $jswrapper: wrapper of the function + * - $jsparent: mangled name of parent namespace + * + * Note: this template is also used for global functions. + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_static_function", "templates") +%{ + SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_static_variable: template for a statement that registers a static variable. + * - $jsname: variable name + * - $jsparent: mangled name of parent namespace + * - $jsgetter: wrapper of the getter function + * - $jssetter: wrapper of the setter function + * + * Note: this template is also used for global variables. + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_static_variable", "templates") +%{ + SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter); +%} + +/* ----------------------------------------------------------------------------- + * js_initializer: template for the module initializer function + * - $jsname: module name + * - $jsv8nspaces: part with code creating namespace objects + * - $jsv8classtemplates: part with code creating class templates + * - $jsv8wrappers: part with code that registers wrapper functions + * - $jsv8inheritance: part with inherit statements + * - $jsv8classinstances: part with code creating class objects + * - $jsv8staticwrappers: part with code adding static functions to class objects + * - $jsv8registerclasses: part with code that registers class objects in namespaces + * - $jsv8registernspaces: part with code that registers namespaces in parent namespaces + * ----------------------------------------------------------------------------- */ %fragment("js_initializer", "templates") %{ extern "C" { From 94730dad7a5d00468d4b2798c7cbd04db6b1d30d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 8 Sep 2012 01:16:54 +0000 Subject: [PATCH 096/352] Beautify output of v8 emitter. Trimming some of the code templates. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13830 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- Source/Modules/javascript.cxx | 69 +++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 3c2c872c8..ea1172c67 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -114,9 +114,7 @@ public: void operator=(const Template& t); -protected: - - void trim(); + Template& trim(); private: @@ -1604,7 +1602,6 @@ public: 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 @@ int V8Emitter::enterClass(Node *n) // 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 @@ int V8Emitter::exitClass(Node *n) // 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 @@ int V8Emitter::exitVariable(Node* n) { 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 @@ int V8Emitter::exitFunction(Node* n) // 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 @@ int V8Emitter::emitNamespaces() { 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 @@ void V8Emitter::emitUndefined() { // 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 @@ void V8Emitter::emitUndefined() { 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 @@ void V8Emitter::emitUndefined() { .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 @@ Template::Template(const String *code_) { } code = NewString(code_); templateName = NewString(""); - - trim(); } Template::Template(const String *code_, const String *templateName_) { @@ -2150,8 +2155,6 @@ Template::Template(const String *code_, const String *templateName_) { code = NewString(code_); templateName = NewString(templateName_); - - trim(); } @@ -2186,22 +2189,22 @@ String *Template::str() { 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 @@ void Template::trim() { Delete(code); code = NewString(newstr); delete[] newstr; + + return *this; } /* ----------------------------------------------------------------------------- From 57980975a0f86961b3a9545fd24f34575609c6c7 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 16 Nov 2012 22:10:02 +0100 Subject: [PATCH 097/352] Generate cleanup code. --- Source/Modules/javascript.cxx | 241 +++++++++++++++++++--------------- 1 file changed, 134 insertions(+), 107 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index ea1172c67..d43af979d 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -61,19 +61,19 @@ bool js_template_enable_debug = false; * named sub-hashes for class, variable, and function states. */ class JSEmitterState { - + public: JSEmitterState(); ~JSEmitterState(); - + DOH *global(); - + DOH *global(const char* key, DOH *initial = 0); - + DOH *clazz(bool reset = false); - + DOH *clazz(const char* key, DOH *initial = 0); DOH *function(bool reset = false); @@ -83,9 +83,9 @@ public: DOH *variable(bool reset = false); DOH *variable(const char* key, DOH *initial = 0); - + static int IsSet(DOH *val); - + private: DOH *getState(const char* key, bool reset = false); @@ -94,7 +94,7 @@ private: }; /** - * A convenience class that wraps a code snippet used as template + * A convenience class that wraps a code snippet used as template * for code generation. */ class Template { @@ -111,7 +111,7 @@ public: Template& replace(const String *pattern, const String *repl); Template& pretty_print(DOH *doh); - + void operator=(const Template& t); Template& trim(); @@ -169,7 +169,7 @@ public: /** * Switches the context for code generation. - * + * * Classes, global variables and global functions may need to * be registered in certain static tables. * This method should be used to switch output DOHs correspondingly. @@ -224,7 +224,7 @@ public: /** * Registers a given code snippet for a given key name. - * + * * This method is called by the fragmentDirective handler * of the JAVASCRIPT language module. **/ @@ -267,18 +267,20 @@ protected: 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, Wrapper *wrapper, String *actioncode, const String *cresult=0, bool emitReturnVariable = true); + virtual void emitCleanupCode(Wrapper *wrapper, ParmList *params); + void registerProxyType(SwigType* type); /** * Helper function to retrieve the first parent class node. */ Node *getBaseClass(Node *n); - + Parm *skipIgnoredArgs(Parm *p); virtual int createNamespace(String *scope); @@ -286,14 +288,14 @@ protected: virtual Hash *createNamespaceEntry(const char *name, const char *parent); virtual int emitNamespaces() = 0; - + protected: Hash *templates; - + State state; - + // contains context specific data (DOHs) // to allow generation of namespace related code // which are switched on namespace change @@ -303,7 +305,7 @@ protected: Hash *undefined_types; String *defaultResultName; - + File *f_wrappers; }; @@ -322,7 +324,7 @@ class JAVASCRIPT:public Language { public: JAVASCRIPT(): emitter(NULL) {} - + ~JAVASCRIPT() { delete emitter; } @@ -337,7 +339,7 @@ public: virtual int constantWrapper(Node *n); virtual void main(int argc, char *argv[]); virtual int top(Node *n); - + /** * Registers all %fragments assigned to section "templates". **/ @@ -351,7 +353,7 @@ private: /* --------------------------------------------------------------------- * functionWrapper() * - * Low level code generator for functions + * Low level code generator for functions * --------------------------------------------------------------------- */ int JAVASCRIPT::functionWrapper(Node *n) { @@ -359,14 +361,14 @@ int JAVASCRIPT::functionWrapper(Node *n) { // note: the default implementation only prints a message // Language::functionWrapper(n); emitter->emitWrapperFunction(n); - + return SWIG_OK; } /* --------------------------------------------------------------------- * functionHandler() * - * Function handler for generating wrappers for functions + * Function handler for generating wrappers for functions * --------------------------------------------------------------------- */ int JAVASCRIPT::functionHandler(Node *n) { @@ -384,20 +386,20 @@ int JAVASCRIPT::functionHandler(Node *n) { /* --------------------------------------------------------------------- * globalfunctionHandler() * - * Function handler for generating wrappers for functions + * Function handler for generating wrappers for functions * --------------------------------------------------------------------- */ int JAVASCRIPT::globalfunctionHandler(Node *n) { emitter->switchNamespace(n); Language::globalfunctionHandler(n); - + return SWIG_OK; } /* --------------------------------------------------------------------- * staticmemberfunctionHandler() * - * Function handler for generating wrappers for static member functions + * Function handler for generating wrappers for static member functions * --------------------------------------------------------------------- */ int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { @@ -406,19 +408,19 @@ int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { * So, don't rely on that after here. Instead use the state variable which is * set by JSEmitter::enterFunction(). */ - Language::staticmemberfunctionHandler(n); + Language::staticmemberfunctionHandler(n); return SWIG_OK; } /* --------------------------------------------------------------------- * variableHandler() * - * Function handler for generating wrappers for variables + * Function handler for generating wrappers for variables * --------------------------------------------------------------------- */ int JAVASCRIPT::variableHandler(Node *n) { - emitter->enterVariable(n); + emitter->enterVariable(n); Language::variableHandler(n); emitter->exitVariable(n); @@ -428,7 +430,7 @@ int JAVASCRIPT::variableHandler(Node *n) { /* --------------------------------------------------------------------- * globalvariableHandler() * - * Function handler for generating wrappers for global variables + * Function handler for generating wrappers for global variables * --------------------------------------------------------------------- */ int JAVASCRIPT::globalvariableHandler(Node *n) { @@ -442,7 +444,7 @@ int JAVASCRIPT::globalvariableHandler(Node *n) { /* --------------------------------------------------------------------- * constantHandler() * - * Function handler for generating wrappers for constants + * Function handler for generating wrappers for constants * --------------------------------------------------------------------- */ int JAVASCRIPT::constantWrapper(Node *n) { @@ -460,7 +462,7 @@ int JAVASCRIPT::constantWrapper(Node *n) { /* --------------------------------------------------------------------- * classHandler() * - * Function handler for generating wrappers for class + * Function handler for generating wrappers for class * --------------------------------------------------------------------- */ int JAVASCRIPT::classHandler(Node *n) { @@ -491,8 +493,8 @@ int JAVASCRIPT::fragmentDirective(Node *n) { /* --------------------------------------------------------------------- * top() * - * Function handler for processing top node of the parse tree - * Wrapper code generation essentially starts from here + * Function handler for processing top node of the parse tree + * Wrapper code generation essentially starts from here * --------------------------------------------------------------------- */ int JAVASCRIPT::top(Node *n) { @@ -569,10 +571,10 @@ void JAVASCRIPT::main(int argc, char *argv[]) { // Add a symbol to the parser for conditional compilation Preprocessor_define("SWIGJAVASCRIPT 1", 0); - // Add typemap definitions + // Add typemap definitions SWIG_typemap_lang("javascript"); - // Set configuration file + // Set configuration file SWIG_config_file("javascript.swg"); allow_overloading(); @@ -600,7 +602,7 @@ extern "C" Language *swig_javascript(void) { JSEmitter::JSEmitter() : templates(NewHash()), - namespaces(NULL), + namespaces(NULL), current_namespace(NULL), undefined_types(NewHash()), defaultResultName(NewString("result")), @@ -618,7 +620,7 @@ JSEmitter::~JSEmitter() { /* ----------------------------------------------------------------------------- * JSEmitter::RegisterTemplate() : Registers a code template - * + * * Note: this is used only by JAVASCRIPT::fragmentDirective(). * ----------------------------------------------------------------------------- */ @@ -656,9 +658,9 @@ int JSEmitter::initialize(Node * n) { Hash *global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); Setattr(namespaces, "::", global_namespace); current_namespace = global_namespace; - + f_wrappers = NewString(""); - + return SWIG_OK; } @@ -675,7 +677,7 @@ Parm *JSEmitter::skipIgnoredArgs(Parm *p) { /* ----------------------------------------------------------------------------- * JSEmitter::getBaseClass() : the node of the base class or NULL - * + * * Note: the first base class is provided. Multiple inheritance is not * supported. * ----------------------------------------------------------------------------- */ @@ -695,7 +697,7 @@ Node *JSEmitter::getBaseClass(Node *n) { /* ----------------------------------------------------------------------------- * JSEmitter::emitWrapperFunction() : dispatches emitter functions. - * + * * This allows to have small sized, dedicated emitting functions. * All state dependent branching is done here. * ----------------------------------------------------------------------------- */ @@ -762,7 +764,7 @@ int JSEmitter::enterClass(Node *n) { // HACK: assume that a class is abstract // this is resolved by emitCtor (which is only called for non abstract classes) SetFlag(state.clazz(), IS_ABSTRACT); - + return SWIG_OK; } @@ -773,7 +775,7 @@ int JSEmitter::enterFunction(Node *n) { if(Equal(Getattr(n, "storage"), "static")) { SetFlag(state.function(), IS_STATIC); } - + /* Initialize DOH for collecting function dispatchers */ bool is_overloaded = GetFlag(n, "sym:overloaded"); if (is_overloaded && state.global(FUNCTION_DISPATCHERS) == 0) { @@ -787,14 +789,14 @@ int JSEmitter::enterVariable(Node *n) { state.variable(true); state.variable(NAME, Swig_scopename_last(Getattr(n, "name"))); - + if(Equal(Getattr(n, "storage"), "static")) { SetFlag(state.variable(), IS_STATIC); } if (!Language::instance()->is_assignable(n) // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] - // probably some error in char[] typemap + // probably some error in char[] typemap || Equal(Getattr(n, "type"), "a().char")) { SetFlag(state.variable(), IS_IMMUTABLE); } @@ -803,11 +805,11 @@ int JSEmitter::enterVariable(Node *n) { } int JSEmitter::emitCtor(Node *n) { - + Wrapper *wrapper = NewWrapper(); bool is_overloaded = GetFlag(n, "sym:overloaded"); - + Template t_ctor(getTemplate("js_ctor")); //String *mangled_name = SwigType_manglestr(Getattr(n, "name")); @@ -831,6 +833,9 @@ int JSEmitter::emitCtor(Node *n) { marshalInputArgs(n, params, wrapper, Ctor, true, false); Printv(wrapper->code, action, "\n", 0); + + emitCleanupCode(wrapper, params); + t_ctor.replace(T_WRAPPER, wrap_name) .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) .replace(T_LOCALS, wrapper->locals) @@ -842,7 +847,7 @@ int JSEmitter::emitCtor(Node *n) { t_ctor_case.replace(T_WRAPPER, wrap_name) .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); - + DelWrapper(wrapper); // create a dispatching ctor @@ -874,7 +879,7 @@ int JSEmitter::emitDtor(Node *n) { String *free = NewString(""); // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node - // TODO: generate dtors more similar to other wrappers + // TODO: generate dtors more similar to other wrappers if(SwigType_isarray(type)) { Printf(free, "delete [] (%s)", ctype); } else { @@ -891,14 +896,14 @@ int JSEmitter::emitDtor(Node *n) { Delete(p_classtype); Delete(ctype); Delete(free); - + return SWIG_OK; } int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { Wrapper *wrapper = NewWrapper(); Template t_getter(getTemplate("js_getter")); - + // prepare wrapper name String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); Setattr(n, "wrap:name", wrap_name); @@ -914,6 +919,8 @@ int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); marshalOutput(n, wrapper, action); + emitCleanupCode(wrapper, params); + t_getter.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) @@ -930,7 +937,7 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { if (State::IsSet(state.variable(IS_IMMUTABLE))) { return SWIG_OK; } - + Wrapper *wrapper = NewWrapper(); Template t_setter(getTemplate("js_setter")); @@ -950,6 +957,8 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); Append(wrapper->code, action); + emitCleanupCode(wrapper, params); + t_setter.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) @@ -967,7 +976,7 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { int JSEmitter::emitConstant(Node *n) { Wrapper *wrapper = NewWrapper(); - + Template t_getter(getTemplate("js_getter")); // call the variable methods as a constants are @@ -1002,8 +1011,8 @@ int JSEmitter::emitConstant(Node *n) { } int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { - - Wrapper *wrapper = NewWrapper(); + + Wrapper *wrapper = NewWrapper(); Template t_function(getTemplate("js_function")); bool is_overloaded = GetFlag(n, "sym:overloaded"); @@ -1027,6 +1036,8 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Function, is_member, is_static); marshalOutput(n, wrapper, action); + emitCleanupCode(wrapper, params); + t_function.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code) @@ -1040,7 +1051,7 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); Append(state.global(FUNCTION_DISPATCHERS), t_dispatch_case.str()); } - + DelWrapper(wrapper); return SWIG_OK; @@ -1058,7 +1069,7 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { t_function.replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code); - + // call this here, to replace all variables t_function.replace(T_WRAPPER, wrap_name) .replace(T_NAME, state.function(NAME)) @@ -1074,7 +1085,7 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { void JSEmitter::registerProxyType(SwigType* type) { SwigType *ftype = SwigType_typedef_resolve_all(type); if(Language::instance()->classLookup(ftype)) return; - + // TODO: confused... more try and error... understand and fix eventually SwigType *p_ftype = SwigType_add_pointer(ftype); @@ -1140,8 +1151,24 @@ void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, co } } +void JSEmitter::emitCleanupCode(Wrapper *wrapper, ParmList *params) { + Parm *p; + String *tm; + + for (p = params; p;) { + if ((tm = Getattr(p, "tmap:freearg"))) { + //addThrows(n, "tmap:freearg", p); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } +} + int JSEmitter::switchNamespace(Node *n) { - + if (!GetFlag(n, "feature:nspace")) { current_namespace = Getattr(namespaces, "::"); } else { @@ -1188,7 +1215,7 @@ Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent) { Setattr(entry, NAME, Swig_scopename_last(name)); Setattr(entry, NAME_MANGLED, Swig_name_mangle(name)); Setattr(entry, PARENT, NewString(parent)); - + Delete(name); return entry; } @@ -1196,7 +1223,7 @@ Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent) { /********************************************************************** * JavascriptCore: JSEmitter implementation for JavascriptCore engine **********************************************************************/ - + class JSCEmitter:public JSEmitter { public: @@ -1259,13 +1286,13 @@ private: #define STATIC_VARIABLES "static_variables" JSCEmitter::JSCEmitter() -: JSEmitter(), +: JSEmitter(), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), GLOBAL_STR(NULL), f_wrap_cpp(NULL), - f_runtime(NULL), - f_header(NULL), + f_runtime(NULL), + f_header(NULL), f_init(NULL) { } @@ -1332,7 +1359,7 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma } int JSCEmitter::initialize(Node *n) { - + JSEmitter::initialize(n); /* Get the output file name */ @@ -1464,7 +1491,7 @@ int JSCEmitter::exitVariable(Node *n) { .replace(T_SETTER, state.variable(SETTER)); if (GetFlag(n, "ismember")) { - if (GetFlag(state.function(), IS_STATIC) + if (GetFlag(state.function(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) { Append(state.clazz(STATIC_VARIABLES), t_variable.str()); } else { @@ -1589,7 +1616,7 @@ JSEmitter *swig_javascript_create_JSCEmitter() { **********************************************************************/ class V8Emitter: public JSEmitter { - + public: V8Emitter(); @@ -1616,10 +1643,10 @@ private: String *f_runtime; String *f_header; String *f_init; - + /* part for class templates */ String *f_class_templates; - + /* parts for initilizer */ String *f_init_namespaces; String *f_init_class_templates; @@ -1629,18 +1656,18 @@ private: String *f_init_static_wrappers; String *f_init_register_classes; String *f_init_register_namespaces; - + // the output cpp file File *f_wrap_cpp; - + String* GLOBAL; String* NULL_STR; String *VETO_SET; }; -V8Emitter::V8Emitter() -: JSEmitter(), +V8Emitter::V8Emitter() +: JSEmitter(), GLOBAL(NewString("global")), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) @@ -1657,7 +1684,7 @@ V8Emitter::~V8Emitter() int V8Emitter::initialize(Node *n) { JSEmitter::initialize(n); - + // Get the output file name String *outfile = Getattr(n,"outfile"); f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); @@ -1670,7 +1697,7 @@ int V8Emitter::initialize(Node *n) f_header = NewString(""); f_class_templates = NewString(""); f_init = NewString(""); - + f_init_namespaces = NewString(""); f_init_class_templates = NewString(""); f_init_wrappers = NewString(""); @@ -1739,19 +1766,19 @@ int V8Emitter::close() Delete(f_init_class_instances); Delete(f_init_static_wrappers); Delete(f_init_register_classes); - Delete(f_init_register_namespaces); - + Delete(f_init_register_namespaces); + // files Close(f_wrap_cpp); Delete(f_wrap_cpp); - + return SWIG_OK; } int V8Emitter::enterClass(Node *n) { JSEmitter::enterClass(n); - + // 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)) @@ -1774,7 +1801,7 @@ int V8Emitter::exitClass(Node *n) String *clientData = NewString(""); Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED)); 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); @@ -1792,7 +1819,7 @@ int V8Emitter::exitClass(Node *n) .replace(T_CTOR, state.clazz(CTOR)) .trim() .pretty_print(f_init_class_instances); - + // emit inheritance setup Node* baseClass = getBaseClass(n); if(baseClass) { @@ -1804,7 +1831,7 @@ int V8Emitter::exitClass(Node *n) .pretty_print(f_init_inheritance); Delete(base_name_mangled); } - + // emit registeration of class template Template t_register = getTemplate("jsv8_register_class"); t_register.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) @@ -1812,14 +1839,14 @@ int V8Emitter::exitClass(Node *n) .replace(T_PARENT, Getattr(current_namespace, "name_mangled")) .trim() .pretty_print(f_init_register_classes); - + return SWIG_OK; } int V8Emitter::enterVariable(Node* n) { JSEmitter::enterVariable(n); - + state.variable(GETTER, NULL_STR); state.variable(SETTER, VETO_SET); @@ -1848,7 +1875,7 @@ int V8Emitter::exitVariable(Node* n) } } else { // Note: a global variable is treated like a static variable - // with the parent being a nspace object (instead of class object) + // with the parent being a nspace object (instead of class object) Template t_register = getTemplate("jsv8_register_static_variable"); t_register.replace(T_PARENT, Getattr(current_namespace, NAME)) .replace(T_NAME, state.variable(NAME)) @@ -1864,7 +1891,7 @@ int V8Emitter::exitVariable(Node* n) int V8Emitter::exitFunction(Node* n) { bool is_member = GetFlag(n, "ismember"); - + // create a dispatcher for overloaded functions bool is_overloaded = GetFlag(n, "sym:overloaded"); if (is_overloaded) { @@ -1876,7 +1903,7 @@ int V8Emitter::exitFunction(Node* n) return SWIG_OK; } } - + // register the function at the specific context if(is_member) { if(GetFlag(state.function(), IS_STATIC)) { @@ -1896,7 +1923,7 @@ int V8Emitter::exitFunction(Node* n) } } else { // Note: a global function is treated like a static function - // with the parent being a nspace object instead of class object + // with the parent being a nspace object instead of class object Template t_register = getTemplate("jsv8_register_static_function"); t_register.replace(T_PARENT, Getattr(current_namespace, NAME)) .replace(T_NAME, state.function(NAME)) @@ -1978,11 +2005,11 @@ int V8Emitter::emitNamespaces() { .replace(T_NAME, name) .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()); - } - + } + return SWIG_OK; } @@ -2015,7 +2042,7 @@ void V8Emitter::emitUndefined() { .replace(T_FREE, free) .trim() .pretty_print(f_wrappers); - + // create a class template and initialize clientData Template clientDataDef = getTemplate("jsv8_define_class_template"); clientDataDef.replace(T_NAME_MANGLED, mangled_name) @@ -2030,7 +2057,7 @@ void V8Emitter::emitUndefined() { Delete(free); Delete(ctype); - } + } } JSEmitter *swig_javascript_create_V8Emitter() { @@ -2042,8 +2069,8 @@ JSEmitter *swig_javascript_create_V8Emitter() { * Helper implementations **********************************************************************/ -JSEmitterState::JSEmitterState() - : _global(NewHash()) +JSEmitterState::JSEmitterState() + : _global(NewHash()) { // initialize sub-hashes Setattr(_global, "class", NewHash()); @@ -2051,12 +2078,12 @@ JSEmitterState::JSEmitterState() Setattr(_global, "variable", NewHash()); } -JSEmitterState::~JSEmitterState() -{ +JSEmitterState::~JSEmitterState() +{ Delete(_global); } - -DOH *JSEmitterState::getState(const char* key, bool _new) + +DOH *JSEmitterState::getState(const char* key, bool _new) { if (_new) { Hash *hash = NewHash(); @@ -2064,7 +2091,7 @@ DOH *JSEmitterState::getState(const char* key, bool _new) } return Getattr(_global, key); } - + DOH *JSEmitterState::global() { return _global; } @@ -2081,7 +2108,7 @@ DOH *JSEmitterState::clazz(bool _new) { return getState("class", _new); } - + DOH *JSEmitterState::clazz(const char* key, DOH *initial) { DOH *c = clazz(); @@ -2110,7 +2137,7 @@ DOH *JSEmitterState::variable(bool _new) return getState("variable", _new); } -DOH *JSEmitterState::variable(const char* key, DOH *initial) +DOH *JSEmitterState::variable(const char* key, DOH *initial) { DOH *v = variable(); if(initial != 0) { @@ -2118,9 +2145,9 @@ DOH *JSEmitterState::variable(const char* key, DOH *initial) } return Getattr(v, key); } - + /*static*/ -int JSEmitterState::IsSet(DOH *val) +int JSEmitterState::IsSet(DOH *val) { if (!val) { return 0; @@ -2213,7 +2240,7 @@ Template& Template::trim() { char* newstr = new char[new_length+1]; memcpy(newstr, str+start_pos, new_length); newstr[new_length] = 0; - + Delete(code); code = NewString(newstr); delete[] newstr; @@ -2223,9 +2250,9 @@ Template& Template::trim() { /* ----------------------------------------------------------------------------- * Template& Template::replace(const String* pattern, const String* repl) : - * + * * replaces all occurences of a given pattern with a given replacement. - * + * * - pattern: the pattern to be replaced * - repl: the replacement string * - returns a reference to the Template to allow chaining of methods. From 058a27bf32c6fc082c3753af3aaffb1ab4d85e83 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 17 Nov 2012 02:12:12 +0100 Subject: [PATCH 098/352] Simplify creation of a Javascript shell. --- Tools/javascript/javascript.cxx | 31 +++++------------------- Tools/javascript/js_shell.h | 12 ++++++---- Tools/javascript/jsc_shell.cxx | 38 ++++++++++++++--------------- Tools/javascript/v8_shell.cxx | 42 ++++++++++++++++----------------- 4 files changed, 53 insertions(+), 70 deletions(-) diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx index 798158ff0..a1e6c9984 100644 --- a/Tools/javascript/javascript.cxx +++ b/Tools/javascript/javascript.cxx @@ -7,14 +7,6 @@ #include "js_shell.h" -#ifdef USE_JSC -extern JSShell* create_jsc_shell(); -#endif - -#ifdef USE_V8 -extern JSShell* create_v8_shell(); -#endif - void print_usage() { std::cout << "javascript [-i] [-jsc|-v8] [-l module] " << std::endl; } @@ -37,16 +29,12 @@ int main(int argc, char* argv[]) { std::string module_name(argv[idx]); module_names.push_back(module_name); } else if(strcmp(argv[idx], "-v8") == 0) { -#ifdef USE_V8 - shell = create_v8_shell(); -#else +#ifndef USE_V8 std::cerr << "V8 support is not enabled" << std::endl; exit(-1); #endif } else if(strcmp(argv[idx], "-jsc") == 0) { -#ifdef USE_JSC - shell = create_jsc_shell(); -#else +#ifndef USE_JSC std::cerr << "JSC support is not enabled" << std::endl; exit(-1); #endif @@ -56,16 +44,9 @@ int main(int argc, char* argv[]) { scriptPath = argv[idx]; } } - - if (shell == 0) { -#ifdef USE_JSC - shell = create_jsc_shell(); -#else - std::cerr << "JSC support is not enabled" << std::endl; - exit(-1); -#endif - } - + + shell = JSShell::Create(); + bool failed = false; for(std::vector::iterator it = module_names.begin(); it != module_names.end(); ++it) { @@ -94,6 +75,6 @@ int main(int argc, char* argv[]) { } delete shell; - + return 0; } diff --git a/Tools/javascript/js_shell.h b/Tools/javascript/js_shell.h index 96535a4c0..830873f0d 100644 --- a/Tools/javascript/js_shell.h +++ b/Tools/javascript/js_shell.h @@ -18,10 +18,12 @@ public: JSShell() {} - virtual ~JSShell(); - + virtual ~JSShell() = 0; + + static JSShell* Create(); + bool ImportModule(const std::string& name); - + virtual bool RunScript(const std::string& scriptPath); virtual bool RunShell(); @@ -31,7 +33,7 @@ protected: virtual bool RegisterModule(HANDLE library, const std::string& module_name) = 0; virtual bool InitializeEngine() = 0; - + virtual bool ExecuteScript(const std::string& source, const std::string& name) = 0; virtual bool DisposeEngine() = 0; @@ -39,7 +41,7 @@ protected: static std::string ReadFile(const std::string& fileName); protected: - + std::vector loaded_modules; }; diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx index a21fb3f1a..c069b5c65 100644 --- a/Tools/javascript/jsc_shell.cxx +++ b/Tools/javascript/jsc_shell.cxx @@ -19,7 +19,7 @@ typedef int (*JSCIntializer)(JSGlobalContextRef context); public: JSCShell() {}; - + virtual ~JSCShell(); protected: @@ -27,14 +27,14 @@ protected: virtual bool RegisterModule(HANDLE library, const std::string& module_name); virtual bool InitializeEngine(); - + virtual bool ExecuteScript(const std::string& source, const std::string& name); virtual bool DisposeEngine(); private: - static JSValueRef Print(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + static JSValueRef Print(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); static bool RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback cbFunction); @@ -43,7 +43,7 @@ private: private: std::vector module_initializers; - + JSGlobalContextRef context; }; @@ -56,7 +56,7 @@ JSCShell::~JSCShell() { bool JSCShell::RegisterModule(HANDLE library, const std::string& module_name) { std::string symname = std::string(module_name).append("_initialize"); - + JSCIntializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); if(init_function == 0) return false; @@ -64,7 +64,7 @@ bool JSCShell::RegisterModule(HANDLE library, const std::string& module_name) { return true; } -bool JSCShell::InitializeEngine() { +bool JSCShell::InitializeEngine() { if(context != 0) { JSGlobalContextRelease(context); context = 0; @@ -81,7 +81,7 @@ bool JSCShell::InitializeEngine() { if(!init_function(context)) { return false; } - } + } return true; } @@ -104,9 +104,9 @@ bool JSCShell::DisposeEngine() { return true; } -JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object, - JSObjectRef globalobj, size_t argc, - const JSValueRef args[], JSValueRef* ex) { +JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object, + JSObjectRef globalobj, size_t argc, + const JSValueRef args[], JSValueRef* ex) { if (argc > 0) { JSStringRef string = JSValueToStringCopy(context, args[0], NULL); @@ -114,18 +114,18 @@ JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object, char *stringUTF8 = new char[numChars]; JSStringGetUTF8CString(string, stringUTF8, numChars); printf("%s\n", stringUTF8); - + delete[] stringUTF8; } - + return JSValueMakeUndefined(context); } -bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object, +bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) { JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); JSObjectSetProperty(context, object, js_functionName, - JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), kJSPropertyAttributeNone, NULL); JSStringRelease(js_functionName); return true; @@ -133,10 +133,10 @@ bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object, void JSCShell::PrintError(JSContextRef ctx, JSValueRef err, const std::string& name) { char *buffer; - + JSStringRef string = JSValueToStringCopy(ctx, err, 0); size_t length = JSStringGetLength(string); - + buffer = new char[length+1]; JSStringGetUTF8CString(string, buffer, length+1); std::string errMsg(buffer); @@ -144,7 +144,7 @@ void JSCShell::PrintError(JSContextRef ctx, JSValueRef err, const std::string& n delete[] buffer; JSObjectRef errObj = JSValueToObject(ctx, err, 0); - + if(errObj == 0) { std::cerr << errMsg << std::endl; return; @@ -154,12 +154,12 @@ void JSCShell::PrintError(JSContextRef ctx, JSValueRef err, const std::string& n // though, it happened that this was always "" JSStringRef lineKey = JSStringCreateWithUTF8CString("line"); JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0); - int line = (int) JSValueToNumber(ctx, jsLine, 0); + int line = (int) JSValueToNumber(ctx, jsLine, 0); JSStringRelease(lineKey); std::cerr << name << ":" << line << ":" << errMsg << std::endl; } -JSShell* create_jsc_shell() { +JSShell* JSShell::Create() { return new JSCShell(); } diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 27923dd86..71960caba 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -15,9 +15,9 @@ class V8Shell: public JSShell { public: V8Shell(); - + virtual ~V8Shell(); - + virtual bool RunScript(const std::string& scriptPath); virtual bool RunShell(); @@ -28,11 +28,11 @@ protected: virtual bool RegisterModule(HANDLE library, const std::string& module_name); virtual bool InitializeEngine(); - + virtual bool ExecuteScript(const std::string& source, const std::string& name); virtual bool DisposeEngine(); - + private: v8::Persistent CreateShellContext(); @@ -46,13 +46,13 @@ private: static v8::Handle Version(const v8::Arguments& args); static const char* ToCString(const v8::String::Utf8Value& value); - + void ExtendEngine(); - + protected: std::vector module_initializers; - + v8::Persistent context; }; @@ -75,7 +75,7 @@ V8Shell::~V8Shell() { bool V8Shell::RegisterModule(HANDLE library, const std::string& module_name) { std::string symname = std::string(module_name).append("_initialize"); - + V8ExtensionRegistrar init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); if(init_function == 0) return false; @@ -88,10 +88,10 @@ bool V8Shell::RunScript(const std::string& scriptPath) { if (!context.IsEmpty()) { context.Dispose(); } - + std::string source = ReadFile(scriptPath); - context = CreateShellContext(); + context = CreateShellContext(); if (context.IsEmpty()) { printf("Could not create context.\n"); return false; @@ -104,11 +104,11 @@ bool V8Shell::RunScript(const std::string& scriptPath) { if(!ExecuteScript(source, scriptPath)) { return false; } - + context->Exit(); context.Dispose(); v8::V8::Dispose(); - + return true; } @@ -117,18 +117,18 @@ bool V8Shell::RunShell() { if (!context.IsEmpty()) { context.Dispose(); } - - context = CreateShellContext(); + + context = CreateShellContext(); if (context.IsEmpty()) { printf("Could not create context.\n"); return false; } - + context->Enter(); v8::Context::Scope context_scope(context); ExtendEngine(); - + static const int kBufferSize = 1024; while (true) { char buffer[kBufferSize]; @@ -152,13 +152,13 @@ bool V8Shell::InitializeEngine() { } void V8Shell::ExtendEngine() { - + // register extensions for(std::vector::iterator it=module_initializers.begin(); it != module_initializers.end(); ++it) { (*it)(context); } - + } bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) { @@ -195,7 +195,7 @@ bool V8Shell::DisposeEngine() { v8::Persistent V8Shell::CreateShellContext() { v8::HandleScope scope; - + // Create a template for the global object. v8::Handle global = v8::ObjectTemplate::New(); @@ -205,7 +205,7 @@ v8::Persistent V8Shell::CreateShellContext() { global->Set(v8::String::New("version"), v8::FunctionTemplate::New(V8Shell::Version)); v8::Persistent _context = v8::Context::New(NULL, global); - + return _context; } @@ -282,6 +282,6 @@ const char* V8Shell::ToCString(const v8::String::Utf8Value& value) { return *value ? *value : ""; } -JSShell* create_v8_shell() { +JSShell* JSShell::Create() { return new V8Shell(); } From 6754bf2b49862211eb67bc2a31ce79ae31de9034 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 17 Nov 2012 03:41:22 +0100 Subject: [PATCH 099/352] Generate cleanup code for %newobject. --- Source/Modules/javascript.cxx | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index d43af979d..90300a24f 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -272,7 +272,7 @@ protected: virtual void marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, const String *cresult=0, bool emitReturnVariable = true); - virtual void emitCleanupCode(Wrapper *wrapper, ParmList *params); + virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params); void registerProxyType(SwigType* type); @@ -834,7 +834,7 @@ int JSEmitter::emitCtor(Node *n) { Printv(wrapper->code, action, "\n", 0); - emitCleanupCode(wrapper, params); + emitCleanupCode(n, wrapper, params); t_ctor.replace(T_WRAPPER, wrap_name) .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) @@ -919,7 +919,7 @@ int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); marshalOutput(n, wrapper, action); - emitCleanupCode(wrapper, params); + emitCleanupCode(n, wrapper, params); t_getter.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) @@ -957,7 +957,7 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); Append(wrapper->code, action); - emitCleanupCode(wrapper, params); + emitCleanupCode(n, wrapper, params); t_setter.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) @@ -1036,7 +1036,7 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { marshalInputArgs(n, params, wrapper, Function, is_member, is_static); marshalOutput(n, wrapper, action); - emitCleanupCode(wrapper, params); + emitCleanupCode(n, wrapper, params); t_function.replace(T_WRAPPER, wrap_name) .replace(T_LOCALS, wrapper->locals) @@ -1151,7 +1151,7 @@ void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, co } } -void JSEmitter::emitCleanupCode(Wrapper *wrapper, ParmList *params) { +void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) { Parm *p; String *tm; @@ -1165,6 +1165,15 @@ void JSEmitter::emitCleanupCode(Wrapper *wrapper, ParmList *params) { p = nextSibling(p); } } + + if (GetFlag(n, "feature:new")) { + tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0); + if (tm != NIL) { + //addThrows(throws_hash, "newfree", n); + Printv(wrapper->code, tm, "\n", NIL); + } + } + } int JSEmitter::switchNamespace(Node *n) { From 008adca72f5917d8a80cc252572f0b1e80ed4e69 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 22 Nov 2012 22:50:50 +0100 Subject: [PATCH 100/352] Provide more control about the target object/namespace where a v8 module is registered to. --- Lib/javascript/v8/javascriptcode.swg | 3 +-- Tools/javascript/v8_shell.cxx | 7 +++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index eb95cb1bf..1b196cffd 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -386,12 +386,11 @@ fail: %{ extern "C" { -void $jsname_initialize(v8::Handle context) +void $jsname_initialize(v8::Handle context, v8::Handle global_obj) { SWIG_InitializeModule(0); v8::HandleScope scope; - v8::Local global_obj = context->Global(); // a class template for creating proxies of undefined types SWIGV8_SWIGTYPE_Proxy_class_templ = SWIGV8_CreateClassTemplate("SwigProxy"); diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 71960caba..8b45ac0d6 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -9,7 +9,7 @@ #include "js_shell.h" -typedef int (*V8ExtensionRegistrar) (v8::Handle); +typedef int (*V8ExtensionRegistrar) (v8::Handle, v8::Handle); class V8Shell: public JSShell { @@ -153,10 +153,13 @@ bool V8Shell::InitializeEngine() { void V8Shell::ExtendEngine() { + v8::HandleScope scope; + v8::Local global = context->Global(); + // register extensions for(std::vector::iterator it=module_initializers.begin(); it != module_initializers.end(); ++it) { - (*it)(context); + (*it)(context, global); } } From caa6827dafc4cc5b0ea3b8c16922905c46bbbf29 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 23 Nov 2012 01:09:11 +0100 Subject: [PATCH 101/352] Javascript interpreter supports for JSC and V8 simultaneously. Before, one had to build two different versions. --- Tools/javascript/javascript.cxx | 14 +++++--------- Tools/javascript/js_shell.cxx | 31 +++++++++++++++++++++++++++++++ Tools/javascript/js_shell.h | 6 ++---- Tools/javascript/jsc_shell.cxx | 2 +- Tools/javascript/v8_shell.cxx | 2 +- 5 files changed, 40 insertions(+), 15 deletions(-) diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx index a1e6c9984..82e94f434 100644 --- a/Tools/javascript/javascript.cxx +++ b/Tools/javascript/javascript.cxx @@ -29,15 +29,9 @@ int main(int argc, char* argv[]) { std::string module_name(argv[idx]); module_names.push_back(module_name); } else if(strcmp(argv[idx], "-v8") == 0) { -#ifndef USE_V8 - std::cerr << "V8 support is not enabled" << std::endl; - exit(-1); -#endif + shell = JSShell::Create(JSShell::V8); } else if(strcmp(argv[idx], "-jsc") == 0) { -#ifndef USE_JSC - std::cerr << "JSC support is not enabled" << std::endl; - exit(-1); -#endif + shell = JSShell::Create(JSShell::JSC); } else if(strcmp(argv[idx], "-i") == 0) { interactive = true; } else { @@ -45,7 +39,9 @@ int main(int argc, char* argv[]) { } } - shell = JSShell::Create(); + if (shell == 0) { + shell = JSShell::Create(); + } bool failed = false; for(std::vector::iterator it = module_names.begin(); diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx index b2b8672a6..8762fbff5 100644 --- a/Tools/javascript/js_shell.cxx +++ b/Tools/javascript/js_shell.cxx @@ -15,6 +15,8 @@ #error "implement dll loading" #endif + + JSShell::~JSShell() { for(std::vector::iterator it = loaded_modules.begin(); @@ -93,3 +95,32 @@ std::string JSShell::ReadFile(const std::string& fileName) return script; } + +#ifdef ENABLE_JSC +extern JSShell* JSCShell_Create(); +#endif +#ifdef ENABLE_V8 +extern JSShell* V8Shell_Create(); +#endif + +typedef JSShell*(*ShellFactory)(); + +static ShellFactory js_shell_factories[2] = { +#ifdef ENABLE_JSC +JSCShell_Create, +#else +0, +#endif +#ifdef ENABLE_V8 +V8Shell_Create, +#else +0, +#endif +}; + +JSShell *JSShell::Create(Engine engine) { + if(js_shell_factories[engine] == 0) { + throw "Engine not supported."; + } + return js_shell_factories[engine](); +} diff --git a/Tools/javascript/js_shell.h b/Tools/javascript/js_shell.h index 830873f0d..54f55b69d 100644 --- a/Tools/javascript/js_shell.h +++ b/Tools/javascript/js_shell.h @@ -10,7 +10,7 @@ class JSShell { public: enum Engine { - JSC, + JSC = 0, V8 }; @@ -20,7 +20,7 @@ public: virtual ~JSShell() = 0; - static JSShell* Create(); + static JSShell* Create(Engine engine = JSC); bool ImportModule(const std::string& name); @@ -46,6 +46,4 @@ protected: }; -typedef JSShell* (*JSShellFactory)(); - #endif // JS_SHELL_H diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx index c069b5c65..ee95e04a5 100644 --- a/Tools/javascript/jsc_shell.cxx +++ b/Tools/javascript/jsc_shell.cxx @@ -160,6 +160,6 @@ void JSCShell::PrintError(JSContextRef ctx, JSValueRef err, const std::string& n std::cerr << name << ":" << line << ":" << errMsg << std::endl; } -JSShell* JSShell::Create() { +JSShell* JSCShell_Create() { return new JSCShell(); } diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 8b45ac0d6..0055bad98 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -285,6 +285,6 @@ const char* V8Shell::ToCString(const v8::String::Utf8Value& value) { return *value ? *value : ""; } -JSShell* JSShell::Create() { +JSShell* V8Shell_Create() { return new V8Shell(); } From bad64925eddf9f78b5bddd6fe559973c51b7f59f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 23 Nov 2012 01:59:54 +0100 Subject: [PATCH 102/352] Configuration is now easier for building and running examples and tests using v8. --- Examples/Makefile.in | 50 +++++++++++++++++++++++++++----------------- configure.in | 22 ++++++++++++------- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index bf9fe5cd8..803c7fa9a 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -520,19 +520,8 @@ java_clean: # You need to set this variable to the jscore[or other javascript engine] directories containing the # files "JavaScript.h" and others -ifeq (,$(V8)) - JS_INCLUDE = @JSCOREINC@ - JS_DLNK = @JSCOREDYNAMICLINKING@ -else - JS_INCLUDE = @JSV8INC@ - JS_DLNK = @JSV8DYNAMICLINKING@ -endif - -ifeq (,$(V8)) - SWIGJS = $(SWIG) -javascript -jsc -else - SWIGJS = $(SWIG) -javascript -v8 -endif +JS_INCLUDE = @JSCOREINC@ @JSV8INC@ +JS_DLNK = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ # Extra JAVASCRIPT specific dynamic linking options JS_LIBPREFIX = @JSCORELIBRARYPREFIX@ @@ -541,17 +530,40 @@ JSLDSHARED = @JSCORELDSHARED@ JSCXXSHARED = @JSCORECXXSHARED@ JSCFLAGS = @JSCORECFLAGS@ JSCXXFLAGS = @JSCXXFLAGS@ +ROOT_DIR = @ROOT_DIR@ +JSCORE = @JSCORE@ +JSV8 = @JSV8@ +JSDEFAULT = @JSDEFAULT@ -JSEXE_SRC_DIR = $(TOP)/../Tools/javascript +JSEXE_SRC_DIR = $(ROOT_DIR)/Tools/javascript JSEXE = $(JSEXE_SRC_DIR)/javascript -ifeq (,$(V8)) - JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx $(JSEXE_SRC_DIR)/jsc_shell.cxx + +ifneq (,$(JSCORE)) + JSEXE_SRC_JSC = $(JSEXE_SRC_DIR)/jsc_shell.cxx + JSEXE_FLAGS_JSC = -DENABLE_JSC +endif + +ifneq (,$(JSV8)) + JSEXE_SRC_V8 = $(JSEXE_SRC_DIR)/v8_shell.cxx + JSEXE_FLAGS_V8 = -DENABLE_V8 +endif + +JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx $(JSEXE_SRC_JSC) $(JSEXE_SRC_V8) +JSEXE_FLAGS = $(JSEXE_FLAGS_JSC) $(JSEXE_FLAGS_V8) + +# this controls which engine the code will be generated for +# and correspondingly the argument for the js interpreter +ifneq (,$(JSC)) + SWIGJS = $(SWIG) -javascript -jsc JSEXE_OPTS = -jsc - JSEXE_FLAGS = -DUSE_JSC else - JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx $(JSEXE_SRC_DIR)/v8_shell.cxx +ifneq (,$(V8)) + SWIGJS = $(SWIG) -javascript -v8 JSEXE_OPTS = -v8 - JSEXE_FLAGS = -DUSE_V8 +else + SWIGJS = $(SWIG) -javascript -$(JSDEFAULT) + JSEXE_OPTS = -$(JSDEFAULT) +endif endif # ---------------------------------------------------------------- diff --git a/configure.in b/configure.in index 5a00636a2..e4841fc70 100644 --- a/configure.in +++ b/configure.in @@ -1081,12 +1081,13 @@ AC_SUBST(JAVACFLAGS) # Look for JAVASCRIPT [JavaScriptCore Headers and Library] #---------------------------------------------------------------- AC_ARG_WITH(javascript, AS_HELP_STRING([--without-javascript], [Disable JAVASCRIPT]), [with_javascript="$withval"], [with_javascript=yes]) +AC_ARG_VAR(JSDEFAULT, "The default engine to use ( v8 | jsc ).") # First, check for "--without-javascript" or "--with-javascript=no". if test x"${with_javascript}" = xno -o x"${with_alllang}" = xno ; then -AC_MSG_NOTICE([Disabling Javascript]) -JAVASCRIPT= -else + AC_MSG_NOTICE([Disabling Javascript]) + JAVASCRIPT= +fi ### JavascriptCore ### @@ -1120,8 +1121,8 @@ fi # check for JavaScriptCore, Webkit libraries -AC_ARG_WITH(jscorelib,[ --with-jscorelib =path Set location of JavaScriptCore (Webkit) library directory],[ - JSCORELIB="-L$withval"], [JSCORELIB=]) +AC_ARG_WITH(jscorelib,[ --with-jscorelib =path Set location of JavaScriptCore (Webkit) library directory], + [JSCORELIB="-L$withval"], [JSCORELIB=]) AC_MSG_CHECKING(for JavaScriptCore(Webkit) library) if test -z "$JSCORELIB"; then @@ -1149,10 +1150,10 @@ done if test -z "$JSCORELIB"; then AC_MSG_RESULT(not found) -fi - + JSCORE= else -AC_MSG_RESULT($JSCORELIB) + AC_MSG_RESULT($JSCORELIB) + JSCORE=1 fi # linking options @@ -1202,6 +1203,7 @@ case $host in esac fi +AC_SUBST(JSCORE) AC_SUBST(JSCOREINC) AC_SUBST(JSCOREDYNAMICLINKING) AC_SUBST(JSCORELIBRARYPREFIX) @@ -1237,6 +1239,9 @@ done if test "$JSV8INC" = "" ; then AC_MSG_RESULT(not found) + JSV8= +else + JSV8=1 fi @@ -1274,6 +1279,7 @@ esac AC_SUBST(JSV8INC) AC_SUBST(JSV8DYNAMICLINKING) +AC_SUBST(JSDEFAULT) #---------------------------------------------------------------- # Look for gcj From 9d2264456334c88a6b0b74940cc3e96add527325 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 29 Nov 2012 03:17:27 +0100 Subject: [PATCH 103/352] Rename a argument variable to avoid errors with overloaded functions. --- Lib/javascript/jsc/javascriptcode.swg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 34245ed14..87a11cecf 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -213,7 +213,7 @@ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef th * ----------------------------------------------------------------------------- */ %fragment ("js_overloaded_function", "templates") %{ -int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* result) +int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* p_result) { $jslocals JSValueRef jsresult; @@ -221,7 +221,7 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode - *result = jsresult; + *p_result = jsresult; return SWIG_OK; goto fail; From f9d6afbdfef0d3ef3fb0d5a1675a0b1f4d2a5630 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 29 Nov 2012 03:19:00 +0100 Subject: [PATCH 104/352] Add a missing return statement in JS shell. --- Tools/javascript/js_shell.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx index 8762fbff5..322ca1cb9 100644 --- a/Tools/javascript/js_shell.cxx +++ b/Tools/javascript/js_shell.cxx @@ -74,6 +74,7 @@ bool JSShell::RunShell() { ExecuteScript(source, "(shell)"); } printf("\n"); + return true; } std::string JSShell::ReadFile(const std::string& fileName) From fb9c4955fb4c39f66ea74dcd714bb34f593b3b40 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 29 Nov 2012 03:20:49 +0100 Subject: [PATCH 105/352] Not a real change: removed some trailing spaces. --- Lib/javascript/jsc/javascriptcode.swg | 52 +++++++++++++-------------- Tools/javascript/js_shell.cxx | 12 +++---- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 87a11cecf..000733ea7 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -14,7 +14,7 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode - return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); goto fail; fail: return NULL; @@ -48,13 +48,13 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { JSObjectRef thisObject = NULL; - - // switch all cases by means of series of if-returns. + + // switch all cases by means of series of if-returns. $jsdispatchcases - // default: + // default: SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsname"); - + fail: return thisObject; } @@ -74,7 +74,7 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc { $jslocals $jscode - return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); goto fail; fail: @@ -87,7 +87,7 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc * - $jsargcount: number of arguments of called ctor * - $jswrapper: wrapper of called ctor * - * Note: a try-catch-like mechanism is used to switch cases + * Note: a try-catch-like mechanism is used to switch cases * ----------------------------------------------------------------------------- */ %fragment ("js_ctor_dispatch_case", "templates") %{ @@ -125,13 +125,13 @@ JSValueRef $jswrapper(JSContextRef context, JSObjectRef thisObject, JSStringRef { $jslocals JSValueRef jsresult; - + $jscode return jsresult; goto fail; fail: - return NULL; + return NULL; } %} @@ -147,12 +147,12 @@ bool $jswrapper(JSContextRef context, JSObjectRef thisObject, JSStringRef proper { $jslocals $jscode - + return true; - + goto fail; fail: - return false; + return false; } %} @@ -170,13 +170,13 @@ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef th JSValueRef jsresult; if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); - + $jscode return jsresult; - + goto fail; fail: - return NULL; + return NULL; } %} @@ -193,15 +193,15 @@ JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef th { $jslocals JSValueRef jsresult; - int res; + int res; $jscode - + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); return jsresult; - + goto fail; fail: - return NULL; + return NULL; } %} @@ -219,14 +219,14 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec JSValueRef jsresult; if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); - + $jscode *p_result = jsresult; return SWIG_OK; - + goto fail; fail: - return SWIG_TypeError; + return SWIG_TypeError; } %} @@ -260,12 +260,12 @@ bool $jsname_initialize(JSGlobalContextRef context) { SWIG_InitializeModule(0); JSObjectRef global_object = JSContextGetGlobalObject(context); - + /* Initialize the base swig type object */ _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; _SwigObject_objectDefinition.staticValues = _SwigObject_values; _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); - + /* Create objects for namespaces */ $jscreatenamespaces @@ -358,7 +358,7 @@ JSStaticFunction $jsmangledname_functions[] = { * - $jsbaseclass: mangled name of base class * ----------------------------------------------------------------------------- */ %fragment ("jsc_class_definition", "templates") -%{ +%{ $jsmangledname_classDefinition.staticFunctions = $jsmangledname_staticFunctions; $jsmangledname_classDefinition.staticValues = $jsmangledname_staticValues; $jsmangledname_classDefinition.callAsConstructor = $jsctor; @@ -407,7 +407,7 @@ JSClassDefinition $jsnspace_classDefinition; * - $jsmangledname: mangled name of namespace * ----------------------------------------------------------------------------- */ %fragment ("jsc_nspace_definition", "templates") -%{ +%{ $jsmangledname_classDefinition.staticFunctions = $jsmangledname_functions; $jsmangledname_classDefinition.staticValues = $jsmangledname_values; JSObjectRef $jsmangledname_object = JSObjectMake(context, JSClassCreate(&$jsmangledname_classDefinition), NULL); diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx index 322ca1cb9..f0290c785 100644 --- a/Tools/javascript/js_shell.cxx +++ b/Tools/javascript/js_shell.cxx @@ -33,19 +33,19 @@ bool JSShell::ImportModule(const std::string& name) { HANDLE handle = LOAD_LIBRARY(lib_name.c_str()); if(handle == 0) { - std::cout << "Could not load library " << lib_name << ":" + std::cout << "Could not load library " << lib_name << ":" << std::endl << LIBRARY_ERROR() << std::endl; return false; } - + if(!RegisterModule(handle, name)) { std::cout << "Could not find initializer function in " << lib_name << std::endl; CLOSE_LIBRARY(handle); return false; } - loaded_modules.push_back(handle); - + loaded_modules.push_back(handle); + return true; } @@ -56,14 +56,14 @@ bool JSShell::RunScript(const std::string& scriptPath) { if(!ExecuteScript(source, scriptPath)) { return false; } - + return DisposeEngine(); } bool JSShell::RunShell() { if(!InitializeEngine()) return false; - + static const int kBufferSize = 1024; while (true) { char buffer[kBufferSize]; From 7fffd801e410749c37a818b22c5682375c5f9a1b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 1 Dec 2012 13:21:22 +0100 Subject: [PATCH 106/352] Fix std_string.i which generated compile errors in certain cases. --- Lib/javascript/jsc/std_string.i | 73 ++++++++++++++------------------- 1 file changed, 30 insertions(+), 43 deletions(-) diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i index 9fbee75ef..5056b17bf 100755 --- a/Lib/javascript/jsc/std_string.i +++ b/Lib/javascript/jsc/std_string.i @@ -11,6 +11,30 @@ %{ #include + +std::string SWIGJSC_valueToString(JSContextRef context, JSValueRef value) { + JSStringRef jsstring = JSValueToStringCopy(context, value, /* JSValueRef *exception */ 0); + unsigned int length = JSStringGetLength(jsstring); + char *cstr = new char[length+1]; + JSStringGetUTF8CString(jsstring, cstr, length); + + // create a copy + std::string result(cstr); + + JSStringRelease(jsstring); + delete[] cstr; + + return result; +} + +JSValueRef SWIGJSC_stringToValue(JSContextRef context, const std::string& s) +{ + JSValueRef result; + JSStringRef jsstring = JSStringCreateWithUTF8CString(s.c_str()); + result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return result; +} %} namespace std { @@ -21,51 +45,14 @@ class string; // string -%typemap(in) string -%{ if (!$input) { - // TODO: Throw exception? - return NULL; - } - JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); - size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); - char* $1_cstr = (char *)malloc($1_strsize * sizeof(char)); - JSStringGetUTF8CString($1_str, $1_cstr, $1_strsize); - $1 = std::string($1_cstr); +%typemap(in) string, const string& +%{ + $1 = SWIGJSC_valueToString(context, $input); %} -%typemap(out) string %{ - JSStringRef jsstring = JSStringCreateWithUTF8CString($1.c_str()); - $result = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); +%typemap(out) string, const string& +%{ + $result = SWIGJSC_stringToValue(context, $1); %} -%typemap(freearg) string //TODO: Not working: A memory leak -%{ free($1_cstr); %} - -//%typemap(typecheck) string = char *; - -// const string & -%typemap(in) const string & -%{ if (!$input) { - // TODO: Throw exception? - return NULL; - } - JSStringRef $1_str = JSValueToStringCopy(context, $input, NULL); - size_t $1_strsize = JSStringGetMaximumUTF8CStringSize($1_str); - char* $1_cstr = (char *)malloc($1_strsize * sizeof(char)); - JSStringGetUTF8CString($1_str, $1_cstr, $1_strsize); - $1 = new std::string($1_cstr); -%} - -%typemap(out) const string & %{ - JSStringRef jsstring = JSStringCreateWithUTF8CString($1.c_str()); - $result = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); -%} - -%typemap(freearg) const string & //TODO: Not working: A memory leak -%{ free($1_cstr); %} - -//%typemap(typecheck) const string & = char *; - } From be06ceea2686f65a29a5d46d5d675d4366e5571c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sun, 2 Dec 2012 23:51:47 +0100 Subject: [PATCH 107/352] Fixes in std_string for JSC generator. --- Lib/javascript/jsc/std_string.i | 41 ++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i index 5056b17bf..d1ac12ef9 100755 --- a/Lib/javascript/jsc/std_string.i +++ b/Lib/javascript/jsc/std_string.i @@ -15,8 +15,8 @@ std::string SWIGJSC_valueToString(JSContextRef context, JSValueRef value) { JSStringRef jsstring = JSValueToStringCopy(context, value, /* JSValueRef *exception */ 0); unsigned int length = JSStringGetLength(jsstring); - char *cstr = new char[length+1]; - JSStringGetUTF8CString(jsstring, cstr, length); + char *cstr = new char[length + 1]; + JSStringGetUTF8CString(jsstring, cstr, length + 1); // create a copy std::string result(cstr); @@ -38,21 +38,34 @@ JSValueRef SWIGJSC_stringToValue(JSContextRef context, const std::string& s) %} namespace std { + %naturalvar string; -%naturalvar string; + class string; -class string; -// string - -%typemap(in) string, const string& -%{ - $1 = SWIGJSC_valueToString(context, $input); -%} + %typemap(in) string + %{ + $1 = SWIGJSC_valueToString(context, $input); + %} -%typemap(out) string, const string& -%{ - $result = SWIGJSC_stringToValue(context, $1); -%} + %typemap(in) const string & + %{ + $1 = new std::string(SWIGJSC_valueToString(context, $input)); + %} + + %typemap(freearg) const string & + %{ + delete $1; + %} + + %typemap(out) string + %{ + $result = SWIGJSC_stringToValue(context, $1); + %} + + %typemap(out) const string & + %{ + $result = SWIGJSC_stringToValue(context, $1); + %} } From 2c4a90a37d7818f792417bfff73a88b9efcbdd01 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Dec 2012 01:36:51 +0100 Subject: [PATCH 108/352] Generate defines for initializer function. --- Lib/javascript/jsc/javascriptcode.swg | 6 +++++- Source/Modules/javascript.cxx | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 000733ea7..0ad1e364d 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -244,6 +244,10 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec } %} +%fragment ("js_initializer_define", "templates") %{ +#define SWIGJSC_INIT $jsname_initialize +%} + /* ----------------------------------------------------------------------------- * js_initializer: template for the module initializer function * - $jsname: module name @@ -256,7 +260,7 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec extern "C" { #endif -bool $jsname_initialize(JSGlobalContextRef context) { +bool SWIGJSC_INIT (JSGlobalContextRef context) { SWIG_InitializeModule(0); JSObjectRef global_object = JSContextGetGlobalObject(context); diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 90300a24f..f0b8c472a 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1407,6 +1407,9 @@ int JSCEmitter::dump(Node *n) { // write the swig banner Swig_banner(f_wrap_cpp); + Template initializer_define(getTemplate("js_initializer_define")); + initializer_define.replace(T_NAME, module).pretty_print(f_header); + SwigType_emit_type_table(f_runtime, f_wrappers); Printv(f_wrap_cpp, f_runtime, "\n", 0); @@ -1414,7 +1417,7 @@ int JSCEmitter::dump(Node *n) { Printv(f_wrap_cpp, f_wrappers, "\n", 0); emitNamespaces(); - + // compose the initializer function using a template Template initializer(getTemplate("js_initializer")); initializer.replace(T_NAME, module) From 9d630ab930f83252e75d6e66e2912cbe75ca253f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 8 Jan 2013 21:48:22 +0100 Subject: [PATCH 109/352] Fix std::string support for v8. --- Lib/javascript/jsc/std_string.i | 8 +- Lib/javascript/v8/javascriptstrings.swg | 5 +- Lib/javascript/v8/std_string.i | 106 +++++++++++++----------- 3 files changed, 60 insertions(+), 59 deletions(-) diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i index d1ac12ef9..a23396fe6 100755 --- a/Lib/javascript/jsc/std_string.i +++ b/Lib/javascript/jsc/std_string.i @@ -1,12 +1,10 @@ /* ----------------------------------------------------------------------------- * std_string.i * - * Typemaps for std::string and const std::string& - * These are mapped to a JSCore String and are passed around by value. + * Typemaps for const std::string&. + * To use non-const std::string references use the following %apply: + * %apply const std::string & {std::string &}; * - * To use non-const std::string references use the following %apply. Note - * that they are passed by value. - * %apply const std::string & {std::string &}; * ----------------------------------------------------------------------------- */ %{ diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg index e955bee3a..69b6836a8 100644 --- a/Lib/javascript/v8/javascriptstrings.swg +++ b/Lib/javascript/v8/javascriptstrings.swg @@ -2,7 +2,7 @@ /* ------------------------------------------------------------ * utility methods for char strings * ------------------------------------------------------------ */ -%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +%fragment("SWIG_AsCharPtrAndSize", "header", fragment="SWIG_pchar_descriptor") { SWIGINTERN int SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, int *alloc) { @@ -47,9 +47,6 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size) if (carray) { if (size > INT_MAX) { // TODO: handle extra long strings - //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - //return pchar_descriptor ? - // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); return v8::Undefined(); } else { v8::Handle js_str = v8::String::New(carray, size); diff --git a/Lib/javascript/v8/std_string.i b/Lib/javascript/v8/std_string.i index 0d6143319..d9221627f 100755 --- a/Lib/javascript/v8/std_string.i +++ b/Lib/javascript/v8/std_string.i @@ -1,68 +1,74 @@ /* ----------------------------------------------------------------------------- * std_string.i * - * Typemaps for std::string and const std::string& - * These are mapped to a JSCore String and are passed around by value. + * Typemaps for std::string and const std::string&. + * + * To use non-const std::string references use the following %apply: + * %apply const std::string & {std::string &}; * - * To use non-const std::string references use the following %apply. Note - * that they are passed by value. - * %apply const std::string & {std::string &}; * ----------------------------------------------------------------------------- */ %{ #include %} +%fragment("SWIGV8_valueToString", "header", fragment="SWIG_AsCharPtrAndSize") { +std::string* SWIGV8_valueToStringPtr(v8::Handle val) { + int alloc; + size_t size; + char* chars; + int res = SWIG_AsCharPtrAndSize(val, &chars, &size, &alloc); + + if(res != SWIG_OK) { + v8::ThrowException(v8::Exception::TypeError(v8::String::New("Could not convert to string."))); + return 0; + } + + // copies the data (again) + std::string *str = new std::string(chars); + + if (alloc) delete[] chars; + + return str; +} +} + +%fragment("SWIGV8_stringToValue", "header", fragment="SWIG_FromCharPtrAndSize") { +v8::Handle SWIGV8_stringToValue(const std::string &str) { + return SWIG_FromCharPtrAndSize(str.c_str(), str.length()); +} +} + namespace std { + %naturalvar string; -%naturalvar string; + class string; -class string; + %typemap(in, fragment="SWIGV8_valueToString") string (std::string* tmp) + %{ + tmp = SWIGV8_valueToStringPtr($input); + $1 = *tmp; + delete tmp; + %} -// string + %typemap(in, fragment="SWIGV8_valueToString") const string & + %{ + $1 = SWIGV8_valueToStringPtr($input); + %} + + %typemap(freearg) const string & + %{ + delete $1; + %} -%typemap(in) string -%{ - if(!$input->IsString()) { - // TODO: Throw exception? - return NULL; - } + %typemap(out, fragment="SWIGV8_stringToValue") string + %{ + $result = SWIGV8_stringToValue($1); + %} - size_t $1_strsize = js_str->Utf8Length(); - char* 1_cstr = new char[1_strsize]; - js_str->WriteUtf8(1_cstr, 1_strsize); - $1 = std::string($1_cstr); -%} - -%typemap(out) string %{ - $result = v8::String::New($1.c_str(), $1.size()); -%} - -%typemap(freearg) string -%{%} - -// const string & -%typemap(in) const string & -%{ - - if(!$input->IsString()) { - // TODO: Throw exception? - return NULL; - } - - size_t $1_strsize = js_str->Utf8Length(); - char* 1_cstr = new char[1_strsize]; - js_str->WriteUtf8(1_cstr, 1_strsize); - $1 = newstd::string($1_cstr); -%} - -%typemap(out) const string & %{ - $result = v8::String::New($1.c_str(), $1.size()); -%} - -%typemap(freearg) const string & //TODO: Not working: A memory leak -%{ free($1_cstr); %} - -//%typemap(typecheck) const string & = char *; + %typemap(out, fragment="SWIGV8_stringToValue") const string & + %{ + $result = SWIGV8_stringToValue($1); + %} } From 31844ac72adfd82c310c239434db579ba7f6670a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 8 Jan 2013 22:34:38 +0100 Subject: [PATCH 110/352] Simplify the signature of the v8 module intializer. --- Lib/javascript/v8/javascriptcode.swg | 2 +- Tools/javascript/v8_shell.cxx | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 1b196cffd..f86198622 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -386,7 +386,7 @@ fail: %{ extern "C" { -void $jsname_initialize(v8::Handle context, v8::Handle global_obj) +void $jsname_initialize(v8::Handle global_obj) { SWIG_InitializeModule(0); diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 0055bad98..7e4b34a3d 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -9,7 +9,7 @@ #include "js_shell.h" -typedef int (*V8ExtensionRegistrar) (v8::Handle, v8::Handle); +typedef int (*V8ExtensionRegistrar) (v8::Handle); class V8Shell: public JSShell { @@ -159,7 +159,7 @@ void V8Shell::ExtendEngine() { // register extensions for(std::vector::iterator it=module_initializers.begin(); it != module_initializers.end(); ++it) { - (*it)(context, global); + (*it)(global); } } From 4fea3a403e5856565d51a5bf0b0a4cec4c03a583 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 8 Jan 2013 22:36:32 +0100 Subject: [PATCH 111/352] Generate an extra file part after the initializer for v8 modules. E.g., this is useful for creating node.js modules. --- Source/Modules/javascript.cxx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index f0b8c472a..a307a399c 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1655,6 +1655,7 @@ private: String *f_runtime; String *f_header; String *f_init; + String *f_post_init; /* part for class templates */ String *f_class_templates; @@ -1709,6 +1710,7 @@ int V8Emitter::initialize(Node *n) f_header = NewString(""); f_class_templates = NewString(""); f_init = NewString(""); + f_post_init = NewString(""); f_init_namespaces = NewString(""); f_init_class_templates = NewString(""); @@ -1723,6 +1725,7 @@ int V8Emitter::initialize(Node *n) Swig_register_filebyname("runtime", f_runtime); Swig_register_filebyname("header", f_header); Swig_register_filebyname("init", f_init); + Swig_register_filebyname("post-init", f_post_init); return SWIG_OK; } @@ -1762,6 +1765,8 @@ int V8Emitter::dump(Node *n) Printv(f_wrap_cpp, f_init, 0); + Printv(f_wrap_cpp, f_post_init, 0); + return SWIG_OK; } @@ -1779,6 +1784,8 @@ int V8Emitter::close() Delete(f_init_static_wrappers); Delete(f_init_register_classes); Delete(f_init_register_namespaces); + Delete(f_init); + Delete(f_post_init); // files Close(f_wrap_cpp); From 213c107b7f4762bf58f7d6a7c7f8b463e2068206 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 8 Jan 2013 22:37:16 +0100 Subject: [PATCH 112/352] Add a swig macro to register node.js extensions. --- Lib/javascript/v8/node.i | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Lib/javascript/v8/node.i diff --git a/Lib/javascript/v8/node.i b/Lib/javascript/v8/node.i new file mode 100644 index 000000000..3b60e92af --- /dev/null +++ b/Lib/javascript/v8/node.i @@ -0,0 +1,7 @@ +%define %node(moduleName) +%insert("post-init") %{ +extern "C" { + NODE_MODULE(moduleName, moduleName ## _initialize) +} +%} +%enddef \ No newline at end of file From caa92740d3241e6aa34ee38a6dbcf846d72c3275 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 9 Jan 2013 00:33:09 +0100 Subject: [PATCH 113/352] Add an option to deactivate creation of an extra module object in javascript. This is useful, if the extension host calls the initializer with custom local variables. E.g., this is the case with node.js. --- Source/Modules/javascript.cxx | 73 +++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 21 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index a307a399c..8850ebd60 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -55,6 +55,8 @@ bool js_template_enable_debug = false; #define V8_REGISTER_CLASSES "$jsv8registerclasses" #define V8_REGISTER_NS "$jsv8registernspaces" +#define FLAG_NO_MODULE_OBJECT "NO_MODULE_OBJECT" + /** * A convenience class to manage state variables for emitters. * The implementation delegates to swig Hash DOHs and provides @@ -307,7 +309,6 @@ protected: String *defaultResultName; File *f_wrappers; - }; /********************************************************************** @@ -522,6 +523,8 @@ void JAVASCRIPT::main(int argc, char *argv[]) { int mode = -1; + bool createModuleObject = true; + for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i], "-v8") == 0) { @@ -539,6 +542,9 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { Swig_mark_arg(i); js_template_enable_debug = true; + } else if (strcmp(argv[i], "-no-moduleobject") == 0) { + Swig_mark_arg(i); + createModuleObject = false; } } } @@ -568,6 +574,10 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } } + if(!createModuleObject) { + SetFlag(emitter->getState().global(), FLAG_NO_MODULE_OBJECT); + } + // Add a symbol to the parser for conditional compilation Preprocessor_define("SWIGJAVASCRIPT 1", 0); @@ -649,13 +659,19 @@ JSEmitterState &JSEmitter::getState() { return state; } -int JSEmitter::initialize(Node * n) { +int JSEmitter::initialize(Node *n) { if(namespaces != NULL) { Delete(namespaces); } namespaces = NewHash(); - Hash *global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); + Hash *global_namespace; + if(State::IsSet(state.global(FLAG_NO_MODULE_OBJECT))) { + Printf(stdout, "AAAAAAAAAAAAAAAAAAAAAAAAAAA"); + global_namespace = createNamespaceEntry("global", 0); + } else { + global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); + } Setattr(namespaces, "::", global_namespace); current_namespace = global_namespace; @@ -1417,7 +1433,7 @@ int JSCEmitter::dump(Node *n) { Printv(f_wrap_cpp, f_wrappers, "\n", 0); emitNamespaces(); - + // compose the initializer function using a template Template initializer(getTemplate("js_initializer")); initializer.replace(T_NAME, module) @@ -1676,6 +1692,7 @@ private: String* GLOBAL; String* NULL_STR; String *VETO_SET; + String *moduleName; }; @@ -1698,6 +1715,8 @@ int V8Emitter::initialize(Node *n) { JSEmitter::initialize(n); + moduleName = Getattr(n,"name"); + // Get the output file name String *outfile = Getattr(n,"outfile"); f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); @@ -1730,11 +1749,8 @@ int V8Emitter::initialize(Node *n) return SWIG_OK; } -int V8Emitter::dump(Node *n) +int V8Emitter::dump(Node *) { - // Get the module name - String* module = Getattr(n,"name"); - // write the swig banner Swig_banner(f_wrap_cpp); @@ -1752,7 +1768,7 @@ int V8Emitter::dump(Node *n) // compose the initializer function using a template // filled with sub-parts Template initializer(getTemplate("js_initializer")); - initializer.replace(T_NAME, module) + initializer.replace(T_NAME, moduleName) .replace(V8_NAME_SPACES, f_init_namespaces) .replace(V8_CLASS_TEMPLATES, f_init_class_templates) .replace(V8_WRAPPERS, f_init_wrappers) @@ -2013,20 +2029,35 @@ int V8Emitter::emitNamespaces() { String *parent = Getattr(entry, PARENT); 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"); - t_create_ns.replace(T_NAME_MANGLED, name_mangled) - .trim() - .pretty_print(f_init_namespaces); + bool do_create = true; + bool do_register = true; - 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) - .trim(); + if (Equal(parent, "")) { + do_register = false; + } - // prepend in order to achieve reversed order of registration statements - Insert(f_init_register_namespaces, 0, t_register_ns.str()); + if (Equal(name, "global")) { + do_create = false; + } + + if (do_create) { + // create namespace object and register it to the parent scope + Template t_create_ns = getTemplate("jsv8_create_namespace"); + t_create_ns.replace(T_NAME_MANGLED, name_mangled) + .trim() + .pretty_print(f_init_namespaces); + } + + if (do_register) { + 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) + .trim(); + + // prepend in order to achieve reversed order of registration statements + Insert(f_init_register_namespaces, 0, t_register_ns.str()); + } } return SWIG_OK; From 04cdde05636f22d8504389a3a92a5c39885f04ad Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 18 Jan 2013 15:33:04 +0100 Subject: [PATCH 114/352] Add test to check javascript unicode strings. --- Examples/test-suite/javascript/Makefile.in | 5 ++- .../javascript/javascript_unicode_runme.js | 7 ++++ Examples/test-suite/javascript_unicode.i | 10 +++++ Lib/javascript/jsc/javascriptstrings.swg | 38 +++++++++---------- 4 files changed, 39 insertions(+), 21 deletions(-) create mode 100644 Examples/test-suite/javascript/javascript_unicode_runme.js create mode 100644 Examples/test-suite/javascript_unicode.i diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index d59f3d60e..e57081412 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -47,7 +47,8 @@ CPP_TEST_CASES = \ typemap_namespace \ typemap_ns_using \ using1 \ - using2 + using2 \ + javascript_unicode SKIP_CPP_CASES = @SKIP_CPP_CASES@ SKIP_C_CASES = @SKIP_C_CASES@ @@ -94,7 +95,7 @@ run_testcase = \ # Clean %.clean: - + clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile javascript_clean diff --git a/Examples/test-suite/javascript/javascript_unicode_runme.js b/Examples/test-suite/javascript/javascript_unicode_runme.js new file mode 100644 index 000000000..4974ef40b --- /dev/null +++ b/Examples/test-suite/javascript/javascript_unicode_runme.js @@ -0,0 +1,7 @@ +var str = "olé"; + +var copy = javascript_unicode.copy_string(str); + +if (str !== copy) { + print("Error: copy is not equal: original="+str+", copy="+copy); +} diff --git a/Examples/test-suite/javascript_unicode.i b/Examples/test-suite/javascript_unicode.i new file mode 100644 index 000000000..516eee5dd --- /dev/null +++ b/Examples/test-suite/javascript_unicode.i @@ -0,0 +1,10 @@ +%module javascript_unicode + +%newobject copy_string; + +%inline %{ +#include +const char* copy_string(const char* str) { + return strdup(str); +} +%} diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg index f83c7533d..26908d9da 100644 --- a/Lib/javascript/jsc/javascriptstrings.swg +++ b/Lib/javascript/jsc/javascriptstrings.swg @@ -1,5 +1,5 @@ /* ------------------------------------------------------------ - * utility methods for char strings + * utility methods for char strings * ------------------------------------------------------------ */ %fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { SWIGINTERN int @@ -8,14 +8,14 @@ SWIG_JSC_AsCharPtrAndSize(JSContextRef context, JSValueRef valRef, char** cptr, if(JSValueIsString(context, valRef)) { JSStringRef js_str = JSValueToStringCopy(context, valRef, NULL); size_t len = JSStringGetMaximumUTF8CStringSize(js_str); - size_t abs_len = JSStringGetLength(js_str); char* cstr = (char*) malloc(len * sizeof(char)); - JSStringGetUTF8CString(js_str, cstr, len); - + /* JSStringGetUTF8CString returns the length including 0-terminator */ + len = JSStringGetUTF8CString(js_str, cstr, len); + if(alloc) *alloc = SWIG_NEWOBJ; - if(psize) *psize = abs_len + 1; + if(psize) *psize = len; if(cptr) *cptr = cstr; - + return SWIG_OK; } else { if(JSValueIsObject(context, valRef)) { @@ -47,7 +47,7 @@ SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t siz if (size > INT_MAX) { // TODO: handle extra long strings //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - //return pchar_descriptor ? + //return pchar_descriptor ? // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); return JSValueMakeUndefined(context); } else { @@ -58,7 +58,7 @@ SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t siz for(i=0;i Date: Fri, 18 Jan 2013 15:34:11 +0100 Subject: [PATCH 115/352] Bugfix: in javascript interpreter load extensions on MacOSX correctly. --- Tools/javascript/js_shell.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx index f0290c785..fa5500f8e 100644 --- a/Tools/javascript/js_shell.cxx +++ b/Tools/javascript/js_shell.cxx @@ -6,11 +6,16 @@ #include #ifdef __GNUC__ +#ifdef __APPLE__ +#define LIBRARY_EXT ".dylib" +#else +#define LIBRARY_EXT ".so" +#endif #include #define LOAD_LIBRARY(name) dlopen(name, RTLD_LAZY) #define CLOSE_LIBRARY(handle) dlclose(handle) #define LIBRARY_ERROR dlerror -#define LIBRARYFILE(name) std::string("lib").append(name).append(".so") +#define LIBRARYFILE(name) std::string("lib").append(name).append(LIBRARY_EXT) #else #error "implement dll loading" #endif From 04c0803f736ef8bd264d7a099a88b4258461547f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 18 Jan 2013 15:35:45 +0100 Subject: [PATCH 116/352] Fixes in configuration to detect JavascriptCore on MacOSX correctly. --- configure.in | 99 ++++++++++++++++++++++++++++------------------------ 1 file changed, 54 insertions(+), 45 deletions(-) diff --git a/configure.in b/configure.in index e4841fc70..0e00c958a 100644 --- a/configure.in +++ b/configure.in @@ -1106,11 +1106,13 @@ if test -z "$JSCOREINCDIR"; then esac fi +JSCORE=0 for d in $JSCOREINCDIR ; do if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then AC_MSG_RESULT($d) JSCOREINCDIR=$d JSCOREINC=-I\"$d\" + JSCORE=1 break fi done @@ -1119,51 +1121,55 @@ if test "$JSCOREINC" = "" ; then AC_MSG_RESULT(not found) fi +# under linux look for the javascript core library +case $host in + *-*-linux*) + # check for JavaScriptCore, Webkit libraries + AC_ARG_WITH(jscorelib,[ --with-jscorelib =path Set location of JavaScriptCore (Webkit) library directory], [JSCORELIB="-L$withval"], [JSCORELIB=]) + AC_MSG_CHECKING(for JavaScriptCore(Webkit) library) -# check for JavaScriptCore, Webkit libraries -AC_ARG_WITH(jscorelib,[ --with-jscorelib =path Set location of JavaScriptCore (Webkit) library directory], - [JSCORELIB="-L$withval"], [JSCORELIB=]) -AC_MSG_CHECKING(for JavaScriptCore(Webkit) library) + if test -z "$JSCORELIB"; then + JSCORELIBDIRS="/usr/lib/ /usr/local/lib/" + for i in $JSCORELIBDIRS ; do -if test -z "$JSCORELIB"; then -dirs="/usr/lib/ /usr/local/lib/" -for i in $dirs ; do + if test -r $i/libwebkit-1.0.la; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkit-1.0" + break + fi - if test -r $i/libwebkit-1.0.la; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -lwebkit-1.0" - break - fi + if test -r $i/libjavascriptcoregtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -ljavascriptcoregtk-1.0" + break + fi - if test -r $i/libjavascriptcoregtk-1.0.so; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -ljavascriptcoregtk-1.0" - break - fi + if test -r $i/libwebkitgtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkitgtk-1.0" + break + fi + done + fi - if test -r $i/libwebkitgtk-1.0.so; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -lwebkitgtk-1.0" - break - fi -done - -if test -z "$JSCORELIB"; then - AC_MSG_RESULT(not found) - JSCORE= -else - AC_MSG_RESULT($JSCORELIB) - JSCORE=1 -fi + if test -z "$JSCORELIB"; then + AC_MSG_RESULT(not found) + JSCORE=0 + else + AC_MSG_RESULT($JSCORELIB) + JSCORE=1 + fi + ;; +esac # linking options case $host in -*-*-darwin*) +*-*-darwin*) JSCOREDYNAMICLINKING="-framework JavaScriptCore" JSCORECFLAGS="" ;; -*-*-linux*) - JSCOREDYNAMICLINKING="$JSCORELIB" +*-*-linux*) + JSCOREDYNAMICLINKING="$JSCORELIB" JSCORECFLAGS="" ;; *) @@ -1179,18 +1185,18 @@ case $host in esac if test "$JS_NO_WARNINGS" == "1"; then -case $host in -*-*-darwin* | *-*-linux* | *-*-cygwin* | *-*-mingw*) - JSCXXFLAGS="`echo $CXXFLAGS | sed 's/-Wall//g'`" - ;; -*) - JSCXXFLAGS="$CXXFLAGS" -esac + case $host in + *-*-darwin* | *-*-linux* | *-*-cygwin* | *-*-mingw*) + JSCXXFLAGS="`echo $CXXFLAGS | sed 's/-Wall//g'`" + ;; + *) + JSCXXFLAGS="$CXXFLAGS" + esac fi # library output case $host in -*-*-darwin*) +*-*-darwin*) JSCORESO=".dylib" JSCORELDSHARED='$(CC) -dynamiclib' JSCORECXXSHARED='$(CXX) -dynamiclib' @@ -1201,7 +1207,6 @@ case $host in JSCORECXXSHARED='$(CXXSHARED)' ;; esac -fi AC_SUBST(JSCORE) AC_SUBST(JSCOREINC) @@ -1259,17 +1264,19 @@ done if test "$JSV8LIB" = "" ; then AC_MSG_RESULT(not found) + JSV8= else AC_MSG_RESULT($JSV8LIB) + JSV8=1 fi # linking options case $host in -*-*-darwin*) +*-*-darwin*) JSV8DYNAMICLINKING="" # TODO: add osx configuration ;; -*-*-linux*) +*-*-linux*) JSV8DYNAMICLINKING="$JSV8LIB" ;; *) @@ -1277,8 +1284,10 @@ case $host in ;; esac +AC_SUBST(JSV8) AC_SUBST(JSV8INC) AC_SUBST(JSV8DYNAMICLINKING) + AC_SUBST(JSDEFAULT) #---------------------------------------------------------------- From 8eb9aa9e73fca795fbd6a716ba830366a4919405 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 22 Jan 2013 15:53:39 +0100 Subject: [PATCH 117/352] Add gitignore file. --- .gitignore | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..72df6b572 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +Makefile +/Examples/Makefile +/Examples/*/Makefile +/Examples/test-suite/*/Makefile +/CCache +*.Po +swigp4.ml +Source/Include/stamp-h1 +Source/Include/swigconfig.h +config.log +config.status +preinst-swig +swig.spec From 22525249f26e36d6603c7ee7bce58cefd8ff611f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 22 Jan 2013 15:54:08 +0100 Subject: [PATCH 118/352] Resolve compile warnings in v8_shell. --- Tools/javascript/v8_shell.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 7e4b34a3d..e2ab1541d 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -149,6 +149,7 @@ bool V8Shell::RunShell() { bool V8Shell::InitializeEngine() { + return true; } void V8Shell::ExtendEngine() { @@ -194,6 +195,7 @@ bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) } bool V8Shell::DisposeEngine() { + return true; } v8::Persistent V8Shell::CreateShellContext() { From 8b10c47ed80a42c4f47b339820333132188659c0 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 22 Jan 2013 19:23:11 +0100 Subject: [PATCH 119/352] Fix regression: add an include for Node.js header. --- Lib/javascript/v8/node.i | 6 +++++- Source/Modules/javascript.cxx | 1 - 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/v8/node.i b/Lib/javascript/v8/node.i index 3b60e92af..3fed6e7db 100644 --- a/Lib/javascript/v8/node.i +++ b/Lib/javascript/v8/node.i @@ -1,7 +1,11 @@ +%insert("init") %{ +#include +%} + %define %node(moduleName) %insert("post-init") %{ extern "C" { NODE_MODULE(moduleName, moduleName ## _initialize) } %} -%enddef \ No newline at end of file +%enddef diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 8850ebd60..b35887ef0 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -667,7 +667,6 @@ int JSEmitter::initialize(Node *n) { namespaces = NewHash(); Hash *global_namespace; if(State::IsSet(state.global(FLAG_NO_MODULE_OBJECT))) { - Printf(stdout, "AAAAAAAAAAAAAAAAAAAAAAAAAAA"); global_namespace = createNamespaceEntry("global", 0); } else { global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); From a4036deda841a9894e7228c4fb80cebe86ff8efc Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 22 Jan 2013 19:26:29 +0100 Subject: [PATCH 120/352] Add pre-processor defines to detect the javascript engine. --- Source/Modules/javascript.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index b35887ef0..cf64b56c0 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -553,11 +553,13 @@ void JAVASCRIPT::main(int argc, char *argv[]) { case JSEmitter::V8: { emitter = swig_javascript_create_V8Emitter(); + Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0); break; } case JSEmitter::JavascriptCore: { emitter = swig_javascript_create_JSCEmitter(); + Preprocessor_define("SWIG_JAVASCRIPT_JSC 1", 0); break; } case JSEmitter::QtScript: From e3da21ee442913c5554203bf8699cab62a69ed15 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 22 Jan 2013 19:28:44 +0100 Subject: [PATCH 121/352] Add more ignores. --- .gitignore | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 72df6b572..2cd4b9b4e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1,87 @@ -Makefile -/Examples/Makefile -/Examples/*/Makefile -/Examples/test-suite/*/Makefile /CCache *.Po swigp4.ml -Source/Include/stamp-h1 -Source/Include/swigconfig.h config.log config.status preinst-swig swig.spec +3build +*.o +CCache/* +Lib/ocaml/swigp4.ml +Lib/swigwarn.swg +Source/Include/stamp-h1 +Source/Include/swigconfig.h +Source/Include/swigconfig.h.in +.deps +.dirstamp +*.cxx~ +*.h~ +Tools/config/* +config.log +config.status +configure +preinst-swig +swig +swig.spec +Source/CParse/parser.* +aclocal.m4 +autom4te.cache/* +*.so +example_wrap.cxx +Source/eswig +runme +.gitignore +swig-jsc.geany +/Makefile +Lib/guile/Makefile +Lib/mzscheme/Makefile +Examples/Makefile +Examples/test-suite/*/Makefile +Examples/perl5/*/Makefile +Examples/android/*/Makefile +Examples/lua/*/Makefile +Examples/guile/Makefile +Examples/guile/*/Makefile +Examples/xml/Makefile +Examples/tcl/*/Makefile +Examples/r/*/Makefile +Examples/octave/*/Makefile +Examples/ruby/*/Makefile +Examples/mzscheme/*/Makefile +Examples/python/*/Makefile +Examples/csharp/*/Makefile +Examples/d/*/Makefile +Examples/pike/*/Makefile +Examples/java/*/Makefile +Examples/php/*/Makefile +Examples/chicken/*/Makefile +Examples/go/*/Makefile +Examples/ocaml/*/Makefile +Examples/modula3/*/Makefile +CCache/Makefile +Source/Makefile +Doc/Manual/Makefile +Examples/test-suite/javascript/*.cxx +Examples/test-suite/javascript/*.c +Examples/test-suite/javascript/*.so +Source/Makefile.in +IndentBaks/ +Examples/javascript/vanilla/ +*.pyc +core +Examples/test-suite/*/*.cxx +Examples/test-suite/*/*.c +Examples/test-suite/*/*.h +Examples/test-suite/python/*.py +Examples/javascript/*/*_wrap.c +Tools/javascript/javascript +Tools/javascript/javascript_d +.settings +*.log +*_wrap.cxx +Examples/*/*/*.gdb +*.orig +*.kdev4 +*.geany +/build \ No newline at end of file From 65560a8664f19aaa03392bba33a4ac435867fa35 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 25 Jan 2013 14:07:06 +0100 Subject: [PATCH 122/352] Fix v8 string conversion in case of null arguments. --- Lib/javascript/v8/std_string.i | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/Lib/javascript/v8/std_string.i b/Lib/javascript/v8/std_string.i index d9221627f..e3248742b 100755 --- a/Lib/javascript/v8/std_string.i +++ b/Lib/javascript/v8/std_string.i @@ -14,19 +14,22 @@ %fragment("SWIGV8_valueToString", "header", fragment="SWIG_AsCharPtrAndSize") { std::string* SWIGV8_valueToStringPtr(v8::Handle val) { + + if (!val->IsString()) return 0; + int alloc; size_t size; char* chars; int res = SWIG_AsCharPtrAndSize(val, &chars, &size, &alloc); - + if(res != SWIG_OK) { v8::ThrowException(v8::Exception::TypeError(v8::String::New("Could not convert to string."))); return 0; } - + // copies the data (again) std::string *str = new std::string(chars); - + if (alloc) delete[] chars; return str; @@ -45,20 +48,22 @@ namespace std { class string; %typemap(in, fragment="SWIGV8_valueToString") string (std::string* tmp) - %{ + %{ tmp = SWIGV8_valueToStringPtr($input); $1 = *tmp; - delete tmp; + if (tmp == 0) { v8::ThrowException(v8::Exception::TypeError(v8::String::New("Null pointer."))); goto fail; } + if (tmp) delete tmp; %} - %typemap(in, fragment="SWIGV8_valueToString") const string & - %{ + %typemap(in, fragment="SWIGV8_valueToString") const string & + %{ $1 = SWIGV8_valueToStringPtr($input); + if ($1 == 0) { v8::ThrowException(v8::Exception::TypeError(v8::String::New("Null pointer."))); goto fail; } %} - - %typemap(freearg) const string & - %{ - delete $1; + + %typemap(freearg) const string & + %{ + if ($1) delete $1; %} %typemap(out, fragment="SWIGV8_stringToValue") string From 5da4f5794c45a09f3e8b641568d38ff650403752 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 25 Jan 2013 14:20:51 +0100 Subject: [PATCH 123/352] Add preprocessor define for building node.js extensions. --- Lib/javascript/v8/node.i | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/javascript/v8/node.i b/Lib/javascript/v8/node.i index 3fed6e7db..a0327a1e3 100644 --- a/Lib/javascript/v8/node.i +++ b/Lib/javascript/v8/node.i @@ -1,4 +1,5 @@ %insert("init") %{ +#define BUILDING_NODE_EXTENSION #include %} From 31feff8586c880bf91f7b6bde61b9dbdc6be57c9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 25 Jan 2013 17:03:23 +0100 Subject: [PATCH 124/352] Add missing return statement in v8 code template. --- Lib/javascript/v8/javascriptcode.swg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index f86198622..3dbd12e09 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -57,7 +57,7 @@ v8::Handle $jswrapper(const v8::Arguments& args) { SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); fail: - scope.Close(v8::Undefined()); + return scope.Close(v8::Undefined()); } %} From 827cef75a35ff9ff84c76c46abf483672c4dbcc4 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 25 Jan 2013 17:09:13 +0100 Subject: [PATCH 125/352] Add an ifndef-guard to resolve a warning when building nodejs extension. --- Lib/javascript/v8/node.i | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/javascript/v8/node.i b/Lib/javascript/v8/node.i index a0327a1e3..4baa5e72f 100644 --- a/Lib/javascript/v8/node.i +++ b/Lib/javascript/v8/node.i @@ -1,5 +1,8 @@ %insert("init") %{ +#ifndef BUILDING_NODE_EXTENSION #define BUILDING_NODE_EXTENSION +#endif + #include %} @@ -7,6 +10,6 @@ %insert("post-init") %{ extern "C" { NODE_MODULE(moduleName, moduleName ## _initialize) -} +} %} %enddef From d3aa8e06fb3d3eb49c05975108acf2c84b716774 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 30 Jan 2013 18:50:03 +0100 Subject: [PATCH 126/352] Bugfix: treat persistent V8 references correctly. V8 is somewhat inconvenient regarding invoke of destructors for C++ proxies. --- Lib/javascript/v8/javascriptcode.swg | 3 +++ Lib/javascript/v8/javascriptruntime.swg | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 3dbd12e09..256b71315 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -118,6 +118,9 @@ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { $jsfree proxy->swigCObject; } delete proxy; + + object.Clear(); + object.Dispose(); } %} diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index b6ef55d90..f61bb27b3 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -72,12 +72,17 @@ public: }; ~SWIGV8_Proxy() { + handle.ClearWeak(); + handle->SetInternalField(0, v8::Undefined()); + handle.Dispose(); + handle.Clear(); v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); } bool swigCMemOwn; void *swigCObject; swig_type_info *info; + v8::Persistent handle; }; class SWIGV8_ClientData { @@ -131,14 +136,16 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; cdata->info = info; obj->SetPointerInInternalField(0, cdata); - - v8::Persistent weakptr = v8::Persistent::New(obj); - // clientdata must be set for owned data as we need to register the dtor + + cdata->handle = v8::Persistent::New(obj); + + // 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); + cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); } else { - weakptr.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); + cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); } + cdata->handle.MarkIndependent(); } int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { From b511e33121c5167a9a206ddc2f3417f56d39afa9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 3 May 2013 18:23:36 +0200 Subject: [PATCH 127/352] Remove std::iostream relicts from generated v8 wrapper code. --- Lib/javascript/v8/javascriptcode.swg | 1 - Lib/javascript/v8/javascriptruntime.swg | 1 - 2 files changed, 2 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 256b71315..0856c12ae 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -114,7 +114,6 @@ fail: 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; $jsfree proxy->swigCObject; } delete proxy; diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index f61bb27b3..8136be184 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -8,7 +8,6 @@ #include #include #include -#include %} %insert(runtime) "swigrun.swg"; /* SWIG API */ From 26a4f849485d03fe57ba47435f11953b019ae515 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Thu, 11 Jul 2013 15:06:08 +0400 Subject: [PATCH 128/352] added missing javascript/v8 dir --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index 0a485cd33..9a19d73fa 100644 --- a/Makefile.in +++ b/Makefile.in @@ -431,7 +431,7 @@ install-main: @$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@ lib-languages = gcj typemaps tcl perl5 python guile java mzscheme ruby php ocaml octave \ - pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d javascript javascript/jsc + pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d javascript javascript/jsc javascript/v8 lib-modules = std From 9111773400ba10b6b98fea7996d3dcbf53b97ecf Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Thu, 11 Jul 2013 16:41:40 +0400 Subject: [PATCH 129/352] generate v8-3.19.x compatible code --- Lib/javascript/v8/javascriptcode.swg | 9 ++++----- Lib/javascript/v8/javascripthelpers.swg | 4 ++-- Lib/javascript/v8/javascriptruntime.swg | 22 ++++++++++------------ 3 files changed, 16 insertions(+), 19 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 0856c12ae..6ca0fff42 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -111,15 +111,14 @@ fail: * ----------------------------------------------------------------------------- */ %fragment ("js_dtor", "templates") %{ -void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { - SWIGV8_Proxy* proxy = (SWIGV8_Proxy*) parameter; +void $jswrapper(v8::Isolate *iso, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) { if(proxy->swigCMemOwn && proxy->swigCObject) { $jsfree proxy->swigCObject; } delete proxy; - object.Clear(); - object.Dispose(); + object->Dispose(); + object->Clear(); } %} @@ -395,7 +394,7 @@ void $jsname_initialize(v8::Handle global_obj) v8::HandleScope scope; // a class template for creating proxies of undefined types - SWIGV8_SWIGTYPE_Proxy_class_templ = SWIGV8_CreateClassTemplate("SwigProxy"); + SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); /* create objects for namespaces */ $jsv8nspaces diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index 4fcf0e447..b3868efff 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -3,14 +3,14 @@ /** * Creates a class template for a class with specified initialization function. */ -v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol) { +v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) { v8::Local class_templ = v8::FunctionTemplate::New(); class_templ->SetClassName(v8::String::NewSymbol(symbol)); v8::Handle inst_templ = class_templ->InstanceTemplate(); inst_templ->SetInternalFieldCount(1); - return v8::Persistent::New(class_templ); + return class_templ; } /** diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 8136be184..13d8cf590 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -72,7 +72,7 @@ public: ~SWIGV8_Proxy() { handle.ClearWeak(); - handle->SetInternalField(0, v8::Undefined()); + //handle->SetInternalField(0, v8::Undefined()); handle.Dispose(); handle.Clear(); v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); @@ -87,7 +87,7 @@ public: class SWIGV8_ClientData { public: v8::Handle class_templ; - void (*dtor) (v8::Persistent< v8::Value > object, void *parameter); + void (*dtor) (v8::Isolate *iso, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *parameter); }; v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; @@ -97,7 +97,7 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; v8::Handle cdataRef = objRef->GetInternalField(0); - SWIGV8_Proxy *cdata = (SWIGV8_Proxy *) v8::External::Unwrap(cdataRef); + SWIGV8_Proxy *cdata = (SWIGV8_Proxy *) (!cdataRef.IsEmpty() && cdataRef->IsExternal()? cdataRef.As()->Value(): NULL); if(cdata == NULL) { return SWIG_ERROR; } @@ -122,11 +122,8 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle 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_Proxy_DefaultDtor(v8::Isolate* isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) { + delete proxy; } void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { @@ -134,9 +131,9 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->swigCObject = ptr; cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; cdata->info = info; - obj->SetPointerInInternalField(0, cdata); + obj->SetAlignedPointerInInternalField(0, cdata); - cdata->handle = v8::Persistent::New(obj); + cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); // clientdata must be set for owned data as we need to register the dtor if(cdata->swigCMemOwn) { @@ -159,12 +156,13 @@ int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { v8::HandleScope scope; + v8::Isolate *iso = v8::Isolate::GetCurrent(); v8::Handle class_templ; if(info->clientdata != 0) { - class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; + class_templ = v8::Handle::New(iso, ((SWIGV8_ClientData*) info->clientdata)->class_templ); } else { - class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ; + class_templ = v8::Handle::New(iso, SWIGV8_SWIGTYPE_Proxy_class_templ); } v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); SWIGV8_SetPrivateData(result, ptr, info, flags); From fe25e2dfc8fd4fa29702685684337444f5948cb1 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Thu, 18 Jul 2013 18:42:03 +0400 Subject: [PATCH 130/352] replaced GetInternalField with GetAlignedPointer (it does not work with SetAlignedPointer, btw) --- Lib/javascript/v8/javascriptruntime.swg | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 13d8cf590..d23efcb55 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -96,8 +96,7 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t v8::HandleScope scope; if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; - v8::Handle cdataRef = objRef->GetInternalField(0); - SWIGV8_Proxy *cdata = (SWIGV8_Proxy *) (!cdataRef.IsEmpty() && cdataRef->IsExternal()? cdataRef.As()->Value(): NULL); + SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); if(cdata == NULL) { return SWIG_ERROR; } From 9b6a4870dd96656f0e9ec731e9b2dea856ae4939 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Thu, 18 Jul 2013 18:53:15 +0400 Subject: [PATCH 131/352] added missing scope.Close() --- Lib/javascript/v8/javascripthelpers.swg | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index b3868efff..d28243d88 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -4,13 +4,14 @@ * Creates a class template for a class with specified initialization function. */ v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) { + v8::HandleScope scope; v8::Local class_templ = v8::FunctionTemplate::New(); class_templ->SetClassName(v8::String::NewSymbol(symbol)); v8::Handle inst_templ = class_templ->InstanceTemplate(); inst_templ->SetInternalFieldCount(1); - return class_templ; + return scope.Close(class_templ); } /** From 45bfc97ef437eb919bec2579dd39e3bbb0fd1c12 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Thu, 18 Jul 2013 19:15:38 +0400 Subject: [PATCH 132/352] converted function templates to the persistent ones (fixed crash on large wrappers) --- Lib/javascript/v8/javascriptcode.swg | 2 +- Lib/javascript/v8/javascriptruntime.swg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 6ca0fff42..a6cd18c62 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -261,7 +261,7 @@ fail: %fragment("jsv8_define_class_template", "templates") %{ v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); - $jsmangledname_clientData.class_templ = $jsmangledname_class; + $jsmangledname_clientData.class_templ.Reset(v8::Isolate::GetCurrent(), $jsmangledname_class); $jsmangledname_clientData.dtor = $jsdtor; SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData; %} diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index d23efcb55..12c274ed2 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -86,7 +86,7 @@ public: class SWIGV8_ClientData { public: - v8::Handle class_templ; + v8::Persistent class_templ; void (*dtor) (v8::Isolate *iso, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *parameter); }; From a190288e663e207375a42bfb7476ab1ca336f2af Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Thu, 18 Jul 2013 21:03:56 +0400 Subject: [PATCH 133/352] fixed overloaded functions multiplication --- Source/Modules/javascript.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index cf64b56c0..cd562737f 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1093,7 +1093,7 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { .pretty_print(f_wrappers); // Delete the state variable - state.global(FUNCTION_DISPATCHERS, 0); + state.global(FUNCTION_DISPATCHERS, NewString("")); DelWrapper(wrapper); return SWIG_OK; From 868803ce2ad158326cb70d2e5667baf4014df31a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Sat, 31 Aug 2013 03:44:44 +0200 Subject: [PATCH 134/352] Merge replayed as done by c778d16abed35829b103d607a53c8f88e3b2d595 --- CMakeLists.txt | 4 -- Lib/javascript/v8/javascriptcode.swg | 44 +++++++++++++-- Lib/javascript/v8/javascriptinit.swg | 42 +++++++++++--- Lib/javascript/v8/javascriptruntime.swg | 59 +++++++++++++++---- Lib/javascript/v8/node.i | 15 ++--- Lib/javascript/v8/std_pair.i | 1 - Lib/javascript/v8/std_string.i | 2 +- Makefile.in | 3 +- Source/Modules/javascript.cxx | 75 ++++++++++++++++--------- 9 files changed, 179 insertions(+), 66 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e7d96cc8e..1bf7a2c76 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,10 +135,6 @@ add_library(modules "${SWIG_SOURCE_DIR}/Modules/allegrocl.cxx" "${SWIG_SOURCE_DIR}/Modules/guile.cxx" "${SWIG_SOURCE_DIR}/Modules/java.cxx" "${SWIG_SOURCE_DIR}/Modules/javascript.cxx" - "${SWIG_SOURCE_DIR}/Modules/javascript_emitter.h" - "${SWIG_SOURCE_DIR}/Modules/javascript_emitter.cxx" - "${SWIG_SOURCE_DIR}/Modules/javascript_v8.h" - "${SWIG_SOURCE_DIR}/Modules/javascript_v8.cxx" "${SWIG_SOURCE_DIR}/Modules/lang.cxx" "${SWIG_SOURCE_DIR}/Modules/lua.cxx" "${SWIG_SOURCE_DIR}/Modules/modula3.cxx" diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index a6cd18c62..d79a0c34b 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -111,14 +111,28 @@ fail: * ----------------------------------------------------------------------------- */ %fragment ("js_dtor", "templates") %{ -void $jswrapper(v8::Isolate *iso, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) { + +#ifdef BUILDING_NODE_EXTENSION +void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) +#else +void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) +#endif +{ if(proxy->swigCMemOwn && proxy->swigCObject) { +#ifdef SWIGRUNTIME_DEBUG + printf("Deleting wrapped instance: %s\n", proxy->info->name); +#endif $jsfree proxy->swigCObject; } delete proxy; - object->Dispose(); object->Clear(); + +#ifdef BUILDING_NODE_EXTENSION + object->Dispose(); +#else + object->Dispose(isolate); +#endif } %} @@ -266,6 +280,7 @@ fail: SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData; %} + /* ----------------------------------------------------------------------------- * jsv8_inherit: template for an class inherit statement. * - $jsmangledname: mangled class name @@ -273,7 +288,17 @@ fail: * ----------------------------------------------------------------------------- */ %fragment("jsv8_inherit", "templates") %{ - $jsmangledname_class->Inherit($jsbaseclass_class); + if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty())) + { + $jsmangledname_class->Inherit(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ); +#ifdef SWIGRUNTIME_DEBUG + printf("Inheritance successful $jsmangledname $jsbaseclass\n"); +#endif + } else { +#ifdef SWIGRUNTIME_DEBUG + printf("Unable to inherit baseclass, it didn't exist $jsmangledname $jsbaseclass\n"); +#endif + } %} /* ----------------------------------------------------------------------------- @@ -387,9 +412,13 @@ fail: %{ extern "C" { +#ifdef BUILDING_NODE_EXTENSION +void $jsname_initialize(v8::Handle global_obj, v8::Handle /*module*/) +#else void $jsname_initialize(v8::Handle global_obj) +#endif { - SWIG_InitializeModule(0); + SWIG_InitializeModule(static_cast(&global_obj)); v8::HandleScope scope; @@ -419,8 +448,13 @@ void $jsname_initialize(v8::Handle global_obj) /* create and register namespace objects */ $jsv8registernspaces - } +#ifdef BUILDING_NODE_EXTENSION +NODE_MODULE($jsname, $jsname_initialize); +#endif + + + } // extern "C" %} diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg index 1bca4c244..684728023 100644 --- a/Lib/javascript/v8/javascriptinit.swg +++ b/Lib/javascript/v8/javascriptinit.swg @@ -1,14 +1,42 @@ %insert(init) %{ -SWIGRUNTIME void -SWIG_V8_SetModule(swig_module_info *swig_module) {} -SWIGRUNTIME swig_module_info * -SWIG_V8_GetModule(void) { - return 0; + +SWIGRUNTIME void +SWIG_V8_SetModule(void *, swig_module_info *swig_module) { + v8::Local global_obj = v8::Context::GetCurrent()->Global(); + v8::Local mod = v8::External::New(swig_module); + assert(!mod.IsEmpty()); + global_obj->SetHiddenValue(v8::String::New("swig_module_info_data"), mod); } -#define SWIG_GetModule(clientdata) SWIG_V8_GetModule() -#define SWIG_SetModule(clientdata, pointer) SWIG_V8_SetModule(pointer) +SWIGRUNTIME swig_module_info * +SWIG_V8_GetModule(void *) { + v8::Local global_obj = v8::Context::GetCurrent()->Global(); + v8::Local moduleinfo = global_obj->GetHiddenValue(v8::String::New("swig_module_info_data")); + + if (moduleinfo.IsEmpty()) + { + // It's not yet loaded + return 0; + } + + v8::Local moduleinfo_extern = v8::Local::Cast(moduleinfo); + + if (moduleinfo_extern.IsEmpty()) + { + // Something's not right + return 0; + } + + void *ptr = moduleinfo_extern->Value(); + assert(ptr); + swig_module_info *retptr = static_cast(ptr); + assert(retptr); + return retptr; +} + +#define SWIG_GetModule(clientdata) SWIG_V8_GetModule(clientdata) +#define SWIG_SetModule(clientdata, pointer) SWIG_V8_SetModule(clientdata, pointer) %} diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 12c274ed2..f2443ce1f 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -5,7 +5,9 @@ * ----------------------------------------------------------------------------- */ %insert(runtime) %{ + #include + #include #include %} @@ -60,7 +62,7 @@ public: %insert(runtime) %{ -// Note: to trigger the c8 gc more often one can tell v8 about the memory consumption +// Note: to trigger the v8 gc more often one can tell v8 about the memory consumption // TODO: we could add a v8 specific parameter to control this value #define SWIGV8_AVG_OBJ_SIZE 1000 @@ -71,9 +73,19 @@ public: }; ~SWIGV8_Proxy() { +#ifdef BUILDING_NODE_EXTENSION handle.ClearWeak(); +#else + handle.ClearWeak(v8::Isolate::GetCurrent()); +#endif + //handle->SetInternalField(0, v8::Undefined()); + +#ifdef BUILDING_NODE_EXTENSION handle.Dispose(); +#else + handle.Dispose(v8::Isolate::GetCurrent()); +#endif handle.Clear(); v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); } @@ -87,7 +99,12 @@ public: class SWIGV8_ClientData { public: v8::Persistent class_templ; - void (*dtor) (v8::Isolate *iso, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *parameter); + +#ifdef BUILDING_NODE_EXTENSION + void (*dtor) (v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); +#else + void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); +#endif }; v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; @@ -101,15 +118,11 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t return SWIG_ERROR; } if(cdata->info != info) { - bool type_valid = false; - swig_cast_info *t = info->cast; - while(t != NULL) { - if(t->type == cdata->info) { - type_valid = true; - break; - } - t = t->next; + swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info); + if (!tc && cdata->info->name) { + tc = SWIG_TypeCheck(cdata->info->name, info); } + bool type_valid = tc != 0; if(!type_valid) { return SWIG_TypeError; } @@ -121,8 +134,13 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t return SWIG_OK; } -void SWIGV8_Proxy_DefaultDtor(v8::Isolate* isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) { - delete proxy; +#ifdef BUILDING_NODE_EXTENSION +void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) +#else +void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) +#endif +{ + delete proxy; } void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { @@ -132,8 +150,13 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->info = info; obj->SetAlignedPointerInInternalField(0, cdata); +#ifdef BUILDING_NODE_EXTENSION + #warning port me +#else cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); +#endif +#ifdef BUILDING_NODE_EXTENSION // clientdata must be set for owned data as we need to register the dtor if(cdata->swigCMemOwn) { cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); @@ -141,6 +164,14 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); } cdata->handle.MarkIndependent(); +#else + if(cdata->swigCMemOwn) { + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); + } else { + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor); + } + cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); +#endif } int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { @@ -175,4 +206,8 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in #define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_V8_ConvertInstancePtr(obj, pptr, type, flags) #define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_V8_NewPointerObj(thisvalue, type, flags) +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_V8_ConvertPtr(obj, pptr, type, 0) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_V8_NewPointerObj(ptr, type, 0) + %} + diff --git a/Lib/javascript/v8/node.i b/Lib/javascript/v8/node.i index 4baa5e72f..8bf9ef061 100644 --- a/Lib/javascript/v8/node.i +++ b/Lib/javascript/v8/node.i @@ -1,15 +1,12 @@ -%insert("init") %{ +%insert("begin") %{ #ifndef BUILDING_NODE_EXTENSION #define BUILDING_NODE_EXTENSION #endif - -#include %} -%define %node(moduleName) -%insert("post-init") %{ -extern "C" { - NODE_MODULE(moduleName, moduleName ## _initialize) -} +%insert("runtime") %{ +// we are including relative to the src folder because of issues +// with other files which might be named "node.h" +#include %} -%enddef + diff --git a/Lib/javascript/v8/std_pair.i b/Lib/javascript/v8/std_pair.i index fe45ee676..8d6057223 100755 --- a/Lib/javascript/v8/std_pair.i +++ b/Lib/javascript/v8/std_pair.i @@ -5,7 +5,6 @@ * ----------------------------------------------------------------------------- */ %include -%include // ------------------------------------------------------------------------ // std::pair diff --git a/Lib/javascript/v8/std_string.i b/Lib/javascript/v8/std_string.i index e3248742b..5ad1ead27 100755 --- a/Lib/javascript/v8/std_string.i +++ b/Lib/javascript/v8/std_string.i @@ -73,7 +73,7 @@ namespace std { %typemap(out, fragment="SWIGV8_stringToValue") const string & %{ - $result = SWIGV8_stringToValue($1); + $result = SWIGV8_stringToValue(*$1); %} } diff --git a/Makefile.in b/Makefile.in index 9a19d73fa..c1fc82f74 100644 --- a/Makefile.in +++ b/Makefile.in @@ -431,7 +431,8 @@ install-main: @$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@ lib-languages = gcj typemaps tcl perl5 python guile java mzscheme ruby php ocaml octave \ - pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d javascript javascript/jsc javascript/v8 + pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d javascript javascript/jsc \ + javascript/v8 lib-modules = std diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index cd562737f..4c36e838a 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -22,7 +22,6 @@ bool js_template_enable_debug = false; #define CTOR_DISPATCHERS "ctor_dispatchers" #define DTOR "dtor" #define ARGCOUNT "wrap:argc" -#define FUNCTION_DISPATCHERS "function_dispatchers" // variables used in code templates // ATTENTION: be aware of prefix collisions when defining those variables @@ -793,12 +792,6 @@ int JSEmitter::enterFunction(Node *n) { SetFlag(state.function(), IS_STATIC); } - /* Initialize DOH for collecting function dispatchers */ - bool is_overloaded = GetFlag(n, "sym:overloaded"); - if (is_overloaded && state.global(FUNCTION_DISPATCHERS) == 0) { - state.global(FUNCTION_DISPATCHERS, NewString("")); - } - return SWIG_OK; } @@ -1061,13 +1054,6 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) .pretty_print(f_wrappers); - // handle function overloading - if (is_overloaded) { - Template t_dispatch_case = getTemplate("js_function_dispatch_case"); - t_dispatch_case.replace(T_WRAPPER, wrap_name) - .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); - Append(state.global(FUNCTION_DISPATCHERS), t_dispatch_case.str()); - } DelWrapper(wrapper); @@ -1075,14 +1061,47 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { } int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { + Wrapper *wrapper = NewWrapper(); + + // Generate call list, go to first node + Node *sibl = n; + + while (Getattr(sibl, "sym:previousSibling")) + sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up + + do { + String *siblname = Getattr(sibl, "wrap:name"); + + if (siblname) + { + // handle function overloading + Template t_dispatch_case = getTemplate("js_function_dispatch_case"); + t_dispatch_case.replace(T_WRAPPER, siblname) + .replace(T_ARGCOUNT, Getattr(sibl, ARGCOUNT)); + + Append(wrapper->code, t_dispatch_case.str()); + } + + } while ((sibl = Getattr(sibl, "sym:nextSibling"))); + + + Template t_function(getTemplate("js_function_dispatcher")); - Wrapper *wrapper = NewWrapper(); - String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); - Setattr(n, "wrap:name", wrap_name); +// String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); - Append(wrapper->code, state.global(FUNCTION_DISPATCHERS)); + + String *fun_name = Getattr(n, "sym:name"); + + Node *methodclass = Swig_methodclass(n); + String *class_name = Getattr(methodclass, "sym:name"); + + String *new_string = NewStringf("%s_%s", class_name, fun_name); + String *wrap_name = Swig_name_wrapper(new_string); + + Setattr(n, "wrap:name", wrap_name); + state.function(WRAPPER_NAME, wrap_name); t_function.replace(T_LOCALS, wrapper->locals) .replace(T_CODE, wrapper->code); @@ -1093,7 +1112,6 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { .pretty_print(f_wrappers); // Delete the state variable - state.global(FUNCTION_DISPATCHERS, NewString("")); DelWrapper(wrapper); return SWIG_OK; @@ -1480,7 +1498,7 @@ int JSCEmitter::exitFunction(Node *n) { // handle overloaded functions if (is_overloaded) { if (!Getattr(n, "sym:nextSibling")) { - state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); + //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); // create dispatcher emitFunctionDispatcher(n, is_member); } else { @@ -1742,6 +1760,7 @@ int V8Emitter::initialize(Node *n) f_init_register_namespaces = NewString(""); // note: this is necessary for built-in generation of swig runtime code + Swig_register_filebyname("begin", f_wrap_cpp); Swig_register_filebyname("runtime", f_runtime); Swig_register_filebyname("header", f_header); Swig_register_filebyname("init", f_init); @@ -1757,7 +1776,8 @@ int V8Emitter::dump(Node *) SwigType_emit_type_table(f_runtime, f_wrappers); - emitUndefined(); + // Let's not and say we did + // emitUndefined(); Printv(f_wrap_cpp, f_runtime, "\n", 0); Printv(f_wrap_cpp, f_header, "\n", 0); @@ -1859,12 +1879,15 @@ int V8Emitter::exitClass(Node *n) // emit inheritance setup Node* baseClass = getBaseClass(n); if(baseClass) { + String *base_name = Getattr(baseClass, "name"); + Template t_inherit = getTemplate("jsv8_inherit"); - String *base_name_mangled = SwigType_manglestr(Getattr(baseClass, "name")); + + String *base_name_mangled = SwigType_manglestr(base_name); t_inherit.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_BASECLASS, base_name_mangled) - .trim() - .pretty_print(f_init_inheritance); + .replace(T_BASECLASS, base_name_mangled) + .trim() + .pretty_print(f_init_inheritance); Delete(base_name_mangled); } @@ -1932,7 +1955,7 @@ int V8Emitter::exitFunction(Node* n) bool is_overloaded = GetFlag(n, "sym:overloaded"); if (is_overloaded) { if (!Getattr(n, "sym:nextSibling")) { - state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); + //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); emitFunctionDispatcher(n, is_member); } else { //don't register wrappers of overloaded functions in function tables From 9e74bdb97e049511be20322aa85884c1249d3606 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Tue, 6 Aug 2013 15:50:43 +0400 Subject: [PATCH 135/352] added virtual dtor to V8ErrorHandler --- Lib/javascript/v8/javascriptruntime.swg | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index c2aca8c32..329354d8a 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -40,6 +40,7 @@ void SWIG_V8_Raise(const char* msg) { */ class V8ErrorHandler { public: + virtual ~V8ErrorHandler() {} virtual void error(int code, const char* msg) { SWIG_V8_Raise(msg); } From 3af7d543cb52623f962a48f91a129181af29901a Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Wed, 7 Aug 2013 16:11:59 +0400 Subject: [PATCH 136/352] fixed crash while instantiating generic-wrapped objects from external code, please review --- Lib/javascript/v8/javascriptruntime.swg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 329354d8a..17c33ca09 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -171,14 +171,14 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info #ifdef BUILDING_NODE_EXTENSION // clientdata must be set for owned data as we need to register the dtor - if(cdata->swigCMemOwn) { + if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); } else { cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); } cdata->handle.MarkIndependent(); #else - if(cdata->swigCMemOwn) { + if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); } else { cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor); From cf9b7e89ac52badd89acc2ba2bb5072055837ce0 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 27 Jul 2013 09:50:03 -0600 Subject: [PATCH 137/352] Get memory updates working with Node.js again. --- Lib/javascript/v8/javascriptcode.swg | 20 ++++++++++++-- Lib/javascript/v8/javascriptruntime.swg | 35 ++++++++++++++++++++----- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index d79a0c34b..daeeee6be 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -118,6 +118,11 @@ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) #endif { + +#ifdef BUILDING_NODE_EXTENSION + SWIGV8_Proxy *proxy = static_cast(parameter); +#endif + if(proxy->swigCMemOwn && proxy->swigCObject) { #ifdef SWIGRUNTIME_DEBUG printf("Deleting wrapped instance: %s\n", proxy->info->name); @@ -126,11 +131,12 @@ void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWI } delete proxy; - object->Clear(); #ifdef BUILDING_NODE_EXTENSION - object->Dispose(); + object.Clear(); + object.Dispose(); #else + object->Clear(); object->Dispose(isolate); #endif } @@ -275,7 +281,11 @@ fail: %fragment("jsv8_define_class_template", "templates") %{ v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); +#ifdef BUILDING_NODE_EXTENSION + $jsmangledname_clientData.class_templ = v8::Persistent::New($jsmangledname_class); +#else $jsmangledname_clientData.class_templ.Reset(v8::Isolate::GetCurrent(), $jsmangledname_class); +#endif $jsmangledname_clientData.dtor = $jsdtor; SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData; %} @@ -423,7 +433,13 @@ void $jsname_initialize(v8::Handle global_obj) v8::HandleScope scope; // a class template for creating proxies of undefined types + +#ifdef BUILDING_NODE_EXTENSION + SWIGV8_SWIGTYPE_Proxy_class_templ = v8::Persistent::New(SWIGV8_CreateClassTemplate("SwigProxy")); +#else SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); +#endif + /* create objects for namespaces */ $jsv8nspaces diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index f2443ce1f..c2aca8c32 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -101,7 +101,7 @@ public: v8::Persistent class_templ; #ifdef BUILDING_NODE_EXTENSION - void (*dtor) (v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); + void (*dtor) (v8::Persistent< v8::Value> object, void *parameter); #else void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); #endif @@ -113,7 +113,14 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t v8::HandleScope scope; if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; + +#ifdef BUILDING_NODE_EXTENSION + v8::Handle cdataRef = objRef->GetInternalField(0); + SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); +#else SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + if(cdata == NULL) { return SWIG_ERROR; } @@ -135,12 +142,16 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t } #ifdef BUILDING_NODE_EXTENSION -void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) +void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) #else void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) #endif { - delete proxy; +#ifdef BUILDING_NODE_EXTENSION + SWIGV8_Proxy *proxy = static_cast(parameter); +#endif + + delete proxy; } void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { @@ -148,11 +159,12 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->swigCObject = ptr; cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; cdata->info = info; - obj->SetAlignedPointerInInternalField(0, cdata); #ifdef BUILDING_NODE_EXTENSION - #warning port me + obj->SetPointerInInternalField(0, cdata); + cdata->handle = v8::Persistent::New(obj); #else + obj->SetAlignedPointerInInternalField(0, cdata); cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); #endif @@ -186,14 +198,25 @@ int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { v8::HandleScope scope; + v8::Handle class_templ; + + +#ifdef BUILDING_NODE_EXTENSION + if(info->clientdata != 0) { + class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; + } else { + class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ; + } +#else v8::Isolate *iso = v8::Isolate::GetCurrent(); - v8::Handle class_templ; if(info->clientdata != 0) { class_templ = v8::Handle::New(iso, ((SWIGV8_ClientData*) info->clientdata)->class_templ); } else { class_templ = v8::Handle::New(iso, SWIGV8_SWIGTYPE_Proxy_class_templ); } +#endif + v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); SWIGV8_SetPrivateData(result, ptr, info, flags); From d5df0bb72101d057b6d59cf7d683263e65288884 Mon Sep 17 00:00:00 2001 From: Eric Wing Date: Wed, 7 Aug 2013 15:11:49 -0700 Subject: [PATCH 138/352] Added #if defined guard for V8_3_14 to allow users from the original SWIG v8 implementation to continue using the new changes. It works similarly to the BUILDING_NODE_EXTENSION in all but two places. This define must be explicitly set by users because there is no way to auto detect. (Perhaps a command line switch can be added to generate this on request?) --- Lib/javascript/v8/javascriptcode.swg | 16 ++++++++-------- Lib/javascript/v8/javascriptruntime.swg | 18 +++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 195141214..42be1a2dc 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -112,14 +112,14 @@ fail: %fragment ("js_dtor", "templates") %{ -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) #else void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) #endif { -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) SWIGV8_Proxy *proxy = static_cast(parameter); #endif @@ -132,7 +132,7 @@ void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWI delete proxy; -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) object.Clear(); object.Dispose(); #else @@ -281,7 +281,7 @@ fail: %fragment("jsv8_define_class_template", "templates") %{ v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) $jsmangledname_clientData.class_templ = v8::Persistent::New($jsmangledname_class); #else $jsmangledname_clientData.class_templ.Reset(v8::Isolate::GetCurrent(), $jsmangledname_class); @@ -300,7 +300,7 @@ fail: %{ if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty())) { -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) $jsmangledname_class->Inherit(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ); #else $jsmangledname_class->Inherit( @@ -431,7 +431,7 @@ fail: %{ extern "C" { -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) void $jsname_initialize(v8::Handle global_obj, v8::Handle /*module*/) #else void $jsname_initialize(v8::Handle global_obj) @@ -443,7 +443,7 @@ void $jsname_initialize(v8::Handle global_obj) // a class template for creating proxies of undefined types -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) SWIGV8_SWIGTYPE_Proxy_class_templ = v8::Persistent::New(SWIGV8_CreateClassTemplate("SwigProxy")); #else SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); @@ -475,7 +475,7 @@ void $jsname_initialize(v8::Handle global_obj) $jsv8registernspaces } -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) NODE_MODULE($jsname, $jsname_initialize); #endif diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 17c33ca09..fddfcf70c 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -74,7 +74,7 @@ public: }; ~SWIGV8_Proxy() { -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) handle.ClearWeak(); #else handle.ClearWeak(v8::Isolate::GetCurrent()); @@ -82,7 +82,7 @@ public: //handle->SetInternalField(0, v8::Undefined()); -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) handle.Dispose(); #else handle.Dispose(v8::Isolate::GetCurrent()); @@ -101,7 +101,7 @@ class SWIGV8_ClientData { public: v8::Persistent class_templ; -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) void (*dtor) (v8::Persistent< v8::Value> object, void *parameter); #else void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); @@ -115,7 +115,7 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) v8::Handle cdataRef = objRef->GetInternalField(0); SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); #else @@ -142,13 +142,13 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t return SWIG_OK; } -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) #else void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) #endif { -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) SWIGV8_Proxy *proxy = static_cast(parameter); #endif @@ -161,7 +161,7 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; cdata->info = info; -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) obj->SetPointerInInternalField(0, cdata); cdata->handle = v8::Persistent::New(obj); #else @@ -169,7 +169,7 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); #endif -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) // clientdata must be set for owned data as we need to register the dtor if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); @@ -202,7 +202,7 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in v8::Handle class_templ; -#ifdef BUILDING_NODE_EXTENSION +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) if(info->clientdata != 0) { class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; } else { From 046ca7686b5605fc7e729d5a4afbe28f2d2c6807 Mon Sep 17 00:00:00 2001 From: Jason Turner Date: Sat, 27 Jul 2013 12:35:36 -0600 Subject: [PATCH 139/352] Adjust for v8::Persistent API which was deprecated @ 3.19.16 https://groups.google.com/forum/#!topic/v8-users/oBE_DTpRC08 --- Lib/javascript/v8/javascriptcode.swg | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index daeeee6be..195141214 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -300,7 +300,16 @@ fail: %{ if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty())) { +#ifdef BUILDING_NODE_EXTENSION $jsmangledname_class->Inherit(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ); +#else + $jsmangledname_class->Inherit( + v8::Handle::New( + v8::Isolate::GetCurrent(), + static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ) + ); +#endif + #ifdef SWIGRUNTIME_DEBUG printf("Inheritance successful $jsmangledname $jsbaseclass\n"); #endif From ed729f7d3adaf675bbf7f1f800cdcbe17287d987 Mon Sep 17 00:00:00 2001 From: Eric Wing Date: Thu, 11 Jul 2013 19:09:17 -0700 Subject: [PATCH 140/352] This brings over the memory leak fixes for pointers to structs with a %extend destructor from my Neha fork. The generator was not generating and connecting the needed code for the requested destructor to the v8 dtor finalizer. I did not realize this branch has some JavaScriptCore stuff in it too. Unfortunately, it seems to have its own unique problems (like creating C++ files when it should be generating C files). My changes are targeted for v8, and I don't think my JSCore changes fully reach in this JSCore implementation so more work would need to be done to get this branch working. I think my Neha fork is in better shape at the moment. Also, I did port over the 'NULL out the dtor function pointer' in the %nodefaultdtor fix to v8. Usage case: struct MyData { %extend { ~MyData() { FreeData($self); } } }; %newobject CreateData; struct MyData* CreateData(void); %delobject FreeData; void FreeData(struct MyData* the_data); where the use case is something like: var my_data = example.CreateData(); my_data = null; --- Lib/javascript/jsc/javascriptcode.swg | 19 +++++ Lib/javascript/v8/javascriptcode.swg | 21 +++++- Source/Modules/javascript.cxx | 101 +++++++++++++++++++++++++- 3 files changed, 137 insertions(+), 4 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 0ad1e364d..40ce9c9b0 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -113,6 +113,25 @@ void $jswrapper(JSObjectRef thisObject) } %} +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * - ${destructor_action}: The custom destructor action to invoke. + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtoroverride", "templates") +%{ +void $jswrapper(JSObjectRef thisObject) +{ + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*) JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) { + $jstype* arg1 = ($jstype*)t->swigCObject; + ${destructor_action} + } + if(t) free(t); +} +%} + /* ----------------------------------------------------------------------------- * js_getter: template for getter function wrappers * - $jswrapper: wrapper function name diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index f86198622..62267ae52 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -114,13 +114,32 @@ fail: 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; +// std::cout << "Deleting wrapped instance: " << proxy->info->name << std::endl; $jsfree proxy->swigCObject; } delete proxy; } %} +/* ----------------------------------------------------------------------------- + * js_dtoroverride: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * - ${destructor_action}: The custom destructor action to invoke. + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtoroverride", "templates") +%{ +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; + $jstype arg1 = ($jstype)t->swigCObject; + ${destructor_action} + } + delete proxy; +} +%} + /* ----------------------------------------------------------------------------- * js_getter: template for getter function wrappers * - $jswrapper: wrapper function name diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 8850ebd60..a8f1b0b0a 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -886,7 +886,6 @@ int JSEmitter::emitCtor(Node *n) { int JSEmitter::emitDtor(Node *n) { - Template t_dtor = getTemplate("js_dtor"); String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); SwigType *type = state.clazz(TYPE); @@ -894,20 +893,116 @@ int JSEmitter::emitDtor(Node *n) { String *ctype = SwigType_lstr(p_classtype, ""); String *free = NewString(""); + // (Taken from JSCore implementation.) + /* The if (Extend) block was taken from the Ruby implementation. + * The problem is that in the case of an %extend to create a destructor for a struct to coordinate automatic memory cleanup with the Javascript collector, + * the swig function was not being generated. More specifically: + struct MyData { + %extend { + ~MyData() { + FreeData($self); + } + } + }; + %newobject CreateData; + struct MyData* CreateData(void); + %delobject FreeData; + void FreeData(struct MyData* the_data); + + where the use case is something like: + var my_data = example.CreateData(); + my_data = null; + + This function was not being generated: + SWIGINTERN void delete_MyData(struct MyData *self){ + FreeData(self); + } + + I don't understand fully why it wasn't being generated. It just seems to happen in the Lua generator. + There is a comment about staticmemberfunctionHandler having an inconsistency and I tracked down dome of the SWIGINTERN void delete_* + code to that function in the Language base class. + The Ruby implementation seems to have an explicit check for if(Extend) and explicitly generates the code, so that's what I'm doing here. + The Ruby implementation does other stuff which I omit. + */ + if (Extend) { + String *wrap = Getattr(n, "wrap:code"); + if (wrap) { + Printv(f_wrappers, wrap, NIL); + } + } + + // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node // TODO: generate dtors more similar to other wrappers + // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used. 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)) + String* destructor_action = Getattr(n, "wrap:action"); + // Adapted from the JSCore implementation. + /* The next challenge is to generate the correct finalize function for JavaScriptCore to call. + Originally, it would use this fragment from javascriptcode.swg + %fragment ("JS_destructordefn", "templates") + %{ + void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) + { + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject); + if(t) free(t); + } + %} + + But for the above example case of %extend to define a destructor on a struct, we need to override the system to not call + free ((${type}*)t->swigCObject); + and substitute it with what the user has provided. + To solve this, I created a variation fragment called JS_destructoroverridedefn: + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) { + ${type}* arg1 = (${type}*)t->swigCObject; + ${destructor_action} + } + if(t) free(t); + + Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action") + to decide if the user has a preferred destructor action. + Based on that, I decide which fragment to use. + And in the case of the custom action, I substitute that action in. + I noticed that destructor_action has the form + delete_MyData(arg1); + The explicit arg1 is a little funny, so I structured the fragment to create a temporary variable called arg1 to make the generation easier. + This might suggest this solution misunderstands a more complex case. + + Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above. + So this code doesn't actually quite work as I expect. The end result is that the code still works because + destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is wierd. + I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free. + + Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above. + But I don't fully understand the conditions of any of these things, and since it works for the moment, I don't want to break more stuff. + */ + if(destructor_action) { + Template t_dtor = getTemplate("js_dtoroverride"); + state.clazz(DTOR, wrap_name); + t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + .replace(T_WRAPPER, wrap_name) + .replace(T_FREE, free) + .replace(T_TYPE, ctype); + + t_dtor.replace("${destructor_action}", destructor_action); + Wrapper_pretty_print(t_dtor.str(), f_wrappers); + } + else { + Template t_dtor = getTemplate("js_dtor"); + state.clazz(DTOR, wrap_name); + t_dtor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) .replace(T_WRAPPER, wrap_name) .replace(T_FREE, free) .replace(T_TYPE, ctype) .pretty_print(f_wrappers); + } Delete(p_classtype); Delete(ctype); From f8feeacb68593063914c58c60e408d8515295b7f Mon Sep 17 00:00:00 2001 From: Eric Wing Date: Thu, 11 Jul 2013 19:11:56 -0700 Subject: [PATCH 141/352] v8: Removed the extern "C" around the initialize function because it makes no sense since it requires a C++ templates object as a parameter. --- Lib/javascript/v8/javascriptcode.swg | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 62267ae52..003658613 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -403,7 +403,8 @@ fail: * ----------------------------------------------------------------------------- */ %fragment("js_initializer", "templates") %{ -extern "C" { +// The extern "C" makes little sense here because the paramater is using C++ objects and templates. +// extern "C" { void $jsname_initialize(v8::Handle global_obj) { @@ -440,5 +441,5 @@ void $jsname_initialize(v8::Handle global_obj) } -} // extern "C" +// } // extern "C" %} From 65a0be8876959dd9a79bc3d7290af15ab646202d Mon Sep 17 00:00:00 2001 From: Eric Wing Date: Thu, 11 Jul 2013 20:04:01 -0700 Subject: [PATCH 142/352] v8: variable name bug fix in my template modifications for pointers to structs. --- Lib/javascript/v8/javascriptcode.swg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 003658613..ef3d1f896 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -133,7 +133,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; - $jstype arg1 = ($jstype)t->swigCObject; + $jstype arg1 = ($jstype)proxy->swigCObject; ${destructor_action} } delete proxy; From 4503c5390304202275a849eaa8473985adf86f02 Mon Sep 17 00:00:00 2001 From: Eric Wing Date: Wed, 7 Aug 2013 15:12:36 -0700 Subject: [PATCH 143/352] Since this code uses assert, #include is needed. --- Lib/javascript/v8/javascriptinit.swg | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg index 684728023..13ec1aff8 100644 --- a/Lib/javascript/v8/javascriptinit.swg +++ b/Lib/javascript/v8/javascriptinit.swg @@ -1,5 +1,6 @@ %insert(init) %{ +#include SWIGRUNTIME void SWIG_V8_SetModule(void *, swig_module_info *swig_module) { From 0732592ed99759afab2f05e6be1723659e955464 Mon Sep 17 00:00:00 2001 From: Kota Iguchi Date: Wed, 7 Aug 2013 18:10:53 -0700 Subject: [PATCH 144/352] Patch to support argout typemap for your swig-v8 branch. --- Source/Modules/javascript.cxx | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 8c82890a6..6eb2c572d 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1285,6 +1285,16 @@ void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) { Parm *p; String *tm; + for (p = params; p;) { + if ((tm = Getattr(p, "tmap:argout"))) { + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + for (p = params; p;) { if ((tm = Getattr(p, "tmap:freearg"))) { //addThrows(n, "tmap:freearg", p); From cb5f4dc47eeac71a0c5f39618027382567cb53d4 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Thu, 15 Aug 2013 14:33:00 +0400 Subject: [PATCH 145/352] ported to newer, more efficient v8 api --- Lib/javascript/v8/javascriptcode.swg | 67 ++++++++++++------------- Lib/javascript/v8/javascripthelpers.swg | 10 ++-- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 39c1f3a79..ebe841b22 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -7,19 +7,18 @@ * - $jsmangledtype: mangled type of class * ----------------------------------------------------------------------------- */ %fragment("js_ctor", "templates") %{ -v8::Handle $jswrapper(const v8::Arguments& args) { +void $jswrapper(const v8::FunctionCallbackInfo& args) { v8::HandleScope scope; v8::Handle self = args.Holder(); $jslocals if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode - - SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); - return scope.Close(self); - goto fail; + SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + args.GetReturnValue().Set(self); + fail: - return scope.Close(v8::Undefined()); + return; } %} @@ -30,10 +29,9 @@ fail: * ----------------------------------------------------------------------------- */ %fragment ("js_veto_ctor", "templates") %{ -v8::Handle $jswrapper(const v8::Arguments& args) { +void $jswrapper(const v8::FunctionCallbackInfo& args) { v8::HandleScope scope; SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); - return scope.Close(v8::Undefined()); } %} @@ -45,7 +43,7 @@ v8::Handle $jswrapper(const v8::Arguments& args) { * ----------------------------------------------------------------------------- */ %fragment ("js_ctor_dispatcher", "templates") %{ -v8::Handle $jswrapper(const v8::Arguments& args) { +void $jswrapper(const v8::FunctionCallbackInfo& args) { v8::HandleScope scope; OverloadErrorHandler errorHandler; v8::Handle self; @@ -57,7 +55,7 @@ v8::Handle $jswrapper(const v8::Arguments& args) { SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); fail: - return scope.Close(v8::Undefined()); + return; } %} @@ -70,7 +68,7 @@ fail: * - $jsmangledtype: mangled type of class * ----------------------------------------------------------------------------- */ %fragment("js_overloaded_ctor", "templates") %{ -v8::Handle $jswrapper(const v8::Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) { +void $jswrapper(const v8::FunctionCallbackInfo& args, V8ErrorHandler& SWIGV8_ErrorHandler) { v8::HandleScope scope; v8::Handle self = args.Holder(); $jslocals @@ -78,11 +76,11 @@ v8::Handle $jswrapper(const v8::Arguments& args, V8ErrorHandler& SWIG $jscode SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); - return scope.Close(self); + args.GetReturnValue().Set(self); goto fail; fail: - return scope.Close(v8::Undefined()); + return; } %} @@ -97,10 +95,9 @@ fail: %{ if(args.Length() == $jsargcount) { errorHandler.err.Clear(); - self = $jswrapper(args, errorHandler); - if(errorHandler.err.IsEmpty()) { - return scope.Close(self); - } + $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) + return; } %} @@ -171,15 +168,16 @@ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { * ----------------------------------------------------------------------------- */ %fragment("js_getter", "templates") %{ -v8::Handle $jswrapper(v8::Local property, const v8::AccessorInfo& info) { +void $jswrapper(v8::Local property, const v8::PropertyCallbackInfo& info) { v8::HandleScope scope; v8::Handle jsresult; $jslocals $jscode - return scope.Close(jsresult); + info.GetReturnValue().Set(jsresult); + return; goto fail; fail: - return scope.Close(v8::Undefined()); + return; } %} @@ -191,7 +189,7 @@ fail: * ----------------------------------------------------------------------------- */ %fragment("js_setter", "templates") %{ -void $jswrapper(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { +void $jswrapper(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info) { v8::HandleScope scope; $jslocals $jscode @@ -209,17 +207,18 @@ fail: * ----------------------------------------------------------------------------- */ %fragment("js_function", "templates") %{ -v8::Handle $jswrapper(const v8::Arguments &args) { +void $jswrapper(const v8::FunctionCallbackInfo& args) { v8::HandleScope scope; v8::Handle jsresult; $jslocals if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); - + $jscode - return scope.Close(jsresult); + args.GetReturnValue().Set(jsresult); + return; goto fail; fail: - return scope.Close(v8::Undefined()); + return; } %} @@ -232,7 +231,7 @@ fail: * ----------------------------------------------------------------------------- */ %fragment("js_function_dispatcher", "templates") %{ -v8::Handle $jswrapper(const v8::Arguments &args) { +void $jswrapper(const v8::FunctionCallbackInfo& args) { v8::HandleScope scope; v8::Handle jsresult; OverloadErrorHandler errorHandler; @@ -242,7 +241,7 @@ v8::Handle $jswrapper(const v8::Arguments &args) { goto fail; fail: - return scope.Close(v8::Undefined()); + return; } %} @@ -254,16 +253,17 @@ fail: * ----------------------------------------------------------------------------- */ %fragment ("js_overloaded_function", "templates") %{ -v8::Handle $jswrapper(const v8::Arguments &args, V8ErrorHandler& SWIGV8_ErrorHandler) +void $jswrapper(const v8::FunctionCallbackInfo& args, V8ErrorHandler& SWIGV8_ErrorHandler) { v8::HandleScope scope; v8::Handle jsresult; $jslocals $jscode - return scope.Close(jsresult); + args.GetReturnValue().Set(jsresult); + return; goto fail; fail: - return scope.Close(jsresult); + return; } %} @@ -277,10 +277,9 @@ fail: %{ if(args.Length() == $jsargcount) { errorHandler.err.Clear(); - jsresult = $jswrapper(args, errorHandler); - if(errorHandler.err.IsEmpty()) { - return scope.Close(jsresult); - } + $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) + return; } %} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index d28243d88..847e9b73c 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -17,7 +17,7 @@ v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) /** * Registers a class method with given name for a given class template. */ -void SWIGV8_AddMemberFunction(v8::Handle class_templ, const char* symbol, v8::InvocationCallback _func) { +void SWIGV8_AddMemberFunction(v8::Handle class_templ, const char* symbol, v8::FunctionCallback _func) { v8::Handle proto_templ = class_templ->PrototypeTemplate(); proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); } @@ -25,7 +25,7 @@ void SWIGV8_AddMemberFunction(v8::Handle class_templ, cons /** * Registers a class property with given name for a given class template. */ -void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { +void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetterCallback getter, v8::AccessorSetterCallback setter) { v8::Handle proto_templ = class_templ->InstanceTemplate(); proto_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } @@ -33,18 +33,18 @@ void SWIGV8_AddMemberVariable(v8::Handle class_templ, cons /** * Registers a class method with given name for a given object. */ -void SWIGV8_AddStaticFunction(v8::Handle obj, const char* symbol, v8::InvocationCallback _func) { +void SWIGV8_AddStaticFunction(v8::Handle obj, const char* symbol, const v8::FunctionCallback& _func) { obj->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); } /** * Registers a class method with given name for a given object. */ -void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, v8::AccessorGetter getter, v8::AccessorSetter setter) { +void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, v8::AccessorGetterCallback getter, v8::AccessorSetterCallback setter) { obj->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } -void JS_veto_set_variable(v8::Local property, v8::Local value, const v8::AccessorInfo& info) +void JS_veto_set_variable(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info) { char buffer[256]; char msg[512]; From 5aba4c7ea657f086519acb950e19c416d808b74a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 05:35:03 +0200 Subject: [PATCH 146/352] Starting from scratch with Examples configuration. --- Examples/Makefile.in | 89 +++++++------------------------------------- 1 file changed, 14 insertions(+), 75 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 803c7fa9a..94a00e642 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -517,102 +517,41 @@ java_clean: ##### JAVASCRIPT ###### ################################################################## -# You need to set this variable to the jscore[or other javascript engine] directories containing the -# files "JavaScript.h" and others - -JS_INCLUDE = @JSCOREINC@ @JSV8INC@ -JS_DLNK = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ - -# Extra JAVASCRIPT specific dynamic linking options -JS_LIBPREFIX = @JSCORELIBRARYPREFIX@ -JSSO =@JSCORESO@ -JSLDSHARED = @JSCORELDSHARED@ -JSCXXSHARED = @JSCORECXXSHARED@ -JSCFLAGS = @JSCORECFLAGS@ -JSCXXFLAGS = @JSCXXFLAGS@ -ROOT_DIR = @ROOT_DIR@ -JSCORE = @JSCORE@ -JSV8 = @JSV8@ -JSDEFAULT = @JSDEFAULT@ - -JSEXE_SRC_DIR = $(ROOT_DIR)/Tools/javascript -JSEXE = $(JSEXE_SRC_DIR)/javascript - -ifneq (,$(JSCORE)) - JSEXE_SRC_JSC = $(JSEXE_SRC_DIR)/jsc_shell.cxx - JSEXE_FLAGS_JSC = -DENABLE_JSC -endif - -ifneq (,$(JSV8)) - JSEXE_SRC_V8 = $(JSEXE_SRC_DIR)/v8_shell.cxx - JSEXE_FLAGS_V8 = -DENABLE_V8 -endif - -JSEXE_SRC = $(JSEXE_SRC_DIR)/javascript.cxx $(JSEXE_SRC_DIR)/js_shell.cxx $(JSEXE_SRC_JSC) $(JSEXE_SRC_V8) -JSEXE_FLAGS = $(JSEXE_FLAGS_JSC) $(JSEXE_FLAGS_V8) - -# this controls which engine the code will be generated for -# and correspondingly the argument for the js interpreter -ifneq (,$(JSC)) - SWIGJS = $(SWIG) -javascript -jsc - JSEXE_OPTS = -jsc -else -ifneq (,$(V8)) - SWIGJS = $(SWIG) -javascript -v8 - JSEXE_OPTS = -v8 -else - SWIGJS = $(SWIG) -javascript -$(JSDEFAULT) - JSEXE_OPTS = -$(JSDEFAULT) -endif -endif - # ---------------------------------------------------------------- -# Build a javascript dynamically loadable module (C) +# Definitions # ---------------------------------------------------------------- -# Note: for v8 there is no C support, so forwarding to javascript_cpp -ifeq (,$(V8)) -javascript: $(SRCS) - $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) - $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(SRCS) $(ISRCS) $(INCLUDES) $(JS_INCLUDE) - $(JSLDSHARED) $(CCSHARED) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) -else -javascript: $(SRCS) javascript_cpp -endif +JSEXE = node +SWIGJS = $(SWIG) -javascript -node +JS_BUILD = node-gyp rebuild # ---------------------------------------------------------------- -# Build a javascript dynamically loadable module (C++) +# Run the javascript executable # ---------------------------------------------------------------- -javascript_cpp: $(SRCS) +javascript_wrapper_cpp: $(SRCS) $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) - $(CXX) -c $(CCSHARED) $(CXXFLAGS) $(JSCXXFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(JS_INCLUDE) - $(JSCXXSHARED) $(CCSHARED) $(OBJS) $(IOBJS) $(JS_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(JS_LIBPREFIX)$(TARGET)$(JSSO) -# ---------------------------------------------------------------- -# Compile a javascript executable -# ---------------------------------------------------------------- -javascript_exe: $(SRCS) - $(CXX) $(CXXFLAGS) $(JSEXE_FLAGS) $(JS_INCLUDE) $(LIBS) $(JSEXE_SRC) $(JS_DLNK) -ldl -o $(JSEXE) +javascript_build: + $(JS_BUILD) -# ---------------------------------------------------------------- -# Run the Compile a javascript executable -# ---------------------------------------------------------------- +#javascript_run: $(SRCS) +# env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JSEXE) $(JSEXE_OPTS) -l $(TARGET) $(JS_SCRIPT) javascript_run: $(SRCS) - env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JSEXE) $(JSEXE_OPTS) -l $(TARGET) $(JS_SCRIPT) + env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JSEXE) $(JSEXE_OPTS) $(JS_SCRIPT) # ----------------------------------------------------------------- # Cleaning the javascript examples # ----------------------------------------------------------------- javascript_clean: + rm -rf build rm -f *_wrap* runme rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@JSCORESO@ - ################################################################## ##### MODULA3 ###### ################################################################## @@ -1247,14 +1186,14 @@ R_CFLAGS=-fPIC r: $(SRCS) $(SWIG) -r $(SWIGOPT) $(INTERFACEPATH) ifneq ($(SRCS),) - $(CXX) -g -c $(CFLAGS) $(R_CFLAGS) $(SRCS) $(INCLUDES) + $(CXX) -g -c $(CFLAGS) $(R_CFLAGS) $(SRCS) $(INCLUDES) endif +( PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null ) r_cpp: $(CXXSRCS) $(SWIG) -c++ -r $(SWIGOPT) -o $(RCXXSRCS) $(INTERFACEPATH) ifneq ($(CXXSRCS),) - $(CXX) -g -c $(CFLAGS) $(R_CFLAGS) $(CXXSRCS) $(INCLUDES) + $(CXX) -g -c $(CFLAGS) $(R_CFLAGS) $(CXXSRCS) $(INCLUDES) endif +( PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(OBJS) > /dev/null ) From 5228c0eeab0e96930d18e1b0b0d732636adc882f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 05:36:41 +0200 Subject: [PATCH 147/352] Add a dedicated mode for creating node modules. --- Source/Modules/javascript.cxx | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 6eb2c572d..884e09ebe 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -145,8 +145,7 @@ public: enum JSEmitterType { JavascriptCore, - V8, - QtScript + V8 }; JSEmitter(); @@ -530,14 +529,16 @@ void JAVASCRIPT::main(int argc, char *argv[]) { Swig_mark_arg(i); mode = JSEmitter::V8; SWIG_library_directory("javascript/v8"); + } else if (strcmp(argv[i], "-node") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + createModuleObject = false; + Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); } else if (strcmp(argv[i], "-jsc") == 0) { Swig_mark_arg(i); mode = JSEmitter::JavascriptCore; SWIG_library_directory("javascript/jsc"); - } else if (strcmp(argv[i], "-qt") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::QtScript; - SWIG_library_directory("javascript/qt"); } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { Swig_mark_arg(i); js_template_enable_debug = true; @@ -561,12 +562,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { Preprocessor_define("SWIG_JAVASCRIPT_JSC 1", 0); break; } - case JSEmitter::QtScript: - { - Printf(stderr, "QtScript support is not yet implemented."); - SWIG_exit(-1); - break; - } default: { Printf(stderr, "Unknown emitter type."); @@ -898,15 +893,15 @@ int JSEmitter::emitDtor(Node *n) { } } }; - %newobject CreateData; + %newobject CreateData; struct MyData* CreateData(void); %delobject FreeData; void FreeData(struct MyData* the_data); - + where the use case is something like: var my_data = example.CreateData(); my_data = null; - + This function was not being generated: SWIGINTERN void delete_MyData(struct MyData *self){ FreeData(self); @@ -964,13 +959,13 @@ int JSEmitter::emitDtor(Node *n) { to decide if the user has a preferred destructor action. Based on that, I decide which fragment to use. And in the case of the custom action, I substitute that action in. - I noticed that destructor_action has the form + I noticed that destructor_action has the form delete_MyData(arg1); The explicit arg1 is a little funny, so I structured the fragment to create a temporary variable called arg1 to make the generation easier. This might suggest this solution misunderstands a more complex case. Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above. - So this code doesn't actually quite work as I expect. The end result is that the code still works because + So this code doesn't actually quite work as I expect. The end result is that the code still works because destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is wierd. I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free. @@ -1186,7 +1181,7 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { // String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); - + String *fun_name = Getattr(n, "sym:name"); Node *methodclass = Swig_methodclass(n); From a48438c562b3f1601e5bbc9cedcf9f124af97975 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 05:39:37 +0200 Subject: [PATCH 148/352] Better v8 version handling. You should start to specify a version on command line, e.g., swig -javascript -v8 -DSWIG_V8_VERSION=0x032007 --- Lib/javascript/v8/javascriptcode.swg | 180 ++++++++++++++---------- Lib/javascript/v8/javascripthelpers.swg | 44 ++++-- Lib/javascript/v8/javascriptruntime.swg | 44 ++++-- 3 files changed, 168 insertions(+), 100 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index ebe841b22..377e93752 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -6,19 +6,37 @@ * - $jsargcount: number of arguments * - $jsmangledtype: mangled type of class * ----------------------------------------------------------------------------- */ + +%insert(runtime) %{ +#if (SWIG_V8_VERSION < 0x031900) +typedef v8::Handle SwigV8ReturnValue; +typedef v8::Arguments SwigV8Arguments; +typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) return scope.Close(val) +#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) +#else +typedef void SwigV8ReturnValue; +typedef v8::FunctionCallbackInfo SwigV8Arguments; +typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) return args.GetReturnValue().Set(val) +#define SWIGV8_RETURN_INFO(val, info) return args.GetReturnValue().Set(val) +#endif +%} + %fragment("js_ctor", "templates") %{ -void $jswrapper(const v8::FunctionCallbackInfo& args) { +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { v8::HandleScope scope; v8::Handle self = args.Holder(); $jslocals - if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); - args.GetReturnValue().Set(self); + SWIGV8_RETURN(self); + goto fail; fail: - return; + SWIGV8_RETURN(v8::Undefined()); } %} @@ -29,9 +47,10 @@ fail: * ----------------------------------------------------------------------------- */ %fragment ("js_veto_ctor", "templates") %{ -void $jswrapper(const v8::FunctionCallbackInfo& args) { +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { v8::HandleScope scope; SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); + SWIGV8_RETURN(v8::Undefined()); } %} @@ -43,18 +62,19 @@ void $jswrapper(const v8::FunctionCallbackInfo& args) { * ----------------------------------------------------------------------------- */ %fragment ("js_ctor_dispatcher", "templates") %{ -void $jswrapper(const v8::FunctionCallbackInfo& args) { +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { v8::HandleScope scope; OverloadErrorHandler errorHandler; v8::Handle self; - + // switch all cases by means of series of if-returns. $jsdispatchcases // default: SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); - + fail: + SWIGV8_RETURN(v8::Undefined()); return; } %} @@ -68,19 +88,19 @@ fail: * - $jsmangledtype: mangled type of class * ----------------------------------------------------------------------------- */ %fragment("js_overloaded_ctor", "templates") %{ -void $jswrapper(const v8::FunctionCallbackInfo& args, V8ErrorHandler& SWIGV8_ErrorHandler) { +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) { v8::HandleScope scope; v8::Handle self = args.Holder(); $jslocals - if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode - + SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); - args.GetReturnValue().Set(self); + SWIGV8_RETURN(self); goto fail; fail: - return; + SWIGV8_RETURN(v8::Undefined()); } %} @@ -89,15 +109,23 @@ fail: * - $jsargcount: number of arguments of called ctor * - $jswrapper: wrapper of called ctor * - * Note: a try-catch-like mechanism is used to switch cases + * Note: a try-catch-like mechanism is used to switch cases * ----------------------------------------------------------------------------- */ %fragment ("js_ctor_dispatch_case", "templates") %{ if(args.Length() == $jsargcount) { errorHandler.err.Clear(); +#if SWIG_V8_VERSION < 0x031900 + self = $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return scope.Close(self); + } +#else $jswrapper(args, errorHandler); - if(errorHandler.err.IsEmpty()) + if(errorHandler.err.IsEmpty()) { return; + } +#endif } %} @@ -109,15 +137,13 @@ fail: %fragment ("js_dtor", "templates") %{ -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) -void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) -#else -void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) -#endif +#if (SWIG_V8_VERSION < 0x031900) +void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) +{ + SWIGV8_Proxy *proxy = static_cast(parameter); +#else +void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) { - -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) - SWIGV8_Proxy *proxy = static_cast(parameter); #endif if(proxy->swigCMemOwn && proxy->swigCObject) { @@ -129,11 +155,10 @@ void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWI delete proxy; -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) object.Clear(); +#if (SWIG_V8_VERSION < 0x031900) object.Dispose(); #else - object->Clear(); object->Dispose(isolate); #endif } @@ -143,7 +168,7 @@ void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWI * js_dtoroverride: template for a destructor wrapper * - $jsmangledname: mangled class name * - $jstype: class type - * - ${destructor_action}: The custom destructor action to invoke. + * - ${destructor_action}: The custom destructor action to invoke. * ----------------------------------------------------------------------------- */ %fragment ("js_dtoroverride", "templates") %{ @@ -166,18 +191,18 @@ void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ -%fragment("js_getter", "templates") +%fragment("js_getter", "templates") %{ -void $jswrapper(v8::Local property, const v8::PropertyCallbackInfo& info) { +SwigV8ReturnValue $jswrapper(v8::Local property, const SwigV8PropertyCallbackInfo& info) { v8::HandleScope scope; v8::Handle jsresult; $jslocals $jscode - info.GetReturnValue().Set(jsresult); - return; + SWIGV8_RETURN_INFO(jsresult, info); + goto fail; fail: - return; + SWIGV8_RETURN_INFO(v8::Undefined(), info); } %} @@ -189,7 +214,8 @@ fail: * ----------------------------------------------------------------------------- */ %fragment("js_setter", "templates") %{ -void $jswrapper(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info) { +void $jswrapper(v8::Local property, v8::Local value, + const SwigV8PropertyCallbackInfo& info) { v8::HandleScope scope; $jslocals $jscode @@ -205,20 +231,20 @@ fail: * - $jslocals: locals part of wrapper * - $jscode: code part of wrapper * ----------------------------------------------------------------------------- */ -%fragment("js_function", "templates") +%fragment("js_function", "templates") %{ -void $jswrapper(const v8::FunctionCallbackInfo& args) { +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { v8::HandleScope scope; v8::Handle jsresult; $jslocals - if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); $jscode - args.GetReturnValue().Set(jsresult); - return; + SWIGV8_RETURN(jsresult); + goto fail; fail: - return; + SWIGV8_RETURN(v8::Undefined()); } %} @@ -231,7 +257,7 @@ fail: * ----------------------------------------------------------------------------- */ %fragment("js_function_dispatcher", "templates") %{ -void $jswrapper(const v8::FunctionCallbackInfo& args) { +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { v8::HandleScope scope; v8::Handle jsresult; OverloadErrorHandler errorHandler; @@ -241,7 +267,7 @@ void $jswrapper(const v8::FunctionCallbackInfo& args) { goto fail; fail: - return; + SWIGV8_RETURN(v8::Undefined()); } %} @@ -253,17 +279,17 @@ fail: * ----------------------------------------------------------------------------- */ %fragment ("js_overloaded_function", "templates") %{ -void $jswrapper(const v8::FunctionCallbackInfo& args, V8ErrorHandler& SWIGV8_ErrorHandler) +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) { - v8::HandleScope scope; + v8::HandleScope scope; v8::Handle jsresult; $jslocals $jscode - args.GetReturnValue().Set(jsresult); - return; + SWIGV8_RETURN(jsresult); + goto fail; fail: - return; + SWIGV8_RETURN(v8::Undefined()); } %} @@ -275,11 +301,20 @@ fail: * ----------------------------------------------------------------------------- */ %fragment ("js_function_dispatch_case", "templates") %{ + if(args.Length() == $jsargcount) { - errorHandler.err.Clear(); - $jswrapper(args, errorHandler); - if(errorHandler.err.IsEmpty()) + errorHandler.err.Clear(); +#if (SWIG_V8_VERSION < 0x031900) + jsresult = $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return scope.Close(jsresult); + } +#else + $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { return; + } +#endif } %} @@ -287,7 +322,7 @@ fail: * jsv8_declare_class_template: template for a class template declaration. * - $jsmangledname: mangled class name * ----------------------------------------------------------------------------- */ -%fragment("jsv8_declare_class_template", "templates") +%fragment("jsv8_declare_class_template", "templates") %{ SWIGV8_ClientData $jsmangledname_clientData; %} @@ -298,15 +333,15 @@ fail: * - $jsmangledtype: mangled class type * - $jsdtor: the dtor wrapper * ----------------------------------------------------------------------------- */ -%fragment("jsv8_define_class_template", "templates") +%fragment("jsv8_define_class_template", "templates") %{ v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) $jsmangledname_clientData.class_templ = v8::Persistent::New($jsmangledname_class); #else $jsmangledname_clientData.class_templ.Reset(v8::Isolate::GetCurrent(), $jsmangledname_class); #endif - $jsmangledname_clientData.dtor = $jsdtor; + $jsmangledname_clientData.dtor = $jsdtor; SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData; %} @@ -316,11 +351,11 @@ fail: * - $jsmangledname: mangled class name * - $jsbaseclass: mangled name of the base class * ----------------------------------------------------------------------------- */ -%fragment("jsv8_inherit", "templates") +%fragment("jsv8_inherit", "templates") %{ if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty())) { -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) $jsmangledname_class->Inherit(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ); #else $jsmangledname_class->Inherit( @@ -345,7 +380,7 @@ fail: * - $jsname: class name * - $jsmangledname: mangled class name * ----------------------------------------------------------------------------- */ -%fragment("jsv8_create_class_instance", "templates") +%fragment("jsv8_create_class_instance", "templates") %{ v8::Handle $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); $jsmangledname_class_0->SetCallHandler($jsctor); @@ -360,7 +395,7 @@ fail: * - $jsmangledname: mangled class name * - $jsparent: mangled name of parent namespace * ----------------------------------------------------------------------------- */ -%fragment("jsv8_register_class", "templates") +%fragment("jsv8_register_class", "templates") %{ $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); %} @@ -369,7 +404,7 @@ fail: * jsv8_create_namespace: template for a statement that creates a namespace object. * - $jsmangledname: mangled namespace name * ----------------------------------------------------------------------------- */ -%fragment("jsv8_create_namespace", "templates") +%fragment("jsv8_create_namespace", "templates") %{ v8::Handle $jsmangledname_obj = v8::Object::New(); %} @@ -380,7 +415,7 @@ fail: * - $jsmangledname: mangled name of namespace * - $jsparent: mangled name of parent namespace * ----------------------------------------------------------------------------- */ -%fragment("jsv8_register_namespace", "templates") +%fragment("jsv8_register_namespace", "templates") %{ $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); %} @@ -391,7 +426,7 @@ fail: * - $jsname: name of the function * - $jswrapper: wrapper of the member function * ----------------------------------------------------------------------------- */ -%fragment("jsv8_register_member_function", "templates") +%fragment("jsv8_register_member_function", "templates") %{ SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper); %} @@ -416,7 +451,7 @@ fail: * * Note: this template is also used for global functions. * ----------------------------------------------------------------------------- */ -%fragment("jsv8_register_static_function", "templates") +%fragment("jsv8_register_static_function", "templates") %{ SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper); %} @@ -430,7 +465,7 @@ fail: * * Note: this template is also used for global variables. * ----------------------------------------------------------------------------- */ -%fragment("jsv8_register_static_variable", "templates") +%fragment("jsv8_register_static_variable", "templates") %{ SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter); %} @@ -447,10 +482,8 @@ fail: * - $jsv8registerclasses: part with code that registers class objects in namespaces * - $jsv8registernspaces: part with code that registers namespaces in parent namespaces * ----------------------------------------------------------------------------- */ -%fragment("js_initializer", "templates") +%fragment("js_initializer", "templates") %{ -// The extern "C" makes little sense here because the paramater is using C++ objects and templates. -// extern "C" { #if defined(BUILDING_NODE_EXTENSION) void $jsname_initialize(v8::Handle global_obj, v8::Handle /*module*/) @@ -464,34 +497,34 @@ void $jsname_initialize(v8::Handle global_obj) // a class template for creating proxies of undefined types -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) SWIGV8_SWIGTYPE_Proxy_class_templ = v8::Persistent::New(SWIGV8_CreateClassTemplate("SwigProxy")); #else SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); #endif - + /* create objects for namespaces */ $jsv8nspaces - + /* create class templates */ $jsv8classtemplates - + /* register wrapper functions */ $jsv8wrappers - + /* setup inheritances */ $jsv8inheritance - + /* class instances */ $jsv8classinstances - + /* add static class functions and variables */ $jsv8staticwrappers /* register classes */ $jsv8registerclasses - + /* create and register namespace objects */ $jsv8registernspaces } @@ -500,7 +533,4 @@ void $jsname_initialize(v8::Handle global_obj) NODE_MODULE($jsname, $jsname_initialize); #endif - - -// } // extern "C" %} diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index 847e9b73c..61bc45da5 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -1,7 +1,20 @@ %insert(runtime) %{ +// Note: since 3.19 there are new CallBack types, since 03.21.9 the old ones have been removed +#if SWIG_V8_VERSION < 0x031900 +typedef v8::InvocationCallback SwigV8FunctionCallback; +typedef v8::AccessorGetter SwigV8AccessorGetterCallback; +typedef v8::AccessorSetter SwigV8AccessorSetterCallback; +typedef v8::AccessorInfo SwigV8PropertyCallbackInfoVoid; +#else +typedef v8::FunctionCallback SwigV8FunctionCallback; +typedef v8::AccessorGetterCallback SwigV8AccessorGetterCallback; +typedef v8::AccessorSetterCallback SwigV8AccessorSetterCallback; +typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfoVoid; +#endif + /** - * Creates a class template for a class with specified initialization function. + * Creates a class template for a class with specified initialization function. */ v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) { v8::HandleScope scope; @@ -15,44 +28,49 @@ v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) } /** - * Registers a class method with given name for a given class template. + * Registers a class method with given name for a given class template. */ -void SWIGV8_AddMemberFunction(v8::Handle class_templ, const char* symbol, v8::FunctionCallback _func) { +void SWIGV8_AddMemberFunction(v8::Handle class_templ, const char* symbol, + SwigV8FunctionCallback _func) { v8::Handle proto_templ = class_templ->PrototypeTemplate(); - proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); + proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); } /** - * Registers a class property with given name for a given class template. + * Registers a class property with given name for a given class template. */ -void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, v8::AccessorGetterCallback getter, v8::AccessorSetterCallback setter) { +void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, + SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { v8::Handle proto_templ = class_templ->InstanceTemplate(); proto_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } /** - * Registers a class method with given name for a given object. + * Registers a class method with given name for a given object. */ -void SWIGV8_AddStaticFunction(v8::Handle obj, const char* symbol, const v8::FunctionCallback& _func) { +void SWIGV8_AddStaticFunction(v8::Handle obj, const char* symbol, + const SwigV8FunctionCallback& _func) { obj->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); } /** - * Registers a class method with given name for a given object. + * Registers a class method with given name for a given object. */ -void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, v8::AccessorGetterCallback getter, v8::AccessorSetterCallback setter) { +void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, + SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { obj->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); } -void JS_veto_set_variable(v8::Local property, v8::Local value, const v8::PropertyCallbackInfo& info) +void JS_veto_set_variable(v8::Local property, v8::Local value, + const SwigV8PropertyCallbackInfoVoid& info) { char buffer[256]; char msg[512]; int res; - + property->WriteUtf8(buffer, 256); res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); - + if(res<0) { SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); } else { diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index fddfcf70c..841b03e21 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -4,8 +4,28 @@ * Javascript support code * ----------------------------------------------------------------------------- */ -%insert(runtime) %{ +%define %swig_v8_define_version(version) +%begin %{ +#ifndef SWIG_V8_VERSION +#define SWIG_V8_VERSION version +#endif +%} +%enddef +#ifdef SWIG_V8_VERSION +%swig_v8_define_version(SWIG_V8_VERSION) +#else +// HACK: defining a default version +%swig_v8_define_version(SWIG_V8_VERSION) +#endif + +#ifdef BUILDING_NODE_EXTENSION +%insert("runtime") %{ +#include +%} +#endif + +%insert(runtime) %{ #include #include @@ -13,7 +33,7 @@ %} %insert(runtime) "swigrun.swg"; /* SWIG API */ -%insert(runtime) "swigerrors.swg"; /* SWIG errors */ +%insert(runtime) "swigerrors.swg"; /* SWIG errors */ %insert(runtime) %{ #define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) @@ -25,16 +45,16 @@ void SWIG_V8_Raise(const char* msg) { v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); } -/* +/* Note: There are two contexts for handling errors. A static V8ErrorHandler is used in not overloaded methods. For overloaded methods the throwing type checking mechanism is used during dispatching. As V8 exceptions can not be resetted properly the trick is to use a dynamic ErrorHandler with same local name as the global one. - + - See defintion of SWIG_Error above. - - See code templates 'JS_function_dispatcher', 'JS_functionwrapper_overload', + - See code templates 'JS_function_dispatcher', 'JS_functionwrapper_overload', and 'JS_function_dispatch_case' in javascriptcode.swg */ @@ -72,8 +92,8 @@ public: SWIGV8_Proxy(): swigCMemOwn(false), swigCObject(0), info(0) { v8::V8::AdjustAmountOfExternalAllocatedMemory(SWIGV8_AVG_OBJ_SIZE); }; - - ~SWIGV8_Proxy() { + + ~SWIGV8_Proxy() { #if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) handle.ClearWeak(); #else @@ -90,7 +110,7 @@ public: handle.Clear(); v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); } - + bool swigCMemOwn; void *swigCObject; swig_type_info *info; @@ -112,7 +132,7 @@ v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { v8::HandleScope scope; - + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; #if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) @@ -157,7 +177,7 @@ void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *objec void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { SWIGV8_Proxy* cdata = new SWIGV8_Proxy(); - cdata->swigCObject = ptr; + cdata->swigCObject = ptr; cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; cdata->info = info; @@ -210,7 +230,7 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in } #else v8::Isolate *iso = v8::Isolate::GetCurrent(); - + if(info->clientdata != 0) { class_templ = v8::Handle::New(iso, ((SWIGV8_ClientData*) info->clientdata)->class_templ); } else { @@ -220,7 +240,7 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); SWIGV8_SetPrivateData(result, ptr, info, flags); - + return scope.Close(result); } From 11e2179dd318d49665fe665022a2a5ea30c59392 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 05:40:22 +0200 Subject: [PATCH 149/352] First example that addresses node.js as primary execution environment. --- Examples/javascript/class/Makefile | 14 +++++----- Examples/javascript/class/binding.gyp | 8 ++++++ Examples/javascript/class/runme.js | 39 ++++++++++++++------------- 3 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 Examples/javascript/class/binding.gyp diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile index 507289ed1..99a9e9e86 100755 --- a/Examples/javascript/class/Makefile +++ b/Examples/javascript/class/Makefile @@ -5,17 +5,17 @@ JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/class/binding.gyp b/Examples/javascript/class/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/class/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js index 50261d868..0ecaf3f82 100755 --- a/Examples/javascript/class/runme.js +++ b/Examples/javascript/class/runme.js @@ -1,15 +1,16 @@ // file: runme.js +var example = require("./build/Release/example"); // ----- Object creation ----- -print("Creating some objects:"); +console.log("Creating some objects:"); c = new example.Circle(10); -print("Created circle " + c); +console.log("Created circle " + c); s = new example.Square(10); -print("Created square " + s); +console.log("Created square " + s); // ----- Access a static member ----- -print("\nA total of " + example.Shape.nshapes + " shapes were created"); // access static member as properties of the class object +console.log("\nA total of " + example.Shape.nshapes + " shapes were created"); // access static member as properties of the class object // ----- Member data access ----- // Set the location of the object. @@ -21,26 +22,26 @@ c.y = 30; s.x = -10; s.y = 5; -print("\nHere is their new position:"); -print("Circle = (" + c.x + "," + c.y + ")"); -print("Square = (" + s.x + "," + s.y + ")"); +console.log("\nHere is their new position:"); +console.log("Circle = (" + c.x + "," + c.y + ")"); +console.log("Square = (" + s.x + "," + s.y + ")"); // ----- Call some methods ----- -print("\nHere are some properties of the shapes:"); -print("Circle:"); -print("area = " + c.area() + ""); -print("perimeter = " + c.perimeter() + ""); -print("\n"); -print("Square:"); -print("area = " + s.area() + ""); -print("perimeter = " + s.perimeter() + ""); +console.log("\nHere are some properties of the shapes:"); +console.log("Circle:"); +console.log("area = " + c.area() + ""); +console.log("perimeter = " + c.perimeter() + ""); +console.log("\n"); +console.log("Square:"); +console.log("area = " + s.area() + ""); +console.log("perimeter = " + s.perimeter() + ""); // ----- Delete everything ----- -print("\nGuess I'll clean up now"); +console.log("\nGuess I'll clean up now"); // Note: this invokes the virtual destructor delete c; -delete s; +delete s; -print (example.Shape.nshapes + " shapes remain"); +console.log(example.Shape.nshapes + " shapes remain"); -print("Goodbye"); +console.log("Goodbye"); From dbf2b1fe945714641322c2f758bde63140db37fa Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 05:46:19 +0200 Subject: [PATCH 150/352] Ignore javascript Example build files. --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2cd4b9b4e..147e44cb2 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,5 @@ Examples/*/*/*.gdb *.orig *.kdev4 *.geany -/build \ No newline at end of file +Examples/javascript/*/build +build From 5da54ca435741f74a7212d7034b11b9fa17046d7 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 06:26:54 +0200 Subject: [PATCH 151/352] Convert javascript examples to nodejs. --- Examples/javascript/class/runme.js | 1 - Examples/javascript/constant/Makefile | 16 ++--- Examples/javascript/constant/binding.gyp | 8 +++ Examples/javascript/constant/runme.js | 24 +++---- Examples/javascript/enum/Makefile | 16 ++--- Examples/javascript/enum/binding.gyp | 8 +++ .../enum/{example.cpp => example.cxx} | 0 Examples/javascript/enum/runme.js | 26 ++++---- Examples/javascript/exception/Makefile | 16 ++--- Examples/javascript/exception/binding.gyp | 8 +++ .../exception/{example.cpp => example.cxx} | 0 Examples/javascript/exception/runme.js | 25 ++++---- Examples/javascript/functor/Makefile | 16 ++--- Examples/javascript/functor/binding.gyp | 8 +++ .../functor/{example.cpp => example.cxx} | 0 Examples/javascript/functor/runme.js | 7 +-- Examples/javascript/namespace/Makefile | 16 ++--- Examples/javascript/namespace/binding.gyp | 8 +++ .../namespace/{example.cpp => example.cxx} | 0 Examples/javascript/namespace/runme.js | 17 +++-- Examples/javascript/operator/Makefile | 16 ++--- Examples/javascript/operator/binding.gyp | 8 +++ Examples/javascript/operator/example.cpp | 0 Examples/javascript/operator/runme.js | 16 ++--- Examples/javascript/overload/Makefile | 16 ++--- Examples/javascript/overload/binding.gyp | 8 +++ Examples/javascript/overload/example.cpp | 0 Examples/javascript/overload/runme.js | 2 + Examples/javascript/pointer/Makefile | 16 ++--- Examples/javascript/pointer/binding.gyp | 8 +++ .../pointer/{example.cpp => example.cxx} | 0 Examples/javascript/pointer/runme.js | 19 +++--- Examples/javascript/reference/Makefile | 16 ++--- Examples/javascript/reference/binding.gyp | 8 +++ .../reference/{example.cpp => example.cxx} | 0 Examples/javascript/reference/runme.js | 24 +++---- Examples/javascript/simple/Makefile | 18 +++--- Examples/javascript/simple/binding.gyp | 8 +++ .../simple/{example.c => example.cxx} | 0 Examples/javascript/simple/runme.js | 8 +-- Examples/javascript/template/Makefile | 16 ++--- Examples/javascript/template/binding.gyp | 8 +++ Examples/javascript/template/example.cpp | 0 Examples/javascript/template/runme.js | 12 ++-- Examples/javascript/variables/Makefile | 18 +++--- Examples/javascript/variables/binding.gyp | 8 +++ .../variables/{example.c => example.cxx} | 0 Examples/javascript/variables/runme.js | 62 +++++++++---------- 48 files changed, 312 insertions(+), 223 deletions(-) create mode 100644 Examples/javascript/constant/binding.gyp create mode 100644 Examples/javascript/enum/binding.gyp rename Examples/javascript/enum/{example.cpp => example.cxx} (100%) create mode 100644 Examples/javascript/exception/binding.gyp rename Examples/javascript/exception/{example.cpp => example.cxx} (100%) create mode 100644 Examples/javascript/functor/binding.gyp rename Examples/javascript/functor/{example.cpp => example.cxx} (100%) create mode 100644 Examples/javascript/namespace/binding.gyp rename Examples/javascript/namespace/{example.cpp => example.cxx} (100%) create mode 100644 Examples/javascript/operator/binding.gyp delete mode 100644 Examples/javascript/operator/example.cpp create mode 100644 Examples/javascript/overload/binding.gyp delete mode 100644 Examples/javascript/overload/example.cpp create mode 100644 Examples/javascript/pointer/binding.gyp rename Examples/javascript/pointer/{example.cpp => example.cxx} (100%) create mode 100644 Examples/javascript/reference/binding.gyp rename Examples/javascript/reference/{example.cpp => example.cxx} (100%) create mode 100644 Examples/javascript/simple/binding.gyp rename Examples/javascript/simple/{example.c => example.cxx} (100%) create mode 100644 Examples/javascript/template/binding.gyp delete mode 100644 Examples/javascript/template/example.cpp create mode 100644 Examples/javascript/variables/binding.gyp rename Examples/javascript/variables/{example.c => example.cxx} (100%) diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js index 0ecaf3f82..5bb62ecd4 100755 --- a/Examples/javascript/class/runme.js +++ b/Examples/javascript/class/runme.js @@ -1,4 +1,3 @@ -// file: runme.js var example = require("./build/Release/example"); // ----- Object creation ----- diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile index dbf2f6660..99a9e9e86 100755 --- a/Examples/javascript/constant/Makefile +++ b/Examples/javascript/constant/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/constant/binding.gyp b/Examples/javascript/constant/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/constant/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/constant/runme.js b/Examples/javascript/constant/runme.js index cd4783a27..b11c08c98 100755 --- a/Examples/javascript/constant/runme.js +++ b/Examples/javascript/constant/runme.js @@ -1,14 +1,14 @@ -// file: runme.js +var example = require("./build/Release/example"); -print("ICONST = " + example.ICONST + " (should be 42)\n"); -print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); -print("CCONST = " + example.CCONST + " (should be 'x')\n"); -print("CCONST2 = " + example.CCONST2 + " (this should be on a new line)\n"); -print("SCONST = " + example.SCONST + " (should be 'Hello World')\n"); -print("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')\n"); -print("EXPR = " + example.EXPR + " (should be 48.5484)\n"); -print("iconst = " + example.iconst + " (should be 37)\n"); -print("fconst = " + example.fconst + " (should be 3.14)\n"); +console.log("ICONST = " + example.ICONST + " (should be 42)\n"); +console.log("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +console.log("CCONST = " + example.CCONST + " (should be 'x')\n"); +console.log("CCONST2 = " + example.CCONST2 + " (this should be on a new line)\n"); +console.log("SCONST = " + example.SCONST + " (should be 'Hello World')\n"); +console.log("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')\n"); +console.log("EXPR = " + example.EXPR + " (should be 48.5484)\n"); +console.log("iconst = " + example.iconst + " (should be 37)\n"); +console.log("fconst = " + example.fconst + " (should be 3.14)\n"); -print("EXTERN = " + example.EXTERN + " (should be undefined)\n"); -print("FOO = " + example.FOO + " (should be undefined)\n"); +console.log("EXTERN = " + example.EXTERN + " (should be undefined)\n"); +console.log("FOO = " + example.FOO + " (should be undefined)\n"); diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/enum/Makefile +++ b/Examples/javascript/enum/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/enum/binding.gyp b/Examples/javascript/enum/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/enum/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/enum/example.cpp b/Examples/javascript/enum/example.cxx similarity index 100% rename from Examples/javascript/enum/example.cpp rename to Examples/javascript/enum/example.cxx diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js index 3f6283639..9d3accd1d 100755 --- a/Examples/javascript/enum/runme.js +++ b/Examples/javascript/enum/runme.js @@ -1,26 +1,26 @@ -// file: runme.py +var example = require("./build/Release/example"); // ----- Object creation ----- // Print out the value of some enums -print("*** color ***"); -print(" RED =" + example.RED); -print(" BLUE =" + example.BLUE); -print(" GREEN =" + example.GREEN); +console.log("*** color ***"); +console.log(" RED =" + example.RED); +console.log(" BLUE =" + example.BLUE); +console.log(" GREEN =" + example.GREEN); -print("\n*** Foo::speed ***"); -print(" Foo_IMPULSE =" + example.Foo.IMPULSE); -print(" Foo_WARP =" + example.Foo.WARP); -print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); +console.log("\n*** Foo::speed ***"); +console.log(" Foo_IMPULSE =" + example.Foo.IMPULSE); +console.log(" Foo_WARP =" + example.Foo.WARP); +console.log(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); -print("\nTesting use of enums with functions\n"); +console.log("\nTesting use of enums with functions\n"); example.enum_test(example.RED, example.Foo.IMPULSE); example.enum_test(example.BLUE, example.Foo.WARP); example.enum_test(example.GREEN, example.Foo.LUDICROUS); example.enum_test(1234,5678); -print("\nTesting use of enum with class method"); +console.log("\nTesting use of enum with class method"); f = new example.Foo(); f.enum_test(example.Foo.IMPULSE); @@ -28,7 +28,7 @@ f.enum_test(example.Foo.WARP); f.enum_test(example.Foo.LUDICROUS); // enum value BLUE of enum color is accessed as property of cconst -print("example.BLUE= " + example.BLUE); +console.log("example.BLUE= " + example.BLUE); // enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst -print("example.speed.LUDICROUS= " + example.Foo.LUDICROUS); +console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS); diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/exception/Makefile +++ b/Examples/javascript/exception/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/exception/binding.gyp b/Examples/javascript/exception/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/exception/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/exception/example.cpp b/Examples/javascript/exception/example.cxx similarity index 100% rename from Examples/javascript/exception/example.cpp rename to Examples/javascript/exception/example.cxx diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js index 936b37883..f7041f028 100644 --- a/Examples/javascript/exception/runme.js +++ b/Examples/javascript/exception/runme.js @@ -1,7 +1,6 @@ -//file: runme.js -// Throw a lot of exceptions +var example = require("./build/Release/example"); -print("Trying to catch some exceptions."); +console.log("Trying to catch some exceptions."); t = new example.Test(); try{ t.unknown(); @@ -9,9 +8,9 @@ try{ } catch(error) { if(error == -1) { - print("t.unknown() didn't throw"); + console.log("t.unknown() didn't throw"); } else { - print("successfully catched throw in Test::unknown()."); + console.log("successfully catched throw in Test::unknown()."); } } @@ -21,9 +20,9 @@ try{ } catch(error){ if(error == -1) { - print("t.simple() did not throw"); + console.log("t.simple() did not throw"); } else { - print("successfully catched throw in Test::simple()."); + console.log("successfully catched throw in Test::simple()."); } } @@ -32,9 +31,9 @@ try{ throw -1; } catch(error){ if(error == -1) { - print("t.message() did not throw"); + console.log("t.message() did not throw"); } else { - print("successfully catched throw in Test::message()."); + console.log("successfully catched throw in Test::message()."); } } @@ -44,9 +43,9 @@ try{ } catch(error){ if(error == -1) { - print("t.hosed() did not throw"); + console.log("t.hosed() did not throw"); } else { - print("successfully catched throw in Test::hosed()."); + console.log("successfully catched throw in Test::hosed()."); } } @@ -57,9 +56,9 @@ for (var i=1; i<4; i++) { } catch(error){ if(error == -1) { - print("t.multi(" + i + ") did not throw"); + console.log("t.multi(" + i + ") did not throw"); } else { - print("successfully catched throw in Test::multi()."); + console.log("successfully catched throw in Test::multi()."); } } } diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/functor/Makefile +++ b/Examples/javascript/functor/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/functor/binding.gyp b/Examples/javascript/functor/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/functor/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/functor/example.cpp b/Examples/javascript/functor/example.cxx similarity index 100% rename from Examples/javascript/functor/example.cpp rename to Examples/javascript/functor/example.cxx diff --git a/Examples/javascript/functor/runme.js b/Examples/javascript/functor/runme.js index 48d332c83..f7be78286 100644 --- a/Examples/javascript/functor/runme.js +++ b/Examples/javascript/functor/runme.js @@ -1,5 +1,4 @@ -// Operator overloading example - +var example = require("./build/Release/example"); a = new example.intSum(0); b = new example.doubleSum(100.0); @@ -11,6 +10,6 @@ for (i=1;i<=100;i++) a.call(i); // Note: function call b.call(Math.sqrt(i)); // Note: function call -print(a.result()); -print(b.result()); +console.log(a.result()); +console.log(b.result()); diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/namespace/Makefile +++ b/Examples/javascript/namespace/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/namespace/binding.gyp b/Examples/javascript/namespace/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/namespace/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/namespace/example.cpp b/Examples/javascript/namespace/example.cxx similarity index 100% rename from Examples/javascript/namespace/example.cpp rename to Examples/javascript/namespace/example.cxx diff --git a/Examples/javascript/namespace/runme.js b/Examples/javascript/namespace/runme.js index dc49b078e..9a9d6744d 100644 --- a/Examples/javascript/namespace/runme.js +++ b/Examples/javascript/namespace/runme.js @@ -1,11 +1,10 @@ - print("Global variable Foo=" + example.nspace.Foo); - example.nspace.Foo = 5; - print("Variable Foo changed to " + example.nspace.Foo); - print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); +var example = require("./build/Release/example"); -print("Creating some objects:"); +console.log("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +console.log("Variable Foo changed to " + example.nspace.Foo); +console.log("GCD of number 6,18 is " + example.nspace.gcd(6,18)); + +console.log("Creating some objects:"); c = new example.nspace.Circle(10); -print("area = " + c.area()); - - - +console.log("area = " + c.area()); diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/operator/Makefile +++ b/Examples/javascript/operator/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/operator/binding.gyp b/Examples/javascript/operator/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/operator/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/operator/example.cpp b/Examples/javascript/operator/example.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/Examples/javascript/operator/runme.js b/Examples/javascript/operator/runme.js index 92b8e3b74..9dba4b7f9 100644 --- a/Examples/javascript/operator/runme.js +++ b/Examples/javascript/operator/runme.js @@ -1,23 +1,23 @@ -// Operator overloading example +var example = require("./build/Release/example"); a = new example.Complex(2,3); b = new example.Complex(-5,10); -print ("a =" + a); -print ("b =" + b); +console.log ("a =" + a); +console.log ("b =" + b); c = a.plus(b); -print("c =" + c); -print("a*b =" + a.times(b)); -print("a-c =" + a.minus(c)); +console.log("c =" + c); +console.log("a*b =" + a.times(b)); +console.log("a-c =" + a.minus(c)); e = example.Complex.copy(a.minus(c)); -print("e =" + e); +console.log("e =" + e); // Big expression f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); -print("f =" + f); +console.log("f =" + f); diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/overload/Makefile +++ b/Examples/javascript/overload/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/overload/binding.gyp b/Examples/javascript/overload/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/overload/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/overload/example.cpp b/Examples/javascript/overload/example.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/Examples/javascript/overload/runme.js b/Examples/javascript/overload/runme.js index 6b822f107..5ff5d01be 100644 --- a/Examples/javascript/overload/runme.js +++ b/Examples/javascript/overload/runme.js @@ -1,3 +1,5 @@ +var example = require("./build/Release/example"); + example.f(); example.f(1); example.f(1, 2); diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/pointer/Makefile +++ b/Examples/javascript/pointer/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/pointer/binding.gyp b/Examples/javascript/pointer/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/pointer/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/pointer/example.cpp b/Examples/javascript/pointer/example.cxx similarity index 100% rename from Examples/javascript/pointer/example.cpp rename to Examples/javascript/pointer/example.cxx diff --git a/Examples/javascript/pointer/runme.js b/Examples/javascript/pointer/runme.js index 48f92f11f..00778dfbc 100755 --- a/Examples/javascript/pointer/runme.js +++ b/Examples/javascript/pointer/runme.js @@ -1,7 +1,7 @@ -// file: runme.js +var example = require("./build/Release/example"); // First create some objects using the pointer library. -print("Testing the pointer library\n"); +console.log("Testing the pointer library\n"); a = example.new_intp(); b = example.new_intp(); c = example.new_intp(); @@ -9,9 +9,9 @@ c = example.new_intp(); example.intp_assign(a,37); example.intp_assign(b,42); -print(" a = " + example.intp_value(a) + "\n"); -print(" b = " + example.intp_value(b) + "\n"); -print(" c = " + example.intp_value(c) + "\n"); +console.log(" a = " + example.intp_value(a) + "\n"); +console.log(" b = " + example.intp_value(b) + "\n"); +console.log(" c = " + example.intp_value(c) + "\n"); //// Call the add() function with some pointers example.add(a, b, c); @@ -19,7 +19,7 @@ example.add(a, b, c); // //// Now get the result r = example.intp_value(c); -print(" 37 + 42 = " + r + "\n"); +console.log(" 37 + 42 = " + r + "\n"); // Clean up the pointers example.delete_intp(a); @@ -30,9 +30,6 @@ example.delete_intp(c); //// This should be much easier. Now how it is no longer //// necessary to manufacture pointers. //"OUTPUT" Mapping is not supported - -//print("Trying the typemap library"); +//console.log("Trying the typemap library"); //r = example.subtract(37,42); -//print("37 - 42 =" + r); - - +//console.log("37 - 42 =" + r); diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/reference/Makefile +++ b/Examples/javascript/reference/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/reference/binding.gyp b/Examples/javascript/reference/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/reference/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/reference/example.cpp b/Examples/javascript/reference/example.cxx similarity index 100% rename from Examples/javascript/reference/example.cpp rename to Examples/javascript/reference/example.cxx diff --git a/Examples/javascript/reference/runme.js b/Examples/javascript/reference/runme.js index 5cf00061e..ee5737076 100755 --- a/Examples/javascript/reference/runme.js +++ b/Examples/javascript/reference/runme.js @@ -1,23 +1,23 @@ // This file illustrates the manipulation of C++ references in Javascript. -// TODO: deleteion of vector objects created here +var example = require("./build/Release/example"); // ----- Object creation ----- -print("Creating some objects:\n"); +console.log("Creating some objects:\n"); a = new example.Vector(3,4,5); b = new example.Vector(10,11,12); -print(" created" + a.print()); -print(" created" + b.print()); +console.log(" created" + a.print()); +console.log(" created" + b.print()); // ----- Call an overloaded operator ----- // This calls the wrapper we placed around operator+(const Vector &a, const Vector &) // It returns a new allocated object. -print("Adding a+b\n"); +console.log("Adding a+b\n"); c = example.addv(a, b); -print("a+b = " + c.print()); +console.log("a+b = " + c.print()); // TODO: Note: Unless we free the result, a memory leak will occur @@ -26,9 +26,9 @@ print("a+b = " + c.print()); // ----- Create a vector array ----- // Note: Using the high-level interface here -print("Creating an array of vectors\n"); +console.log("Creating an array of vectors\n"); va = new example.VectorArray(10); -print("va = " + va + "\n"); +console.log("va = " + va + "\n"); // ----- Set some values in the array ----- @@ -46,20 +46,20 @@ va.set(2,example.addv(a,b)); // Get some values from the array -print("Getting some array values\n"); +console.log("Getting some array values\n"); for (i = 0; i < 5; i++) { temp = va.get(i); - print(i,temp.print()); + console.log(i,temp.print()); } // Watch under resource meter to check on this -print("Making sure we don't leak memory.\n"); +console.log("Making sure we don't leak memory.\n"); for (i = 0; i < 1000000; i++) { c = va.get(i % 10); } //---------TODO--------- //----- Clean up ----- -//print("Cleaning up\n"); +//console.log("Cleaning up\n"); //example.delete_VectorArray(va); //example.delete_Vector(a); diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile index fb4669329..99a9e9e86 100755 --- a/Examples/javascript/simple/Makefile +++ b/Examples/javascript/simple/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.c +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/simple/binding.gyp b/Examples/javascript/simple/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/simple/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/simple/example.c b/Examples/javascript/simple/example.cxx similarity index 100% rename from Examples/javascript/simple/example.c rename to Examples/javascript/simple/example.cxx diff --git a/Examples/javascript/simple/runme.js b/Examples/javascript/simple/runme.js index 96c11a5a2..d970dcb7c 100755 --- a/Examples/javascript/simple/runme.js +++ b/Examples/javascript/simple/runme.js @@ -1,22 +1,22 @@ -/* file: runme.js */ +var example = require("./build/Release/example"); /* Call our gcd() function */ x = 42; y = 105; g = example.gcd(x,y); -print("GCD of x and y is=" + g); +console.log("GCD of x and y is=" + g); /* Manipulate the Foo global variable */ /* Output its current value */ -print("Global variable Foo=" + example.Foo); +console.log("Global variable Foo=" + example.Foo); /* Change its value */ example.Foo = 3.1415926; /* See if the change took effect */ -print("Variable Foo changed to=" + example.Foo); +console.log("Variable Foo changed to=" + example.Foo); diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile index 180e99cae..99a9e9e86 100755 --- a/Examples/javascript/template/Makefile +++ b/Examples/javascript/template/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cpp +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: +wrapper:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_cpp + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/template/binding.gyp b/Examples/javascript/template/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/template/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/template/example.cpp b/Examples/javascript/template/example.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/Examples/javascript/template/runme.js b/Examples/javascript/template/runme.js index b2a5264ab..551475c72 100644 --- a/Examples/javascript/template/runme.js +++ b/Examples/javascript/template/runme.js @@ -1,8 +1,8 @@ -// file: runme.js +var example = require("./build/Release/example"); //Call some templated functions -print(example.maxint(3,7)); -print(example.maxdouble(3.14,2.18)); +console.log(example.maxint(3,7)); +console.log(example.maxdouble(3.14,2.18)); // Create some class @@ -19,14 +19,12 @@ sum = 0; for(i=0;i<=100;i++) sum = sum + iv.getitem(i); -print(sum); +console.log(sum); sum = 0.0; for(i=0;i<=1000;i++) sum = sum + dv.getitem(i); -print(sum); +console.log(sum); delete iv; delete dv; - - diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile index fb4669329..99a9e9e86 100755 --- a/Examples/javascript/variables/Makefile +++ b/Examples/javascript/variables/Makefile @@ -1,21 +1,21 @@ TOP = ../.. SWIG = $(TOP)/../preinst-swig -SRCS = example.c +CXXSRCS = example.cxx JS_SCRIPT = runme.js TARGET = example INTERFACE = example.i -all:: - $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build clean:: $(MAKE) -f $(TOP)/Makefile javascript_clean -javascript_exe:: - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' javascript_exe - -check:: all +check:: build $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/variables/binding.gyp b/Examples/javascript/variables/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/variables/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/variables/example.c b/Examples/javascript/variables/example.cxx similarity index 100% rename from Examples/javascript/variables/example.c rename to Examples/javascript/variables/example.cxx diff --git a/Examples/javascript/variables/runme.js b/Examples/javascript/variables/runme.js index 7c4e151de..22d208480 100755 --- a/Examples/javascript/variables/runme.js +++ b/Examples/javascript/variables/runme.js @@ -1,4 +1,4 @@ -// file: runme.js +var example = require("./build/Release/example"); // Try to set the values of some global variables example.ivar = 42; @@ -17,52 +17,52 @@ example.iptrvar= example.new_int(37); example.ptptr = example.new_Point(37,42); example.name = "Bill"; -// Now print out the values of the variables -print("Variables (values printed from Python)" + "\n"); -print("ivar = " + example.ivar + "\n"); -print("svar = " + example.svar + "\n"); -print("lvar = " + example.lvar + "\n"); -print("uivar = " + example.uivar + "\n"); -print("usvar = " + example.usvar + "\n"); -print("ulvar = " + example.ulvar + "\n"); -print("scvar = " + example.scvar + "\n"); -print("ucvar = " + example.ucvar + "\n"); -print("fvar = " + example.fvar + "\n"); -print("dvar = " + example.dvar + "\n"); -print("cvar = " + example.cvar + "\n"); -print("strvar = " + example.strvar+ "\n"); -print("cstrvar = " + example.cstrvar+ "\n"); -print("iptrvar = " + example.iptrvar+ "\n"); -print("name = " + example.name + "\n"); -print("ptptr = " + example.ptptr + ": " + example.Point_print(example.ptptr) + "\n"); -print("pt = " + example.pt + ": " + example.Point_print(example.pt) + "\n"); +// Now console.log out the values of the variables +console.log("Variables (values console.loged from Python)" + "\n"); +console.log("ivar = " + example.ivar + "\n"); +console.log("svar = " + example.svar + "\n"); +console.log("lvar = " + example.lvar + "\n"); +console.log("uivar = " + example.uivar + "\n"); +console.log("usvar = " + example.usvar + "\n"); +console.log("ulvar = " + example.ulvar + "\n"); +console.log("scvar = " + example.scvar + "\n"); +console.log("ucvar = " + example.ucvar + "\n"); +console.log("fvar = " + example.fvar + "\n"); +console.log("dvar = " + example.dvar + "\n"); +console.log("cvar = " + example.cvar + "\n"); +console.log("strvar = " + example.strvar+ "\n"); +console.log("cstrvar = " + example.cstrvar+ "\n"); +console.log("iptrvar = " + example.iptrvar+ "\n"); +console.log("name = " + example.name + "\n"); +console.log("ptptr = " + example.ptptr + ": " + example.Point_print(example.ptptr) + "\n"); +console.log("pt = " + example.pt + ": " + example.Point_print(example.pt) + "\n"); -print("\nVariables (values printed from C)"); +console.log("\nVariables (values console.loged from C)"); example.print_vars(); -print("\nNow I'm going to try and modify some read only variables"); +console.log("\nNow I'm going to try and modify some read only variables"); -print("Tring to set 'path'"); +console.log("Tring to set 'path'"); try{ example.path = "Whoa!"; - print("Hey, what's going on?!?! This shouldn't work"); + console.log("Hey, what's going on?!?! This shouldn't work"); } catch(e){ - print("Good."); + console.log("Good."); } -print("Trying to set 'status'"); +console.log("Trying to set 'status'"); try{ example.status = 0; - print("Hey, what's going on?!?! This shouldn't work"); + console.log("Hey, what's going on?!?! This shouldn't work"); } catch(e){ - print("Good."); + console.log("Good."); } -print("\nI'm going to try and update a structure variable.\n"); +console.log("\nI'm going to try and update a structure variable.\n"); example.pt = example.ptptr; -print("The new value is: "); +console.log("The new value is: "); example.pt_print(); -print("You should see the value: " + example.Point_print(example.ptptr)); +console.log("You should see the value: " + example.Point_print(example.ptptr)); From 14a137adca1a101595e103893d7143aa43525791 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 06:27:14 +0200 Subject: [PATCH 152/352] Fix regression. --- Lib/javascript/v8/javascriptcode.swg | 1 - 1 file changed, 1 deletion(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 377e93752..068632380 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -75,7 +75,6 @@ SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { fail: SWIGV8_RETURN(v8::Undefined()); - return; } %} From 78a3cc9e3e4bdf6d55cb52ab8812c4127e6ad475 Mon Sep 17 00:00:00 2001 From: Kota Iguchi Date: Fri, 16 Aug 2013 10:15:37 +0900 Subject: [PATCH 153/352] Added the finalize callback (JSObjectFinalizeCallback) --- Lib/javascript/jsc/javascriptcode.swg | 5 +++-- Source/Modules/javascript.cxx | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 40ce9c9b0..0325a7a35 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -108,7 +108,7 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc void $jswrapper(JSObjectRef thisObject) { SWIG_PRV_DATA* t = (SWIG_PRV_DATA*) JSObjectGetPrivate(thisObject); - if(t && t->swigCMemOwn) free (($jstype*)t->swigCObject); + if(t && t->swigCMemOwn) free (($jstype)t->swigCObject); if(t) free(t); } %} @@ -125,7 +125,7 @@ void $jswrapper(JSObjectRef thisObject) { SWIG_PRV_DATA* t = (SWIG_PRV_DATA*) JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) { - $jstype* arg1 = ($jstype*)t->swigCObject; + $jstype arg1 = ($jstype)t->swigCObject; ${destructor_action} } if(t) free(t); @@ -385,6 +385,7 @@ JSStaticFunction $jsmangledname_functions[] = { $jsmangledname_classDefinition.staticFunctions = $jsmangledname_staticFunctions; $jsmangledname_classDefinition.staticValues = $jsmangledname_staticValues; $jsmangledname_classDefinition.callAsConstructor = $jsctor; + $jsmangledname_classDefinition.finalize = $jsdtor; $jsmangledname_objectDefinition.staticValues = $jsmangledname_values; $jsmangledname_objectDefinition.staticFunctions = $jsmangledname_functions; $jsmangledname_objectDefinition.parentClass = $jsbaseclass_classRef; diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 884e09ebe..cec65338a 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1700,6 +1700,7 @@ int JSCEmitter::exitClass(Node *n) { .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) .replace(T_BASECLASS, base_name_mangled) .replace(T_CTOR, state.clazz(CTOR)) + .replace(T_DTOR, state.clazz(DTOR)) .pretty_print(state.global(INITIALIZER)); Delete(base_name_mangled); From a29975c69a0bf0628d740232cab722387588eed2 Mon Sep 17 00:00:00 2001 From: Kota Iguchi Date: Fri, 16 Aug 2013 16:08:47 +0900 Subject: [PATCH 154/352] Typemap for natural support for arrays --- Lib/javascript/jsc/arrays_javascript.i | 123 ++++++++++++++++++++++++ Lib/javascript/v8/arrays_javascript.i | 125 +++++++++++++++++++++++++ 2 files changed, 248 insertions(+) create mode 100644 Lib/javascript/jsc/arrays_javascript.i create mode 100644 Lib/javascript/v8/arrays_javascript.i diff --git a/Lib/javascript/jsc/arrays_javascript.i b/Lib/javascript/jsc/arrays_javascript.i new file mode 100644 index 000000000..b9199d86b --- /dev/null +++ b/Lib/javascript/jsc/arrays_javascript.i @@ -0,0 +1,123 @@ +/* ----------------------------------------------------------------------------- + * arrays_javascript.i + * + * These typemaps give more natural support for arrays. The typemaps are not efficient + * as there is a lot of copying of the array values whenever the array is passed to C/C++ + * from JavaScript and vice versa. The JavaScript array is expected to be the same size as the C array. + * An exception is thrown if they are not. + * + * Example usage: + * Wrapping: + * + * %include + * %inline %{ + * extern int FiddleSticks[3]; + * %} + * + * Use from JavaScript like this: + * + * var fs = [10, 11, 12]; + * example.FiddleSticks = fs; + * fs = example.FiddleSticks; + * ----------------------------------------------------------------------------- */ + +%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} +%fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {} + +%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY] + (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if (JSValueIsObject(context, $input)) + { + // Convert into Array + array = JSValueToObject(context, $input, NULL); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); + + // Get primitive value from JSObject + res = SWIG_AsVal(int)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) int[], int[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + JSValueRef values[length]; + + for (i = 0; i < length; i++) + { + values[i] = SWIG_From(int)($1[i]); + } + + $result = JSObjectMakeArray(context, length, values, NULL); +} + +%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY] + (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if (JSValueIsObject(context, $input)) + { + // Convert into Array + array = JSValueToObject(context, $input, NULL); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); + + // Get primitive value from JSObject + res = SWIG_AsVal(double)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) double[], double[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + JSValueRef values[length]; + + for (i = 0; i < length; i++) + { + values[i] = SWIG_From(double)($1[i]); + } + + $result = JSObjectMakeArray(context, length, values, NULL); +} diff --git a/Lib/javascript/v8/arrays_javascript.i b/Lib/javascript/v8/arrays_javascript.i new file mode 100644 index 000000000..22b50be8f --- /dev/null +++ b/Lib/javascript/v8/arrays_javascript.i @@ -0,0 +1,125 @@ +/* ----------------------------------------------------------------------------- + * arrays_javascript.i + * + * These typemaps give more natural support for arrays. The typemaps are not efficient + * as there is a lot of copying of the array values whenever the array is passed to C/C++ + * from JavaScript and vice versa. The JavaScript array is expected to be the same size as the C array. + * An exception is thrown if they are not. + * + * Example usage: + * Wrapping: + * + * %include + * %inline %{ + * extern int FiddleSticks[3]; + * %} + * + * Use from JavaScript like this: + * + * var fs = [10, 11, 12]; + * example.FiddleSticks = fs; + * fs = example.FiddleSticks; + * ----------------------------------------------------------------------------- */ + +%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} +%fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {} + +%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY] + (int length = 0, v8::Local array, v8::Local jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if ($input->IsArray()) + { + // Convert into Array + array = v8::Local::Cast($input); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = array->Get(i); + + // Get primitive value from JSObject + res = SWIG_AsVal(int)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) int[], int[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + v8::Local array = v8::Array::New(length); + + for (i = 0; i < length; i++) + { + array->Set(i, SWIG_From(int)($1[i])); + } + + + $result = array; +} + +%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY] + (int length = 0, v8::Local array, v8::Local jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if ($input->IsArray()) + { + // Convert into Array + array = v8::Local::Cast($input); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = array->Get(i); + + // Get primitive value from JSObject + res = SWIG_AsVal(double)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) double[], double[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + v8::Local array = v8::Array::New(length); + + for (i = 0; i < length; i++) + { + array->Set(i, SWIG_From(double)($1[i])); + } + + + $result = array; +} From f70c0e16f292e1fab77fb9ae63f56e86c3ae90c4 Mon Sep 17 00:00:00 2001 From: Kota Iguchi Date: Wed, 28 Aug 2013 15:08:50 +0900 Subject: [PATCH 155/352] Add "equals" to compare between pointers Add "getCPtr" to retrieve pointer value --- Lib/javascript/jsc/javascriptruntime.swg | 23 +++++++- Lib/javascript/v8/javascripthelpers.swg | 6 ++ Lib/javascript/v8/javascriptruntime.swg | 73 ++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/Lib/javascript/jsc/javascriptruntime.swg b/Lib/javascript/jsc/javascriptruntime.swg index 1eddf93f1..88379415a 100644 --- a/Lib/javascript/jsc/javascriptruntime.swg +++ b/Lib/javascript/jsc/javascriptruntime.swg @@ -78,6 +78,23 @@ JSValueRef _wrap_SwigObject_getCPtr(JSContextRef context, JSObjectRef function, return jsresult; } +JSValueRef _wrap_SwigObject_equals(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + bool result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA*) JSObjectGetPrivate(obj); + + JSObjectRef obj2 = JSValueToObject(context, argv[0], NULL); + SWIG_PRV_DATA *cdata2 = (SWIG_PRV_DATA*) JSObjectGetPrivate(obj2); + + result = (cdata->swigCObject == cdata2->swigCObject); + jsresult = JSValueMakeBoolean(context, result); + + return jsresult; +} + JSStaticValue _SwigObject_values[] = { { 0, 0, 0, 0 @@ -87,7 +104,11 @@ JSStaticValue _SwigObject_values[] = { JSStaticFunction _SwigObject_functions[] = { { "disown",_wrap_SwigObject_disown, kJSPropertyAttributeNone - },{ + }, + { + "equals",_wrap_SwigObject_equals, kJSPropertyAttributeNone + }, + { "getCPtr",_wrap_SwigObject_getCPtr, kJSPropertyAttributeNone }, { diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index 61bc45da5..52f3f106f 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -24,6 +24,12 @@ v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) v8::Handle inst_templ = class_templ->InstanceTemplate(); inst_templ->SetInternalFieldCount(1); + v8::Handle equals_templ = class_templ->PrototypeTemplate(); + equals_templ->Set(v8::String::NewSymbol("equals"), v8::FunctionTemplate::New(_wrap_equals)); + + v8::Handle cptr_templ = class_templ->PrototypeTemplate(); + cptr_templ->Set(v8::String::NewSymbol("getCPtr"), v8::FunctionTemplate::New(_wrap_getCPtr)); + return scope.Close(class_templ); } diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 841b03e21..bfc93a8fb 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -175,6 +175,28 @@ void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *objec delete proxy; } +int SWIG_V8_GetInstancePtr(v8::Handle valRef, void** ptr) { + if(!valRef->IsObject()) { + return SWIG_TypeError; + } + v8::Handle objRef = valRef->ToObject(); + + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; + +#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) + v8::Handle cdataRef = objRef->GetInternalField(0); + SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); +#else + SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + + if(cdata == NULL) { + return SWIG_ERROR; + } + + *ptr = cdata->swigCObject; +} + void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { SWIGV8_Proxy* cdata = new SWIGV8_Proxy(); cdata->swigCObject = ptr; @@ -253,5 +275,56 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in #define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_V8_ConvertPtr(obj, pptr, type, 0) #define SWIG_NewFunctionPtrObj(ptr, type) SWIG_V8_NewPointerObj(ptr, type, 0) +#define SWIG_GetInstancePtr(obj, ptr) SWIG_V8_GetInstancePtr(obj, ptr) + +v8::Handle _wrap_equals(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle jsresult; + void *arg1 = (void *) 0 ; + void *arg2 = (void *) 0 ; + bool result; + int res1; + int res2; + + if(args.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for _wrap_equals."); + + res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ERROR, "Could not get pointer from 'this' object for _wrap_equals."); + } + res2 = SWIG_GetInstancePtr(args[0], &arg2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "equals" "', argument " "1"" of type '" "void *""'"); + } + + result = (bool)(arg1 == arg2); + jsresult = v8::Boolean::New(result); + + return scope.Close(jsresult); + goto fail; +fail: + return scope.Close(v8::Undefined()); +} + +v8::Handle _wrap_getCPtr(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle jsresult; + void *arg1 = (void *) 0 ; + long result; + int res1; + + res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getCPtr" "', argument " "1"" of type '" "void *""'"); + } + + result = (long)arg1; + jsresult = v8::Number::New(result); + + return scope.Close(jsresult); + goto fail; +fail: + return scope.Close(v8::Undefined()); +} %} From d3074ba4c1cc46bfebd3b09671f92965cab533ed Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 14:02:52 +0200 Subject: [PATCH 156/352] Fix error in SWIG_V8_GetInstancePtr. --- Lib/javascript/v8/javascriptruntime.swg | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index bfc93a8fb..1c97506da 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -195,6 +195,8 @@ int SWIG_V8_GetInstancePtr(v8::Handle valRef, void** ptr) { } *ptr = cdata->swigCObject; + + return SWIG_OK; } void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info *info, int flags) { From cef82c720f4875b9ddf53667e5396d3b80c7eefd Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 14:41:35 +0200 Subject: [PATCH 157/352] Replace old style v8 version switches. --- Lib/javascript/v8/javascriptruntime.swg | 28 ++++++++++--------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 1c97506da..139a5a3ee 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -94,19 +94,14 @@ public: }; ~SWIGV8_Proxy() { -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) handle.ClearWeak(); -#else - handle.ClearWeak(v8::Isolate::GetCurrent()); -#endif - - //handle->SetInternalField(0, v8::Undefined()); - -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) handle.Dispose(); #else + handle.ClearWeak(v8::Isolate::GetCurrent()); handle.Dispose(v8::Isolate::GetCurrent()); #endif + handle.Clear(); v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); } @@ -121,7 +116,7 @@ class SWIGV8_ClientData { public: v8::Persistent class_templ; -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) void (*dtor) (v8::Persistent< v8::Value> object, void *parameter); #else void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); @@ -135,7 +130,7 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) v8::Handle cdataRef = objRef->GetInternalField(0); SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); #else @@ -162,13 +157,13 @@ int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_t return SWIG_OK; } -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) #else void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) #endif { -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) SWIGV8_Proxy *proxy = static_cast(parameter); #endif @@ -183,7 +178,7 @@ int SWIG_V8_GetInstancePtr(v8::Handle valRef, void** ptr) { if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) v8::Handle cdataRef = objRef->GetInternalField(0); SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); #else @@ -205,7 +200,7 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; cdata->info = info; -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) obj->SetPointerInInternalField(0, cdata); cdata->handle = v8::Persistent::New(obj); #else @@ -213,7 +208,7 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); #endif -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) // clientdata must be set for owned data as we need to register the dtor if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); @@ -246,7 +241,7 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in v8::Handle class_templ; -#if defined(BUILDING_NODE_EXTENSION) || defined(V8_3_14) +#if (SWIG_V8_VERSION < 0x031900) if(info->clientdata != 0) { class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; } else { @@ -329,4 +324,3 @@ fail: return scope.Close(v8::Undefined()); } %} - From 8bbd92883101584583e3139e442bc418100b4a45 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 16:57:40 +0200 Subject: [PATCH 158/352] Make javascript test-suite work with nodejs. --- .gitignore | 1 + Examples/test-suite/javascript/Makefile.in | 60 ++++++++++--------- .../javascript/abstract_access_runme.js | 3 +- .../javascript/abstract_typedef2_runme.js | 2 + .../javascript/abstract_typedef_runme.js | 2 + .../javascript/abstract_virtual_runme.js | 2 + .../javascript/array_member_runme.js | 2 + .../javascript/arrays_global_runme.js | 2 + .../javascript/char_binary_runme.js | 2 + .../javascript/class_ignore_runme.js | 1 + .../javascript/class_scope_weird_runme.js | 1 + .../javascript/complextest_runme.js | 1 + .../test-suite/javascript/constover_runme.js | 4 +- .../javascript/constructor_copy_runme.js | 1 + .../test-suite/javascript/cpp_enum_runme.js | 2 + .../javascript/cpp_namespace_runme.js | 4 +- .../test-suite/javascript/cpp_static_runme.js | 2 + .../javascript/director_alternating_runme.js | 1 + .../javascript/enum_template_runme.js | 4 +- .../javascript/javascript_unicode_runme.js | 2 + .../namespace_virtual_method_runme.js | 1 + .../javascript/overload_copy_runme.js | 1 + .../javascript/preproc_include_runme.js | 1 + .../test-suite/javascript/preproc_runme.js | 1 + .../javascript/ret_by_value_runme.js | 1 + Examples/test-suite/javascript/setup_test.sh | 6 ++ .../javascript/struct_value_runme.js | 5 +- .../javascript/template_static_runme.js | 1 + .../javascript/typedef_class_runme.js | 8 ++- .../javascript/typedef_inherit_runme.js | 1 + .../javascript/typedef_scope_runme.js | 5 +- .../javascript/typemap_arrays_runme.js | 1 + .../javascript/typemap_delete_runme.js | 1 + .../javascript/typemap_namespace_runme.js | 1 + .../javascript/typemap_ns_using_runme.js | 1 + .../test-suite/javascript/using1_runme.js | 2 +- .../test-suite/javascript/using2_runme.js | 1 + 37 files changed, 98 insertions(+), 39 deletions(-) create mode 100644 Examples/test-suite/javascript/setup_test.sh diff --git a/.gitignore b/.gitignore index 147e44cb2..665699d05 100644 --- a/.gitignore +++ b/.gitignore @@ -75,6 +75,7 @@ Examples/test-suite/*/*.c Examples/test-suite/*/*.h Examples/test-suite/python/*.py Examples/javascript/*/*_wrap.c +Examples/test-suite/javascript/*/* Tools/javascript/javascript Tools/javascript/javascript_d .settings diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index e57081412..edc621c7e 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -10,25 +10,23 @@ top_builddir = @top_builddir@ JS_INCLUDE = @JSCOREINC@ JS_DLNK = @JSCOREDYNAMICLINKING@ JSCXXFLAGS = @JSCXXFLAGS@ -JAVASCRIPT_EXE = $(top_srcdir)/Tools/javascript/javascript +JAVASCRIPT_EXE = node +SWIG = $(top_builddir)/preinst_swig C_TEST_CASES = \ - preproc \ - preproc_include + preproc + CPP_TEST_CASES = \ abstract_access \ abstract_typedef \ abstract_typedef2 \ abstract_virtual \ - array_member \ arrays_global \ char_binary \ class_ignore \ class_scope_weird \ - complextest \ constover \ - constructor_copy \ cpp_enum \ cpp_namespace \ cpp_static \ @@ -50,6 +48,12 @@ CPP_TEST_CASES = \ using2 \ javascript_unicode +BROKEN_TEST_CASES = \ + array_member \ + complextest \ + constructor_copy \ + preproc_include + SKIP_CPP_CASES = @SKIP_CPP_CASES@ SKIP_C_CASES = @SKIP_C_CASES@ SKIP_CPP_STD_CASES = @SKIP_CPP_STD_CASES@ @@ -57,45 +61,47 @@ SKIP_MULTI_CPP_CASES = @SKIP_MULTI_CPP_CASES@ include $(srcdir)/../common.mk -ifeq (,$(V8)) -JSENGINEFLAG = -jsc -else -JSENGINEFLAG = -v8 -endif - # Overridden variables here # Custom tests - tests with additional commandline options -javascript_exe: - $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TOP='$(top_builddir)/$(EXAMPLES)' javascript_exe - # Rules for the different types of tests -%.cpptest: javascript_exe - $(setup) - +$(swig_and_compile_cpp) +%.cpptest: + $(prepare_test) + $(generate_cpp_wrapper) + $(build_module) $(run_testcase) -%.ctest: javascript_exe - $(setup) - +$(swig_and_compile_c) +%.ctest: + $(prepare_test) + $(generate_cpp_wrapper) + $(build_module) $(run_testcase) -%.multicpptest: javascript_exe - $(setup) - +$(swig_and_compile_multi_cpp) +%.multicpptest: + $(prepare_test) + $(generate_cpp_wrapper) + $(build_module) $(run_testcase) +prepare_test = \ + sh ./setup_test.sh $* + +generate_cpp_wrapper = \ + $(SWIG) -c++ -javascript -node -o $*/$*_wrap.cxx ../$*.i + +build_module = \ + cd $* && node-gyp configure build && cd .. + # Runs the testcase. A testcase is only run if # a file is found which has _runme.js appended after the testcase name. run_testcase = \ - if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ - env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(JAVASCRIPT_EXE) $(JSENGINEFLAG) -l $* $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + node $(srcdir)/$*$(SCRIPTSUFFIX); \ fi # Clean %.clean: - clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile javascript_clean diff --git a/Examples/test-suite/javascript/abstract_access_runme.js b/Examples/test-suite/javascript/abstract_access_runme.js index 356d07ea7..8f87d2105 100644 --- a/Examples/test-suite/javascript/abstract_access_runme.js +++ b/Examples/test-suite/javascript/abstract_access_runme.js @@ -1,5 +1,6 @@ +var abstract_access = require("./abstract_access"); + var d = new abstract_access.D() if (d.do_x() != 1) { throw "Error"; } - diff --git a/Examples/test-suite/javascript/abstract_typedef2_runme.js b/Examples/test-suite/javascript/abstract_typedef2_runme.js index 8adc2e05b..c177e49c3 100644 --- a/Examples/test-suite/javascript/abstract_typedef2_runme.js +++ b/Examples/test-suite/javascript/abstract_typedef2_runme.js @@ -1,3 +1,5 @@ +var abstract_typedef2 = require("./abstract_typedef2"); + var a = new abstract_typedef2.A_UF(); if (a == undefined) diff --git a/Examples/test-suite/javascript/abstract_typedef_runme.js b/Examples/test-suite/javascript/abstract_typedef_runme.js index 106baea65..abcfc581d 100644 --- a/Examples/test-suite/javascript/abstract_typedef_runme.js +++ b/Examples/test-suite/javascript/abstract_typedef_runme.js @@ -1,3 +1,5 @@ +var abstract_typedef = require("./abstract_typedef"); + var e = new abstract_typedef.Engine(); var a = new abstract_typedef.A() diff --git a/Examples/test-suite/javascript/abstract_virtual_runme.js b/Examples/test-suite/javascript/abstract_virtual_runme.js index c15abb5f6..9e2814e41 100644 --- a/Examples/test-suite/javascript/abstract_virtual_runme.js +++ b/Examples/test-suite/javascript/abstract_virtual_runme.js @@ -1,3 +1,5 @@ +var abstract_virtual = require("./abstract_virtual"); + d = new abstract_virtual.D() if (d == undefined) diff --git a/Examples/test-suite/javascript/array_member_runme.js b/Examples/test-suite/javascript/array_member_runme.js index dee4c2ca9..8c4ef1da5 100644 --- a/Examples/test-suite/javascript/array_member_runme.js +++ b/Examples/test-suite/javascript/array_member_runme.js @@ -1,3 +1,5 @@ +var array_member = require("./array_member"); + var f = new array_member.Foo(); f.data = array_member.global_data; diff --git a/Examples/test-suite/javascript/arrays_global_runme.js b/Examples/test-suite/javascript/arrays_global_runme.js index 9668826f3..fdb365f83 100644 --- a/Examples/test-suite/javascript/arrays_global_runme.js +++ b/Examples/test-suite/javascript/arrays_global_runme.js @@ -1,3 +1,5 @@ +var arrays_global = require("./arrays_global"); + arrays_global.array_i = arrays_global.array_const_i; arrays_global.BeginString_FIX44a; diff --git a/Examples/test-suite/javascript/char_binary_runme.js b/Examples/test-suite/javascript/char_binary_runme.js index 7cd09bd5c..42abe6060 100644 --- a/Examples/test-suite/javascript/char_binary_runme.js +++ b/Examples/test-suite/javascript/char_binary_runme.js @@ -1,3 +1,5 @@ +var char_binary = require("./char_binary"); + var t = new char_binary.Test(); if (t.strlen('hile') != 4) { print(t.strlen('hile')); diff --git a/Examples/test-suite/javascript/class_ignore_runme.js b/Examples/test-suite/javascript/class_ignore_runme.js index 00bb2591e..f0a32a1c4 100644 --- a/Examples/test-suite/javascript/class_ignore_runme.js +++ b/Examples/test-suite/javascript/class_ignore_runme.js @@ -1,3 +1,4 @@ +var class_ignore = require("./class_ignore"); a = new class_ignore.Bar(); diff --git a/Examples/test-suite/javascript/class_scope_weird_runme.js b/Examples/test-suite/javascript/class_scope_weird_runme.js index c442cc7f6..ac745d023 100644 --- a/Examples/test-suite/javascript/class_scope_weird_runme.js +++ b/Examples/test-suite/javascript/class_scope_weird_runme.js @@ -1,3 +1,4 @@ +var class_scope_weird = require("./class_scope_weird"); f = new class_scope_weird.Foo(); g = new class_scope_weird.Foo(3); diff --git a/Examples/test-suite/javascript/complextest_runme.js b/Examples/test-suite/javascript/complextest_runme.js index 9d3cf4264..1fcc97648 100644 --- a/Examples/test-suite/javascript/complextest_runme.js +++ b/Examples/test-suite/javascript/complextest_runme.js @@ -1,3 +1,4 @@ +var complextest = require("./complextest"); a = [-1,2]; diff --git a/Examples/test-suite/javascript/constover_runme.js b/Examples/test-suite/javascript/constover_runme.js index f131ef444..764d8b328 100644 --- a/Examples/test-suite/javascript/constover_runme.js +++ b/Examples/test-suite/javascript/constover_runme.js @@ -1,3 +1,5 @@ +var constover = require("./constover"); + p = constover.test("test"); if (p != "test") { throw "test failed!"; @@ -7,7 +9,7 @@ p = constover.test_pconst("test"); if (p != "test_pconst") { throw "test_pconst failed!"; } - + f = new constover.Foo(); p = f.test("test"); diff --git a/Examples/test-suite/javascript/constructor_copy_runme.js b/Examples/test-suite/javascript/constructor_copy_runme.js index 627b0936b..39dce52ce 100644 --- a/Examples/test-suite/javascript/constructor_copy_runme.js +++ b/Examples/test-suite/javascript/constructor_copy_runme.js @@ -1,3 +1,4 @@ +var constructor_copy = require("./constructor_copy"); f1 = new constructor_copy.Foo1(3); f11 = new constructor_copy.Foo1(f1); diff --git a/Examples/test-suite/javascript/cpp_enum_runme.js b/Examples/test-suite/javascript/cpp_enum_runme.js index f5a9e3595..35f7c60ac 100644 --- a/Examples/test-suite/javascript/cpp_enum_runme.js +++ b/Examples/test-suite/javascript/cpp_enum_runme.js @@ -1,3 +1,5 @@ +var cpp_enum = require("./cpp_enum"); + var f = new cpp_enum.Foo() if(f.hola != cpp_enum.Hello){ diff --git a/Examples/test-suite/javascript/cpp_namespace_runme.js b/Examples/test-suite/javascript/cpp_namespace_runme.js index 5795536bd..3bdfef3e9 100644 --- a/Examples/test-suite/javascript/cpp_namespace_runme.js +++ b/Examples/test-suite/javascript/cpp_namespace_runme.js @@ -1,3 +1,5 @@ +var cpp_namespace = require("./cpp_namespace"); + var n = cpp_namespace.fact(4); if (n != 24){ throw ("Bad return value error!"); @@ -16,7 +18,7 @@ if (cpp_namespace.do_method(t) != "Test::method"){ if (cpp_namespace.do_method2(t) != "Test::method"){ throw ("Bad return value error!"); -} +} cpp_namespace.weird("hello", 4); delete t; diff --git a/Examples/test-suite/javascript/cpp_static_runme.js b/Examples/test-suite/javascript/cpp_static_runme.js index 0ff28b4ee..2579aeafe 100644 --- a/Examples/test-suite/javascript/cpp_static_runme.js +++ b/Examples/test-suite/javascript/cpp_static_runme.js @@ -1,3 +1,5 @@ +var cpp_static = require("./cpp_static"); + cpp_static.StaticFunctionTest.static_func(); cpp_static.StaticFunctionTest.static_func_2(1); cpp_static.StaticFunctionTest.static_func_3(1,2); diff --git a/Examples/test-suite/javascript/director_alternating_runme.js b/Examples/test-suite/javascript/director_alternating_runme.js index 3c2c883a1..a0411eace 100644 --- a/Examples/test-suite/javascript/director_alternating_runme.js +++ b/Examples/test-suite/javascript/director_alternating_runme.js @@ -1,3 +1,4 @@ +var director_alternating = require("./director_alternating"); id = director_alternating.getBar().id(); if (id != director_alternating.idFromGetBar()) diff --git a/Examples/test-suite/javascript/enum_template_runme.js b/Examples/test-suite/javascript/enum_template_runme.js index 54195c78b..20f8c3482 100644 --- a/Examples/test-suite/javascript/enum_template_runme.js +++ b/Examples/test-suite/javascript/enum_template_runme.js @@ -1,6 +1,8 @@ +var enum_template = require("./enum_template"); + if (enum_template.MakeETest() != 1) throw "RuntimeError"; if (enum_template.TakeETest(0) != null) throw "RuntimeError"; - + diff --git a/Examples/test-suite/javascript/javascript_unicode_runme.js b/Examples/test-suite/javascript/javascript_unicode_runme.js index 4974ef40b..f5f747aa7 100644 --- a/Examples/test-suite/javascript/javascript_unicode_runme.js +++ b/Examples/test-suite/javascript/javascript_unicode_runme.js @@ -1,3 +1,5 @@ +var javascript_unicode = require("./javascript_unicode"); + var str = "olé"; var copy = javascript_unicode.copy_string(str); diff --git a/Examples/test-suite/javascript/namespace_virtual_method_runme.js b/Examples/test-suite/javascript/namespace_virtual_method_runme.js index bb187b993..24d3bd487 100644 --- a/Examples/test-suite/javascript/namespace_virtual_method_runme.js +++ b/Examples/test-suite/javascript/namespace_virtual_method_runme.js @@ -1,2 +1,3 @@ +var namespace_virtual_method = require("./namespace_virtual_method"); x = new namespace_virtual_method.Spam(); diff --git a/Examples/test-suite/javascript/overload_copy_runme.js b/Examples/test-suite/javascript/overload_copy_runme.js index 88fab3720..1039ffda1 100644 --- a/Examples/test-suite/javascript/overload_copy_runme.js +++ b/Examples/test-suite/javascript/overload_copy_runme.js @@ -1,3 +1,4 @@ +var overload_copy = require("./overload_copy"); f = new overload_copy.Foo(); g = new overload_copy.Foo(f); diff --git a/Examples/test-suite/javascript/preproc_include_runme.js b/Examples/test-suite/javascript/preproc_include_runme.js index d52ef97c1..4b827fbcc 100644 --- a/Examples/test-suite/javascript/preproc_include_runme.js +++ b/Examples/test-suite/javascript/preproc_include_runme.js @@ -1,3 +1,4 @@ +var preproc_include = require("./preproc_include"); if (preproc_include.multiply10(10) != 100) throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/preproc_runme.js b/Examples/test-suite/javascript/preproc_runme.js index b708385da..669f9d1f0 100644 --- a/Examples/test-suite/javascript/preproc_runme.js +++ b/Examples/test-suite/javascript/preproc_runme.js @@ -1,3 +1,4 @@ +var preproc = require("./preproc"); if (preproc.endif != 1) throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/ret_by_value_runme.js b/Examples/test-suite/javascript/ret_by_value_runme.js index 720cd398f..d9a77a20b 100644 --- a/Examples/test-suite/javascript/ret_by_value_runme.js +++ b/Examples/test-suite/javascript/ret_by_value_runme.js @@ -1,3 +1,4 @@ +var ret_by_value = require("./ret_by_value"); a = ret_by_value.get_test(); if (a.myInt != 100) diff --git a/Examples/test-suite/javascript/setup_test.sh b/Examples/test-suite/javascript/setup_test.sh new file mode 100644 index 000000000..03ce3bc90 --- /dev/null +++ b/Examples/test-suite/javascript/setup_test.sh @@ -0,0 +1,6 @@ +#!/bin/sh +if [ ! -d $1 ]; then + mkdir $1; +fi +echo "module.exports = require('./build/Release/$1')" > $1/index.js +echo "{\"targets\":[{\"target_name\": \"$1\",\"sources\":[\"$1_wrap.cxx\"]}]}" > $1/binding.gyp diff --git a/Examples/test-suite/javascript/struct_value_runme.js b/Examples/test-suite/javascript/struct_value_runme.js index 314551688..d6b26f726 100644 --- a/Examples/test-suite/javascript/struct_value_runme.js +++ b/Examples/test-suite/javascript/struct_value_runme.js @@ -1,10 +1,11 @@ +var struct_value = require("./struct_value"); b = new struct_value.Bar(); b.a.x = 3; -if (b.a.x != 3) +if (b.a.x != 3) throw "RuntimeError"; b.b.x = 3; -if (b.b.x != 3) +if (b.b.x != 3) throw "RuntimeError" diff --git a/Examples/test-suite/javascript/template_static_runme.js b/Examples/test-suite/javascript/template_static_runme.js index 338e2c55c..477d97249 100644 --- a/Examples/test-suite/javascript/template_static_runme.js +++ b/Examples/test-suite/javascript/template_static_runme.js @@ -1,2 +1,3 @@ +var template_static = require("./template_static"); template_static.Foo.bar_double(1); diff --git a/Examples/test-suite/javascript/typedef_class_runme.js b/Examples/test-suite/javascript/typedef_class_runme.js index accefb499..3e4dc9093 100644 --- a/Examples/test-suite/javascript/typedef_class_runme.js +++ b/Examples/test-suite/javascript/typedef_class_runme.js @@ -1,5 +1,7 @@ +var typedef_class = require("./typedef_class"); + a = new typedef_class.RealA(); -a.a = 3; - +a.a = 3; + b = new typedef_class.B(); -b.testA(a); +b.testA(a); diff --git a/Examples/test-suite/javascript/typedef_inherit_runme.js b/Examples/test-suite/javascript/typedef_inherit_runme.js index f16c1787e..4abcc2536 100644 --- a/Examples/test-suite/javascript/typedef_inherit_runme.js +++ b/Examples/test-suite/javascript/typedef_inherit_runme.js @@ -1,3 +1,4 @@ +var typedef_inherit = require("./typedef_inherit"); a = new typedef_inherit.Foo(); b = new typedef_inherit.Bar(); diff --git a/Examples/test-suite/javascript/typedef_scope_runme.js b/Examples/test-suite/javascript/typedef_scope_runme.js index 8a08ffb9b..0ac56884c 100644 --- a/Examples/test-suite/javascript/typedef_scope_runme.js +++ b/Examples/test-suite/javascript/typedef_scope_runme.js @@ -1,3 +1,4 @@ +var typedef_scope = require("./typedef_scope"); b = new typedef_scope.Bar(); x = b.test1(42,"hello"); @@ -7,5 +8,5 @@ if (x != 42) x = b.test2(42,"hello"); if (x != "hello") print("Failed!!"); - - + + diff --git a/Examples/test-suite/javascript/typemap_arrays_runme.js b/Examples/test-suite/javascript/typemap_arrays_runme.js index 2126ed15f..cd6827ac9 100644 --- a/Examples/test-suite/javascript/typemap_arrays_runme.js +++ b/Examples/test-suite/javascript/typemap_arrays_runme.js @@ -1,3 +1,4 @@ +var typemap_arrays = require("./typemap_arrays"); if (typemap_arrays.sumA(null) != 60) throw "RuntimeError, Sum is wrong"; diff --git a/Examples/test-suite/javascript/typemap_delete_runme.js b/Examples/test-suite/javascript/typemap_delete_runme.js index d58684df4..4b3174956 100644 --- a/Examples/test-suite/javascript/typemap_delete_runme.js +++ b/Examples/test-suite/javascript/typemap_delete_runme.js @@ -1,3 +1,4 @@ +var typemap_delete = require("./typemap_delete"); r = new typemap_delete.Rect(123); if (r.val != 123) diff --git a/Examples/test-suite/javascript/typemap_namespace_runme.js b/Examples/test-suite/javascript/typemap_namespace_runme.js index d679f3b0b..614e0ffeb 100644 --- a/Examples/test-suite/javascript/typemap_namespace_runme.js +++ b/Examples/test-suite/javascript/typemap_namespace_runme.js @@ -1,3 +1,4 @@ +var typemap_namespace = require("./typemap_namespace"); if (typemap_namespace.test1("hello") != "hello") throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/typemap_ns_using_runme.js b/Examples/test-suite/javascript/typemap_ns_using_runme.js index d05f7f0c1..9115c16ae 100644 --- a/Examples/test-suite/javascript/typemap_ns_using_runme.js +++ b/Examples/test-suite/javascript/typemap_ns_using_runme.js @@ -1,3 +1,4 @@ +var typemap_ns_using = require("./typemap_ns_using"); if (typemap_ns_using.spam(37) != 37) throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/using1_runme.js b/Examples/test-suite/javascript/using1_runme.js index cb54a62fa..a2e37fcb6 100644 --- a/Examples/test-suite/javascript/using1_runme.js +++ b/Examples/test-suite/javascript/using1_runme.js @@ -1,4 +1,4 @@ - +var using1 = require("./using1"); if (using1.spam(37) != 37) throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/using2_runme.js b/Examples/test-suite/javascript/using2_runme.js index 948f58ead..aa5e9b15f 100644 --- a/Examples/test-suite/javascript/using2_runme.js +++ b/Examples/test-suite/javascript/using2_runme.js @@ -1,3 +1,4 @@ +var using2 = require("./using2"); if (using2.spam(37) != 37) throw "RuntimeError"; From fa27ff29769031cef7dbb3b1951ec6adde09b0cf Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 17:03:08 +0200 Subject: [PATCH 159/352] Add a travis configuration (experimental). --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..7d848aa07 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +node_js: + -0.10.0 + +before_script: "./autogen.sh && ./configure.sh && make" +script: "make check-javascript-test-suite" From 0aabfeb231d74ac997b28e816987fb033d6b2fd9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 17:07:49 +0200 Subject: [PATCH 160/352] Slight modification to travis config. --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 7d848aa07..04ce3c8b9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,7 @@ node_js: -0.10.0 - +language: c +compiler: + - gcc before_script: "./autogen.sh && ./configure.sh && make" script: "make check-javascript-test-suite" From 83e6aa85b6e7f8097eb02179bb8f3faaeb06037b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 17:13:38 +0200 Subject: [PATCH 161/352] Not a real change. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 04ce3c8b9..d2df5ffa3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,5 +3,6 @@ node_js: language: c compiler: - gcc + before_script: "./autogen.sh && ./configure.sh && make" script: "make check-javascript-test-suite" From 262aca8ead684a53c4f2029db5f32a3505e348b3 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 17:16:40 +0200 Subject: [PATCH 162/352] Fix in travis config. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d2df5ffa3..37f81955e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,5 +4,5 @@ language: c compiler: - gcc -before_script: "./autogen.sh && ./configure.sh && make" +before_script: "./autogen.sh && ./configure && make" script: "make check-javascript-test-suite" From da48f3307f4ac358ca2d325f8c04b9a5afb90323 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 18:24:19 +0200 Subject: [PATCH 163/352] Remove javascript autoconf detection (Temporarily). I want to cut it down to a minimum having only nodejs. We will activate the others (native JSC and V8) later. --- configure.in | 213 --------------------------------------------------- 1 file changed, 213 deletions(-) diff --git a/configure.in b/configure.in index 0e00c958a..6ff3d5258 100644 --- a/configure.in +++ b/configure.in @@ -1089,207 +1089,6 @@ if test x"${with_javascript}" = xno -o x"${with_alllang}" = xno ; then JAVASCRIPT= fi -### JavascriptCore ### - -# check for include files -AC_MSG_CHECKING(for include file JavaScriptCore/JavaScript.h) -AC_ARG_WITH(javascriptincl, [ --with-javascript=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=]) - -if test -z "$JSCOREINCDIR"; then - JSCOREINCDIR="/usr/include/ /usr/local/include/" - - # Add in default directory for JavaScriptCore headers for Linux and MacOSX - case $host in - *-*-linux*) JSCOREINCDIR="/usr/include/webkit-1.0/ /usr/include/webkitgtk-1.0/ /usr/local/include/webkit-1.0/JavaScriptCore/ $JSCOREINCDIR";; - *-*-darwin*) JSCOREINCDIR="/System/Library/Frameworks/JavaScriptCore.framework/Headers/ $JSCOREINCDIR";; - *);; - esac -fi - -JSCORE=0 -for d in $JSCOREINCDIR ; do - if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then - AC_MSG_RESULT($d) - JSCOREINCDIR=$d - JSCOREINC=-I\"$d\" - JSCORE=1 - break - fi -done - -if test "$JSCOREINC" = "" ; then - AC_MSG_RESULT(not found) -fi - -# under linux look for the javascript core library -case $host in - *-*-linux*) - # check for JavaScriptCore, Webkit libraries - AC_ARG_WITH(jscorelib,[ --with-jscorelib =path Set location of JavaScriptCore (Webkit) library directory], [JSCORELIB="-L$withval"], [JSCORELIB=]) - AC_MSG_CHECKING(for JavaScriptCore(Webkit) library) - - if test -z "$JSCORELIB"; then - JSCORELIBDIRS="/usr/lib/ /usr/local/lib/" - for i in $JSCORELIBDIRS ; do - - if test -r $i/libwebkit-1.0.la; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -lwebkit-1.0" - break - fi - - if test -r $i/libjavascriptcoregtk-1.0.so; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -ljavascriptcoregtk-1.0" - break - fi - - if test -r $i/libwebkitgtk-1.0.so; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -lwebkitgtk-1.0" - break - fi - done - fi - - if test -z "$JSCORELIB"; then - AC_MSG_RESULT(not found) - JSCORE=0 - else - AC_MSG_RESULT($JSCORELIB) - JSCORE=1 - fi - ;; -esac - -# linking options -case $host in -*-*-darwin*) - JSCOREDYNAMICLINKING="-framework JavaScriptCore" - JSCORECFLAGS="" - ;; -*-*-linux*) - JSCOREDYNAMICLINKING="$JSCORELIB" - JSCORECFLAGS="" - ;; -*) - JSCOREDYNAMICLINKING="" - JSCORECFLAGS="" - ;; -esac - -# JSCORELIBRARYPREFIX -case $host in -*-*-cygwin* | *-*-mingw*) JSCORELIBRARYPREFIX="";; -*) JSCORELIBRARYPREFIX="lib";; -esac - -if test "$JS_NO_WARNINGS" == "1"; then - case $host in - *-*-darwin* | *-*-linux* | *-*-cygwin* | *-*-mingw*) - JSCXXFLAGS="`echo $CXXFLAGS | sed 's/-Wall//g'`" - ;; - *) - JSCXXFLAGS="$CXXFLAGS" - esac -fi - -# library output -case $host in -*-*-darwin*) - JSCORESO=".dylib" - JSCORELDSHARED='$(CC) -dynamiclib' - JSCORECXXSHARED='$(CXX) -dynamiclib' - ;; -*) - JSCORESO=$SO - JSCORELDSHARED='$(LDSHARED)' - JSCORECXXSHARED='$(CXXSHARED)' - ;; -esac - -AC_SUBST(JSCORE) -AC_SUBST(JSCOREINC) -AC_SUBST(JSCOREDYNAMICLINKING) -AC_SUBST(JSCORELIBRARYPREFIX) -AC_SUBST(JSCORECFLAGS) -AC_SUBST(JSCORESO) -AC_SUBST(JSCORELDSHARED) -AC_SUBST(JSCORECXXSHARED) -AC_SUBST(JSCXXFLAGS) - -### V8 ### - -# check for include files -AC_MSG_CHECKING(for include file v8.h) -AC_ARG_WITH(v8inc, [ --with-v8inc=path Set location of Javascript include directory], [JSV8INCDIR="$withval"]) - -if test -z "$JSV8INCDIR"; then - # Add in default directory for JavaScriptCore headers for Linux and MacOSX - case $host in - *-*-linux*) JSV8INCDIR="/usr/include /usr/local/include/ $JSV8INCDIR";; - *-*-darwin*) JSV8INCDIR="$JSV8INCDIR";; #TODO: add configuration for osx - *);; - esac -fi - -for d in $JSV8INCDIR ; do - if test -r "$d/v8.h" ; then - AC_MSG_RESULT($d) - JSV8INCDIR=$d - JSV8INC=-I\"$d\" - break - fi -done - -if test "$JSV8INC" = "" ; then - AC_MSG_RESULT(not found) - JSV8= -else - JSV8=1 -fi - - -# check for V8 library -AC_MSG_CHECKING(for v8 library) -AC_ARG_WITH(v8lib,[ --with-v8lib=path Set location of V8 library directory],[JSV8LIBDIR="$withval"], [JSV8LIB=]) - -v8libdirs="$JSV8LIBDIR /usr/lib/ /usr/local/lib/" -for i in $v8libdirs ; do - if test -r $i/libv8.so; then - JSV8LIB="-L$i -lv8" - break - fi -done - -if test "$JSV8LIB" = "" ; then - AC_MSG_RESULT(not found) - JSV8= -else - AC_MSG_RESULT($JSV8LIB) - JSV8=1 -fi - - -# linking options -case $host in -*-*-darwin*) - JSV8DYNAMICLINKING="" # TODO: add osx configuration - ;; -*-*-linux*) - JSV8DYNAMICLINKING="$JSV8LIB" - ;; -*) - JSV8DYNAMICLINKING="" - ;; -esac - -AC_SUBST(JSV8) -AC_SUBST(JSV8INC) -AC_SUBST(JSV8DYNAMICLINKING) - -AC_SUBST(JSDEFAULT) - #---------------------------------------------------------------- # Look for gcj #---------------------------------------------------------------- @@ -2451,18 +2250,6 @@ fi AC_SUBST(SKIP_JAVA) SKIP_JAVASCRIPT= -if test -z "$JSCOREINC" && test -z "$JSV8INC"; then - # Add in default directory for JavaScriptCore headers for Linux and MacOSX - case $host in - *-*-linux*) if test -z "$JSCORELIB" && test -z "$JSV8LIB"; then - SKIP_JAVASCRIPT="1" - fi - ;; - *-*-darwin*)SKIP_JAVASCRIPT="1" - ;; - *);; - esac -fi AC_SUBST(SKIP_JAVASCRIPT) SKIP_GUILE= From 0e78fc0ad7a962f2d3687c1fb32294e174e68dd5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 3 Sep 2013 18:50:46 +0200 Subject: [PATCH 164/352] Fixing travis configuration. --- .travis.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 37f81955e..f57e81319 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,12 @@ -node_js: - -0.10.0 language: c compiler: - gcc - -before_script: "./autogen.sh && ./configure && make" +node_js: + -0.10.12 +before_script: + - "sudo add-apt-repository -y ppa:chris-lea/node.js" + - "sudo apt-get update" + - "sudo apt-get install -y nodejs" + - "sudo npm install -g node-gyp" + - "./autogen.sh && ./configure && make" script: "make check-javascript-test-suite" From 8778146b4b45d5033bb65701ab881b1edcc51b9b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 4 Sep 2013 12:10:08 +0200 Subject: [PATCH 165/352] Relax type check in SWIG_AsVal_int. The array_member test-case revealed that integers come in as `Numbers`. --- Examples/test-suite/javascript/Makefile.in | 2 +- Lib/javascript/v8/javascriptprimitives.swg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index edc621c7e..42e3d6b45 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -23,6 +23,7 @@ CPP_TEST_CASES = \ abstract_typedef2 \ abstract_virtual \ arrays_global \ + array_member \ char_binary \ class_ignore \ class_scope_weird \ @@ -49,7 +50,6 @@ CPP_TEST_CASES = \ javascript_unicode BROKEN_TEST_CASES = \ - array_member \ complextest \ constructor_copy \ preproc_include diff --git a/Lib/javascript/v8/javascriptprimitives.swg b/Lib/javascript/v8/javascriptprimitives.swg index bd0295478..f34bbb75a 100644 --- a/Lib/javascript/v8/javascriptprimitives.swg +++ b/Lib/javascript/v8/javascriptprimitives.swg @@ -33,7 +33,7 @@ v8::Handle SWIG_From_dec(int)(int value) SWIGINTERN int SWIG_AsVal_dec(int)(v8::Handle valRef, int* val) { - if (!valRef->IsInt32()) { + if (!valRef->IsNumber()) { return SWIG_TypeError; } if(val) *val = valRef->IntegerValue(); From 54dd7e96c0f9623649947f8f6237a8f1be1ac770 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 4 Sep 2013 12:47:24 +0200 Subject: [PATCH 166/352] Fix cleanup configuration for javascript test-suite. --- Examples/test-suite/javascript/Makefile.in | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 42e3d6b45..058a06f99 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -91,7 +91,11 @@ generate_cpp_wrapper = \ $(SWIG) -c++ -javascript -node -o $*/$*_wrap.cxx ../$*.i build_module = \ - cd $* && node-gyp configure build && cd .. + if [ ! -f $(srcdir)/$*/build/Makefile ]; then \ + cd $* && node-gyp configure build && cd ..; \ + else \ + cd $* && node-gyp build && cd ..; \ + fi # Runs the testcase. A testcase is only run if # a file is found which has _runme.js appended after the testcase name. @@ -102,6 +106,6 @@ run_testcase = \ # Clean %.clean: + rm -rf $* clean: - $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile javascript_clean From fec11a8def1e1bea9626fab8f17d05c253178bec Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 4 Sep 2013 13:07:07 +0200 Subject: [PATCH 167/352] Allow exceptions in generated example/test node extensions. --- Examples/test-suite/javascript/Makefile.in | 4 ++-- Examples/test-suite/javascript/setup_test.sh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 058a06f99..f0810a167 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -27,7 +27,9 @@ CPP_TEST_CASES = \ char_binary \ class_ignore \ class_scope_weird \ + complextest \ constover \ + constructor_copy \ cpp_enum \ cpp_namespace \ cpp_static \ @@ -50,8 +52,6 @@ CPP_TEST_CASES = \ javascript_unicode BROKEN_TEST_CASES = \ - complextest \ - constructor_copy \ preproc_include SKIP_CPP_CASES = @SKIP_CPP_CASES@ diff --git a/Examples/test-suite/javascript/setup_test.sh b/Examples/test-suite/javascript/setup_test.sh index 03ce3bc90..3f45d814a 100644 --- a/Examples/test-suite/javascript/setup_test.sh +++ b/Examples/test-suite/javascript/setup_test.sh @@ -2,5 +2,5 @@ if [ ! -d $1 ]; then mkdir $1; fi -echo "module.exports = require('./build/Release/$1')" > $1/index.js -echo "{\"targets\":[{\"target_name\": \"$1\",\"sources\":[\"$1_wrap.cxx\"]}]}" > $1/binding.gyp +sed s/\$testcase/$1/ node_template/binding.gyp.in > $1/binding.gyp +sed s/\$testcase/$1/ node_template/index.js.in > $1/index.js From b7db2a84c907b96e3371b8c8301b32421a10fef5 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Wed, 4 Sep 2013 19:33:48 +0400 Subject: [PATCH 168/352] fixed return values and added missing newer v8 dtor wrapper. --- Lib/javascript/v8/javascriptcode.swg | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 068632380..89d011e3d 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -18,8 +18,8 @@ typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; typedef void SwigV8ReturnValue; typedef v8::FunctionCallbackInfo SwigV8Arguments; typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; -#define SWIGV8_RETURN(val) return args.GetReturnValue().Set(val) -#define SWIGV8_RETURN_INFO(val, info) return args.GetReturnValue().Set(val) +#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return +#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return #endif %} @@ -171,16 +171,25 @@ void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWI * ----------------------------------------------------------------------------- */ %fragment ("js_dtoroverride", "templates") %{ -void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) { - SWIGV8_Proxy* proxy = (SWIGV8_Proxy*) parameter; +#if (SWIG_V8_VERSION < 0x031900) +void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) +{ + SWIGV8_Proxy *proxy = static_cast(parameter); +#else +void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) +{ +#endif if(proxy->swigCMemOwn && proxy->swigCObject) { $jstype arg1 = ($jstype)proxy->swigCObject; ${destructor_action} } delete proxy; - object.Clear(); +#if (SWIG_V8_VERSION < 0x031900) object.Dispose(); +#else + object->Dispose(isolate); +#endif } %} @@ -214,7 +223,7 @@ fail: %fragment("js_setter", "templates") %{ void $jswrapper(v8::Local property, v8::Local value, - const SwigV8PropertyCallbackInfo& info) { + const SwigV8PropertyCallbackInfoVoid& info) { v8::HandleScope scope; $jslocals $jscode From 4068f31c6b66f08c24f760f46da5b4a4d7b6f11b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 4 Sep 2013 17:54:35 +0200 Subject: [PATCH 169/352] Use a diffent name for the V8_VERSION provided via command line. --- Lib/javascript/v8/javascriptruntime.swg | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 139a5a3ee..5acd04de9 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -12,11 +12,11 @@ %} %enddef -#ifdef SWIG_V8_VERSION -%swig_v8_define_version(SWIG_V8_VERSION) +#ifdef V8_VERSION +%swig_v8_define_version(V8_VERSION) #else // HACK: defining a default version -%swig_v8_define_version(SWIG_V8_VERSION) +%swig_v8_define_version(0x031110) #endif #ifdef BUILDING_NODE_EXTENSION From 315287b6563f4730468e4b882e569fa72893ba71 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 4 Sep 2013 17:55:44 +0200 Subject: [PATCH 170/352] Put the SWIG_V8_VERSION macro into "runtime" block. --- Lib/javascript/v8/javascriptruntime.swg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 5acd04de9..f998b729b 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -5,7 +5,7 @@ * ----------------------------------------------------------------------------- */ %define %swig_v8_define_version(version) -%begin %{ +%insert("runtime") %{ #ifndef SWIG_V8_VERSION #define SWIG_V8_VERSION version #endif From 8b0ee5491a9f19a57fef83433d755cc0a9e40c40 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 4 Sep 2013 18:04:40 +0200 Subject: [PATCH 171/352] Added missing template configuration files for nodejs based tests. --- .../javascript/node_template/binding.gyp.in | 25 +++++++++++++++++++ .../javascript/node_template/index.js.in | 1 + 2 files changed, 26 insertions(+) create mode 100644 Examples/test-suite/javascript/node_template/binding.gyp.in create mode 100644 Examples/test-suite/javascript/node_template/index.js.in diff --git a/Examples/test-suite/javascript/node_template/binding.gyp.in b/Examples/test-suite/javascript/node_template/binding.gyp.in new file mode 100644 index 000000000..2895d3080 --- /dev/null +++ b/Examples/test-suite/javascript/node_template/binding.gyp.in @@ -0,0 +1,25 @@ +{ + "targets": [ + { + "target_name": "$testcase", + "sources":[ "$testcase_wrap.cxx" ], + "include_dirs": ["../.."], + 'conditions': [ + ['OS=="mac"', + { + 'xcode_settings': { + 'GCC_ENABLE_CPP_RTTI': 'YES', + 'GCC_ENABLE_CPP_EXCEPTIONS' : 'YES' + } + } + ], + ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', + { + 'cflags!': [ '-fno-exceptions' ], + 'cflags_cc!': [ '-fno-exceptions', '-fno-rtti' ] + } + ] + ], + } + ], +} diff --git a/Examples/test-suite/javascript/node_template/index.js.in b/Examples/test-suite/javascript/node_template/index.js.in new file mode 100644 index 000000000..72330499d --- /dev/null +++ b/Examples/test-suite/javascript/node_template/index.js.in @@ -0,0 +1 @@ +module.exports = require('./build/Release/$testcase'); From 2a39abebb684e7e5a2bf878b9d74c54de415bae1 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Wed, 4 Sep 2013 20:10:42 +0400 Subject: [PATCH 172/352] moved common swig v8 definitions in javascriptruntime.swg, fixed obsoleted api calls --- Lib/javascript/v8/javascriptcode.swg | 16 ------------- Lib/javascript/v8/javascriptruntime.swg | 32 +++++++++++++++++++++---- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 89d011e3d..4277e8b0c 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -7,22 +7,6 @@ * - $jsmangledtype: mangled type of class * ----------------------------------------------------------------------------- */ -%insert(runtime) %{ -#if (SWIG_V8_VERSION < 0x031900) -typedef v8::Handle SwigV8ReturnValue; -typedef v8::Arguments SwigV8Arguments; -typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; -#define SWIGV8_RETURN(val) return scope.Close(val) -#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) -#else -typedef void SwigV8ReturnValue; -typedef v8::FunctionCallbackInfo SwigV8Arguments; -typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; -#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return -#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return -#endif -%} - %fragment("js_ctor", "templates") %{ SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { v8::HandleScope scope; diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 139a5a3ee..5febe07bf 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -35,6 +35,22 @@ %insert(runtime) "swigrun.swg"; /* SWIG API */ %insert(runtime) "swigerrors.swg"; /* SWIG errors */ +%insert(runtime) %{ +#if (SWIG_V8_VERSION < 0x031900) +typedef v8::Handle SwigV8ReturnValue; +typedef v8::Arguments SwigV8Arguments; +typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) return scope.Close(val) +#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) +#else +typedef void SwigV8ReturnValue; +typedef v8::FunctionCallbackInfo SwigV8Arguments; +typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return +#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return +#endif +%} + %insert(runtime) %{ #define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) #define SWIG_exception(code, msg) SWIGV8_ErrorHandler.error(code, msg) @@ -274,7 +290,11 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in #define SWIG_GetInstancePtr(obj, ptr) SWIG_V8_GetInstancePtr(obj, ptr) +#if (SWIG_V8_VERSION < 0x031900) v8::Handle _wrap_equals(const v8::Arguments &args) { +#else +void _wrap_equals(const v8::FunctionCallbackInfo& args) { +#endif v8::HandleScope scope; v8::Handle jsresult; void *arg1 = (void *) 0 ; @@ -297,13 +317,17 @@ v8::Handle _wrap_equals(const v8::Arguments &args) { result = (bool)(arg1 == arg2); jsresult = v8::Boolean::New(result); - return scope.Close(jsresult); + SWIGV8_RETURN(jsresult); goto fail; fail: - return scope.Close(v8::Undefined()); + SWIGV8_RETURN(v8::Undefined()); } +#if (SWIG_V8_VERSION < 0x031900) v8::Handle _wrap_getCPtr(const v8::Arguments &args) { +#else +void _wrap_getCPtr(const v8::FunctionCallbackInfo& args) { +#endif v8::HandleScope scope; v8::Handle jsresult; void *arg1 = (void *) 0 ; @@ -318,9 +342,9 @@ v8::Handle _wrap_getCPtr(const v8::Arguments &args) { result = (long)arg1; jsresult = v8::Number::New(result); - return scope.Close(jsresult); + SWIGV8_RETURN(jsresult); goto fail; fail: - return scope.Close(v8::Undefined()); + SWIGV8_RETURN(v8::Undefined()); } %} From b49da78b0a6ef1d6e9f624c60710f79e709fca2e Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Thu, 5 Sep 2013 19:50:15 +0400 Subject: [PATCH 173/352] fixed deprecation warnings for v8-3.21 --- Lib/javascript/v8/javascriptcode.swg | 8 ++++++-- Lib/javascript/v8/javascriptruntime.swg | 10 ++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 4277e8b0c..ac322ab42 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -141,8 +141,10 @@ void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWI object.Clear(); #if (SWIG_V8_VERSION < 0x031900) object.Dispose(); -#else +#elif (SWIG_V8_VERSION < 0x032100) object->Dispose(isolate); +#else + object->Dispose(); #endif } %} @@ -171,8 +173,10 @@ void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWI #if (SWIG_V8_VERSION < 0x031900) object.Dispose(); -#else +#elif (SWIG_V8_VERSION < 0x032100) object->Dispose(isolate); +#else + object->Dispose(); #endif } %} diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index ab52aa815..31ce84a04 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -110,7 +110,7 @@ public: }; ~SWIGV8_Proxy() { -#if (SWIG_V8_VERSION < 0x031900) +#if (SWIG_V8_VERSION < 0x031900 || SWIG_V8_VERSION >= 0x032100) handle.ClearWeak(); handle.Dispose(); #else @@ -238,7 +238,13 @@ void SWIGV8_SetPrivateData(v8::Handle obj, void* ptr, swig_type_info } else { cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor); } - cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); + +# if (SWIG_V8_VERSION < 0x032100) + cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); +# else + cdata->handle.MarkIndependent(); +# endif + #endif } From 4794fa1884215982384535d25bfcc8e37b496629 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 6 Sep 2013 00:38:07 +0300 Subject: [PATCH 174/352] Refactored custom javascript engines to support primitive 'require' statements. --- Tools/javascript/javascript.cxx | 24 +----- Tools/javascript/js_shell.cxx | 47 +++++++---- Tools/javascript/js_shell.h | 7 +- Tools/javascript/jsc_shell.cxx | 134 +++++++++++++++++++++++--------- Tools/javascript/v8_shell.cxx | 122 ++++++++++++++++------------- 5 files changed, 203 insertions(+), 131 deletions(-) diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx index 82e94f434..ec4ac4e3f 100644 --- a/Tools/javascript/javascript.cxx +++ b/Tools/javascript/javascript.cxx @@ -14,21 +14,12 @@ void print_usage() { int main(int argc, char* argv[]) { std::string scriptPath = ""; - std::vector module_names; bool interactive = false; JSShell* shell = 0; for (int idx = 1; idx < argc; ++idx) { - if(strcmp(argv[idx], "-l") == 0) { - idx++; - if(idx > argc) { - print_usage(); - exit(-1); - } - std::string module_name(argv[idx]); - module_names.push_back(module_name); - } else if(strcmp(argv[idx], "-v8") == 0) { + if(strcmp(argv[idx], "-v8") == 0) { shell = JSShell::Create(JSShell::V8); } else if(strcmp(argv[idx], "-jsc") == 0) { shell = JSShell::Create(JSShell::JSC); @@ -44,19 +35,6 @@ int main(int argc, char* argv[]) { } bool failed = false; - for(std::vector::iterator it = module_names.begin(); - it != module_names.end(); ++it) { - std::string module_name = *it; - - bool success = shell->ImportModule(module_name); - failed |= !success; - } - - if (failed) { - delete shell; - printf("FAIL: Some modules could not be loaded.\n"); - return -1; - } if(interactive) { failed = !(shell->RunShell()); diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx index fa5500f8e..ca5ca7ecd 100644 --- a/Tools/javascript/js_shell.cxx +++ b/Tools/javascript/js_shell.cxx @@ -21,7 +21,6 @@ #endif - JSShell::~JSShell() { for(std::vector::iterator it = loaded_modules.begin(); @@ -32,32 +31,46 @@ JSShell::~JSShell() { } -bool JSShell::ImportModule(const std::string& name) { +// TODO: this could be done more intelligent... +// - can we achieve source file relative loading? +// - better path resolution +std::string JSShell::LoadModule(const std::string& name, HANDLE* library) { - std::string lib_name = LIBRARYFILE(name); + // works only for posix like OSs + size_t pathIdx = name.find_last_of("/"); - HANDLE handle = LOAD_LIBRARY(lib_name.c_str()); - if(handle == 0) { - std::cout << "Could not load library " << lib_name << ":" - << std::endl << LIBRARY_ERROR() << std::endl; - return false; - } + std::string lib_name; + std::string module_name; + if (pathIdx == std::string::npos) { + module_name = name; + lib_name = std::string(name).append(LIBRARY_EXT); + } else { + std::string path = name.substr(0, pathIdx+1); + module_name = name.substr(pathIdx+1); + lib_name = path.append(module_name).append(LIBRARY_EXT); + } - if(!RegisterModule(handle, name)) { - std::cout << "Could not find initializer function in " << lib_name << std::endl; - CLOSE_LIBRARY(handle); - return false; - } + HANDLE handle = LOAD_LIBRARY(lib_name.c_str()); + if(handle == 0) { + std::cout << "Could not load library " << lib_name << ":" + << std::endl << LIBRARY_ERROR() << std::endl; + return 0; + } - loaded_modules.push_back(handle); + loaded_modules.push_back(handle); - return true; + *library = handle; + + return module_name; } bool JSShell::RunScript(const std::string& scriptPath) { std::string source = ReadFile(scriptPath); if(!InitializeEngine()) return false; + // Node.js compatibility: make `print` available as `console.log()` + ExecuteScript("var console = {}; console.log = print;", ""); + if(!ExecuteScript(source, scriptPath)) { return false; } @@ -126,7 +139,7 @@ V8Shell_Create, JSShell *JSShell::Create(Engine engine) { if(js_shell_factories[engine] == 0) { - throw "Engine not supported."; + throw "Engine not available."; } return js_shell_factories[engine](); } diff --git a/Tools/javascript/js_shell.h b/Tools/javascript/js_shell.h index 54f55b69d..84a8534d6 100644 --- a/Tools/javascript/js_shell.h +++ b/Tools/javascript/js_shell.h @@ -5,6 +5,7 @@ #include typedef void* HANDLE; +typedef void* MODULE; class JSShell { @@ -22,7 +23,7 @@ public: static JSShell* Create(Engine engine = JSC); - bool ImportModule(const std::string& name); + std::string LoadModule(const std::string& name, HANDLE* library); virtual bool RunScript(const std::string& scriptPath); @@ -30,11 +31,9 @@ public: protected: - virtual bool RegisterModule(HANDLE library, const std::string& module_name) = 0; - virtual bool InitializeEngine() = 0; - virtual bool ExecuteScript(const std::string& source, const std::string& name) = 0; + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath) = 0; virtual bool DisposeEngine() = 0; diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx index ee95e04a5..e4e8cdd96 100644 --- a/Tools/javascript/jsc_shell.cxx +++ b/Tools/javascript/jsc_shell.cxx @@ -14,7 +14,7 @@ class JSCShell: public JSShell { -typedef int (*JSCIntializer)(JSGlobalContextRef context); +typedef int (*JSCIntializer)(JSGlobalContextRef context, JSObjectRef *module); public: @@ -24,26 +24,26 @@ public: protected: - virtual bool RegisterModule(HANDLE library, const std::string& module_name); - virtual bool InitializeEngine(); - virtual bool ExecuteScript(const std::string& source, const std::string& name); + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath); virtual bool DisposeEngine(); private: - static JSValueRef Print(JSContextRef context,JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + JSObjectRef Import(const std::string &moduleName); + + static JSValueRef Print(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + + static JSValueRef Require(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); static bool RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback cbFunction); - static void PrintError(JSContextRef, JSValueRef, const std::string&); + static void PrintError(JSContextRef, JSValueRef); private: - std::vector module_initializers; - JSGlobalContextRef context; }; @@ -54,16 +54,6 @@ JSCShell::~JSCShell() { } } -bool JSCShell::RegisterModule(HANDLE library, const std::string& module_name) { - std::string symname = std::string(module_name).append("_initialize"); - - JSCIntializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); - if(init_function == 0) return false; - - module_initializers.push_back(init_function); - return true; -} - bool JSCShell::InitializeEngine() { if(context != 0) { JSGlobalContextRelease(context); @@ -73,26 +63,33 @@ bool JSCShell::InitializeEngine() { context = JSGlobalContextCreate(NULL); if(context == 0) return false; JSObjectRef globalObject = JSContextGetGlobalObject(context); + + + // store this for later use + JSClassDefinition __shell_classdef__; + JSClassRef __shell_class__ = JSClassCreate(&__shell_classdef__); + JSObjectRef __shell__ = JSObjectMake(context, __shell_class__, 0); + bool success = JSObjectSetPrivate(__shell__, (void*) (long) this); + JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__"); + JSObjectSetProperty(context, globalObject, shellKey, __shell__, kJSPropertyAttributeReadOnly, NULL); + JSStringRelease(shellKey); + JSCShell::RegisterFunction(context, globalObject, "print", JSCShell::Print); - // Call module initializers - for(std::vector::iterator it = module_initializers.begin(); - it != module_initializers.end(); ++it) { - JSCIntializer init_function = *it; - if(!init_function(context)) { - return false; - } - } + JSCShell::RegisterFunction(context, globalObject, "require", JSCShell::Require); + return true; } -bool JSCShell::ExecuteScript(const std::string& source, const std::string& name) { +bool JSCShell::ExecuteScript(const std::string& source, const std::string& scriptPath) { JSStringRef jsScript; + JSStringRef sourceURL; JSValueRef ex; jsScript = JSStringCreateWithUTF8CString(source.c_str()); - JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + sourceURL = JSStringCreateWithUTF8CString(scriptPath.c_str()); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, sourceURL, 0, &ex); JSStringRelease(jsScript); if (jsResult == NULL && ex != NULL) { - JSCShell::PrintError(context, ex, name); + JSCShell::PrintError(context, ex); return false; } return true; @@ -121,6 +118,65 @@ JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object, return JSValueMakeUndefined(context); } +// Attention: this feature should not create too high expectations. +// It is only capable of loading things relative to the execution directory +// and not relative to the parent script. +JSValueRef JSCShell::Require(JSContextRef context, JSObjectRef object, + JSObjectRef globalObj, size_t argc, + const JSValueRef args[], JSValueRef* ex) { + JSObjectRef module; + + JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__"); + JSValueRef shellAsVal = JSObjectGetProperty(context, globalObj, shellKey, NULL); + JSStringRelease(shellKey); + JSObjectRef shell = JSValueToObject(context, shellAsVal, 0); + JSCShell *_this = (JSCShell*) (long) JSObjectGetPrivate(shell); + + if (argc > 0) + { + JSStringRef string = JSValueToStringCopy(context, args[0], NULL); + size_t numChars = JSStringGetMaximumUTF8CStringSize(string); + char *stringUTF8 = new char[numChars]; + JSStringGetUTF8CString(string, stringUTF8, numChars); + + std::string modulePath(stringUTF8); + module = _this->Import(modulePath); + + delete[] stringUTF8; + } + + if (module) { + return module; + } else { + printf("Ooops.\n"); + return JSValueMakeUndefined(context); + } +} + +JSObjectRef JSCShell::Import(const std::string& module_path) { + + HANDLE library; + std::string module_name = LoadModule(module_path, &library); + + if (library == 0) { + printf("Could not load module."); + return 0; + } + + std::string symname = std::string(module_name).append("_initialize"); + + JSCIntializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); + if(init_function == 0) { + printf("Could not find module's initializer function."); + return 0; + } + + JSObjectRef module; + init_function(context, &module); + + return module; +} + bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) { JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); @@ -131,12 +187,12 @@ bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object, return true; } -void JSCShell::PrintError(JSContextRef ctx, JSValueRef err, const std::string& name) { +void JSCShell::PrintError(JSContextRef ctx, JSValueRef err) { char *buffer; + size_t length; JSStringRef string = JSValueToStringCopy(ctx, err, 0); - size_t length = JSStringGetLength(string); - + length = JSStringGetLength(string); buffer = new char[length+1]; JSStringGetUTF8CString(string, buffer, length+1); std::string errMsg(buffer); @@ -150,14 +206,22 @@ void JSCShell::PrintError(JSContextRef ctx, JSValueRef err, const std::string& n return; } - // Note: usually you would also retrieve the property "sourceURL" - // though, it happened that this was always "" + JSStringRef sourceURLKey = JSStringCreateWithUTF8CString("sourceURL"); + JSStringRef sourceURLStr = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, errObj, sourceURLKey, 0), 0); + length = JSStringGetLength(sourceURLStr); + buffer = new char[length+1]; + JSStringGetUTF8CString(sourceURLStr, buffer, length+1); + std::string sourceURL(buffer); + delete[] buffer; + JSStringRelease(sourceURLStr); + JSStringRelease(sourceURLKey); + JSStringRef lineKey = JSStringCreateWithUTF8CString("line"); JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0); int line = (int) JSValueToNumber(ctx, jsLine, 0); JSStringRelease(lineKey); - std::cerr << name << ":" << line << ":" << errMsg << std::endl; + std::cerr << sourceURL << ":" << line << ":" << errMsg << std::endl; } JSShell* JSCShell_Create() { diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index e2ab1541d..8a571e0f1 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -9,7 +9,7 @@ #include "js_shell.h" -typedef int (*V8ExtensionRegistrar) (v8::Handle); +typedef int (*V8ExtensionInitializer) (v8::Handle module); class V8Shell: public JSShell { @@ -25,36 +25,33 @@ public: protected: - virtual bool RegisterModule(HANDLE library, const std::string& module_name); - virtual bool InitializeEngine(); - virtual bool ExecuteScript(const std::string& source, const std::string& name); + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath); virtual bool DisposeEngine(); private: + v8::Handle Import(const std::string& moduleName); + v8::Persistent CreateShellContext(); void ReportException(v8::TryCatch* handler); static v8::Handle Print(const v8::Arguments& args); + static v8::Handle Require(const v8::Arguments& args); + static v8::Handle Quit(const v8::Arguments& args); static v8::Handle Version(const v8::Arguments& args); static const char* ToCString(const v8::String::Utf8Value& value); - void ExtendEngine(); - protected: - std::vector module_initializers; - v8::Persistent context; - }; #ifdef __GNUC__ @@ -73,16 +70,6 @@ V8Shell::~V8Shell() { v8::V8::Dispose(); } -bool V8Shell::RegisterModule(HANDLE library, const std::string& module_name) { - std::string symname = std::string(module_name).append("_initialize"); - - V8ExtensionRegistrar init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); - if(init_function == 0) return false; - - module_initializers.push_back(init_function); - return true; -} - bool V8Shell::RunScript(const std::string& scriptPath) { if (!context.IsEmpty()) { @@ -97,9 +84,16 @@ bool V8Shell::RunScript(const std::string& scriptPath) { return false; } context->Enter(); + //v8::Context::Scope context_scope(context); + v8::HandleScope scope; - v8::Context::Scope context_scope(context); - ExtendEngine(); + // Store a pointer to this shell for later use + v8::Handle global = context->Global(); + v8::Local __shell__ = v8::External::New((void*) (long) this); + global->SetHiddenValue(v8::String::New("__shell__"), __shell__); + + // Node.js compatibility: make `print` available as `console.log()` + ExecuteScript("var console = {}; console.log = print;", ""); if(!ExecuteScript(source, scriptPath)) { return false; @@ -127,7 +121,8 @@ bool V8Shell::RunShell() { context->Enter(); v8::Context::Scope context_scope(context); - ExtendEngine(); + + ExecuteScript("var console = {}; console.log = print;", ""); static const int kBufferSize = 1024; while (true) { @@ -152,45 +147,26 @@ bool V8Shell::InitializeEngine() { return true; } -void V8Shell::ExtendEngine() { - - v8::HandleScope scope; - v8::Local global = context->Global(); - - // register extensions - for(std::vector::iterator it=module_initializers.begin(); - it != module_initializers.end(); ++it) { - (*it)(global); - } - -} - bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) { v8::HandleScope handle_scope; v8::TryCatch try_catch; v8::Handle script = v8::Script::Compile(v8::String::New(source.c_str()), v8::String::New(name.c_str())); + + // Stop if script is empty if (script.IsEmpty()) { // Print errors that happened during compilation. ReportException(&try_catch); return false; + } + + v8::Handle result = script->Run(); + + // Print errors that happened during execution. + if (try_catch.HasCaught()) { + ReportException(&try_catch); + return false; } else { - v8::Handle result = script->Run(); - if (result.IsEmpty()) { - assert(try_catch.HasCaught()); - // Print errors that happened during execution. - ReportException(&try_catch); - return false; - } else { - assert(!try_catch.HasCaught()); - if (!result->IsUndefined()) { - // If all went well and the result wasn't undefined then print - // the returned value. - //v8::String::Utf8Value str(result); - //const char* cstr = V8Shell::ToCString(str); - //printf("%s\n", cstr); - } - return true; - } + return true; } } @@ -207,6 +183,7 @@ v8::Persistent V8Shell::CreateShellContext() { // Bind global functions global->Set(v8::String::New("print"), v8::FunctionTemplate::New(V8Shell::Print)); global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(V8Shell::Quit)); + global->Set(v8::String::New("require"), v8::FunctionTemplate::New(V8Shell::Require)); global->Set(v8::String::New("version"), v8::FunctionTemplate::New(V8Shell::Version)); v8::Persistent _context = v8::Context::New(NULL, global); @@ -214,6 +191,26 @@ v8::Persistent V8Shell::CreateShellContext() { return _context; } +v8::Handle V8Shell::Import(const std::string& module_path) +{ + v8::HandleScope scope; + + HANDLE library; + std::string module_name = LoadModule(module_path, &library); + + std::string symname = std::string(module_name).append("_initialize"); + + V8ExtensionInitializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); + + if(init_function == 0) { + printf("Could not find initializer function."); + return v8::Undefined(); + } + + v8::Local module = v8::Object::New(); + init_function(module); + return scope.Close(module); +} v8::Handle V8Shell::Print(const v8::Arguments& args) { bool first = true; @@ -233,6 +230,27 @@ v8::Handle V8Shell::Print(const v8::Arguments& args) { return v8::Undefined(); } +v8::Handle V8Shell::Require(const v8::Arguments& args) { + v8::HandleScope scope; + + if (args.Length() != 1) { + printf("Illegal arguments for `require`"); + }; + + v8::String::Utf8Value str(args[0]); + const char* cstr = V8Shell::ToCString(str); + std::string moduleName(cstr); + + v8::Local global = v8::Context::GetCurrent()->Global(); + v8::Local hidden = global->GetHiddenValue(v8::String::New("__shell__")); + v8::Local __shell__ = v8::Local::Cast(hidden); + V8Shell* _this = (V8Shell*) (long) __shell__->Value(); + + v8::Handle module = _this->Import(moduleName); + + return scope.Close(module); +} + v8::Handle V8Shell::Quit(const v8::Arguments& args) { int exit_code = args[0]->Int32Value(); fflush(stdout); From 29ccb270afa761d57d6a6728ca49d92fe9d35bc0 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 6 Sep 2013 00:40:29 +0300 Subject: [PATCH 175/352] Renamed object provided to JS initializers. JSC initializer create a new module object. V8 initializer fill a provided 'exports' object. --- Lib/javascript/jsc/javascriptcode.swg | 6 ++-- Lib/javascript/v8/javascriptcode.swg | 13 +++++--- Source/Modules/javascript.cxx | 45 ++++++++++++++------------- 3 files changed, 35 insertions(+), 29 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 0325a7a35..a55f24d33 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -279,11 +279,9 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec extern "C" { #endif -bool SWIGJSC_INIT (JSGlobalContextRef context) { +bool SWIGJSC_INIT (JSGlobalContextRef context, JSObjectRef *exports) { SWIG_InitializeModule(0); - JSObjectRef global_object = JSContextGetGlobalObject(context); - /* Initialize the base swig type object */ _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; _SwigObject_objectDefinition.staticValues = _SwigObject_values; @@ -298,6 +296,8 @@ bool SWIGJSC_INIT (JSGlobalContextRef context) { /* Register namespaces */ $jsregisternamespaces + *exports = exports_object; + return true; } diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 4277e8b0c..dcaf2a707 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -477,15 +477,19 @@ fail: %fragment("js_initializer", "templates") %{ -#if defined(BUILDING_NODE_EXTENSION) -void $jsname_initialize(v8::Handle global_obj, v8::Handle /*module*/) +// Note: 'extern "C"'' disables name mangling which makes it easier to load the symbol manually +// TODO: is it ok to do that? +extern "C" +#if (NODE_MODULE_VERSION < 0x000C) +void $jsname_initialize(v8::Handle exports) #else -void $jsname_initialize(v8::Handle global_obj) +void $jsname_initialize(v8::Handle exports, v8::Handle /*module*/) #endif { - SWIG_InitializeModule(static_cast(&global_obj)); + SWIG_InitializeModule(static_cast(&exports)); v8::HandleScope scope; + v8::Handle exports_obj = exports; // a class template for creating proxies of undefined types @@ -495,7 +499,6 @@ void $jsname_initialize(v8::Handle global_obj) SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); #endif - /* create objects for namespaces */ $jsv8nspaces diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index cec65338a..360fb1aec 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -521,7 +521,10 @@ void JAVASCRIPT::main(int argc, char *argv[]) { int mode = -1; - bool createModuleObject = true; + // Note: creating a module object is not supported anymore. + // instead the initializer is called with an externally created object + // This makes it obsolete to handle node extensions differently + bool createModuleObject = false; for (int i = 1; i < argc; i++) { if (argv[i]) { @@ -533,7 +536,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { Swig_mark_arg(i); mode = JSEmitter::V8; SWIG_library_directory("javascript/v8"); - createModuleObject = false; Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); } else if (strcmp(argv[i], "-jsc") == 0) { Swig_mark_arg(i); @@ -544,7 +546,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { js_template_enable_debug = true; } else if (strcmp(argv[i], "-no-moduleobject") == 0) { Swig_mark_arg(i); - createModuleObject = false; } } } @@ -655,18 +656,18 @@ JSEmitterState &JSEmitter::getState() { return state; } -int JSEmitter::initialize(Node *n) { +int JSEmitter::initialize(Node * /*n*/) { if(namespaces != NULL) { Delete(namespaces); } namespaces = NewHash(); Hash *global_namespace; - if(State::IsSet(state.global(FLAG_NO_MODULE_OBJECT))) { - global_namespace = createNamespaceEntry("global", 0); - } else { - global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); - } +// if(State::IsSet(state.global(FLAG_NO_MODULE_OBJECT))) { + global_namespace = createNamespaceEntry("exports", 0); +// } else { +// global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); +// } Setattr(namespaces, "::", global_namespace); current_namespace = global_namespace; @@ -1407,8 +1408,6 @@ private: String *NULL_STR; String *VETO_SET; - const char *GLOBAL_STR; - // output file and major code parts File *f_wrap_cpp; @@ -1433,7 +1432,6 @@ JSCEmitter::JSCEmitter() : JSEmitter(), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), - GLOBAL_STR(NULL), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), @@ -1735,6 +1733,8 @@ int JSCEmitter::emitNamespaces() { String *functions = Getattr(entry, "functions"); String *variables = Getattr(entry, "values"); + // skip the global namespace which is given by the application + Template namespace_definition(getTemplate("jsc_nspace_declaration")); namespace_definition.replace("$jsglobalvariables", variables) .replace("$jsglobalfunctions", functions) @@ -1745,11 +1745,15 @@ int JSCEmitter::emitNamespaces() { t_createNamespace.replace(T_NAME_MANGLED, name_mangled); Append(state.global(CREATE_NAMESPACES), t_createNamespace.str()); - Template t_registerNamespace(getTemplate("jsc_nspace_registration")); - t_registerNamespace.replace(T_NAME_MANGLED, name_mangled) - .replace(T_NAME, name) - .replace(T_PARENT, parent_mangled); - Append(state.global(REGISTER_NAMESPACES), t_registerNamespace.str()); + // Don't register 'exports' as namespace. It is return to the application. + if (!Equal("exports", name)) { + Template t_registerNamespace(getTemplate("jsc_nspace_registration")); + t_registerNamespace.replace(T_NAME_MANGLED, name_mangled) + .replace(T_NAME, name) + .replace(T_PARENT, parent_mangled); + Append(state.global(REGISTER_NAMESPACES), t_registerNamespace.str()); + } + } return SWIG_OK; @@ -1809,7 +1813,6 @@ private: // the output cpp file File *f_wrap_cpp; - String* GLOBAL; String* NULL_STR; String *VETO_SET; String *moduleName; @@ -1818,7 +1821,6 @@ private: V8Emitter::V8Emitter() : JSEmitter(), - GLOBAL(NewString("global")), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) { @@ -1826,7 +1828,6 @@ V8Emitter::V8Emitter() V8Emitter::~V8Emitter() { - Delete(GLOBAL); Delete(NULL_STR); Delete(VETO_SET); } @@ -2161,7 +2162,9 @@ int V8Emitter::emitNamespaces() { do_register = false; } - if (Equal(name, "global")) { + // Note: 'exports' is by convention the name of the object where + // globals are stored into + if (Equal(name, "exports")) { do_create = false; } From 962207e0f33a322af3f9303f1e15ce9e28eb7281 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 6 Sep 2013 00:41:18 +0300 Subject: [PATCH 176/352] Rewritten Javascript autoconfiguration. --- configure.in | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 6ff3d5258..75727de51 100644 --- a/configure.in +++ b/configure.in @@ -1078,17 +1078,212 @@ AC_SUBST(JAVACXXSHARED) AC_SUBST(JAVACFLAGS) #---------------------------------------------------------------- -# Look for JAVASCRIPT [JavaScriptCore Headers and Library] +# Look for JAVASCRIPT #---------------------------------------------------------------- AC_ARG_WITH(javascript, AS_HELP_STRING([--without-javascript], [Disable JAVASCRIPT]), [with_javascript="$withval"], [with_javascript=yes]) -AC_ARG_VAR(JSDEFAULT, "The default engine to use ( v8 | jsc ).") # First, check for "--without-javascript" or "--with-javascript=no". -if test x"${with_javascript}" = xno -o x"${with_alllang}" = xno ; then +if test x"${with_javascript}" = xno -o x"${with_alllang}" = xno ; then AC_MSG_NOTICE([Disabling Javascript]) JAVASCRIPT= +else + #---------------------------------------------------------------- + # General Javascript settings shared by JSC and V8 + #---------------------------------------------------------------- + + case $host in + *-*-cygwin* | *-*-mingw*) + JSLIBRARYPREFIX="" + ;; + *) + JSLIBRARYPREFIX="lib" + ;; + esac + + case $host in + *-*-darwin*) + JSSO=".dylib" + JSLDSHARED='$(CC) -dynamiclib' + JSCXXSHARED='$(CXX) -dynamiclib' + ;; + *) + JSSO=$SO + JSLDSHARED='$(LDSHARED)' + JSCXXSHARED='$(CXXSHARED)' + ;; + esac + + #---------------------------------------------------------------- + # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING) + #---------------------------------------------------------------- + + # check for include files + AC_MSG_CHECKING(for include file JavaScriptCore/JavaScript.h) + AC_ARG_WITH(jscoreinc, [ --with-jscinc=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=]) + + if test -z "$JSCOREINCDIR"; then + JSCOREINCDIR="/usr/include/ /usr/local/include/" + + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) + JSCOREINCDIR="/usr/include/webkit-1.0/ /usr/include/webkitgtk-1.0/ /usr/local/include/webkit-1.0/JavaScriptCore/ $JSCOREINCDIR" + ;; + *-*-darwin*) + JSCOREINCDIR="/System/Library/Frameworks/JavaScriptCore.framework/Headers/ $JSCOREINCDIR" + ;; + *) + ;; + esac + fi + + for d in $JSCOREINCDIR ; do + if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then + AC_MSG_RESULT($d) + JSCOREINCDIR=$d + JSCOREINC=-I\"$d\" + break + fi + done + + if test "$JSCOREINC" = "" ; then + AC_MSG_RESULT(not found) + fi + + # check for JavaScriptCore/Webkit libraries + AC_ARG_WITH(jscorelib,[ --with-jsclib =path Set location of the JavaScriptCore/Webkit library directory],[JSCORELIB="-L$withval"], [JSCORELIB=]) + AC_MSG_CHECKING(for JavaScriptCore/Webkit library) + + # look for the library when not provided + if test -z "$JSCORELIB"; then + case $host in + *-*-linux*) + dirs="/usr/lib/ /usr/local/lib/" + for i in $dirs ; do + if test -r $i/libwebkit-1.0.la; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkit-1.0" + break + fi + + if test -r $i/libjavascriptcoregtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -ljavascriptcoregtk-1.0" + break + fi + + if test -r $i/libwebkitgtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkitgtk-1.0" + break + fi + done + + if test -z "$JSCORELIB"; then + AC_MSG_RESULT(not found) + JSCENABLED=0 + else + JSCOREDYNAMICLINKING="$JSCORELIB" + JSCENABLED=1 + fi + ;; + *-*-darwin*) + JSCOREDYNAMICLINKING="-framework JavaScriptCore" + ;; + *) + ;; + esac + fi + + #---------------------------------------------------------------- + # Look for V8 settings (JSV8INCDIR, JSV8DYNAMICLINKING) + #---------------------------------------------------------------- + + # check for include files + AC_MSG_CHECKING(for include file v8.h) + AC_ARG_WITH(jsv8inc, [ --with-v8inc=path Set location of Javascript include directory], [JSV8INCDIR="$withval"]) + + # if not include dir is specified we try to find + if test -z "$JSV8INCDIR"; then + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) + JSV8INCDIR="/usr/include /usr/local/include/ $JSV8INCDIR" + ;; + *-*-darwin*) + JSV8INCDIR="$JSV8INCDIR" + ;; + *) + ;; + esac + fi + + for d in $JSV8INCDIR ; do + if test -r "$d/v8.h" ; then + JSV8INCDIR=$d + JSV8INC=-I\"$d\" + break + fi + done + + if test "$JSV8INC" = "" ; then + AC_MSG_RESULT(not found) + else + AC_MSG_RESULT($JSV8INCDIR) + fi + + # check for V8 library + AC_MSG_CHECKING(for v8 library) + AC_ARG_WITH(jsv8lib,[ --with-v8lib=path Set location of V8 library directory],[JSV8LIBDIR="$withval"], [JSV8LIB=]) + + v8libdirs="$JSV8LIBDIR /usr/lib/ /usr/local/lib/" + for d in $v8libdirs ; do + if test -r $d/libv8.so; then + JSV8LIBDIR=$d + JSV8LIB="-L$d -lv8" + break + fi + done + + if test "$JSV8LIB" = "" ; then + AC_MSG_RESULT(not found) + JSV8ENABLED=0 + else + AC_MSG_RESULT($JSV8LIBDIR) + JSV8ENABLED=1 + fi + + + # linking options + case $host in + *-*-darwin*) + JSV8DYNAMICLINKING="" # TODO: add osx configuration + ;; + *-*-linux*) + JSV8DYNAMICLINKING="$JSV8LIB" + ;; + *) + JSV8DYNAMICLINKING="" + ;; + esac + fi +AC_SUBST(JSCFLAGS) +AC_SUBST(JSCXXFLAGS) +AC_SUBST(JSLIBRARYPREFIX) +AC_SUBST(JSSO) +AC_SUBST(JSLDSHARED) +AC_SUBST(JSCXXSHARED) + +AC_SUBST(JSCOREINC) +AC_SUBST(JSCOREDYNAMICLINKING) +AC_SUBST(JSV8INC) +AC_SUBST(JSV8DYNAMICLINKING) + +AC_SUBST(JSCENABLED) +AC_SUBST(JSV8ENABLED) + #---------------------------------------------------------------- # Look for gcj #---------------------------------------------------------------- From 26b5acbbe850c3494f4b79c62f678a92f219f61a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 6 Sep 2013 00:42:56 +0300 Subject: [PATCH 177/352] Test-suite Makefile now supports testing for all three Javascript variants. - node.js - custom JavascriptCore interpreter - custom V8 interpreter --- Examples/Makefile.in | 68 +++++++-- Examples/test-suite/javascript/Makefile.in | 157 +++++++++------------ 2 files changed, 123 insertions(+), 102 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 94a00e642..806ed09d4 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -517,29 +517,67 @@ java_clean: ##### JAVASCRIPT ###### ################################################################## +ROOT_DIR = @ROOT_DIR@ +JSCFLAGS = @JSCFLAGS@ +JSCXXFLAGS = @JSCXXFLAGS@ +JSINCLUDES = @JSCOREINC@ @JSV8INC@ +JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ +JSLIBRARYPREFIX = @JSLIBRARYPREFIX@ +JSSO =@JSSO@ +JSLDSHARED = @JSLDSHARED@ +JSCXXSHARED = @JSCXXSHARED@ + # ---------------------------------------------------------------- -# Definitions +# Compile a custom javascript interpreter +# ---------------------------------------------------------------- +# +# Note: +# There is no common CLI Javascript interpreter. +# V8 comes with one 'd8' which however does not provide a means +# to load extensions. Therefore, by default we use nodejs as +# environment. +# For testing native v8 and jsc extensions we provide our own +# interpreter (see 'Tools/javascript'). # ---------------------------------------------------------------- -JSEXE = node -SWIGJS = $(SWIG) -javascript -node -JS_BUILD = node-gyp rebuild +JS_INTERPRETER_SRC_DIR = $(ROOT_DIR)/Tools/javascript + +# These settings are provided by 'configure' (see '/configure.in') +ifeq (1, @JSV8ENABLED@) + JS_INTERPRETER_SRC_V8 = $(JS_INTERPRETER_SRC_DIR)/v8_shell.cxx + JS_INTERPRETER_CXXFLAGS_V8 = -DENABLE_V8 +endif + +ifeq (1, @JSCENABLED@) + JS_INTERPRETER_SRC_JSC = $(JS_INTERPRETER_SRC_DIR)/jsc_shell.cxx + JS_INTERPRETER_CXXFLAGS_JSC = -DENABLE_JSC +endif + +JS_INTERPRETER_CXXFLAGS = $(JS_INTERPRETER_CXXFLAGS_JSC) $(JS_INTERPRETER_CXXFLAGS_V8) +JS_INTERPRETER_SRC = \ + $(JS_INTERPRETER_SRC_DIR)/javascript.cxx $(JS_INTERPRETER_SRC_DIR)/js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_INTERPRETER_SRC_V8) + +# TODO: improve: +# - exe suffix +# - '-ldl' should come from configure +javascript_exe: $(SRCS) + $(CXX) $(CXXFLAGS) $(JS_INTERPRETER_CXXFLAGS) $(JSINCLUDES) $(JS_INTERPRETER_SRC) -ldl $(LIBS) $(JSDYNAMICLINKING) -o $(JS_INTERPRETER_SRC_DIR)/javascript + +SWIGJS = $(SWIG) -javascript # ---------------------------------------------------------------- # Run the javascript executable # ---------------------------------------------------------------- -javascript_wrapper_cpp: $(SRCS) +javascript: $(SRCS) + $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) + $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) + $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +javascript_cpp: $(SRCS) $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) - -javascript_build: - $(JS_BUILD) - -#javascript_run: $(SRCS) -# env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JSEXE) $(JSEXE_OPTS) -l $(TARGET) $(JS_SCRIPT) - -javascript_run: $(SRCS) - env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(JSEXE) $(JSEXE_OPTS) $(JS_SCRIPT) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) + $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) # ----------------------------------------------------------------- # Cleaning the javascript examples @@ -549,7 +587,7 @@ javascript_clean: rm -rf build rm -f *_wrap* runme rm -f core @EXTRA_CLEAN@ - rm -f *.@OBJEXT@ *@JSCORESO@ + rm -f *.@OBJEXT@ *@JSSO@ ################################################################## diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index f0810a167..c78553c6c 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -7,105 +7,88 @@ SCRIPTSUFFIX = _runme.js srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ -JS_INCLUDE = @JSCOREINC@ -JS_DLNK = @JSCOREDYNAMICLINKING@ -JSCXXFLAGS = @JSCXXFLAGS@ -JAVASCRIPT_EXE = node -SWIG = $(top_builddir)/preinst_swig +SWIG = $(top_builddir)/preinst_swig -C_TEST_CASES = \ - preproc - - -CPP_TEST_CASES = \ - abstract_access \ - abstract_typedef \ - abstract_typedef2 \ - abstract_virtual \ - arrays_global \ - array_member \ - char_binary \ - class_ignore \ - class_scope_weird \ - complextest \ - constover \ - constructor_copy \ - cpp_enum \ - cpp_namespace \ - cpp_static \ - director_alternating \ - enum_template \ - namespace_virtual_method \ - overload_copy \ - ret_by_value \ - struct_value \ - template_static \ - typedef_class \ - typedef_inherit \ - typedef_scope \ - typemap_arrays \ - typemap_delete \ - typemap_namespace \ - typemap_ns_using \ - using1 \ - using2 \ - javascript_unicode - -BROKEN_TEST_CASES = \ - preproc_include - -SKIP_CPP_CASES = @SKIP_CPP_CASES@ -SKIP_C_CASES = @SKIP_C_CASES@ -SKIP_CPP_STD_CASES = @SKIP_CPP_STD_CASES@ -SKIP_MULTI_CPP_CASES = @SKIP_MULTI_CPP_CASES@ +ifneq (, $(ENGINE)) + JSENGINE = $(ENGINE) +else + JSENGINE = "node" +endif include $(srcdir)/../common.mk -# Overridden variables here +SWIGOPT += -$(JSENGINE) -# Custom tests - tests with additional commandline options +ifeq ("node",$(JSENGINE)) -# Rules for the different types of tests -%.cpptest: - $(prepare_test) - $(generate_cpp_wrapper) - $(build_module) - $(run_testcase) + setup = \ + if [ ! -f $(srcdir)/$*/binding.gyp ]; then \ + echo "Setting up nodejs addon..."; \ + sh ./setup_test.sh $*; \ + $(SWIG) -c++ -javascript -node -o $*/$*_wrap.cxx ../$*.i; \ + fi -%.ctest: - $(prepare_test) - $(generate_cpp_wrapper) - $(build_module) - $(run_testcase) + nodejs_swig_and_compile = \ + if [ ! -f $(srcdir)/$*/build/Makefile ]; then \ + echo "Configuring node add-on..."; \ + node-gyp --directory $* configure; \ + fi; \ + echo "Building node add-on..."; \ + node-gyp --directory $* build; \ -%.multicpptest: - $(prepare_test) - $(generate_cpp_wrapper) - $(build_module) - $(run_testcase) + run_testcase = \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + node $(srcdir)/$*$(SCRIPTSUFFIX); \ + fi -prepare_test = \ - sh ./setup_test.sh $* + # Rules for the different types of tests + %.cpptest: + $(setup) + $(nodejs_swig_and_compile) + $(run_testcase) -generate_cpp_wrapper = \ - $(SWIG) -c++ -javascript -node -o $*/$*_wrap.cxx ../$*.i + %.ctest: + $(setup) + $(nodejs_swig_and_compile) + $(run_testcase) -build_module = \ - if [ ! -f $(srcdir)/$*/build/Makefile ]; then \ - cd $* && node-gyp configure build && cd ..; \ - else \ - cd $* && node-gyp build && cd ..; \ - fi + %.multicpptest: + $(setup) + $(nodejs_swig_and_compile) + $(run_testcase) -# Runs the testcase. A testcase is only run if -# a file is found which has _runme.js appended after the testcase name. -run_testcase = \ - if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ - node $(srcdir)/$*$(SCRIPTSUFFIX); \ - fi + # Clean + %.clean: + rm -rf $* + +else + + run_testcase = \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + $(top_srcdir)/Tools/javascript/javascript -$(JSENGINE) $(srcdir)/$*$(SCRIPTSUFFIX); \ + fi + + # Rules for the different types of tests + %.cpptest: + $(setup) + +$(swig_and_compile_cpp) + $(run_testcase) + + %.ctest: + $(setup) + +$(swig_and_compile_c) + $(run_testcase) + + %.multicpptest: + $(setup) + +$(swig_and_compile_multi_cpp) + $(run_testcase) + + # Clean + %.clean: + rm $*_wrap.cxx + +endif -# Clean -%.clean: - rm -rf $* clean: From 492d3010ff33c1b6af9bca9472ad08e0330ffb42 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 6 Sep 2013 01:40:23 +0300 Subject: [PATCH 178/352] Javascript V8 test-cases always create cpp wrappers. --- Examples/test-suite/javascript/Makefile.in | 69 ++++++++++++---------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index c78553c6c..dcc643649 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -10,38 +10,38 @@ top_builddir = @top_builddir@ SWIG = $(top_builddir)/preinst_swig ifneq (, $(ENGINE)) - JSENGINE = $(ENGINE) + JSENGINE = $(ENGINE) else - JSENGINE = "node" + JSENGINE = "node" endif include $(srcdir)/../common.mk SWIGOPT += -$(JSENGINE) + ifeq ("node",$(JSENGINE)) - setup = \ - if [ ! -f $(srcdir)/$*/binding.gyp ]; then \ - echo "Setting up nodejs addon..."; \ - sh ./setup_test.sh $*; \ - $(SWIG) -c++ -javascript -node -o $*/$*_wrap.cxx ../$*.i; \ - fi + setup = \ + if [ ! -f $(srcdir)/$*/binding.gyp ]; then \ + echo "Setting up nodejs addon..."; \ + sh ./setup_test.sh $*; \ + $(SWIG) -c++ -javascript -node -o $*/$*_wrap.cxx ../$*.i; \ + fi - nodejs_swig_and_compile = \ - if [ ! -f $(srcdir)/$*/build/Makefile ]; then \ - echo "Configuring node add-on..."; \ - node-gyp --directory $* configure; \ - fi; \ - echo "Building node add-on..."; \ - node-gyp --directory $* build; \ + nodejs_swig_and_compile = \ + if [ ! -f $(srcdir)/$*/build/Makefile ]; then \ + echo "Configuring node add-on..."; \ + node-gyp --directory $* configure; \ + fi; \ + echo "Building node add-on..."; \ + node-gyp --directory $* build; \ - run_testcase = \ - if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ - node $(srcdir)/$*$(SCRIPTSUFFIX); \ - fi + run_testcase = \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + node $(srcdir)/$*$(SCRIPTSUFFIX); \ + fi - # Rules for the different types of tests %.cpptest: $(setup) $(nodejs_swig_and_compile) @@ -57,38 +57,43 @@ ifeq ("node",$(JSENGINE)) $(nodejs_swig_and_compile) $(run_testcase) - # Clean %.clean: rm -rf $* else - run_testcase = \ - if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ - $(top_srcdir)/Tools/javascript/javascript -$(JSENGINE) $(srcdir)/$*$(SCRIPTSUFFIX); \ - fi + run_testcase = \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + $(top_srcdir)/Tools/javascript/javascript -$(JSENGINE) $(srcdir)/$*$(SCRIPTSUFFIX); \ + fi - # Rules for the different types of tests %.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) - %.ctest: - $(setup) - +$(swig_and_compile_c) - $(run_testcase) - %.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) - # Clean %.clean: rm $*_wrap.cxx endif +ifeq (v8,$(ENGINE)) + %.ctest: + $(setup) + +$(swig_and_compile_cpp) + $(run_testcase) +endif + +ifeq (jsc,$(ENGINE)) + %.ctest: + $(setup) + +$(swig_and_compile_c) + $(run_testcase) +endif clean: From 0facc7ecf9f48a98a6f66c557917657d3adb2d36 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 6 Sep 2013 15:59:43 +0300 Subject: [PATCH 179/352] Allow to run the test suite with our list of smoke tests. The javascript generator can not deal with the whole test-suite. Moreover, during development I want to have immediate feedback using a set of smoke tests. --- Examples/test-suite/javascript/Makefile.in | 99 +++++++++++++++++----- 1 file changed, 80 insertions(+), 19 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index dcc643649..0f532b119 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -15,27 +15,85 @@ else JSENGINE = "node" endif +# Note: the javascript generator is not ready yet for the real game. +# To be able keep the behavior continously tested that is expected to work already +# we have a 'light' version of the test-suite +# This will be removed and replaced by a list of 'BROKEN_TEST_CASES' when +# the number gets smaller (currently we have about 65 broken tests for JSC, and 85 for V8) + +ifneq (,$(SMOKE)) + +C_TEST_CASES = \ + preproc + +CPP_TEST_CASES = \ + abstract_access \ + abstract_typedef \ + abstract_typedef2 \ + abstract_virtual \ + arrays_global \ + array_member \ + char_binary \ + class_ignore \ + class_scope_weird \ + complextest \ + constover \ + constructor_copy \ + cpp_enum \ + cpp_namespace \ + cpp_static \ + director_alternating \ + enum_template \ + namespace_virtual_method \ + overload_copy \ + ret_by_value \ + struct_value \ + template_static \ + typedef_class \ + typedef_inherit \ + typedef_scope \ + typemap_arrays \ + typemap_delete \ + typemap_namespace \ + typemap_ns_using \ + using1 \ + using2 \ + javascript_unicode + +BROKEN_TEST_CASES = \ + preproc_include + +SKIP_CPP_CASES = @SKIP_CPP_CASES@ +SKIP_C_CASES = @SKIP_C_CASES@ +SKIP_CPP_STD_CASES = @SKIP_CPP_STD_CASES@ +SKIP_MULTI_CPP_CASES = @SKIP_MULTI_CPP_CASES@ + +endif + include $(srcdir)/../common.mk SWIGOPT += -$(JSENGINE) +_setup = \ + if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ + echo "$(ACTION)ing testcase $* (with run test) under javascript ($(JSENGINE))" ; \ + else \ + echo "$(ACTION)ing testcase $* under javascript ($(JSENGINE))" ; \ + fi; ifeq ("node",$(JSENGINE)) - setup = \ + __setup = \ if [ ! -f $(srcdir)/$*/binding.gyp ]; then \ - echo "Setting up nodejs addon..."; \ sh ./setup_test.sh $*; \ $(SWIG) -c++ -javascript -node -o $*/$*_wrap.cxx ../$*.i; \ fi nodejs_swig_and_compile = \ if [ ! -f $(srcdir)/$*/build/Makefile ]; then \ - echo "Configuring node add-on..."; \ - node-gyp --directory $* configure; \ + node-gyp --loglevel=silent --directory $* configure; \ fi; \ - echo "Building node add-on..."; \ - node-gyp --directory $* build; \ + node-gyp --loglevel=silent --directory $* build; \ run_testcase = \ if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ @@ -43,23 +101,23 @@ ifeq ("node",$(JSENGINE)) fi %.cpptest: - $(setup) + $(_setup) + $(__setup) $(nodejs_swig_and_compile) $(run_testcase) %.ctest: - $(setup) + $(_setup) + $(__setup) $(nodejs_swig_and_compile) $(run_testcase) %.multicpptest: - $(setup) + $(_setup) + $(__setup) $(nodejs_swig_and_compile) $(run_testcase) - %.clean: - rm -rf $* - else run_testcase = \ @@ -68,32 +126,35 @@ else fi %.cpptest: - $(setup) + $(_setup) +$(swig_and_compile_cpp) $(run_testcase) %.multicpptest: - $(setup) + $(_setup) +$(swig_and_compile_multi_cpp) $(run_testcase) - %.clean: - rm $*_wrap.cxx - endif ifeq (v8,$(ENGINE)) %.ctest: - $(setup) + $(_setup) +$(swig_and_compile_cpp) $(run_testcase) endif ifeq (jsc,$(ENGINE)) %.ctest: - $(setup) + $(_setup) +$(swig_and_compile_c) $(run_testcase) endif +%.clean: + rm -rf $* + clean: + rm -f *_wrap.cxx + rm -f *_wrap.c + rm -f *.so From 6b35c2d419eac4f71780a939254e8a459c075849 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 6 Sep 2013 16:26:02 +0300 Subject: [PATCH 180/352] Let Travis test all three targets. - nodejs: 0.10.12 - libwebgitgtk 1.0 - libv8 3.7.12 We should soon switch to a new v8 version or add an extra runner. --- .travis.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f57e81319..a38965992 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,5 +8,11 @@ before_script: - "sudo apt-get update" - "sudo apt-get install -y nodejs" - "sudo npm install -g node-gyp" + - "sudo apt-get install libv8-3.7.12.22 libv8-dev" + - "sudo apt-get install libwebkitgtk-dev" - "./autogen.sh && ./configure && make" -script: "make check-javascript-test-suite" + - "cd Examples && make javascript_exe && cd .." +script: + - "make SMOKE=1 check-javascript-test-suite" + - "make SMOKE=1 ENGINE=jsc check-javascript-test-suite" + - "make SMOKE=1 ENGINE=v8 check-javascript-test-suite" From 1729fac3605d6649919ee508bcf8b03f904886f4 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 12:46:07 +0300 Subject: [PATCH 181/352] Bug-fix for static variables as proposed by Kota Iguchi. Fixes #20. --- Source/Modules/javascript.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 360fb1aec..54135d852 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1636,7 +1636,7 @@ int JSCEmitter::exitVariable(Node *n) { .replace(T_SETTER, state.variable(SETTER)); if (GetFlag(n, "ismember")) { - if (GetFlag(state.function(), IS_STATIC) + if (GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) { Append(state.clazz(STATIC_VARIABLES), t_variable.str()); } else { From e01e337d752dbbfc58a06b87fe1169d3f6ada76f Mon Sep 17 00:00:00 2001 From: Eric Wing Date: Thu, 5 Sep 2013 14:50:15 -0700 Subject: [PATCH 182/352] Added unit test using C99 INFINITY. This test actually tests a float conversion bug where converting to float imposed overflow checking which should not be there and causes this program to error out. This was seen originally in Javascript, but it turns out Python has the same bug. Lua does not have this bug. Other generators have not been tested. This test also tests the rename feature. The Javascript generator was not renaming the variable correctly. --- Examples/test-suite/infinity.i | 49 +++++++++++++++++++ .../test-suite/javascript/infinity_runme.js | 4 ++ 2 files changed, 53 insertions(+) create mode 100644 Examples/test-suite/infinity.i create mode 100644 Examples/test-suite/javascript/infinity_runme.js diff --git a/Examples/test-suite/infinity.i b/Examples/test-suite/infinity.i new file mode 100644 index 000000000..a01f05fc5 --- /dev/null +++ b/Examples/test-suite/infinity.i @@ -0,0 +1,49 @@ +%module infinity + +#include + +/* C99 defines INFINITY + Because INFINITY may be defined by compiler built-ins, we can't use #define. + Instead, expose the variable MYINFINITY and then use %rename to make it INFINITY in the scripting language. +*/ +%rename(INFINITY) MYINFINITY; + + +%inline %{ +#include + +/* C99 math.h defines INFINITY. If not available, this is the fallback. */ +#ifndef INFINITY + #ifdef _MSC_VER + union MSVC_EVIL_FLOAT_HACK + { + unsigned __int8 Bytes[4]; + float Value; + }; + static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}}; + #define INFINITY (INFINITY_HACK.Value) + #endif + + #ifdef __GNUC__ + #define INFINITY (__builtin_inf()) + #elif defined(__clang__) + #if __has_builtin(__builtin_inf) + #define INFINITY (__builtin_inf()) + #endif + #endif + + #ifndef INFINITY + #define INFINITY (1e1000) + #endif +#endif + +/* This will allow us to bind the real INFINITY value through SWIG via MYINFINITY. Use %rename to fix the name. */ +const double MYINFINITY = INFINITY; + +/* Use of float is intentional because the original bug was in the float conversion due to overflow checking. */ +float use_infinity(float inf_val) +{ + return inf_val; +} +%} + diff --git a/Examples/test-suite/javascript/infinity_runme.js b/Examples/test-suite/javascript/infinity_runme.js new file mode 100644 index 000000000..f15134848 --- /dev/null +++ b/Examples/test-suite/javascript/infinity_runme.js @@ -0,0 +1,4 @@ + +var my_infinity = infinity.INFINTY; +var ret_val = infinity.use_infinity(my_infinity); + From 1438d0cfb45f0f1b740eb8d1d366f694ba99d0b6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 13:17:38 +0300 Subject: [PATCH 183/352] Add `infinity` test-case to list of smoke tests. --- Examples/test-suite/javascript/Makefile.in | 1 + Examples/test-suite/javascript/infinity_runme.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 0f532b119..0b6d2f7c6 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -44,6 +44,7 @@ CPP_TEST_CASES = \ cpp_static \ director_alternating \ enum_template \ + infinity \ namespace_virtual_method \ overload_copy \ ret_by_value \ diff --git a/Examples/test-suite/javascript/infinity_runme.js b/Examples/test-suite/javascript/infinity_runme.js index f15134848..1dcf366c6 100644 --- a/Examples/test-suite/javascript/infinity_runme.js +++ b/Examples/test-suite/javascript/infinity_runme.js @@ -1,4 +1,4 @@ +var infinity = require("./infinity"); var my_infinity = infinity.INFINTY; var ret_val = infinity.use_infinity(my_infinity); - From 64da1173ddf8bd1fe04800e2afbe0f9c5d2dc818 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 13:23:47 +0300 Subject: [PATCH 184/352] Activate Javascript testcases `rename1-4`. --- Examples/test-suite/javascript/Makefile.in | 4 ++ .../test-suite/javascript/rename1_runme.js | 68 +++++++++++++++++++ .../test-suite/javascript/rename2_runme.js | 68 +++++++++++++++++++ .../test-suite/javascript/rename3_runme.js | 68 +++++++++++++++++++ .../test-suite/javascript/rename4_runme.js | 68 +++++++++++++++++++ 5 files changed, 276 insertions(+) create mode 100644 Examples/test-suite/javascript/rename1_runme.js create mode 100644 Examples/test-suite/javascript/rename2_runme.js create mode 100644 Examples/test-suite/javascript/rename3_runme.js create mode 100644 Examples/test-suite/javascript/rename4_runme.js diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 0b6d2f7c6..7c6b9ad4e 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -47,6 +47,10 @@ CPP_TEST_CASES = \ infinity \ namespace_virtual_method \ overload_copy \ + rename1 \ + rename2 \ + rename3 \ + rename4 \ ret_by_value \ struct_value \ template_static \ diff --git a/Examples/test-suite/javascript/rename1_runme.js b/Examples/test-suite/javascript/rename1_runme.js new file mode 100644 index 000000000..8374e6a89 --- /dev/null +++ b/Examples/test-suite/javascript/rename1_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename1"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename2_runme.js b/Examples/test-suite/javascript/rename2_runme.js new file mode 100644 index 000000000..bc6a95a59 --- /dev/null +++ b/Examples/test-suite/javascript/rename2_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename2"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename3_runme.js b/Examples/test-suite/javascript/rename3_runme.js new file mode 100644 index 000000000..9e57e80ea --- /dev/null +++ b/Examples/test-suite/javascript/rename3_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename3"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename4_runme.js b/Examples/test-suite/javascript/rename4_runme.js new file mode 100644 index 000000000..d651fc7a1 --- /dev/null +++ b/Examples/test-suite/javascript/rename4_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename4"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); From 108143951da3859e0c056780706b6841231febb3 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 13:55:08 +0300 Subject: [PATCH 185/352] Activate Javascript test-cases `rename_simple` and `rename_scope`. These reveal current deficiencies in the Javascript generator with `%rename`ing. --- Examples/test-suite/javascript/Makefile.in | 2 + .../javascript/rename_scope_runme.js | 17 +++++++ .../javascript/rename_simple_runme.js | 50 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 Examples/test-suite/javascript/rename_scope_runme.js create mode 100644 Examples/test-suite/javascript/rename_simple_runme.js diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 7c6b9ad4e..5d7fba02e 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -51,6 +51,8 @@ CPP_TEST_CASES = \ rename2 \ rename3 \ rename4 \ + rename_simple \ + rename_scope \ ret_by_value \ struct_value \ template_static \ diff --git a/Examples/test-suite/javascript/rename_scope_runme.js b/Examples/test-suite/javascript/rename_scope_runme.js new file mode 100644 index 000000000..c0226df69 --- /dev/null +++ b/Examples/test-suite/javascript/rename_scope_runme.js @@ -0,0 +1,17 @@ +var rename_scope = require("./rename_scope"); + +var a = new rename_scope.Natural_UP(); +var b = new rename_scope.Natural_BP(); + +if (a.rtest() !== 1) { + throw new Error("a.rtest(): Expected 1, was " + a.rtest()); +} + +if (b.rtest() !== 1) { + throw new Error("b.rtest(): Expected 1, was " + b.rtest()); +} + +var f = rename_scope.equals; +if (f === undefined) { + throw new Error("Equality operator has not been renamed."); +} diff --git a/Examples/test-suite/javascript/rename_simple_runme.js b/Examples/test-suite/javascript/rename_simple_runme.js new file mode 100644 index 000000000..918dd68a5 --- /dev/null +++ b/Examples/test-suite/javascript/rename_simple_runme.js @@ -0,0 +1,50 @@ +var rename_simple = require("./rename_simple"); +var NewStruct = rename_simple.NewStruct; + +var s = new NewStruct(); + +// renamed instance variable +if (s.NewInstanceVariable !== 111) { + throw new Error("NewInstanceVariable: Expected 111, was " + s.NewInstanceVariable); +} + +// renamed instance method +if (s.NewInstanceMethod() !== 222) { + throw new Error("NewInstanceMethod(): Expected 222, was " + s.NewInstanceMethod()); +} + +// renamed static method +if (NewStruct.NewStaticMethod() !== 333) { + throw new Error("NewInstanceMethod(): Expected 333, was " + NewStruct.NewStaticMethod()); +} + +// renamed static variable +if (NewStruct.NewStaticVariable !== 444) { + throw new Error("NewInstanceMethod(): Expected 444, was " + NewStruct.NewStaticVariable); +} + +// renamed global function +if (rename_simple.NewFunction() !== 555) { + throw new Error("rename_simple.NewFunction(): Expected 555, was " + rename_simple.NewFunction()); +} + +// renamed global variable +if (rename_simple.NewGlobalVariable !== 666) { + throw new Error("rename_simple.NewGlobalVariable: Expected 666, was " + rename_simple.NewGlobalVariable); +} + +// setting renamed variables +s.NewInstanceVariable = 1111; +if (s.NewInstanceVariable !== 1111) { + throw new Error("NewInstanceVariable: Expected 1111, was " + s.NewInstanceVariable); +} + +NewStruct.NewStaticVariable = 4444; +if (NewStruct.NewStaticVariable !== 4444) { + throw new Error("NewInstanceMethod(): Expected 4444, was " + NewStruct.NewStaticVariable); +} + +rename_simple.NewGlobalVariable = 6666; +if (rename_simple.NewGlobalVariable !== 6666) { + throw new Error("rename_simple.NewGlobalVariable: Expected 6666, was " + rename_simple.NewGlobalVariable); +} From b6c9c97b96bc3039ccb291d76a64d009fc81fbb7 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 15:05:11 +0300 Subject: [PATCH 186/352] Fix Javascript generator to use %renamed variable names. --- Examples/test-suite/javascript/Makefile.in | 2 +- Source/Modules/javascript.cxx | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 5d7fba02e..49dd18054 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -44,7 +44,6 @@ CPP_TEST_CASES = \ cpp_static \ director_alternating \ enum_template \ - infinity \ namespace_virtual_method \ overload_copy \ rename1 \ @@ -68,6 +67,7 @@ CPP_TEST_CASES = \ javascript_unicode BROKEN_TEST_CASES = \ + infinity \ preproc_include SKIP_CPP_CASES = @SKIP_CPP_CASES@ diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 54135d852..5bd22f710 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -793,8 +793,18 @@ int JSEmitter::enterFunction(Node *n) { int JSEmitter::enterVariable(Node *n) { + // reset the state information for variables. state.variable(true); - state.variable(NAME, Swig_scopename_last(Getattr(n, "name"))); + + // Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings. + + if (Equal(Getattr(n, "view"), "memberconstantHandler")) { + // Note: this is kind of hacky/experimental + // For constants/enums 'sym:name' contains e.g., 'Foo_Hello' instead of 'Hello' + state.variable(NAME, Getattr(n, "memberconstantHandler:sym:name")); + } else { + state.variable(NAME, Swig_scopename_last(Getattr(n, "sym:name"))); + } if(Equal(Getattr(n, "storage"), "static")) { SetFlag(state.variable(), IS_STATIC); From fc4d9b665c5839df06501e736163bfeadb7503d1 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 16:28:29 +0300 Subject: [PATCH 187/352] Fix v8 generator to use a non clashing name for built-in 'equals' method. --- Lib/javascript/v8/javascripthelpers.swg | 2 +- Lib/javascript/v8/javascriptruntime.swg | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg index 52f3f106f..8da6627e2 100644 --- a/Lib/javascript/v8/javascripthelpers.swg +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -25,7 +25,7 @@ v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) inst_templ->SetInternalFieldCount(1); v8::Handle equals_templ = class_templ->PrototypeTemplate(); - equals_templ->Set(v8::String::NewSymbol("equals"), v8::FunctionTemplate::New(_wrap_equals)); + equals_templ->Set(v8::String::NewSymbol("equals"), v8::FunctionTemplate::New(_SWIGV8_wrap_equals)); v8::Handle cptr_templ = class_templ->PrototypeTemplate(); cptr_templ->Set(v8::String::NewSymbol("getCPtr"), v8::FunctionTemplate::New(_wrap_getCPtr)); diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 31ce84a04..c34b62108 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -297,9 +297,9 @@ v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, in #define SWIG_GetInstancePtr(obj, ptr) SWIG_V8_GetInstancePtr(obj, ptr) #if (SWIG_V8_VERSION < 0x031900) -v8::Handle _wrap_equals(const v8::Arguments &args) { +v8::Handle _SWIGV8_wrap_equals(const v8::Arguments &args) { #else -void _wrap_equals(const v8::FunctionCallbackInfo& args) { +void _SWIGV8_wrap_equals(const v8::FunctionCallbackInfo& args) { #endif v8::HandleScope scope; v8::Handle jsresult; @@ -309,11 +309,11 @@ void _wrap_equals(const v8::FunctionCallbackInfo& args) { int res1; int res2; - if(args.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for _wrap_equals."); + if(args.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for equals."); res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ERROR, "Could not get pointer from 'this' object for _wrap_equals."); + SWIG_exception_fail(SWIG_ERROR, "Could not get pointer from 'this' object for equals."); } res2 = SWIG_GetInstancePtr(args[0], &arg2); if (!SWIG_IsOK(res2)) { From 407d8ef5acff62578c701da74cfdf9a752baffd1 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 17:34:53 +0300 Subject: [PATCH 188/352] Clean up in `javascripttypemaps.swg`. - following the same layout/order as pytypemaps - added typemaps for `long long` and `unsigned long long`, which are only copies of those for `long` and `unsigned long` and hence are just experimental. --- Lib/javascript/jsc/javascriptfragments.swg | 23 ++++ ...primitives.swg => javascriptprimtypes.swg} | 96 +++++++++++++-- Lib/javascript/jsc/javascripttypemaps.swg | 41 +++++-- Lib/javascript/v8/javascriptfragments.swg | 23 ++++ ...primitives.swg => javascriptprimtypes.swg} | 114 ++++++++++++++---- Lib/javascript/v8/javascripttypemaps.swg | 43 +++++-- 6 files changed, 287 insertions(+), 53 deletions(-) create mode 100644 Lib/javascript/jsc/javascriptfragments.swg rename Lib/javascript/jsc/{javascriptprimitives.swg => javascriptprimtypes.swg} (53%) create mode 100644 Lib/javascript/v8/javascriptfragments.swg rename Lib/javascript/v8/{javascriptprimitives.swg => javascriptprimtypes.swg} (55%) diff --git a/Lib/javascript/jsc/javascriptfragments.swg b/Lib/javascript/jsc/javascriptfragments.swg new file mode 100644 index 000000000..4778bf033 --- /dev/null +++ b/Lib/javascript/jsc/javascriptfragments.swg @@ -0,0 +1,23 @@ +/* + + Create a file with this name, 'javascriptfragments.swg', in your working + directory and add all the %fragments you want to take precedence + over the default ones defined by swig. + + For example, if you add: + + %fragment(SWIG_AsVal_frag(int),"header") { + SWIGINTERNINLINE int + SWIG_AsVal(int)(PyObject *obj, int *val) + { + ; + } + } + + this will replace the code used to retrieve an integer value for all + the typemaps that need it, including: + + int, std::vector, std::list >, etc. + + +*/ diff --git a/Lib/javascript/jsc/javascriptprimitives.swg b/Lib/javascript/jsc/javascriptprimtypes.swg similarity index 53% rename from Lib/javascript/jsc/javascriptprimitives.swg rename to Lib/javascript/jsc/javascriptprimtypes.swg index f61e83272..2c23cc07f 100644 --- a/Lib/javascript/jsc/javascriptprimitives.swg +++ b/Lib/javascript/jsc/javascriptprimtypes.swg @@ -1,5 +1,11 @@ +/* ------------------------------------------------------------ + * Primitive Types + * ------------------------------------------------------------ */ + +/* boolean */ + %fragment(SWIG_From_frag(bool),"header") { -SWIGINTERNINLINE +SWIGINTERNINLINE JSValueRef SWIG_From_dec(bool)(bool value) { return JSValueMakeBoolean(context, value); @@ -19,6 +25,8 @@ int SWIG_AsVal_dec(bool)(JSValueRef obj, bool *val) } } +/* int */ + %fragment(SWIG_From_frag(int),"header") { SWIGINTERNINLINE JSValueRef SWIG_From_dec(int)(int value) @@ -27,9 +35,11 @@ SWIGINTERNINLINE JSValueRef } } +/* long */ + %fragment(SWIG_From_frag(long),"header") { SWIGINTERNINLINE JSValueRef - SWIG_From_dec(long)(long value) +SWIG_From_dec(long)(long value) { return JSValueMakeNumber(context, value); } @@ -44,7 +54,7 @@ SWIG_AsVal_dec(long)(JSValueRef obj, long* val) return SWIG_TypeError; } if(val) *val = (long) JSValueToNumber(context, obj, NULL); - + return SWIG_OK; } } @@ -53,35 +63,97 @@ SWIG_AsVal_dec(long)(JSValueRef obj, long* val) %fragment(SWIG_From_frag(unsigned long),"header", fragment=SWIG_From_frag(long)) { -SWIGINTERNINLINE JSValueRef +SWIGINTERNINLINE JSValueRef SWIG_From_dec(unsigned long)(unsigned long value) { return (value > LONG_MAX) ? - JSValueMakeNumber(context, value) : JSValueMakeNumber(context, %numeric_cast(value,long)); + JSValueMakeNumber(context, value) : JSValueMakeNumber(context, %numeric_cast(value,long)); } } %fragment(SWIG_AsVal_frag(unsigned long),"header", fragment="SWIG_CanCastAsInteger") { SWIGINTERN int -SWIG_AsVal_dec(unsigned long)(JSValueRef obj, unsigned long *val) +SWIG_AsVal_dec(unsigned long)(JSValueRef obj, unsigned long *val) { if(!JSValueIsNumber(context, obj)) { return SWIG_TypeError; } - + long longVal = (long) JSValueToNumber(context, obj, NULL); - + if(longVal < 0) { return SWIG_OverflowError; } - - if(val) *val = longVal; - + + if(val) *val = longVal; + return SWIG_OK; } } +/* long long */ +// Note: these are copied from 'long' and probably need fixing + +%fragment(SWIG_From_frag(long long),"header") { +SWIGINTERNINLINE JSValueRef +SWIG_From_dec(long long)(long long value) +{ + return JSValueMakeNumber(context, value); +} +} + +%fragment(SWIG_AsVal_frag(long long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN int +SWIG_AsVal_dec(long long)(JSValueRef obj, long long* val) +{ + if (!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = (long long) JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} + +/* unsigned long long */ +// Note: these are copied from 'unsigned long' and probably need fixing + +%fragment(SWIG_From_frag(unsigned long long),"header", + fragment=SWIG_From_frag(long long), + fragment="") { +SWIGINTERN JSValueRef +SWIG_From_dec(unsigned long long)(unsigned long long value) +{ + return (value > LONG_MAX) ? + JSValueMakeNumber(context, value) : JSValueMakeNumber(context, %numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN int +SWIG_AsVal_dec(unsigned long long)(JSValueRef obj, unsigned long long *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + + long long longVal = (unsigned long long) JSValueToNumber(context, obj, NULL); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* double */ + %fragment(SWIG_From_frag(double),"header") { SWIGINTERN JSValueRef SWIG_From_dec(double) (double val) @@ -98,7 +170,7 @@ SWIG_AsVal_dec(double)(JSValueRef obj, double *val) return SWIG_TypeError; } if(val) *val = JSValueToNumber(context, obj, NULL); - + return SWIG_OK; } } diff --git a/Lib/javascript/jsc/javascripttypemaps.swg b/Lib/javascript/jsc/javascripttypemaps.swg index 9bde8eb2a..aa0a829f9 100644 --- a/Lib/javascript/jsc/javascripttypemaps.swg +++ b/Lib/javascript/jsc/javascripttypemaps.swg @@ -1,21 +1,46 @@ +/* ------------------------------------------------------------ + * Typemap specializations for Javascript + * ------------------------------------------------------------ */ +/* ------------------------------------------------------------ + * Fragment section + * ------------------------------------------------------------ */ + +/* These macros are necessary to provide an extra parameter + to SWIG_AsVal_dec functions (JSContextRef context). +*/ #define SWIG_FROM_DECL_ARGS SWIG_JSC_FROM_DECL_ARGS #define SWIG_FROM_CALL_ARGS SWIG_JSC_FROM_CALL_ARGS #define SWIG_AS_DECL_ARGS SWIG_JSC_AS_DECL_ARGS #define SWIG_AS_CALL_ARGS SWIG_JSC_AS_CALL_ARGS -#define SWIG_Object JSValueRef -#define VOID_Object JSValueMakeUndefined(context) -#define SWIG_AppendOutput(result, obj) -#define SWIG_SetConstant(name, obj) -#define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise(context, exception, type) /* Include fundamental fragemt definitions */ %include -/* Python fragments for fundamental types */ -%include - +/* Look for user fragments file. */ +%include + +/* Javascript fragments for fundamental types */ +%include + +/* Javascript fragments for char* strings */ %include +/* ------------------------------------------------------------ + * Unified typemap section + * ------------------------------------------------------------ */ + +#define SWIG_Object JSValueRef +#define VOID_Object JSValueMakeUndefined(context) + +/* append output */ +#define SWIG_AppendOutput(result, obj) + +/* set constant */ +#define SWIG_SetConstant(name, obj) + +/* raise */ +#define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise(context, exception, type) + /* Include the unified typemap library */ %include diff --git a/Lib/javascript/v8/javascriptfragments.swg b/Lib/javascript/v8/javascriptfragments.swg new file mode 100644 index 000000000..4778bf033 --- /dev/null +++ b/Lib/javascript/v8/javascriptfragments.swg @@ -0,0 +1,23 @@ +/* + + Create a file with this name, 'javascriptfragments.swg', in your working + directory and add all the %fragments you want to take precedence + over the default ones defined by swig. + + For example, if you add: + + %fragment(SWIG_AsVal_frag(int),"header") { + SWIGINTERNINLINE int + SWIG_AsVal(int)(PyObject *obj, int *val) + { + ; + } + } + + this will replace the code used to retrieve an integer value for all + the typemaps that need it, including: + + int, std::vector, std::list >, etc. + + +*/ diff --git a/Lib/javascript/v8/javascriptprimitives.swg b/Lib/javascript/v8/javascriptprimtypes.swg similarity index 55% rename from Lib/javascript/v8/javascriptprimitives.swg rename to Lib/javascript/v8/javascriptprimtypes.swg index f34bbb75a..5e0187460 100644 --- a/Lib/javascript/v8/javascriptprimitives.swg +++ b/Lib/javascript/v8/javascriptprimtypes.swg @@ -1,6 +1,12 @@ +/* ------------------------------------------------------------ + * Primitive Types + * ------------------------------------------------------------ */ + +/* boolean */ + %fragment(SWIG_From_frag(bool),"header") { -SWIGINTERNINLINE -v8::Handle +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(bool)(bool value) { return v8::Boolean::New(value); @@ -15,12 +21,14 @@ int SWIG_AsVal_dec(bool)(v8::Handle obj, bool *val) if(!obj->IsBoolean()) { return SWIG_ERROR; } - + if (val) *val = obj->BooleanValue(); return SWIG_OK; } } +/* int */ + %fragment(SWIG_From_frag(int),"header") { SWIGINTERNINLINE v8::Handle SWIG_From_dec(int)(int value) @@ -30,18 +38,19 @@ v8::Handle SWIG_From_dec(int)(int value) } %fragment(SWIG_AsVal_frag(int),"header") { -SWIGINTERN +SWIGINTERN int SWIG_AsVal_dec(int)(v8::Handle valRef, int* val) { if (!valRef->IsNumber()) { return SWIG_TypeError; } if(val) *val = valRef->IntegerValue(); - + return SWIG_OK; } } +/* long */ %fragment(SWIG_From_frag(long),"header") { SWIGINTERNINLINE @@ -53,14 +62,14 @@ v8::Handle SWIG_From_dec(long)(long value) %fragment(SWIG_AsVal_frag(long),"header", fragment="SWIG_CanCastAsInteger") { -SWIGINTERN +SWIGINTERN int SWIG_AsVal_dec(long)(v8::Handle obj, long* val) { if (!obj->IsNumber()) { return SWIG_TypeError; } if(val) *val = (long) obj->IntegerValue(); - + return SWIG_OK; } } @@ -69,37 +78,98 @@ int SWIG_AsVal_dec(long)(v8::Handle obj, long* val) %fragment(SWIG_From_frag(unsigned long),"header", fragment=SWIG_From_frag(long)) { -SWIGINTERNINLINE +SWIGINTERNINLINE v8::Handle SWIG_From_dec(unsigned long)(unsigned long value) { return (value > LONG_MAX) ? - v8::Integer::NewFromUnsigned(value) : v8::Integer::New(%numeric_cast(value,long)); + v8::Integer::NewFromUnsigned(value) : v8::Integer::New(%numeric_cast(value,long)); } } %fragment(SWIG_AsVal_frag(unsigned long),"header", fragment="SWIG_CanCastAsInteger") { -SWIGINTERN -int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long *val) +SWIGINTERN +int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long *val) { if(!obj->IsNumber()) { return SWIG_TypeError; } - + long longVal = (long) obj->NumberValue(); - + if(longVal < 0) { return SWIG_OverflowError; } - - if(val) *val = longVal; - + + if(val) *val = longVal; + return SWIG_OK; } } +/* long long */ +// Note: these are copied from 'long' and probably need fixing + +%fragment(SWIG_From_frag(long long),"header") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(long long)(long long value) +{ + return v8::Number::New(value); +} +} + +%fragment(SWIG_AsVal_frag(long long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN +int SWIG_AsVal_dec(long)(v8::Handle obj, long long* val) +{ + if (!obj->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = (long long) obj->IntegerValue(); + + return SWIG_OK; +} +} + +/* unsigned long long */ +// Note: these are copied from 'unsigned long' and probably need fixing + +%fragment(SWIG_From_frag(unsigned long long),"header", + fragment=SWIG_From_frag(long long)) { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(unsigned long long)(unsigned long long value) +{ + return (value > LONG_MAX) ? + v8::Integer::NewFromUnsigned(value) : v8::Integer::New(%numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN +int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long long *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + + long long longVal = (long long) obj->NumberValue(); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* double */ + %fragment(SWIG_From_frag(double),"header") { -SWIGINTERN +SWIGINTERN v8::Handle SWIG_From_dec(double) (double val) { return v8::Number::New(val); @@ -107,21 +177,15 @@ v8::Handle SWIG_From_dec(double) (double val) } %fragment(SWIG_AsVal_frag(double),"header") { -SWIGINTERN +SWIGINTERN int SWIG_AsVal_dec(double)(v8::Handle obj, double *val) { if(!obj->IsNumber()) { return SWIG_TypeError; } if(val) *val = obj->NumberValue(); - + return SWIG_OK; } } -%typemap(in) char * -%{ - v8::String::Utf8Value _$1($input); - $1 = *_$1; -%} - diff --git a/Lib/javascript/v8/javascripttypemaps.swg b/Lib/javascript/v8/javascripttypemaps.swg index 479a1f076..b12e5c899 100644 --- a/Lib/javascript/v8/javascripttypemaps.swg +++ b/Lib/javascript/v8/javascripttypemaps.swg @@ -1,16 +1,43 @@ -#define SWIG_Object v8::Handle -#define VOID_Object v8::Undefined() -#define SWIG_AppendOutput(result, obj) -#define SWIG_SetConstant(name, obj) -#define SWIG_Raise(obj, type, desc) SWIG_V8_Raise(type) +/* ------------------------------------------------------------ + * Typemap specializations for Javascript + * ------------------------------------------------------------ */ + +/* ------------------------------------------------------------ + * Fragment section + * ------------------------------------------------------------ */ /* Include fundamental fragemt definitions */ %include -/* Python fragments for fundamental types */ -%include - +/* Look for user fragments file. */ +%include + +/* Javascript fragments for fundamental types */ +%include + +/* Javascript fragments for char* strings */ %include + +/* ------------------------------------------------------------ + * Unified typemap section + * ------------------------------------------------------------ */ + +/* Javascript types */ + +#define SWIG_Object v8::Handle +#define VOID_Object v8::Undefined() + +/* Overload of the output/constant/exception/dirout handling */ + +/* append output */ +#define SWIG_AppendOutput(result, obj) + +/* set constant */ +#define SWIG_SetConstant(name, obj) + +/* raise */ +#define SWIG_Raise(obj, type, desc) SWIG_V8_Raise(type) + /* Include the unified typemap library */ %include From 3c5946d998f2bcecc88f04de8df7a6f3da292b32 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 17:38:44 +0300 Subject: [PATCH 189/352] Redefined set of Javascript smoke tests. --- Examples/test-suite/javascript/Makefile.in | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 49dd18054..ad08b2360 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -24,7 +24,8 @@ endif ifneq (,$(SMOKE)) C_TEST_CASES = \ - preproc + preproc \ + preproc_include CPP_TEST_CASES = \ abstract_access \ @@ -42,14 +43,9 @@ CPP_TEST_CASES = \ cpp_enum \ cpp_namespace \ cpp_static \ - director_alternating \ enum_template \ namespace_virtual_method \ overload_copy \ - rename1 \ - rename2 \ - rename3 \ - rename4 \ rename_simple \ rename_scope \ ret_by_value \ @@ -67,8 +63,7 @@ CPP_TEST_CASES = \ javascript_unicode BROKEN_TEST_CASES = \ - infinity \ - preproc_include + infinity SKIP_CPP_CASES = @SKIP_CPP_CASES@ SKIP_C_CASES = @SKIP_C_CASES@ From 571c516a0b096564b070350c9b90255db3422768 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 22:25:51 +0300 Subject: [PATCH 190/352] Some fixes for the Javascript generator. - added missing `exception.i` - added missing generator block `wrappers` for v8 --- Lib/javascript/jsc/exception.i | 1 + Lib/javascript/v8/exception.i | 1 + Source/Modules/javascript.cxx | 1 + 3 files changed, 3 insertions(+) create mode 100644 Lib/javascript/jsc/exception.i create mode 100644 Lib/javascript/v8/exception.i diff --git a/Lib/javascript/jsc/exception.i b/Lib/javascript/jsc/exception.i new file mode 100644 index 000000000..0246cfde8 --- /dev/null +++ b/Lib/javascript/jsc/exception.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/exception.i b/Lib/javascript/v8/exception.i new file mode 100644 index 000000000..0246cfde8 --- /dev/null +++ b/Lib/javascript/v8/exception.i @@ -0,0 +1 @@ +%include diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 5bd22f710..876978a42 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1875,6 +1875,7 @@ int V8Emitter::initialize(Node *n) Swig_register_filebyname("begin", f_wrap_cpp); Swig_register_filebyname("runtime", f_runtime); Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrappers); Swig_register_filebyname("init", f_init); Swig_register_filebyname("post-init", f_post_init); From e5ad9cdc0527b21cbabaad02a22efd8418459d99 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 9 Sep 2013 22:26:30 +0300 Subject: [PATCH 191/352] Added two more Javascript tests. - `abstract_inherit` - `char_strings` --- .../javascript/abstract_inherit_runme.js | 40 +++++++++++++++++++ .../javascript/char_strings_runme.js | 11 +++++ 2 files changed, 51 insertions(+) create mode 100644 Examples/test-suite/javascript/abstract_inherit_runme.js create mode 100644 Examples/test-suite/javascript/char_strings_runme.js diff --git a/Examples/test-suite/javascript/abstract_inherit_runme.js b/Examples/test-suite/javascript/abstract_inherit_runme.js new file mode 100644 index 000000000..3af2eae74 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_inherit_runme.js @@ -0,0 +1,40 @@ +var abstract_inherit = require("./abstract_inherit"); + +// Shouldn't be able to instantiate any of these classes +// since none of them implements the pure virtual function +// declared in the base class (Foo). +var Foo = abstract_inherit.Foo; +var Bar = abstract_inherit.Bar; +var Spam = abstract_inherit.Spam; + +var caughtException = false; +try { + new Foo(); +} catch (err) { + caughtException = true; +} +if (!caughtException) { + throw new Error("Foo should be instantiated as it is abstract"); +} + +caughtException = false; +try { + new Bar(); +} catch (err) { + caughtException = true; +} + +if (!caughtException) { + throw new Error("Bar should be instantiated as it is abstract"); +} + +caughtException = false; +try { + new Spam(); +} catch (err) { + caughtException = true; +} + +if (!caughtException) { + throw new Error("Spam should be instantiated as it is abstract"); +} diff --git a/Examples/test-suite/javascript/char_strings_runme.js b/Examples/test-suite/javascript/char_strings_runme.js new file mode 100644 index 000000000..fe17cb982 --- /dev/null +++ b/Examples/test-suite/javascript/char_strings_runme.js @@ -0,0 +1,11 @@ +var char_strings = require("char_strings"); + +var assertIsEqual = function(expected, actual) { + if (expected !== actual) { + throw new Error("Expected "+expected+", was "+actual); + } +}; + +assertIsEqual("hi there", char_strings.CharPingPong("hi there")); +assertIsEqual("hi there", char_strings.CharArrayPingPong("hi there")); +assertIsEqual("hi there", char_strings.CharArrayDimsPingPong("hi there")); From be35d94fdb8b274b443e2467d8a1b6d2dd0723c6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 10 Sep 2013 11:53:12 +0300 Subject: [PATCH 192/352] Add support for PackedData to Javascript generator. --- Lib/javascript/jsc/javascriptcode.swg | 10 +- Lib/javascript/jsc/javascriptrun.swg | 255 +++++++++++++ Lib/javascript/jsc/javascriptruntime.swg | 181 +-------- Lib/javascript/jsc/javascripttypemaps.swg | 8 + Lib/javascript/v8/javascriptcode.swg | 1 - Lib/javascript/v8/javascriptrun.swg | 444 ++++++++++++++++++++++ Lib/javascript/v8/javascriptruntime.swg | 320 +--------------- 7 files changed, 718 insertions(+), 501 deletions(-) create mode 100644 Lib/javascript/jsc/javascriptrun.swg create mode 100644 Lib/javascript/v8/javascriptrun.swg diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index a55f24d33..2660e0e5e 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -107,7 +107,7 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc %{ void $jswrapper(JSObjectRef thisObject) { - SWIG_PRV_DATA* t = (SWIG_PRV_DATA*) JSObjectGetPrivate(thisObject); + SwigPrivData* t = (SwigPrivData*) JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) free (($jstype)t->swigCObject); if(t) free(t); } @@ -123,7 +123,7 @@ void $jswrapper(JSObjectRef thisObject) %{ void $jswrapper(JSObjectRef thisObject) { - SWIG_PRV_DATA* t = (SWIG_PRV_DATA*) JSObjectGetPrivate(thisObject); + SwigPrivData* t = (SwigPrivData*) JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) { $jstype arg1 = ($jstype)t->swigCObject; ${destructor_action} @@ -287,6 +287,12 @@ bool SWIGJSC_INIT (JSGlobalContextRef context, JSObjectRef *exports) { _SwigObject_objectDefinition.staticValues = _SwigObject_values; _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + /* Initialize the PackedData class */ + _SwigPackedData_objectDefinition.staticFunctions = _SwigPackedData_functions; + _SwigPackedData_objectDefinition.staticValues = _SwigPackedData_values; + _SwigPackedData_objectDefinition.finalize = _wrap_SwigPackedData_delete; + _SwigPackedData_classRef = JSClassCreate(&_SwigPackedData_objectDefinition); + /* Create objects for namespaces */ $jscreatenamespaces diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg new file mode 100644 index 000000000..3038fcd71 --- /dev/null +++ b/Lib/javascript/jsc/javascriptrun.swg @@ -0,0 +1,255 @@ +/*****************************************************************************/ +/* Errors and exceptions +/* +/*****************************************************************************/ + +#define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_fail goto fail + +void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) { + JSStringRef message = JSStringCreateWithUTF8CString(type); + *exception = JSValueMakeString(context, message); + JSStringRelease(message); +} + +void SWIG_JSC_exception(JSContextRef context, JSValueRef *exception, int code, const char* msg) { + SWIG_Javascript_Raise(context, exception, msg); +} + +/*****************************************************************************/ +/* The parent class of all Proxies +/* +/*****************************************************************************/ + +typedef struct { + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; +} SwigPrivData; + +JSValueRef _wrap_SwigObject_disown(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData *) JSObjectGetPrivate(obj); + + cdata->swigCMemOwn = false; + + jsresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef _wrap_SwigObject_getCPtr(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + long result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData*) JSObjectGetPrivate(obj); + + result = (long) cdata->swigCObject; + jsresult = JSValueMakeNumber(context, result); + + return jsresult; +} + +JSValueRef _wrap_SwigObject_equals(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + bool result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData*) JSObjectGetPrivate(obj); + + JSObjectRef obj2 = JSValueToObject(context, argv[0], NULL); + SwigPrivData *cdata2 = (SwigPrivData*) JSObjectGetPrivate(obj2); + + result = (cdata->swigCObject == cdata2->swigCObject); + jsresult = JSValueMakeBoolean(context, result); + + return jsresult; +} + +JSStaticValue _SwigObject_values[] = { + { + 0, 0, 0, 0 + } +}; + +JSStaticFunction _SwigObject_functions[] = { + { + "disown",_wrap_SwigObject_disown, kJSPropertyAttributeNone + }, + { + "equals",_wrap_SwigObject_equals, kJSPropertyAttributeNone + }, + { + "getCPtr",_wrap_SwigObject_getCPtr, kJSPropertyAttributeNone + }, + { + 0, 0, 0 + } +}; + +JSClassDefinition _SwigObject_objectDefinition; + +JSClassRef _SwigObject_classRef; + + +int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef objRef, void** ptr, swig_type_info *info, int flags) { + SwigPrivData *cdata = (SwigPrivData *) JSObjectGetPrivate(objRef); + if(cdata == NULL) { + return SWIG_ERROR; + } + if(cdata->info != info) { + bool type_valid = false; + swig_cast_info *t = info->cast; + while(t != NULL) { + if(t->type == cdata->info) { + type_valid = true; + break; + } + t = t->next; + } + if(!type_valid) { + return SWIG_TypeError; + } + } + + *ptr = cdata->swigCObject; + + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + + return SWIG_OK; +} + +int SWIG_JSC_ConvertPtr(JSContextRef context, JSValueRef valRef, void** ptr, swig_type_info *info, int flags) { + if(!JSValueIsObject(context, valRef)) { + return SWIG_TypeError; + } + + JSObjectRef objRef = JSValueToObject(context, valRef, NULL); + if(objRef == NULL) { + return SWIG_ERROR; + } + + return SWIG_JSC_ConvertInstancePtr(context, objRef, ptr, info, flags); +} + +JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_info *info, int flags) { + + JSClassRef classRef; + if(info->clientdata == NULL) { + classRef = _SwigObject_classRef; + } else { + classRef = (JSClassRef) info->clientdata; + } + + JSObjectRef result = JSObjectMake(context, classRef, NULL); + + SwigPrivData* cdata = (SwigPrivData*) malloc(sizeof(SwigPrivData)); + cdata->swigCObject = ptr; + cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; + cdata->info = info; + + JSObjectSetPrivate(result, cdata); + + return result; +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_JSC_ConvertPtr(context, obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_JSC_NewPointerObj(context, ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) + +/*****************************************************************************/ +/* A class for packed data +/* +/*****************************************************************************/ + +typedef struct { + void *data; + size_t size; + swig_type_info *type; +} SwigPackedData; + +JSStaticValue _SwigPackedData_values[] = { + { + 0, 0, 0, 0 + } +}; +JSStaticFunction _SwigPackedData_functions[] = { + { + 0, 0, 0 + } +}; +JSClassDefinition _SwigPackedData_objectDefinition; +JSClassRef _SwigPackedData_classRef; + +SWIGRUNTIMEINLINE +int SwigJSCPacked_Check(JSContextRef context, JSValueRef valRef) { + return JSValueIsObjectOfClass(context, valRef, _SwigPackedData_classRef); +} + +SWIGRUNTIME +swig_type_info* SwigJSCPacked_UnpackData(JSContextRef context, JSValueRef valRef, void *ptr, size_t size) { + if (SwigJSCPacked_Check(context, valRef)) { + JSObjectRef objRef = JSValueToObject(context, valRef, NULL); + SwigPackedData *sobj = (SwigPackedData *) JSObjectGetPrivate(objRef); + if (sobj->size != size) return 0; + memcpy(ptr, sobj->data, size); + return sobj->type; + } else { + return 0; + } +} + +SWIGRUNTIME +int SWIG_JSC_ConvertPacked(JSContextRef context, JSValueRef valRef, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigJSCPacked_UnpackData(context, valRef, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +SWIGRUNTIME +JSValueRef SWIG_JSC_NewPackedObj(JSContextRef context, void *data, size_t size, swig_type_info *type) { + + JSClassRef classRef = _SwigObject_classRef; + JSObjectRef result = JSObjectMake(context, classRef, NULL); + + SwigPackedData* cdata = (SwigPackedData*) malloc(sizeof(SwigPackedData)); + cdata->data = data; + cdata->size = size; + cdata->type = type; + + JSObjectSetPrivate(result, cdata); + + return result; +} + +/* SwigPackedData wrappers */ + +void _wrap_SwigPackedData_delete(JSObjectRef obj) +{ + SwigPackedData* cdata = (SwigPackedData*) JSObjectGetPrivate(obj); + if (cdata) { + free(cdata->data); + } +} + +/* for C++ member pointers, ie, member methods */ + +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_JSC_ConvertPacked(context, obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_JSC_NewPackedObj(context, ptr, sz, type) diff --git a/Lib/javascript/jsc/javascriptruntime.swg b/Lib/javascript/jsc/javascriptruntime.swg index 88379415a..8f8390890 100644 --- a/Lib/javascript/jsc/javascriptruntime.swg +++ b/Lib/javascript/jsc/javascriptruntime.swg @@ -14,183 +14,6 @@ %} %insert(runtime) "swigrun.swg"; /* SWIG API */ -%insert(runtime) "swigerrors.swg"; /* SWIG errors */ +%insert(runtime) "swigerrors.swg"; /* SWIG errors */ -%insert(runtime) %{ -#define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) -#define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) -#define SWIG_fail goto fail - -#define SWIG_JSC_FROM_DECL_ARGS(arg1) (JSContextRef context, arg1) -#define SWIG_JSC_FROM_CALL_ARGS(arg1) (context, arg1) -#define SWIG_JSC_AS_DECL_ARGS(arg1, arg2) (JSContextRef context, arg1, arg2) -#define SWIG_JSC_AS_CALL_ARGS(arg1, arg2) (context, arg1, arg2) -%} - -%insert(runtime) %{ -typedef struct { - bool swigCMemOwn; - void *swigCObject; - swig_type_info *info; -}SWIG_PRV_DATA; -%} - -%insert(runtime) %{ - -void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) { - JSStringRef message = JSStringCreateWithUTF8CString(type); - *exception = JSValueMakeString(context, message); - JSStringRelease(message); -} - -void SWIG_JSC_exception(JSContextRef context, JSValueRef *exception, int code, const char* msg) { - SWIG_Javascript_Raise(context, exception, msg); -} - -%} - -%insert(runtime) %{ - -JSValueRef _wrap_SwigObject_disown(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - JSValueRef jsresult; - - JSObjectRef obj = JSValueToObject(context, thisObject, NULL); - SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) JSObjectGetPrivate(obj); - - cdata->swigCMemOwn = false; - - jsresult = JSValueMakeUndefined(context); - return jsresult; -} - -JSValueRef _wrap_SwigObject_getCPtr(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - JSValueRef jsresult; - long result; - - JSObjectRef obj = JSValueToObject(context, thisObject, NULL); - SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA*) JSObjectGetPrivate(obj); - - result = (long) cdata->swigCObject; - jsresult = JSValueMakeNumber(context, result); - - return jsresult; -} - -JSValueRef _wrap_SwigObject_equals(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - JSValueRef jsresult; - bool result; - - JSObjectRef obj = JSValueToObject(context, thisObject, NULL); - SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA*) JSObjectGetPrivate(obj); - - JSObjectRef obj2 = JSValueToObject(context, argv[0], NULL); - SWIG_PRV_DATA *cdata2 = (SWIG_PRV_DATA*) JSObjectGetPrivate(obj2); - - result = (cdata->swigCObject == cdata2->swigCObject); - jsresult = JSValueMakeBoolean(context, result); - - return jsresult; -} - -JSStaticValue _SwigObject_values[] = { - { - 0, 0, 0, 0 - } -}; - -JSStaticFunction _SwigObject_functions[] = { - { - "disown",_wrap_SwigObject_disown, kJSPropertyAttributeNone - }, - { - "equals",_wrap_SwigObject_equals, kJSPropertyAttributeNone - }, - { - "getCPtr",_wrap_SwigObject_getCPtr, kJSPropertyAttributeNone - }, - { - 0, 0, 0 - } -}; - -JSClassDefinition _SwigObject_objectDefinition; - -JSClassRef _SwigObject_classRef; - -%} - - -%insert(runtime) %{ -int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef objRef, void** ptr, swig_type_info *info, int flags) { - SWIG_PRV_DATA *cdata = (SWIG_PRV_DATA *) JSObjectGetPrivate(objRef); - if(cdata == NULL) { - return SWIG_ERROR; - } - if(cdata->info != info) { - bool type_valid = false; - swig_cast_info *t = info->cast; - while(t != NULL) { - if(t->type == cdata->info) { - type_valid = true; - break; - } - t = t->next; - } - if(!type_valid) { - return SWIG_TypeError; - } - } - - *ptr = cdata->swigCObject; - - if(flags & SWIG_POINTER_DISOWN) { - cdata->swigCMemOwn = false; - } - - return SWIG_OK; -} - -int SWIG_JSC_ConvertPtr(JSContextRef context, JSValueRef valRef, void** ptr, swig_type_info *info, int flags) { - if(!JSValueIsObject(context, valRef)) { - return SWIG_TypeError; - } - - JSObjectRef objRef = JSValueToObject(context, valRef, NULL); - if(objRef == NULL) { - return SWIG_ERROR; - } - - return SWIG_JSC_ConvertInstancePtr(context, objRef, ptr, info, flags); -} - -JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_info *info, int flags) { - - JSClassRef classRef; - if(info->clientdata == NULL) { - classRef = _SwigObject_classRef; - } else { - classRef = (JSClassRef) info->clientdata; - } - - JSObjectRef result = JSObjectMake(context, classRef, NULL); - - SWIG_PRV_DATA* cdata = (SWIG_PRV_DATA*) malloc(sizeof(SWIG_PRV_DATA)); - cdata->swigCObject = ptr; - cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; - cdata->info = info; - - JSObjectSetPrivate(result, cdata); - - return result; -} - -#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_JSC_ConvertPtr(context, obj, ptr, info, flags) -#define SWIG_NewPointerObj(ptr, info, flags) SWIG_JSC_NewPointerObj(context, ptr, info, flags) - -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) -#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) - -%} +%insert(runtime) "javascriptrun.swg"; /* SWIG errors */ diff --git a/Lib/javascript/jsc/javascripttypemaps.swg b/Lib/javascript/jsc/javascripttypemaps.swg index aa0a829f9..12e78dc2f 100644 --- a/Lib/javascript/jsc/javascripttypemaps.swg +++ b/Lib/javascript/jsc/javascripttypemaps.swg @@ -8,6 +8,7 @@ /* These macros are necessary to provide an extra parameter to SWIG_AsVal_dec functions (JSContextRef context). + They must be defined before including `typemaps/fragments.swg` */ #define SWIG_FROM_DECL_ARGS SWIG_JSC_FROM_DECL_ARGS #define SWIG_FROM_CALL_ARGS SWIG_JSC_FROM_CALL_ARGS @@ -42,5 +43,12 @@ /* raise */ #define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise(context, exception, type) +%insert("runtime") %{ +#define SWIG_JSC_FROM_DECL_ARGS(arg1) (JSContextRef context, arg1) +#define SWIG_JSC_FROM_CALL_ARGS(arg1) (context, arg1) +#define SWIG_JSC_AS_DECL_ARGS(arg1, arg2) (JSContextRef context, arg1, arg2) +#define SWIG_JSC_AS_CALL_ARGS(arg1, arg2) (context, arg1, arg2) +%} + /* Include the unified typemap library */ %include diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index d12f56f09..58ed18d0d 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -137,7 +137,6 @@ void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWI } delete proxy; - object.Clear(); #if (SWIG_V8_VERSION < 0x031900) object.Dispose(); diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg new file mode 100644 index 000000000..227977b16 --- /dev/null +++ b/Lib/javascript/v8/javascriptrun.swg @@ -0,0 +1,444 @@ +/* ---------------------------------------------------------------------------*/ +/* Error handling +/* +/* ---------------------------------------------------------------------------*/ + +#define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) +#define SWIG_exception(code, msg) SWIGV8_ErrorHandler.error(code, msg) +#define SWIG_fail goto fail +#define SWIGV8_OVERLOAD false + +void SWIG_V8_Raise(const char* msg) { + v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); +} + +/* + Note: There are two contexts for handling errors. + A static V8ErrorHandler is used in not overloaded methods. + For overloaded methods the throwing type checking mechanism is used + during dispatching. As V8 exceptions can not be resetted properly + the trick is to use a dynamic ErrorHandler with same local name as the global + one. + + - See defintion of SWIG_Error above. + - See code templates 'JS_function_dispatcher', 'JS_functionwrapper_overload', + and 'JS_function_dispatch_case' in javascriptcode.swg + +*/ +class V8ErrorHandler { +public: + virtual ~V8ErrorHandler() {} + virtual void error(int code, const char* msg) { + SWIG_V8_Raise(msg); + } +}; +// this is used in usually +V8ErrorHandler SWIGV8_ErrorHandler; + +// instances of this are used in overloaded functions +class OverloadErrorHandler: public V8ErrorHandler { +public: + virtual void error(int code, const char* msg) { + err = v8::Exception::Error(v8::String::New(msg)); + if(code != SWIG_TypeError) { + v8::ThrowException(err); + } + } + v8::Handle err; +}; + +// Note: these typedefs and defines are used to deal with v8 API changes since version 3.19.00 + +#if (SWIG_V8_VERSION < 0x031900) +typedef v8::Handle SwigV8ReturnValue; +typedef v8::Arguments SwigV8Arguments; +typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) return scope.Close(val) +#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) +#else +typedef void SwigV8ReturnValue; +typedef v8::FunctionCallbackInfo SwigV8Arguments; +typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return +#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return +#endif + + +/* ---------------------------------------------------------------------------*/ +/* Basic Proxy object +/* +/* ---------------------------------------------------------------------------*/ + +// Note: to trigger the v8 gc more often one can tell v8 about the memory consumption +// TODO: we could add a v8 specific parameter to control this value +#define SWIGV8_AVG_OBJ_SIZE 1000 + +class SWIGV8_Proxy { +public: + SWIGV8_Proxy(): swigCMemOwn(false), swigCObject(0), info(0) { + v8::V8::AdjustAmountOfExternalAllocatedMemory(SWIGV8_AVG_OBJ_SIZE); + }; + + ~SWIGV8_Proxy() { +#if (SWIG_V8_VERSION < 0x031900 || SWIG_V8_VERSION >= 0x032100) + handle.ClearWeak(); + handle.Dispose(); +#else + handle.ClearWeak(v8::Isolate::GetCurrent()); + handle.Dispose(v8::Isolate::GetCurrent()); +#endif + + handle.Clear(); + v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); + } + + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; + v8::Persistent handle; +}; + +class SWIGV8_ClientData { +public: + v8::Persistent class_templ; + +#if (SWIG_V8_VERSION < 0x031900) + void (*dtor) (v8::Persistent< v8::Value> object, void *parameter); +#else + void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); +#endif +}; + +v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; + +int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); +#else + SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + + if(cdata == NULL) { + return SWIG_ERROR; + } + if(cdata->info != info) { + swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info); + if (!tc && cdata->info->name) { + tc = SWIG_TypeCheck(cdata->info->name, info); + } + bool type_valid = tc != 0; + if(!type_valid) { + return SWIG_TypeError; + } + } + *ptr = cdata->swigCObject; + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + return SWIG_OK; +} + +#if (SWIG_V8_VERSION < 0x031900) +void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) +#else +void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) +#endif +{ +#if (SWIG_V8_VERSION < 0x031900) + SWIGV8_Proxy *proxy = static_cast(parameter); +#endif + + delete proxy; +} + +int SWIG_V8_GetInstancePtr(v8::Handle valRef, void** ptr) { + if(!valRef->IsObject()) { + return SWIG_TypeError; + } + v8::Handle objRef = valRef->ToObject(); + + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); +#else + SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + + if(cdata == NULL) { + return SWIG_ERROR; + } + + *ptr = cdata->swigCObject; + + return SWIG_OK; +} + +void SWIGV8_SetPrivateData(v8::Handle 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; + +#if (SWIG_V8_VERSION < 0x031900) + obj->SetPointerInInternalField(0, cdata); + cdata->handle = v8::Persistent::New(obj); +#else + obj->SetAlignedPointerInInternalField(0, cdata); + cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); +#endif + +#if (SWIG_V8_VERSION < 0x031900) + // clientdata must be set for owned data as we need to register the dtor + if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { + cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); + } else { + cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); + } + cdata->handle.MarkIndependent(); +#else + if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); + } else { + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor); + } + +#if (SWIG_V8_VERSION < 0x032100) + cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); +#else + cdata->handle.MarkIndependent(); +#endif + +#endif +} + +int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + + if(!valRef->IsObject()) { + return SWIG_TypeError; + } + v8::Handle objRef = valRef->ToObject(); + return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags); +} + +v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + v8::Handle class_templ; + +#if (SWIG_V8_VERSION < 0x031900) + if(info->clientdata != 0) { + class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; + } else { + class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ; + } +#else + v8::Isolate *iso = v8::Isolate::GetCurrent(); + + if(info->clientdata != 0) { + class_templ = v8::Handle::New(iso, ((SWIGV8_ClientData*) info->clientdata)->class_templ); + } else { + class_templ = v8::Handle::New(iso, SWIGV8_SWIGTYPE_Proxy_class_templ); + } +#endif + + v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); + SWIGV8_SetPrivateData(result, ptr, info, flags); + + return scope.Close(result); +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_V8_ConvertPtr(obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_V8_NewPointerObj(ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_V8_ConvertInstancePtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_V8_NewPointerObj(thisvalue, type, flags) + +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_V8_ConvertPtr(obj, pptr, type, 0) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_V8_NewPointerObj(ptr, type, 0) + +#define SWIG_GetInstancePtr(obj, ptr) SWIG_V8_GetInstancePtr(obj, ptr) + +#if (SWIG_V8_VERSION < 0x031900) +v8::Handle _SWIGV8_wrap_equals(const v8::Arguments &args) { +#else +void _SWIGV8_wrap_equals(const v8::FunctionCallbackInfo& args) { +#endif + v8::HandleScope scope; + v8::Handle jsresult; + void *arg1 = (void *) 0 ; + void *arg2 = (void *) 0 ; + bool result; + int res1; + int res2; + + if(args.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for equals."); + + res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ERROR, "Could not get pointer from 'this' object for equals."); + } + res2 = SWIG_GetInstancePtr(args[0], &arg2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "equals" "', argument " "1"" of type '" "void *""'"); + } + + result = (bool)(arg1 == arg2); + jsresult = v8::Boolean::New(result); + + SWIGV8_RETURN(jsresult); + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} + +#if (SWIG_V8_VERSION < 0x031900) +v8::Handle _wrap_getCPtr(const v8::Arguments &args) { +#else +void _wrap_getCPtr(const v8::FunctionCallbackInfo& args) { +#endif + v8::HandleScope scope; + v8::Handle jsresult; + void *arg1 = (void *) 0 ; + long result; + int res1; + + res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getCPtr" "', argument " "1"" of type '" "void *""'"); + } + + result = (long)arg1; + jsresult = v8::Number::New(result); + + SWIGV8_RETURN(jsresult); + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} + +/* ---------------------------------------------------------------------------*/ +/* PackedData object +/* +/* ---------------------------------------------------------------------------*/ + +class SwigV8PackedData { +public: + SwigV8PackedData(void *data, size_t size, swig_type_info *type): data(data), size(size), type(type) {}; + + ~SwigV8PackedData() { + }; + + void* data; + size_t size; + swig_type_info *type; + + v8::Persistent handle; +}; + +SWIGRUNTIMEINLINE +int SwigV8Packed_Check(v8::Handle valRef) { + v8::HandleScope scope; + v8::Handle objRef = valRef->ToObject(); + if(objRef->InternalFieldCount() < 1) return false; + v8::Handle flag = objRef->GetHiddenValue(v8::String::New("__swig__packed_data__")); + return (flag->IsBoolean() && flag->BooleanValue()); +} + +SWIGRUNTIME +swig_type_info* SwigV8Packed_UnpackData(v8::Handle valRef, void *ptr, size_t size) { + if (SwigV8Packed_Check(valRef)) { + v8::HandleScope scope; + SwigV8PackedData *sobj; + + v8::Handle objRef = valRef->ToObject(); + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + sobj = static_cast(v8::External::Unwrap(cdataRef)); +#else + sobj = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + if (sobj == NULL || sobj->size != size) return 0; + memcpy(ptr, sobj->data, size); + return sobj->type; + } else { + return 0; + } +} + +SWIGRUNTIME +int SWIGV8_ConvertPacked(v8::Handle valRef, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigV8Packed_UnpackData(valRef, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +#if (SWIG_V8_VERSION < 0x031900) +void _wrap_SwigV8PackedData_delete(v8::Persistent< v8::Value > object, void *parameter) +{ + SwigV8PackedData *cdata = static_cast(parameter); +#else +void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SwigV8PackedData *proxy) +{ +#endif + + delete cdata; + + object.Clear(); +#if (SWIG_V8_VERSION < 0x031900) + object.Dispose(); +#elif (SWIG_V8_VERSION < 0x032100) + object->Dispose(isolate); +#else + object->Dispose(); +#endif +} + +SWIGRUNTIME +v8::Handle SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type) { + v8::HandleScope scope; + + SwigV8PackedData* cdata = new SwigV8PackedData(data, size, type); + v8::Handle obj = v8::Object::New(); + + obj->SetHiddenValue(v8::String::New("__swig__packed_data__"), v8::Boolean::New(true)); + +#if (SWIG_V8_VERSION < 0x031900) + obj->SetPointerInInternalField(0, cdata); + cdata->handle = v8::Persistent::New(obj); +#else + obj->SetAlignedPointerInInternalField(0, cdata); + cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); +#endif + +#if (SWIG_V8_VERSION < 0x031900) + cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete); + cdata->handle.MarkIndependent(); +#else + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, _wrap_SwigV8PackedData_delete); +# if (SWIG_V8_VERSION < 0x032100) + cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); +# else + cdata->handle.MarkIndependent(); +# endif +#endif + + return scope.Close(obj); +} + +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIGV8_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIGV8_NewPackedObj(ptr, sz, type) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index c34b62108..8df5816a9 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -1,7 +1,6 @@ /* ----------------------------------------------------------------------------- * javascriptruntime.swg * - * Javascript support code * ----------------------------------------------------------------------------- */ %define %swig_v8_define_version(version) @@ -35,322 +34,5 @@ %insert(runtime) "swigrun.swg"; /* SWIG API */ %insert(runtime) "swigerrors.swg"; /* SWIG errors */ -%insert(runtime) %{ -#if (SWIG_V8_VERSION < 0x031900) -typedef v8::Handle SwigV8ReturnValue; -typedef v8::Arguments SwigV8Arguments; -typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; -#define SWIGV8_RETURN(val) return scope.Close(val) -#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) -#else -typedef void SwigV8ReturnValue; -typedef v8::FunctionCallbackInfo SwigV8Arguments; -typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; -#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return -#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return -#endif -%} +%insert(runtime) "javascriptrun.swg" -%insert(runtime) %{ -#define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) -#define SWIG_exception(code, msg) SWIGV8_ErrorHandler.error(code, msg) -#define SWIG_fail goto fail -#define SWIGV8_OVERLOAD false - -void SWIG_V8_Raise(const char* msg) { - v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); -} - -/* - Note: There are two contexts for handling errors. - A static V8ErrorHandler is used in not overloaded methods. - For overloaded methods the throwing type checking mechanism is used - during dispatching. As V8 exceptions can not be resetted properly - the trick is to use a dynamic ErrorHandler with same local name as the global - one. - - - See defintion of SWIG_Error above. - - See code templates 'JS_function_dispatcher', 'JS_functionwrapper_overload', - and 'JS_function_dispatch_case' in javascriptcode.swg - -*/ -class V8ErrorHandler { -public: - virtual ~V8ErrorHandler() {} - virtual void error(int code, const char* msg) { - SWIG_V8_Raise(msg); - } -}; -// this is used in usually -V8ErrorHandler SWIGV8_ErrorHandler; - -// instances of this are used in overloaded functions -class OverloadErrorHandler: public V8ErrorHandler { -public: - virtual void error(int code, const char* msg) { - err = v8::Exception::Error(v8::String::New(msg)); - if(code != SWIG_TypeError) { - v8::ThrowException(err); - } - } - v8::Handle err; -}; -%} - -%insert(runtime) %{ - -// Note: to trigger the v8 gc more often one can tell v8 about the memory consumption -// TODO: we could add a v8 specific parameter to control this value -#define SWIGV8_AVG_OBJ_SIZE 1000 - -class SWIGV8_Proxy { -public: - SWIGV8_Proxy(): swigCMemOwn(false), swigCObject(0), info(0) { - v8::V8::AdjustAmountOfExternalAllocatedMemory(SWIGV8_AVG_OBJ_SIZE); - }; - - ~SWIGV8_Proxy() { -#if (SWIG_V8_VERSION < 0x031900 || SWIG_V8_VERSION >= 0x032100) - handle.ClearWeak(); - handle.Dispose(); -#else - handle.ClearWeak(v8::Isolate::GetCurrent()); - handle.Dispose(v8::Isolate::GetCurrent()); -#endif - - handle.Clear(); - v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); - } - - bool swigCMemOwn; - void *swigCObject; - swig_type_info *info; - v8::Persistent handle; -}; - -class SWIGV8_ClientData { -public: - v8::Persistent class_templ; - -#if (SWIG_V8_VERSION < 0x031900) - void (*dtor) (v8::Persistent< v8::Value> object, void *parameter); -#else - void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); -#endif -}; - -v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; - -int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { - v8::HandleScope scope; - - if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; - -#if (SWIG_V8_VERSION < 0x031900) - v8::Handle cdataRef = objRef->GetInternalField(0); - SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); -#else - SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); -#endif - - if(cdata == NULL) { - return SWIG_ERROR; - } - if(cdata->info != info) { - swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info); - if (!tc && cdata->info->name) { - tc = SWIG_TypeCheck(cdata->info->name, info); - } - bool type_valid = tc != 0; - if(!type_valid) { - return SWIG_TypeError; - } - } - *ptr = cdata->swigCObject; - if(flags & SWIG_POINTER_DISOWN) { - cdata->swigCMemOwn = false; - } - return SWIG_OK; -} - -#if (SWIG_V8_VERSION < 0x031900) -void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) -#else -void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) -#endif -{ -#if (SWIG_V8_VERSION < 0x031900) - SWIGV8_Proxy *proxy = static_cast(parameter); -#endif - - delete proxy; -} - -int SWIG_V8_GetInstancePtr(v8::Handle valRef, void** ptr) { - if(!valRef->IsObject()) { - return SWIG_TypeError; - } - v8::Handle objRef = valRef->ToObject(); - - if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; - -#if (SWIG_V8_VERSION < 0x031900) - v8::Handle cdataRef = objRef->GetInternalField(0); - SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); -#else - SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); -#endif - - if(cdata == NULL) { - return SWIG_ERROR; - } - - *ptr = cdata->swigCObject; - - return SWIG_OK; -} - -void SWIGV8_SetPrivateData(v8::Handle 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; - -#if (SWIG_V8_VERSION < 0x031900) - obj->SetPointerInInternalField(0, cdata); - cdata->handle = v8::Persistent::New(obj); -#else - obj->SetAlignedPointerInInternalField(0, cdata); - cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); -#endif - -#if (SWIG_V8_VERSION < 0x031900) - // clientdata must be set for owned data as we need to register the dtor - if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { - cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); - } else { - cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); - } - cdata->handle.MarkIndependent(); -#else - if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { - cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); - } else { - cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor); - } - -# if (SWIG_V8_VERSION < 0x032100) - cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); -# else - cdata->handle.MarkIndependent(); -# endif - -#endif -} - -int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { - v8::HandleScope scope; - - if(!valRef->IsObject()) { - return SWIG_TypeError; - } - v8::Handle objRef = valRef->ToObject(); - return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags); -} - -v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { - v8::HandleScope scope; - v8::Handle class_templ; - - -#if (SWIG_V8_VERSION < 0x031900) - if(info->clientdata != 0) { - class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; - } else { - class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ; - } -#else - v8::Isolate *iso = v8::Isolate::GetCurrent(); - - if(info->clientdata != 0) { - class_templ = v8::Handle::New(iso, ((SWIGV8_ClientData*) info->clientdata)->class_templ); - } else { - class_templ = v8::Handle::New(iso, SWIGV8_SWIGTYPE_Proxy_class_templ); - } -#endif - - v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); - SWIGV8_SetPrivateData(result, ptr, info, flags); - - return scope.Close(result); -} - -#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_V8_ConvertPtr(obj, ptr, info, flags) -#define SWIG_NewPointerObj(ptr, info, flags) SWIG_V8_NewPointerObj(ptr, info, flags) - -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_V8_ConvertInstancePtr(obj, pptr, type, flags) -#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_V8_NewPointerObj(thisvalue, type, flags) - -#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_V8_ConvertPtr(obj, pptr, type, 0) -#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_V8_NewPointerObj(ptr, type, 0) - -#define SWIG_GetInstancePtr(obj, ptr) SWIG_V8_GetInstancePtr(obj, ptr) - -#if (SWIG_V8_VERSION < 0x031900) -v8::Handle _SWIGV8_wrap_equals(const v8::Arguments &args) { -#else -void _SWIGV8_wrap_equals(const v8::FunctionCallbackInfo& args) { -#endif - v8::HandleScope scope; - v8::Handle jsresult; - void *arg1 = (void *) 0 ; - void *arg2 = (void *) 0 ; - bool result; - int res1; - int res2; - - if(args.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for equals."); - - res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ERROR, "Could not get pointer from 'this' object for equals."); - } - res2 = SWIG_GetInstancePtr(args[0], &arg2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "equals" "', argument " "1"" of type '" "void *""'"); - } - - result = (bool)(arg1 == arg2); - jsresult = v8::Boolean::New(result); - - SWIGV8_RETURN(jsresult); - goto fail; -fail: - SWIGV8_RETURN(v8::Undefined()); -} - -#if (SWIG_V8_VERSION < 0x031900) -v8::Handle _wrap_getCPtr(const v8::Arguments &args) { -#else -void _wrap_getCPtr(const v8::FunctionCallbackInfo& args) { -#endif - v8::HandleScope scope; - v8::Handle jsresult; - void *arg1 = (void *) 0 ; - long result; - int res1; - - res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getCPtr" "', argument " "1"" of type '" "void *""'"); - } - - result = (long)arg1; - jsresult = v8::Number::New(result); - - SWIGV8_RETURN(jsresult); - goto fail; -fail: - SWIGV8_RETURN(v8::Undefined()); -} -%} From 001f38c6a9ebd19dee26196e9b0ee2421b8cbe5f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 10 Sep 2013 13:29:16 +0300 Subject: [PATCH 193/352] Fix settings for building nodejs tests. Removed the `-node` command line flag. Instead one has to use `-v8 -DBUILDING_NODE_EXTENSION=1`. --- Examples/test-suite/javascript/Makefile.in | 2 +- .../javascript/node_template/binding.gyp.in | 3 +++ Lib/javascript/jsc/javascriptrun.swg | 24 +++++++++---------- Lib/javascript/v8/javascriptrun.swg | 24 +++++++++---------- Source/Modules/javascript.cxx | 7 ------ 5 files changed, 28 insertions(+), 32 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index ad08b2360..48ce7cdbb 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -88,7 +88,7 @@ ifeq ("node",$(JSENGINE)) __setup = \ if [ ! -f $(srcdir)/$*/binding.gyp ]; then \ sh ./setup_test.sh $*; \ - $(SWIG) -c++ -javascript -node -o $*/$*_wrap.cxx ../$*.i; \ + $(SWIG) -c++ -javascript -v8 -DBUILDING_NODE_EXTENSION=1 -I$(top_srcdir)/Examples/test-suite -includeall -o $*/$*_wrap.cxx ../$*.i; \ fi nodejs_swig_and_compile = \ diff --git a/Examples/test-suite/javascript/node_template/binding.gyp.in b/Examples/test-suite/javascript/node_template/binding.gyp.in index 2895d3080..dffd52c6c 100644 --- a/Examples/test-suite/javascript/node_template/binding.gyp.in +++ b/Examples/test-suite/javascript/node_template/binding.gyp.in @@ -4,6 +4,9 @@ "target_name": "$testcase", "sources":[ "$testcase_wrap.cxx" ], "include_dirs": ["../.."], + 'defines': [ + 'BUILDING_NODE_EXTENSION=1', + ], 'conditions': [ ['OS=="mac"', { diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg index 3038fcd71..c8f16f36f 100644 --- a/Lib/javascript/jsc/javascriptrun.swg +++ b/Lib/javascript/jsc/javascriptrun.swg @@ -1,7 +1,7 @@ -/*****************************************************************************/ -/* Errors and exceptions -/* -/*****************************************************************************/ +/* ---------------------------------------------------------------------------- + * Errors and exceptions + * + * ---------------------------------------------------------------------------*/ #define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) #define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) @@ -17,10 +17,10 @@ void SWIG_JSC_exception(JSContextRef context, JSValueRef *exception, int code, c SWIG_Javascript_Raise(context, exception, msg); } -/*****************************************************************************/ -/* The parent class of all Proxies -/* -/*****************************************************************************/ +/* ---------------------------------------------------------------------------- + * The parent class of all Proxies + * + * ---------------------------------------------------------------------------*/ typedef struct { bool swigCMemOwn; @@ -167,10 +167,10 @@ JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_in #define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) #define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) -/*****************************************************************************/ -/* A class for packed data -/* -/*****************************************************************************/ +/* ---------------------------------------------------------------------------- + * A class for packed data + * + * ---------------------------------------------------------------------------*/ typedef struct { void *data; diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg index 227977b16..bab81613c 100644 --- a/Lib/javascript/v8/javascriptrun.swg +++ b/Lib/javascript/v8/javascriptrun.swg @@ -1,7 +1,7 @@ -/* ---------------------------------------------------------------------------*/ -/* Error handling -/* -/* ---------------------------------------------------------------------------*/ +/* --------------------------------------------------------------------------- + * Error handling + * + * ---------------------------------------------------------------------------*/ #define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) #define SWIG_exception(code, msg) SWIGV8_ErrorHandler.error(code, msg) @@ -64,10 +64,10 @@ typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; #endif -/* ---------------------------------------------------------------------------*/ -/* Basic Proxy object -/* -/* ---------------------------------------------------------------------------*/ +/* --------------------------------------------------------------------------- + * Basic Proxy object + * + * ---------------------------------------------------------------------------*/ // Note: to trigger the v8 gc more often one can tell v8 about the memory consumption // TODO: we could add a v8 specific parameter to control this value @@ -323,10 +323,10 @@ fail: SWIGV8_RETURN(v8::Undefined()); } -/* ---------------------------------------------------------------------------*/ -/* PackedData object -/* -/* ---------------------------------------------------------------------------*/ +/* --------------------------------------------------------------------------- + * PackedData object + * + * ---------------------------------------------------------------------------*/ class SwigV8PackedData { public: diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 876978a42..0a8b4931e 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -532,11 +532,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { Swig_mark_arg(i); mode = JSEmitter::V8; SWIG_library_directory("javascript/v8"); - } else if (strcmp(argv[i], "-node") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::V8; - SWIG_library_directory("javascript/v8"); - Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); } else if (strcmp(argv[i], "-jsc") == 0) { Swig_mark_arg(i); mode = JSEmitter::JavascriptCore; @@ -544,8 +539,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { Swig_mark_arg(i); js_template_enable_debug = true; - } else if (strcmp(argv[i], "-no-moduleobject") == 0) { - Swig_mark_arg(i); } } } From dd84e6f9e0b67737ca1031cd6bbb4dcc4eb84340 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 10 Sep 2013 14:16:36 +0300 Subject: [PATCH 194/352] Some fixes and cleanup in Javascript generator. - v8 generator uses the correct mangled name for class templates - removed symbols for template variables in favor of using the string literals directly, as it is easier to understand when debugging. --- Lib/javascript/v8/javascriptcode.swg | 2 +- Source/Modules/javascript.cxx | 288 +++++++++++---------------- 2 files changed, 121 insertions(+), 169 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 58ed18d0d..1b06dbdc8 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -337,7 +337,7 @@ fail: $jsmangledname_clientData.class_templ.Reset(v8::Isolate::GetCurrent(), $jsmangledname_class); #endif $jsmangledname_clientData.dtor = $jsdtor; - SWIGTYPE$jsmangledtype->clientdata = &$jsmangledname_clientData; + SWIGTYPE_$jsmangledtype->clientdata = &$jsmangledname_clientData; %} diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 0a8b4931e..f86c4aeef 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -23,39 +23,6 @@ bool js_template_enable_debug = false; #define DTOR "dtor" #define ARGCOUNT "wrap:argc" -// variables used in code templates -// ATTENTION: be aware of prefix collisions when defining those variables -#define T_NAME "$jsname" -#define T_NAME_MANGLED "$jsmangledname" -#define T_TYPE "$jstype" -#define T_TYPE_MANGLED "$jsmangledtype" -#define T_WRAPPER "$jswrapper" -#define T_CTOR "$jsctor" -#define T_DTOR "$jsdtor" -#define T_GETTER "$jsgetter" -#define T_SETTER "$jssetter" -#define T_DISPATCH_CASES "$jsdispatchcases" -#define T_BASECLASS "$jsbaseclass" -#define T_NAMESPACE "$jsnspace" -#define T_PARENT "$jsparent" -#define T_OVERLOAD "$jsoverloadext" -#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" -#define V8_CLASS_TEMPLATES "$jsv8classtemplates" -#define V8_WRAPPERS "$jsv8wrappers" -#define V8_INHERITANCE "$jsv8inheritance" -#define V8_CLASS_INSTANCES "$jsv8classinstances" -#define V8_STATIC_WRAPPERS "$jsv8staticwrappers" -#define V8_REGISTER_CLASSES "$jsv8registerclasses" -#define V8_REGISTER_NS "$jsv8registernspaces" - -#define FLAG_NO_MODULE_OBJECT "NO_MODULE_OBJECT" - /** * A convenience class to manage state variables for emitters. * The implementation delegates to swig Hash DOHs and provides @@ -521,11 +488,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { int mode = -1; - // Note: creating a module object is not supported anymore. - // instead the initializer is called with an externally created object - // This makes it obsolete to handle node extensions differently - bool createModuleObject = false; - for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i], "-v8") == 0) { @@ -564,10 +526,6 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } } - if(!createModuleObject) { - SetFlag(emitter->getState().global(), FLAG_NO_MODULE_OBJECT); - } - // Add a symbol to the parser for conditional compilation Preprocessor_define("SWIGJAVASCRIPT 1", 0); @@ -655,12 +613,8 @@ int JSEmitter::initialize(Node * /*n*/) { Delete(namespaces); } namespaces = NewHash(); - Hash *global_namespace; -// if(State::IsSet(state.global(FLAG_NO_MODULE_OBJECT))) { - global_namespace = createNamespaceEntry("exports", 0); -// } else { -// global_namespace = createNamespaceEntry(Char(Getattr(n, "name")), "global"); -// } + Hash *global_namespace = createNamespaceEntry("exports", 0); + Setattr(namespaces, "::", global_namespace); current_namespace = global_namespace; @@ -845,16 +799,16 @@ int JSEmitter::emitCtor(Node *n) { emitCleanupCode(n, wrapper, params); - t_ctor.replace(T_WRAPPER, wrap_name) - .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) - .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) + t_ctor.replace("$jswrapper", wrap_name) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .replace("$jsargcount", Getattr(n, ARGCOUNT)) .pretty_print(f_wrappers); Template t_ctor_case(getTemplate("js_ctor_dispatch_case")); - t_ctor_case.replace(T_WRAPPER, wrap_name) - .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)); + t_ctor_case.replace("$jswrapper", wrap_name) + .replace("$jsargcount", Getattr(n, ARGCOUNT)); Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); DelWrapper(wrapper); @@ -864,9 +818,9 @@ int JSEmitter::emitCtor(Node *n) { if (!Getattr(n, "sym:nextSibling")) { String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); Template t_mainctor(getTemplate("js_ctor_dispatcher")); - t_mainctor.replace(T_WRAPPER, wrap_name) - .replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_DISPATCH_CASES, state.clazz(CTOR_DISPATCHERS)) + t_mainctor.replace("$jswrapper", wrap_name) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS)) .pretty_print(f_wrappers); state.clazz(CTOR, wrap_name); } @@ -980,9 +934,9 @@ int JSEmitter::emitDtor(Node *n) { Template t_dtor = getTemplate("js_dtoroverride"); state.clazz(DTOR, wrap_name); t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) - .replace(T_WRAPPER, wrap_name) - .replace(T_FREE, free) - .replace(T_TYPE, ctype); + .replace("$jswrapper", wrap_name) + .replace("$jsfree", free) + .replace("$jstype", ctype); t_dtor.replace("${destructor_action}", destructor_action); Wrapper_pretty_print(t_dtor.str(), f_wrappers); @@ -990,10 +944,10 @@ int JSEmitter::emitDtor(Node *n) { else { Template t_dtor = getTemplate("js_dtor"); state.clazz(DTOR, wrap_name); - t_dtor.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_WRAPPER, wrap_name) - .replace(T_FREE, free) - .replace(T_TYPE, ctype) + t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jswrapper", wrap_name) + .replace("$jsfree", free) + .replace("$jstype", ctype) .pretty_print(f_wrappers); } @@ -1025,9 +979,9 @@ int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { emitCleanupCode(n, wrapper, params); - t_getter.replace(T_WRAPPER, wrap_name) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) + t_getter.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) .pretty_print(f_wrappers); DelWrapper(wrapper); @@ -1063,9 +1017,9 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { emitCleanupCode(n, wrapper, params); - t_setter.replace(T_WRAPPER, wrap_name) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) + t_setter.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) .pretty_print(f_wrappers); DelWrapper(wrapper); @@ -1102,9 +1056,9 @@ int JSEmitter::emitConstant(Node *n) { assert(value != NULL); marshalOutput(n, wrapper, action, value, false); - t_getter.replace(T_WRAPPER, wrap_name) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) + t_getter.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) .pretty_print(f_wrappers); exitVariable(n); @@ -1142,10 +1096,10 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { emitCleanupCode(n, wrapper, params); - t_function.replace(T_WRAPPER, wrap_name) - .replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code) - .replace(T_ARGCOUNT, Getattr(n, ARGCOUNT)) + t_function.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .replace("$jsargcount", Getattr(n, ARGCOUNT)) .pretty_print(f_wrappers); @@ -1170,8 +1124,8 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { { // handle function overloading Template t_dispatch_case = getTemplate("js_function_dispatch_case"); - t_dispatch_case.replace(T_WRAPPER, siblname) - .replace(T_ARGCOUNT, Getattr(sibl, ARGCOUNT)); + t_dispatch_case.replace("$jswrapper", siblname) + .replace("$jsargcount", Getattr(sibl, ARGCOUNT)); Append(wrapper->code, t_dispatch_case.str()); } @@ -1197,12 +1151,12 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { Setattr(n, "wrap:name", wrap_name); state.function(WRAPPER_NAME, wrap_name); - t_function.replace(T_LOCALS, wrapper->locals) - .replace(T_CODE, wrapper->code); + t_function.replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code); // call this here, to replace all variables - t_function.replace(T_WRAPPER, wrap_name) - .replace(T_NAME, state.function(NAME)) + t_function.replace("$jswrapper", wrap_name) + .replace("$jsname", state.function(NAME)) .pretty_print(f_wrappers); // Delete the state variable @@ -1544,7 +1498,7 @@ int JSCEmitter::dump(Node *n) { Swig_banner(f_wrap_cpp); Template initializer_define(getTemplate("js_initializer_define")); - initializer_define.replace(T_NAME, module).pretty_print(f_header); + initializer_define.replace("$jsname", module).pretty_print(f_header); SwigType_emit_type_table(f_runtime, f_wrappers); @@ -1556,7 +1510,7 @@ int JSCEmitter::dump(Node *n) { // compose the initializer function using a template Template initializer(getTemplate("js_initializer")); - initializer.replace(T_NAME, module) + initializer.replace("$jsname", module) .replace("$jsregisterclasses", state.global(INITIALIZER)) .replace("$jscreatenamespaces", state.global(CREATE_NAMESPACES)) .replace("$jsregisternamespaces", state.global(REGISTER_NAMESPACES)) @@ -1608,8 +1562,8 @@ int JSCEmitter::exitFunction(Node *n) { } } - t_function.replace(T_NAME, state.function(NAME)) - .replace(T_WRAPPER, state.function(WRAPPER_NAME)); + t_function.replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)); if (is_member) { if (GetFlag(state.function(), IS_STATIC)) { @@ -1634,9 +1588,9 @@ int JSCEmitter::enterVariable(Node *n) { int JSCEmitter::exitVariable(Node *n) { Template t_variable(getTemplate("jsc_variable_declaration")); - t_variable.replace(T_NAME, state.variable(NAME)) - .replace(T_GETTER, state.variable(GETTER)) - .replace(T_SETTER, state.variable(SETTER)); + t_variable.replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)); if (GetFlag(n, "ismember")) { if (GetFlag(state.variable(), IS_STATIC) @@ -1660,7 +1614,7 @@ int JSCEmitter::enterClass(Node *n) { state.clazz(STATIC_FUNCTIONS, NewString("")); Template t_class_decl = getTemplate("jsc_class_declaration"); - t_class_decl.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + t_class_decl.replace("$jsmangledname", state.clazz(NAME_MANGLED)) .pretty_print(f_wrappers); return SWIG_OK; @@ -1668,7 +1622,7 @@ int JSCEmitter::enterClass(Node *n) { int JSCEmitter::exitClass(Node *n) { Template t_class_tables(getTemplate("jsc_class_tables")); - t_class_tables.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) + t_class_tables.replace("$jsmangledname", state.clazz(NAME_MANGLED)) .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES)) .replace("$jsclassfunctions", state.clazz(MEMBER_FUNCTIONS)) .replace("$jsstaticclassfunctions", state.clazz(STATIC_FUNCTIONS)) @@ -1682,8 +1636,8 @@ int JSCEmitter::exitClass(Node *n) { // for abstract classes add a vetoing ctor if(GetFlag(state.clazz(), IS_ABSTRACT)) { Template t_veto_ctor(getTemplate("js_veto_ctor")); - t_veto_ctor.replace(T_WRAPPER, state.clazz(CTOR)) - .replace(T_NAME, state.clazz(NAME)) + t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) + .replace("$jsname", state.clazz(NAME)) .pretty_print(f_wrappers); } @@ -1697,11 +1651,11 @@ int JSCEmitter::exitClass(Node *n) { Delete(base_name_mangled); base_name_mangled = SwigType_manglestr(Getattr(base_class, "name")); } - t_classtemplate.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_TYPE_MANGLED, state.clazz(TYPE_MANGLED)) - .replace(T_BASECLASS, base_name_mangled) - .replace(T_CTOR, state.clazz(CTOR)) - .replace(T_DTOR, state.clazz(DTOR)) + t_classtemplate.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jsbaseclass", base_name_mangled) + .replace("$jsctor", state.clazz(CTOR)) + .replace("$jsdtor", state.clazz(DTOR)) .pretty_print(state.global(INITIALIZER)); Delete(base_name_mangled); @@ -1710,9 +1664,9 @@ int JSCEmitter::exitClass(Node *n) { /* adds a class registration statement to initializer function */ Template t_registerclass(getTemplate("jsc_class_registration")); - t_registerclass.replace(T_NAME, state.clazz(NAME)) - .replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_NAMESPACE, Getattr(current_namespace, NAME_MANGLED)) + t_registerclass.replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsnspace", Getattr(current_namespace, NAME_MANGLED)) .pretty_print(state.global(INITIALIZER)); return SWIG_OK; @@ -1741,19 +1695,19 @@ int JSCEmitter::emitNamespaces() { Template namespace_definition(getTemplate("jsc_nspace_declaration")); namespace_definition.replace("$jsglobalvariables", variables) .replace("$jsglobalfunctions", functions) - .replace(T_NAMESPACE, name_mangled) + .replace("$jsnspace", name_mangled) .pretty_print(f_wrap_cpp); Template t_createNamespace(getTemplate("jsc_nspace_definition")); - t_createNamespace.replace(T_NAME_MANGLED, name_mangled); + t_createNamespace.replace("$jsmangledname", name_mangled); Append(state.global(CREATE_NAMESPACES), t_createNamespace.str()); // Don't register 'exports' as namespace. It is return to the application. if (!Equal("exports", name)) { Template t_registerNamespace(getTemplate("jsc_nspace_registration")); - t_registerNamespace.replace(T_NAME_MANGLED, name_mangled) - .replace(T_NAME, name) - .replace(T_PARENT, parent_mangled); + t_registerNamespace.replace("$jsmangledname", name_mangled) + .replace("$jsname", name) + .replace("$jsparent", parent_mangled); Append(state.global(REGISTER_NAMESPACES), t_registerNamespace.str()); } @@ -1882,7 +1836,7 @@ int V8Emitter::dump(Node *) SwigType_emit_type_table(f_runtime, f_wrappers); - // Let's not and say we did + // This is important to have proxies for classes that have not been exposed to swig // emitUndefined(); Printv(f_wrap_cpp, f_runtime, "\n", 0); @@ -1895,15 +1849,15 @@ int V8Emitter::dump(Node *) // compose the initializer function using a template // filled with sub-parts Template initializer(getTemplate("js_initializer")); - initializer.replace(T_NAME, moduleName) - .replace(V8_NAME_SPACES, f_init_namespaces) - .replace(V8_CLASS_TEMPLATES, f_init_class_templates) - .replace(V8_WRAPPERS, f_init_wrappers) - .replace(V8_INHERITANCE, f_init_inheritance) - .replace(V8_CLASS_INSTANCES, f_init_class_instances) - .replace(V8_STATIC_WRAPPERS, f_init_static_wrappers) - .replace(V8_REGISTER_CLASSES, f_init_register_classes) - .replace(V8_REGISTER_NS, f_init_register_namespaces) + initializer.replace("$jsname", moduleName) + .replace("$jsv8nspaces", f_init_namespaces) + .replace("$jsv8classtemplates", f_init_class_templates) + .replace("$jsv8wrappers", f_init_wrappers) + .replace("$jsv8inheritance", f_init_inheritance) + .replace("$jsv8classinstances", f_init_class_instances) + .replace("$jsv8staticwrappers", f_init_static_wrappers) + .replace("$jsv8registerclasses", f_init_register_classes) + .replace("$jsv8registernspaces", f_init_register_namespaces) .pretty_print(f_init); Printv(f_wrap_cpp, f_init, 0); @@ -1943,7 +1897,7 @@ int V8Emitter::enterClass(Node *n) // 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)) + t_decl_class.replace("$jsmangledname", state.clazz(NAME_MANGLED)) .trim() .pretty_print(f_class_templates); @@ -1954,8 +1908,8 @@ int V8Emitter::exitClass(Node *n) { if(GetFlag(state.clazz(), IS_ABSTRACT)) { Template t_veto_ctor(getTemplate("js_veto_ctor")); - t_veto_ctor.replace(T_WRAPPER, state.clazz(CTOR)) - .replace(T_NAME, state.clazz(NAME)) + t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) + .replace("$jsname", state.clazz(NAME)) .pretty_print(f_wrappers); } @@ -1965,20 +1919,18 @@ 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, p_classtype_str) - .replace(T_DTOR, state.clazz(DTOR)) + t_def_class.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jsdtor", state.clazz(DTOR)) .trim() .pretty_print(f_init_class_templates); 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)) + t_class_instance.replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsctor", state.clazz(CTOR)) .trim() .pretty_print(f_init_class_instances); @@ -1990,8 +1942,8 @@ int V8Emitter::exitClass(Node *n) Template t_inherit = getTemplate("jsv8_inherit"); String *base_name_mangled = SwigType_manglestr(base_name); - t_inherit.replace(T_NAME_MANGLED, state.clazz(NAME_MANGLED)) - .replace(T_BASECLASS, base_name_mangled) + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsbaseclass", base_name_mangled) .trim() .pretty_print(f_init_inheritance); Delete(base_name_mangled); @@ -1999,9 +1951,9 @@ int V8Emitter::exitClass(Node *n) // emit registeration of class template 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")) + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.clazz(NAME)) + .replace("$jsparent", Getattr(current_namespace, "name_mangled")) .trim() .pretty_print(f_init_register_classes); @@ -2023,18 +1975,18 @@ int V8Emitter::exitVariable(Node* n) if(GetFlag(n, "ismember")) { if(GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem") ) { 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)) + t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) .trim() .pretty_print(f_init_static_wrappers); } else { 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)) + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) .trim() .pretty_print(f_init_wrappers); } @@ -2042,10 +1994,10 @@ int V8Emitter::exitVariable(Node* n) // 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"); - 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)) + t_register.replace("$jsparent", Getattr(current_namespace, NAME)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) .trim() .pretty_print(f_init_wrappers); } @@ -2073,16 +2025,16 @@ int V8Emitter::exitFunction(Node* n) if(is_member) { if(GetFlag(state.function(), IS_STATIC)) { 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)) + t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) .trim() .pretty_print(f_init_static_wrappers); } else { 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)) + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) .trim() .pretty_print(f_init_wrappers); } @@ -2090,9 +2042,9 @@ int V8Emitter::exitFunction(Node* n) // 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"); - t_register.replace(T_PARENT, Getattr(current_namespace, NAME)) - .replace(T_NAME, state.function(NAME)) - .replace(T_WRAPPER, state.function(WRAPPER_NAME)) + t_register.replace("$jsparent", Getattr(current_namespace, NAME)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) .trim() .pretty_print(f_init_static_wrappers); } @@ -2175,16 +2127,16 @@ int V8Emitter::emitNamespaces() { if (do_create) { // create namespace object and register it to the parent scope Template t_create_ns = getTemplate("jsv8_create_namespace"); - t_create_ns.replace(T_NAME_MANGLED, name_mangled) + t_create_ns.replace("$jsmangledname", name_mangled) .trim() .pretty_print(f_init_namespaces); } if (do_register) { 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) + t_register_ns.replace("$jsmangledname", name_mangled) + .replace("$jsname", name) + .replace("$jsparent", parent_mangled) .trim(); // prepend in order to achieve reversed order of registration statements @@ -2213,24 +2165,24 @@ void V8Emitter::emitUndefined() { // emit clientData declaration Template clientDataDecl = getTemplate("jsv8_declare_class_template"); - clientDataDecl.replace(T_NAME_MANGLED, mangled_name) + clientDataDecl.replace("$jsmangledname", mangled_name) .trim() .pretty_print(f_class_templates); // emit an extra dtor for unknown types Template t_dtor = getTemplate("js_dtor"); - t_dtor.replace(T_NAME_MANGLED, mangled_name) - .replace(T_WRAPPER, dtor) - .replace(T_FREE, free) + t_dtor.replace("$jsmangledname", mangled_name) + .replace("$jswrapper", dtor) + .replace("$jsfree", free) .trim() .pretty_print(f_wrappers); // create a class template and initialize clientData Template clientDataDef = getTemplate("jsv8_define_class_template"); - clientDataDef.replace(T_NAME_MANGLED, mangled_name) - .replace(T_NAME, mangled_name) - .replace(T_TYPE_MANGLED, type_mangled) - .replace(T_DTOR, dtor) + clientDataDef.replace("$jsmangledname", mangled_name) + .replace("$jsname", mangled_name) + .replace("$jsmangledtype", type_mangled) + .replace("$jsdtor", dtor) .trim() .pretty_print(f_init_class_templates); From c53e3e4dab9b6ab61e63880476721c61ec9ff940 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 10 Sep 2013 14:45:33 +0300 Subject: [PATCH 195/352] Fix configuration for nodejs based tests. - use $(SWIGOPT) - less verbose --- Examples/test-suite/javascript/Makefile.in | 23 ++++++++----------- .../javascript/node_template/binding.gyp.in | 2 +- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 48ce7cdbb..70c404e61 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -10,9 +10,9 @@ top_builddir = @top_builddir@ SWIG = $(top_builddir)/preinst_swig ifneq (, $(ENGINE)) - JSENGINE = $(ENGINE) + JSENGINE=$(ENGINE) else - JSENGINE = "node" + JSENGINE=node endif # Note: the javascript generator is not ready yet for the real game. @@ -74,8 +74,6 @@ endif include $(srcdir)/../common.mk -SWIGOPT += -$(JSENGINE) - _setup = \ if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ echo "$(ACTION)ing testcase $* (with run test) under javascript ($(JSENGINE))" ; \ @@ -83,19 +81,16 @@ _setup = \ echo "$(ACTION)ing testcase $* under javascript ($(JSENGINE))" ; \ fi; -ifeq ("node",$(JSENGINE)) +ifeq (node,$(JSENGINE)) + + SWIGOPT += -v8 -DBUILDING_NODE_EXTENSION=1 __setup = \ - if [ ! -f $(srcdir)/$*/binding.gyp ]; then \ - sh ./setup_test.sh $*; \ - $(SWIG) -c++ -javascript -v8 -DBUILDING_NODE_EXTENSION=1 -I$(top_srcdir)/Examples/test-suite -includeall -o $*/$*_wrap.cxx ../$*.i; \ - fi + sh ./setup_test.sh $*; \ + $(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i; nodejs_swig_and_compile = \ - if [ ! -f $(srcdir)/$*/build/Makefile ]; then \ - node-gyp --loglevel=silent --directory $* configure; \ - fi; \ - node-gyp --loglevel=silent --directory $* build; \ + node-gyp --loglevel=silent --directory $* configure build 1>>/dev/null run_testcase = \ if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ @@ -122,6 +117,8 @@ ifeq ("node",$(JSENGINE)) else + SWIGOPT += -$(JSENGINE) + run_testcase = \ if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ $(top_srcdir)/Tools/javascript/javascript -$(JSENGINE) $(srcdir)/$*$(SCRIPTSUFFIX); \ diff --git a/Examples/test-suite/javascript/node_template/binding.gyp.in b/Examples/test-suite/javascript/node_template/binding.gyp.in index dffd52c6c..435381043 100644 --- a/Examples/test-suite/javascript/node_template/binding.gyp.in +++ b/Examples/test-suite/javascript/node_template/binding.gyp.in @@ -2,7 +2,7 @@ "targets": [ { "target_name": "$testcase", - "sources":[ "$testcase_wrap.cxx" ], + "sources":[ "../$testcase_wrap.cxx" ], "include_dirs": ["../.."], 'defines': [ 'BUILDING_NODE_EXTENSION=1', From 09a210e037c8d5ca46ee4edc4c904f11b04cb893 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 12 Sep 2013 04:09:21 +0300 Subject: [PATCH 196/352] Bugfix in Javascript generator: detect member setter/getters correctly. --- Source/Modules/javascript.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index f86c4aeef..8d53d99ec 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -667,16 +667,18 @@ int JSEmitter::emitWrapperFunction(Node *n) { String *kind = Getattr(n, "kind"); if (kind) { - bool is_member = GetFlag(n, "ismember"); if (Cmp(kind, "function") == 0) { + bool is_member = GetFlag(n, "ismember"); bool is_static = GetFlag(state.function(), IS_STATIC); ret = emitFunction(n, is_member, is_static); } else if (Cmp(kind, "variable") == 0) { bool is_static = GetFlag(state.variable(), IS_STATIC); bool is_setter = GetFlag(n, "wrap:issetter"); if (is_setter) { + bool is_member = GetFlag(n, "memberset"); ret = emitSetter(n, is_member, is_static); } else { + bool is_member = GetFlag(n, "memberget"); ret = emitGetter(n, is_member, is_static); } } else { From 8bf95c4356b61da9f510245310a0bd3c1fafe36f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 12 Sep 2013 05:09:35 +0300 Subject: [PATCH 197/352] Bugfix for Javascript generator: avoid duplicate action code generation. --- Source/Modules/javascript.cxx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 8d53d99ec..7b21c42fb 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -791,12 +791,15 @@ int JSEmitter::emitCtor(Node *n) { ParmList *params = Getattr(n, "parms"); emit_parameter_variables(params, wrapper); emit_attach_parmmaps(params, wrapper); + // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemap. + // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere + Delete(wrapper->code); + wrapper->code = NewString(""); Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0)); - String *action = emit_action(n); marshalInputArgs(n, params, wrapper, Ctor, true, false); - + String *action = emit_action(n); Printv(wrapper->code, action, "\n", 0); emitCleanupCode(n, wrapper, params); @@ -1049,13 +1052,14 @@ int JSEmitter::emitConstant(Node *n) { Setattr(n, "wrap:name", wrap_name); // prepare code part - String *action = NewString(""); String *value = Getattr(n, "rawval"); if (value == NULL) { value = Getattr(n, "rawvalue"); if (value == NULL) value = Getattr(n, "value"); } assert(value != NULL); + + String *action = NewString(""); marshalOutput(n, wrapper, action, value, false); t_getter.replace("$jswrapper", wrap_name) @@ -1091,9 +1095,13 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { emit_parameter_variables(params, wrapper); emit_attach_parmmaps(params, wrapper); - // prepare code part - String *action = emit_action(n); + // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemap. + // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere + Delete(wrapper->code); + wrapper->code = NewString(""); + marshalInputArgs(n, params, wrapper, Function, is_member, is_static); + String *action = emit_action(n); marshalOutput(n, wrapper, action); emitCleanupCode(n, wrapper, params); From 1a04e488bc5e17de266181f6b39e00e114f9ae8a Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 12 Sep 2013 05:40:59 +0300 Subject: [PATCH 198/352] Fix Javascript generator for smartpointeraccessed variables. --- Source/Modules/javascript.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 7b21c42fb..d7b6b9ce7 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -673,6 +673,10 @@ int JSEmitter::emitWrapperFunction(Node *n) { ret = emitFunction(n, is_member, is_static); } else if (Cmp(kind, "variable") == 0) { bool is_static = GetFlag(state.variable(), IS_STATIC); + // HACK: smartpointeraccessed static variables are not treated as statics + if (GetFlag(n, "allocate:smartpointeraccess")) { + is_static = false; + } bool is_setter = GetFlag(n, "wrap:issetter"); if (is_setter) { bool is_member = GetFlag(n, "memberset"); From acfed20eba1c72571f65048c62653bf339d5564b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 12 Sep 2013 05:10:23 +0200 Subject: [PATCH 199/352] Bugfix Javascript generator: valid name for dispatcher functions. --- Source/Modules/javascript.cxx | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index d7b6b9ce7..0ca740caf 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1146,21 +1146,17 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { } while ((sibl = Getattr(sibl, "sym:nextSibling"))); - - - Template t_function(getTemplate("js_function_dispatcher")); -// String *wrap_name = Swig_name_wrapper(Getattr(n, "name")); - - - String *fun_name = Getattr(n, "sym:name"); - - Node *methodclass = Swig_methodclass(n); - String *class_name = Getattr(methodclass, "sym:name"); - - String *new_string = NewStringf("%s_%s", class_name, fun_name); - String *wrap_name = Swig_name_wrapper(new_string); + // Note: this dispatcher function gets called after the last overloaded function has been created. + // At this time, n.wrap:name contains the name of the last wrapper function. + // To get a valid function name for the dispatcher function we take the last wrapper name and + // substract the extension "sym:overname", + String *wrap_name = NewString(Getattr(n, "wrap:name")); + String *overname = Getattr(n, "sym:overname"); + int l1 = Len(wrap_name); + int l2 = Len(overname); + Delslice(wrap_name, l1-l2, l1); Setattr(n, "wrap:name", wrap_name); state.function(WRAPPER_NAME, wrap_name); From 477b2393b10f664696b8cf1e49c2b98deab39d79 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 12 Sep 2013 05:26:22 +0200 Subject: [PATCH 200/352] Add stub 'typemaps.i' files. --- Lib/javascript/jsc/typemaps.i | 0 Lib/javascript/v8/typemaps.i | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 Lib/javascript/jsc/typemaps.i create mode 100644 Lib/javascript/v8/typemaps.i diff --git a/Lib/javascript/jsc/typemaps.i b/Lib/javascript/jsc/typemaps.i new file mode 100644 index 000000000..e69de29bb diff --git a/Lib/javascript/v8/typemaps.i b/Lib/javascript/v8/typemaps.i new file mode 100644 index 000000000..e69de29bb From 89fd7ed9c1b1c1e0a1a5344018ab9d0a5ce711b0 Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Sat, 14 Sep 2013 16:17:21 +0400 Subject: [PATCH 201/352] fixed newer v8 compilation --- Lib/javascript/v8/javascriptrun.swg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg index bab81613c..fbdb75c3a 100644 --- a/Lib/javascript/v8/javascriptrun.swg +++ b/Lib/javascript/v8/javascriptrun.swg @@ -392,7 +392,7 @@ void _wrap_SwigV8PackedData_delete(v8::Persistent< v8::Value > object, void *par { SwigV8PackedData *cdata = static_cast(parameter); #else -void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SwigV8PackedData *proxy) +void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SwigV8PackedData *cdata) { #endif From 325b5445d67ccf60855aac970ecb6ba913e2b32b Mon Sep 17 00:00:00 2001 From: Vladimir Menshakov Date: Sat, 14 Sep 2013 16:19:47 +0400 Subject: [PATCH 202/352] removed Clear before Dispose from newer v8 code, consider the following code: template void Persistent::Dispose() { if (this->IsEmpty()) return; //Clear will trigger this V8::DisposeGlobal(reinterpret_cast(this->val_)); ... } --- Lib/javascript/v8/javascriptrun.swg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg index fbdb75c3a..5be16add5 100644 --- a/Lib/javascript/v8/javascriptrun.swg +++ b/Lib/javascript/v8/javascriptrun.swg @@ -398,8 +398,8 @@ void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent< v8::Obj delete cdata; - object.Clear(); #if (SWIG_V8_VERSION < 0x031900) + object.Clear(); object.Dispose(); #elif (SWIG_V8_VERSION < 0x032100) object->Dispose(isolate); From bb7bd50eabdf5cc2f07640227713ef75dc1c8fce Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 00:55:43 +0200 Subject: [PATCH 203/352] Add support for IN/OUTPUT typemaps. --- Lib/javascript/jsc/javascriptrun.swg | 40 ++++++ Lib/javascript/jsc/javascripttypemaps.swg | 2 +- Lib/javascript/jsc/typemaps.i | 148 ++++++++++++++++++++++ Lib/javascript/v8/javascriptrun.swg | 18 +++ Lib/javascript/v8/javascripttypemaps.swg | 4 +- Lib/javascript/v8/typemaps.i | 148 ++++++++++++++++++++++ Source/Modules/javascript.cxx | 44 ++++--- 7 files changed, 382 insertions(+), 22 deletions(-) diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg index c8f16f36f..0e68b7618 100644 --- a/Lib/javascript/jsc/javascriptrun.swg +++ b/Lib/javascript/jsc/javascriptrun.swg @@ -253,3 +253,43 @@ void _wrap_SwigPackedData_delete(JSObjectRef obj) #define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_JSC_ConvertPacked(context, obj, ptr, sz, ty) #define SWIG_NewMemberObj(ptr, sz, type) SWIG_JSC_NewPackedObj(context, ptr, sz, type) + + +/* --------------------------------------------------------------------------- + * Support for IN/OUTPUT typemaps (see Lib/typemaps/inoutlist.swg) + * + * ---------------------------------------------------------------------------*/ + +unsigned int SWIGJSC_ArrayLength(JSContextRef context, JSObjectRef arr) { + static JSStringRef LENGTH = 0; + JSValueRef exception = NULL; + JSValueRef js_length; + double length; + + if (LENGTH == 0) { + LENGTH = JSStringCreateWithUTF8CString("length"); + } + + js_length = JSObjectGetProperty(context, arr, LENGTH, &exception); + if (exception == 0 && JSValueIsNumber(context, js_length)) { + length = JSValueToNumber(context, js_length, 0); + return (unsigned int) length; + } else { + return 0; + } +} + +SWIGRUNTIME +JSValueRef SWIGJSC_AppendOutput(JSContextRef context, JSValueRef value, JSValueRef obj) { + JSObjectRef arr; + unsigned int length; + + if (JSValueIsUndefined(context, value)) { + arr = JSObjectMakeArray(context, 0, 0, 0); + } else { + arr = JSValueToObject(context, value, 0); + } + + length = SWIGJSC_ArrayLength(context, arr); + JSObjectSetPropertyAtIndex(context, arr, length, obj, 0); +} diff --git a/Lib/javascript/jsc/javascripttypemaps.swg b/Lib/javascript/jsc/javascripttypemaps.swg index 12e78dc2f..e8fbbeca8 100644 --- a/Lib/javascript/jsc/javascripttypemaps.swg +++ b/Lib/javascript/jsc/javascripttypemaps.swg @@ -35,7 +35,7 @@ #define VOID_Object JSValueMakeUndefined(context) /* append output */ -#define SWIG_AppendOutput(result, obj) +#define SWIG_AppendOutput(result, obj) SWIGJSC_AppendOutput(context, result, obj) /* set constant */ #define SWIG_SetConstant(name, obj) diff --git a/Lib/javascript/jsc/typemaps.i b/Lib/javascript/jsc/typemaps.i index e69de29bb..d3d8afb19 100644 --- a/Lib/javascript/jsc/typemaps.i +++ b/Lib/javascript/jsc/typemaps.i @@ -0,0 +1,148 @@ +/* ----------------------------------------------------------------------------- + * typemaps.i + * + * Pointer handling + * These mappings provide support for input/output arguments and common + * uses for C/C++ pointers. + * ----------------------------------------------------------------------------- */ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +/* +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + long long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned long long *INPUT + unsigned char *INPUT + bool *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +*/ + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +/* +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Python tuple. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + long long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned long long *OUTPUT + unsigned char *OUTPUT + bool *OUTPUT + float *OUTPUT + double *OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Python output of the function would be a tuple containing both +output values. + +*/ + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + +/* +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Python tuple. + + int *INOUT + short *INOUT + long *INOUT + long long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned long long *INOUT + unsigned char *INOUT + bool *INOUT + float *INOUT + double *INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include + void neg(double *INOUT); + +or you can use the %apply directive : + + %include + %apply double *INOUT { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Python). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Python variable you might do this : + + x = neg(x) + +Note : previous versions of SWIG used the symbol 'BOTH' to mark +input/output arguments. This is still supported, but will be slowly +phased out in future releases. + +*/ + +%include diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg index bab81613c..14936986f 100644 --- a/Lib/javascript/v8/javascriptrun.swg +++ b/Lib/javascript/v8/javascriptrun.swg @@ -442,3 +442,21 @@ v8::Handle SWIGV8_NewPackedObj(void *data, size_t size, swig_type_inf #define SWIG_ConvertMember(obj, ptr, sz, ty) SWIGV8_ConvertPacked(obj, ptr, sz, ty) #define SWIG_NewMemberObj(ptr, sz, type) SWIGV8_NewPackedObj(ptr, sz, type) + + +/* --------------------------------------------------------------------------- + * Support for IN/OUTPUT typemaps (see Lib/typemaps/inoutlist.swg) + * + * ---------------------------------------------------------------------------*/ + +SWIGRUNTIME +v8::Handle SWIGV8_AppendOutput(v8::Handle result, v8::Handle obj) { + v8::HandleScope scope; + if (result->IsUndefined()) { + result = v8::Array::New(); + } + v8::Handle arr = v8::Handle::Cast(result); + arr->Set(arr->Length(), obj); + + return scope.Close(arr); +} diff --git a/Lib/javascript/v8/javascripttypemaps.swg b/Lib/javascript/v8/javascripttypemaps.swg index b12e5c899..90317a1c7 100644 --- a/Lib/javascript/v8/javascripttypemaps.swg +++ b/Lib/javascript/v8/javascripttypemaps.swg @@ -31,13 +31,13 @@ /* Overload of the output/constant/exception/dirout handling */ /* append output */ -#define SWIG_AppendOutput(result, obj) +#define SWIG_AppendOutput(result, obj) SWIGV8_AppendOutput(result, obj) /* set constant */ #define SWIG_SetConstant(name, obj) /* raise */ #define SWIG_Raise(obj, type, desc) SWIG_V8_Raise(type) - + /* Include the unified typemap library */ %include diff --git a/Lib/javascript/v8/typemaps.i b/Lib/javascript/v8/typemaps.i index e69de29bb..d3d8afb19 100644 --- a/Lib/javascript/v8/typemaps.i +++ b/Lib/javascript/v8/typemaps.i @@ -0,0 +1,148 @@ +/* ----------------------------------------------------------------------------- + * typemaps.i + * + * Pointer handling + * These mappings provide support for input/output arguments and common + * uses for C/C++ pointers. + * ----------------------------------------------------------------------------- */ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +/* +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + long long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned long long *INPUT + unsigned char *INPUT + bool *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +*/ + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +/* +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Python tuple. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + long long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned long long *OUTPUT + unsigned char *OUTPUT + bool *OUTPUT + float *OUTPUT + double *OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Python output of the function would be a tuple containing both +output values. + +*/ + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + +/* +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Python tuple. + + int *INOUT + short *INOUT + long *INOUT + long long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned long long *INOUT + unsigned char *INOUT + bool *INOUT + float *INOUT + double *INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include + void neg(double *INOUT); + +or you can use the %apply directive : + + %include + %apply double *INOUT { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Python). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Python variable you might do this : + + x = neg(x) + +Note : previous versions of SWIG used the symbol 'BOTH' to mark +input/output arguments. This is still supported, but will be slowly +phased out in future releases. + +*/ + +%include diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 0ca740caf..2996d6230 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -235,9 +235,9 @@ protected: 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 emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg); - virtual void marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, const String *cresult=0, bool emitReturnVariable = true); + virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult=0, bool emitReturnVariable = true); virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params); @@ -984,7 +984,7 @@ int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { // prepare code part String *action = emit_action(n); marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); - marshalOutput(n, wrapper, action); + marshalOutput(n, params, wrapper, action); emitCleanupCode(n, wrapper, params); @@ -1064,7 +1064,7 @@ int JSEmitter::emitConstant(Node *n) { assert(value != NULL); String *action = NewString(""); - marshalOutput(n, wrapper, action, value, false); + marshalOutput(n, 0, wrapper, action, value, false); t_getter.replace("$jswrapper", wrap_name) .replace("$jslocals", wrapper->locals) @@ -1099,14 +1099,15 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { emit_parameter_variables(params, wrapper); emit_attach_parmmaps(params, wrapper); - // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemap. - // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere + // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generates an extra line of applied typemap. + // Deleting wrapper->code here fixes the problem, and seems to have no side effect elsewhere Delete(wrapper->code); wrapper->code = NewString(""); marshalInputArgs(n, params, wrapper, Function, is_member, is_static); String *action = emit_action(n); - marshalOutput(n, wrapper, action); + + marshalOutput(n, params, wrapper, action); emitCleanupCode(n, wrapper, params); @@ -1210,9 +1211,11 @@ void JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg } } -void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) { +void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) { SwigType *type = Getattr(n, "type"); String *tm; + Parm *p; + // 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 @@ -1226,7 +1229,6 @@ void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, co } if (tm) { - Replaceall(tm, "$result", "jsresult"); Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); if (should_own) { @@ -1242,22 +1244,26 @@ void JSEmitter::marshalOutput(Node *n, Wrapper *wrapper, String *actioncode, co } 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")); } + + if (params) { + for (p = params; p;) { + if ((tm = Getattr(p, "tmap:argout"))) { + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + } + + Replaceall(wrapper->code, "$result", "jsresult"); } void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) { Parm *p; String *tm; - for (p = params; p;) { - if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(wrapper->code, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); - } else { - p = nextSibling(p); - } - } - for (p = params; p;) { if ((tm = Getattr(p, "tmap:freearg"))) { //addThrows(n, "tmap:freearg", p); From b7f827e42ce3073d44f163877f7712782740d1bf Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 01:23:03 +0200 Subject: [PATCH 204/352] Fix typemap declarations for (unsigned) long long. --- Lib/javascript/jsc/javascriptprimtypes.swg | 12 +++++++++--- Lib/javascript/v8/javascriptprimtypes.swg | 19 +++++++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/Lib/javascript/jsc/javascriptprimtypes.swg b/Lib/javascript/jsc/javascriptprimtypes.swg index 2c23cc07f..7e9898a24 100644 --- a/Lib/javascript/jsc/javascriptprimtypes.swg +++ b/Lib/javascript/jsc/javascriptprimtypes.swg @@ -95,7 +95,9 @@ SWIG_AsVal_dec(unsigned long)(JSValueRef obj, unsigned long *val) /* long long */ // Note: these are copied from 'long' and probably need fixing -%fragment(SWIG_From_frag(long long),"header") { +%fragment(SWIG_From_frag(long long),"header", + fragment=SWIG_From_frag(long), + fragment="") { SWIGINTERNINLINE JSValueRef SWIG_From_dec(long long)(long long value) { @@ -104,7 +106,9 @@ SWIG_From_dec(long long)(long long value) } %fragment(SWIG_AsVal_frag(long long),"header", - fragment="SWIG_CanCastAsInteger") { + fragment=SWIG_AsVal_frag(long), + fragment="SWIG_CanCastAsInteger", + fragment="") { SWIGINTERN int SWIG_AsVal_dec(long long)(JSValueRef obj, long long* val) { @@ -132,7 +136,9 @@ SWIG_From_dec(unsigned long long)(unsigned long long value) } %fragment(SWIG_AsVal_frag(unsigned long long),"header", - fragment="SWIG_CanCastAsInteger") { + fragment=SWIG_AsVal_frag(unsigned long), + fragment="SWIG_CanCastAsInteger", + fragment="") { SWIGINTERN int SWIG_AsVal_dec(unsigned long long)(JSValueRef obj, unsigned long long *val) { diff --git a/Lib/javascript/v8/javascriptprimtypes.swg b/Lib/javascript/v8/javascriptprimtypes.swg index 5e0187460..706a799b7 100644 --- a/Lib/javascript/v8/javascriptprimtypes.swg +++ b/Lib/javascript/v8/javascriptprimtypes.swg @@ -110,7 +110,9 @@ int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long *val) /* long long */ // Note: these are copied from 'long' and probably need fixing -%fragment(SWIG_From_frag(long long),"header") { +%fragment(SWIG_From_frag(long long),"header", + fragment=SWIG_From_frag(long), + fragment="") { SWIGINTERNINLINE v8::Handle SWIG_From_dec(long long)(long long value) { @@ -119,9 +121,11 @@ v8::Handle SWIG_From_dec(long long)(long long value) } %fragment(SWIG_AsVal_frag(long long),"header", - fragment="SWIG_CanCastAsInteger") { + fragment=SWIG_AsVal_frag(long), + fragment="SWIG_CanCastAsInteger", + fragment="") { SWIGINTERN -int SWIG_AsVal_dec(long)(v8::Handle obj, long long* val) +int SWIG_AsVal_dec(long long)(v8::Handle obj, long long* val) { if (!obj->IsNumber()) { return SWIG_TypeError; @@ -136,7 +140,8 @@ int SWIG_AsVal_dec(long)(v8::Handle obj, long long* val) // Note: these are copied from 'unsigned long' and probably need fixing %fragment(SWIG_From_frag(unsigned long long),"header", - fragment=SWIG_From_frag(long long)) { + fragment=SWIG_From_frag(long long), + fragment="") { SWIGINTERNINLINE v8::Handle SWIG_From_dec(unsigned long long)(unsigned long long value) { @@ -146,9 +151,11 @@ v8::Handle SWIG_From_dec(unsigned long long)(unsigned long long value } %fragment(SWIG_AsVal_frag(unsigned long long),"header", - fragment="SWIG_CanCastAsInteger") { + fragment=SWIG_AsVal_frag(unsigned long), + fragment="SWIG_CanCastAsInteger", + fragment="") { SWIGINTERN -int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long long *val) +int SWIG_AsVal_dec(unsigned long long)(v8::Handle obj, unsigned long long *val) { if(!obj->IsNumber()) { return SWIG_TypeError; From bf416876ddf24249f75eff9854e551d789dfab42 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 01:33:19 +0200 Subject: [PATCH 205/352] Bugfix for JSC %typemap(out) std::string&. --- Lib/javascript/jsc/std_string.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i index a23396fe6..fb1bd62b5 100755 --- a/Lib/javascript/jsc/std_string.i +++ b/Lib/javascript/jsc/std_string.i @@ -63,7 +63,7 @@ namespace std { %typemap(out) const string & %{ - $result = SWIGJSC_stringToValue(context, $1); + $result = SWIGJSC_stringToValue(context, *$1); %} } From 973042302b017111b06305bedafe47798fcfad86 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 01:57:55 +0200 Subject: [PATCH 206/352] Removed dead code. --- Source/Modules/javascript.cxx | 74 ----------------------------------- 1 file changed, 74 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 2996d6230..e2ca9026a 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -241,8 +241,6 @@ protected: virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params); - void registerProxyType(SwigType* type); - /** * Helper function to retrieve the first parent class node. */ @@ -269,8 +267,6 @@ protected: Hash *namespaces; Hash *current_namespace; - Hash *undefined_types; - String *defaultResultName; File *f_wrappers; @@ -562,7 +558,6 @@ JSEmitter::JSEmitter() : templates(NewHash()), namespaces(NULL), current_namespace(NULL), - undefined_types(NewHash()), defaultResultName(NewString("result")), f_wrappers(NULL) { @@ -1176,20 +1171,6 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { return SWIG_OK; } -void JSEmitter::registerProxyType(SwigType* type) { - SwigType *ftype = SwigType_typedef_resolve_all(type); - if(Language::instance()->classLookup(ftype)) return; - - // TODO: confused... more try and error... understand and fix eventually - SwigType *p_ftype = SwigType_add_pointer(ftype); - - // register undefined wrappers - SwigType_remember_clientdata(p_ftype, 0); - Setattr(undefined_types, SwigType_manglestr(p_ftype), p_ftype); - - 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"); @@ -1223,10 +1204,6 @@ void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, Strin tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode); bool should_own = GetFlag(n, "feature:new"); - bool needs_proxy = GetFlag(n, "tmap:out:SWIGTYPE"); - if(needs_proxy) { - registerProxyType(type); - } if (tm) { Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); @@ -1760,7 +1737,6 @@ protected: virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); virtual int emitNamespaces(); - virtual void emitUndefined(); private: @@ -1852,9 +1828,6 @@ int V8Emitter::dump(Node *) SwigType_emit_type_table(f_runtime, f_wrappers); - // This is important to have proxies for classes that have not been exposed to swig - // emitUndefined(); - 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); @@ -2163,53 +2136,6 @@ int V8Emitter::emitNamespaces() { return SWIG_OK; } -void V8Emitter::emitUndefined() { - Iterator ki; - for (ki = First(undefined_types); ki.item; ki = Next(ki)) { - String *mangled_name = NewStringf("SWIGTYPE%s", ki.key); - SwigType *type = ki.item; - String *dtor = Swig_name_destroy("", mangled_name); - String *type_mangled = ki.key; - 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"); - clientDataDecl.replace("$jsmangledname", mangled_name) - .trim() - .pretty_print(f_class_templates); - - // emit an extra dtor for unknown types - Template t_dtor = getTemplate("js_dtor"); - t_dtor.replace("$jsmangledname", mangled_name) - .replace("$jswrapper", dtor) - .replace("$jsfree", free) - .trim() - .pretty_print(f_wrappers); - - // create a class template and initialize clientData - Template clientDataDef = getTemplate("jsv8_define_class_template"); - clientDataDef.replace("$jsmangledname", mangled_name) - .replace("$jsname", mangled_name) - .replace("$jsmangledtype", type_mangled) - .replace("$jsdtor", dtor) - .trim() - .pretty_print(f_init_class_templates); - - Delete(mangled_name); - Delete(dtor); - Delete(free); - Delete(ctype); - - } -} - JSEmitter *swig_javascript_create_V8Emitter() { return new V8Emitter(); } From 80ce36c445c704a105a70d6820baefb74a7cd0ec Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 02:27:51 +0200 Subject: [PATCH 207/352] Make JSC inheritance definition more robust. --- Lib/javascript/jsc/javascriptcode.swg | 15 ++++++++++++++- Source/Modules/javascript.cxx | 17 ++++++++++++----- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 2660e0e5e..42837f7f4 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -394,11 +394,24 @@ JSStaticFunction $jsmangledname_functions[] = { $jsmangledname_classDefinition.finalize = $jsdtor; $jsmangledname_objectDefinition.staticValues = $jsmangledname_values; $jsmangledname_objectDefinition.staticFunctions = $jsmangledname_functions; - $jsmangledname_objectDefinition.parentClass = $jsbaseclass_classRef; + $jsclass_inheritance JSClassRef $jsmangledname_classRef = JSClassCreate(&$jsmangledname_objectDefinition); SWIGTYPE_$jsmangledtype->clientdata = $jsmangledname_classRef; %} +%fragment ("jsc_class_inherit", templates) +%{ + if (SWIGTYPE_p$jsbaseclassmangled != NULL) { + $jsmangledname_objectDefinition.parentClass = (JSClassRef) SWIGTYPE_p$jsbaseclassmangled->clientdata; + } +%} + +%fragment ("jsc_class_noinherit", templates) +%{ + $jsmangledname_objectDefinition.parentClass = _SwigObject_classRef; +%} + + /* ----------------------------------------------------------------------------- * jsc_register_class: template for registration of a class * - $jsname: class name diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index e2ca9026a..038094a12 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1638,19 +1638,26 @@ int JSCEmitter::exitClass(Node *n) { Template t_classtemplate(getTemplate("jsc_class_definition")); /* prepare registration of base class */ - String *base_name_mangled = NewString("_SwigObject"); + String *jsclass_inheritance = NewString(""); Node *base_class = getBaseClass(n); if (base_class != NULL) { - Delete(base_name_mangled); - base_name_mangled = SwigType_manglestr(Getattr(base_class, "name")); + Template t_inherit(getTemplate("jsc_class_inherit")); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsbaseclassmangled", SwigType_manglestr(Getattr(base_class, "name"))) + .pretty_print(jsclass_inheritance); + } else { + Template t_inherit(getTemplate("jsc_class_noinherit")); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .pretty_print(jsclass_inheritance); } + t_classtemplate.replace("$jsmangledname", state.clazz(NAME_MANGLED)) .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) - .replace("$jsbaseclass", base_name_mangled) + .replace("$jsclass_inheritance", jsclass_inheritance) .replace("$jsctor", state.clazz(CTOR)) .replace("$jsdtor", state.clazz(DTOR)) .pretty_print(state.global(INITIALIZER)); - Delete(base_name_mangled); + Delete(jsclass_inheritance); /* Note: this makes sure that there is a swig_type added for this class */ SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); From 1f07195812f79a20bb1f37178e596dd0bab8ef2e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 03:53:00 +0200 Subject: [PATCH 208/352] Rearrange generation of init block to have custom init code within the initializer body. --- Lib/javascript/jsc/javascriptcode.swg | 50 ----------------- Lib/javascript/jsc/javascriptinit.swg | 54 ++++++++++++++++++- Lib/javascript/v8/javascriptcode.swg | 68 ----------------------- Lib/javascript/v8/javascriptinit.swg | 78 +++++++++++++++++++++++++-- Source/Modules/javascript.cxx | 12 +++-- 5 files changed, 137 insertions(+), 125 deletions(-) diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg index 42837f7f4..60c52b2b3 100644 --- a/Lib/javascript/jsc/javascriptcode.swg +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -263,56 +263,6 @@ int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObjec } %} -%fragment ("js_initializer_define", "templates") %{ -#define SWIGJSC_INIT $jsname_initialize -%} - -/* ----------------------------------------------------------------------------- - * js_initializer: template for the module initializer function - * - $jsname: module name - * - $jscreatenamespaces: part with code for creating namespace objects - * - $jscreateclasses: part with code for creating classes - * - $jsregisternamespaces: part with code for registration of namespaces - * ----------------------------------------------------------------------------- */ -%fragment ("js_initializer", "templates") %{ -#ifdef __cplusplus -extern "C" { -#endif - -bool SWIGJSC_INIT (JSGlobalContextRef context, JSObjectRef *exports) { - SWIG_InitializeModule(0); - - /* Initialize the base swig type object */ - _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; - _SwigObject_objectDefinition.staticValues = _SwigObject_values; - _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); - - /* Initialize the PackedData class */ - _SwigPackedData_objectDefinition.staticFunctions = _SwigPackedData_functions; - _SwigPackedData_objectDefinition.staticValues = _SwigPackedData_values; - _SwigPackedData_objectDefinition.finalize = _wrap_SwigPackedData_delete; - _SwigPackedData_classRef = JSClassCreate(&_SwigPackedData_objectDefinition); - - /* Create objects for namespaces */ - $jscreatenamespaces - - /* Register classes */ - $jsregisterclasses - - /* Register namespaces */ - $jsregisternamespaces - - *exports = exports_object; - - return true; -} - -#ifdef __cplusplus -} -#endif - -%} - /* ----------------------------------------------------------------------------- * jsc_variable_declaration: template for a variable table entry * - $jsname: name of the variable diff --git a/Lib/javascript/jsc/javascriptinit.swg b/Lib/javascript/jsc/javascriptinit.swg index 69bc3a9b1..a32ba336c 100644 --- a/Lib/javascript/jsc/javascriptinit.swg +++ b/Lib/javascript/jsc/javascriptinit.swg @@ -9,7 +9,59 @@ SWIG_JSC_GetModule(void) { #define SWIG_GetModule(clientdata) SWIG_JSC_GetModule() #define SWIG_SetModule(clientdata, pointer) SWIG_JSC_SetModule(pointer) - %} %insert(init) "swiginit.swg" + +%fragment ("js_initializer_define", "templates") %{ +#define SWIGJSC_INIT $jsname_initialize +%} + +// Open the initializer function +%insert(init) +%{ + +#ifdef __cplusplus +extern "C" { +#endif + +bool SWIGJSC_INIT (JSGlobalContextRef context, JSObjectRef *exports) { + SWIG_InitializeModule(0); +%} + +/* ----------------------------------------------------------------------------- + * js_initializer: template for the module initializer function + * - $jsname: module name + * - $jscreatenamespaces: part with code for creating namespace objects + * - $jscreateclasses: part with code for creating classes + * - $jsregisternamespaces: part with code for registration of namespaces + * ----------------------------------------------------------------------------- */ +%fragment ("js_initializer", "templates") %{ + /* Initialize the base swig type object */ + _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; + _SwigObject_objectDefinition.staticValues = _SwigObject_values; + _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + + /* Initialize the PackedData class */ + _SwigPackedData_objectDefinition.staticFunctions = _SwigPackedData_functions; + _SwigPackedData_objectDefinition.staticValues = _SwigPackedData_values; + _SwigPackedData_objectDefinition.finalize = _wrap_SwigPackedData_delete; + _SwigPackedData_classRef = JSClassCreate(&_SwigPackedData_objectDefinition); + + /* Create objects for namespaces */ + $jscreatenamespaces + + /* Register classes */ + $jsregisterclasses + + /* Register namespaces */ + $jsregisternamespaces + + *exports = exports_object; + + return true; +} +#ifdef __cplusplus +} +#endif +%} diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index 1b06dbdc8..c05c6daf3 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -464,71 +464,3 @@ fail: %{ SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter); %} - -/* ----------------------------------------------------------------------------- - * js_initializer: template for the module initializer function - * - $jsname: module name - * - $jsv8nspaces: part with code creating namespace objects - * - $jsv8classtemplates: part with code creating class templates - * - $jsv8wrappers: part with code that registers wrapper functions - * - $jsv8inheritance: part with inherit statements - * - $jsv8classinstances: part with code creating class objects - * - $jsv8staticwrappers: part with code adding static functions to class objects - * - $jsv8registerclasses: part with code that registers class objects in namespaces - * - $jsv8registernspaces: part with code that registers namespaces in parent namespaces - * ----------------------------------------------------------------------------- */ -%fragment("js_initializer", "templates") -%{ - -// Note: 'extern "C"'' disables name mangling which makes it easier to load the symbol manually -// TODO: is it ok to do that? -extern "C" -#if (NODE_MODULE_VERSION < 0x000C) -void $jsname_initialize(v8::Handle exports) -#else -void $jsname_initialize(v8::Handle exports, v8::Handle /*module*/) -#endif -{ - SWIG_InitializeModule(static_cast(&exports)); - - v8::HandleScope scope; - v8::Handle exports_obj = exports; - - // a class template for creating proxies of undefined types - -#if (SWIG_V8_VERSION < 0x031900) - SWIGV8_SWIGTYPE_Proxy_class_templ = v8::Persistent::New(SWIGV8_CreateClassTemplate("SwigProxy")); -#else - SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); -#endif - - /* create objects for namespaces */ - $jsv8nspaces - - /* create class templates */ - $jsv8classtemplates - - /* register wrapper functions */ - $jsv8wrappers - - /* setup inheritances */ - $jsv8inheritance - - /* class instances */ - $jsv8classinstances - - /* add static class functions and variables */ - $jsv8staticwrappers - - /* register classes */ - $jsv8registerclasses - - /* create and register namespace objects */ - $jsv8registernspaces -} - -#if defined(BUILDING_NODE_EXTENSION) -NODE_MODULE($jsname, $jsname_initialize); -#endif - -%} diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg index 13ec1aff8..de1fe91f4 100644 --- a/Lib/javascript/v8/javascriptinit.swg +++ b/Lib/javascript/v8/javascriptinit.swg @@ -22,7 +22,7 @@ SWIG_V8_GetModule(void *) { } v8::Local moduleinfo_extern = v8::Local::Cast(moduleinfo); - + if (moduleinfo_extern.IsEmpty()) { // Something's not right @@ -41,6 +41,78 @@ SWIG_V8_GetModule(void *) { %} -%insert(init) %{/************ BEGIN: "swiginit.swg" *******************/ %} %insert(init) "swiginit.swg" -%insert(init) %{/************ END: "swiginit.swg" *******************/ %} + +// Open the initializer function definition here + +%fragment ("js_initializer_define", "templates") %{ +#define SWIGV8_INIT $jsname_initialize +%} + +%insert(init) %{ +// Note: 'extern "C"'' disables name mangling which makes it easier to load the symbol manually +// TODO: is it ok to do that? +extern "C" +#if (NODE_MODULE_VERSION < 0x000C) +void SWIGV8_INIT (v8::Handle exports) +#else +void SWIGV8_INIT (v8::Handle exports, v8::Handle /*module*/) +#endif +{ + SWIG_InitializeModule(static_cast(&exports)); + + v8::HandleScope scope; + v8::Handle exports_obj = exports; +%} + + +/* ----------------------------------------------------------------------------- + * js_initializer: template for the module initializer function + * - $jsname: module name + * - $jsv8nspaces: part with code creating namespace objects + * - $jsv8classtemplates: part with code creating class templates + * - $jsv8wrappers: part with code that registers wrapper functions + * - $jsv8inheritance: part with inherit statements + * - $jsv8classinstances: part with code creating class objects + * - $jsv8staticwrappers: part with code adding static functions to class objects + * - $jsv8registerclasses: part with code that registers class objects in namespaces + * - $jsv8registernspaces: part with code that registers namespaces in parent namespaces + * ----------------------------------------------------------------------------- */ +%fragment("js_initializer", "templates") +%{ + // a class template for creating proxies of undefined types +#if (SWIG_V8_VERSION < 0x031900) + SWIGV8_SWIGTYPE_Proxy_class_templ = v8::Persistent::New(SWIGV8_CreateClassTemplate("SwigProxy")); +#else + SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); +#endif + + /* create objects for namespaces */ + $jsv8nspaces + + /* create class templates */ + $jsv8classtemplates + + /* register wrapper functions */ + $jsv8wrappers + + /* setup inheritances */ + $jsv8inheritance + + /* class instances */ + $jsv8classinstances + + /* add static class functions and variables */ + $jsv8staticwrappers + + /* register classes */ + $jsv8registerclasses + + /* create and register namespace objects */ + $jsv8registernspaces +} + +#if defined(BUILDING_NODE_EXTENSION) +NODE_MODULE($jsname, $jsname_initialize); +#endif +%} diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 038094a12..d9ec51247 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1828,11 +1828,17 @@ int V8Emitter::initialize(Node *n) return SWIG_OK; } -int V8Emitter::dump(Node *) +int V8Emitter::dump(Node *n) { + /* Get the module name */ + String *module = Getattr(n, "name"); + // write the swig banner Swig_banner(f_wrap_cpp); + Template initializer_define(getTemplate("js_initializer_define")); + initializer_define.replace("$jsname", module).pretty_print(f_header); + SwigType_emit_type_table(f_runtime, f_wrappers); Printv(f_wrap_cpp, f_runtime, "\n", 0); @@ -1853,8 +1859,8 @@ int V8Emitter::dump(Node *) .replace("$jsv8classinstances", f_init_class_instances) .replace("$jsv8staticwrappers", f_init_static_wrappers) .replace("$jsv8registerclasses", f_init_register_classes) - .replace("$jsv8registernspaces", f_init_register_namespaces) - .pretty_print(f_init); + .replace("$jsv8registernspaces", f_init_register_namespaces); + Printv(f_init, initializer.str(), 0); Printv(f_wrap_cpp, f_init, 0); From b6426bde2501e6304193644ddc6e8c933db4412e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 04:12:06 +0200 Subject: [PATCH 209/352] Add cdata.i typemaps. --- Lib/javascript/jsc/cdata.i | 1 + Lib/javascript/v8/cdata.i | 1 + 2 files changed, 2 insertions(+) create mode 100644 Lib/javascript/jsc/cdata.i create mode 100644 Lib/javascript/v8/cdata.i diff --git a/Lib/javascript/jsc/cdata.i b/Lib/javascript/jsc/cdata.i new file mode 100644 index 000000000..367965990 --- /dev/null +++ b/Lib/javascript/jsc/cdata.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/cdata.i b/Lib/javascript/v8/cdata.i new file mode 100644 index 000000000..367965990 --- /dev/null +++ b/Lib/javascript/v8/cdata.i @@ -0,0 +1 @@ +%include From 3e28d1e28f81688184cf2c362fa01b7efaaad790 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 04:12:42 +0200 Subject: [PATCH 210/352] Let v8 generated code include stdlib.h --- Lib/javascript/v8/javascriptruntime.swg | 1 + 1 file changed, 1 insertion(+) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 8df5816a9..2e18d19bf 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -29,6 +29,7 @@ #include #include +#include %} %insert(runtime) "swigrun.swg"; /* SWIG API */ From eb9523b5caef732bbd1b259850e16dc8a9e11564 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 04:12:55 +0200 Subject: [PATCH 211/352] Add missing macros. --- Lib/javascript/jsc/javascriptrun.swg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg index 0e68b7618..3463d2351 100644 --- a/Lib/javascript/jsc/javascriptrun.swg +++ b/Lib/javascript/jsc/javascriptrun.swg @@ -167,6 +167,9 @@ JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_in #define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) #define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_JSC_ConvertPtr(context, obj, pptr, type, 0) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_JSC_NewPointerObj(context, ptr, type, 0) + /* ---------------------------------------------------------------------------- * A class for packed data * From 147cec70f1226dead5d93afd711b99bc9e81827f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 04:54:57 +0200 Subject: [PATCH 212/352] Replace $symname in generated function wrappers. --- Source/Modules/javascript.cxx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index d9ec51247..97542d93a 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1081,7 +1081,8 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { bool is_overloaded = GetFlag(n, "sym:overloaded"); // prepare the function wrapper name - String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + String *iname = Getattr(n, "sym:name"); + String *wrap_name = Swig_name_wrapper(iname); if (is_overloaded) { t_function = getTemplate("js_overloaded_function"); Append(wrap_name, Getattr(n, "sym:overname")); @@ -1106,6 +1107,8 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { emitCleanupCode(n, wrapper, params); + Replaceall(wrapper->code, "$symname", iname); + t_function.replace("$jswrapper", wrap_name) .replace("$jslocals", wrapper->locals) .replace("$jscode", wrapper->code) From 0528fd3ac3f6205ce642fa6997908df160030608 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 11:46:00 +0200 Subject: [PATCH 213/352] Bugfix for Javascript generator. --- Lib/javascript/v8/javascriptcode.swg | 4 +++- Source/Modules/javascript.cxx | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg index c05c6daf3..9bcb33176 100644 --- a/Lib/javascript/v8/javascriptcode.swg +++ b/Lib/javascript/v8/javascriptcode.swg @@ -337,7 +337,9 @@ fail: $jsmangledname_clientData.class_templ.Reset(v8::Isolate::GetCurrent(), $jsmangledname_class); #endif $jsmangledname_clientData.dtor = $jsdtor; - SWIGTYPE_$jsmangledtype->clientdata = &$jsmangledname_clientData; + if (SWIGTYPE_$jsmangledtype->clientdata == 0) { + SWIGTYPE_$jsmangledtype->clientdata = &$jsmangledname_clientData; + } %} diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 97542d93a..99030a772 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -416,6 +416,10 @@ int JAVASCRIPT::constantWrapper(Node *n) { if (Equal(Getattr(n, "kind"), "function")) { return SWIG_OK; } + // TODO: the emitter for constants must be implemented in a cleaner way + // currently we treat it like a read-only variable + // however, there is a remaining bug with function pointer constants + // which could be fixed with a cleaner approach emitter->emitConstant(n); return SWIG_OK; @@ -706,7 +710,8 @@ int JSEmitter::enterClass(Node *n) { state.clazz(true); state.clazz(NAME, Getattr(n, "sym:name")); - state.clazz(NAME_MANGLED, SwigType_manglestr(Getattr(n, "name"))); + //state.clazz(NAME_MANGLED, SwigType_manglestr(Getattr(n, "name"))); + state.clazz(NAME_MANGLED, Getattr(n, "sym:name")); state.clazz(TYPE, NewString(Getattr(n, "classtype"))); String *type = SwigType_manglestr(Getattr(n, "classtypeobj")); @@ -1921,7 +1926,9 @@ int V8Emitter::exitClass(Node *n) /* Note: this makes sure that there is a swig_type added for this class */ String *clientData = NewString(""); Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED)); - SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), clientData); + + /* Note: this makes sure that there is a swig_type added for this class */ + SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); // emit definition of v8 class template Template t_def_class = getTemplate("jsv8_define_class_template"); From dd4ed7f3d6bc6a13c271ac7ffb629115414113ec Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 11:46:52 +0200 Subject: [PATCH 214/352] Disable testcase 'typemap_variables' for v8. It uses output typemaps that are not compatible with the v8 API. --- Examples/test-suite/javascript/Makefile.in | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 70c404e61..940016726 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -62,9 +62,6 @@ CPP_TEST_CASES = \ using2 \ javascript_unicode -BROKEN_TEST_CASES = \ - infinity - SKIP_CPP_CASES = @SKIP_CPP_CASES@ SKIP_C_CASES = @SKIP_C_CASES@ SKIP_CPP_STD_CASES = @SKIP_CPP_STD_CASES@ @@ -81,6 +78,13 @@ _setup = \ echo "$(ACTION)ing testcase $* under javascript ($(JSENGINE))" ; \ fi; +ifeq (v8,$(ENGINE)) + + typemap_variables.cpptest: + echo "skipping testcase typemap_variables under javascript (v8)." + +endif + ifeq (node,$(JSENGINE)) SWIGOPT += -v8 -DBUILDING_NODE_EXTENSION=1 @@ -141,6 +145,7 @@ ifeq (v8,$(ENGINE)) $(_setup) +$(swig_and_compile_cpp) $(run_testcase) + endif ifeq (jsc,$(ENGINE)) From b99e8613ad7103bd99d7f6c7e24b774c73467201 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 21:56:52 +0200 Subject: [PATCH 215/352] Bugfix in argument marshalling. --- Source/Modules/javascript.cxx | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 99030a772..3d85fc974 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -235,7 +235,7 @@ protected: virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) = 0; - virtual void emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg); + virtual String *emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg); virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult=0, bool emitReturnVariable = true); @@ -1179,7 +1179,7 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { return SWIG_OK; } -void JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) { +String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) { // Get input typemap for current param String *tm = Getattr(p, "tmap:in"); SwigType *type = Getattr(p, "type"); @@ -1197,7 +1197,10 @@ void JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg 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(type, 0)); + Swig_print(p); } + + return tm; } void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) { @@ -1413,6 +1416,7 @@ JSCEmitter::~JSCEmitter() { void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { Parm *p; + String *tm; // determine an offset index, as members have an extra 'this' argument // except: static members and ctors. @@ -1429,7 +1433,7 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma // process arguments int i = 0; - for (p = parms; p; p = nextSibling(p), i++) { + for (p = parms; p; i++) { String *arg = NewString(""); switch (mode) { case Getter: @@ -1453,8 +1457,13 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma default: throw "Illegal state."; } - emitInputTypemap(n, p, wrapper, arg); + tm = emitInputTypemap(n, p, wrapper, arg); Delete(arg); + if (tm) { + p = Getattr(p, "tmap:in:next"); + } else { + p = nextSibling(p); + } } } @@ -2066,6 +2075,7 @@ int V8Emitter::exitFunction(Node* n) void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { Parm *p; + String *tm; int startIdx = 0; if (is_member && !is_static && mode!=Ctor) { @@ -2109,8 +2119,14 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar default: throw "Illegal state."; } - emitInputTypemap(n, p, wrapper, arg); + + tm = emitInputTypemap(n, p, wrapper, arg); Delete(arg); + if (tm) { + p = Getattr(p, "tmap:in:next"); + } else { + p = nextSibling(p); + } } } From b3c198ccee3dad34f75c4617900e53e1770f0ee9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 16 Sep 2013 22:28:14 +0200 Subject: [PATCH 216/352] Fix regression. --- Source/Modules/javascript.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 3d85fc974..3807e072a 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1197,7 +1197,6 @@ String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String * 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(type, 0)); - Swig_print(p); } return tm; @@ -2089,7 +2088,7 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar Setattr(n, ARGCOUNT, argcount); int i = 0; - for (p = parms; p; p = nextSibling(p), i++) { + for (p = parms; p; i++) { String *arg = NewString(""); switch (mode) { case Getter: @@ -2122,6 +2121,7 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar tm = emitInputTypemap(n, p, wrapper, arg); Delete(arg); + if (tm) { p = Getattr(p, "tmap:in:next"); } else { From d34a6da08c1dd59ad14731f4ea6a7e8b3b6dd8b7 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 17 Sep 2013 01:53:22 +0200 Subject: [PATCH 217/352] Disable warnings for some v8 test-cases. --- Examples/test-suite/javascript/Makefile.in | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 940016726..d7e7fce40 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -80,9 +80,16 @@ _setup = \ ifeq (v8,$(ENGINE)) + # This test can not be run with v8 as it uses v8 API incompatible output typemaps typemap_variables.cpptest: echo "skipping testcase typemap_variables under javascript (v8)." + # with v8 we have to generate C++ wrappers only + # these tests did raise warnings which are ignored + nested.ctest: SWIGOPT += -w312,-325 + nested_structs.ctest: SWIGOPT += -w312,-325 + unions.ctest: SWIGOPT += -w312,-325 + endif ifeq (node,$(JSENGINE)) From 8bf966a65c2120d2bf050857587e7e7bd7cafd58 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 24 Sep 2013 01:47:13 +0200 Subject: [PATCH 218/352] Fix %nspace support and activated relevant tests. --- Examples/test-suite/director_nspace.i | 16 +-- Examples/test-suite/javascript/Makefile.in | 2 + .../javascript/nspace_extend_runme.js | 27 ++++++ .../test-suite/javascript/nspace_runme.js | 77 +++++++++++++++ Examples/test-suite/nspace.i | 2 +- Examples/test-suite/nspace_extend.i | 2 +- Source/Modules/javascript.cxx | 97 +++++++++++++------ 7 files changed, 181 insertions(+), 42 deletions(-) create mode 100644 Examples/test-suite/javascript/nspace_extend_runme.js create mode 100644 Examples/test-suite/javascript/nspace_runme.js diff --git a/Examples/test-suite/director_nspace.i b/Examples/test-suite/director_nspace.i index 6814a43a3..264604877 100644 --- a/Examples/test-suite/director_nspace.i +++ b/Examples/test-suite/director_nspace.i @@ -15,10 +15,10 @@ namespace Bar FooBar() {} FooBar(const FooBar&) {} virtual ~FooBar() {} - + std::string FooBarDo() { return "Bar::Foo2::Foo2Bar()"; } }; - + class Foo { public: virtual ~Foo() {} @@ -37,7 +37,7 @@ namespace Bar %include // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGJAVASCRIPT) %nspace Bar::Foo; %nspace Bar::FooBar; #else @@ -47,17 +47,17 @@ namespace Bar %feature("director") Bar::Foo; namespace Bar -{ +{ class FooBar { public: FooBar(); FooBar(const FooBar&); virtual ~FooBar(); - + std::string FooBarDo(); - + }; - + class Foo { public: @@ -67,7 +67,7 @@ namespace Bar virtual std::string fooBar(FooBar* fb); virtual Foo makeFoo(); virtual FooBar makeFooBar(); - + static Foo* get_self(Foo *self_); }; } diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index d7e7fce40..40aa0ec86 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -45,6 +45,8 @@ CPP_TEST_CASES = \ cpp_static \ enum_template \ namespace_virtual_method \ + nspace \ + nspace_extend \ overload_copy \ rename_simple \ rename_scope \ diff --git a/Examples/test-suite/javascript/nspace_extend_runme.js b/Examples/test-suite/javascript/nspace_extend_runme.js new file mode 100644 index 000000000..ab81c19d3 --- /dev/null +++ b/Examples/test-suite/javascript/nspace_extend_runme.js @@ -0,0 +1,27 @@ +var nspace_extend = require("./nspace_extend"); + +// constructors and destructors +var color1 = new nspace_extend.Outer.Inner1.Color(); +var color = new nspace_extend.Outer.Inner1.Color(color1); +delete color1; + +// class methods +color.colorInstanceMethod(20.0); +nspace_extend.Outer.Inner1.Color.colorStaticMethod(20.0); +var created = nspace_extend.Outer.Inner1.Color.create(); + + +// constructors and destructors +var color2 = new nspace_extend.Outer.Inner2.Color(); +color = new nspace_extend.Outer.Inner2.Color(color2); +delete color2; + +// class methods +color.colorInstanceMethod(20.0); +nspace_extend.Outer.Inner2.Color.colorStaticMethod(20.0); +created = nspace_extend.Outer.Inner2.Color.create(); + +// Same class different namespaces +var col1 = new nspace_extend.Outer.Inner1.Color(); +var col2 = nspace_extend.Outer.Inner2.Color.create(); +col2.colors(col1, col1, col2, col2, col2); diff --git a/Examples/test-suite/javascript/nspace_runme.js b/Examples/test-suite/javascript/nspace_runme.js new file mode 100644 index 000000000..929a6b21d --- /dev/null +++ b/Examples/test-suite/javascript/nspace_runme.js @@ -0,0 +1,77 @@ +var nspace = require("./nspace"); + +var color1 = new nspace.Outer.Inner1.Color(); +var color = new nspace.Outer.Inner1.Color(color1); +delete color1; + +// class methods +color.colorInstanceMethod(20.0); +nspace.Outer.Inner1.Color.colorStaticMethod(20.0); +var created = nspace.Outer.Inner1.Color.create(); + +// class enums +var someClass = new nspace.Outer.SomeClass(); +var channel = someClass.GetInner1ColorChannel(); +if (channel != nspace.Outer.Inner1.Color.Transmission) { + throw new Error("Failed."); +} + +// class anonymous enums +var val1 = nspace.Outer.Inner1.Color.ColorEnumVal1; +var val2 = nspace.Outer.Inner1.Color.ColorEnumVal2; +if (val1 !== 0 || val2 !== 0x22) { + throw new Error("Failed."); +} + +// instance member variables +color.instanceMemberVariable = 123; +if (color.instanceMemberVariable !== 123) { + throw new Error("Failed."); +} + +// static member variables +nspace.Outer.Inner1.Color.staticMemberVariable = 789; +if (nspace.Outer.Inner1.Color.staticMemberVariable !== 789) { + throw new Error("Failed."); +} + +if (nspace.Outer.Inner1.Color.staticConstMemberVariable !== 222) { + throw new Error("Failed."); +} + +if (nspace.Outer.Inner1.Color.staticConstEnumMemberVariable !== nspace.Outer.Inner1.Color.Transmission) { + throw new Error("Failed."); +} + +// Same class different namespaces +var col1 = new nspace.Outer.Inner1.Color(); +var col2 = nspace.Outer.Inner2.Color.create(); +col2.colors(col1, col1, col2, col2, col2); + +// TODO: why isn't it scoped in the namespace??? +nspace.namespaceFunction(color); +nspace.Outer.Inner1.namespaceVar = 111; +if (nspace.Outer.Inner1.namespaceVar !== 111) { + throw new Error("Failed."); +} + +// global enums +var outerChannel1 = someClass.GetInner1Channel(); +if (outerChannel1 != nspace.Outer.Inner1.Transmission1) { + throw new Error("Failed."); +} + +var outerChannel2 = someClass.GetInner2Channel(); +if (outerChannel2 !== nspace.Outer.Inner2.Transmission2) { + throw new Error("Failed."); +} + +// turn feature off / ignoring +var ns = new nspace.Outer.namespce(); +var nons = new nspace.NoNSpacePlease(); + +// Derived class +var blue3 = new nspace.Outer.Inner3.Blue(); +blue3.blueInstanceMethod(); +var blue4 = new nspace.Outer.Inner4.Blue(); +blue4.blueInstanceMethod(); diff --git a/Examples/test-suite/nspace.i b/Examples/test-suite/nspace.i index 2e10542d3..9bffc21ff 100644 --- a/Examples/test-suite/nspace.i +++ b/Examples/test-suite/nspace.i @@ -2,7 +2,7 @@ %module nspace // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGJAVASCRIPT) #if defined(SWIGJAVA) SWIG_JAVABODY_PROXY(public, public, SWIGTYPE) diff --git a/Examples/test-suite/nspace_extend.i b/Examples/test-suite/nspace_extend.i index 1965ef8f6..7c1b075ed 100644 --- a/Examples/test-suite/nspace_extend.i +++ b/Examples/test-suite/nspace_extend.i @@ -2,7 +2,7 @@ %module nspace_extend // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGJAVASCRIPT) #if defined(SWIGJAVA) SWIG_JAVABODY_PROXY(public, public, SWIGTYPE) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 3807e072a..13a0aab7d 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -396,7 +396,6 @@ int JAVASCRIPT::variableHandler(Node *n) { * --------------------------------------------------------------------- */ int JAVASCRIPT::globalvariableHandler(Node *n) { - emitter->switchNamespace(n); Language::globalvariableHandler(n); @@ -410,6 +409,7 @@ int JAVASCRIPT::globalvariableHandler(Node *n) { * --------------------------------------------------------------------- */ int JAVASCRIPT::constantWrapper(Node *n) { + emitter->switchNamespace(n); // Note: callbacks trigger this wrapper handler // TODO: handle callback declarations @@ -464,7 +464,6 @@ int JAVASCRIPT::fragmentDirective(Node *n) { * --------------------------------------------------------------------- */ int JAVASCRIPT::top(Node *n) { - emitter->initialize(n); Language::top(n); @@ -482,7 +481,6 @@ int JAVASCRIPT::top(Node *n) { * --------------------------------------------------------------------- */ void JAVASCRIPT::main(int argc, char *argv[]) { - // Set javascript subdirectory in SWIG library SWIG_library_directory("javascript"); @@ -667,7 +665,7 @@ int JSEmitter::emitWrapperFunction(Node *n) { if (kind) { if (Cmp(kind, "function") == 0) { - bool is_member = GetFlag(n, "ismember"); + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); bool is_static = GetFlag(state.function(), IS_STATIC); ret = emitFunction(n, is_member, is_static); } else if (Cmp(kind, "variable") == 0) { @@ -707,18 +705,23 @@ int JSEmitter::emitWrapperFunction(Node *n) { } int JSEmitter::enterClass(Node *n) { - state.clazz(true); state.clazz(NAME, Getattr(n, "sym:name")); - //state.clazz(NAME_MANGLED, SwigType_manglestr(Getattr(n, "name"))); - state.clazz(NAME_MANGLED, Getattr(n, "sym:name")); + state.clazz("nspace", current_namespace); + + // Creating a mangled name using the current namespace and the symbol name + String *mangled_name = NewString(""); + Printf(mangled_name, "%s_%s", Getattr(current_namespace, NAME_MANGLED), Getattr(n, "sym:name")); + state.clazz(NAME_MANGLED, SwigType_manglestr(mangled_name)); + Delete(mangled_name); + state.clazz(TYPE, NewString(Getattr(n, "classtype"))); String *type = SwigType_manglestr(Getattr(n, "classtypeobj")); String *classtype_mangled = NewString(""); Printf(classtype_mangled, "p%s", type); - Delete(type); state.clazz(TYPE_MANGLED, classtype_mangled); + Delete(type); String *ctor_wrapper = NewString("_wrap_new_veto_"); Append(ctor_wrapper, state.clazz(NAME)); @@ -734,23 +737,19 @@ int JSEmitter::enterClass(Node *n) { } int JSEmitter::enterFunction(Node *n) { - state.function(true); state.function(NAME, Getattr(n, "sym:name")); if(Equal(Getattr(n, "storage"), "static")) { SetFlag(state.function(), IS_STATIC); } - return SWIG_OK; } int JSEmitter::enterVariable(Node *n) { - // reset the state information for variables. state.variable(true); // Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings. - if (Equal(Getattr(n, "view"), "memberconstantHandler")) { // Note: this is kind of hacky/experimental // For constants/enums 'sym:name' contains e.g., 'Foo_Hello' instead of 'Hello' @@ -763,10 +762,12 @@ int JSEmitter::enterVariable(Node *n) { SetFlag(state.variable(), IS_STATIC); } - if (!Language::instance()->is_assignable(n) - // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] - // probably some error in char[] typemap - || Equal(Getattr(n, "type"), "a().char")) { + if (!Language::instance()->is_assignable(n)) { + SetFlag(state.variable(), IS_IMMUTABLE); + } + + // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] + if (Equal(Getattr(n, "type"), "a().char")) { SetFlag(state.variable(), IS_IMMUTABLE); } @@ -1273,23 +1274,43 @@ void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) { } int JSEmitter::switchNamespace(Node *n) { + // HACK: somehow this gets called when member functions are processed...ignoring + if (GetFlag(n, "ismember")) { + return SWIG_OK; + } + String *nspace = Getattr(n, "sym:nspace"); + + // if nspace is deactivated, everything goes into the global scope 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 (parent) namespaces recursively - if (!Getattr(namespaces, scope)) { - createNamespace(scope); - } - current_namespace = Getattr(namespaces, scope); - } else { - current_namespace = Getattr(namespaces, "::"); + return SWIG_OK; + } + + if (nspace == NULL) { + // enums and constants do not have 'sym:nspace' set + // so we try to get the namespace from the qualified name + if(Equal(Getattr(n, "nodeType"), "enumitem")) { + nspace = Swig_scopename_prefix(Getattr(n, "name")); } } + if (nspace == NULL) { + current_namespace = Getattr(namespaces, "::"); + return SWIG_OK; + } + + String *scope = NewString(nspace); + // replace "." with "::" that we can use Swig_scopename_last + Replaceall(scope, ".", "::"); + + // if the scope is not yet registered + // create (parent) namespaces recursively + if (!Getattr(namespaces, scope)) { + createNamespace(scope); + } + current_namespace = Getattr(namespaces, scope); + return SWIG_OK; } @@ -1434,6 +1455,12 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma int i = 0; for (p = parms; p; i++) { String *arg = NewString(""); + String *type = Getattr(p, "type"); + + // ignore varargs + if (SwigType_isvarargs(type)) + break; + switch (mode) { case Getter: case Function: @@ -1556,7 +1583,7 @@ int JSCEmitter::enterFunction(Node *n) { int JSCEmitter::exitFunction(Node *n) { Template t_function = getTemplate("jsc_function_declaration"); - bool is_member = GetFlag(n, "ismember"); + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); bool is_overloaded = GetFlag(n, "sym:overloaded"); // handle overloaded functions @@ -1682,7 +1709,7 @@ int JSCEmitter::exitClass(Node *n) { Template t_registerclass(getTemplate("jsc_class_registration")); t_registerclass.replace("$jsname", state.clazz(NAME)) .replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsnspace", Getattr(current_namespace, NAME_MANGLED)) + .replace("$jsnspace", Getattr(state.clazz("nspace"),NAME_MANGLED)) .pretty_print(state.global(INITIALIZER)); return SWIG_OK; @@ -1973,7 +2000,7 @@ int V8Emitter::exitClass(Node *n) Template t_register = getTemplate("jsv8_register_class"); t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) .replace("$jsname", state.clazz(NAME)) - .replace("$jsparent", Getattr(current_namespace, "name_mangled")) + .replace("$jsparent", Getattr(state.clazz("nspace"),NAME_MANGLED)) .trim() .pretty_print(f_init_register_classes); @@ -2014,7 +2041,7 @@ int V8Emitter::exitVariable(Node* n) // 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"); - t_register.replace("$jsparent", Getattr(current_namespace, NAME)) + t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED)) .replace("$jsname", state.variable(NAME)) .replace("$jsgetter", state.variable(GETTER)) .replace("$jssetter", state.variable(SETTER)) @@ -2027,7 +2054,7 @@ int V8Emitter::exitVariable(Node* n) int V8Emitter::exitFunction(Node* n) { - bool is_member = GetFlag(n, "ismember"); + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); // create a dispatcher for overloaded functions bool is_overloaded = GetFlag(n, "sym:overloaded"); @@ -2090,6 +2117,12 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar int i = 0; for (p = parms; p; i++) { String *arg = NewString(""); + String *type = Getattr(p, "type"); + + // ignore varargs + if (SwigType_isvarargs(type)) + break; + switch (mode) { case Getter: if (is_member && !is_static && i == 0) { From b9ecf75f17c05bc58d6e6347877b5aedd92d2d28 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 24 Sep 2013 01:50:13 +0200 Subject: [PATCH 219/352] Fix emitter for member pointer constants. However, I am not happy with the constant emitter in general. Should not return dynamic values but register constant wrappers statically. --- Source/Modules/javascript.cxx | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 13a0aab7d..05912a69e 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1044,30 +1044,37 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { int JSEmitter::emitConstant(Node *n) { Wrapper *wrapper = NewWrapper(); + SwigType *type = Getattr(n, "type"); + String *name = Getattr(n, "name"); + String *iname = Getattr(n, "sym:name"); + String *wname = Swig_name_wrapper(name); + String *rawval = Getattr(n, "rawval"); + String *value = rawval ? rawval : Getattr(n, "value"); Template t_getter(getTemplate("js_getter")); // call the variable methods as a constants are // registred in same way enterVariable(n); + state.variable(GETTER, wname); + // TODO: why do we need this? + Setattr(n, "wrap:name", wname); - // 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 code part - String *value = Getattr(n, "rawval"); - if (value == NULL) { - value = Getattr(n, "rawvalue"); - if (value == NULL) value = Getattr(n, "value"); + // special treatment of member pointers + if (SwigType_type(type) == T_MPOINTER) { + // TODO: this could go into a code-template + String *mpointer_wname = NewString(""); + Printf(mpointer_wname, "_wrapConstant_%s", iname); + Setattr(n, "memberpointer:constant:wrap:name", mpointer_wname); + String *str = SwigType_str(type, mpointer_wname); + Printf(f_wrappers, "static %s = %s;\n", str, value); + Delete(str); + value = mpointer_wname; } - assert(value != NULL); - String *action = NewString(""); - marshalOutput(n, 0, wrapper, action, value, false); + marshalOutput(n, 0, wrapper, NewString(""), value, false); - t_getter.replace("$jswrapper", wrap_name) + t_getter.replace("$jswrapper", wname) .replace("$jslocals", wrapper->locals) .replace("$jscode", wrapper->code) .pretty_print(f_wrappers); From 2efe63ebb2c87e2e8cde445ffdf964f6cc38869e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 24 Sep 2013 01:50:33 +0200 Subject: [PATCH 220/352] Add some test runners. --- .../test-suite/javascript/callback_runme.js | 30 +++++++++++++ .../test-suite/javascript/disown_runme.js | 22 ++++++++++ .../javascript/dynamic_cast_runme.js | 12 +++++ Examples/test-suite/javascript/empty_runme.js | 1 + .../test-suite/javascript/varargs_runme.js | 44 +++++++++++++++++++ 5 files changed, 109 insertions(+) create mode 100644 Examples/test-suite/javascript/callback_runme.js create mode 100644 Examples/test-suite/javascript/disown_runme.js create mode 100644 Examples/test-suite/javascript/dynamic_cast_runme.js create mode 100644 Examples/test-suite/javascript/empty_runme.js create mode 100644 Examples/test-suite/javascript/varargs_runme.js diff --git a/Examples/test-suite/javascript/callback_runme.js b/Examples/test-suite/javascript/callback_runme.js new file mode 100644 index 000000000..9b1ef01a3 --- /dev/null +++ b/Examples/test-suite/javascript/callback_runme.js @@ -0,0 +1,30 @@ +var callback = require("./callback"); + +if (callback.foo(2) !== 2) { + throw new Error("Failed."); +} +if (callback.A_bar(2) !== 4) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.foo) != callback.foo(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, foo) != callback.foo(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.A_bar) != callback.A_bar(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.foof) != callback.foof(3)) { + throw new Error("Failed."); +} +if (callback.foobar_i(3, callback.foo_i) != callback.foo_i(3)) { + throw new Error("Failed."); +} +if (callback.foobar_d(3.5, callback.foo_d) != callback.foo_d(3.5)) { + throw new Error("Failed."); +} +var a = new callback.A(); +if (callback.foobarm(3, a, callback.A.foom_cb_ptr) != a.foom(3)) { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/disown_runme.js b/Examples/test-suite/javascript/disown_runme.js new file mode 100644 index 000000000..a4a6fd880 --- /dev/null +++ b/Examples/test-suite/javascript/disown_runme.js @@ -0,0 +1,22 @@ +var disown = require("./disown"); + +var a = new disown.A(); +var tmp = a.thisown; +a.thisown = 0 +if (a.thisown) { + throw new Error("Failed."); +} +a.thisown = 1 +if (!a.thisown) { + throw new Error("Failed."); +} +a.thisown = tmp +if (a.thisown != tmp) { + throw new Error("Failed."); +} + +var b = new disown.B(); +b.acquire(a); +if (a.thisown) { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/dynamic_cast_runme.js b/Examples/test-suite/javascript/dynamic_cast_runme.js new file mode 100644 index 000000000..0029cb0f8 --- /dev/null +++ b/Examples/test-suite/javascript/dynamic_cast_runme.js @@ -0,0 +1,12 @@ +var dynamic_cast = require("./dynamic_cast"); + +var f = new dynamic_cast.Foo(); +var b = new dynamic_cast.Bar(); + +var x = f.blah(); +var y = b.blah(); + +var a = dynamic_cast.do_test(y); +if (a != "Bar::test") { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/empty_runme.js b/Examples/test-suite/javascript/empty_runme.js new file mode 100644 index 000000000..db06b3902 --- /dev/null +++ b/Examples/test-suite/javascript/empty_runme.js @@ -0,0 +1 @@ +var empty = require("./empty"); \ No newline at end of file diff --git a/Examples/test-suite/javascript/varargs_runme.js b/Examples/test-suite/javascript/varargs_runme.js new file mode 100644 index 000000000..69d761e63 --- /dev/null +++ b/Examples/test-suite/javascript/varargs_runme.js @@ -0,0 +1,44 @@ +var varargs = require("./varargs"); + +if (varargs.test("Hello") != "Hello") { + throw new Error("Failed"); +} + +var f = new varargs.Foo("Greetings") +if (f.str != "Greetings") { + throw new Error("Failed"); +} + +if (f.test("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_def("Hello",1) != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_def("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello", 1) != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello", 1, 2) != "Hello") { + throw new Error("Failed"); +} + +var thrown = false; +try { + varargs.test_plenty("Hello", 1, 2, 3); +} catch (err) { + thrown = true; +} +if (!thrown) { + throw new Error("Failed"); +} From dc62a69775f7eff6a11e7ca7f162ae960b53e671 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 24 Sep 2013 03:55:10 +0200 Subject: [PATCH 221/352] Fix bug with typedefd function pointers. --- Source/Modules/javascript.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 05912a69e..8a77a0b48 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -664,7 +664,12 @@ int JSEmitter::emitWrapperFunction(Node *n) { String *kind = Getattr(n, "kind"); if (kind) { - if (Cmp(kind, "function") == 0) { + + if (Equal(kind, "function") + // HACK: sneaky.ctest revealed that typedef'd (global) functions must be + // detected via the 'view' attribute. + || (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler")) + ) { bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); bool is_static = GetFlag(state.function(), IS_STATIC); ret = emitFunction(n, is_member, is_static); From 51b36d1a1f0c9efe3ef3d25c8bd8c3dfecfa4a52 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 24 Sep 2013 03:55:51 +0200 Subject: [PATCH 222/352] Add non pretty printing function to Templates. --- Source/Modules/javascript.cxx | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 8a77a0b48..239981219 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -78,6 +78,8 @@ public: Template& replace(const String *pattern, const String *repl); + Template& print(DOH *doh); + Template& pretty_print(DOH *doh); void operator=(const Template& t); @@ -1092,7 +1094,6 @@ int JSEmitter::emitConstant(Node *n) { } int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { - Wrapper *wrapper = NewWrapper(); Template t_function(getTemplate("js_function")); @@ -2038,8 +2039,8 @@ int V8Emitter::exitVariable(Node* n) .replace("$jsname", state.variable(NAME)) .replace("$jsgetter", state.variable(GETTER)) .replace("$jssetter", state.variable(SETTER)) - .trim() - .pretty_print(f_init_static_wrappers); + .trim(). + print(f_init_static_wrappers); } else { Template t_register = getTemplate("jsv8_register_member_variable"); t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) @@ -2047,7 +2048,7 @@ int V8Emitter::exitVariable(Node* n) .replace("$jsgetter", state.variable(GETTER)) .replace("$jssetter", state.variable(SETTER)) .trim() - .pretty_print(f_init_wrappers); + .print(f_init_wrappers); } } else { // Note: a global variable is treated like a static variable @@ -2058,7 +2059,7 @@ int V8Emitter::exitVariable(Node* n) .replace("$jsgetter", state.variable(GETTER)) .replace("$jssetter", state.variable(SETTER)) .trim() - .pretty_print(f_init_wrappers); + .print(f_init_wrappers); } return SWIG_OK; @@ -2088,14 +2089,14 @@ int V8Emitter::exitFunction(Node* n) .replace("$jsname", state.function(NAME)) .replace("$jswrapper", state.function(WRAPPER_NAME)) .trim() - .pretty_print(f_init_static_wrappers); + .print(f_init_static_wrappers); } else { Template t_register = getTemplate("jsv8_register_member_function"); t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) .replace("$jsname", state.function(NAME)) .replace("$jswrapper", state.function(WRAPPER_NAME)) .trim() - .pretty_print(f_init_wrappers); + .print(f_init_wrappers); } } else { // Note: a global function is treated like a static function @@ -2423,6 +2424,11 @@ Template& Template::replace(const String *pattern, const String *repl) { return *this; } +Template& Template::print(DOH *doh) { + Printv(doh, str(), 0); + return *this; +} + Template& Template::pretty_print(DOH *doh) { Wrapper_pretty_print(str(), doh); return *this; From 335d926c449d22821eb916d0f862062b925c2ca6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 24 Sep 2013 03:56:19 +0200 Subject: [PATCH 223/352] Add stub std_deque.i files. --- Lib/javascript/jsc/std_deque.i | 1 + Lib/javascript/v8/std_deque.i | 1 + 2 files changed, 2 insertions(+) create mode 100644 Lib/javascript/jsc/std_deque.i create mode 100644 Lib/javascript/v8/std_deque.i diff --git a/Lib/javascript/jsc/std_deque.i b/Lib/javascript/jsc/std_deque.i new file mode 100644 index 000000000..cb98f6c2f --- /dev/null +++ b/Lib/javascript/jsc/std_deque.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/std_deque.i b/Lib/javascript/v8/std_deque.i new file mode 100644 index 000000000..cb98f6c2f --- /dev/null +++ b/Lib/javascript/v8/std_deque.i @@ -0,0 +1 @@ +%include From 7adf93ef0f86babb564b1458228f5b4666f414dc Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 26 Sep 2013 04:13:32 +0200 Subject: [PATCH 224/352] Fix test configuration for nodejs. --- Examples/test-suite/javascript/Makefile.in | 20 +++++++++++++------ .../javascript/char_strings_runme.js | 2 +- .../javascript/node_template/binding.gyp.in | 2 ++ Examples/test-suite/javascript/setup_test.sh | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 40aa0ec86..1010a49e7 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -80,11 +80,11 @@ _setup = \ echo "$(ACTION)ing testcase $* under javascript ($(JSENGINE))" ; \ fi; -ifeq (v8,$(ENGINE)) +ifneq (jsc,$(ENGINE)) # This test can not be run with v8 as it uses v8 API incompatible output typemaps typemap_variables.cpptest: - echo "skipping testcase typemap_variables under javascript (v8)." + echo "skipping testcase typemap_variables under javascript ($(JSENGINE))." # with v8 we have to generate C++ wrappers only # these tests did raise warnings which are ignored @@ -98,8 +98,18 @@ ifeq (node,$(JSENGINE)) SWIGOPT += -v8 -DBUILDING_NODE_EXTENSION=1 + # shut up some warnings + # contract macro has an empty 'else' at the end... + aggregate.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" + contract_wrap.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" + + # dunno... ignoring generously + apply_signed_char.cpptest: GYP_CFLAGS = \"Wno-ignored-qualifiers\" + constant_pointers.cpptest: GYP_CFLAGS = \"Wno-ignored-qualifiers\" + enum_thorough.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" + __setup = \ - sh ./setup_test.sh $*; \ + sh ./setup_test.sh $* $(GYP_CFLAGS); \ $(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i; nodejs_swig_and_compile = \ @@ -124,9 +134,6 @@ ifeq (node,$(JSENGINE)) %.multicpptest: $(_setup) - $(__setup) - $(nodejs_swig_and_compile) - $(run_testcase) else @@ -171,3 +178,4 @@ clean: rm -f *_wrap.cxx rm -f *_wrap.c rm -f *.so + rm -f *.o diff --git a/Examples/test-suite/javascript/char_strings_runme.js b/Examples/test-suite/javascript/char_strings_runme.js index fe17cb982..cca50d851 100644 --- a/Examples/test-suite/javascript/char_strings_runme.js +++ b/Examples/test-suite/javascript/char_strings_runme.js @@ -1,4 +1,4 @@ -var char_strings = require("char_strings"); +var char_strings = require("./char_strings"); var assertIsEqual = function(expected, actual) { if (expected !== actual) { diff --git a/Examples/test-suite/javascript/node_template/binding.gyp.in b/Examples/test-suite/javascript/node_template/binding.gyp.in index 435381043..209774ae0 100644 --- a/Examples/test-suite/javascript/node_template/binding.gyp.in +++ b/Examples/test-suite/javascript/node_template/binding.gyp.in @@ -18,6 +18,8 @@ ], ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', { + 'cflags': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cflags], + 'cflags_cc': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cflags], 'cflags!': [ '-fno-exceptions' ], 'cflags_cc!': [ '-fno-exceptions', '-fno-rtti' ] } diff --git a/Examples/test-suite/javascript/setup_test.sh b/Examples/test-suite/javascript/setup_test.sh index 3f45d814a..913a74c4b 100644 --- a/Examples/test-suite/javascript/setup_test.sh +++ b/Examples/test-suite/javascript/setup_test.sh @@ -2,5 +2,5 @@ if [ ! -d $1 ]; then mkdir $1; fi -sed s/\$testcase/$1/ node_template/binding.gyp.in > $1/binding.gyp +sed -e "s/\$testcase/$1/" -e "s/\$cflags/$2/" < node_template/binding.gyp.in > $1/binding.gyp sed s/\$testcase/$1/ node_template/index.js.in > $1/index.js From 582bd297690605d98ae758d164cc48e299ae34b3 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 26 Sep 2013 04:55:34 +0200 Subject: [PATCH 225/352] Trying to install former working version of nodejs. --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index a38965992..3b8500aee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,9 @@ compiler: node_js: -0.10.12 before_script: - - "sudo add-apt-repository -y ppa:chris-lea/node.js" - - "sudo apt-get update" - - "sudo apt-get install -y nodejs" + - "sudo apt-get install rlwrap" + - "wget https://launchpad.net/~chris-lea/+archive/node.js/+build/4936691/+files/nodejs_0.10.18-1chl1~precise1_amd64.deb" + - "sudo dpkg -i nodejs_0.10.18-1chl1~precise1_amd64.deb" - "sudo npm install -g node-gyp" - "sudo apt-get install libv8-3.7.12.22 libv8-dev" - "sudo apt-get install libwebkitgtk-dev" From c2d3da2eeca2d1923d9c69dda70a8ce2f1b2cf1e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 26 Sep 2013 05:14:34 +0200 Subject: [PATCH 226/352] Fix test configuration. --- Examples/test-suite/javascript/Makefile.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 1010a49e7..49652f0bd 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -101,11 +101,11 @@ ifeq (node,$(JSENGINE)) # shut up some warnings # contract macro has an empty 'else' at the end... aggregate.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" - contract_wrap.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" + contract.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" # dunno... ignoring generously - apply_signed_char.cpptest: GYP_CFLAGS = \"Wno-ignored-qualifiers\" - constant_pointers.cpptest: GYP_CFLAGS = \"Wno-ignored-qualifiers\" + apply_signed_char.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" + constant_pointers.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" enum_thorough.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" __setup = \ From 6a366cc050f25b3d358d8f4d85e37011ada82726 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 27 Sep 2013 03:23:37 +0200 Subject: [PATCH 227/352] Fix regression. --- Source/Modules/javascript.cxx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 239981219..70bb12f68 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1571,18 +1571,12 @@ int JSCEmitter::dump(Node *n) { } int JSCEmitter::close() { - /* strings */ Delete(f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); - Delete(namespaces); - - /* files */ - Close(f_wrap_cpp); Delete(f_wrap_cpp); - return SWIG_OK; } @@ -1927,7 +1921,6 @@ int V8Emitter::dump(Node *n) int V8Emitter::close() { - // strings Delete(f_runtime); Delete(f_header); Delete(f_class_templates); @@ -1941,11 +1934,7 @@ int V8Emitter::close() Delete(f_init_register_namespaces); Delete(f_init); Delete(f_post_init); - - // files - Close(f_wrap_cpp); Delete(f_wrap_cpp); - return SWIG_OK; } From 00053169cd5d69c42b1b1bbf58336776e1820c97 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 27 Sep 2013 02:44:53 +0200 Subject: [PATCH 228/352] CMake configuration. --- CMakeLists.txt | 173 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..1bf7a2c76 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,173 @@ +project(swig) +cmake_minimum_required(VERSION 2.8) + +# Project wide configuration variables +# ------------------------------------ + +set(SWIG_VERSION 2.0.6) +set(SWIG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Source" CACHE INTERNAL "Path of swig sources" FORCE) + +# Configure +# --------- + +include(CheckIncludeFiles) +include(CheckIncludeFile) +include(CheckTypeSize) +include(CheckSymbolExists) +include(CheckLibraryExists) +include(CheckCSourceCompiles) + +# HACK: didn't get the bool check working for Visual Studio 2008 +if(MSVC) +set(HAVE_BOOL 1) +else() +set(CMAKE_EXTRA_INCLUDE_FILES stdbool.h) +check_type_size("bool" HAVE_BOOL) +set(CMAKE_EXTRA_INCLUDE_FILES) +endif() + +check_include_file("inttypes.h" HAVE_INTTYPES_H) +check_include_file("memory.h" HAVE_MEMORY_H) +check_include_file("stddef.h" HAVE_STDDEF_H) +check_include_file("stdint.h" HAVE_STDINT_H) +check_include_file("stdlib.h" HAVE_STDLIB_H) +check_include_file("string.h" HAVE_STRING_H) +check_include_file("strings.h" HAVE_STRINGS_H) +check_include_file("sys/stat.h" HAVE_SYS_STAT_H) +check_include_file("sys/types.h" HAVE_SYS_TYPES_H) +check_include_file("unistd.h" HAVE_UNISTD_H) +check_include_files( "stdlib.h;stdarg.h;string.h;float.h" HAVE_STDC_HEADERS ) + +check_library_exists(dl dlopen "" HAVE_LIBDL) + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Tools/swigconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/Source/Include/swigconfig.h) + +# Compiler flags +# -------------- + +include_directories("${SWIG_SOURCE_DIR}/CParse" + "${SWIG_SOURCE_DIR}/Include" + "${SWIG_SOURCE_DIR}/DOH" + "${SWIG_SOURCE_DIR}/Swig" + "${SWIG_SOURCE_DIR}/Preprocessor" + "${SWIG_SOURCE_DIR}/Modules" + "${PROJECT_BINARY_DIR}/Source/Include" +) + +# Pre-Build +# --------- + +# Copy Lib directory into the build dist folder +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Dist) +file(COPY ${PROJECT_SOURCE_DIR}/Lib DESTINATION ${PROJECT_BINARY_DIR}/Dist) + +# add the command to generate the source code (depends on bison) +file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Source/CParse) +add_custom_command ( + OUTPUT ${PROJECT_BINARY_DIR}/Source/CParse/parser.c + DEPENDS ${SWIG_SOURCE_DIR}/CParse/parser.y + COMMAND bison -o ${PROJECT_BINARY_DIR}/Source/CParse/parser.c --defines=${PROJECT_BINARY_DIR}/Source/Include/parser.h ${SWIG_SOURCE_DIR}/CParse/parser.y +) +set_property(SOURCE ${PROJECT_BINARY_DIR}/Source/CParse/parser.c PROPERTY GENERATED 1) +set_property(SOURCE ${PROJECT_BINARY_DIR}/Source/CParse/parser.h PROPERTY GENERATED 1) + +# generate swigwarn.swg +file(READ ${SWIG_SOURCE_DIR}/Include/swigwarn.h SWIG_WARN_H) +string(REGEX REPLACE "#define WARN([^ \\t]*)[ \\t]*([0-9]+)" "%define SWIGWARN\\1 \\2 %enddef" SWIG_WARN_SWG ${SWIG_WARN_H}) +file(WRITE ${PROJECT_BINARY_DIR}/Dist/Lib/swigwarn.swg ${SWIG_WARN_SWG}) +set_property(SOURCE ${PROJECT_BINARY_DIR}/Dist/Lib/swigwarn.swg PROPERTY GENERATED 1) + +# Libraries +# --------- + +add_library(cparse "${SWIG_SOURCE_DIR}/CParse/cscanner.c" + "${SWIG_SOURCE_DIR}/CParse/templ.c" + "${SWIG_SOURCE_DIR}/CParse/util.c" + "${PROJECT_BINARY_DIR}/Source/CParse/parser.c" + "${PROJECT_BINARY_DIR}/Source/CParse/parser.h" +) + +add_library(preprocessor "${SWIG_SOURCE_DIR}/Preprocessor/cpp.c" + "${SWIG_SOURCE_DIR}/Preprocessor/expr.c" +) + +add_library(doh "${SWIG_SOURCE_DIR}/DOH/base.c" + "${SWIG_SOURCE_DIR}/DOH/file.c" + "${SWIG_SOURCE_DIR}/DOH/fio.c" + "${SWIG_SOURCE_DIR}/DOH/hash.c" + "${SWIG_SOURCE_DIR}/DOH/list.c" + "${SWIG_SOURCE_DIR}/DOH/memory.c" + "${SWIG_SOURCE_DIR}/DOH/string.c" + "${SWIG_SOURCE_DIR}/DOH/void.c" +) + +add_library(core "${SWIG_SOURCE_DIR}/Swig/cwrap.c" + "${SWIG_SOURCE_DIR}/Swig/deprecate.c" + "${SWIG_SOURCE_DIR}/Swig/error.c" + "${SWIG_SOURCE_DIR}/Swig/fragment.c" + "${SWIG_SOURCE_DIR}/Swig/getopt.c" + "${SWIG_SOURCE_DIR}/Swig/include.c" + "${SWIG_SOURCE_DIR}/Swig/misc.c" + "${SWIG_SOURCE_DIR}/Swig/naming.c" + "${SWIG_SOURCE_DIR}/Swig/parms.c" + "${SWIG_SOURCE_DIR}/Swig/scanner.c" + "${SWIG_SOURCE_DIR}/Swig/stype.c" + "${SWIG_SOURCE_DIR}/Swig/symbol.c" + "${SWIG_SOURCE_DIR}/Swig/tree.c" + "${SWIG_SOURCE_DIR}/Swig/typemap.c" + "${SWIG_SOURCE_DIR}/Swig/typeobj.c" + "${SWIG_SOURCE_DIR}/Swig/typesys.c" + "${SWIG_SOURCE_DIR}/Swig/wrapfunc.c" +) + +add_library(modules "${SWIG_SOURCE_DIR}/Modules/allegrocl.cxx" + "${SWIG_SOURCE_DIR}/Modules/allocate.cxx" + "${SWIG_SOURCE_DIR}/Modules/browser.cxx" + "${SWIG_SOURCE_DIR}/Modules/cffi.cxx" + "${SWIG_SOURCE_DIR}/Modules/chicken.cxx" + "${SWIG_SOURCE_DIR}/Modules/clisp.cxx" + "${SWIG_SOURCE_DIR}/Modules/contract.cxx" + "${SWIG_SOURCE_DIR}/Modules/csharp.cxx" + "${SWIG_SOURCE_DIR}/Modules/d.cxx" + "${SWIG_SOURCE_DIR}/Modules/directors.cxx" + "${SWIG_SOURCE_DIR}/Modules/emit.cxx" + "${SWIG_SOURCE_DIR}/Modules/go.cxx" + "${SWIG_SOURCE_DIR}/Modules/guile.cxx" + "${SWIG_SOURCE_DIR}/Modules/java.cxx" + "${SWIG_SOURCE_DIR}/Modules/javascript.cxx" + "${SWIG_SOURCE_DIR}/Modules/lang.cxx" + "${SWIG_SOURCE_DIR}/Modules/lua.cxx" + "${SWIG_SOURCE_DIR}/Modules/modula3.cxx" + "${SWIG_SOURCE_DIR}/Modules/module.cxx" + "${SWIG_SOURCE_DIR}/Modules/mzscheme.cxx" + "${SWIG_SOURCE_DIR}/Modules/ocaml.cxx" + "${SWIG_SOURCE_DIR}/Modules/octave.cxx" + "${SWIG_SOURCE_DIR}/Modules/overload.cxx" + "${SWIG_SOURCE_DIR}/Modules/perl5.cxx" + "${SWIG_SOURCE_DIR}/Modules/php.cxx" + "${SWIG_SOURCE_DIR}/Modules/pike.cxx" + "${SWIG_SOURCE_DIR}/Modules/python.cxx" + "${SWIG_SOURCE_DIR}/Modules/r.cxx" + "${SWIG_SOURCE_DIR}/Modules/ruby.cxx" + "${SWIG_SOURCE_DIR}/Modules/s-exp.cxx" + "${SWIG_SOURCE_DIR}/Modules/tcl8.cxx" + "${SWIG_SOURCE_DIR}/Modules/typepass.cxx" + "${SWIG_SOURCE_DIR}/Modules/uffi.cxx" + "${SWIG_SOURCE_DIR}/Modules/utils.cxx" + "${SWIG_SOURCE_DIR}/Modules/xml.cxx" + "${PROJECT_BINARY_DIR}/Source/Include/swigconfig.h" + "${SWIG_SOURCE_DIR}/Include/swigwarn.h" +) + +add_executable(swig + "${SWIG_SOURCE_DIR}/Modules/main.cxx" + "${SWIG_SOURCE_DIR}/Modules/swigmain.cxx" +) + +target_link_libraries(swig cparse preprocessor doh core modules) + +# copy binary into Dist folder +get_property(SWIG_EXECUTABLE TARGET swig PROPERTY LOCATION) +add_custom_command(TARGET swig POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy ${SWIG_EXECUTABLE} ${PROJECT_BINARY_DIR}/Dist +) From ecf9f96079067386a5f8bc83fadd4ac9e03f551c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 27 Sep 2013 02:45:22 +0200 Subject: [PATCH 229/352] Javascript documentation. --- .../Javascript/MappingC++ToJavascript.md | 220 ++++ .../V8_CodeGeneratorSpecification.md | 1063 ++++++++++++++++ Doc/Manual/Javascript.html | 770 ++++++++++++ Doc/Manual/Javascript.md | 1103 +++++++++++++++++ Doc/Manual/pandoc_template.html | 56 + 5 files changed, 3212 insertions(+) create mode 100644 Doc/Devel/Javascript/MappingC++ToJavascript.md create mode 100644 Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md create mode 100644 Doc/Manual/Javascript.html create mode 100644 Doc/Manual/Javascript.md create mode 100644 Doc/Manual/pandoc_template.html diff --git a/Doc/Devel/Javascript/MappingC++ToJavascript.md b/Doc/Devel/Javascript/MappingC++ToJavascript.md new file mode 100644 index 000000000..c77064933 --- /dev/null +++ b/Doc/Devel/Javascript/MappingC++ToJavascript.md @@ -0,0 +1,220 @@ +# Mapping C++ language features to Javascript + +## Namespaces + +A namespace is represented as a static instance (global variable) +containing other namespaces, global variables and functions +and class templates + +### Example: + +C++: + +~~~~c++ +namespace foo { + int x; + namespace bar { + double y; + } +} +~~~~ + +Javascript: + +~~~~javascript +var foo = new Object(); +foo.x = 0; +foo.bar = new Object(); +foo.bar.y = 0.0; +~~~~ + +## Global variables and functions + +Global variables and functions are properties of other context objects +(global or namespaces). + +### Example: + +C++: + +~~~~c++ +int x; +namespace foo { + void bar(); +} +~~~~ + +Javascript: + +~~~~javascript +var x = 0; +var foo = new Object(); +foo.bar = function() { + return undefined; +} +~~~~ + +## Classes + +Classes are defined as class templates and instantiated using the `new` +operator. +Class members are set in the constructor function using the `this` reference. +Private class members are set using the `var` keyword. + +### Example: + +C++: + +~~~~c++ +class Foo { + int bar(); + +private: + int x; +} +~~~~ + +Javascript: + +~~~~javascript +var Foo = function() { + var x = 42; + this.bar = function() { return x; }; +}; + +var foo = new Foo(); +foo.bar(); +~~~~ + +## Static class members and functions + +Static variables and functions should be added to the class template object. + +~~~~c++ +class Foo { + static std::string foo(); + std::string bar(); +} +~~~~ + +Javascript: + +~~~~javascript +var Foo = function() { + this.bar = function() { + return "bar"; + } +}; +Foo.foo = function() { + return "foo"; +}; + +var foo = new Foo(); +foo.foo() +> TypeError: Object [object Object] has no method 'foo' +Foo.foo() +> "foo" +foo.bar(); +> "bar" +~~~~ + +## Inheritance + +Javascript uses a prototype based inheritance mechanism. This limits +feature support to single inheritance. + +### Example: + +C++: + +~~~~c++ +class Foo { +public: + int foo(); + +private: + int x; +} + +class Bar: public Foo { +public: + int bar(); +} +~~~~ + +Javascript: + +~~~~javascript +var Foo = function() { + var x = 42; + this.foo = function() { return x; }; +}; + +var Bar = function() { + this.bar = function() { return 6; }; +} +Bar.prototype = new Foo(); +Bar.prototype.constructor = Bar; + +var foo = new Foo(); +var bar = new Bar(); + +foo.foo() +> 42 +foo.bar() +> TypeError: Object [object Object] has no method 'bar' +bar.foo() +> 42 +bar.bar() +> 6 +~~~~ + +## Virtual methods + +The prototype mechanism of Javascript allows method overriding which is +needed to map the concept of virtual functions. + +### Example: + +C++: + +~~~~c++ +class Foo { +public: + virtual int foo(); +} + +class Bar: public Foo { +public: + virtual int foo(); +} +~~~~ + +Javascript: + +~~~~javascript +var Foo = function() { + this.foo = function() { return 1; }; +}; + +var Bar = function() {} +Bar.prototype = new Foo(); +Bar.prototype.constructor = Bar; +Bar.prototype.foo = function() { return 42; }; + +var foo = new Foo(); +var bar = new Bar(); + +foo.foo() +> 1 +bar.foo() +> 42 +~~~~ + +## Overloading + +In Javascript like in other scripting languages method overloading is not +available. I.e., there can only be one function for one function name. +Therefore, it is necessary to implement a method dispatching mechanism +for these methods. + diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md new file mode 100644 index 000000000..63027b74d --- /dev/null +++ b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md @@ -0,0 +1,1063 @@ +Javascript: Specification of a Code Generator for V8 +==================================================== + +The aim of this is to evolve a specification for a code generator. + +## Top Level structure + +The generated code consists of the following blocks: + +~~~~ + + + + + + + + + + +~~~~ + +- `HELPER_FUNCTIONS`: static, from swg-file +- `INCLUDES`: static, module property +- `CLASS_TEMPLATES`: dynamically growing, on class declarations +- `FUNCTION_WRAPPERS`: dynamically growing, on method declarations +- `INITIALIZER`: dynamically growing, aggregates everything (to be specified in more detail) + +### INCLUDES + +~~~~ +#include + + +~~~~ + +`USER_DEFINED_INCLUDES`: a module property + +### CLASS_TEMPLATES + +Static references to class templates which are (should be) read-only and can be reused. + +~~~~ +v8::Persistent SWIGV8_${NAME_MANGLED}; +~~~~ + +Notes: + - it is very important to consider namespaces from the beginning. + `NAME_MANGLED` is the mangled qualified class name, e.g., `foo_bar_MyClass` for `foo::bar::MyClass`, + which is retrieved ny `Swig_string_mangle(Getattr(n, "name"))` + - namespaces do not need a function template, as they will not be + instantiated + +## FUNCTION_WRAPPERS + +There are different types of function wrappers: + + - Global Functions (global/namespace/class) + - Constructors / Destructors + - Getters / Settters + - Member Functions + +### Global Functions + +~~~~ +v8::Handle wrap_${NAME_MANGLED}(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle ret; + ${LOCALS} + ${CODE} + return scope.Close(ret); +} +~~~~ + +- `LOCALS`: declarations for input and output arguments +- `CODE` contains input marshalling, the action, and output marshalling + +### Constructors + +~~~~ +v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + ${LOCALS} + ${CODE} + self->SetInternalField(0, v8::External::New(ptr)); + return self; +} +~~~~ + +- `LOCALS`: declarations for input arguments +- `CODE` contains input marshalling, and the action + +### Destructors + +TODO: I haven't found out yet how a descrtuctor can be registered + +### Getters + +~~~~ +v8::Handle ${NAME_MANGLED}_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle ret; + ${LOCALS} + ${CODE} + return scope.Close(ret); +} +~~~~ + +- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` +- `LOCALS`: declarations for output arguments +- `CODE` contains the action, and output marshalling + +### Setters + +~~~~ +void ${NAME_MANGLED}_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + ${LOCALS} + ${CODE} +} +~~~~ +- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` +- `LOCALS`: declarations for input arguments +- `CODE` contains input marshalling, and the action + +### Functions + +~~~~ +v8::Handle ${NAME_MANGLED}(const Arguments &args) { + v8::HandleScope scope; + v8::Handle ret; + ${LOCALS} + ${CODE} + return scope.Close(ret); +} +~~~~ + +- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` +- `LOCALS`: declarations for input arguments +- `CODE` contains input marshalling, the action, and output marshalling + + +### Overloading + +TODO: if a function or a ctor is overloaded, a dispatcher function +must be generated which calls overloading wrappers depending on number +and type of input arguments. + + +## Initializer + +~~~~ +void ${MODULE}_Initialize(v8::Handle context) +{ + v8::HandleScope scope; + + // register the module in globale context + v8::Local global = context->Global(); + + ${PART_NAMESPACES} + + ${PART_CLASS_TEMPLATES} + + ${PART_WRAPPERS} + + ${PART_INHERITANCE} + + ${PART_REGISTER_CLASSES} + + ${PART_REGISTER_NS} +} +~~~~ + +### Namespaces + +Namespaces are objects without class templates. I.e., instances are created, +referenced locally, used as contexts for other registrations, and stored +in the according parent contexts. + +~~~~~ +v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New(); +~~~~~ + +### Class Templates + +~~~~ +SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new); +~~~~ + +- `NAME_UNQUALIFIED`: the class name without context, i.e., namespaces + +### Inheritance + +~~~~ +SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS}); +~~~~ + +- Note: multiple inheritance is not possible; thus we will always take the first parent class + +### Registration + +The registration part consists of registering classes at contexts (i.e., global or namespace), +methods and properties at classes or contexts, and namespaces as objects at +parent contexts. + +#### Global Variable + +~~~~ +${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER}, ${SETTER}); +~~~~ + +- `CONTEXT`: either global, or the according namespace template +- `${SETTER} = 0` for read-only variables + +#### Global Function + +~~~~ +SWIGV8_AddGlobalFunction(${CONTEXT}, "${NAME_UNQUALIFIED}", wrap_${NAME_QUALIFIED}); +~~~~ + +- `CONTEXT`: either global, or the according namespace template + +#### Class + +~~~~ +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction())); +~~~~ + +- Note: every class template has an associated ctor function wrapper, which is registered here +- `CONTEXT`: either global, or the according namespace instance + +#### Class method + +~~~~ +SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED}); +~~~~ + +Note: implemented in static helper function + +#### Class variable + +~~~~ +SWIGV8_AddProperty(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER}); +~~~~ + +- `GETTER`: the name of the generated wrapper for the property getter +- `SETTER`: the name of the generated wrapper for property setter; optional (i.e., maybe `NULL`) + +### Namespace + +~~~~ +${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance())); +~~~~ + +Note: it is important to register the namespace objects in reverse order, +e.g., + +~~~~ +namespace foo { + namespace bar {} +} +~~~~ + +would be registered in this order: + +~~~~ +foo->Set(v8::String::NewSymbol("bar", bar->NewInstance())); +global->Set(v8::String::NewSymbol("foo", foo->NewInstance())); +~~~~ + +## HELPER_FUNCTIONS + +A lot of boiler-plate code can be shifted into static helper functions: + +~~~~ + +/** + * Creates a class template for a class without extra initialization function. + */ +v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol, v8::InvocationCallback func) +{ + v8::Local class_templ = v8::FunctionTemplate::New(func); + class_templ->SetClassName(v8::String::NewSymbol(symbol)); + + v8::Handle inst_templ = class_templ->InstanceTemplate(); + inst_templ->SetInternalFieldCount(1); + + return v8::Persistent::New(class_templ); +} + +/** + * Registers a class method with given name for a given class template. + */ +void SWIGV8_AddMemberFunction(v8::Handle class_templ, + const char* symbol, + v8::InvocationCallback func) +{ + v8::Handle proto_templ = class_templ->PrototypeTemplate(); + proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)); +} + +/** + * Registers a class property with given name for a given class template. + */ +void SWIGV8_AddMemberVariable(v8::Handle class_templ, + const char* varname, + v8::AccessorGetter getter, + v8::AccessorSetter setter) +{ + v8::Handle proto_templ = class_templ->InstanceTemplate(); + proto_templ->SetAccessor(v8::String::New(varname), getter, setter); +} + + +/** + * Adds a property with given name to a given context. + */ +void SWIGV8_AddGlobalVariable(v8::Handle context, + const char* varname, + v8::AccessorGetter getter, + v8::AccessorSetter setter) +{ + context->SetAccessor(v8::String::NewSymbol(varname), getter, setter); +} + +/** + * Adds a function with given name to a given context. + */ +void SWIGV8_AddGlobalFunction(v8::Handle context, + const char* symbol, + v8::InvocationCallback func) +{ + context->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)->GetFunction()); +} + +template +static T* SWIGV8_UnwrapThisPointer (v8::Handle handle) +{ + // assert(!handle.IsEmpty()); + // assert(handle->InternalFieldCount() > 0); + v8::Local wrap = v8::Local::Cast(handle->GetInternalField(0)); + return static_cast(wrap->Value()); +} + +~~~~ + +------------------------- + +Examples +======== + +In this chapter manually coded wrappers are presented. +This has been useful for studying the addressed code generation on basis +of examples. + +## Global variable + +~~~~~ +static double Foo = 42.0; + +void Foo_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + double arg1 ; + arg1 = value->NumberValue(); + Foo = arg1; +} + +v8::Handle Foo_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle ret; + double result; + + result = Foo; + + ret = v8::Number::New(result); + return scope.Close(ret); +} + +int GlobalVar_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + global->SetAccessor(v8::String::New("Foo"), Foo_get, Foo_set); + + return 0; +} +~~~~~ + +## Global functions + +~~~~~ + +static double foo(int bla) { + return (bla * 2.1); +} + +v8::Handle wrap_foo(const v8::Arguments &args) { + v8::HandleScope scope; + v8::Handle ret; + + int arg1 ; + double result; + + arg1 = args[0]->Int32Value(); + + result = foo(arg1); + + ret = v8::Number::New(result); + + return scope.Close(ret); +} + +int GlobalFunc_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + global->Set(v8::String::NewSymbol("foo"), v8::FunctionTemplate::New(wrap_foo)->GetFunction()); + + return 0; +} +~~~~~ + + +## Namespaces + +~~~~~ + +namespace foo { + static double bar = 42.0; +} + +void foo_bar_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + + double arg1 ; + arg1 = value->NumberValue(); + foo::bar = arg1; + +} + +v8::Handle foo_bar_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle ret; + double result; + + result = foo::bar; + + ret = v8::Number::New(result); + return scope.Close(ret); +} + +int Namespace_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Handle foo = v8::ObjectTemplate::New(); + + foo->SetAccessor(v8::String::New("bar"), foo_bar_get, foo_bar_set); + + global->Set(v8::String::New("foo"), foo->NewInstance()); + return 0; +} + +~~~~~ + +## Class + +~~~~~ + +class A { +public: + A() { + x = 42; + } + + ~A() {} + + double foo(bool a) { + if(a) + return 11.11; + else + return 22.22; + } + + int x; +}; + +v8::Handle A_new(const v8::Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + A *result; + result = new A(); + self->SetInternalField(0, v8::External::New(result)); + return self; +} + +void A_x_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + A *arg1; + int arg2; + + arg1 = SWIGV8_UnwrapThisPointer(info.Holder()); + arg2 = value->Int32Value(); + + arg1->x = arg2; + +} + +v8::Handle A_x_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle jsresult; + A *arg1; + int result; + + arg1 = SWIGV8_UnwrapThisPointer(info.Holder()); + result = arg1->x; + + jsresult = v8::Int32::New(result); + return scope.Close(jsresult); +} + +v8::Handle wrap_A_foo(const v8::Arguments& args) +{ + v8::HandleScope scope; + v8::Handle jsresult; + A *arg1; + double arg2; + double result; + + arg1 = SWIGV8_UnwrapThisPointer(args.Holder()); + arg2 = args[0]->NumberValue(); + + result = arg1->foo(arg2); + + jsresult = v8::Number::New(result); + return scope.Close(jsresult); +} + +int Class_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Persistent class_A = SWIGV8_CreateClassTemplate("A", A_new); + SWIGV8_AddMemberVariable(class_A, "x", A_x_get, A_x_set); + SWIGV8_AddMemberFunction(class_A, "foo", wrap_A_foo); + + global->Set(v8::String::NewSymbol("A"), class_A->GetFunction()); + + return 0; +} + +~~~~~ + +## Static variables and functions + +Static variables and functions are implemented similar to global ones. +They are added to the class object instead of the class template. +Therefore, these are only accessible via the class object and not via +instances of this class. + +~~~~~ + +class A { +public: + A() { + x = 7; + } + + ~A() {} + + static int foo() { + return 42; + } + + static int x; +}; + +int A::x = 7; + +v8::Handle A_new(const v8::Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + A *result; + result = new A(); + self->SetInternalField(0, v8::External::New(result)); + return self; +} + +void A_x_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { + v8::HandleScope scope; + int arg1; + + arg1 = value->Int32Value(); + + A::x = arg1; + +} + +v8::Handle A_x_get(v8::Local property, const v8::AccessorInfo& info) { + v8::HandleScope scope; + v8::Handle jsresult; + int result; + + result = A::x; + + jsresult = v8::Int32::New(result); + return scope.Close(jsresult); +} + +v8::Handle wrap_A_foo(const v8::Arguments& args) +{ + v8::HandleScope scope; + v8::Handle jsresult; + int result; + + result = A::foo(); + + jsresult = v8::Number::New(result); + return scope.Close(jsresult); +} + +int Class_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Persistent classtempl_A = SWIGV8_CreateClassTemplate("A", A_new); + + v8::Handle class_A = classtempl_A->GetFunction(); + + SWIGV8_AddGlobalVariable(class_A, "x", A_x_get, A_x_set); + SWIGV8_AddGlobalFunction(class_A, "foo", wrap_A_foo); + + global->Set(v8::String::NewSymbol("A"), class_A); + + return 0; +} + +~~~~~ + +## Inheritance + +~~~~~ +class A { +public: + A() {} + + ~A() {} + + double foo() { + return 11.11; + } +}; + +class B: public A { +public: + B() {} + ~B() {} + + int bar() { + return 7; + } +}; + +... (left out function wrappers) ... + +int Class_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + v8::Persistent class_A = SWIGV8_CreateClassTemplate("A", A_new); + v8::Persistent class_B = SWIGV8_CreateClassTemplate("B", B_new); + + SWIGV8_AddMemberFunction(class_A, "foo", wrap_A_foo); + SWIGV8_AddMemberFunction(class_B, "bar", wrap_B_bar); + + class_B->Inherit(class_A); + + global->Set(v8::String::NewSymbol("A"), class_A->GetFunction()); + global->Set(v8::String::NewSymbol("B"), class_B->GetFunction()); + + return 0; +} +~~~~~ + +## String arguments + +At a first stage all strings are treated as Utf8. +For proper handling strings as return values I have to study +other modules. + +~~~~~ +int my_strlen(const char* s) { + return strlen(s); +} + +// creates a new string +const char* foo(int a) { + char* result = new char[a+1]; + result[a] = 0; + memset(result, 'a', a); + return result; +} + +v8::Handle wrap_my_strlen(const v8::Arguments& args) +{ + v8::HandleScope scope; + v8::Handle jsresult; + const char* arg1; + int result; + + v8::String::Utf8Value utf8(args[0]); + + result = my_strlen(*utf8); + + jsresult = v8::Number::New(result); + return scope.Close(jsresult); +} + +v8::Handle wrap_foo(const v8::Arguments& args) +{ + v8::HandleScope scope; + v8::Handle jsresult; + int arg1; + const char* result; + + arg1 = args[0]->Int32Value(); + result = foo(arg1); + + jsresult = v8::String::New(result); + + return scope.Close(jsresult); +} + +int Strings_Initialize(v8::Handle context) { + + v8::Local global = context->Global(); + + SWIGV8_AddGlobalFunction(global, "strlen", wrap_my_strlen); + SWIGV8_AddGlobalFunction(global, "foo", wrap_foo); + + return 0; +} +~~~~~ + +------------------------- + +Control flow analysis +===================== + +## Global variables + +### Example: +~~~~ +int x; + +namespace foo { + double y; +} +~~~~ + +### Control flow: +Command: +~~~~ +swig -analyze -c++ functionWrapper +before globalvariableHandler +before example.i +~~~~ + +~~~~ +enter top() of example +enter variableHandler() of x +enter globalvariableHandler() of x + | sym:name - "x" + | name - "x" + | type - "int" + + enter variableWrapper() of x + + enter functionWrapper() of x + | name - "x" + | sym:name - "x_set" + | parms - int + | wrap:action - "x = arg1;" + | type - "void" + exit functionWrapper() of x + + enter functionWrapper() of x + | name - "x" + | sym:name - "x_get" + | type - "int" + exit functionWrapper() of x + exit variableWrapper() of x +exit globalvariableHandler() of x +exit variableHandler() of x + +enter variableHandler() of foo::y +enter globalvariableHandler() of foo::y + | sym:name - "y" + | name - "foo::y" + | type - "double" + + enter variableWrapper() of foo::y + enter functionWrapper() of foo::y + | name - "foo::y" + | sym:name - "y_set" + | parms - double + | wrap:action - "foo::y = arg1;" + | type - "void" + exit functionWrapper() of foo::y + + enter functionWrapper() of foo::y + | name - "foo::y" + | sym:name - "y_get" + | wrap:action - "result = (double)foo::y;" + | type - "double" + exit functionWrapper() of foo::y + exit variableWrapper() of foo::y +exit globalvariableHandler() of foo::y +exit variableHandler() of foo::y +exit top() of example + +~~~~ + +## Simple class + +### Example: + +~~~~ +class A { +public: + A(); + ~A(); +}; + +namespace foo { + class B { + }; +} +~~~~ + +### Control flow: + +~~~~ +enter top() of example + enter classHandler() of A + enter constructorHandler() of A + enter functionWrapper() of A + | name - "A" + | sym:name - "new_A" + | access - "public" + | wrap:action - "result = (A *)new A();" + | type - "p.A" + exit functionWrapper() of A + exit constructorHandler() of A + enter destructorHandler() of ~A + enter functionWrapper() of ~A + | name - "~A" + | sym:name - "delete_A" + | parms - A * + | wrap:action - "delete arg1;" + exit functionWrapper() of ~A + exit destructorHandler() of ~A +exit classHandler() of A +enter classHandler() of foo::B + enter constructorHandler() of foo::B::B + enter functionWrapper() of foo::B::B + | name - "foo::B::B" + | sym:name - "new_B" + | access - "public" + | wrap:action - "result = (foo::B *)new foo::B();" + | type - "p.foo::B" + exit functionWrapper() of foo::B::B + exit constructorHandler() of foo::B::B + enter destructorHandler() of foo::B::~B + enter functionWrapper() of foo::B::~B + | name - "foo::B::~B" + | sym:name - "delete_B" + | parms - foo::B * + | wrap:action - "delete arg1;" + | type - "void" + exit functionWrapper() of foo::B::~B + exit destructorHandler() of foo::B::~B +exit classHandler() of foo::B +exit top() of example + +~~~~ + +### Example + +~~~~ +class A { +public: + int x; +}; +~~~~ + + +### Control flow + +~~~~ +enter top() of example +enter classHandler() of A + enter variableHandler() of x + enter membervariableHandler() of x + enter functionWrapper() of x + | name - "x" + | sym:name - "A_x_set" + | access - "public" + | parms - A *,int + | wrap:action - "if (arg1) (arg1)->x = arg2;" + | type - "void" + | memberset - "1" + exit functionWrapper() of x + enter functionWrapper() of x + | name - "x" + | sym:name - "A_x_get" + | access - "public" + | parms - A * + | wrap:action - "result = (int) ((arg1)->x);" + | type - "int" + | memberset - "1" + | memberget - "1" + exit functionWrapper() of x + exit membervariableHandler() of x + exit variableHandler() of x + enter constructorHandler() of A::A + enter functionWrapper() of A::A + exit functionWrapper() of A::A + exit constructorHandler() of A::A + enter destructorHandler() of A::~A + enter functionWrapper() of A::~A + exit functionWrapper() of A::~A + exit destructorHandler() of A::~A +exit classHandler() of A +exit top() of example +~~~~ + +## Class method + +### Example + +~~~~ +class A { +public: + void foo(int x, double y); +private: + void bar(); +}; +~~~~ + +### Control flow + +~~~~ +enter top() of example +enter classHandler() of A + enter functionHandler() of foo + enter memberfunctionHandler() of foo + enter functionWrapper() of foo + | name - "foo" + | sym:name - "A_foo" + | access - "public" + | parms - A *,int,double + | wrap:action - "(arg1)->foo(arg2,arg3);" + | type - "void" + exit functionWrapper() of foo + exit memberfunctionHandler() of foo + exit functionHandler() of foo +... +exit classHandler() of A +exit top() of example +~~~~ + +## Static class variable and method + +### Example + +~~~~ +class A { +public: + static int x; + + static void foo(); +}; +~~~~ + +### Control flow + +~~~~ +enter top() of example +enter classHandler() of A + enter variableHandler() of x + enter staticmembervariableHandler() of x + enter variableWrapper() of A::x + enter functionWrapper() of A::x + | name - "A::x" + | sym:name - "A_x_set" + | parms - int + | wrap:action - "A::x = arg1;" + | type - "void" + exit functionWrapper() of A::x + enter functionWrapper() of A::x + +++ cdecl ---------------------------------------- + | name - "A::x" + | ismember - "1" + | sym:name - "A_x_get" + | variableWrapper:sym:name - "A_x" + | wrap:action - "result = (int)A::x;" + | type - "int" + exit functionWrapper() of A::x + exit variableWrapper() of A::x + exit staticmembervariableHandler() of x + exit variableHandler() of x + enter functionHandler() of foo + enter staticmemberfunctionHandler() of foo + enter globalfunctionHandler() of A::foo + enter functionWrapper() of A::foo + | name - "A::foo" + | sym:name - "A_foo" + | wrap:action - "A::foo();" + | type - "void" + exit functionWrapper() of A::foo + exit globalfunctionHandler() of A::foo + exit staticmemberfunctionHandler() of foo + exit functionHandler() of foo + enter constructorHandler() of A::A + exit constructorHandler() of A::A + enter destructorHandler() of A::~A + exit destructorHandler() of A::~A +exit classHandler() of A +exit top() of example +~~~~ + +## Inheritance + +### Example + +~~~~ +class A { +}; + +class B: public A { +}; +~~~~ + +### Control flow + +~~~~ +enter top() of example +enter classHandler() of A + +++ class ---------------------------------------- + | name - "A" + | sym:name - "A" +... +exit classHandler() of A +enter classHandler() of B + | name - "B" + | sym:name - "B" + | privatebaselist - 0xf1238f10 + | protectedbaselist - 0xf1238ef0 + | baselist - 0xf1238ed0 + | bases - 0xf1239830 + | allbases - 0xf1239c30 +... +exit classHandler() of B +exit top() of example +~~~~ diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html new file mode 100644 index 000000000..a53e2a7cd --- /dev/null +++ b/Doc/Manual/Javascript.html @@ -0,0 +1,770 @@ + + + + + + + SWIG AND JAVASCRIPT + + + + + +
+

Overview

+

This chapter describes SWIG support for Javascript. The module is designed to support JavascriptCore and V8 as target engine. Currently only JavascriptCore support is implemented. JavaScriptCore is the built-in JavaScript engine for WebKit, whereas V8 is the engine used by Chromium.

+

JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. C++, on the other hand, is statically typed, compiled, general purpose programming language. The approach I followed here is "Test driven" where I have written the examples/test-cases to be supported for Javascript one-by-one and implemented the required module files in parallel. The support for Javascript would be added similar to other supported target languages in swig. Swig comes with an "Examples" directory for Javascript like other supported language. The directory contains examples for every supported feature of the target language. There is also a test-suite directory for javascript which contains additional tests.

+

Preliminaries

+

In order to use this module, you will need to have installed javascriptcore and you can install it by installing package libwebkit-dev You can find out some necessary compiler/linker flag by

+
pkg-config javascriptcoregtk-1.0 --cflags --libs
+
+

Using the module

+

To generate an extension for JavascriptCore one would call swig as follows

+

swig -c++ -javascript -jsc example.i +
+

This generates a C++ source file containing the wrapper.

+

How does Javascript talk to C++?

+

JavascriptCore provides a C-API which allows to extend a Javascript interpreter with native methods and structures. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is also possible to add your own commands and variables. A reference manual of this API can be found here.

+

Typically, when you add a new command to the javascript interpreter you need to do two things: first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process.

+

Wrapper functions

+

Suppose you have an ordinary C function like this :

+

int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); +} +
+

In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things :

+
    +
  • Gather function arguments and make sure they are valid.
  • +
  • Call the C function.
  • +
  • Convert the return value into a form recognized by the javascript.
  • +
+

As an example, the javascript wrapper function for the fact() function above example might look like the following :

+

JSValueRef wrap_fact(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + int arg1 = (int)JSValueToNumber(context, argv[0], NULL); + int arg2 = (int)JSValueToNumber(context, argv[1], NULL); + int result = (int)fact(arg1,arg2); + JSValueRef jsresult = JSValueMakeNumber(context, result); + return jsresult; +} +
+

Once you have created a wrapper function, the final step is to tell the javascript about the new function. This is done by register function called by the javascript when the module is loaded. For example, adding the above function to the javascript interpreter requires code like the following :

+

bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_globalvarsclassname = JSStringCreateWithUTF8CString(globalvarsclassname); + JSObjectSetProperty(context,js_globalvarsclassname,JSObjectMakeFunctionWithCallback(context, + js_globalvarsclassname, callback), kJSPropertyAttributeNone,NULL); + JSStringRelease(jsstring); + return true; +} + +int example_init(JSContextRef context) { + JSObjectRef global; + ... + jsc_registerFunction(context, global, "fact", wrap_fact); + ... +} +
+

When executed, javascript will now have a new command called "fact" that you can use like any other Javascript command. Although the process of adding a new function to javascript has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code.

+

Variable Linking

+

Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable:

+

double Foo = 3.5; +
+

To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called.

+

bool Foo_set(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef value, + JSValueRef* exception) +{ + JSValueRef jsresult; + double arg1 = (double)JSValueToNumber(context, value, NULL); + Foo = arg1; + jscresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef Foo_get(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + double result = (double)Foo; + jsresult = JSValueMakeNumber(context, result); + return jsresult; +} +
+

In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as Foo might implicitly call the get function. Similarly, typing Foo = 4 would call the underlying set function to change the value.

+

A tour of basic C/C++ wrapping

+

By default, SWIG tries to build a very natural javascript interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping.

+

Modules

+

The SWIG %module directive specifies the name of the Javascript module. If you specify %module example, then everything is wrapped into a Javascript 'example' module. Underneath the covers, this module consists of a cpp source file example.cpp. When choosing a module name, make sure you don't use the same name as a built-in Javascript command or standard module name.

+

Global variables

+

C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that javascript works.

+

// SWIG interface file with global variables +%module example +... +%inline %{ +extern double Foo; +extern int gcd(int x, int y); +%} +... +
+

Now look at the javascript:

+

print("Global variable Foo=" + example.Foo); +example.Foo = 3.1415926; +print("Variable Foo changed to=" + example.Foo); +print("GCD of x and y is=" + example.gcd(x,y)); +
+

Constants and enums

+

C/C++ constants are installed as javascript objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example:

+

#define ICONST 42 +#define FCONST 2.1828 +%constant int iconst = 37; +
+

In javascript they are treated as:

+

print("ICONST = " + example.ICONST + " (should be 42)\n"); +print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +print("iconst = " + example.iconst + " (should be 37)\n"); +
+

For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile. Enums are treated as constants.So if we have enums in c++ as:

+

void enum_test(color c, Foo::speed s); +
+

In javascript they are treated as:

+

example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); +
+

Inside the class

+

For class enums as below:

+

class Foo { +public: +Foo() { } +enum speed { IMPULSE, WARP, LUDICROUS }; +} +
+

In javascript they are treated as:

+

print(" Foo_IMPULSE =" + example.Foo.IMPULSE); +print(" Foo_WARP =" + example.Foo.WARP); +print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); +
+

Pointers

+

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface

+

/* File : example.i */ +%module example +%{ +extern void add(int *, int *, int *); +%} +
+

When wrapped, you will be able to use the functions in a natural way from javascript. For example:

+

// Call the add() function with some pointers +example.add(a, b, c); +
+

// In javascript the code look like as:

+

a = example.new_intp(); +example.intp_assign(a,37); +
+
    +
  • The first one creates an int-pointer instance.
  • +
  • The second one assigns it the value 37.
  • +
+

C++ classes

+

C++ classes are wrapped by javascript classes as well. For example, if you have this class,

+

class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; +}; +
+

you can use it in javascript like this:

+

print("Creating some objects:"); +c = new example.Circle(10); +print("area = " + c.area()); +
+

Class data members are accessed in the same manner as C structures.

+

Static class members and functions are mapped to javascript in a straight-forward manner:

+

class Spam { +public: + static void foo(); + static int bar; +}; +
+

In javascript, the static member can be access in this way:

+

// ----- Access a static member ----- +print("\nA access of static member is" + example.Spam.Foo); // access static member as properties of the class object. +
+

C++ inheritance

+

SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this

+

class A { +public: + void foo(); + virtual void bar(); +}; +class B: public A { +public: + virtual void bar(); +}; +
+

Those classes are wrapped into a hierarchy of javascript classes that reflect the same inheritance structure. All of the usual javascript utility functions work normally:

+

var a = new example.A(); +a.foo(); +a.bar(); +var b = new example.B(); +b.foo(); +b.bar(); +print("b.cPtr = " + b.getCPtr()); +
+

C++ overloaded functions

+

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:

+

void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} +
+

You can use them in javascript in a straightforward manner:

+

example.f(1); +example.f(1, 2); +example.f("bla"); +
+

C++ operators

+

Certain C++ overloaded operators can be handled automatically by SWIG. Though, in javascript operator overloading is not possible. Instead one has to make use of the %rename feature.

+

For example, consider a class like this:

+

/* File : example.h */ +#include <math.h> +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; +
+

When wrapped, it works like you expect:

+

a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +print ("a =" + a); +print ("b =" + b); + +c = a.plus(b); + +print("c =" + c); +print("a*b =" + a.times(b)); +print("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +print("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +print("f =" + f); +
+

One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this

+

class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; +
+

then SWIG ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:

+

%rename(Complex_add_dc) operator+(double, const Complex &);

+

There are ways to make this operator appear as part of the class using the %extend directive.

+

C++ namespaces:

+

SWIG is aware of C++ namespaces, but namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this,

+

%module example +namespace nspace { +extern int gcd(int x, int y); +extern double Foo; +class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; + }; +} +
+

for namespaces, you use the %feature directive in interface file. %feature attaches a new attribute to any parse tree node that matches given prototype.

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%feature("nspace", 1); +%include "example.h" +
+

it works in javascript as follows:

+

print("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +print("Variable Foo changed to " + example.nspace.Foo); +print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); +print("Creating some objects:"); +c = new example.nspace.Circle(10); +print("area = " + c.area()); +
+

If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:

+

%rename(Bar_spam) Bar::spam; +namespace Foo { + int spam(); +} +namespace Bar { + int spam(); +} +
+

If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence.

+

C++ templates

+

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ +%template(maxint) max<int>; +%template(maxdouble) max<double>; +%template(vecint) vector<int>; +%template(vecdouble) vector<double>; +
+

In javascript:

+

//Call some templated functions +print(example.maxint(3,7)); +print(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +print(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +print(sum); +
+

Exception handling

+

The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into javascript exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following:

+

Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the javascript extension by writing the following in an interface file:

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" +
+

Actually in JS there is no support for typed exceptions.For now there is support for integer and string exception. Example for integer exception

+

JSValueRef jsc_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +*exception = JSValueMakeNumber(context, 13); +int result = (int)gcd(arg1,arg2); +JSValueRef jsresult = JSValueMakeNumber(context, result); +
+

and for string exception:

+

JSValueRef wrap_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +JSStringRef message = JSStringCreateWithUTF8CString("This is a test error."); +*exception = JSValueMakeString(context, message); +JSStringRelease(message); +int result = (int)gcd(arg1,arg2); +JSValueRef jscresult = JSValueMakeNumber(context, result); +return jsresult; +} +
+

How to use generated modules?

+

Basically there is no standard extension mechanism in Javascript. We provided a custom interpreter with extension abilities. If JSC is embedded into a custom application, one has to make use of a generated module initializer function that allows easy extension of interpreter. The basic approach is as follows:

+

Basic Mechanism

+
    +
  • Creating the context
  • +
  • Calling module initializer
  • +
  • Evaluate Javascript
  • +
+

Creating the context

+

JSGlobalContextRef context = JSGlobalContextCreate(NULL); +JSObjectRef globalObject = JSContextGetGlobalObject(context); +... +
+

Calling module initializer

+

extern int example_init(JSGlobalContextRef context); + ... + example_init(context); + ... +
+

Evaluate Javascript

+

// Evaluate the javascript +char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); +JSStringRef jsScript; +if(!scriptContent) { + printf("FAIL: runme script could not be loaded.\n"); + failed = 1; + } + else { + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(scriptContent); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + if (!jsResult && ex) { + jsc_printError(context, ex, scriptPath); + failed = 1; + } + } + if (scriptContent != NULL) { + free(scriptContent); + } + JSStringRelease(jsScript); + JSGlobalContextRelease(context); + globalObject = 0; + for(std::vector<HANDLE>::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + dlclose(handle); + } + if (failed) { + printf("FAIL: Some tests failed.\n"); + return 1; + } +} +
+

Typemaps

+

A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from javascript to C, you might define a typemap like this:

+

%typemap(in) int { + $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} + printf("Received an integer : %d\n",$1); +} +
+

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int.

+

Javascript typemaps

+

The previous section illustrated an "in" typemap for converting javascript objects to C. A variety of different typemap methods are defined by the javascript module. For example, to convert a C integer back into a javascript object, you might define an "out" typemap like this:

+

%typemap(out) int { + $result = JSValueMakeNumber(context, $1); +} +
+

The Javascript module makes use of Swig's unified template library.

+

Typemap variables

+

Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

+

$1: A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Javascript.

+

$input: A javascript Object * holding a raw javascript object with an argument or variable value.

+

$result: A javascript Object * that holds the result to be returned to javascript.

+

$1_name: The parameter name that was matched.

+

$1_type: The actual C datatype matched by the typemap.

+

$1_ltype: An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.

+

$symname: The javascript name of the wrapper function being created.

+

Javascript: Specification of a Code Generator for JSC

+

The module implementation tries to accomplish a separation of logic and code generation by making use of code templates. In the following, the templates are explained.

+

Top Level structure

+

The generated code consists of the following blocks:

+

<RUNTIME> +<INCLUDES> +<HELPER_FUNCTIONS> +<FUNCTION_WRAPPERS> +<INITIALIZER> +
+
    +
  • RUNTIME: runtime code generated by swig
  • +
  • HELPER_FUNCTIONS: static, from swg-file
  • +
  • INCLUDES: static, module property
  • +
  • FUNCTION_WRAPPERS: dynamically growing, on method declarations
  • +
  • INITIALIZER: dynamically growing, aggregates everything
  • +
+

INCLUDES

+

#include <JavaScriptCore/JavaScript.h> +<USER_DEFINED_INCLUDES> +
+

USER_DEFINED_INCLUDES: a module property

+

HELPER_FUNCTIONS

+

A lot of boiler-plate code can be shifted into static helper functions:

+

bool JS_registerClass(JSGlobalContextRef& context, JSObjectRef& parentObject,const char* className, + JSClassDefinition* definition) { + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject,js_className, classObject,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef& context,JSObjectRef& namespaceObj,JSObjectRef& parentNamespace,const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace,js_name, namespaceObj,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + return true; +} + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context,object,js_functionName,JSObjectMakeFunctionWithCallback(context, + js_functionName, callback), kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return val; +} +
+

FUNCTION_WRAPPERS

+

There are different types of function wrappers: - Member Functions - Getproperty / Setproperty - Global Functions (global/namespace/class) - Constructors / Destructors

+

Member Functions

+

JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • functionname: the name of generated wrapper for function
  • +
  • LOCALS: declarations for input arguments
  • +
  • CODE: contains input marshalling, the action, and output marshalling
  • +
+

Setproperty

+

bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • setname: the name of the generated wrapper for setproperty.
  • +
  • LOCALS: declarations for input arguments
  • +
  • CODE: contains input marshalling, and the action
  • +
+

Getproperty

+

JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • getname: the name of the generated wrapper for the getproperty
  • +
  • LOCALS: declarations for output arguments
  • +
  • CODE: contains the action, and output marshalling
  • +
+

Global Functions

+

JSStaticValue ${namespace}_values[] = { + ${jsglobalvariables} + { 0, 0, 0, 0 } +}; +JSStaticFunction ${namespace}_functions[] = { + ${jsglobalfunctions} + { 0, 0, 0 } +}; +JSClassDefinition ${namespace}_classDefinition; +
+

Variable declaration

+

{"${propertyname}",${getname}, ${setname}, kJSPropertyAttributeNone} +
+

This is used to fill variable definition tables. kJSPropertyAttributeNone is JSC specific and means that the variable has a getter and setter. Even for read-only variables a setter is used which throws an exception.

+

Constructor

+

~~

+

JSObjectRef wrap_createclassnamemangled{overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { ${LOCALS} ${CODE} return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN);

+
goto fail;
+fail:
+return NULL;
+
+

}

+
- `classname_mangled` is the mangled qualified class name,   e.g., `foo::A -> foo_A`
+- `LOCALS`: declarations for input arguments 
+- `CODE`: contains input marshalling, and the action 
+
+## Destructors
+
+

void wrap${classname_mangled}_finalize(JSObjectRef thisObject) { SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) delete (${type}*)(t->swigCObject); if(t) delete t; }

+

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + +## Initializer +
+

bool ${modulename}_initialize(JSGlobalContextRef context) { SWIG_InitializeModule(0);

+
JSObjectRef global_object = JSContextGetGlobalObject(context);
+
+/* Initialize the base swig type object */
+_SwigObject_objectDefinition.staticFunctions = _SwigObject_functions;
+_SwigObject_objectDefinition.staticValues = _SwigObject_values;
+_SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition);
+
+/* Create objects for namespaces */
+${create_namespaces}
+
+/* Create classes */
+${initializercode}
+
+/* Register namespaces */
+${register_namespaces}
+
+return true;
+
+

}

+

## Class template defintions + +A class is specified by a static part (`*_classDefinition`) and a dynamic part (`*_objectDefinition`). +
+

${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}objectDefinition); SWIGTYPE${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%}

+

Notes: +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + which is retrieved by `Swig_name_mangle(Getattr(n, "name"))` +- ClassDefinitions are built using the staticValues array and the staticFunction array. The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties to the class object. + +## Inheritance +
+

{${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef};

+

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` +- Note: multiple inheritance is not possible; thus we will always take the first parent class + +## Namespaces + +Namespaces are objects without class templates. i.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. +
+

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

+

## Registration + +The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. + +* Global functions +
+

JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper}

+

* Classes +
+

JS_registerClass(context, ${namespace}_object, "${classname}", &${classname_mangled}_classDefinition)

+

Note: every class template has an associated constructor function wrapper, which is registered here + +* Namespaces +
+

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

+

Namespaces are registered using: +
+

JS_registerNamespace(context, ${namespace}_object, ${parent_namespace}_object, "${namespace}");

+

~~

+
+ + diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md new file mode 100644 index 000000000..a01c630d8 --- /dev/null +++ b/Doc/Manual/Javascript.md @@ -0,0 +1,1103 @@ +% SWIG AND JAVASCRIPT + +# Overview + +This chapter describes SWIG support for Javascript. +The module is designed to support JavascriptCore and V8 as target engine. +Currently only JavascriptCore support is implemented. +JavaScriptCore is the built-in JavaScript engine for WebKit, whereas V8 is the engine used by Chromium. + +JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. C++, on the other hand, is statically typed, compiled, general purpose programming language. +The approach I followed here is "Test driven" where I have written the examples/test-cases to be supported for Javascript one-by-one and implemented the required module files in parallel. +The support for Javascript would be added similar to other supported target languages in swig. Swig comes with an "Examples" directory for Javascript like other supported language. The directory contains examples for every supported feature of the target language. There is also a test-suite directory for javascript which contains additional tests. + +# Preliminaries + +In order to use this module, you will need to have installed javascriptcore and you can install it by installing package libwebkit-dev +You can find out some necessary compiler/linker flag by + + pkg-config javascriptcoregtk-1.0 --cflags --libs + +## Using the module + +To generate an extension for JavascriptCore one would call swig as follows + +~~~~ + +swig -c++ -javascript -jsc example.i + +~~~~ + +This generates a C++ source file containing the wrapper. + +## How does Javascript talk to C++? + +JavascriptCore provides a C-API which allows to extend a Javascript interpreter with native methods and structures. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is also possible to add your own commands and variables. A reference manual of this API can be found +[here](http://developer.apple.com/library/mac/#documentation/Carbon/Reference/WebKit_JavaScriptCore_Ref/_index.html). + +Typically, when you add a new command to the javascript interpreter you need to do two things: first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process. + +## Wrapper functions + +Suppose you have an ordinary C function like this : + +~~~~ + +int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); +} + +~~~~ + +In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things : + + - Gather function arguments and make sure they are valid. + - Call the C function. + - Convert the return value into a form recognized by the javascript. + +As an example, the javascript wrapper function for the fact() function above example might look like the following : + +~~~~ + +JSValueRef wrap_fact(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + int arg1 = (int)JSValueToNumber(context, argv[0], NULL); + int arg2 = (int)JSValueToNumber(context, argv[1], NULL); + int result = (int)fact(arg1,arg2); + JSValueRef jsresult = JSValueMakeNumber(context, result); + return jsresult; +} + +~~~~ + +Once you have created a wrapper function, the final step is to tell the javascript about the new function. This is done by register function called by the javascript when the module is loaded. For example, adding the above function to the javascript interpreter requires code like the following : + +~~~~ + +bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_globalvarsclassname = JSStringCreateWithUTF8CString(globalvarsclassname); + JSObjectSetProperty(context,js_globalvarsclassname,JSObjectMakeFunctionWithCallback(context, + js_globalvarsclassname, callback), kJSPropertyAttributeNone,NULL); + JSStringRelease(jsstring); + return true; +} + +int example_init(JSContextRef context) { + JSObjectRef global; + ... + jsc_registerFunction(context, global, "fact", wrap_fact); + ... +} + +~~~~ + +When executed, javascript will now have a new command called "fact" that you can use like any other Javascript command. +Although the process of adding a new function to javascript has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code. + +## Variable Linking + +Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable: + +~~~~ + +double Foo = 3.5; + +~~~~ + +To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called. + +~~~~ + +bool Foo_set(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef value, + JSValueRef* exception) +{ + JSValueRef jsresult; + double arg1 = (double)JSValueToNumber(context, value, NULL); + Foo = arg1; + jscresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef Foo_get(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + double result = (double)Foo; + jsresult = JSValueMakeNumber(context, result); + return jsresult; +} + +~~~~ + +In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as Foo might implicitly call the get function. Similarly, typing Foo = 4 would call the underlying set function to change the value. + +# A tour of basic C/C++ wrapping + +By default, SWIG tries to build a very natural javascript interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping. + +## Modules + +The SWIG %module directive specifies the name of the Javascript module. If you specify `%module example`, then everything is wrapped into a Javascript 'example' module. Underneath the covers, this module consists of a cpp source file example.cpp. When choosing a module name, make sure you don't use the same name as a built-in Javascript command or standard module name. + +## Global variables + +C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that javascript works. + +~~~~ + +// SWIG interface file with global variables +%module example +... +%inline %{ +extern double Foo; +extern int gcd(int x, int y); +%} +... + +~~~~ + +Now look at the javascript: + +~~~~ + +print("Global variable Foo=" + example.Foo); +example.Foo = 3.1415926; +print("Variable Foo changed to=" + example.Foo); +print("GCD of x and y is=" + example.gcd(x,y)); + +~~~~ + +## Constants and enums + +C/C++ constants are installed as javascript objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example: + +~~~~ + +#define ICONST 42 +#define FCONST 2.1828 +%constant int iconst = 37; + +~~~~ + +In javascript they are treated as: + +~~~~ + +print("ICONST = " + example.ICONST + " (should be 42)\n"); +print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +print("iconst = " + example.iconst + " (should be 37)\n"); + +~~~~ + +For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile. +Enums are treated as constants.So if we have enums in c++ as: + +~~~~ + +void enum_test(color c, Foo::speed s); + +~~~~ + +In javascript they are treated as: + +~~~~ + +example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); + +~~~~ + +### Inside the class +For class enums as below: + +~~~~ + +class Foo { +public: +Foo() { } +enum speed { IMPULSE, WARP, LUDICROUS }; +} + +~~~~ + +In javascript they are treated as: + +~~~~ + +print(" Foo_IMPULSE =" + example.Foo.IMPULSE); +print(" Foo_WARP =" + example.Foo.WARP); +print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); + +~~~~ + +## Pointers + +C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface + +~~~~ + +/* File : example.i */ +%module example +%{ +extern void add(int *, int *, int *); +%} + +~~~~ + +When wrapped, you will be able to use the functions in a natural way from javascript. For example: + +~~~~ + +// Call the add() function with some pointers +example.add(a, b, c); + +~~~~ + +// In javascript the code look like as: + +~~~~ + +a = example.new_intp(); +example.intp_assign(a,37); + +~~~~ + +- The first one creates an int-pointer instance. +- The second one assigns it the value 37. + +### C++ classes + +C++ classes are wrapped by javascript classes as well. For example, if you have this class, + +~~~~ + +class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; +}; + +~~~~ + +you can use it in javascript like this: + +~~~~ + +print("Creating some objects:"); +c = new example.Circle(10); +print("area = " + c.area()); + +~~~~ + +Class data members are accessed in the same manner as C structures. + +Static class members and functions are mapped to javascript in a straight-forward manner: + +~~~~ + +class Spam { +public: + static void foo(); + static int bar; +}; + +~~~~ + +In javascript, the static member can be access in this way: + +~~~~ + +// ----- Access a static member ----- +print("\nA access of static member is" + example.Spam.Foo); // access static member as properties of the class object. + +~~~~ + +## C++ inheritance + +SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this + +~~~~ + +class A { +public: + void foo(); + virtual void bar(); +}; +class B: public A { +public: + virtual void bar(); +}; + +~~~~ + +Those classes are wrapped into a hierarchy of javascript classes that reflect the same inheritance structure. All of the usual javascript utility functions work normally: + +~~~~ + +var a = new example.A(); +a.foo(); +a.bar(); +var b = new example.B(); +b.foo(); +b.bar(); +print("b.cPtr = " + b.getCPtr()); + +~~~~ + +## C++ overloaded functions + +C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this: + +~~~~ + +void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} + +~~~~ + +You can use them in javascript in a straightforward manner: + +~~~~ + +example.f(1); +example.f(1, 2); +example.f("bla"); + +~~~~ + +## C++ operators + +Certain C++ overloaded operators can be handled automatically by SWIG. Though, in javascript operator overloading is not possible. Instead one has to make use of the `%rename` feature. + +For example, consider a class like this: + +~~~~ + +/* File : example.h */ +#include +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + +~~~~ + +When wrapped, it works like you expect: + +~~~~ + +a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +print ("a =" + a); +print ("b =" + b); + +c = a.plus(b); + +print("c =" + c); +print("a*b =" + a.times(b)); +print("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +print("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +print("f =" + f); + +~~~~ + +One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this + +~~~~ + +class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; + +~~~~ + +then SWIG ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example: + +%rename(Complex_add_dc) operator+(double, const Complex &); + +There are ways to make this operator appear as part of the class using the %extend directive. + +## C++ namespaces: + +SWIG is aware of C++ namespaces, but namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this, + +~~~~ + +%module example +namespace nspace { +extern int gcd(int x, int y); +extern double Foo; +class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; + }; +} + +~~~~ + +for namespaces, you use the %feature directive in interface file. %feature attaches a new attribute to any parse tree node that matches given prototype. + +~~~~ + +/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%feature("nspace", 1); +%include "example.h" + +~~~~ + +it works in javascript as follows: + +~~~~ + +print("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +print("Variable Foo changed to " + example.nspace.Foo); +print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); +print("Creating some objects:"); +c = new example.nspace.Circle(10); +print("area = " + c.area()); + +~~~~ + +If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example: + +~~~~ + +%rename(Bar_spam) Bar::spam; +namespace Foo { + int spam(); +} +namespace Bar { + int spam(); +} + +~~~~ + +If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. +SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence. + +## C++ templates + +C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example: + +~~~~ + +/* File : example.i */ +%module example +%{ +#include "example.h" +%} +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + +~~~~ + +In javascript: + +~~~~ + +//Call some templated functions +print(example.maxint(3,7)); +print(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +print(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +print(sum); + +~~~~ + +## Exception handling + +The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into javascript exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following: + +Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the javascript extension by writing the following in an interface file: + +~~~~ + +/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" + +~~~~ + +Actually in JS there is no support for typed exceptions.For now there is support for integer and string +exception. Example for integer exception + +~~~~ + +JSValueRef jsc_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +*exception = JSValueMakeNumber(context, 13); +int result = (int)gcd(arg1,arg2); +JSValueRef jsresult = JSValueMakeNumber(context, result); + +~~~~ + +and for string exception: + +~~~~ + +JSValueRef wrap_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +JSStringRef message = JSStringCreateWithUTF8CString("This is a test error."); +*exception = JSValueMakeString(context, message); +JSStringRelease(message); +int result = (int)gcd(arg1,arg2); +JSValueRef jscresult = JSValueMakeNumber(context, result); +return jsresult; +} + +~~~~ + +## How to use generated modules? + +Basically there is no standard extension mechanism in Javascript. We provided a custom interpreter with extension abilities. If JSC is embedded into a custom application, one has to make use of a generated module initializer function that allows easy extension of interpreter. +The basic approach is as follows: + +### Basic Mechanism +- Creating the context +- Calling module initializer +- Evaluate Javascript + +#### Creating the context + +~~~~ + +JSGlobalContextRef context = JSGlobalContextCreate(NULL); +JSObjectRef globalObject = JSContextGetGlobalObject(context); +... + +~~~~ + +### Calling module initializer + +~~~~ + + extern int example_init(JSGlobalContextRef context); + ... + example_init(context); + ... + +~~~~ + +### Evaluate Javascript + +~~~~ + +// Evaluate the javascript +char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); +JSStringRef jsScript; +if(!scriptContent) { + printf("FAIL: runme script could not be loaded.\n"); + failed = 1; + } + else { + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(scriptContent); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + if (!jsResult && ex) { + jsc_printError(context, ex, scriptPath); + failed = 1; + } + } + if (scriptContent != NULL) { + free(scriptContent); + } + JSStringRelease(jsScript); + JSGlobalContextRelease(context); + globalObject = 0; + for(std::vector::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + dlclose(handle); + } + if (failed) { + printf("FAIL: Some tests failed.\n"); + return 1; + } +} + +~~~~ + +## Typemaps + +A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from javascript to C, you might define a typemap like this: + +~~~~ + +%typemap(in) int { + $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} + printf("Received an integer : %d\n",$1); +} + +~~~~ + +Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int. + +## Javascript typemaps + +The previous section illustrated an "in" typemap for converting javascript objects to C. A variety of different typemap methods are defined by the javascript module. For example, to convert a C integer back into a javascript object, you might define an "out" typemap like this: + +~~~~ + +%typemap(out) int { + $result = JSValueMakeNumber(context, $1); +} + +~~~~ + +The Javascript module makes use of Swig's unified template library. + +## Typemap variables + +Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables: + +`$1`: +A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Javascript. + +`$input`: +A javascript Object * holding a raw javascript object with an argument or variable value. + +`$result`: +A javascript Object * that holds the result to be returned to javascript. + +`$1_name`: +The parameter name that was matched. + +`$1_type`: +The actual C datatype matched by the typemap. + +`$1_ltype`: +An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of `$1_type`. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned. + +`$symname`: +The javascript name of the wrapper function being created. + +# Javascript: Specification of a Code Generator for JSC + +The module implementation tries to accomplish a separation of logic and code generation by making +use of code templates. In the following, the templates are explained. + +# Top Level structure + +The generated code consists of the following blocks: + +~~~~ + + + + + + + +~~~~ + +- `RUNTIME`: runtime code generated by swig +- `HELPER_FUNCTIONS`: static, from swg-file +- `INCLUDES`: static, module property +- `FUNCTION_WRAPPERS`: dynamically growing, on method declarations +- `INITIALIZER`: dynamically growing, aggregates everything + +## INCLUDES + +~~~~ + +#include + + +~~~~ + +`USER_DEFINED_INCLUDES`: a module property + +## `HELPER_FUNCTIONS` + +A lot of boiler-plate code can be shifted into static helper functions: + +~~~~ + +bool JS_registerClass(JSGlobalContextRef& context, JSObjectRef& parentObject,const char* className, + JSClassDefinition* definition) { + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject,js_className, classObject,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef& context,JSObjectRef& namespaceObj,JSObjectRef& parentNamespace,const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace,js_name, namespaceObj,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + return true; +} + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context,object,js_functionName,JSObjectMakeFunctionWithCallback(context, + js_functionName, callback), kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return val; +} + +~~~~ + +## `FUNCTION_WRAPPERS` + +There are different types of function wrappers: +- Member Functions +- Getproperty / Setproperty +- Global Functions (global/namespace/class) +- Constructors / Destructors + + +## Member Functions + +~~~~ + +JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} + +~~~~ + +- `functionname`: the name of generated wrapper for function +- `LOCALS`: declarations for input arguments +- `CODE`: contains input marshalling, the action, and output marshalling + +## Setproperty + +~~~~ + +bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} + +~~~~ + +- `setname`: the name of the generated wrapper for setproperty. +- `LOCALS`: declarations for input arguments +- `CODE`: contains input marshalling, and the action + +## Getproperty + +~~~~ + +JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} + +~~~~ + +- `getname`: the name of the generated wrapper for the getproperty +- `LOCALS`: declarations for output arguments +- `CODE`: contains the action, and output marshalling + + +## Global Functions + +~~~~ + +JSStaticValue ${namespace}_values[] = { + ${jsglobalvariables} + { 0, 0, 0, 0 } +}; +JSStaticFunction ${namespace}_functions[] = { + ${jsglobalfunctions} + { 0, 0, 0 } +}; +JSClassDefinition ${namespace}_classDefinition; + +~~~~ + +## Variable declaration + +~~~~ + +{"${propertyname}",${getname}, ${setname}, kJSPropertyAttributeNone} + +~~~~ + +This is used to fill variable definition tables. +`kJSPropertyAttributeNone` is JSC specific and means that the variable has a getter and setter. +Even for read-only variables a setter is used which throws an exception. + +## Constructor + +~~~~ + +JSObjectRef _wrap_create_${classname_mangled}${overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN); + + goto fail; + fail: + return NULL; +} + +~~~~ +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` +- `LOCALS`: declarations for input arguments +- `CODE`: contains input marshalling, and the action + +## Destructors + +~~~~ + +void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) +{ + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) delete (${type}*)(t->swigCObject); + if(t) delete t; +} + +~~~~ + +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + +## Initializer + +~~~~ + +bool ${modulename}_initialize(JSGlobalContextRef context) { + SWIG_InitializeModule(0); + + JSObjectRef global_object = JSContextGetGlobalObject(context); + + /* Initialize the base swig type object */ + _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; + _SwigObject_objectDefinition.staticValues = _SwigObject_values; + _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + + /* Create objects for namespaces */ + ${create_namespaces} + + /* Create classes */ + ${initializercode} + + /* Register namespaces */ + ${register_namespaces} + + return true; +} + +~~~~ + +## Class template defintions + +A class is specified by a static part (`*_classDefinition`) and a dynamic part (`*_objectDefinition`). + +~~~~ + +${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; + ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; + ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; + ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; + ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; + ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; + JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}_objectDefinition); + SWIGTYPE_${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%} + +~~~~ + +Notes: +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + which is retrieved by `Swig_name_mangle(Getattr(n, "name"))` +- ClassDefinitions are built using the staticValues array and the staticFunction array. The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties to the class object. + +## Inheritance + +~~~~ + +{${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef}; + +~~~~ + +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` +- Note: multiple inheritance is not possible; thus we will always take the first parent class + +## Namespaces + +Namespaces are objects without class templates. i.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. + +~~~~ + + ${namespace}_classDefinition.staticFunctions = ${namespace}_functions; + ${namespace}_classDefinition.staticValues = ${namespace}_values; + JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL); + +~~~~ + +## Registration + +The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. + +* Global functions + +~~~~ + +JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper} + +~~~~ + +* Classes + +~~~~ + +JS_registerClass(context, ${namespace}_object, "${classname}", &${classname_mangled}_classDefinition) + +~~~~ + +Note: every class template has an associated constructor function wrapper, which is registered here + +* Namespaces + +~~~~ + +${namespace}_classDefinition.staticFunctions = ${namespace}_functions; +${namespace}_classDefinition.staticValues = ${namespace}_values; +JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL); + +~~~~ + +Namespaces are registered using: + +~~~~ + +JS_registerNamespace(context, ${namespace}_object, ${parent_namespace}_object, "${namespace}"); + +~~~~ + diff --git a/Doc/Manual/pandoc_template.html b/Doc/Manual/pandoc_template.html new file mode 100644 index 000000000..390bfc51c --- /dev/null +++ b/Doc/Manual/pandoc_template.html @@ -0,0 +1,56 @@ + + + + + + +$for(author-meta)$ + +$endfor$ +$if(date-meta)$ + +$endif$ + $if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$ +$if(highlighting-css)$ + +$endif$ +$for(css)$ + +$endfor$ +$if(math)$ + $math$ +$endif$ +$for(header-includes)$ + $header-includes$ +$endfor$ + + +$for(include-before)$ +$include-before$ +$endfor$ +$if(title)$ +
+

$title$

+$for(author)$ +

$author$

+$endfor$ +$if(date)$ +

$date$

+$endif$ +
+$endif$ +$if(toc)$ +
+$toc$ +
+$endif$ +
+$body$ +
+$for(include-after)$ +$include-after$ +$endfor$ + + From 48af60d82904f1eef37b9beac03f8412947e883e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 27 Sep 2013 02:46:11 +0200 Subject: [PATCH 230/352] Javascript examples. --- Examples/javascript/check.list | 13 +++ Examples/javascript/class/Makefile | 21 +++++ Examples/javascript/class/binding.gyp | 8 ++ Examples/javascript/class/example.cxx | 28 +++++++ Examples/javascript/class/example.h | 34 ++++++++ Examples/javascript/class/example.i | 10 +++ Examples/javascript/class/runme.js | 46 +++++++++++ Examples/javascript/constant/Makefile | 21 +++++ Examples/javascript/constant/binding.gyp | 8 ++ Examples/javascript/constant/example.h | 8 ++ Examples/javascript/constant/example.i | 24 ++++++ Examples/javascript/constant/runme.js | 14 ++++ Examples/javascript/enum/Makefile | 21 +++++ Examples/javascript/enum/binding.gyp | 8 ++ Examples/javascript/enum/example.cxx | 37 +++++++++ Examples/javascript/enum/example.h | 13 +++ Examples/javascript/enum/example.i | 11 +++ Examples/javascript/enum/runme.js | 34 ++++++++ Examples/javascript/exception/Makefile | 21 +++++ Examples/javascript/exception/binding.gyp | 8 ++ Examples/javascript/exception/example.cxx | 1 + Examples/javascript/exception/example.h | 53 ++++++++++++ Examples/javascript/exception/example.i | 12 +++ Examples/javascript/exception/runme.js | 64 +++++++++++++++ Examples/javascript/functor/Makefile | 21 +++++ Examples/javascript/functor/binding.gyp | 8 ++ Examples/javascript/functor/example.cxx | 0 Examples/javascript/functor/example.i | 25 ++++++ Examples/javascript/functor/runme.js | 15 ++++ Examples/javascript/namespace/Makefile | 21 +++++ Examples/javascript/namespace/binding.gyp | 8 ++ Examples/javascript/namespace/example.cxx | 36 ++++++++ Examples/javascript/namespace/example.h | 20 +++++ Examples/javascript/namespace/example.i | 10 +++ Examples/javascript/namespace/runme.js | 10 +++ Examples/javascript/operator/Makefile | 21 +++++ Examples/javascript/operator/binding.gyp | 8 ++ Examples/javascript/operator/example.h | 36 ++++++++ Examples/javascript/operator/example.i | 34 ++++++++ Examples/javascript/operator/runme.js | 25 ++++++ Examples/javascript/overload/Makefile | 21 +++++ Examples/javascript/overload/binding.gyp | 8 ++ Examples/javascript/overload/example.h | 28 +++++++ Examples/javascript/overload/example.i | 16 ++++ Examples/javascript/overload/runme.js | 9 ++ Examples/javascript/overload/swig_gdb.log | 0 Examples/javascript/pointer/Makefile | 21 +++++ Examples/javascript/pointer/binding.gyp | 8 ++ Examples/javascript/pointer/example.cxx | 16 ++++ Examples/javascript/pointer/example.i | 30 +++++++ Examples/javascript/pointer/runme.js | 35 ++++++++ Examples/javascript/pointer/typemaps.i | 0 Examples/javascript/reference/Makefile | 21 +++++ Examples/javascript/reference/binding.gyp | 8 ++ Examples/javascript/reference/example.cxx | 46 +++++++++++ Examples/javascript/reference/example.h | 26 ++++++ Examples/javascript/reference/example.i | 42 ++++++++++ Examples/javascript/reference/runme.js | 67 +++++++++++++++ Examples/javascript/reference/swig_gdb.log | 22 +++++ Examples/javascript/simple/Makefile | 21 +++++ Examples/javascript/simple/binding.gyp | 8 ++ Examples/javascript/simple/example.cxx | 18 ++++ Examples/javascript/simple/example.i | 7 ++ Examples/javascript/simple/runme.js | 26 ++++++ Examples/javascript/template/Makefile | 21 +++++ Examples/javascript/template/binding.gyp | 8 ++ Examples/javascript/template/example.h | 32 ++++++++ Examples/javascript/template/example.i | 17 ++++ Examples/javascript/template/runme.js | 30 +++++++ Examples/javascript/variables/Makefile | 21 +++++ Examples/javascript/variables/binding.gyp | 8 ++ Examples/javascript/variables/example.cxx | 96 ++++++++++++++++++++++ Examples/javascript/variables/example.h | 6 ++ Examples/javascript/variables/example.i | 49 +++++++++++ Examples/javascript/variables/runme.js | 68 +++++++++++++++ Examples/javascript/variables/swig_gdb.log | 9 ++ 76 files changed, 1685 insertions(+) create mode 100644 Examples/javascript/check.list create mode 100755 Examples/javascript/class/Makefile create mode 100644 Examples/javascript/class/binding.gyp create mode 100755 Examples/javascript/class/example.cxx create mode 100755 Examples/javascript/class/example.h create mode 100755 Examples/javascript/class/example.i create mode 100755 Examples/javascript/class/runme.js create mode 100755 Examples/javascript/constant/Makefile create mode 100644 Examples/javascript/constant/binding.gyp create mode 100644 Examples/javascript/constant/example.h create mode 100755 Examples/javascript/constant/example.i create mode 100755 Examples/javascript/constant/runme.js create mode 100755 Examples/javascript/enum/Makefile create mode 100644 Examples/javascript/enum/binding.gyp create mode 100755 Examples/javascript/enum/example.cxx create mode 100755 Examples/javascript/enum/example.h create mode 100755 Examples/javascript/enum/example.i create mode 100755 Examples/javascript/enum/runme.js create mode 100755 Examples/javascript/exception/Makefile create mode 100644 Examples/javascript/exception/binding.gyp create mode 100644 Examples/javascript/exception/example.cxx create mode 100644 Examples/javascript/exception/example.h create mode 100644 Examples/javascript/exception/example.i create mode 100644 Examples/javascript/exception/runme.js create mode 100755 Examples/javascript/functor/Makefile create mode 100644 Examples/javascript/functor/binding.gyp create mode 100644 Examples/javascript/functor/example.cxx create mode 100644 Examples/javascript/functor/example.i create mode 100644 Examples/javascript/functor/runme.js create mode 100755 Examples/javascript/namespace/Makefile create mode 100644 Examples/javascript/namespace/binding.gyp create mode 100644 Examples/javascript/namespace/example.cxx create mode 100644 Examples/javascript/namespace/example.h create mode 100644 Examples/javascript/namespace/example.i create mode 100644 Examples/javascript/namespace/runme.js create mode 100755 Examples/javascript/operator/Makefile create mode 100644 Examples/javascript/operator/binding.gyp create mode 100644 Examples/javascript/operator/example.h create mode 100644 Examples/javascript/operator/example.i create mode 100644 Examples/javascript/operator/runme.js create mode 100755 Examples/javascript/overload/Makefile create mode 100644 Examples/javascript/overload/binding.gyp create mode 100644 Examples/javascript/overload/example.h create mode 100644 Examples/javascript/overload/example.i create mode 100644 Examples/javascript/overload/runme.js create mode 100644 Examples/javascript/overload/swig_gdb.log create mode 100755 Examples/javascript/pointer/Makefile create mode 100644 Examples/javascript/pointer/binding.gyp create mode 100755 Examples/javascript/pointer/example.cxx create mode 100755 Examples/javascript/pointer/example.i create mode 100755 Examples/javascript/pointer/runme.js create mode 100644 Examples/javascript/pointer/typemaps.i create mode 100755 Examples/javascript/reference/Makefile create mode 100644 Examples/javascript/reference/binding.gyp create mode 100755 Examples/javascript/reference/example.cxx create mode 100755 Examples/javascript/reference/example.h create mode 100755 Examples/javascript/reference/example.i create mode 100755 Examples/javascript/reference/runme.js create mode 100644 Examples/javascript/reference/swig_gdb.log create mode 100755 Examples/javascript/simple/Makefile create mode 100644 Examples/javascript/simple/binding.gyp create mode 100644 Examples/javascript/simple/example.cxx create mode 100644 Examples/javascript/simple/example.i create mode 100755 Examples/javascript/simple/runme.js create mode 100755 Examples/javascript/template/Makefile create mode 100644 Examples/javascript/template/binding.gyp create mode 100644 Examples/javascript/template/example.h create mode 100644 Examples/javascript/template/example.i create mode 100644 Examples/javascript/template/runme.js create mode 100755 Examples/javascript/variables/Makefile create mode 100644 Examples/javascript/variables/binding.gyp create mode 100755 Examples/javascript/variables/example.cxx create mode 100755 Examples/javascript/variables/example.h create mode 100755 Examples/javascript/variables/example.i create mode 100755 Examples/javascript/variables/runme.js create mode 100644 Examples/javascript/variables/swig_gdb.log diff --git a/Examples/javascript/check.list b/Examples/javascript/check.list new file mode 100644 index 000000000..146f1800f --- /dev/null +++ b/Examples/javascript/check.list @@ -0,0 +1,13 @@ +class +constant +enum +exception +functor +namespace +operator +overload +pointer +reference +simple +template +variables diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/class/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/class/binding.gyp b/Examples/javascript/class/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/class/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/class/example.cxx b/Examples/javascript/class/example.cxx new file mode 100755 index 000000000..e23fa6f73 --- /dev/null +++ b/Examples/javascript/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ +#include +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/javascript/class/example.h b/Examples/javascript/class/example.h new file mode 100755 index 000000000..64b7684fa --- /dev/null +++ b/Examples/javascript/class/example.h @@ -0,0 +1,34 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; diff --git a/Examples/javascript/class/example.i b/Examples/javascript/class/example.i new file mode 100755 index 000000000..75700b305 --- /dev/null +++ b/Examples/javascript/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js new file mode 100755 index 000000000..5bb62ecd4 --- /dev/null +++ b/Examples/javascript/class/runme.js @@ -0,0 +1,46 @@ +var example = require("./build/Release/example"); + +// ----- Object creation ----- + +console.log("Creating some objects:"); +c = new example.Circle(10); +console.log("Created circle " + c); +s = new example.Square(10); +console.log("Created square " + s); + +// ----- Access a static member ----- +console.log("\nA total of " + example.Shape.nshapes + " shapes were created"); // access static member as properties of the class object + +// ----- Member data access ----- +// Set the location of the object. +// Note: methods in the base class Shape are used since +// x and y are defined there. + +c.x = 20; +c.y = 30; +s.x = -10; +s.y = 5; + +console.log("\nHere is their new position:"); +console.log("Circle = (" + c.x + "," + c.y + ")"); +console.log("Square = (" + s.x + "," + s.y + ")"); + +// ----- Call some methods ----- +console.log("\nHere are some properties of the shapes:"); +console.log("Circle:"); +console.log("area = " + c.area() + ""); +console.log("perimeter = " + c.perimeter() + ""); +console.log("\n"); +console.log("Square:"); +console.log("area = " + s.area() + ""); +console.log("perimeter = " + s.perimeter() + ""); + +// ----- Delete everything ----- +console.log("\nGuess I'll clean up now"); +// Note: this invokes the virtual destructor +delete c; +delete s; + +console.log(example.Shape.nshapes + " shapes remain"); + +console.log("Goodbye"); diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/constant/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/constant/binding.gyp b/Examples/javascript/constant/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/constant/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/constant/example.h b/Examples/javascript/constant/example.h new file mode 100644 index 000000000..2c88ebd1e --- /dev/null +++ b/Examples/javascript/constant/example.h @@ -0,0 +1,8 @@ +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" +#define EXTERN extern +#define FOO (ICONST + BAR) diff --git a/Examples/javascript/constant/example.i b/Examples/javascript/constant/example.i new file mode 100755 index 000000000..a6d28e7c9 --- /dev/null +++ b/Examples/javascript/constant/example.i @@ -0,0 +1,24 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/javascript/constant/runme.js b/Examples/javascript/constant/runme.js new file mode 100755 index 000000000..b11c08c98 --- /dev/null +++ b/Examples/javascript/constant/runme.js @@ -0,0 +1,14 @@ +var example = require("./build/Release/example"); + +console.log("ICONST = " + example.ICONST + " (should be 42)\n"); +console.log("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +console.log("CCONST = " + example.CCONST + " (should be 'x')\n"); +console.log("CCONST2 = " + example.CCONST2 + " (this should be on a new line)\n"); +console.log("SCONST = " + example.SCONST + " (should be 'Hello World')\n"); +console.log("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')\n"); +console.log("EXPR = " + example.EXPR + " (should be 48.5484)\n"); +console.log("iconst = " + example.iconst + " (should be 37)\n"); +console.log("fconst = " + example.fconst + " (should be 3.14)\n"); + +console.log("EXTERN = " + example.EXTERN + " (should be undefined)\n"); +console.log("FOO = " + example.FOO + " (should be undefined)\n"); diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/enum/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/enum/binding.gyp b/Examples/javascript/enum/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/enum/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/enum/example.cxx b/Examples/javascript/enum/example.cxx new file mode 100755 index 000000000..6785e57ac --- /dev/null +++ b/Examples/javascript/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.c */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/javascript/enum/example.h b/Examples/javascript/enum/example.h new file mode 100755 index 000000000..9119cd9fc --- /dev/null +++ b/Examples/javascript/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/javascript/enum/example.i b/Examples/javascript/enum/example.i new file mode 100755 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/javascript/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js new file mode 100755 index 000000000..9d3accd1d --- /dev/null +++ b/Examples/javascript/enum/runme.js @@ -0,0 +1,34 @@ +var example = require("./build/Release/example"); + +// ----- Object creation ----- + +// Print out the value of some enums +console.log("*** color ***"); +console.log(" RED =" + example.RED); +console.log(" BLUE =" + example.BLUE); +console.log(" GREEN =" + example.GREEN); + +console.log("\n*** Foo::speed ***"); +console.log(" Foo_IMPULSE =" + example.Foo.IMPULSE); +console.log(" Foo_WARP =" + example.Foo.WARP); +console.log(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); + +console.log("\nTesting use of enums with functions\n"); + +example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); +example.enum_test(1234,5678); + +console.log("\nTesting use of enum with class method"); +f = new example.Foo(); + +f.enum_test(example.Foo.IMPULSE); +f.enum_test(example.Foo.WARP); +f.enum_test(example.Foo.LUDICROUS); + +// enum value BLUE of enum color is accessed as property of cconst +console.log("example.BLUE= " + example.BLUE); + +// enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst +console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS); diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/exception/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/exception/binding.gyp b/Examples/javascript/exception/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/exception/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/exception/example.cxx b/Examples/javascript/exception/example.cxx new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Examples/javascript/exception/example.cxx @@ -0,0 +1 @@ + diff --git a/Examples/javascript/exception/example.h b/Examples/javascript/exception/example.h new file mode 100644 index 000000000..7cf917d01 --- /dev/null +++ b/Examples/javascript/exception/example.h @@ -0,0 +1,53 @@ +/* File : example.h */ + +#include +#ifndef SWIG +struct A { +}; +#endif + +class Exc { +public: + Exc(int c, const char *m) { + code = c; + strncpy(msg,m,256); + } + int code; + char msg[256]; +}; + +#if defined(_MSC_VER) + #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +class Test { +public: + int simple() throw(int) { + throw(37); + return 1; + } + int message() throw(const char *) { + throw("I died."); + return 1; + } + int hosed() throw(Exc) { + throw(Exc(42,"Hosed")); + return 1; + } + int unknown() throw(A*) { + static A a; + throw &a; + return 1; + } + int multi(int x) throw(int, const char *, Exc) { + if (x == 1) throw(37); + if (x == 2) throw("Bleah!"); + if (x == 3) throw(Exc(42,"No-go-diggy-die")); + return 1; + } +}; + +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + diff --git a/Examples/javascript/exception/example.i b/Examples/javascript/exception/example.i new file mode 100644 index 000000000..08672c3a8 --- /dev/null +++ b/Examples/javascript/exception/example.i @@ -0,0 +1,12 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js new file mode 100644 index 000000000..f7041f028 --- /dev/null +++ b/Examples/javascript/exception/runme.js @@ -0,0 +1,64 @@ +var example = require("./build/Release/example"); + +console.log("Trying to catch some exceptions."); +t = new example.Test(); +try{ + t.unknown(); + throw -1; +} catch(error) +{ + if(error == -1) { + console.log("t.unknown() didn't throw"); + } else { + console.log("successfully catched throw in Test::unknown()."); + } +} + +try{ + t.simple(); + throw -1; +} +catch(error){ + if(error == -1) { + console.log("t.simple() did not throw"); + } else { + console.log("successfully catched throw in Test::simple()."); + } +} + +try{ + t.message(); + throw -1; +} catch(error){ + if(error == -1) { + console.log("t.message() did not throw"); + } else { + console.log("successfully catched throw in Test::message()."); + } +} + +try{ + t.hosed(); + throw -1; +} +catch(error){ + if(error == -1) { + console.log("t.hosed() did not throw"); + } else { + console.log("successfully catched throw in Test::hosed()."); + } +} + +for (var i=1; i<4; i++) { + try{ + t.multi(i); + throw -1; + } + catch(error){ + if(error == -1) { + console.log("t.multi(" + i + ") did not throw"); + } else { + console.log("successfully catched throw in Test::multi()."); + } + } +} diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/functor/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/functor/binding.gyp b/Examples/javascript/functor/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/functor/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/functor/example.cxx b/Examples/javascript/functor/example.cxx new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/functor/example.i b/Examples/javascript/functor/example.i new file mode 100644 index 000000000..0450c2124 --- /dev/null +++ b/Examples/javascript/functor/example.i @@ -0,0 +1,25 @@ +/* File : example.i */ +%module example + + +%inline %{ +// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 +template class Sum { + T res; +public: + Sum(T i = 0) : res(i) { } + void operator() (T x) { res += x; } + T result() const { return res; } +}; + +%} + +%rename(call) *::operator(); // the fn call operator + +// Instantiate a few versions +%template(intSum) Sum; +%template(doubleSum) Sum; + + + + diff --git a/Examples/javascript/functor/runme.js b/Examples/javascript/functor/runme.js new file mode 100644 index 000000000..f7be78286 --- /dev/null +++ b/Examples/javascript/functor/runme.js @@ -0,0 +1,15 @@ +var example = require("./build/Release/example"); + +a = new example.intSum(0); +b = new example.doubleSum(100.0); + +// Use the objects. They should be callable just like a normal +// javascript function. + +for (i=1;i<=100;i++) + a.call(i); // Note: function call + b.call(Math.sqrt(i)); // Note: function call + +console.log(a.result()); +console.log(b.result()); + diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/namespace/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/namespace/binding.gyp b/Examples/javascript/namespace/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/namespace/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/namespace/example.cxx b/Examples/javascript/namespace/example.cxx new file mode 100644 index 000000000..5beeb09fe --- /dev/null +++ b/Examples/javascript/namespace/example.cxx @@ -0,0 +1,36 @@ +/* File : example.c */ + +#include +#include "example.h" + +#define M_PI 3.14159 + + +/* A global variable */ +namespace nspace +{ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +Circle::Circle(): radius(1.0) {} + +Circle::Circle(double r): radius(r) { + std::cout << "created Circle with r=" << radius << std::endl; +} + +double Circle::area() { + std::cout << "Circle::area called, r=" << radius << std::endl; + return M_PI*radius*radius; +} +} diff --git a/Examples/javascript/namespace/example.h b/Examples/javascript/namespace/example.h new file mode 100644 index 000000000..7f76c2f07 --- /dev/null +++ b/Examples/javascript/namespace/example.h @@ -0,0 +1,20 @@ + +namespace nspace { + +extern int gcd(int x, int y); +extern double Foo; + +class Circle +{ +public: + Circle(); + + Circle(double r); + + double area(); + + double radius; + +}; + +} diff --git a/Examples/javascript/namespace/example.i b/Examples/javascript/namespace/example.i new file mode 100644 index 000000000..e14b10b44 --- /dev/null +++ b/Examples/javascript/namespace/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%feature("nspace", 1); + +%include "example.h" diff --git a/Examples/javascript/namespace/runme.js b/Examples/javascript/namespace/runme.js new file mode 100644 index 000000000..9a9d6744d --- /dev/null +++ b/Examples/javascript/namespace/runme.js @@ -0,0 +1,10 @@ +var example = require("./build/Release/example"); + +console.log("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +console.log("Variable Foo changed to " + example.nspace.Foo); +console.log("GCD of number 6,18 is " + example.nspace.gcd(6,18)); + +console.log("Creating some objects:"); +c = new example.nspace.Circle(10); +console.log("area = " + c.area()); diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/operator/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/operator/binding.gyp b/Examples/javascript/operator/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/operator/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/operator/example.h b/Examples/javascript/operator/example.h new file mode 100644 index 000000000..4da6a2307 --- /dev/null +++ b/Examples/javascript/operator/example.h @@ -0,0 +1,36 @@ +/* File : example.h */ +#include + +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + + + + + diff --git a/Examples/javascript/operator/example.i b/Examples/javascript/operator/example.i new file mode 100644 index 000000000..7a1bd45e1 --- /dev/null +++ b/Examples/javascript/operator/example.i @@ -0,0 +1,34 @@ +/* File : example.i */ +%module example +#pragma SWIG nowarn=SWIGWARN_IGNORE_OPERATOR_EQ +%{ +#include "example.h" +%} + +/* This header file is a little tough to handle because it has overloaded + operators and constructors. We're going to try and deal with that here */ + +/* This turns the copy constructor in a function ComplexCopy() that can + be called */ + +%rename(assign) Complex::operator=; +%rename(plus) Complex::operator+; +%rename(minus) Complex::operator-(const Complex &) const; +%rename(uminus) Complex::operator-() const; +%rename(times) Complex::operator*; + +/* Now grab the original header file */ +%include "example.h" + +/* An output method that turns a complex into a short string */ +%extend Complex { + char *toString() { + static char temp[512]; + sprintf(temp,"(%g,%g)", $self->re(), $self->im()); + return temp; + } + static Complex* copy(const Complex& c) { + return new Complex(c); + } +}; + diff --git a/Examples/javascript/operator/runme.js b/Examples/javascript/operator/runme.js new file mode 100644 index 000000000..9dba4b7f9 --- /dev/null +++ b/Examples/javascript/operator/runme.js @@ -0,0 +1,25 @@ +var example = require("./build/Release/example"); + +a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +console.log ("a =" + a); +console.log ("b =" + b); + +c = a.plus(b); + +console.log("c =" + c); +console.log("a*b =" + a.times(b)); +console.log("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +console.log("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +console.log("f =" + f); + + + + + diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/overload/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/overload/binding.gyp b/Examples/javascript/overload/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/overload/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/overload/example.h b/Examples/javascript/overload/example.h new file mode 100644 index 000000000..2f112f1e1 --- /dev/null +++ b/Examples/javascript/overload/example.h @@ -0,0 +1,28 @@ +#include + +void f() { + std::cout << "Called f()." << std::endl; +} + +void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} + +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} + +void f(bool val) { + std::cout << "Called f(bool)." << std::endl; +} + +void f(long val) { + std::cout << "Called f(long)." << std::endl; +} + +void f(double val) { + std::cout << "Called f(double)." << std::endl; +} diff --git a/Examples/javascript/overload/example.i b/Examples/javascript/overload/example.i new file mode 100644 index 000000000..b86689f8a --- /dev/null +++ b/Examples/javascript/overload/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* + Note: overloading is implemented in a sloppy way currently + i.e., only the number of arguments is taken into conideration + for dispatching. + To solve the problem one has to rename such conflicting methods. +*/ +%rename(f_double) f(double val); + +%include "example.h" diff --git a/Examples/javascript/overload/runme.js b/Examples/javascript/overload/runme.js new file mode 100644 index 000000000..5ff5d01be --- /dev/null +++ b/Examples/javascript/overload/runme.js @@ -0,0 +1,9 @@ +var example = require("./build/Release/example"); + +example.f(); +example.f(1); +example.f(1, 2); +example.f("bla"); +example.f(false); +example.f(11111111111); +example.f_double(1.0); diff --git a/Examples/javascript/overload/swig_gdb.log b/Examples/javascript/overload/swig_gdb.log new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/pointer/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/pointer/binding.gyp b/Examples/javascript/pointer/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/pointer/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/pointer/example.cxx b/Examples/javascript/pointer/example.cxx new file mode 100755 index 000000000..8762329fe --- /dev/null +++ b/Examples/javascript/pointer/example.cxx @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void subtract(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/javascript/pointer/example.i b/Examples/javascript/pointer/example.i new file mode 100755 index 000000000..38c67d7d2 --- /dev/null +++ b/Examples/javascript/pointer/example.i @@ -0,0 +1,30 @@ +/* File : example.i */ +%module example + +%{ +extern void add(int *, int *, int *); +extern void subtract(int *, int *, int *); +extern int divide(int, int, int *); +%} + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void subtract(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +extern int divide(int n, int d, int *r); + + + + diff --git a/Examples/javascript/pointer/runme.js b/Examples/javascript/pointer/runme.js new file mode 100755 index 000000000..00778dfbc --- /dev/null +++ b/Examples/javascript/pointer/runme.js @@ -0,0 +1,35 @@ +var example = require("./build/Release/example"); + +// First create some objects using the pointer library. +console.log("Testing the pointer library\n"); +a = example.new_intp(); +b = example.new_intp(); +c = example.new_intp(); + +example.intp_assign(a,37); +example.intp_assign(b,42); + +console.log(" a = " + example.intp_value(a) + "\n"); +console.log(" b = " + example.intp_value(b) + "\n"); +console.log(" c = " + example.intp_value(c) + "\n"); + +//// Call the add() function with some pointers +example.add(a, b, c); + +// +//// Now get the result +r = example.intp_value(c); +console.log(" 37 + 42 = " + r + "\n"); + +// Clean up the pointers +example.delete_intp(a); +example.delete_intp(b); +example.delete_intp(c); + +//// Now try the typemap library +//// This should be much easier. Now how it is no longer +//// necessary to manufacture pointers. +//"OUTPUT" Mapping is not supported +//console.log("Trying the typemap library"); +//r = example.subtract(37,42); +//console.log("37 - 42 =" + r); diff --git a/Examples/javascript/pointer/typemaps.i b/Examples/javascript/pointer/typemaps.i new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/reference/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/reference/binding.gyp b/Examples/javascript/reference/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/reference/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/reference/example.cxx b/Examples/javascript/reference/example.cxx new file mode 100755 index 000000000..8a513bf49 --- /dev/null +++ b/Examples/javascript/reference/example.cxx @@ -0,0 +1,46 @@ +/* File : example.cxx */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include "example.h" +#include +#include + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/Examples/javascript/reference/example.h b/Examples/javascript/reference/example.h new file mode 100755 index 000000000..4915adb1b --- /dev/null +++ b/Examples/javascript/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/Examples/javascript/reference/example.i b/Examples/javascript/reference/example.i new file mode 100755 index 000000000..1cf19c82c --- /dev/null +++ b/Examples/javascript/reference/example.i @@ -0,0 +1,42 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { + return (*$self)[index]; + } + void set(int index, Vector &a) { + (*$self)[index] = a; + } + } +}; diff --git a/Examples/javascript/reference/runme.js b/Examples/javascript/reference/runme.js new file mode 100755 index 000000000..ee5737076 --- /dev/null +++ b/Examples/javascript/reference/runme.js @@ -0,0 +1,67 @@ +// This file illustrates the manipulation of C++ references in Javascript. +var example = require("./build/Release/example"); + +// ----- Object creation ----- + +console.log("Creating some objects:\n"); +a = new example.Vector(3,4,5); +b = new example.Vector(10,11,12); + +console.log(" created" + a.print()); +console.log(" created" + b.print()); + +// ----- Call an overloaded operator ----- + +// This calls the wrapper we placed around operator+(const Vector &a, const Vector &) +// It returns a new allocated object. + +console.log("Adding a+b\n"); +c = example.addv(a, b); +console.log("a+b = " + c.print()); + + +// TODO: Note: Unless we free the result, a memory leak will occur +//delete_Vector(c); + +// ----- Create a vector array ----- + +// Note: Using the high-level interface here +console.log("Creating an array of vectors\n"); +va = new example.VectorArray(10); +console.log("va = " + va + "\n"); + +// ----- Set some values in the array ----- + +// These operators copy the value of a and b to the vector array +va.set(0,a); +va.set(1,b); + +// This will work, but it will cause a memory leak! +va.set(2,example.addv(a,b)); + +// The non-leaky way to do it +//c = addv(a,b); +//va.set(3,c); +//delete_Vector(c); + +// Get some values from the array + +console.log("Getting some array values\n"); +for (i = 0; i < 5; i++) { + temp = va.get(i); + console.log(i,temp.print()); +} + +// Watch under resource meter to check on this +console.log("Making sure we don't leak memory.\n"); +for (i = 0; i < 1000000; i++) { + c = va.get(i % 10); +} +//---------TODO--------- +//----- Clean up ----- +//console.log("Cleaning up\n"); + +//example.delete_VectorArray(va); +//example.delete_Vector(a); +//example.delete_Vector(b); + diff --git a/Examples/javascript/reference/swig_gdb.log b/Examples/javascript/reference/swig_gdb.log new file mode 100644 index 000000000..57bca0306 --- /dev/null +++ b/Examples/javascript/reference/swig_gdb.log @@ -0,0 +1,22 @@ +Loaded swig printers +SwigStringPrinter: Could not convert const char* to string +SwigListIterator: Construction failed. + Cannot access memory at address 0x7d894828ec834853. +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigListIterator: Construction failed. + Cannot access memory at address 0x7d894828ec834853. +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not dereference struct String* diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/simple/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/simple/binding.gyp b/Examples/javascript/simple/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/simple/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/simple/example.cxx b/Examples/javascript/simple/example.cxx new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/javascript/simple/example.cxx @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/javascript/simple/example.i b/Examples/javascript/simple/example.i new file mode 100644 index 000000000..24093b9bf --- /dev/null +++ b/Examples/javascript/simple/example.i @@ -0,0 +1,7 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +%} diff --git a/Examples/javascript/simple/runme.js b/Examples/javascript/simple/runme.js new file mode 100755 index 000000000..d970dcb7c --- /dev/null +++ b/Examples/javascript/simple/runme.js @@ -0,0 +1,26 @@ +var example = require("./build/Release/example"); + +/* Call our gcd() function */ + +x = 42; +y = 105; +g = example.gcd(x,y); +console.log("GCD of x and y is=" + g); + +/* Manipulate the Foo global variable */ + +/* Output its current value */ +console.log("Global variable Foo=" + example.Foo); + +/* Change its value */ +example.Foo = 3.1415926; + +/* See if the change took effect */ +console.log("Variable Foo changed to=" + example.Foo); + + + + + + + diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/template/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/template/binding.gyp b/Examples/javascript/template/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/template/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/template/example.h b/Examples/javascript/template/example.h new file mode 100644 index 000000000..7401df650 --- /dev/null +++ b/Examples/javascript/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return $self->get(index); + } + void setitem(int index, T val) { + $self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/javascript/template/example.i b/Examples/javascript/template/example.i new file mode 100644 index 000000000..8f94c4da1 --- /dev/null +++ b/Examples/javascript/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + diff --git a/Examples/javascript/template/runme.js b/Examples/javascript/template/runme.js new file mode 100644 index 000000000..551475c72 --- /dev/null +++ b/Examples/javascript/template/runme.js @@ -0,0 +1,30 @@ +var example = require("./build/Release/example"); + +//Call some templated functions +console.log(example.maxint(3,7)); +console.log(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +console.log(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +console.log(sum); + +delete iv; +delete dv; diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile new file mode 100755 index 000000000..99a9e9e86 --- /dev/null +++ b/Examples/javascript/variables/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +wrapper:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +build:: wrapper + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build + +clean:: + $(MAKE) -f $(TOP)/Makefile javascript_clean + +check:: build + $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ + TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run diff --git a/Examples/javascript/variables/binding.gyp b/Examples/javascript/variables/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/variables/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/variables/example.cxx b/Examples/javascript/variables/example.cxx new file mode 100755 index 000000000..3ad4c2323 --- /dev/null +++ b/Examples/javascript/variables/example.cxx @@ -0,0 +1,96 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include +#include +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +#ifdef __cplusplus // Note: for v8 this must be linkable with g++, without extern cstrvar is mangled +extern const char cstrvar[] = "Goodbye"; +#else +const char cstrvar[] = "Goodbye"; +#endif +const +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/javascript/variables/example.h b/Examples/javascript/variables/example.h new file mode 100755 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/javascript/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/javascript/variables/example.i b/Examples/javascript/variables/example.i new file mode 100755 index 000000000..591b871ed --- /dev/null +++ b/Examples/javascript/variables/example.i @@ -0,0 +1,49 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + diff --git a/Examples/javascript/variables/runme.js b/Examples/javascript/variables/runme.js new file mode 100755 index 000000000..22d208480 --- /dev/null +++ b/Examples/javascript/variables/runme.js @@ -0,0 +1,68 @@ +var example = require("./build/Release/example"); + +// Try to set the values of some global variables +example.ivar = 42; +example.svar = -31000; +example.lvar = 65537; +example.uivar = 123456; +example.usvar = 61000; +example.ulvar = 654321; +example.scvar = -13; +example.ucvar = 251; +example.cvar = "S"; +example.fvar = 3.14159; +example.dvar = 2.1828; +example.strvar = "Hello World"; +example.iptrvar= example.new_int(37); +example.ptptr = example.new_Point(37,42); +example.name = "Bill"; + +// Now console.log out the values of the variables +console.log("Variables (values console.loged from Python)" + "\n"); +console.log("ivar = " + example.ivar + "\n"); +console.log("svar = " + example.svar + "\n"); +console.log("lvar = " + example.lvar + "\n"); +console.log("uivar = " + example.uivar + "\n"); +console.log("usvar = " + example.usvar + "\n"); +console.log("ulvar = " + example.ulvar + "\n"); +console.log("scvar = " + example.scvar + "\n"); +console.log("ucvar = " + example.ucvar + "\n"); +console.log("fvar = " + example.fvar + "\n"); +console.log("dvar = " + example.dvar + "\n"); +console.log("cvar = " + example.cvar + "\n"); +console.log("strvar = " + example.strvar+ "\n"); +console.log("cstrvar = " + example.cstrvar+ "\n"); +console.log("iptrvar = " + example.iptrvar+ "\n"); +console.log("name = " + example.name + "\n"); +console.log("ptptr = " + example.ptptr + ": " + example.Point_print(example.ptptr) + "\n"); +console.log("pt = " + example.pt + ": " + example.Point_print(example.pt) + "\n"); + + +console.log("\nVariables (values console.loged from C)"); + +example.print_vars(); + +console.log("\nNow I'm going to try and modify some read only variables"); + +console.log("Tring to set 'path'"); +try{ + example.path = "Whoa!"; + console.log("Hey, what's going on?!?! This shouldn't work"); +} +catch(e){ + console.log("Good."); +} + +console.log("Trying to set 'status'"); +try{ + example.status = 0; + console.log("Hey, what's going on?!?! This shouldn't work"); +} catch(e){ + console.log("Good."); +} + +console.log("\nI'm going to try and update a structure variable.\n"); +example.pt = example.ptptr; +console.log("The new value is: "); +example.pt_print(); +console.log("You should see the value: " + example.Point_print(example.ptptr)); diff --git a/Examples/javascript/variables/swig_gdb.log b/Examples/javascript/variables/swig_gdb.log new file mode 100644 index 000000000..2fe437110 --- /dev/null +++ b/Examples/javascript/variables/swig_gdb.log @@ -0,0 +1,9 @@ +Loaded swig printers +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string From 41ec3fb67e65f3448e52c0eb7372d0331bc7b6ca Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 27 Sep 2013 02:54:42 +0200 Subject: [PATCH 231/352] Travis configuration for Javascript branch. --- .travis.yml | 70 ++++++++++++----------------------------------------- 1 file changed, 15 insertions(+), 55 deletions(-) diff --git a/.travis.yml b/.travis.yml index 26758304f..3b8500aee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,58 +1,18 @@ -language: cpp +language: c compiler: - - clang - gcc -env: - - SWIGLANG= -matrix: - include: - - compiler: gcc - env: SWIGLANG=csharp - - compiler: gcc - env: SWIGLANG=go - - compiler: gcc - env: SWIGLANG=guile - - compiler: gcc - env: SWIGLANG=java - - compiler: gcc - env: SWIGLANG=lua - - compiler: gcc - env: SWIGLANG=octave SWIGJOBS=-j4 - - compiler: gcc - env: SWIGLANG=perl5 - - compiler: gcc - env: SWIGLANG=php - - compiler: gcc - env: SWIGLANG=python - - compiler: gcc - env: SWIGLANG=python PY3=1 - - compiler: gcc - env: SWIGLANG=ruby - - compiler: gcc - env: SWIGLANG=tcl - allow_failures: - # None -before_install: - - lsb_release -a - - uname -a - - sudo apt-get -qq update - - time sudo apt-get -qq install libboost-dev - - if test "$SWIGLANG" = "csharp"; then sudo apt-get -qq install mono-devel; fi - - if test "$SWIGLANG" = "go"; then go env | sed -e 's/^/export /' > goenvsetup && source goenvsetup && rm -f goenvsetup; fi # Until configure.ac is fixed - - if test "$SWIGLANG" = "guile"; then sudo apt-get -qq install guile-2.0-dev; fi - - if test "$SWIGLANG" = "lua"; then sudo apt-get -qq install lua5.1 liblua5.1-dev; fi - - if test "$SWIGLANG" = "octave"; then sudo apt-get -qq install octave3.2 octave3.2-headers; fi - - if test "$SWIGLANG" = "php"; then sudo apt-get install php5-cli php5-dev; fi - - if test "$SWIGLANG" = "python" -a "$PY3"; then sudo apt-get install python3-dev; fi - - if test "$SWIGLANG" = "tcl"; then sudo apt-get -qq install tcl8.4-dev; fi +node_js: + -0.10.12 +before_script: + - "sudo apt-get install rlwrap" + - "wget https://launchpad.net/~chris-lea/+archive/node.js/+build/4936691/+files/nodejs_0.10.18-1chl1~precise1_amd64.deb" + - "sudo dpkg -i nodejs_0.10.18-1chl1~precise1_amd64.deb" + - "sudo npm install -g node-gyp" + - "sudo apt-get install libv8-3.7.12.22 libv8-dev" + - "sudo apt-get install libwebkitgtk-dev" + - "./autogen.sh && ./configure && make" + - "cd Examples && make javascript_exe && cd .." script: - - ./autogen.sh && ./configure - - make -s $SWIGJOBS - - if test -z "$SWIGLANG"; then make -s check-ccache; fi - - ./swig -version - - if test -n "$SWIGLANG"; then make -s check-$SWIGLANG-version; fi - - if test -n "$SWIGLANG"; then make -k $SWIGJOBS check-$SWIGLANG-examples; fi - - if test -n "$SWIGLANG"; then make -k $SWIGJOBS check-$SWIGLANG-test-suite; fi -branches: - only: - - master + - "make SMOKE=1 check-javascript-test-suite" + - "make SMOKE=1 ENGINE=jsc check-javascript-test-suite" + - "make SMOKE=1 ENGINE=v8 check-javascript-test-suite" From 1e34ecdc31c82d30141097f7744617361ebb748c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 13 Feb 2014 19:25:16 +0100 Subject: [PATCH 232/352] Next iteration on creating a documentation for the Javascript module. --- .../Javascript/MappingC++ToJavascript.md | 220 --- .../V8_CodeGeneratorSpecification.md | 1063 -------------- Doc/Manual/Javascript.md | 1215 +++-------------- Source/Modules/javascript.cxx | 30 +- 4 files changed, 203 insertions(+), 2325 deletions(-) delete mode 100644 Doc/Devel/Javascript/MappingC++ToJavascript.md delete mode 100644 Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md diff --git a/Doc/Devel/Javascript/MappingC++ToJavascript.md b/Doc/Devel/Javascript/MappingC++ToJavascript.md deleted file mode 100644 index c77064933..000000000 --- a/Doc/Devel/Javascript/MappingC++ToJavascript.md +++ /dev/null @@ -1,220 +0,0 @@ -# Mapping C++ language features to Javascript - -## Namespaces - -A namespace is represented as a static instance (global variable) -containing other namespaces, global variables and functions -and class templates - -### Example: - -C++: - -~~~~c++ -namespace foo { - int x; - namespace bar { - double y; - } -} -~~~~ - -Javascript: - -~~~~javascript -var foo = new Object(); -foo.x = 0; -foo.bar = new Object(); -foo.bar.y = 0.0; -~~~~ - -## Global variables and functions - -Global variables and functions are properties of other context objects -(global or namespaces). - -### Example: - -C++: - -~~~~c++ -int x; -namespace foo { - void bar(); -} -~~~~ - -Javascript: - -~~~~javascript -var x = 0; -var foo = new Object(); -foo.bar = function() { - return undefined; -} -~~~~ - -## Classes - -Classes are defined as class templates and instantiated using the `new` -operator. -Class members are set in the constructor function using the `this` reference. -Private class members are set using the `var` keyword. - -### Example: - -C++: - -~~~~c++ -class Foo { - int bar(); - -private: - int x; -} -~~~~ - -Javascript: - -~~~~javascript -var Foo = function() { - var x = 42; - this.bar = function() { return x; }; -}; - -var foo = new Foo(); -foo.bar(); -~~~~ - -## Static class members and functions - -Static variables and functions should be added to the class template object. - -~~~~c++ -class Foo { - static std::string foo(); - std::string bar(); -} -~~~~ - -Javascript: - -~~~~javascript -var Foo = function() { - this.bar = function() { - return "bar"; - } -}; -Foo.foo = function() { - return "foo"; -}; - -var foo = new Foo(); -foo.foo() -> TypeError: Object [object Object] has no method 'foo' -Foo.foo() -> "foo" -foo.bar(); -> "bar" -~~~~ - -## Inheritance - -Javascript uses a prototype based inheritance mechanism. This limits -feature support to single inheritance. - -### Example: - -C++: - -~~~~c++ -class Foo { -public: - int foo(); - -private: - int x; -} - -class Bar: public Foo { -public: - int bar(); -} -~~~~ - -Javascript: - -~~~~javascript -var Foo = function() { - var x = 42; - this.foo = function() { return x; }; -}; - -var Bar = function() { - this.bar = function() { return 6; }; -} -Bar.prototype = new Foo(); -Bar.prototype.constructor = Bar; - -var foo = new Foo(); -var bar = new Bar(); - -foo.foo() -> 42 -foo.bar() -> TypeError: Object [object Object] has no method 'bar' -bar.foo() -> 42 -bar.bar() -> 6 -~~~~ - -## Virtual methods - -The prototype mechanism of Javascript allows method overriding which is -needed to map the concept of virtual functions. - -### Example: - -C++: - -~~~~c++ -class Foo { -public: - virtual int foo(); -} - -class Bar: public Foo { -public: - virtual int foo(); -} -~~~~ - -Javascript: - -~~~~javascript -var Foo = function() { - this.foo = function() { return 1; }; -}; - -var Bar = function() {} -Bar.prototype = new Foo(); -Bar.prototype.constructor = Bar; -Bar.prototype.foo = function() { return 42; }; - -var foo = new Foo(); -var bar = new Bar(); - -foo.foo() -> 1 -bar.foo() -> 42 -~~~~ - -## Overloading - -In Javascript like in other scripting languages method overloading is not -available. I.e., there can only be one function for one function name. -Therefore, it is necessary to implement a method dispatching mechanism -for these methods. - diff --git a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md b/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md deleted file mode 100644 index 63027b74d..000000000 --- a/Doc/Devel/Javascript/V8_CodeGeneratorSpecification.md +++ /dev/null @@ -1,1063 +0,0 @@ -Javascript: Specification of a Code Generator for V8 -==================================================== - -The aim of this is to evolve a specification for a code generator. - -## Top Level structure - -The generated code consists of the following blocks: - -~~~~ - - - - - - - - - - -~~~~ - -- `HELPER_FUNCTIONS`: static, from swg-file -- `INCLUDES`: static, module property -- `CLASS_TEMPLATES`: dynamically growing, on class declarations -- `FUNCTION_WRAPPERS`: dynamically growing, on method declarations -- `INITIALIZER`: dynamically growing, aggregates everything (to be specified in more detail) - -### INCLUDES - -~~~~ -#include - - -~~~~ - -`USER_DEFINED_INCLUDES`: a module property - -### CLASS_TEMPLATES - -Static references to class templates which are (should be) read-only and can be reused. - -~~~~ -v8::Persistent SWIGV8_${NAME_MANGLED}; -~~~~ - -Notes: - - it is very important to consider namespaces from the beginning. - `NAME_MANGLED` is the mangled qualified class name, e.g., `foo_bar_MyClass` for `foo::bar::MyClass`, - which is retrieved ny `Swig_string_mangle(Getattr(n, "name"))` - - namespaces do not need a function template, as they will not be - instantiated - -## FUNCTION_WRAPPERS - -There are different types of function wrappers: - - - Global Functions (global/namespace/class) - - Constructors / Destructors - - Getters / Settters - - Member Functions - -### Global Functions - -~~~~ -v8::Handle wrap_${NAME_MANGLED}(const v8::Arguments &args) { - v8::HandleScope scope; - v8::Handle ret; - ${LOCALS} - ${CODE} - return scope.Close(ret); -} -~~~~ - -- `LOCALS`: declarations for input and output arguments -- `CODE` contains input marshalling, the action, and output marshalling - -### Constructors - -~~~~ -v8::Handle ${NAME_MANGLED}_new(const v8::Arguments& args) { - v8::HandleScope scope; - v8::Handle self = args.Holder(); - ${LOCALS} - ${CODE} - self->SetInternalField(0, v8::External::New(ptr)); - return self; -} -~~~~ - -- `LOCALS`: declarations for input arguments -- `CODE` contains input marshalling, and the action - -### Destructors - -TODO: I haven't found out yet how a descrtuctor can be registered - -### Getters - -~~~~ -v8::Handle ${NAME_MANGLED}_get(v8::Local property, const v8::AccessorInfo& info) { - v8::HandleScope scope; - v8::Handle ret; - ${LOCALS} - ${CODE} - return scope.Close(ret); -} -~~~~ - -- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` -- `LOCALS`: declarations for output arguments -- `CODE` contains the action, and output marshalling - -### Setters - -~~~~ -void ${NAME_MANGLED}_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - ${LOCALS} - ${CODE} -} -~~~~ -- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` -- `LOCALS`: declarations for input arguments -- `CODE` contains input marshalling, and the action - -### Functions - -~~~~ -v8::Handle ${NAME_MANGLED}(const Arguments &args) { - v8::HandleScope scope; - v8::Handle ret; - ${LOCALS} - ${CODE} - return scope.Close(ret); -} -~~~~ - -- `NAME_MANGLED`: the qualified mangled name of the variable, E.g., `foo::x -> foo_x`, `A.x -> A_x` -- `LOCALS`: declarations for input arguments -- `CODE` contains input marshalling, the action, and output marshalling - - -### Overloading - -TODO: if a function or a ctor is overloaded, a dispatcher function -must be generated which calls overloading wrappers depending on number -and type of input arguments. - - -## Initializer - -~~~~ -void ${MODULE}_Initialize(v8::Handle context) -{ - v8::HandleScope scope; - - // register the module in globale context - v8::Local global = context->Global(); - - ${PART_NAMESPACES} - - ${PART_CLASS_TEMPLATES} - - ${PART_WRAPPERS} - - ${PART_INHERITANCE} - - ${PART_REGISTER_CLASSES} - - ${PART_REGISTER_NS} -} -~~~~ - -### Namespaces - -Namespaces are objects without class templates. I.e., instances are created, -referenced locally, used as contexts for other registrations, and stored -in the according parent contexts. - -~~~~~ -v8::Handle ${NAME_MANGLED} = v8::ObjectTemplate::New(); -~~~~~ - -### Class Templates - -~~~~ -SWIGV8_${NAME_MANGLED} = SWIGV8_CreateClassTemplate("${NAME_UNQUALIFIED}" , ${NAME_MANGLED}_new); -~~~~ - -- `NAME_UNQUALIFIED`: the class name without context, i.e., namespaces - -### Inheritance - -~~~~ -SWIGV8_${NAME_MANGLED}->Inherit(SWIGV8_${BASE_CLASS}); -~~~~ - -- Note: multiple inheritance is not possible; thus we will always take the first parent class - -### Registration - -The registration part consists of registering classes at contexts (i.e., global or namespace), -methods and properties at classes or contexts, and namespaces as objects at -parent contexts. - -#### Global Variable - -~~~~ -${CONTEXT}->SetAccessor(v8::String::NewSymbol("${NAME_UNQUALIFIED}"), ${GETTER}, ${SETTER}); -~~~~ - -- `CONTEXT`: either global, or the according namespace template -- `${SETTER} = 0` for read-only variables - -#### Global Function - -~~~~ -SWIGV8_AddGlobalFunction(${CONTEXT}, "${NAME_UNQUALIFIED}", wrap_${NAME_QUALIFIED}); -~~~~ - -- `CONTEXT`: either global, or the according namespace template - -#### Class - -~~~~ -${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", SWIGV8_${NAME_MANGLED}->GetFunction())); -~~~~ - -- Note: every class template has an associated ctor function wrapper, which is registered here -- `CONTEXT`: either global, or the according namespace instance - -#### Class method - -~~~~ -SWIGV8_AddClassMethod(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", wrap_${NAME_MANGLED}); -~~~~ - -Note: implemented in static helper function - -#### Class variable - -~~~~ -SWIGV8_AddProperty(SWIGV8_${CLASSNAME_MANGLED}, "${NAME_UNQUALIFIED}", ${GETTER}, ${SETTER}); -~~~~ - -- `GETTER`: the name of the generated wrapper for the property getter -- `SETTER`: the name of the generated wrapper for property setter; optional (i.e., maybe `NULL`) - -### Namespace - -~~~~ -${CONTEXT}->Set(v8::String::NewSymbol("${NAME_UNQUALIFIED}", ${NAME_MANGLED}->NewInstance())); -~~~~ - -Note: it is important to register the namespace objects in reverse order, -e.g., - -~~~~ -namespace foo { - namespace bar {} -} -~~~~ - -would be registered in this order: - -~~~~ -foo->Set(v8::String::NewSymbol("bar", bar->NewInstance())); -global->Set(v8::String::NewSymbol("foo", foo->NewInstance())); -~~~~ - -## HELPER_FUNCTIONS - -A lot of boiler-plate code can be shifted into static helper functions: - -~~~~ - -/** - * Creates a class template for a class without extra initialization function. - */ -v8::Persistent SWIGV8_CreateClassTemplate(const char* symbol, v8::InvocationCallback func) -{ - v8::Local class_templ = v8::FunctionTemplate::New(func); - class_templ->SetClassName(v8::String::NewSymbol(symbol)); - - v8::Handle inst_templ = class_templ->InstanceTemplate(); - inst_templ->SetInternalFieldCount(1); - - return v8::Persistent::New(class_templ); -} - -/** - * Registers a class method with given name for a given class template. - */ -void SWIGV8_AddMemberFunction(v8::Handle class_templ, - const char* symbol, - v8::InvocationCallback func) -{ - v8::Handle proto_templ = class_templ->PrototypeTemplate(); - proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)); -} - -/** - * Registers a class property with given name for a given class template. - */ -void SWIGV8_AddMemberVariable(v8::Handle class_templ, - const char* varname, - v8::AccessorGetter getter, - v8::AccessorSetter setter) -{ - v8::Handle proto_templ = class_templ->InstanceTemplate(); - proto_templ->SetAccessor(v8::String::New(varname), getter, setter); -} - - -/** - * Adds a property with given name to a given context. - */ -void SWIGV8_AddGlobalVariable(v8::Handle context, - const char* varname, - v8::AccessorGetter getter, - v8::AccessorSetter setter) -{ - context->SetAccessor(v8::String::NewSymbol(varname), getter, setter); -} - -/** - * Adds a function with given name to a given context. - */ -void SWIGV8_AddGlobalFunction(v8::Handle context, - const char* symbol, - v8::InvocationCallback func) -{ - context->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(func)->GetFunction()); -} - -template -static T* SWIGV8_UnwrapThisPointer (v8::Handle handle) -{ - // assert(!handle.IsEmpty()); - // assert(handle->InternalFieldCount() > 0); - v8::Local wrap = v8::Local::Cast(handle->GetInternalField(0)); - return static_cast(wrap->Value()); -} - -~~~~ - -------------------------- - -Examples -======== - -In this chapter manually coded wrappers are presented. -This has been useful for studying the addressed code generation on basis -of examples. - -## Global variable - -~~~~~ -static double Foo = 42.0; - -void Foo_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - v8::HandleScope scope; - double arg1 ; - arg1 = value->NumberValue(); - Foo = arg1; -} - -v8::Handle Foo_get(v8::Local property, const v8::AccessorInfo& info) { - v8::HandleScope scope; - v8::Handle ret; - double result; - - result = Foo; - - ret = v8::Number::New(result); - return scope.Close(ret); -} - -int GlobalVar_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - global->SetAccessor(v8::String::New("Foo"), Foo_get, Foo_set); - - return 0; -} -~~~~~ - -## Global functions - -~~~~~ - -static double foo(int bla) { - return (bla * 2.1); -} - -v8::Handle wrap_foo(const v8::Arguments &args) { - v8::HandleScope scope; - v8::Handle ret; - - int arg1 ; - double result; - - arg1 = args[0]->Int32Value(); - - result = foo(arg1); - - ret = v8::Number::New(result); - - return scope.Close(ret); -} - -int GlobalFunc_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - - global->Set(v8::String::NewSymbol("foo"), v8::FunctionTemplate::New(wrap_foo)->GetFunction()); - - return 0; -} -~~~~~ - - -## Namespaces - -~~~~~ - -namespace foo { - static double bar = 42.0; -} - -void foo_bar_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - v8::HandleScope scope; - - double arg1 ; - arg1 = value->NumberValue(); - foo::bar = arg1; - -} - -v8::Handle foo_bar_get(v8::Local property, const v8::AccessorInfo& info) { - v8::HandleScope scope; - v8::Handle ret; - double result; - - result = foo::bar; - - ret = v8::Number::New(result); - return scope.Close(ret); -} - -int Namespace_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - - v8::Handle foo = v8::ObjectTemplate::New(); - - foo->SetAccessor(v8::String::New("bar"), foo_bar_get, foo_bar_set); - - global->Set(v8::String::New("foo"), foo->NewInstance()); - return 0; -} - -~~~~~ - -## Class - -~~~~~ - -class A { -public: - A() { - x = 42; - } - - ~A() {} - - double foo(bool a) { - if(a) - return 11.11; - else - return 22.22; - } - - int x; -}; - -v8::Handle A_new(const v8::Arguments& args) { - v8::HandleScope scope; - v8::Handle self = args.Holder(); - A *result; - result = new A(); - self->SetInternalField(0, v8::External::New(result)); - return self; -} - -void A_x_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - v8::HandleScope scope; - A *arg1; - int arg2; - - arg1 = SWIGV8_UnwrapThisPointer(info.Holder()); - arg2 = value->Int32Value(); - - arg1->x = arg2; - -} - -v8::Handle A_x_get(v8::Local property, const v8::AccessorInfo& info) { - v8::HandleScope scope; - v8::Handle jsresult; - A *arg1; - int result; - - arg1 = SWIGV8_UnwrapThisPointer(info.Holder()); - result = arg1->x; - - jsresult = v8::Int32::New(result); - return scope.Close(jsresult); -} - -v8::Handle wrap_A_foo(const v8::Arguments& args) -{ - v8::HandleScope scope; - v8::Handle jsresult; - A *arg1; - double arg2; - double result; - - arg1 = SWIGV8_UnwrapThisPointer(args.Holder()); - arg2 = args[0]->NumberValue(); - - result = arg1->foo(arg2); - - jsresult = v8::Number::New(result); - return scope.Close(jsresult); -} - -int Class_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - - v8::Persistent class_A = SWIGV8_CreateClassTemplate("A", A_new); - SWIGV8_AddMemberVariable(class_A, "x", A_x_get, A_x_set); - SWIGV8_AddMemberFunction(class_A, "foo", wrap_A_foo); - - global->Set(v8::String::NewSymbol("A"), class_A->GetFunction()); - - return 0; -} - -~~~~~ - -## Static variables and functions - -Static variables and functions are implemented similar to global ones. -They are added to the class object instead of the class template. -Therefore, these are only accessible via the class object and not via -instances of this class. - -~~~~~ - -class A { -public: - A() { - x = 7; - } - - ~A() {} - - static int foo() { - return 42; - } - - static int x; -}; - -int A::x = 7; - -v8::Handle A_new(const v8::Arguments& args) { - v8::HandleScope scope; - v8::Handle self = args.Holder(); - A *result; - result = new A(); - self->SetInternalField(0, v8::External::New(result)); - return self; -} - -void A_x_set(v8::Local property, v8::Local value, const v8::AccessorInfo& info) { - v8::HandleScope scope; - int arg1; - - arg1 = value->Int32Value(); - - A::x = arg1; - -} - -v8::Handle A_x_get(v8::Local property, const v8::AccessorInfo& info) { - v8::HandleScope scope; - v8::Handle jsresult; - int result; - - result = A::x; - - jsresult = v8::Int32::New(result); - return scope.Close(jsresult); -} - -v8::Handle wrap_A_foo(const v8::Arguments& args) -{ - v8::HandleScope scope; - v8::Handle jsresult; - int result; - - result = A::foo(); - - jsresult = v8::Number::New(result); - return scope.Close(jsresult); -} - -int Class_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - - v8::Persistent classtempl_A = SWIGV8_CreateClassTemplate("A", A_new); - - v8::Handle class_A = classtempl_A->GetFunction(); - - SWIGV8_AddGlobalVariable(class_A, "x", A_x_get, A_x_set); - SWIGV8_AddGlobalFunction(class_A, "foo", wrap_A_foo); - - global->Set(v8::String::NewSymbol("A"), class_A); - - return 0; -} - -~~~~~ - -## Inheritance - -~~~~~ -class A { -public: - A() {} - - ~A() {} - - double foo() { - return 11.11; - } -}; - -class B: public A { -public: - B() {} - ~B() {} - - int bar() { - return 7; - } -}; - -... (left out function wrappers) ... - -int Class_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - - v8::Persistent class_A = SWIGV8_CreateClassTemplate("A", A_new); - v8::Persistent class_B = SWIGV8_CreateClassTemplate("B", B_new); - - SWIGV8_AddMemberFunction(class_A, "foo", wrap_A_foo); - SWIGV8_AddMemberFunction(class_B, "bar", wrap_B_bar); - - class_B->Inherit(class_A); - - global->Set(v8::String::NewSymbol("A"), class_A->GetFunction()); - global->Set(v8::String::NewSymbol("B"), class_B->GetFunction()); - - return 0; -} -~~~~~ - -## String arguments - -At a first stage all strings are treated as Utf8. -For proper handling strings as return values I have to study -other modules. - -~~~~~ -int my_strlen(const char* s) { - return strlen(s); -} - -// creates a new string -const char* foo(int a) { - char* result = new char[a+1]; - result[a] = 0; - memset(result, 'a', a); - return result; -} - -v8::Handle wrap_my_strlen(const v8::Arguments& args) -{ - v8::HandleScope scope; - v8::Handle jsresult; - const char* arg1; - int result; - - v8::String::Utf8Value utf8(args[0]); - - result = my_strlen(*utf8); - - jsresult = v8::Number::New(result); - return scope.Close(jsresult); -} - -v8::Handle wrap_foo(const v8::Arguments& args) -{ - v8::HandleScope scope; - v8::Handle jsresult; - int arg1; - const char* result; - - arg1 = args[0]->Int32Value(); - result = foo(arg1); - - jsresult = v8::String::New(result); - - return scope.Close(jsresult); -} - -int Strings_Initialize(v8::Handle context) { - - v8::Local global = context->Global(); - - SWIGV8_AddGlobalFunction(global, "strlen", wrap_my_strlen); - SWIGV8_AddGlobalFunction(global, "foo", wrap_foo); - - return 0; -} -~~~~~ - -------------------------- - -Control flow analysis -===================== - -## Global variables - -### Example: -~~~~ -int x; - -namespace foo { - double y; -} -~~~~ - -### Control flow: -Command: -~~~~ -swig -analyze -c++ functionWrapper +before globalvariableHandler +before example.i -~~~~ - -~~~~ -enter top() of example -enter variableHandler() of x -enter globalvariableHandler() of x - | sym:name - "x" - | name - "x" - | type - "int" - - enter variableWrapper() of x - - enter functionWrapper() of x - | name - "x" - | sym:name - "x_set" - | parms - int - | wrap:action - "x = arg1;" - | type - "void" - exit functionWrapper() of x - - enter functionWrapper() of x - | name - "x" - | sym:name - "x_get" - | type - "int" - exit functionWrapper() of x - exit variableWrapper() of x -exit globalvariableHandler() of x -exit variableHandler() of x - -enter variableHandler() of foo::y -enter globalvariableHandler() of foo::y - | sym:name - "y" - | name - "foo::y" - | type - "double" - - enter variableWrapper() of foo::y - enter functionWrapper() of foo::y - | name - "foo::y" - | sym:name - "y_set" - | parms - double - | wrap:action - "foo::y = arg1;" - | type - "void" - exit functionWrapper() of foo::y - - enter functionWrapper() of foo::y - | name - "foo::y" - | sym:name - "y_get" - | wrap:action - "result = (double)foo::y;" - | type - "double" - exit functionWrapper() of foo::y - exit variableWrapper() of foo::y -exit globalvariableHandler() of foo::y -exit variableHandler() of foo::y -exit top() of example - -~~~~ - -## Simple class - -### Example: - -~~~~ -class A { -public: - A(); - ~A(); -}; - -namespace foo { - class B { - }; -} -~~~~ - -### Control flow: - -~~~~ -enter top() of example - enter classHandler() of A - enter constructorHandler() of A - enter functionWrapper() of A - | name - "A" - | sym:name - "new_A" - | access - "public" - | wrap:action - "result = (A *)new A();" - | type - "p.A" - exit functionWrapper() of A - exit constructorHandler() of A - enter destructorHandler() of ~A - enter functionWrapper() of ~A - | name - "~A" - | sym:name - "delete_A" - | parms - A * - | wrap:action - "delete arg1;" - exit functionWrapper() of ~A - exit destructorHandler() of ~A -exit classHandler() of A -enter classHandler() of foo::B - enter constructorHandler() of foo::B::B - enter functionWrapper() of foo::B::B - | name - "foo::B::B" - | sym:name - "new_B" - | access - "public" - | wrap:action - "result = (foo::B *)new foo::B();" - | type - "p.foo::B" - exit functionWrapper() of foo::B::B - exit constructorHandler() of foo::B::B - enter destructorHandler() of foo::B::~B - enter functionWrapper() of foo::B::~B - | name - "foo::B::~B" - | sym:name - "delete_B" - | parms - foo::B * - | wrap:action - "delete arg1;" - | type - "void" - exit functionWrapper() of foo::B::~B - exit destructorHandler() of foo::B::~B -exit classHandler() of foo::B -exit top() of example - -~~~~ - -### Example - -~~~~ -class A { -public: - int x; -}; -~~~~ - - -### Control flow - -~~~~ -enter top() of example -enter classHandler() of A - enter variableHandler() of x - enter membervariableHandler() of x - enter functionWrapper() of x - | name - "x" - | sym:name - "A_x_set" - | access - "public" - | parms - A *,int - | wrap:action - "if (arg1) (arg1)->x = arg2;" - | type - "void" - | memberset - "1" - exit functionWrapper() of x - enter functionWrapper() of x - | name - "x" - | sym:name - "A_x_get" - | access - "public" - | parms - A * - | wrap:action - "result = (int) ((arg1)->x);" - | type - "int" - | memberset - "1" - | memberget - "1" - exit functionWrapper() of x - exit membervariableHandler() of x - exit variableHandler() of x - enter constructorHandler() of A::A - enter functionWrapper() of A::A - exit functionWrapper() of A::A - exit constructorHandler() of A::A - enter destructorHandler() of A::~A - enter functionWrapper() of A::~A - exit functionWrapper() of A::~A - exit destructorHandler() of A::~A -exit classHandler() of A -exit top() of example -~~~~ - -## Class method - -### Example - -~~~~ -class A { -public: - void foo(int x, double y); -private: - void bar(); -}; -~~~~ - -### Control flow - -~~~~ -enter top() of example -enter classHandler() of A - enter functionHandler() of foo - enter memberfunctionHandler() of foo - enter functionWrapper() of foo - | name - "foo" - | sym:name - "A_foo" - | access - "public" - | parms - A *,int,double - | wrap:action - "(arg1)->foo(arg2,arg3);" - | type - "void" - exit functionWrapper() of foo - exit memberfunctionHandler() of foo - exit functionHandler() of foo -... -exit classHandler() of A -exit top() of example -~~~~ - -## Static class variable and method - -### Example - -~~~~ -class A { -public: - static int x; - - static void foo(); -}; -~~~~ - -### Control flow - -~~~~ -enter top() of example -enter classHandler() of A - enter variableHandler() of x - enter staticmembervariableHandler() of x - enter variableWrapper() of A::x - enter functionWrapper() of A::x - | name - "A::x" - | sym:name - "A_x_set" - | parms - int - | wrap:action - "A::x = arg1;" - | type - "void" - exit functionWrapper() of A::x - enter functionWrapper() of A::x - +++ cdecl ---------------------------------------- - | name - "A::x" - | ismember - "1" - | sym:name - "A_x_get" - | variableWrapper:sym:name - "A_x" - | wrap:action - "result = (int)A::x;" - | type - "int" - exit functionWrapper() of A::x - exit variableWrapper() of A::x - exit staticmembervariableHandler() of x - exit variableHandler() of x - enter functionHandler() of foo - enter staticmemberfunctionHandler() of foo - enter globalfunctionHandler() of A::foo - enter functionWrapper() of A::foo - | name - "A::foo" - | sym:name - "A_foo" - | wrap:action - "A::foo();" - | type - "void" - exit functionWrapper() of A::foo - exit globalfunctionHandler() of A::foo - exit staticmemberfunctionHandler() of foo - exit functionHandler() of foo - enter constructorHandler() of A::A - exit constructorHandler() of A::A - enter destructorHandler() of A::~A - exit destructorHandler() of A::~A -exit classHandler() of A -exit top() of example -~~~~ - -## Inheritance - -### Example - -~~~~ -class A { -}; - -class B: public A { -}; -~~~~ - -### Control flow - -~~~~ -enter top() of example -enter classHandler() of A - +++ class ---------------------------------------- - | name - "A" - | sym:name - "A" -... -exit classHandler() of A -enter classHandler() of B - | name - "B" - | sym:name - "B" - | privatebaselist - 0xf1238f10 - | protectedbaselist - 0xf1238ef0 - | baselist - 0xf1238ed0 - | bases - 0xf1239830 - | allbases - 0xf1239c30 -... -exit classHandler() of B -exit top() of example -~~~~ diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index a01c630d8..77b7e086b 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -1,1103 +1,264 @@ -% SWIG AND JAVASCRIPT - +% SWIG and Javascript + +This chapter describes SWIG's support of Javascript. + + # Overview -This chapter describes SWIG support for Javascript. -The module is designed to support JavascriptCore and V8 as target engine. -Currently only JavascriptCore support is implemented. -JavaScriptCore is the built-in JavaScript engine for WebKit, whereas V8 is the engine used by Chromium. +JavaScript is a prototype-based scripting language that is dynamic, weakly typed +and has first-class functions. Its arguably the most popular language for web development. +Beyond of being a browser-based scripting language, with [node.js](http://nodejs.org) +Javascript has found its way to a backend development language, too. -JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. C++, on the other hand, is statically typed, compiled, general purpose programming language. -The approach I followed here is "Test driven" where I have written the examples/test-cases to be supported for Javascript one-by-one and implemented the required module files in parallel. -The support for Javascript would be added similar to other supported target languages in swig. Swig comes with an "Examples" directory for Javascript like other supported language. The directory contains examples for every supported feature of the target language. There is also a test-suite directory for javascript which contains additional tests. +Native Javascript extensions can be used for applications that embed a web-browser view or +that embed a Javascript engine (such as *node.js*). +Extending a general purpose web-browser is not possible as this would be severe security issue. + +With [WebKit](http://www.webkit.org/) there is an modern and open-source browser +implementations available which can be embedded into an application. +At the moment, [Chromium Embedded Framework](http://code.google.com/p/chromiumembedded/) +can not extended as CEF does not provide access to the V8 engine, but instead comes with +its own extension mechanism. + +SWIG Javasript currently supports **JavascriptCore**, the Javascript engine used by `Safari`, +and **v8**, which is used by `Chromium` and `node.js`. # Preliminaries -In order to use this module, you will need to have installed javascriptcore and you can install it by installing package libwebkit-dev -You can find out some necessary compiler/linker flag by +# Running SWIG - pkg-config javascriptcoregtk-1.0 --cflags --libs +Suppose that you defined a SWIG module such as the following: -## Using the module - -To generate an extension for JavascriptCore one would call swig as follows - -~~~~ - -swig -c++ -javascript -jsc example.i - -~~~~ - -This generates a C++ source file containing the wrapper. - -## How does Javascript talk to C++? - -JavascriptCore provides a C-API which allows to extend a Javascript interpreter with native methods and structures. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is also possible to add your own commands and variables. A reference manual of this API can be found -[here](http://developer.apple.com/library/mac/#documentation/Carbon/Reference/WebKit_JavaScriptCore_Ref/_index.html). - -Typically, when you add a new command to the javascript interpreter you need to do two things: first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process. - -## Wrapper functions - -Suppose you have an ordinary C function like this : - -~~~~ - -int fact(int n) { - if (n <= 1) return 1; - else return n*fact(n-1); -} - -~~~~ - -In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things : - - - Gather function arguments and make sure they are valid. - - Call the C function. - - Convert the return value into a form recognized by the javascript. - -As an example, the javascript wrapper function for the fact() function above example might look like the following : - -~~~~ - -JSValueRef wrap_fact(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - int arg1 = (int)JSValueToNumber(context, argv[0], NULL); - int arg2 = (int)JSValueToNumber(context, argv[1], NULL); - int result = (int)fact(arg1,arg2); - JSValueRef jsresult = JSValueMakeNumber(context, result); - return jsresult; -} - -~~~~ - -Once you have created a wrapper function, the final step is to tell the javascript about the new function. This is done by register function called by the javascript when the module is loaded. For example, adding the above function to the javascript interpreter requires code like the following : - -~~~~ - -bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, - const char* functionName, JSObjectCallAsFunctionCallback callback) -{ - JSStringRef js_globalvarsclassname = JSStringCreateWithUTF8CString(globalvarsclassname); - JSObjectSetProperty(context,js_globalvarsclassname,JSObjectMakeFunctionWithCallback(context, - js_globalvarsclassname, callback), kJSPropertyAttributeNone,NULL); - JSStringRelease(jsstring); - return true; -} - -int example_init(JSContextRef context) { - JSObjectRef global; - ... - jsc_registerFunction(context, global, "fact", wrap_fact); - ... -} - -~~~~ - -When executed, javascript will now have a new command called "fact" that you can use like any other Javascript command. -Although the process of adding a new function to javascript has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code. - -## Variable Linking - -Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable: - -~~~~ - -double Foo = 3.5; - -~~~~ - -To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called. - -~~~~ - -bool Foo_set(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef value, - JSValueRef* exception) -{ - JSValueRef jsresult; - double arg1 = (double)JSValueToNumber(context, value, NULL); - Foo = arg1; - jscresult = JSValueMakeUndefined(context); - return jsresult; -} - -JSValueRef Foo_get(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - double result = (double)Foo; - jsresult = JSValueMakeNumber(context, result); - return jsresult; -} - -~~~~ - -In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as Foo might implicitly call the get function. Similarly, typing Foo = 4 would call the underlying set function to change the value. - -# A tour of basic C/C++ wrapping - -By default, SWIG tries to build a very natural javascript interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping. - -## Modules - -The SWIG %module directive specifies the name of the Javascript module. If you specify `%module example`, then everything is wrapped into a Javascript 'example' module. Underneath the covers, this module consists of a cpp source file example.cpp. When choosing a module name, make sure you don't use the same name as a built-in Javascript command or standard module name. - -## Global variables - -C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that javascript works. - -~~~~ - -// SWIG interface file with global variables +```code %module example -... -%inline %{ +%{ +#include "example.h" +%} +int gcd(int x, int y); extern double Foo; -extern int gcd(int x, int y); -%} +``` + +To build a Javascript module, run SWIG using the `-javascript` option +and a desired target engine `-jsc` or `-v8`. + +```shell +$ swig -javascript -jsc example.i +``` + +If building a C++ extension, add the -c++ option: + +```shell +$ swig -c++ -javascript -jsc example.i +``` + +This creates a C/C++ source file example_wrap.c or example_wrap.cxx. The generated C source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application to create an extension module. + +The name of the wrapper file is derived from the name of the input file. +For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. +To change this, you can use the -o option. +The wrapped module will export one function which must be called to register the module with the Javascript interpreter. +For example, if your module is named `example` the corresponding initializer for JavascriptCore would be + +```code +bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports) +``` + +and for v8: + +```code +void example_initialize (v8::Handle exports) +``` + +# Compilation and Linking + +## Installation + + + +## Dealing with `v8` version incompatibilities + +Unfortunately, v8 does not provide pre-processor macros do detect which version you link to. +Therefore, you have to provide this information manually. + + +# Integration + +This should give a short overview how to integrate your module in different environments: as a `node.js` module, and as an extension for an embedded Chromium. + +## Creating `node.js` Extensions + +As `v8` is written in C++ and comes as a C++ library it is crucial to compile your module using the +same compiler flags as used for building v8. To make things easier, `node.js` provides a build tool called `node-gyp`. + +This expects configuration file named `binding.gyp` which is basically in JSON format and +conforms to the same format that is used with Google's build-tool `gyp`. + +`binding.gyp`: +```code +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} +``` + +First you would create the wrapper using SWIG: + +```shell + +``` + +## Embedded Webkit + + +# Implementation + +The Javascript Module implementation has take a very different approach than other modules +to be able to generate code for different Javascript interpreters. + + +## Module Source Code + +The Javascript module is implemented in `Source/Modules/javascript.cxx`. It contains a SWIG Language class which does represents the module's entry point to the swig engine. +It implements the `Language` interface and dispatches the code generation to a `JSEmitter` instance, `V8Emitter` or `JSCEmitter`. Additionally there are some helpers: `Template`, for templated code generation, and `JSEmitterState`, which is used to manage state information during AST traversal. To find your way through this huge source file, here is a rough map: + +```code +// module wide defines + +#define NAME "name" + ... -~~~~ +// Helper class declarations +class JSEmitterState { ... }; -Now look at the javascript: +class Template { ... }; -~~~~ -print("Global variable Foo=" + example.Foo); -example.Foo = 3.1415926; -print("Variable Foo changed to=" + example.Foo); -print("GCD of x and y is=" + example.gcd(x,y)); +// JSEmitter declaration -~~~~ +class JSEmitter { ... }; -## Constants and enums -C/C++ constants are installed as javascript objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example: +// Emitter factory declarations -~~~~ +JSEmitter *swig_javascript_create_JSCEmitter(); +JSEmitter *swig_javascript_create_V8Emitter(); -#define ICONST 42 -#define FCONST 2.1828 -%constant int iconst = 37; -~~~~ +// Javascript module class declaration -In javascript they are treated as: +class JAVASCRIPT:public Language { ... }; -~~~~ -print("ICONST = " + example.ICONST + " (should be 42)\n"); -print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); -print("iconst = " + example.iconst + " (should be 37)\n"); +// Javascript module function definitions -~~~~ +int JAVASCRIPT::functionWrapper(Node *n) { ... } -For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile. -Enums are treated as constants.So if we have enums in c++ as: - -~~~~ - -void enum_test(color c, Foo::speed s); - -~~~~ - -In javascript they are treated as: - -~~~~ - -example.enum_test(example.RED, example.Foo.IMPULSE); -example.enum_test(example.BLUE, example.Foo.WARP); -example.enum_test(example.GREEN, example.Foo.LUDICROUS); - -~~~~ - -### Inside the class -For class enums as below: - -~~~~ - -class Foo { -public: -Foo() { } -enum speed { IMPULSE, WARP, LUDICROUS }; -} - -~~~~ - -In javascript they are treated as: - -~~~~ - -print(" Foo_IMPULSE =" + example.Foo.IMPULSE); -print(" Foo_WARP =" + example.Foo.WARP); -print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); - -~~~~ - -## Pointers - -C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface - -~~~~ - -/* File : example.i */ -%module example -%{ -extern void add(int *, int *, int *); -%} - -~~~~ - -When wrapped, you will be able to use the functions in a natural way from javascript. For example: - -~~~~ - -// Call the add() function with some pointers -example.add(a, b, c); - -~~~~ - -// In javascript the code look like as: - -~~~~ - -a = example.new_intp(); -example.intp_assign(a,37); - -~~~~ - -- The first one creates an int-pointer instance. -- The second one assigns it the value 37. - -### C++ classes - -C++ classes are wrapped by javascript classes as well. For example, if you have this class, - -~~~~ - -class Circle -{ -public: - Circle(); - Circle(double r); - double area(); - double radius; -}; - -~~~~ - -you can use it in javascript like this: - -~~~~ - -print("Creating some objects:"); -c = new example.Circle(10); -print("area = " + c.area()); - -~~~~ - -Class data members are accessed in the same manner as C structures. - -Static class members and functions are mapped to javascript in a straight-forward manner: - -~~~~ - -class Spam { -public: - static void foo(); - static int bar; -}; - -~~~~ - -In javascript, the static member can be access in this way: - -~~~~ - -// ----- Access a static member ----- -print("\nA access of static member is" + example.Spam.Foo); // access static member as properties of the class object. - -~~~~ - -## C++ inheritance - -SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this - -~~~~ - -class A { -public: - void foo(); - virtual void bar(); -}; -class B: public A { -public: - virtual void bar(); -}; - -~~~~ - -Those classes are wrapped into a hierarchy of javascript classes that reflect the same inheritance structure. All of the usual javascript utility functions work normally: - -~~~~ - -var a = new example.A(); -a.foo(); -a.bar(); -var b = new example.B(); -b.foo(); -b.bar(); -print("b.cPtr = " + b.getCPtr()); - -~~~~ - -## C++ overloaded functions - -C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this: - -~~~~ - -void f(int val) { - std::cout << "Called f(int)." << std::endl; -} -void f(int val1, int val2) { - std::cout << "Called f(int, int)." << std::endl; -} -void f(const char* s) { - std::cout << "Called f(const char*)." << std::endl; -} - -~~~~ - -You can use them in javascript in a straightforward manner: - -~~~~ - -example.f(1); -example.f(1, 2); -example.f("bla"); - -~~~~ - -## C++ operators - -Certain C++ overloaded operators can be handled automatically by SWIG. Though, in javascript operator overloading is not possible. Instead one has to make use of the `%rename` feature. - -For example, consider a class like this: - -~~~~ - -/* File : example.h */ -#include -class Complex { -private: - double rpart, ipart; -public: - Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } - Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } - Complex &operator=(const Complex &c) { - rpart = c.rpart; - ipart = c.ipart; - return *this; - } - Complex operator+(const Complex &c) const { - return Complex(rpart+c.rpart, ipart+c.ipart); - } - Complex operator-(const Complex &c) const { - return Complex(rpart-c.rpart, ipart-c.ipart); - } - Complex operator*(const Complex &c) const { - return Complex(rpart*c.rpart - ipart*c.ipart, - rpart*c.ipart + c.rpart*ipart); - } - Complex operator-() const { - return Complex(-rpart, -ipart); - } - - double re() const { return rpart; } - double im() const { return ipart; } -}; - -~~~~ - -When wrapped, it works like you expect: - -~~~~ - -a = new example.Complex(2,3); -b = new example.Complex(-5,10); - -print ("a =" + a); -print ("b =" + b); - -c = a.plus(b); - -print("c =" + c); -print("a*b =" + a.times(b)); -print("a-c =" + a.minus(c)); - -e = example.Complex.copy(a.minus(c)); -print("e =" + e); - -// Big expression -f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); -print("f =" + f); - -~~~~ - -One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this - -~~~~ - -class Complex { -... -friend Complex operator+(double, const Complex &c); -... -}; - -~~~~ - -then SWIG ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example: - -%rename(Complex_add_dc) operator+(double, const Complex &); - -There are ways to make this operator appear as part of the class using the %extend directive. - -## C++ namespaces: - -SWIG is aware of C++ namespaces, but namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this, - -~~~~ - -%module example -namespace nspace { -extern int gcd(int x, int y); -extern double Foo; -class Circle -{ -public: - Circle(); - Circle(double r); - double area(); - double radius; - }; -} - -~~~~ - -for namespaces, you use the %feature directive in interface file. %feature attaches a new attribute to any parse tree node that matches given prototype. - -~~~~ - -/* File : example.i */ -%module example -%{ -#include "example.h" -%} -%feature("nspace", 1); -%include "example.h" - -~~~~ - -it works in javascript as follows: - -~~~~ - -print("Global variable Foo=" + example.nspace.Foo); -example.nspace.Foo = 5; -print("Variable Foo changed to " + example.nspace.Foo); -print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); -print("Creating some objects:"); -c = new example.nspace.Circle(10); -print("area = " + c.area()); - -~~~~ - -If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example: - -~~~~ - -%rename(Bar_spam) Bar::spam; -namespace Foo { - int spam(); -} -namespace Bar { - int spam(); -} - -~~~~ - -If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. -SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence. - -## C++ templates - -C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example: - -~~~~ - -/* File : example.i */ -%module example -%{ -#include "example.h" -%} -/* Let's just grab the original header file here */ -%include "example.h" - -/* Now instantiate some specific template declarations */ -%template(maxint) max; -%template(maxdouble) max; -%template(vecint) vector; -%template(vecdouble) vector; - -~~~~ - -In javascript: - -~~~~ - -//Call some templated functions -print(example.maxint(3,7)); -print(example.maxdouble(3.14,2.18)); - -// Create some class - -iv = new example.vecint(100); -dv = new example.vecdouble(1000); - -for(i=0;i<=100;i++) - iv.setitem(i,2*i); - -for(i=0;i<=1000;i++) - dv.setitem(i, 1.0/(i+1)); - -sum = 0; -for(i=0;i<=100;i++) - sum = sum + iv.getitem(i); - -print(sum); - -sum = 0.0; -for(i=0;i<=1000;i++) - sum = sum + dv.getitem(i); -print(sum); - -~~~~ - -## Exception handling - -The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into javascript exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following: - -Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the javascript extension by writing the following in an interface file: - -~~~~ - -/* File : example.i */ -%module example -%{ -#include "example.h" -%} -%include "std_string.i" - -/* Let's just grab the original header file here */ -%include "example.h" - -~~~~ - -Actually in JS there is no support for typed exceptions.For now there is support for integer and string -exception. Example for integer exception - -~~~~ - -JSValueRef jsc_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ -int arg1 = (int)JSValueToNumber(context, argv[0], NULL); -int arg2 = (int)JSValueToNumber(context, argv[1], NULL); -*exception = JSValueMakeNumber(context, 13); -int result = (int)gcd(arg1,arg2); -JSValueRef jsresult = JSValueMakeNumber(context, result); - -~~~~ - -and for string exception: - -~~~~ - -JSValueRef wrap_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ -int arg1 = (int)JSValueToNumber(context, argv[0], NULL); -int arg2 = (int)JSValueToNumber(context, argv[1], NULL); -JSStringRef message = JSStringCreateWithUTF8CString("This is a test error."); -*exception = JSValueMakeString(context, message); -JSStringRelease(message); -int result = (int)gcd(arg1,arg2); -JSValueRef jscresult = JSValueMakeNumber(context, result); -return jsresult; -} - -~~~~ - -## How to use generated modules? - -Basically there is no standard extension mechanism in Javascript. We provided a custom interpreter with extension abilities. If JSC is embedded into a custom application, one has to make use of a generated module initializer function that allows easy extension of interpreter. -The basic approach is as follows: - -### Basic Mechanism -- Creating the context -- Calling module initializer -- Evaluate Javascript - -#### Creating the context - -~~~~ - -JSGlobalContextRef context = JSGlobalContextCreate(NULL); -JSObjectRef globalObject = JSContextGetGlobalObject(context); ... -~~~~ -### Calling module initializer +// Module factory implementations -~~~~ +static Language *new_swig_javascript() { ... } - extern int example_init(JSGlobalContextRef context); - ... - example_init(context); - ... +extern "C" Language *swig_javascript(void) { ... } -~~~~ -### Evaluate Javascript +// JSEmitter implementation -~~~~ +JSEmitter::JSEmitter() { ... } -// Evaluate the javascript -char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); -JSStringRef jsScript; -if(!scriptContent) { - printf("FAIL: runme script could not be loaded.\n"); - failed = 1; - } - else { - JSValueRef ex; - jsScript = JSStringCreateWithUTF8CString(scriptContent); - JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); - if (!jsResult && ex) { - jsc_printError(context, ex, scriptPath); - failed = 1; - } - } - if (scriptContent != NULL) { - free(scriptContent); - } - JSStringRelease(jsScript); - JSGlobalContextRelease(context); - globalObject = 0; - for(std::vector::iterator it = loaded_modules.begin(); - it != loaded_modules.end(); ++it) { - HANDLE handle = *it; - dlclose(handle); - } - if (failed) { - printf("FAIL: Some tests failed.\n"); - return 1; - } -} +Template JSEmitter::getTemplate(const String *name) { ... } -~~~~ +... -## Typemaps -A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from javascript to C, you might define a typemap like this: +// JSCEmitter declaration -~~~~ +class JSCEmitter: public JSEmitter { ... }; -%typemap(in) int { - $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} - printf("Received an integer : %d\n",$1); -} -~~~~ +// JSCEmitter implementation -Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int. +JSCEmitter::JSCEmitter() { ... } -## Javascript typemaps +void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { ... } -The previous section illustrated an "in" typemap for converting javascript objects to C. A variety of different typemap methods are defined by the javascript module. For example, to convert a C integer back into a javascript object, you might define an "out" typemap like this: +... -~~~~ -%typemap(out) int { - $result = JSValueMakeNumber(context, $1); -} +// JSCEmitter factory -~~~~ +JSEmitter *swig_javascript_create_JSCEmitter() { ... } -The Javascript module makes use of Swig's unified template library. -## Typemap variables +// V8Emitter declaration -Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables: +class V8Emitter: public JSEmitter { ... }; -`$1`: -A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Javascript. -`$input`: -A javascript Object * holding a raw javascript object with an argument or variable value. +// V8Emitter implementation -`$result`: -A javascript Object * that holds the result to be returned to javascript. +V8Emitter::V8Emitter() { ... } -`$1_name`: -The parameter name that was matched. +int V8Emitter::initialize(Node *n) { ... } -`$1_type`: -The actual C datatype matched by the typemap. -`$1_ltype`: -An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of `$1_type`. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned. +// V8Emitter factory -`$symname`: -The javascript name of the wrapper function being created. +JSEmitter *swig_javascript_create_V8Emitter() { ... } -# Javascript: Specification of a Code Generator for JSC -The module implementation tries to accomplish a separation of logic and code generation by making -use of code templates. In the following, the templates are explained. +// Helper implementation (JSEmitterState, Template) -# Top Level structure +JSEmitterState::JSEmitterState() { ... } -The generated code consists of the following blocks: +... -~~~~ +Template::Template(const String *code_) { ... } - - - - - +``` -~~~~ +## Code Templates -- `RUNTIME`: runtime code generated by swig -- `HELPER_FUNCTIONS`: static, from swg-file -- `INCLUDES`: static, module property -- `FUNCTION_WRAPPERS`: dynamically growing, on method declarations -- `INITIALIZER`: dynamically growing, aggregates everything +All generated code is created on the basis of code templates. +The templates for *JavascriptCore* can be found in `Lib/javascript/jsc/javascriptcode.swg`, +for *v8* in `Lib/javascript/v8/javascriptcode.swg`. -## INCLUDES +To track the originating code template for generated code you can run -~~~~ +```shell +swig -javascript -jsc -debug-codetemplates +``` -#include - +which wraps generated code with a descriptive comment -~~~~ +```code +/* begin fragment("temlate_name") */ -`USER_DEFINED_INCLUDES`: a module property +...generated code ... -## `HELPER_FUNCTIONS` +/* end fragment("temlate_name") */ +``` -A lot of boiler-plate code can be shifted into static helper functions: +The Template class is used like this: -~~~~ +```code + Template t_register = getTemplate("jsv8_register_static_variable"); + t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim(). + print(f_init_static_wrappers); +``` -bool JS_registerClass(JSGlobalContextRef& context, JSObjectRef& parentObject,const char* className, - JSClassDefinition* definition) { - JSStringRef js_className = JSStringCreateWithUTF8CString(className); - JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); - JSObjectSetProperty(context, parentObject,js_className, classObject,kJSPropertyAttributeNone, NULL); - JSStringRelease(js_className); - return true; -} +The code template is registered to the *JSEmitter* via +`Template::replace` does simple -bool JS_registerNamespace(JSGlobalContextRef& context,JSObjectRef& namespaceObj,JSObjectRef& parentNamespace,const char* name) -{ - JSStringRef js_name = JSStringCreateWithUTF8CString(name); - JSObjectSetProperty(context, parentNamespace,js_name, namespaceObj,kJSPropertyAttributeNone, NULL); - JSStringRelease(js_name); - return true; -} - -bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) -{ - JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); - JSObjectSetProperty(context,object,js_functionName,JSObjectMakeFunctionWithCallback(context, - js_functionName, callback), kJSPropertyAttributeNone, NULL); - JSStringRelease(js_functionName); - return true; -} -bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - char buffer[256]; - char msg[512]; - int res; - JSStringGetUTF8CString(propertyName, buffer, 256); - res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); - if(res<0) { - SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); - } else { - SWIG_exception(SWIG_ERROR, msg); - } - return false; -} - -JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { - JSValueRef val; - JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); - val = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); - return val; -} - -~~~~ - -## `FUNCTION_WRAPPERS` - -There are different types of function wrappers: -- Member Functions -- Getproperty / Setproperty -- Global Functions (global/namespace/class) -- Constructors / Destructors - - -## Member Functions - -~~~~ - -JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - ${LOCALS} - ${CODE} - return jsresult; - - goto fail; - fail: - return NULL; -} - -~~~~ - -- `functionname`: the name of generated wrapper for function -- `LOCALS`: declarations for input arguments -- `CODE`: contains input marshalling, the action, and output marshalling - -## Setproperty - -~~~~ - -bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - ${LOCALS} - ${CODE} - return jsresult; - - goto fail; - fail: - return NULL; -} - -~~~~ - -- `setname`: the name of the generated wrapper for setproperty. -- `LOCALS`: declarations for input arguments -- `CODE`: contains input marshalling, and the action - -## Getproperty - -~~~~ - -JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - ${LOCALS} - ${CODE} - return jsresult; - - goto fail; - fail: - return NULL; -} - -~~~~ - -- `getname`: the name of the generated wrapper for the getproperty -- `LOCALS`: declarations for output arguments -- `CODE`: contains the action, and output marshalling - - -## Global Functions - -~~~~ - -JSStaticValue ${namespace}_values[] = { - ${jsglobalvariables} - { 0, 0, 0, 0 } -}; -JSStaticFunction ${namespace}_functions[] = { - ${jsglobalfunctions} - { 0, 0, 0 } -}; -JSClassDefinition ${namespace}_classDefinition; - -~~~~ - -## Variable declaration - -~~~~ - -{"${propertyname}",${getname}, ${setname}, kJSPropertyAttributeNone} - -~~~~ - -This is used to fill variable definition tables. -`kJSPropertyAttributeNone` is JSC specific and means that the variable has a getter and setter. -Even for read-only variables a setter is used which throws an exception. - -## Constructor - -~~~~ - -JSObjectRef _wrap_create_${classname_mangled}${overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - ${LOCALS} - ${CODE} - return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN); - - goto fail; - fail: - return NULL; -} - -~~~~ -- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` -- `LOCALS`: declarations for input arguments -- `CODE`: contains input marshalling, and the action - -## Destructors - -~~~~ - -void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) -{ - SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); - if(t && t->swigCMemOwn) delete (${type}*)(t->swigCObject); - if(t) delete t; -} - -~~~~ - -- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` - -## Initializer - -~~~~ - -bool ${modulename}_initialize(JSGlobalContextRef context) { - SWIG_InitializeModule(0); - - JSObjectRef global_object = JSContextGetGlobalObject(context); - - /* Initialize the base swig type object */ - _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; - _SwigObject_objectDefinition.staticValues = _SwigObject_values; - _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); - - /* Create objects for namespaces */ - ${create_namespaces} - - /* Create classes */ - ${initializercode} - - /* Register namespaces */ - ${register_namespaces} - - return true; -} - -~~~~ - -## Class template defintions - -A class is specified by a static part (`*_classDefinition`) and a dynamic part (`*_objectDefinition`). - -~~~~ - -${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; - ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; - ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; - ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; - ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; - ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; - JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}_objectDefinition); - SWIGTYPE_${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%} - -~~~~ - -Notes: -- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` - which is retrieved by `Swig_name_mangle(Getattr(n, "name"))` -- ClassDefinitions are built using the staticValues array and the staticFunction array. The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties to the class object. - -## Inheritance - -~~~~ - -{${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef}; - -~~~~ - -- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` -- Note: multiple inheritance is not possible; thus we will always take the first parent class - -## Namespaces - -Namespaces are objects without class templates. i.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. - -~~~~ - - ${namespace}_classDefinition.staticFunctions = ${namespace}_functions; - ${namespace}_classDefinition.staticValues = ${namespace}_values; - JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL); - -~~~~ - -## Registration - -The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. - -* Global functions - -~~~~ - -JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper} - -~~~~ - -* Classes - -~~~~ - -JS_registerClass(context, ${namespace}_object, "${classname}", &${classname_mangled}_classDefinition) - -~~~~ - -Note: every class template has an associated constructor function wrapper, which is registered here - -* Namespaces - -~~~~ - -${namespace}_classDefinition.staticFunctions = ${namespace}_functions; -${namespace}_classDefinition.staticValues = ${namespace}_values; -JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL); - -~~~~ - -Namespaces are registered using: - -~~~~ - -JS_registerNamespace(context, ${namespace}_object, ${parent_namespace}_object, "${namespace}"); - -~~~~ +## Emitter diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 70bb12f68..b8d36e21f 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -23,6 +23,17 @@ bool js_template_enable_debug = false; #define DTOR "dtor" #define ARGCOUNT "wrap:argc" +// keys for global state variables +#define CREATE_NAMESPACES "create_namespaces" +#define REGISTER_NAMESPACES "register_namespaces" +#define INITIALIZER "initializer" + +// keys for class scoped state variables +#define MEMBER_VARIABLES "member_variables" +#define MEMBER_FUNCTIONS "member_functions" +#define STATIC_FUNCTIONS "static_functions" +#define STATIC_VARIABLES "static_variables" + /** * A convenience class to manage state variables for emitters. * The implementation delegates to swig Hash DOHs and provides @@ -274,15 +285,15 @@ protected: File *f_wrappers; }; -/********************************************************************** - * JAVASCRIPT: swig module implementation - **********************************************************************/ - /* factory methods for concrete JSEmitters: */ JSEmitter *swig_javascript_create_JSCEmitter(); JSEmitter *swig_javascript_create_V8Emitter(); +/********************************************************************** + * JAVASCRIPT: swig module implementation + **********************************************************************/ + class JAVASCRIPT:public Language { public: @@ -1411,17 +1422,6 @@ private: }; -// keys for global state variables -#define CREATE_NAMESPACES "create_namespaces" -#define REGISTER_NAMESPACES "register_namespaces" -#define INITIALIZER "initializer" - -// keys for class scoped state variables -#define MEMBER_VARIABLES "member_variables" -#define MEMBER_FUNCTIONS "member_functions" -#define STATIC_FUNCTIONS "static_functions" -#define STATIC_VARIABLES "static_variables" - JSCEmitter::JSCEmitter() : JSEmitter(), NULL_STR(NewString("NULL")), From 02c55fc52fb30da3cec7188b64d456c7dcf8fc9f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 13 Feb 2014 21:18:06 +0100 Subject: [PATCH 233/352] Next iteration on creating a documentation for the Javascript module. --- Doc/Manual/Javascript.md | 202 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 196 insertions(+), 6 deletions(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 77b7e086b..e1622aa88 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -1,7 +1,7 @@ % SWIG and Javascript This chapter describes SWIG's support of Javascript. - +It does not cover SWIG basics only information that is specific to this module. # Overview @@ -17,7 +17,7 @@ Extending a general purpose web-browser is not possible as this would be severe With [WebKit](http://www.webkit.org/) there is an modern and open-source browser implementations available which can be embedded into an application. At the moment, [Chromium Embedded Framework](http://code.google.com/p/chromiumembedded/) -can not extended as CEF does not provide access to the V8 engine, but instead comes with +can not be extended as CEF does not provide access to the V8 engine, but instead comes with its own extension mechanism. SWIG Javasript currently supports **JavascriptCore**, the Javascript engine used by `Safari`, @@ -69,6 +69,15 @@ and for v8: void example_initialize (v8::Handle exports) ``` +## Missing features + +The Javascript module is not yet as mature as other modules and some things are still missing. +As it makes use of Swigs Unified typemap library (UTL), many typemaps are inherited. + +- Director support +- TODO: there is more + + # Compilation and Linking ## Installation @@ -113,6 +122,7 @@ First you would create the wrapper using SWIG: ## Embedded Webkit +TODO: Here a minimal example of how to implement # Implementation @@ -122,8 +132,9 @@ to be able to generate code for different Javascript interpreters. ## Module Source Code -The Javascript module is implemented in `Source/Modules/javascript.cxx`. It contains a SWIG Language class which does represents the module's entry point to the swig engine. -It implements the `Language` interface and dispatches the code generation to a `JSEmitter` instance, `V8Emitter` or `JSCEmitter`. Additionally there are some helpers: `Template`, for templated code generation, and `JSEmitterState`, which is used to manage state information during AST traversal. To find your way through this huge source file, here is a rough map: +The Javascript module is implemented in `Source/Modules/javascript.cxx`. +It dispatches the code generation to a `JSEmitter` instance, `V8Emitter` or `JSCEmitter`. Additionally there are some helpers: `Template`, for templated code generation, and `JSEmitterState`, which is used to manage state information during AST traversal. +This is a rough map shall make it easier to find a way through this huge source file: ```code // module wide defines @@ -257,8 +268,187 @@ The Template class is used like this: print(f_init_static_wrappers); ``` -The code template is registered to the *JSEmitter* via -`Template::replace` does simple +A code template is registered with the *JSEmitter* via `fragment(name, "template")`, e.g., + +```code +%fragment ("jsc_variable_declaration", "templates") +%{ + {"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone}, +%} +``` + +`Template` creates a copy of that string and `Template::replace` uses Swig's `Replaceall` +to replace variables in the template. `Template::trim` can be used to eliminate +leading and trailing whitespaces. `Template::print` is used to write the final template string +to a Swig `DOH` (based on `Printv`). All methods allow chaining. ## Emitter + +The Javascript module delegates code generation to a `JSEmitter` instance. +The following extract shows the essential interface: + +```code +class JSEmitter { + ... + + /** + * Opens output files and temporary output DOHs. + */ + virtual int initialize(Node *n); + + /** + * Writes all collected code into the output file(s). + */ + virtual int dump(Node *n) = 0; + + /** + * Cleans up all open output DOHs. + */ + virtual int close() = 0; + + ... + + /** + * Invoked at the beginning of the classHandler. + */ + virtual int enterClass(Node *); + + /** + * Invoked at the end of the classHandler. + */ + virtual int exitClass(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the variableHandler. + */ + virtual int enterVariable(Node *); + + /** + * Invoked at the end of the variableHandler. + */ + virtual int exitVariable(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the functionHandler. + */ + virtual int enterFunction(Node *); + + /** + * Invoked at the end of the functionHandler. + */ + virtual int exitFunction(Node *) { + return SWIG_OK; + }; + + /** + * Invoked by functionWrapper callback after call to Language::functionWrapper. + */ + virtual int emitWrapperFunction(Node *n); + + /** + * Invoked from constantWrapper after call to Language::constantWrapper. + **/ + virtual int emitConstant(Node *n); + + /** + * Registers a given code snippet for a given key name. + * + * This method is called by the fragmentDirective handler + * of the JAVASCRIPT language module. + **/ + int registerTemplate(const String *name, const String *code); + + /** + * Retrieve the code template registered for a given name. + */ + Template getTemplate(const String *name); + + State &getState(); + + ... + +} +``` + +The module calls `initialize`, `dump`, and `close` from within the `top` method: + +```code +int JAVASCRIPT::top(Node *n) { + emitter->initialize(n); + + Language::top(n); + + emitter->dump(n); + emitter->close(); + + return SWIG_OK; +} +``` + +The methods `enterClass` and `exitClass` are called from within the `classHandler` method: + +```code +int JAVASCRIPT::classHandler(Node *n) { + + emitter->enterClass(n); + Language::classHandler(n); + emitter->exitClass(n); + + return SWIG_OK; +} +``` + +In `enterClass` the emitter stores state information that is necessary when processing class members. In `exitClass` the wrapper code for the whole class is generated. + + +## Emitter states + +For storing information during the AST traversal the emitter provides a `JSEmitterState` with +different slots to store data representing the scopes global, class, function, and variable. + +```code +class JSEmitterState { + +public: + + JSEmitterState(); + + ~JSEmitterState(); + + DOH *global(); + + DOH *global(const char* key, DOH *initial = 0); + + DOH *clazz(bool reset = false); + + DOH *clazz(const char* key, DOH *initial = 0); + + DOH *function(bool reset = false); + + DOH *function(const char* key, DOH *initial = 0); + + DOH *variable(bool reset = false); + + DOH *variable(const char* key, DOH *initial = 0); + + static int IsSet(DOH *val); + + ... +}; +``` + +When entering a scope, such as in `enterClass`, the corresponding state is reset and new data +is stored: + +```code + state.clazz(RESET); + state.clazz(NAME, Getattr(n, "sym:name")); +``` + +State information can be retrieved using `state.clazz(NAME)` or +with `Getattr` on `state.clazz()` which actually returns a `Hash` instance. From fa8b350cd67a8850a866ee52250a6955ef17699f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 14 Feb 2014 00:00:12 +0100 Subject: [PATCH 234/352] More Javascript module documentation. --- Doc/Manual/Javascript.md | 425 ++++++++++++++++++--------------------- 1 file changed, 193 insertions(+), 232 deletions(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index e1622aa88..b571e05c3 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -1,9 +1,9 @@ -% SWIG and Javascript +# SWIG and Javascript This chapter describes SWIG's support of Javascript. It does not cover SWIG basics only information that is specific to this module. -# Overview +## Overview JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. @@ -14,42 +14,36 @@ Native Javascript extensions can be used for applications that embed a web-brows that embed a Javascript engine (such as *node.js*). Extending a general purpose web-browser is not possible as this would be severe security issue. -With [WebKit](http://www.webkit.org/) there is an modern and open-source browser -implementations available which can be embedded into an application. -At the moment, [Chromium Embedded Framework](http://code.google.com/p/chromiumembedded/) -can not be extended as CEF does not provide access to the V8 engine, but instead comes with -its own extension mechanism. - SWIG Javasript currently supports **JavascriptCore**, the Javascript engine used by `Safari`, and **v8**, which is used by `Chromium` and `node.js`. -# Preliminaries +With [WebKit](http://www.webkit.org/) there is a modern browser +implementation available as open-source which can be embedded into an application. +Unfortunately, [Chromium Embedded Framework](http://code.google.com/p/chromiumembedded/) +does not provide access to the native V8 engine, making it impossible to extend the engine +using the Javascript module. -# Running SWIG +## Preliminaries + +### Running SWIG Suppose that you defined a SWIG module such as the following: -```code -%module example -%{ -#include "example.h" -%} -int gcd(int x, int y); -extern double Foo; -``` + %module example + %{ + #include "example.h" + %} + int gcd(int x, int y); + extern double Foo; To build a Javascript module, run SWIG using the `-javascript` option and a desired target engine `-jsc` or `-v8`. -```shell -$ swig -javascript -jsc example.i -``` + $ swig -javascript -jsc example.i If building a C++ extension, add the -c++ option: -```shell -$ swig -c++ -javascript -jsc example.i -``` + $ swig -c++ -javascript -jsc example.i This creates a C/C++ source file example_wrap.c or example_wrap.cxx. The generated C source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application to create an extension module. @@ -59,15 +53,11 @@ To change this, you can use the -o option. The wrapped module will export one function which must be called to register the module with the Javascript interpreter. For example, if your module is named `example` the corresponding initializer for JavascriptCore would be -```code -bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports) -``` + bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports) and for v8: -```code -void example_initialize (v8::Handle exports) -``` + void example_initialize (v8::Handle exports) ## Missing features @@ -75,26 +65,22 @@ The Javascript module is not yet as mature as other modules and some things are As it makes use of Swigs Unified typemap library (UTL), many typemaps are inherited. - Director support -- TODO: there is more +- TODO: hmpf... I suppose there is more +## Compilation and Linking -# Compilation and Linking +### Installation -## Installation - - - -## Dealing with `v8` version incompatibilities +### Dealing with `v8` version incompatibilities Unfortunately, v8 does not provide pre-processor macros do detect which version you link to. Therefore, you have to provide this information manually. - -# Integration +## Integration This should give a short overview how to integrate your module in different environments: as a `node.js` module, and as an extension for an embedded Chromium. -## Creating `node.js` Extensions +### Creating `node.js` Extensions As `v8` is written in C++ and comes as a C++ library it is crucial to compile your module using the same compiler flags as used for building v8. To make things easier, `node.js` provides a build tool called `node-gyp`. @@ -103,138 +89,132 @@ This expects configuration file named `binding.gyp` which is basically in JSON f conforms to the same format that is used with Google's build-tool `gyp`. `binding.gyp`: -```code -{ - "targets": [ + { - "target_name": "example", - "sources": [ "example.cxx", "example_wrap.cxx" ] + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] } - ] -} -``` First you would create the wrapper using SWIG: -```shell -``` - -## Embedded Webkit +### Embedded Webkit TODO: Here a minimal example of how to implement -# Implementation +## Implementation The Javascript Module implementation has take a very different approach than other modules to be able to generate code for different Javascript interpreters. -## Module Source Code +### Module Source Code The Javascript module is implemented in `Source/Modules/javascript.cxx`. It dispatches the code generation to a `JSEmitter` instance, `V8Emitter` or `JSCEmitter`. Additionally there are some helpers: `Template`, for templated code generation, and `JSEmitterState`, which is used to manage state information during AST traversal. This is a rough map shall make it easier to find a way through this huge source file: -```code -// module wide defines + // module wide defines -#define NAME "name" + #define NAME "name" -... + ... -// Helper class declarations -class JSEmitterState { ... }; + // Helper class declarations + class JSEmitterState { ... }; -class Template { ... }; + class Template { ... }; -// JSEmitter declaration + // JSEmitter declaration -class JSEmitter { ... }; + class JSEmitter { ... }; -// Emitter factory declarations + // Emitter factory declarations -JSEmitter *swig_javascript_create_JSCEmitter(); -JSEmitter *swig_javascript_create_V8Emitter(); + JSEmitter *swig_javascript_create_JSCEmitter(); + JSEmitter *swig_javascript_create_V8Emitter(); -// Javascript module class declaration + // Javascript module class declaration -class JAVASCRIPT:public Language { ... }; + class JAVASCRIPT:public Language { ... }; -// Javascript module function definitions + // Javascript module function definitions -int JAVASCRIPT::functionWrapper(Node *n) { ... } + int JAVASCRIPT::functionWrapper(Node *n) { ... } -... + ... -// Module factory implementations + // Module factory implementations -static Language *new_swig_javascript() { ... } + static Language *new_swig_javascript() { ... } -extern "C" Language *swig_javascript(void) { ... } + extern "C" Language *swig_javascript(void) { ... } -// JSEmitter implementation + // JSEmitter implementation -JSEmitter::JSEmitter() { ... } + JSEmitter::JSEmitter() { ... } -Template JSEmitter::getTemplate(const String *name) { ... } + Template JSEmitter::getTemplate(const String *name) { ... } -... + ... -// JSCEmitter declaration + // JSCEmitter declaration -class JSCEmitter: public JSEmitter { ... }; + class JSCEmitter: public JSEmitter { ... }; -// JSCEmitter implementation + // JSCEmitter implementation -JSCEmitter::JSCEmitter() { ... } + JSCEmitter::JSCEmitter() { ... } -void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { ... } + void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { ... } -... + ... -// JSCEmitter factory + // JSCEmitter factory -JSEmitter *swig_javascript_create_JSCEmitter() { ... } + JSEmitter *swig_javascript_create_JSCEmitter() { ... } -// V8Emitter declaration + // V8Emitter declaration -class V8Emitter: public JSEmitter { ... }; + class V8Emitter: public JSEmitter { ... }; -// V8Emitter implementation + // V8Emitter implementation -V8Emitter::V8Emitter() { ... } + V8Emitter::V8Emitter() { ... } -int V8Emitter::initialize(Node *n) { ... } + int V8Emitter::initialize(Node *n) { ... } -// V8Emitter factory + // V8Emitter factory -JSEmitter *swig_javascript_create_V8Emitter() { ... } + JSEmitter *swig_javascript_create_V8Emitter() { ... } -// Helper implementation (JSEmitterState, Template) + // Helper implementation (JSEmitterState, Template) -JSEmitterState::JSEmitterState() { ... } + JSEmitterState::JSEmitterState() { ... } -... + ... -Template::Template(const String *code_) { ... } + Template::Template(const String *code_) { ... } -``` -## Code Templates +### Code Templates All generated code is created on the basis of code templates. The templates for *JavascriptCore* can be found in `Lib/javascript/jsc/javascriptcode.swg`, @@ -242,213 +222,194 @@ for *v8* in `Lib/javascript/v8/javascriptcode.swg`. To track the originating code template for generated code you can run -```shell -swig -javascript -jsc -debug-codetemplates -``` + $ swig -javascript -jsc -debug-codetemplates which wraps generated code with a descriptive comment -```code -/* begin fragment("temlate_name") */ + /* begin fragment("temlate_name") */ -...generated code ... + ...generated code ... -/* end fragment("temlate_name") */ -``` + /* end fragment("temlate_name") */ The Template class is used like this: -```code - Template t_register = getTemplate("jsv8_register_static_variable"); - t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)) - .trim(). - print(f_init_static_wrappers); -``` + Template t_register = getTemplate("jsv8_register_static_variable"); + t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim(). + print(f_init_static_wrappers); A code template is registered with the *JSEmitter* via `fragment(name, "template")`, e.g., -```code -%fragment ("jsc_variable_declaration", "templates") -%{ - {"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone}, -%} -``` + %fragment ("jsc_variable_declaration", "templates") + %{ + {"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone}, + %} `Template` creates a copy of that string and `Template::replace` uses Swig's `Replaceall` to replace variables in the template. `Template::trim` can be used to eliminate leading and trailing whitespaces. `Template::print` is used to write the final template string to a Swig `DOH` (based on `Printv`). All methods allow chaining. - -## Emitter +### Emitter The Javascript module delegates code generation to a `JSEmitter` instance. The following extract shows the essential interface: -```code -class JSEmitter { - ... + class JSEmitter { + ... - /** - * Opens output files and temporary output DOHs. - */ - virtual int initialize(Node *n); + /** + * Opens output files and temporary output DOHs. + */ + virtual int initialize(Node *n); - /** - * Writes all collected code into the output file(s). - */ - virtual int dump(Node *n) = 0; + /** + * Writes all collected code into the output file(s). + */ + virtual int dump(Node *n) = 0; - /** - * Cleans up all open output DOHs. - */ - virtual int close() = 0; + /** + * Cleans up all open output DOHs. + */ + virtual int close() = 0; - ... + ... - /** - * Invoked at the beginning of the classHandler. - */ - virtual int enterClass(Node *); + /** + * Invoked at the beginning of the classHandler. + */ + virtual int enterClass(Node *); - /** - * Invoked at the end of the classHandler. - */ - virtual int exitClass(Node *) { - return SWIG_OK; - }; + /** + * Invoked at the end of the classHandler. + */ + virtual int exitClass(Node *) { + return SWIG_OK; + }; - /** - * Invoked at the beginning of the variableHandler. - */ - virtual int enterVariable(Node *); + /** + * Invoked at the beginning of the variableHandler. + */ + virtual int enterVariable(Node *); - /** - * Invoked at the end of the variableHandler. - */ - virtual int exitVariable(Node *) { - return SWIG_OK; - }; + /** + * Invoked at the end of the variableHandler. + */ + virtual int exitVariable(Node *) { + return SWIG_OK; + }; - /** - * Invoked at the beginning of the functionHandler. - */ - virtual int enterFunction(Node *); + /** + * Invoked at the beginning of the functionHandler. + */ + virtual int enterFunction(Node *); - /** - * Invoked at the end of the functionHandler. - */ - virtual int exitFunction(Node *) { - return SWIG_OK; - }; + /** + * Invoked at the end of the functionHandler. + */ + virtual int exitFunction(Node *) { + return SWIG_OK; + }; - /** - * Invoked by functionWrapper callback after call to Language::functionWrapper. - */ - virtual int emitWrapperFunction(Node *n); + /** + * Invoked by functionWrapper callback after call to Language::functionWrapper. + */ + virtual int emitWrapperFunction(Node *n); - /** - * Invoked from constantWrapper after call to Language::constantWrapper. - **/ - virtual int emitConstant(Node *n); + /** + * Invoked from constantWrapper after call to Language::constantWrapper. + **/ + virtual int emitConstant(Node *n); - /** - * Registers a given code snippet for a given key name. - * - * This method is called by the fragmentDirective handler - * of the JAVASCRIPT language module. - **/ - int registerTemplate(const String *name, const String *code); + /** + * Registers a given code snippet for a given key name. + * + * This method is called by the fragmentDirective handler + * of the JAVASCRIPT language module. + **/ + int registerTemplate(const String *name, const String *code); - /** - * Retrieve the code template registered for a given name. - */ - Template getTemplate(const String *name); + /** + * Retrieve the code template registered for a given name. + */ + Template getTemplate(const String *name); - State &getState(); + State &getState(); - ... + ... -} -``` + } The module calls `initialize`, `dump`, and `close` from within the `top` method: -```code -int JAVASCRIPT::top(Node *n) { - emitter->initialize(n); + int JAVASCRIPT::top(Node *n) { + emitter->initialize(n); - Language::top(n); + Language::top(n); - emitter->dump(n); - emitter->close(); + emitter->dump(n); + emitter->close(); - return SWIG_OK; -} -``` + return SWIG_OK; + } The methods `enterClass` and `exitClass` are called from within the `classHandler` method: -```code -int JAVASCRIPT::classHandler(Node *n) { + int JAVASCRIPT::classHandler(Node *n) { - emitter->enterClass(n); - Language::classHandler(n); - emitter->exitClass(n); + emitter->enterClass(n); + Language::classHandler(n); + emitter->exitClass(n); - return SWIG_OK; -} -``` + return SWIG_OK; + } In `enterClass` the emitter stores state information that is necessary when processing class members. In `exitClass` the wrapper code for the whole class is generated. -## Emitter states +### Emitter states For storing information during the AST traversal the emitter provides a `JSEmitterState` with different slots to store data representing the scopes global, class, function, and variable. -```code -class JSEmitterState { + class JSEmitterState { -public: + public: - JSEmitterState(); + JSEmitterState(); - ~JSEmitterState(); + ~JSEmitterState(); - DOH *global(); + DOH *global(); - DOH *global(const char* key, DOH *initial = 0); + DOH *global(const char* key, DOH *initial = 0); - DOH *clazz(bool reset = false); + DOH *clazz(bool reset = false); - DOH *clazz(const char* key, DOH *initial = 0); + DOH *clazz(const char* key, DOH *initial = 0); - DOH *function(bool reset = false); + DOH *function(bool reset = false); - DOH *function(const char* key, DOH *initial = 0); + DOH *function(const char* key, DOH *initial = 0); - DOH *variable(bool reset = false); + DOH *variable(bool reset = false); - DOH *variable(const char* key, DOH *initial = 0); + DOH *variable(const char* key, DOH *initial = 0); - static int IsSet(DOH *val); + static int IsSet(DOH *val); - ... -}; -``` + ... + }; When entering a scope, such as in `enterClass`, the corresponding state is reset and new data is stored: -```code - state.clazz(RESET); - state.clazz(NAME, Getattr(n, "sym:name")); -``` + state.clazz(RESET); + state.clazz(NAME, Getattr(n, "sym:name")); State information can be retrieved using `state.clazz(NAME)` or with `Getattr` on `state.clazz()` which actually returns a `Hash` instance. From e829ea601f573b96efdf0e1ed602d90a7d39e29f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 14 Feb 2014 00:00:37 +0100 Subject: [PATCH 235/352] Add Javascript to chapters. --- Doc/Manual/chapters | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/Manual/chapters b/Doc/Manual/chapters index 40e227164..427ec4fa7 100644 --- a/Doc/Manual/chapters +++ b/Doc/Manual/chapters @@ -22,6 +22,7 @@ D.html Go.html Guile.html Java.html +Javascript.html Lisp.html Lua.html Modula3.html From 8148b017f879f272616c8bb36b6bcd60232f9c4f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 14 Feb 2014 00:01:15 +0100 Subject: [PATCH 236/352] Add a pandoc filter to create compatible html. --- Doc/Manual/pandoc_filter.py | 59 +++++++++++++++++++++++++++++++++ Doc/Manual/pandoc_template.html | 54 +++--------------------------- 2 files changed, 63 insertions(+), 50 deletions(-) create mode 100755 Doc/Manual/pandoc_filter.py diff --git a/Doc/Manual/pandoc_filter.py b/Doc/Manual/pandoc_filter.py new file mode 100755 index 000000000..81b259936 --- /dev/null +++ b/Doc/Manual/pandoc_filter.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python + +""" +Pandoc filter that changes pandoc default HTML output for codeblocks +to match SWIG's format: + +
+
...
+
+ +""" + +from pandocfilters import toJSONFilter, stringify, walk, RawBlock, Div, Str +import sys +import json +import re + +global the_title + +def html(x): + return RawBlock('html', x) + +SHELL = re.compile(r"\s*[$]") + +def codeblocks(key, value, format, meta): + if key == 'CodeBlock': + [[id, classes, kvs], contents] = value + if format == "html" or format == "html5": + newcontents = [html('
\n' + contents + '
')] + + if contents.startswith("$"): + classes.append("shell") + + if len(classes) == 0: + classes.append("code") + + return Div([id, classes, kvs], newcontents) + if key == 'Header': + if value[0] == 1: + global the_title + the_title = stringify(value) + value[1][0] = "" + +def set_title(unMeta): + global the_title + unMeta["title"] = {"t": "MetaInlines", "c": [Str(the_title)]} + +def __toJSONFilter(action): + doc = json.loads(sys.stdin.read()) + if len(sys.argv) > 1: + format = sys.argv[1] + else: + format = "" + altered = walk(doc, action, format, doc[0]['unMeta']) + set_title(altered[0]['unMeta']) + json.dump(altered, sys.stdout) + +if __name__ == "__main__": + __toJSONFilter(codeblocks) diff --git a/Doc/Manual/pandoc_template.html b/Doc/Manual/pandoc_template.html index 390bfc51c..d8cbc12ad 100644 --- a/Doc/Manual/pandoc_template.html +++ b/Doc/Manual/pandoc_template.html @@ -1,56 +1,10 @@ - - + + - - - -$for(author-meta)$ - -$endfor$ -$if(date-meta)$ - -$endif$ - $if(title-prefix)$$title-prefix$ - $endif$$if(pagetitle)$$pagetitle$$endif$ -$if(highlighting-css)$ - -$endif$ -$for(css)$ - -$endfor$ -$if(math)$ - $math$ -$endif$ -$for(header-includes)$ - $header-includes$ -$endfor$ + + $pagetitle$ -$for(include-before)$ -$include-before$ -$endfor$ -$if(title)$ -
-

$title$

-$for(author)$ -

$author$

-$endfor$ -$if(date)$ -

$date$

-$endif$ -
-$endif$ -$if(toc)$ -
-$toc$ -
-$endif$ -
$body$ -
-$for(include-after)$ -$include-after$ -$endfor$ From 915b7094331bf99f5cf6ed31d5747d10ae1bebb9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 14 Feb 2014 00:02:05 +0100 Subject: [PATCH 237/352] Not a real change. Using a macro to reset JSEmitterStates for the sake of readability. --- Source/Modules/javascript.cxx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index b8d36e21f..63994c029 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -34,6 +34,8 @@ bool js_template_enable_debug = false; #define STATIC_FUNCTIONS "static_functions" #define STATIC_VARIABLES "static_variables" +#define RESET true + /** * A convenience class to manage state variables for emitters. * The implementation delegates to swig Hash DOHs and provides @@ -723,7 +725,7 @@ int JSEmitter::emitWrapperFunction(Node *n) { } int JSEmitter::enterClass(Node *n) { - state.clazz(true); + state.clazz(RESET); state.clazz(NAME, Getattr(n, "sym:name")); state.clazz("nspace", current_namespace); @@ -755,7 +757,7 @@ int JSEmitter::enterClass(Node *n) { } int JSEmitter::enterFunction(Node *n) { - state.function(true); + state.function(RESET); state.function(NAME, Getattr(n, "sym:name")); if(Equal(Getattr(n, "storage"), "static")) { SetFlag(state.function(), IS_STATIC); @@ -765,7 +767,7 @@ int JSEmitter::enterFunction(Node *n) { int JSEmitter::enterVariable(Node *n) { // reset the state information for variables. - state.variable(true); + state.variable(RESET); // Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings. if (Equal(Getattr(n, "view"), "memberconstantHandler")) { From 1fca61c59ad7a825725b76d394de688774f296e8 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 14 Feb 2014 09:00:04 +0100 Subject: [PATCH 238/352] Conitnued documenting the Javascript module. --- Doc/Manual/Javascript.md | 109 +++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 44 deletions(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index b571e05c3..3525df5fe 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -14,14 +14,10 @@ Native Javascript extensions can be used for applications that embed a web-brows that embed a Javascript engine (such as *node.js*). Extending a general purpose web-browser is not possible as this would be severe security issue. -SWIG Javasript currently supports **JavascriptCore**, the Javascript engine used by `Safari`, -and **v8**, which is used by `Chromium` and `node.js`. +SWIG Javasript currently supports **JavascriptCore**, the Javascript engine used by `Safari/Webkit`, and **v8**, which is used by `Chromium` and `node.js`. -With [WebKit](http://www.webkit.org/) there is a modern browser +[WebKit](http://www.webkit.org/) is a modern browser implementation available as open-source which can be embedded into an application. -Unfortunately, [Chromium Embedded Framework](http://code.google.com/p/chromiumembedded/) -does not provide access to the native V8 engine, making it impossible to extend the engine -using the Javascript module. ## Preliminaries @@ -59,33 +55,42 @@ and for v8: void example_initialize (v8::Handle exports) -## Missing features +### Future work The Javascript module is not yet as mature as other modules and some things are still missing. As it makes use of Swigs Unified typemap library (UTL), many typemaps are inherited. +We could work on that if requested: -- Director support -- TODO: hmpf... I suppose there is more +- More typemaps: compared to other modules there are only a few typemaps implemented. + For instance a lot of the `std_*.i` typemaps are missing, such as `std_iostream`, for instance. -## Compilation and Linking +- Director support: this would allow to extend a C++ abstract base class in Javascript. + A pragmatic intermediate step for the most important usecase + would be to support Javascript callbacks as arguments. -### Installation +- We will try to find a way into + [Chromium Embedded Framework (CEF)](http://code.google.com/p/chromiumembedded/). + CEF is also open-source and available for all platforms. + However, at the moment it does not provide access to the native V8 engine, + making it impossible to extend the engine using the extensions created with this module. -### Dealing with `v8` version incompatibilities - -Unfortunately, v8 does not provide pre-processor macros do detect which version you link to. -Therefore, you have to provide this information manually. ## Integration -This should give a short overview how to integrate your module in different environments: as a `node.js` module, and as an extension for an embedded Chromium. +This should give a short overview how to integrate your module in different environments: as a `node.js` module, and as an extension for an embedded Webkit. ### Creating `node.js` Extensions -As `v8` is written in C++ and comes as a C++ library it is crucial to compile your module using the -same compiler flags as used for building v8. To make things easier, `node.js` provides a build tool called `node-gyp`. +To install `node.js` you can download an installer from their +[web-site](https://launchpad.net/~chris-lea/+archive/node.js) for all platforms. -This expects configuration file named `binding.gyp` which is basically in JSON format and +For Ubuntu there is also a [PPA](https://launchpad.net/~chris-lea/+archive/node.js/) available. + +As `v8` is written in C++ and comes as a C++ library it is crucial to compile your module +using the same compiler flags as used for building v8. +To make things easier, `node.js` provides a build tool called `node-gyp`. + +This expects a configuration file named `binding.gyp` which is basically in JSON format and conforms to the same format that is used with Google's build-tool `gyp`. `binding.gyp`: @@ -99,12 +104,29 @@ conforms to the same format that is used with Google's build-tool `gyp`. ] } -First you would create the wrapper using SWIG: +First create the wrapper using SWIG: + $ swig -javascript -node -c++ example.cxx + +Then run `node-gyp` + + $ node-gyp + +This will create a `build` folder containing the native module. +To use the extension you have to require it in your javascript source file. + + require("./build/Release/example") ### Embedded Webkit -TODO: Here a minimal example of how to implement +Webkit is built-in OSX and available as library for GTK. + +#### OSX + + +#### GTK + + ## Implementation @@ -112,106 +134,105 @@ The Javascript Module implementation has take a very different approach than oth to be able to generate code for different Javascript interpreters. -### Module Source Code +### Source Code The Javascript module is implemented in `Source/Modules/javascript.cxx`. It dispatches the code generation to a `JSEmitter` instance, `V8Emitter` or `JSCEmitter`. Additionally there are some helpers: `Template`, for templated code generation, and `JSEmitterState`, which is used to manage state information during AST traversal. -This is a rough map shall make it easier to find a way through this huge source file: +This rough map shall make it easier to find a way through this huge source file: // module wide defines #define NAME "name" - ... - // Helper class declarations + // ############################### + // # Helper class declarations + class JSEmitterState { ... }; class Template { ... }; - - // JSEmitter declaration + // ############################### + // # JSEmitter declaration class JSEmitter { ... }; - // Emitter factory declarations JSEmitter *swig_javascript_create_JSCEmitter(); JSEmitter *swig_javascript_create_V8Emitter(); + // ############################### + // # Javascript module - // Javascript module class declaration + // Javascript module declaration class JAVASCRIPT:public Language { ... }; - - // Javascript module function definitions + // Javascript module implementation int JAVASCRIPT::functionWrapper(Node *n) { ... } - ... - - // Module factory implementations + // Module factory implementation static Language *new_swig_javascript() { ... } extern "C" Language *swig_javascript(void) { ... } - - // JSEmitter implementation + // ############################### + // # JSEmitter base implementation JSEmitter::JSEmitter() { ... } Template JSEmitter::getTemplate(const String *name) { ... } - ... + // ############################### + // # JSCEmitter // JSCEmitter declaration class JSCEmitter: public JSEmitter { ... }; - // JSCEmitter implementation JSCEmitter::JSCEmitter() { ... } void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { ... } - ... - // JSCEmitter factory JSEmitter *swig_javascript_create_JSCEmitter() { ... } + // ############################### + // # V8Emitter + // V8Emitter declaration class V8Emitter: public JSEmitter { ... }; - // V8Emitter implementation V8Emitter::V8Emitter() { ... } int V8Emitter::initialize(Node *n) { ... } - // V8Emitter factory JSEmitter *swig_javascript_create_V8Emitter() { ... } - // Helper implementation (JSEmitterState, Template) + // ############################### + // # Helper implementation (JSEmitterState, Template) JSEmitterState::JSEmitterState() { ... } - ... Template::Template(const String *code_) { ... } + ... ### Code Templates From 68472802721264ec8adee4f80ce7576eb3dd1a3e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 14 Feb 2014 09:02:37 +0100 Subject: [PATCH 239/352] Pandoc filter detects shell blocks when not explicitely given. Considered as shell if the first character is '$', as in $ swig -javascript Alternatively you can specify the class explicitely: ```shell swig -javascript ``` --- Doc/Manual/pandoc_filter.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Doc/Manual/pandoc_filter.py b/Doc/Manual/pandoc_filter.py index 81b259936..f1e84904a 100755 --- a/Doc/Manual/pandoc_filter.py +++ b/Doc/Manual/pandoc_filter.py @@ -15,12 +15,11 @@ import sys import json import re -global the_title - def html(x): return RawBlock('html', x) SHELL = re.compile(r"\s*[$]") +the_title = "" def codeblocks(key, value, format, meta): if key == 'CodeBlock': @@ -28,21 +27,19 @@ def codeblocks(key, value, format, meta): if format == "html" or format == "html5": newcontents = [html('
\n' + contents + '
')] - if contents.startswith("$"): - classes.append("shell") - if len(classes) == 0: - classes.append("code") + if contents.startswith("$"): + classes.append("shell") + else: + classes.append("code") return Div([id, classes, kvs], newcontents) if key == 'Header': if value[0] == 1: - global the_title the_title = stringify(value) value[1][0] = "" def set_title(unMeta): - global the_title unMeta["title"] = {"t": "MetaInlines", "c": [Str(the_title)]} def __toJSONFilter(action): From 05146e2aed5b8e9df390acdd12b6e5cda2ed2e00 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 14 Feb 2014 13:04:21 +0100 Subject: [PATCH 240/352] Documented extending Node.js and Webkit's Javascript engine. --- Doc/Manual/Javascript.md | 78 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 3525df5fe..11c9f7333 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -77,7 +77,7 @@ We could work on that if requested: ## Integration -This should give a short overview how to integrate your module in different environments: as a `node.js` module, and as an extension for an embedded Webkit. +This should give a short introduction to integrating your module in different environments: as a `node.js` module, and as an extension for an embedded Webkit. ### Creating `node.js` Extensions @@ -117,15 +117,88 @@ To use the extension you have to require it in your javascript source file. require("./build/Release/example") + ### Embedded Webkit -Webkit is built-in OSX and available as library for GTK. +Webkit is built-in for OSX and available as library for GTK. + #### OSX +There is general information about programming with WebKit on +[Apple Developer Documentation](https://developer.apple.com/library/mac/documentation/cocoa/conceptual/DisplayWebContent/DisplayWebContent.html). +Details about `Cocoa` programming are not covered here. + +An integration of a native extension 'example' would look like this: + + #import "appDelegate.h" + + extern bool example_initialize(JSGlobalContextRef context); + + + @implementation ExampleAppDelegate + + @synthesize webView; + + + - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { + + // Start a webview with the bundled index.html file + NSString *path = [[NSBundle mainBundle] bundlePath]; + NSString *url = [NSString stringWithFormat: @"file://%@/Contents/Assets/index.html", path]; + + WebFrame *webframe = [webView mainFrame]; + JSGlobalContextRef context = [webframe globalContext]; + + example_initialize(context); + + [ [webView mainFrame] loadRequest: + [NSURLRequest requestWithURL: [NSURL URLWithString:url] ] + ]; + } + + @end #### GTK +There is general information about programming GTK on the +[GTK documentation](https://developer.gnome.org/gtk2/), in the +[GTK tutorial](https://developer.gnome.org/gtk-tutorial), +and for Webkit there is a [Webkit GTK+ API Reference](http://webkitgtk.org/reference/webkitgtk/stable/index.html). + +An integration of a native extension 'example' would look like this: + + #include + #include + + extern bool example_initialize(JSGlobalContextRef context); + + int main(int argc, char* argv[]) + { + // Initialize GTK+ + gtk_init(&argc, &argv); + + ... + + // Create a browser instance + WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); + WebFrame *webframe = webkit_web_view_get_main_frame(webView); + JSGlobalContextRef context = webkit_web_frame_get_global_context(webFrame); + example_initialize(context); + + ... + + // Load a web page into the browser instance + webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/"); + + ... + + // Run the main GTK+ event loop + gtk_main(); + + return 0; + } + ## Implementation @@ -133,7 +206,6 @@ Webkit is built-in OSX and available as library for GTK. The Javascript Module implementation has take a very different approach than other modules to be able to generate code for different Javascript interpreters. - ### Source Code The Javascript module is implemented in `Source/Modules/javascript.cxx`. From 8df34d54d0957552a53fe5f1e6598849c4ac9f81 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 14 Feb 2014 13:21:52 +0100 Subject: [PATCH 241/352] Beginning to document v8 integration. --- Doc/Manual/Javascript.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 11c9f7333..275557ccc 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -200,6 +200,15 @@ An integration of a native extension 'example' would look like this: } +### Embedded V8 + +It is possible to create a custom application like `node.js` embedding a v8 engine. + +TODO: +- how to install v8 +- v8 version issues: command-line switch, pre-processor macro +- sample integration code + ## Implementation From 77ead7017caca778eb3143fa487856ee8dcd4b7b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 11:13:57 +0100 Subject: [PATCH 242/352] Refactored configuration for javascript examples. --- Examples/Makefile.in | 37 +++++++++++++-- Examples/javascript/class/Makefile | 22 +-------- Examples/javascript/constant/Makefile | 22 +-------- Examples/javascript/enum/Makefile | 22 +-------- Examples/javascript/exception/Makefile | 22 +-------- Examples/javascript/functor/Makefile | 22 +-------- Examples/javascript/js_example.mk | 63 ++++++++++++++++++++++++++ Examples/javascript/namespace/Makefile | 22 +-------- Examples/javascript/operator/Makefile | 22 +-------- Examples/javascript/overload/Makefile | 22 +-------- Examples/javascript/pointer/Makefile | 22 +-------- Examples/javascript/reference/Makefile | 22 +-------- Examples/javascript/simple/Makefile | 22 +-------- Examples/javascript/template/Makefile | 22 +-------- Examples/javascript/variables/Makefile | 22 +-------- 15 files changed, 121 insertions(+), 265 deletions(-) create mode 100644 Examples/javascript/js_example.mk diff --git a/Examples/Makefile.in b/Examples/Makefile.in index a2a211cbd..17e66acce 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -668,6 +668,11 @@ android_clean: ##### JAVASCRIPT ###### ################################################################## +# Note: These targets are used from withing Makefiles in the Example directories. +# There is a common makefile, 'Examples/javascript/js_example.mk' to simplify +# create a configuration for a new example. + + ROOT_DIR = @ROOT_DIR@ JSCFLAGS = @JSCFLAGS@ JSCXXFLAGS = @JSCXXFLAGS@ @@ -689,6 +694,7 @@ JSCXXSHARED = @JSCXXSHARED@ # environment. # For testing native v8 and jsc extensions we provide our own # interpreter (see 'Tools/javascript'). +# # ---------------------------------------------------------------- JS_INTERPRETER_SRC_DIR = $(ROOT_DIR)/Tools/javascript @@ -717,19 +723,38 @@ javascript_exe: $(SRCS) SWIGJS = $(SWIG) -javascript # ---------------------------------------------------------------- -# Run the javascript executable +# Creating and building Javascript wrappers # ---------------------------------------------------------------- -javascript: $(SRCS) +javascript_wrapper: $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) + +javascript_wrapper_cpp: $(SRCS) + $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) + +javascript_build: $(SRCS) $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) -javascript_cpp: $(SRCS) - $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) +javascript_build_cpp:: $(SRCS) $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) +# TODO: make node-gyp configurable and detected via ./configure +javascript_build_node: $(SRCS) + node-gyp --loglevel=silent configure build 1>>/dev/null + +# ----------------------------------------------------------------- +# Running a javascript example +# ----------------------------------------------------------------- + +javascript_run: + $(JS_INTERPRETER_SRC_DIR)/javascript -$(JSENGINE) runme.js + +# TODO: make node configurable and detected via ./configure +javascript_run_node: + node runme.js + # ----------------------------------------------------------------- # Cleaning the javascript examples # ----------------------------------------------------------------- @@ -740,6 +765,8 @@ javascript_clean: rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@JSSO@ + + ################################################################## ##### MODULA3 ###### ################################################################## @@ -1604,7 +1631,7 @@ R_SCRIPT=$(RUNME).R r: $(SRCS) $(SWIG) -r $(SWIGOPT) $(INTERFACEPATH) ifneq ($(SRCS),) - $(CC) -g -c $(CFLAGS) $(R_CFLAGS) $(SRCS) $(INCLUDES) + $(CC) -g -c $(CFLAGS) $(R_CFLAGS) $(SRCS) $(INCLUDES) endif +( PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null ) diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/class/Makefile +++ b/Examples/javascript/class/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/constant/Makefile +++ b/Examples/javascript/constant/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/enum/Makefile +++ b/Examples/javascript/enum/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/exception/Makefile +++ b/Examples/javascript/exception/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/functor/Makefile +++ b/Examples/javascript/functor/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/js_example.mk b/Examples/javascript/js_example.mk new file mode 100644 index 000000000..c2e9c6dcf --- /dev/null +++ b/Examples/javascript/js_example.mk @@ -0,0 +1,63 @@ +# Note: as a convention an example must be in a child directory of this. +# These paths are relative to such an example directory +EXAMPLES_TOP=../.. +SWIG_TOP=../../.. + +SWIG = $(SWIG_TOP)/preinst-swig + +# TODO: we could only set these only if not yet set... +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +ifneq (, $(ENGINE)) + JSENGINE=$(ENGINE) +else + JSENGINE=node +endif + +ifeq (node,$(JSENGINE)) + SWIGOPT=-v8 -DBUILDING_NODE_EXTENSION=1 +endif + +ifeq (v8,$(JSENGINE)) + SWIGOPT=-v8 +endif + +ifeq (jsc,$(JSENGINE)) + SWIGOPT=-jsc +endif + + +ifeq (node,$(JSENGINE)) + +build: wrapper + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_node + +else + +build: wrapper + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_cpp + +endif + +wrapper: + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +ifeq (node,$(JSENGINE)) + +check: build + $(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' javascript_run_node + +else + +check: build + $(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' javascript_run + +endif + +clean: + $(MAKE) -f $(EXAMPLES_TOP)/Makefile javascript_clean diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/namespace/Makefile +++ b/Examples/javascript/namespace/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/operator/Makefile +++ b/Examples/javascript/operator/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/overload/Makefile +++ b/Examples/javascript/overload/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/pointer/Makefile +++ b/Examples/javascript/pointer/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/reference/Makefile +++ b/Examples/javascript/reference/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/simple/Makefile +++ b/Examples/javascript/simple/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/template/Makefile +++ b/Examples/javascript/template/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile index 99a9e9e86..b0934786a 100755 --- a/Examples/javascript/variables/Makefile +++ b/Examples/javascript/variables/Makefile @@ -1,21 +1,3 @@ -TOP = ../.. -SWIG = $(TOP)/../preinst-swig -CXXSRCS = example.cxx -JS_SCRIPT = runme.js -TARGET = example -INTERFACE = example.i +SRCS = example.cxx -wrapper:: - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp - -build:: wrapper - $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build - -clean:: - $(MAKE) -f $(TOP)/Makefile javascript_clean - -check:: build - $(MAKE) -f $(TOP)/Makefile JSCXXSRCS='$(JSCXXSRCS)' TARGET='$(TARGET)' \ - TOP='$(TOP)' JS_SCRIPT='$(JS_SCRIPT)' javascript_run +include ../js_example.mk From fd0e75843d3ec7816c85a5d1ab84bd9319c9b27e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 11:14:48 +0100 Subject: [PATCH 243/352] Deactivated broken JS examples. --- Examples/javascript/check.list | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Examples/javascript/check.list b/Examples/javascript/check.list index 146f1800f..040267812 100644 --- a/Examples/javascript/check.list +++ b/Examples/javascript/check.list @@ -1,13 +1,13 @@ class constant enum -exception +#exception functor -namespace +#namespace operator overload pointer -reference +#reference simple template variables From 48e7df8eb2f7cb87e57dd7a890fbaa9ec8598ac7 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 11:15:18 +0100 Subject: [PATCH 244/352] Better error message when no Javascript emitter is specified. --- Source/Modules/javascript.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 63994c029..496114c01 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -533,7 +533,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } default: { - Printf(stderr, "Unknown emitter type."); + Printf(stderr, "SWIG Javascript: Unknown emitter type.\n"); SWIG_exit(-1); break; } From 7c1f66c29e4d0fd72e656b4bd27b2010c053b2c7 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 11:15:46 +0100 Subject: [PATCH 245/352] Add more notes about how to install node. --- Doc/Manual/Javascript.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 275557ccc..33f65e864 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -79,19 +79,30 @@ We could work on that if requested: This should give a short introduction to integrating your module in different environments: as a `node.js` module, and as an extension for an embedded Webkit. + ### Creating `node.js` Extensions To install `node.js` you can download an installer from their -[web-site](https://launchpad.net/~chris-lea/+archive/node.js) for all platforms. +[web-site](https://launchpad.net/~chris-lea/+archive/node.js) for OSX and Windows. +For Linux you can either build the source yourself and to a `sudo checkinstall` +or stick to the (probably stone-age) packaged version. +For Ubuntu there is a [PPA](https://launchpad.net/~chris-lea/+archive/node.js/) available. -For Ubuntu there is also a [PPA](https://launchpad.net/~chris-lea/+archive/node.js/) available. + $ sudo add-apt-repository ppa:chris-lea/node.js + $ sudo apt-get update + $ sudo apt-get install nodejs As `v8` is written in C++ and comes as a C++ library it is crucial to compile your module using the same compiler flags as used for building v8. To make things easier, `node.js` provides a build tool called `node-gyp`. -This expects a configuration file named `binding.gyp` which is basically in JSON format and -conforms to the same format that is used with Google's build-tool `gyp`. +You have to install it using `npm`: + + $ npm install -g node-gyp + + +`node-gyp` expects a configuration file named `binding.gyp` which is basically in JSON +format and conforms to the same format that is used with Google's build-tool `gyp`. `binding.gyp`: @@ -117,6 +128,15 @@ To use the extension you have to require it in your javascript source file. require("./build/Release/example") +#### Troubleshooting + +- *'module' object has no attribute 'script_main'* + + This happened when `gyp` was installed as distribution package. + It seems to be outdated. Removing it resolves the problem. + + $ sudo apt-get remove gyp + ### Embedded Webkit From 8e65414a764f390e0db4f8ded0031ecdef16d896 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 11:37:15 +0100 Subject: [PATCH 246/352] Add an extra argument for enabling nodejs support. This is essentially using the v8 emitter plus setting a #define. --- Source/Modules/javascript.cxx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 496114c01..fc0006225 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -511,6 +511,11 @@ void JAVASCRIPT::main(int argc, char *argv[]) { Swig_mark_arg(i); mode = JSEmitter::JavascriptCore; SWIG_library_directory("javascript/jsc"); + } else if (strcmp(argv[i], "-node") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { Swig_mark_arg(i); js_template_enable_debug = true; From 3f22a3d639a2884b8cd50d57fc22b6df49a85cdf Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 11:37:40 +0100 Subject: [PATCH 247/352] Simplification in common javascript example Makefile. --- Examples/javascript/js_example.mk | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/Examples/javascript/js_example.mk b/Examples/javascript/js_example.mk index c2e9c6dcf..7cecd184a 100644 --- a/Examples/javascript/js_example.mk +++ b/Examples/javascript/js_example.mk @@ -16,18 +16,7 @@ else JSENGINE=node endif -ifeq (node,$(JSENGINE)) - SWIGOPT=-v8 -DBUILDING_NODE_EXTENSION=1 -endif - -ifeq (v8,$(JSENGINE)) - SWIGOPT=-v8 -endif - -ifeq (jsc,$(JSENGINE)) - SWIGOPT=-jsc -endif - +SWIGOPT=-$(JSENGINE) ifeq (node,$(JSENGINE)) From 462674ea11fc227501a485a878efd1ae9e111126 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 12:28:06 +0100 Subject: [PATCH 248/352] Added examples to Javascript module documentation. --- Doc/Manual/Javascript.md | 183 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 33f65e864..f2289757a 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -128,6 +128,10 @@ To use the extension you have to require it in your javascript source file. require("./build/Release/example") + +A more detailed exlanation is given in section `Examples`. + + #### Troubleshooting - *'module' object has no attribute 'script_main'* @@ -230,6 +234,185 @@ TODO: - sample integration code +## Examples + +Some basic examples are shown here in more detail. + +### Simple + +The common example `simple` looks like this: + + /* File : example.i */ + %module example + + %inline %{ + extern int gcd(int x, int y); + extern double Foo; + %} + +To make this available as node extension a `binding.gyp` has to be created: + + { + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] + } + +Then `node-gyp` is used to build the extension: + + $ node-gyp configure build + + +From a 'nodejs` application this would be used this way: + + // import the extension via require + var example = require("./build/Release/example"); + + // calling the global method + var x = 42; + var y = 105; + var g = example.gcd(x,y); + + // Accessing the globak variable + var f = example.Foo; + example.Foo = 3.1415926; + +First the module `example` is loaded from the previously built extension. +Global methods and variables are available in the scope of the module. + +> Note: ECMAScript 5, the currently implemented Javascript standard, does not have modules. +> `node.js` and other implementations provide this mechanism defined by the +> [CommonJS](http://wiki.commonjs.org/wiki/CommonJS) group. +> For browsers this is provided by [Browserify](http://browserify.org), for instance. + +### Class + +The common example `class` looks defines three classes, `Shape`, `Circle`, and `Square`: + + class Shape { + public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; + }; + + class Circle : public Shape { + private: + double radius; + public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); + }; + + class Square : public Shape { + private: + double width; + public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); + }; + +`Circle` and `Square` inherit from `Shape`. `Shape` has a static variable a function `move` +that can't be overridden (non-virtual) and two abstract functions `area` and `perimeter` (pure virtual) that must be overridden by the sub-classes. + +A `nodejs` extension is built the same way as for the `simple` example. + +From Javascript this extension can be used this way: + + + var example = require("./build/Release/example"); + + // local aliases for convenience + var Shape = example.Shape; + var Circle = example.Circle; + var Square = example.Square; + + // Creating new instances using the 'new' operator + var c = new Circle(10); + var s = new Square(10); + + // Accessing a static member + var nshapes = Shape.nshapes; + + // Accessing member variables + c.x = 20; + c.y = 30; + s.x = -10; + s.y = 5; + + // Calling some methods ----- + c.area(); + c.perimeter(); + s.area(); + s.perimeter(); + + +Running these commands in an interactive node shell result in this output: + + $ node -i + > var example = require("./build/Release/example"); + undefined + > var Shape = example.Shape; + undefined + > var Circle = example.Circle; + undefined + > var Square = example.Square; + undefined + > var c = new Circle(10); + undefined + > var s = new Square(10); + undefined + > var nshapes = Shape.nshapes; + undefined + > Shape.nshapes; + 2 + > c.x = 20; + 20 + > c.y = 30; + 30 + > s.x = -10; + -10 + > s.y = 5; + 5 + > c.area(); + 314.1592653589793 + > c.perimeter(); + 62.83185307179586 + > s.area(); + 100 + > s.perimeter(); + 40 + > c.move(40, 40) + undefined + > c.x + 60 + > c.y + 70 + > + +> Note: In ECMAScript 5 there is no concept for classes. + Instead each function can be used as a constructor function which is executed by the 'new' + operator. Furthermore, during construction the key property `prototype` of the constructor function is used to attach a prototype instance to the created object. + A prototype is essentially an object itself that is the first-class delegate of a class + used whenever the access to a property of an object fails. + The very same prototype instance is shared among all instances of one type. + Prototypal inheritance is explained in more detail on in + [Inheritance and the prototype chain](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain), for instance. + + ## Implementation The Javascript Module implementation has take a very different approach than other modules From 1ffacaab5b7635da623de6c49c22684a1c46d549 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 12:30:57 +0100 Subject: [PATCH 249/352] Add note about '-node' command line flag for Node.js code generation. --- Doc/Manual/Javascript.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index f2289757a..2690cb5db 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -33,7 +33,9 @@ Suppose that you defined a SWIG module such as the following: extern double Foo; To build a Javascript module, run SWIG using the `-javascript` option -and a desired target engine `-jsc` or `-v8`. +and a desired target engine `-jsc`, `-v8`, or `-node`. +The generator for `node` is essentially delegating to the `v8` generator and adds +some necessary preprocessor definitions. $ swig -javascript -jsc example.i From 84ba91dc63d817376486cecfd7188f56303e6e3b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 20 Feb 2014 12:38:53 +0100 Subject: [PATCH 250/352] Some fixes in example section of Javascript documentation. --- Doc/Manual/Javascript.md | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 2690cb5db..044343588 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -292,7 +292,7 @@ Global methods and variables are available in the scope of the module. ### Class -The common example `class` looks defines three classes, `Shape`, `Circle`, and `Square`: +The common example `class` defines three classes, `Shape`, `Circle`, and `Square`: class Shape { public: @@ -327,12 +327,14 @@ The common example `class` looks defines three classes, `Shape`, `Circle`, and ` virtual double perimeter(void); }; -`Circle` and `Square` inherit from `Shape`. `Shape` has a static variable a function `move` -that can't be overridden (non-virtual) and two abstract functions `area` and `perimeter` (pure virtual) that must be overridden by the sub-classes. +`Circle` and `Square` inherit from `Shape`. `Shape` has a static variable `nshapes`, +a function `move` that can't be overridden (non-virtual), +and two abstract functions `area` and `perimeter` (pure virtual) that must be +overridden by the sub-classes. A `nodejs` extension is built the same way as for the `simple` example. -From Javascript this extension can be used this way: +In javascript it can be used this way: var example = require("./build/Release/example"); @@ -342,27 +344,29 @@ From Javascript this extension can be used this way: var Circle = example.Circle; var Square = example.Square; - // Creating new instances using the 'new' operator + // creating new instances using the 'new' operator var c = new Circle(10); var s = new Square(10); - // Accessing a static member - var nshapes = Shape.nshapes; + // accessing a static member + Shape.nshapes; - // Accessing member variables + // accessing member variables c.x = 20; c.y = 30; s.x = -10; s.y = 5; - // Calling some methods ----- + // calling some methods c.area(); c.perimeter(); s.area(); s.perimeter(); + // instantiation of Shape is not permitted + new Shape(); -Running these commands in an interactive node shell result in this output: +Running these commands in an interactive node shell results in the following output: $ node -i > var example = require("./build/Release/example"); @@ -377,8 +381,6 @@ Running these commands in an interactive node shell result in this output: undefined > var s = new Square(10); undefined - > var nshapes = Shape.nshapes; - undefined > Shape.nshapes; 2 > c.x = 20; @@ -403,7 +405,19 @@ Running these commands in an interactive node shell result in this output: 60 > c.y 70 - > + > new Shape() + Error: Class Shape can not be instantiated + at repl:1:2 + at REPLServer.self.eval (repl.js:110:21) + at Interface. (repl.js:239:12) + at Interface.EventEmitter.emit (events.js:95:17) + at Interface._onLine (readline.js:202:10) + at Interface._line (readline.js:531:8) + at Interface._ttyWrite (readline.js:760:14) + at ReadStream.onkeypress (readline.js:99:10) + at ReadStream.EventEmitter.emit (events.js:98:17) + at emitKey (readline.js:1095:12) + > Note: In ECMAScript 5 there is no concept for classes. Instead each function can be used as a constructor function which is executed by the 'new' From 15550dab450f003c0b42d6a3353b137435793999 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 25 Feb 2014 20:16:15 +0100 Subject: [PATCH 251/352] Fix issue with strange constants under OSX. Receiving strange constant nodes before the real tree under OSX 10.8. Not so under Ubuntu 12.04. --- Source/Modules/javascript.cxx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index fc0006225..b20de6202 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -33,6 +33,7 @@ bool js_template_enable_debug = false; #define MEMBER_FUNCTIONS "member_functions" #define STATIC_FUNCTIONS "static_functions" #define STATIC_VARIABLES "static_variables" +#define HAS_TEMPLATES "has_templates" #define RESET true @@ -600,6 +601,9 @@ JSEmitter::~JSEmitter() { * ----------------------------------------------------------------------------- */ int JSEmitter::registerTemplate(const String *name, const String *code) { + if (!State::IsSet(state.global(HAS_TEMPLATES))) { + SetFlag(state.global(), HAS_TEMPLATES); + } return Setattr(templates, name, code); } @@ -1067,6 +1071,13 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { * ----------------------------------------------------------------------------- */ int JSEmitter::emitConstant(Node *n) { + // HACK: somehow it happened under OSX that before everything started + // a lot of SWIG internal constants were emitted + // This didn't happen on Ubuntu Precise... + // so we + if (!State::IsSet(state.global(HAS_TEMPLATES))) { + return SWIG_ERROR; + } Wrapper *wrapper = NewWrapper(); SwigType *type = Getattr(n, "type"); From e62c6126e9d6645eaff2b96d7847d4a8c681bb84 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 10:47:48 +0100 Subject: [PATCH 252/352] Fix regressions in Javascript example configuration. --- Examples/Makefile.in | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 17e66acce..fe0e42fdc 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -717,7 +717,7 @@ JS_INTERPRETER_SRC = \ # TODO: improve: # - exe suffix # - '-ldl' should come from configure -javascript_exe: $(SRCS) +javascript_custom_interpreter: $(JS_INTERPRETER_SRC) $(CXX) $(CXXFLAGS) $(JS_INTERPRETER_CXXFLAGS) $(JSINCLUDES) $(JS_INTERPRETER_SRC) -ldl $(LIBS) $(JSDYNAMICLINKING) -o $(JS_INTERPRETER_SRC_DIR)/javascript SWIGJS = $(SWIG) -javascript @@ -744,11 +744,23 @@ javascript_build_cpp:: $(SRCS) javascript_build_node: $(SRCS) node-gyp --loglevel=silent configure build 1>>/dev/null +# These targets are used by the test-suite: + +javascript: $(SRCS) javascript_custom_interpreter + $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) + $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) + $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +javascript_cpp: $(SRCS) javascript_custom_interpreter + $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) + $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + # ----------------------------------------------------------------- # Running a javascript example # ----------------------------------------------------------------- -javascript_run: +javascript_run: $(JS_INTERPRETER_SRC_DIR)/javascript $(JS_INTERPRETER_SRC_DIR)/javascript -$(JSENGINE) runme.js # TODO: make node configurable and detected via ./configure @@ -764,6 +776,7 @@ javascript_clean: rm -f *_wrap* runme rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@JSSO@ + rm -f $(JS_INTERPRETER_SRC_DIR)/javascript From 16a702c0aac717462b1eb94fc4640446943d9396 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 10:48:38 +0100 Subject: [PATCH 253/352] Added a comment. --- Source/Modules/javascript.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index b20de6202..7b153c66c 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1073,8 +1073,8 @@ int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { int JSEmitter::emitConstant(Node *n) { // HACK: somehow it happened under OSX that before everything started // a lot of SWIG internal constants were emitted - // This didn't happen on Ubuntu Precise... - // so we + // This didn't happen on other platforms yet... + // we ignore those premature definitions if (!State::IsSet(state.global(HAS_TEMPLATES))) { return SWIG_ERROR; } From bf1606c0f9261dcb4ae8d5c24aebc987a67e7510 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 11:10:09 +0100 Subject: [PATCH 254/352] Fix travis configuration. --- .travis.yml | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3b8500aee..2664890d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,16 @@ language: c compiler: - gcc -node_js: - -0.10.12 before_script: - "sudo apt-get install rlwrap" - - "wget https://launchpad.net/~chris-lea/+archive/node.js/+build/4936691/+files/nodejs_0.10.18-1chl1~precise1_amd64.deb" - - "sudo dpkg -i nodejs_0.10.18-1chl1~precise1_amd64.deb" + - "sudo apt-get install python-software-properties" + - "echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js" + - "sudo apt-get update" + - "sudo apt-get install nodejs" - "sudo npm install -g node-gyp" - - "sudo apt-get install libv8-3.7.12.22 libv8-dev" + - "sudo apt-get install libv8-dev" - "sudo apt-get install libwebkitgtk-dev" - "./autogen.sh && ./configure && make" - - "cd Examples && make javascript_exe && cd .." script: - "make SMOKE=1 check-javascript-test-suite" - "make SMOKE=1 ENGINE=jsc check-javascript-test-suite" From b216a739c45cfb595a5b70da7e811b6130148a63 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 20:51:38 +0100 Subject: [PATCH 255/352] Introduced an extra Makefile for the custom javascript interpreter. --- Examples/Makefile.in | 49 +------ Tools/javascript/Makefile.in | 56 ++++++++ Tools/javascript/javascript.cxx | 5 + Tools/javascript/js_shell.cxx | 4 +- Tools/javascript/jsc_shell.cxx | 4 + configure.ac | 6 + swig-v8/swig-v8.xcodeproj/project.pbxproj | 153 ++++++++++++++++++++++ 7 files changed, 233 insertions(+), 44 deletions(-) create mode 100644 Tools/javascript/Makefile.in create mode 100644 swig-v8/swig-v8.xcodeproj/project.pbxproj diff --git a/Examples/Makefile.in b/Examples/Makefile.in index fe0e42fdc..b3292810a 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -683,43 +683,6 @@ JSSO =@JSSO@ JSLDSHARED = @JSLDSHARED@ JSCXXSHARED = @JSCXXSHARED@ -# ---------------------------------------------------------------- -# Compile a custom javascript interpreter -# ---------------------------------------------------------------- -# -# Note: -# There is no common CLI Javascript interpreter. -# V8 comes with one 'd8' which however does not provide a means -# to load extensions. Therefore, by default we use nodejs as -# environment. -# For testing native v8 and jsc extensions we provide our own -# interpreter (see 'Tools/javascript'). -# -# ---------------------------------------------------------------- - -JS_INTERPRETER_SRC_DIR = $(ROOT_DIR)/Tools/javascript - -# These settings are provided by 'configure' (see '/configure.in') -ifeq (1, @JSV8ENABLED@) - JS_INTERPRETER_SRC_V8 = $(JS_INTERPRETER_SRC_DIR)/v8_shell.cxx - JS_INTERPRETER_CXXFLAGS_V8 = -DENABLE_V8 -endif - -ifeq (1, @JSCENABLED@) - JS_INTERPRETER_SRC_JSC = $(JS_INTERPRETER_SRC_DIR)/jsc_shell.cxx - JS_INTERPRETER_CXXFLAGS_JSC = -DENABLE_JSC -endif - -JS_INTERPRETER_CXXFLAGS = $(JS_INTERPRETER_CXXFLAGS_JSC) $(JS_INTERPRETER_CXXFLAGS_V8) -JS_INTERPRETER_SRC = \ - $(JS_INTERPRETER_SRC_DIR)/javascript.cxx $(JS_INTERPRETER_SRC_DIR)/js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_INTERPRETER_SRC_V8) - -# TODO: improve: -# - exe suffix -# - '-ldl' should come from configure -javascript_custom_interpreter: $(JS_INTERPRETER_SRC) - $(CXX) $(CXXFLAGS) $(JS_INTERPRETER_CXXFLAGS) $(JSINCLUDES) $(JS_INTERPRETER_SRC) -ldl $(LIBS) $(JSDYNAMICLINKING) -o $(JS_INTERPRETER_SRC_DIR)/javascript - SWIGJS = $(SWIG) -javascript # ---------------------------------------------------------------- @@ -760,8 +723,11 @@ javascript_cpp: $(SRCS) javascript_custom_interpreter # Running a javascript example # ----------------------------------------------------------------- -javascript_run: $(JS_INTERPRETER_SRC_DIR)/javascript - $(JS_INTERPRETER_SRC_DIR)/javascript -$(JSENGINE) runme.js +javascript_custom_interpreter: + (cd $(ROOT_DIR)/Tools/javascript && $(MAKE) JSENGINE='$(JSENGINE)') + +javascript_run: javascript_custom_interpreter + $(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) runme.js # TODO: make node configurable and detected via ./configure javascript_run_node: @@ -775,9 +741,8 @@ javascript_clean: rm -rf build rm -f *_wrap* runme rm -f core @EXTRA_CLEAN@ - rm -f *.@OBJEXT@ *@JSSO@ - rm -f $(JS_INTERPRETER_SRC_DIR)/javascript - + rm -f *.@OBJEXT@ *@JSSO@ *.bundle + (cd $(ROOT_DIR)/Tools/javascript && $(MAKE) -s clean) ################################################################## diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in new file mode 100644 index 000000000..57e63e88d --- /dev/null +++ b/Tools/javascript/Makefile.in @@ -0,0 +1,56 @@ +# ---------------------------------------------------------------- +# Compile a custom javascript interpreter +# ---------------------------------------------------------------- +# +# Note: +# There is no common CLI Javascript interpreter. +# V8 comes with one 'd8' which however does not provide a means +# to load extensions. Therefore, by default we use nodejs as +# environment. +# For testing native v8 and jsc extensions we provide our own +# interpreter (see 'Tools/javascript'). +# +# ---------------------------------------------------------------- +CC = @CC@ +# HACK: under OSX a g++ compiled interpreter is seg-faulting when loading module libraries +# with 'c++' it works... probably some missing flags? +CXX = @JSINTERPRETERCXX@ +CFLAGS = @BOOST_CPPFLAGS@ @PLATFLAGS@ + +ROOT_DIR = @ROOT_DIR@ +JSCFLAGS = @JSCFLAGS@ +JSCXXFLAGS = @JSCXXFLAGS@ +JSINCLUDES = @JSCOREINC@ @JSV8INC@ +JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ +JSLIBRARYPREFIX = @JSLIBRARYPREFIX@ +JSSO =@JSSO@ +JSLDSHARED = @JSLDSHARED@ +JSCXXSHARED = @JSCXXSHARED@ +JSV8ENABLED = @JSV8ENABLED@ +JSCENABLED = @JSCENABLED@ + +# These settings are provided by 'configure' (see '/configure.in') +ifeq (1, $(JSV8ENABLED)) + JS_INTERPRETER_SRC_V8 = v8_shell.cxx + JS_INTERPRETER_CXXFLAGS_V8 = -DENABLE_V8 +endif + +ifeq (1, $(JSCENABLED)) + JS_INTERPRETER_SRC_JSC = jsc_shell.cxx + JS_INTERPRETER_CXXFLAGS_JSC = -DENABLE_JSC +endif + +JS_INTERPRETER_CXXFLAGS = $(JS_INTERPRETER_CXXFLAGS_JSC) $(JS_INTERPRETER_CXXFLAGS_V8) +JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_INTERPRETER_SRC_V8) + +JS_INTERPRETER_OBJS = $(JS_INTERPRETER_SRC:.cxx=.o) + +%.o: %.cxx + $(CXX) $(JS_INTERPRETER_CXXFLAGS) -g $(JSINCLUDES) -o $@ -c $< + +javascript: $(JS_INTERPRETER_OBJS) + $(CXX) -g -Wl,-search_paths_first -Wl,-headerpad_max_install_names $^ $(CFLAGS) -o javascript $(JSDYNAMICLINKING) + +clean: + rm -f *.o + rm -f javascript diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx index ec4ac4e3f..e5cb0a47e 100644 --- a/Tools/javascript/javascript.cxx +++ b/Tools/javascript/javascript.cxx @@ -13,6 +13,11 @@ void print_usage() { int main(int argc, char* argv[]) { +#if defined(JAVASCRIPT_INTERPRETER_STOP) + std::cout << "Attach your Debugger and press any key to continue" << std::endl; + std::cin.get(); +#endif + std::string scriptPath = ""; bool interactive = false; diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx index ca5ca7ecd..c0ac3da58 100644 --- a/Tools/javascript/js_shell.cxx +++ b/Tools/javascript/js_shell.cxx @@ -7,7 +7,7 @@ #ifdef __GNUC__ #ifdef __APPLE__ -#define LIBRARY_EXT ".dylib" +#define LIBRARY_EXT ".bundle" #else #define LIBRARY_EXT ".so" #endif @@ -52,7 +52,7 @@ std::string JSShell::LoadModule(const std::string& name, HANDLE* library) { HANDLE handle = LOAD_LIBRARY(lib_name.c_str()); if(handle == 0) { - std::cout << "Could not load library " << lib_name << ":" + std::cerr << "Could not load library " << lib_name << ":" << std::endl << LIBRARY_ERROR() << std::endl; return 0; } diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx index e4e8cdd96..cf30d7bd7 100644 --- a/Tools/javascript/jsc_shell.cxx +++ b/Tools/javascript/jsc_shell.cxx @@ -70,6 +70,10 @@ bool JSCShell::InitializeEngine() { JSClassRef __shell_class__ = JSClassCreate(&__shell_classdef__); JSObjectRef __shell__ = JSObjectMake(context, __shell_class__, 0); bool success = JSObjectSetPrivate(__shell__, (void*) (long) this); + if (!success) { + std::cerr << "Could not register the shell in the Javascript context" << std::endl; + return false; + } JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__"); JSObjectSetProperty(context, globalObject, shellKey, __shell__, kJSPropertyAttributeReadOnly, NULL); JSStringRelease(shellKey); diff --git a/configure.ac b/configure.ac index 72b507662..09bb65f25 100644 --- a/configure.ac +++ b/configure.ac @@ -1135,11 +1135,14 @@ else JSSO=".dylib" JSLDSHARED='$(CC) -dynamiclib' JSCXXSHARED='$(CXX) -dynamiclib' + # HACK: didn't manage to get dynamic module loading working with a g++ compiled interpreter + JSINTERPRETERCXX='c++' ;; *) JSSO=$SO JSLDSHARED='$(LDSHARED)' JSCXXSHARED='$(CXXSHARED)' + JSINTERPRETERCXX='$(CXX)' ;; esac @@ -1219,6 +1222,7 @@ else ;; *-*-darwin*) JSCOREDYNAMICLINKING="-framework JavaScriptCore" + JSCENABLED=1 ;; *) ;; @@ -1305,6 +1309,7 @@ AC_SUBST(JSLIBRARYPREFIX) AC_SUBST(JSSO) AC_SUBST(JSLDSHARED) AC_SUBST(JSCXXSHARED) +AC_SUBST(JSINTERPRETERCXX) AC_SUBST(JSCOREINC) AC_SUBST(JSCOREDYNAMICLINKING) @@ -2650,6 +2655,7 @@ AC_CONFIG_FILES([ \ Examples/test-suite/r/Makefile \ Examples/test-suite/go/Makefile \ Examples/test-suite/javascript/Makefile \ + Tools/javascript/Makefile \ Lib/ocaml/swigp4.ml ]) AC_CONFIG_FILES([preinst-swig], [chmod +x preinst-swig]) diff --git a/swig-v8/swig-v8.xcodeproj/project.pbxproj b/swig-v8/swig-v8.xcodeproj/project.pbxproj new file mode 100644 index 000000000..d6fcad63b --- /dev/null +++ b/swig-v8/swig-v8.xcodeproj/project.pbxproj @@ -0,0 +1,153 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXGroup section */ + A7E4F27918BDF64900ED77C7 = { + isa = PBXGroup; + children = ( + ); + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + A7E4F28018BDF64900ED77C7 /* swig-v8 */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = A7E4F28318BDF64900ED77C7 /* Build configuration list for PBXLegacyTarget "swig-v8" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + dependencies = ( + ); + name = "swig-v8"; + passBuildSettingsInEnvironment = 1; + productName = "swig-v8"; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + A7E4F27B18BDF64900ED77C7 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = "Oliver Buchtala"; + }; + buildConfigurationList = A7E4F27E18BDF64900ED77C7 /* Build configuration list for PBXProject "swig-v8" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = A7E4F27918BDF64900ED77C7; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A7E4F28018BDF64900ED77C7 /* swig-v8 */, + ); + }; +/* End PBXProject section */ + +/* Begin XCBuildConfiguration section */ + A7E4F28118BDF64900ED77C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + A7E4F28218BDF64900ED77C7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + SDKROOT = macosx; + }; + name = Release; + }; + A7E4F28418BDF64900ED77C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUGGING_SYMBOLS = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + A7E4F28518BDF64900ED77C7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A7E4F27E18BDF64900ED77C7 /* Build configuration list for PBXProject "swig-v8" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A7E4F28118BDF64900ED77C7 /* Debug */, + A7E4F28218BDF64900ED77C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A7E4F28318BDF64900ED77C7 /* Build configuration list for PBXLegacyTarget "swig-v8" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A7E4F28418BDF64900ED77C7 /* Debug */, + A7E4F28518BDF64900ED77C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = A7E4F27B18BDF64900ED77C7 /* Project object */; +} From 15f12d9b59b9e8522853f010f9d443164774a6a6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 22:44:37 +0100 Subject: [PATCH 256/352] Make examples work with node.js and the custom interpreter. --- Examples/javascript/class/example.js | 1 + Examples/javascript/class/runme.js | 2 +- Examples/javascript/constant/example.js | 1 + Examples/javascript/constant/runme.js | 2 +- Examples/javascript/enum/example.js | 1 + Examples/javascript/enum/runme.js | 2 +- Examples/javascript/exception/example.js | 1 + Examples/javascript/exception/runme.js | 2 +- Examples/javascript/functor/example.js | 1 + Examples/javascript/functor/runme.js | 2 +- Examples/javascript/namespace/example.js | 1 + Examples/javascript/namespace/runme.js | 2 +- Examples/javascript/operator/example.js | 1 + Examples/javascript/operator/runme.js | 2 +- Examples/javascript/overload/example.js | 1 + Examples/javascript/overload/runme.js | 2 +- Examples/javascript/overload/swig_gdb.log | 0 Examples/javascript/pointer/example.js | 1 + Examples/javascript/pointer/runme.js | 2 +- Examples/javascript/reference/example.js | 1 + Examples/javascript/reference/runme.js | 2 +- Examples/javascript/simple/example.js | 1 + Examples/javascript/simple/runme.js | 2 +- Examples/javascript/template/example.js | 1 + Examples/javascript/template/runme.js | 2 +- Examples/javascript/variables/example.js | 1 + Examples/javascript/variables/runme.js | 2 +- 27 files changed, 26 insertions(+), 13 deletions(-) create mode 100644 Examples/javascript/class/example.js create mode 100644 Examples/javascript/constant/example.js create mode 100644 Examples/javascript/enum/example.js create mode 100644 Examples/javascript/exception/example.js create mode 100644 Examples/javascript/functor/example.js create mode 100644 Examples/javascript/namespace/example.js create mode 100644 Examples/javascript/operator/example.js create mode 100644 Examples/javascript/overload/example.js delete mode 100644 Examples/javascript/overload/swig_gdb.log create mode 100644 Examples/javascript/pointer/example.js create mode 100644 Examples/javascript/reference/example.js create mode 100644 Examples/javascript/simple/example.js create mode 100644 Examples/javascript/template/example.js create mode 100644 Examples/javascript/variables/example.js diff --git a/Examples/javascript/class/example.js b/Examples/javascript/class/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/class/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js index 5bb62ecd4..e1d5d9797 100755 --- a/Examples/javascript/class/runme.js +++ b/Examples/javascript/class/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); // ----- Object creation ----- diff --git a/Examples/javascript/constant/example.js b/Examples/javascript/constant/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/constant/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/constant/runme.js b/Examples/javascript/constant/runme.js index b11c08c98..2188bf099 100755 --- a/Examples/javascript/constant/runme.js +++ b/Examples/javascript/constant/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); console.log("ICONST = " + example.ICONST + " (should be 42)\n"); console.log("FCONST = " + example.FCONST + " (should be 2.1828)\n"); diff --git a/Examples/javascript/enum/example.js b/Examples/javascript/enum/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/enum/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js index 9d3accd1d..d4e89e8c8 100755 --- a/Examples/javascript/enum/runme.js +++ b/Examples/javascript/enum/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); // ----- Object creation ----- diff --git a/Examples/javascript/exception/example.js b/Examples/javascript/exception/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/exception/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js index f7041f028..977f51ebc 100644 --- a/Examples/javascript/exception/runme.js +++ b/Examples/javascript/exception/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); console.log("Trying to catch some exceptions."); t = new example.Test(); diff --git a/Examples/javascript/functor/example.js b/Examples/javascript/functor/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/functor/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/functor/runme.js b/Examples/javascript/functor/runme.js index f7be78286..dc12470f4 100644 --- a/Examples/javascript/functor/runme.js +++ b/Examples/javascript/functor/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); a = new example.intSum(0); b = new example.doubleSum(100.0); diff --git a/Examples/javascript/namespace/example.js b/Examples/javascript/namespace/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/namespace/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/namespace/runme.js b/Examples/javascript/namespace/runme.js index 9a9d6744d..08e0d3769 100644 --- a/Examples/javascript/namespace/runme.js +++ b/Examples/javascript/namespace/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); console.log("Global variable Foo=" + example.nspace.Foo); example.nspace.Foo = 5; diff --git a/Examples/javascript/operator/example.js b/Examples/javascript/operator/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/operator/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/operator/runme.js b/Examples/javascript/operator/runme.js index 9dba4b7f9..a700918d6 100644 --- a/Examples/javascript/operator/runme.js +++ b/Examples/javascript/operator/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); a = new example.Complex(2,3); b = new example.Complex(-5,10); diff --git a/Examples/javascript/overload/example.js b/Examples/javascript/overload/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/overload/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/overload/runme.js b/Examples/javascript/overload/runme.js index 5ff5d01be..1e6c861a6 100644 --- a/Examples/javascript/overload/runme.js +++ b/Examples/javascript/overload/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); example.f(); example.f(1); diff --git a/Examples/javascript/overload/swig_gdb.log b/Examples/javascript/overload/swig_gdb.log deleted file mode 100644 index e69de29bb..000000000 diff --git a/Examples/javascript/pointer/example.js b/Examples/javascript/pointer/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/pointer/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/pointer/runme.js b/Examples/javascript/pointer/runme.js index 00778dfbc..7f1e51c9e 100755 --- a/Examples/javascript/pointer/runme.js +++ b/Examples/javascript/pointer/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); // First create some objects using the pointer library. console.log("Testing the pointer library\n"); diff --git a/Examples/javascript/reference/example.js b/Examples/javascript/reference/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/reference/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/reference/runme.js b/Examples/javascript/reference/runme.js index ee5737076..935d2b948 100755 --- a/Examples/javascript/reference/runme.js +++ b/Examples/javascript/reference/runme.js @@ -1,5 +1,5 @@ // This file illustrates the manipulation of C++ references in Javascript. -var example = require("./build/Release/example"); +var example = require("./example"); // ----- Object creation ----- diff --git a/Examples/javascript/simple/example.js b/Examples/javascript/simple/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/simple/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/simple/runme.js b/Examples/javascript/simple/runme.js index d970dcb7c..be2c18669 100755 --- a/Examples/javascript/simple/runme.js +++ b/Examples/javascript/simple/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); /* Call our gcd() function */ diff --git a/Examples/javascript/template/example.js b/Examples/javascript/template/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/template/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/template/runme.js b/Examples/javascript/template/runme.js index 551475c72..55894dfd5 100644 --- a/Examples/javascript/template/runme.js +++ b/Examples/javascript/template/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); //Call some templated functions console.log(example.maxint(3,7)); diff --git a/Examples/javascript/variables/example.js b/Examples/javascript/variables/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/variables/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/variables/runme.js b/Examples/javascript/variables/runme.js index 22d208480..d07861713 100755 --- a/Examples/javascript/variables/runme.js +++ b/Examples/javascript/variables/runme.js @@ -1,4 +1,4 @@ -var example = require("./build/Release/example"); +var example = require("./example"); // Try to set the values of some global variables example.ivar = 42; From 424e3f47123f8a7746d12d02204b896e55b8444d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 22:46:24 +0100 Subject: [PATCH 257/352] Fix custom javascript interpreter configuration for OSX. --- Examples/Makefile.in | 10 +++++----- Examples/javascript/js_example.mk | 2 +- Tools/javascript/Makefile.in | 11 ++++++----- Tools/javascript/javascript.cxx | 11 +++++++++-- Tools/javascript/js_shell.cxx | 14 ++++++++++++-- Tools/javascript/js_shell.h | 5 +++++ configure.ac | 4 ++++ 7 files changed, 42 insertions(+), 15 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index b3292810a..6769fda0b 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -668,7 +668,7 @@ android_clean: ##### JAVASCRIPT ###### ################################################################## -# Note: These targets are used from withing Makefiles in the Example directories. +# Note: These targets are also from within Makefiles in the Example directories. # There is a common makefile, 'Examples/javascript/js_example.mk' to simplify # create a configuration for a new example. @@ -690,10 +690,10 @@ SWIGJS = $(SWIG) -javascript # ---------------------------------------------------------------- javascript_wrapper: - $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) + $(SWIGJS) $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH) javascript_wrapper_cpp: $(SRCS) - $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) + $(SWIGJS) -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cxx $(INTERFACEPATH) javascript_build: $(SRCS) $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) @@ -727,7 +727,7 @@ javascript_custom_interpreter: (cd $(ROOT_DIR)/Tools/javascript && $(MAKE) JSENGINE='$(JSENGINE)') javascript_run: javascript_custom_interpreter - $(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) runme.js + $(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) -L $(TARGET) runme.js # TODO: make node configurable and detected via ./configure javascript_run_node: @@ -741,7 +741,7 @@ javascript_clean: rm -rf build rm -f *_wrap* runme rm -f core @EXTRA_CLEAN@ - rm -f *.@OBJEXT@ *@JSSO@ *.bundle + rm -f *.@OBJEXT@ *@JSSO@ *.$(SO) (cd $(ROOT_DIR)/Tools/javascript && $(MAKE) -s clean) diff --git a/Examples/javascript/js_example.mk b/Examples/javascript/js_example.mk index 7cecd184a..6cb6eb113 100644 --- a/Examples/javascript/js_example.mk +++ b/Examples/javascript/js_example.mk @@ -44,7 +44,7 @@ check: build else check: build - $(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' javascript_run + $(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' TARGET='$(TARGET)' javascript_run endif diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in index 57e63e88d..32744333f 100644 --- a/Tools/javascript/Makefile.in +++ b/Tools/javascript/Makefile.in @@ -16,6 +16,7 @@ CC = @CC@ # with 'c++' it works... probably some missing flags? CXX = @JSINTERPRETERCXX@ CFLAGS = @BOOST_CPPFLAGS@ @PLATFLAGS@ +LINKFLAGS = @JSINTERPRETERLINKFLAGS@ ROOT_DIR = @ROOT_DIR@ JSCFLAGS = @JSCFLAGS@ @@ -32,24 +33,24 @@ JSCENABLED = @JSCENABLED@ # These settings are provided by 'configure' (see '/configure.in') ifeq (1, $(JSV8ENABLED)) JS_INTERPRETER_SRC_V8 = v8_shell.cxx - JS_INTERPRETER_CXXFLAGS_V8 = -DENABLE_V8 + JS_INTERPRETER_ENABLE_V8 = -DENABLE_V8 endif ifeq (1, $(JSCENABLED)) JS_INTERPRETER_SRC_JSC = jsc_shell.cxx - JS_INTERPRETER_CXXFLAGS_JSC = -DENABLE_JSC + JS_INTERPRETER_ENABLE_JSC = -DENABLE_JSC endif -JS_INTERPRETER_CXXFLAGS = $(JS_INTERPRETER_CXXFLAGS_JSC) $(JS_INTERPRETER_CXXFLAGS_V8) +JS_INTERPRETER_DEFINES = $(JS_INTERPRETER_ENABLE_JSC) $(JS_INTERPRETER_ENABLE_V8) JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_INTERPRETER_SRC_V8) JS_INTERPRETER_OBJS = $(JS_INTERPRETER_SRC:.cxx=.o) %.o: %.cxx - $(CXX) $(JS_INTERPRETER_CXXFLAGS) -g $(JSINCLUDES) -o $@ -c $< + $(CXX) $(JS_INTERPRETER_DEFINES) -g $(JSINCLUDES) -o $@ -c $< javascript: $(JS_INTERPRETER_OBJS) - $(CXX) -g -Wl,-search_paths_first -Wl,-headerpad_max_install_names $^ $(CFLAGS) -o javascript $(JSDYNAMICLINKING) + $(CXX) $(LINKFLAGS) $^ $(CFLAGS) -o javascript $(JSDYNAMICLINKING) clean: rm -f *.o diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx index e5cb0a47e..5e7cc0b20 100644 --- a/Tools/javascript/javascript.cxx +++ b/Tools/javascript/javascript.cxx @@ -23,13 +23,18 @@ int main(int argc, char* argv[]) { bool interactive = false; JSShell* shell = 0; + std::vector modulePath; + modulePath.push_back("."); + for (int idx = 1; idx < argc; ++idx) { if(strcmp(argv[idx], "-v8") == 0) { - shell = JSShell::Create(JSShell::V8); + shell = JSShell::Create(JSShell::V8); } else if(strcmp(argv[idx], "-jsc") == 0) { - shell = JSShell::Create(JSShell::JSC); + shell = JSShell::Create(JSShell::JSC); } else if(strcmp(argv[idx], "-i") == 0) { interactive = true; + } else if(strcmp(argv[idx], "-L") == 0) { + modulePath.push_back(argv[++idx]); } else { scriptPath = argv[idx]; } @@ -39,6 +44,8 @@ int main(int argc, char* argv[]) { shell = JSShell::Create(); } + shell->setModulePath(modulePath); + bool failed = false; if(interactive) { diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx index c0ac3da58..5890c922c 100644 --- a/Tools/javascript/js_shell.cxx +++ b/Tools/javascript/js_shell.cxx @@ -41,6 +41,7 @@ std::string JSShell::LoadModule(const std::string& name, HANDLE* library) { std::string lib_name; std::string module_name; + if (pathIdx == std::string::npos) { module_name = name; lib_name = std::string(name).append(LIBRARY_EXT); @@ -50,9 +51,18 @@ std::string JSShell::LoadModule(const std::string& name, HANDLE* library) { lib_name = path.append(module_name).append(LIBRARY_EXT); } - HANDLE handle = LOAD_LIBRARY(lib_name.c_str()); + std::string lib_path; + HANDLE handle = 0; + + for (int i = 0; i < module_path.size(); ++i) { + lib_path = module_path[i] + "/" + lib_name; + if (access( lib_path.c_str(), F_OK ) != -1) { + handle = LOAD_LIBRARY(lib_path.c_str()); + } + } + if(handle == 0) { - std::cerr << "Could not load library " << lib_name << ":" + std::cerr << "Could not find module " << lib_path << ":" << std::endl << LIBRARY_ERROR() << std::endl; return 0; } diff --git a/Tools/javascript/js_shell.h b/Tools/javascript/js_shell.h index 84a8534d6..1e2466b96 100644 --- a/Tools/javascript/js_shell.h +++ b/Tools/javascript/js_shell.h @@ -29,6 +29,10 @@ public: virtual bool RunShell(); + void setModulePath(const std::vector& modulePath) { + module_path = modulePath; + } + protected: virtual bool InitializeEngine() = 0; @@ -42,6 +46,7 @@ protected: protected: std::vector loaded_modules; + std::vector module_path; }; diff --git a/configure.ac b/configure.ac index 09bb65f25..720aebd04 100644 --- a/configure.ac +++ b/configure.ac @@ -1137,12 +1137,14 @@ else JSCXXSHARED='$(CXX) -dynamiclib' # HACK: didn't manage to get dynamic module loading working with a g++ compiled interpreter JSINTERPRETERCXX='c++' + JSINTERPRETERLINKFLAGS='-g -Wl,-search_paths_first -Wl,-headerpad_max_install_names' ;; *) JSSO=$SO JSLDSHARED='$(LDSHARED)' JSCXXSHARED='$(CXXSHARED)' JSINTERPRETERCXX='$(CXX)' + JSINTERPRETERLINKFLAGS='-ldl' ;; esac @@ -1309,7 +1311,9 @@ AC_SUBST(JSLIBRARYPREFIX) AC_SUBST(JSSO) AC_SUBST(JSLDSHARED) AC_SUBST(JSCXXSHARED) + AC_SUBST(JSINTERPRETERCXX) +AC_SUBST(JSINTERPRETERLINKFLAGS) AC_SUBST(JSCOREINC) AC_SUBST(JSCOREDYNAMICLINKING) From 94869c922861adc007e1cfffde279f2c4e554311 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 22:47:29 +0100 Subject: [PATCH 258/352] More gitignores filtering Javascript related files. --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index eb3aa012c..25cac8fec 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ # Editor files and various other junk *.sw? *.bak +*.log +.DS_Store # Local PCRE pcre @@ -23,6 +25,7 @@ pcre *.so *.so.* *.dylib +*.bundle # C/C++ static libraries, based on: # https://github.com/github/gitignore/blob/master/C.gitignore @@ -72,6 +75,7 @@ Lib/ocaml/swigp4.ml Source/Include/stamp-h1 Source/Include/swigconfig.h Source/Makefile +Tools/javascript/Makefile .deps config.log config.status @@ -86,6 +90,7 @@ Source/CParse/parser.c Source/CParse/parser.h Source/eswig swig +Tools/javascript/javascript # Generated documentation Doc/Manual/CCache.html @@ -103,6 +108,7 @@ Examples/test-suite/d/*/ Examples/test-suite/go/*/ Examples/test-suite/guile/*/ Examples/test-suite/java/*/ +Examples/test-suite/javascript/*/ Examples/test-suite/lua/*/ Examples/test-suite/mzscheme/*/ Examples/test-suite/ocaml/*/ @@ -115,6 +121,8 @@ Examples/test-suite/r/*/ Examples/test-suite/ruby/*/ Examples/test-suite/tcl/*/ Examples/test-suite/uffi/*/ +*_wrap.c +*_wrap.cxx # Python generated files, based on: # https://github.com/github/gitignore/blob/master/Python.gitignore From 348cb2026e2edad29003281ed9b0a2f43c10aa54 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 22:56:31 +0100 Subject: [PATCH 259/352] Fix regressions in configuration of some Javascript examples. --- Examples/javascript/constant/Makefile | 2 +- Examples/javascript/operator/Makefile | 2 +- Examples/javascript/overload/Makefile | 2 +- Examples/javascript/template/Makefile | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile index b0934786a..a2570636e 100755 --- a/Examples/javascript/constant/Makefile +++ b/Examples/javascript/constant/Makefile @@ -1,3 +1,3 @@ -SRCS = example.cxx +SRCS = include ../js_example.mk diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile index b0934786a..a2570636e 100755 --- a/Examples/javascript/operator/Makefile +++ b/Examples/javascript/operator/Makefile @@ -1,3 +1,3 @@ -SRCS = example.cxx +SRCS = include ../js_example.mk diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile index b0934786a..a2570636e 100755 --- a/Examples/javascript/overload/Makefile +++ b/Examples/javascript/overload/Makefile @@ -1,3 +1,3 @@ -SRCS = example.cxx +SRCS = include ../js_example.mk diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile index b0934786a..a2570636e 100755 --- a/Examples/javascript/template/Makefile +++ b/Examples/javascript/template/Makefile @@ -1,3 +1,3 @@ -SRCS = example.cxx +SRCS = include ../js_example.mk From 7e015e4acf3cb6644f2002d4457a589f1d76f69d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 26 Feb 2014 23:26:19 +0100 Subject: [PATCH 260/352] Fix regression in Javascript configuration. --- Tools/javascript/Makefile.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in index 32744333f..d1a5e1c98 100644 --- a/Tools/javascript/Makefile.in +++ b/Tools/javascript/Makefile.in @@ -14,7 +14,7 @@ CC = @CC@ # HACK: under OSX a g++ compiled interpreter is seg-faulting when loading module libraries # with 'c++' it works... probably some missing flags? -CXX = @JSINTERPRETERCXX@ +JSCXX = @JSINTERPRETERCXX@ CFLAGS = @BOOST_CPPFLAGS@ @PLATFLAGS@ LINKFLAGS = @JSINTERPRETERLINKFLAGS@ @@ -47,10 +47,10 @@ JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_ JS_INTERPRETER_OBJS = $(JS_INTERPRETER_SRC:.cxx=.o) %.o: %.cxx - $(CXX) $(JS_INTERPRETER_DEFINES) -g $(JSINCLUDES) -o $@ -c $< + $(JSCXX) $(JS_INTERPRETER_DEFINES) -g $(JSINCLUDES) -o $@ -c $< javascript: $(JS_INTERPRETER_OBJS) - $(CXX) $(LINKFLAGS) $^ $(CFLAGS) -o javascript $(JSDYNAMICLINKING) + $(JSCXX) $^ $(CFLAGS) -o javascript $(JSDYNAMICLINKING) $(LINKFLAGS) clean: rm -f *.o From b20b0f4e4b1626030c4155f22313af3ee0fd4e00 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 27 Feb 2014 01:02:06 +0100 Subject: [PATCH 261/352] Removed CMake. Started a separate project which acts as a CMake shell around SWIG. --- CMakeLists.txt | 173 ------------------------------------------------- 1 file changed, 173 deletions(-) delete mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 1bf7a2c76..000000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,173 +0,0 @@ -project(swig) -cmake_minimum_required(VERSION 2.8) - -# Project wide configuration variables -# ------------------------------------ - -set(SWIG_VERSION 2.0.6) -set(SWIG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/Source" CACHE INTERNAL "Path of swig sources" FORCE) - -# Configure -# --------- - -include(CheckIncludeFiles) -include(CheckIncludeFile) -include(CheckTypeSize) -include(CheckSymbolExists) -include(CheckLibraryExists) -include(CheckCSourceCompiles) - -# HACK: didn't get the bool check working for Visual Studio 2008 -if(MSVC) -set(HAVE_BOOL 1) -else() -set(CMAKE_EXTRA_INCLUDE_FILES stdbool.h) -check_type_size("bool" HAVE_BOOL) -set(CMAKE_EXTRA_INCLUDE_FILES) -endif() - -check_include_file("inttypes.h" HAVE_INTTYPES_H) -check_include_file("memory.h" HAVE_MEMORY_H) -check_include_file("stddef.h" HAVE_STDDEF_H) -check_include_file("stdint.h" HAVE_STDINT_H) -check_include_file("stdlib.h" HAVE_STDLIB_H) -check_include_file("string.h" HAVE_STRING_H) -check_include_file("strings.h" HAVE_STRINGS_H) -check_include_file("sys/stat.h" HAVE_SYS_STAT_H) -check_include_file("sys/types.h" HAVE_SYS_TYPES_H) -check_include_file("unistd.h" HAVE_UNISTD_H) -check_include_files( "stdlib.h;stdarg.h;string.h;float.h" HAVE_STDC_HEADERS ) - -check_library_exists(dl dlopen "" HAVE_LIBDL) - -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Tools/swigconfig.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/Source/Include/swigconfig.h) - -# Compiler flags -# -------------- - -include_directories("${SWIG_SOURCE_DIR}/CParse" - "${SWIG_SOURCE_DIR}/Include" - "${SWIG_SOURCE_DIR}/DOH" - "${SWIG_SOURCE_DIR}/Swig" - "${SWIG_SOURCE_DIR}/Preprocessor" - "${SWIG_SOURCE_DIR}/Modules" - "${PROJECT_BINARY_DIR}/Source/Include" -) - -# Pre-Build -# --------- - -# Copy Lib directory into the build dist folder -file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Dist) -file(COPY ${PROJECT_SOURCE_DIR}/Lib DESTINATION ${PROJECT_BINARY_DIR}/Dist) - -# add the command to generate the source code (depends on bison) -file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Source/CParse) -add_custom_command ( - OUTPUT ${PROJECT_BINARY_DIR}/Source/CParse/parser.c - DEPENDS ${SWIG_SOURCE_DIR}/CParse/parser.y - COMMAND bison -o ${PROJECT_BINARY_DIR}/Source/CParse/parser.c --defines=${PROJECT_BINARY_DIR}/Source/Include/parser.h ${SWIG_SOURCE_DIR}/CParse/parser.y -) -set_property(SOURCE ${PROJECT_BINARY_DIR}/Source/CParse/parser.c PROPERTY GENERATED 1) -set_property(SOURCE ${PROJECT_BINARY_DIR}/Source/CParse/parser.h PROPERTY GENERATED 1) - -# generate swigwarn.swg -file(READ ${SWIG_SOURCE_DIR}/Include/swigwarn.h SWIG_WARN_H) -string(REGEX REPLACE "#define WARN([^ \\t]*)[ \\t]*([0-9]+)" "%define SWIGWARN\\1 \\2 %enddef" SWIG_WARN_SWG ${SWIG_WARN_H}) -file(WRITE ${PROJECT_BINARY_DIR}/Dist/Lib/swigwarn.swg ${SWIG_WARN_SWG}) -set_property(SOURCE ${PROJECT_BINARY_DIR}/Dist/Lib/swigwarn.swg PROPERTY GENERATED 1) - -# Libraries -# --------- - -add_library(cparse "${SWIG_SOURCE_DIR}/CParse/cscanner.c" - "${SWIG_SOURCE_DIR}/CParse/templ.c" - "${SWIG_SOURCE_DIR}/CParse/util.c" - "${PROJECT_BINARY_DIR}/Source/CParse/parser.c" - "${PROJECT_BINARY_DIR}/Source/CParse/parser.h" -) - -add_library(preprocessor "${SWIG_SOURCE_DIR}/Preprocessor/cpp.c" - "${SWIG_SOURCE_DIR}/Preprocessor/expr.c" -) - -add_library(doh "${SWIG_SOURCE_DIR}/DOH/base.c" - "${SWIG_SOURCE_DIR}/DOH/file.c" - "${SWIG_SOURCE_DIR}/DOH/fio.c" - "${SWIG_SOURCE_DIR}/DOH/hash.c" - "${SWIG_SOURCE_DIR}/DOH/list.c" - "${SWIG_SOURCE_DIR}/DOH/memory.c" - "${SWIG_SOURCE_DIR}/DOH/string.c" - "${SWIG_SOURCE_DIR}/DOH/void.c" -) - -add_library(core "${SWIG_SOURCE_DIR}/Swig/cwrap.c" - "${SWIG_SOURCE_DIR}/Swig/deprecate.c" - "${SWIG_SOURCE_DIR}/Swig/error.c" - "${SWIG_SOURCE_DIR}/Swig/fragment.c" - "${SWIG_SOURCE_DIR}/Swig/getopt.c" - "${SWIG_SOURCE_DIR}/Swig/include.c" - "${SWIG_SOURCE_DIR}/Swig/misc.c" - "${SWIG_SOURCE_DIR}/Swig/naming.c" - "${SWIG_SOURCE_DIR}/Swig/parms.c" - "${SWIG_SOURCE_DIR}/Swig/scanner.c" - "${SWIG_SOURCE_DIR}/Swig/stype.c" - "${SWIG_SOURCE_DIR}/Swig/symbol.c" - "${SWIG_SOURCE_DIR}/Swig/tree.c" - "${SWIG_SOURCE_DIR}/Swig/typemap.c" - "${SWIG_SOURCE_DIR}/Swig/typeobj.c" - "${SWIG_SOURCE_DIR}/Swig/typesys.c" - "${SWIG_SOURCE_DIR}/Swig/wrapfunc.c" -) - -add_library(modules "${SWIG_SOURCE_DIR}/Modules/allegrocl.cxx" - "${SWIG_SOURCE_DIR}/Modules/allocate.cxx" - "${SWIG_SOURCE_DIR}/Modules/browser.cxx" - "${SWIG_SOURCE_DIR}/Modules/cffi.cxx" - "${SWIG_SOURCE_DIR}/Modules/chicken.cxx" - "${SWIG_SOURCE_DIR}/Modules/clisp.cxx" - "${SWIG_SOURCE_DIR}/Modules/contract.cxx" - "${SWIG_SOURCE_DIR}/Modules/csharp.cxx" - "${SWIG_SOURCE_DIR}/Modules/d.cxx" - "${SWIG_SOURCE_DIR}/Modules/directors.cxx" - "${SWIG_SOURCE_DIR}/Modules/emit.cxx" - "${SWIG_SOURCE_DIR}/Modules/go.cxx" - "${SWIG_SOURCE_DIR}/Modules/guile.cxx" - "${SWIG_SOURCE_DIR}/Modules/java.cxx" - "${SWIG_SOURCE_DIR}/Modules/javascript.cxx" - "${SWIG_SOURCE_DIR}/Modules/lang.cxx" - "${SWIG_SOURCE_DIR}/Modules/lua.cxx" - "${SWIG_SOURCE_DIR}/Modules/modula3.cxx" - "${SWIG_SOURCE_DIR}/Modules/module.cxx" - "${SWIG_SOURCE_DIR}/Modules/mzscheme.cxx" - "${SWIG_SOURCE_DIR}/Modules/ocaml.cxx" - "${SWIG_SOURCE_DIR}/Modules/octave.cxx" - "${SWIG_SOURCE_DIR}/Modules/overload.cxx" - "${SWIG_SOURCE_DIR}/Modules/perl5.cxx" - "${SWIG_SOURCE_DIR}/Modules/php.cxx" - "${SWIG_SOURCE_DIR}/Modules/pike.cxx" - "${SWIG_SOURCE_DIR}/Modules/python.cxx" - "${SWIG_SOURCE_DIR}/Modules/r.cxx" - "${SWIG_SOURCE_DIR}/Modules/ruby.cxx" - "${SWIG_SOURCE_DIR}/Modules/s-exp.cxx" - "${SWIG_SOURCE_DIR}/Modules/tcl8.cxx" - "${SWIG_SOURCE_DIR}/Modules/typepass.cxx" - "${SWIG_SOURCE_DIR}/Modules/uffi.cxx" - "${SWIG_SOURCE_DIR}/Modules/utils.cxx" - "${SWIG_SOURCE_DIR}/Modules/xml.cxx" - "${PROJECT_BINARY_DIR}/Source/Include/swigconfig.h" - "${SWIG_SOURCE_DIR}/Include/swigwarn.h" -) - -add_executable(swig - "${SWIG_SOURCE_DIR}/Modules/main.cxx" - "${SWIG_SOURCE_DIR}/Modules/swigmain.cxx" -) - -target_link_libraries(swig cparse preprocessor doh core modules) - -# copy binary into Dist folder -get_property(SWIG_EXECUTABLE TARGET swig PROPERTY LOCATION) -add_custom_command(TARGET swig POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy ${SWIG_EXECUTABLE} ${PROJECT_BINARY_DIR}/Dist -) From 70385842df0c68c4e7e7eeb4531f703330edb831 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Fri, 28 Feb 2014 10:40:41 +0100 Subject: [PATCH 262/352] Add missing copy ctor for Javascript Code Template class. --- Source/Modules/javascript.cxx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 7b153c66c..748043619 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -86,6 +86,8 @@ public: Template(const String *code, const String *templateName); + Template(const Template& other); + ~Template(); String *str(); @@ -620,7 +622,6 @@ Template JSEmitter::getTemplate(const String *name) { } Template t(templ, name); - return t; } @@ -2441,6 +2442,11 @@ Template& Template::pretty_print(DOH *doh) { return *this; } +Template::Template(const Template& t) { + code = NewString(t.code); + templateName = NewString(t.templateName); +} + void Template::operator=(const Template& t) { Delete(code); Delete(templateName); From dbd61e40e1c92aa02c3ce5170534687f7ae8d42f Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Mar 2014 10:41:35 +0100 Subject: [PATCH 263/352] Fix issues that were observed with newer JavascriptCore. --- Tools/javascript/Makefile.in | 2 +- Tools/javascript/js_shell.cxx | 1 + Tools/javascript/jsc_shell.cxx | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in index d1a5e1c98..f18cfa65d 100644 --- a/Tools/javascript/Makefile.in +++ b/Tools/javascript/Makefile.in @@ -47,7 +47,7 @@ JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_ JS_INTERPRETER_OBJS = $(JS_INTERPRETER_SRC:.cxx=.o) %.o: %.cxx - $(JSCXX) $(JS_INTERPRETER_DEFINES) -g $(JSINCLUDES) -o $@ -c $< + $(JSCXX) $(JS_INTERPRETER_DEFINES) $(CFLAGS) $(JSINCLUDES) -o $@ -c $< javascript: $(JS_INTERPRETER_OBJS) $(JSCXX) $^ $(CFLAGS) -o javascript $(JSDYNAMICLINKING) $(LINKFLAGS) diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx index 5890c922c..539b83d65 100644 --- a/Tools/javascript/js_shell.cxx +++ b/Tools/javascript/js_shell.cxx @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef __GNUC__ #ifdef __APPLE__ diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx index cf30d7bd7..292c4042b 100644 --- a/Tools/javascript/jsc_shell.cxx +++ b/Tools/javascript/jsc_shell.cxx @@ -64,9 +64,9 @@ bool JSCShell::InitializeEngine() { if(context == 0) return false; JSObjectRef globalObject = JSContextGetGlobalObject(context); - // store this for later use - JSClassDefinition __shell_classdef__; + JSClassDefinition __shell_classdef__ = JSClassDefinition(); + JSClassRef __shell_class__ = JSClassCreate(&__shell_classdef__); JSObjectRef __shell__ = JSObjectMake(context, __shell_class__, 0); bool success = JSObjectSetPrivate(__shell__, (void*) (long) this); From a9b8b85c1c1b2bfe5b9b389e6f9406258371d512 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Mar 2014 11:00:26 +0100 Subject: [PATCH 264/352] Minor change in Javascript configuration. --- configure.ac | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 720aebd04..c7527a87f 100644 --- a/configure.ac +++ b/configure.ac @@ -1195,12 +1195,6 @@ else *-*-linux*) dirs="/usr/lib/ /usr/local/lib/" for i in $dirs ; do - if test -r $i/libwebkit-1.0.la; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -lwebkit-1.0" - break - fi - if test -r $i/libjavascriptcoregtk-1.0.so; then AC_MSG_RESULT($i) JSCORELIB="-L$i -ljavascriptcoregtk-1.0" @@ -1212,6 +1206,12 @@ else JSCORELIB="-L$i -lwebkitgtk-1.0" break fi + + if test -r $i/libwebkit-1.0.la; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkit-1.0" + break + fi done if test -z "$JSCORELIB"; then From 1a7e12911ac96e8b788686076f35771ac248220d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Mar 2014 12:00:13 +0100 Subject: [PATCH 265/352] Adding a chapter about Javascript tests and examples. --- Doc/Manual/Javascript.md | 50 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 044343588..0394ccfde 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -57,6 +57,54 @@ and for v8: void example_initialize (v8::Handle exports) +### Running Tests and Examples + +The configuration for tests and examples currently supports Linux and Mac only, MinGW not yet. + +The default interpreter is `node.js` as it is available on all platforms and convenient to use. + +Running the examples with JavascriptCore requires `libjavascriptcoregtk-1.0` to be installed, e.g., under Ubuntu with + + $ sudo apt-get install libjavascriptcoregtk-1.0-dev + +Running with `V8` requires `libv8`: + + $ sudo apt-get install libv8-dev + +Examples can be run using + + $ make ENGINE=jsc check-javascript-examples + +`ENGINE` can be `node`, `jsc`, or `v8`. + +The test-suite can be run using + + $ make ENGINE=jsc check-javascript-test-suite + +A smaller, manually selected set of tests can be run using + + $ make SMOKE=1 ENGINE=jsc check-javascript-test-suite + + +Tests should run without any problems, i.e., have been tried out, on the following platforms/interpreters: + +- Ubuntu Precise 12.04 64bit + - JavascriptCore (GTK) 1.0 + - Node.js (0.10.26) + - v8 (3.7.12) +- Ubuntu Saucy 13.10 64bit + - JavascriptCore (GTK) 1.0 + 3.0 + - Node.js + - v8 (3.14.5) +- Mac OSX Mountain Lion 10.8 + - JavascriptCore (built-in) + - Node.js +- Windows 7 64bit (VS 2010) + - Node.js + +Note: a `CMake` based configuration can be found in the `cmake` branch on + [](https://github.com/oliver----/swig-v8) which can be used to generate a Visual Studio solution. It is rather limited building only the SWIG executable and Javascript examples. + ### Future work The Javascript module is not yet as mature as other modules and some things are still missing. @@ -79,7 +127,7 @@ We could work on that if requested: ## Integration -This should give a short introduction to integrating your module in different environments: as a `node.js` module, and as an extension for an embedded Webkit. +This chapter gives a short introduction how to use a native Javascript extension: as a `node.js` module, and as an extension for an embedded Webkit. ### Creating `node.js` Extensions From 6b82dff8f35d9ca743670a6131a87d493514c6b6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Mar 2014 22:50:23 +0100 Subject: [PATCH 266/352] Minor tweaks in Javascript documentation. --- Doc/Manual/Javascript.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 0394ccfde..73f17eabb 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -1,7 +1,7 @@ # SWIG and Javascript This chapter describes SWIG's support of Javascript. -It does not cover SWIG basics only information that is specific to this module. +It does not cover SWIG basics, but only information that is specific to this module. ## Overview @@ -88,19 +88,19 @@ A smaller, manually selected set of tests can be run using Tests should run without any problems, i.e., have been tried out, on the following platforms/interpreters: -- Ubuntu Precise 12.04 64bit - - JavascriptCore (GTK) 1.0 - - Node.js (0.10.26) - - v8 (3.7.12) -- Ubuntu Saucy 13.10 64bit - - JavascriptCore (GTK) 1.0 + 3.0 - - Node.js - - v8 (3.14.5) -- Mac OSX Mountain Lion 10.8 - - JavascriptCore (built-in) - - Node.js -- Windows 7 64bit (VS 2010) - - Node.js + - Ubuntu Precise 12.04 64bit + - JavascriptCore (Webkit 1.8.3) + - Node.js (0.10.26) + - v8 (3.7.12) + - Ubuntu Saucy 13.10 64bit + - JavascriptCore (Webkit 1.10.2) + - Node.js + - v8 (3.14.5) + - Mac OSX Mountain Lion 10.8 + - JavascriptCore (built-in) + - Node.js + - Windows 7 64bit (VS 2010) + - Node.js Note: a `CMake` based configuration can be found in the `cmake` branch on [](https://github.com/oliver----/swig-v8) which can be used to generate a Visual Studio solution. It is rather limited building only the SWIG executable and Javascript examples. From 924f373a2f6a58c4a8d40e6f61434a6e3f6df50b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Mar 2014 22:51:19 +0100 Subject: [PATCH 267/352] Fix pandoc filter. And add a script that helps to run pandoc with appropriate command line flags. --- Doc/Manual/markdown_to_html.sh | 9 +++++++++ Doc/Manual/pandoc_filter.py | 18 +++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) create mode 100755 Doc/Manual/markdown_to_html.sh diff --git a/Doc/Manual/markdown_to_html.sh b/Doc/Manual/markdown_to_html.sh new file mode 100755 index 000000000..925f62a64 --- /dev/null +++ b/Doc/Manual/markdown_to_html.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [ "$1" == "" ]; then + echo "Usage: markdown_to_html " + echo "-- Example: markdown_to_html Javascript" +else + pandoc -f markdown -t json $1.md | ./pandoc_filter.py | pandoc -f json -t html -s --template pandoc_template.html -o $1.html +fi + diff --git a/Doc/Manual/pandoc_filter.py b/Doc/Manual/pandoc_filter.py index f1e84904a..33ac3ffd6 100755 --- a/Doc/Manual/pandoc_filter.py +++ b/Doc/Manual/pandoc_filter.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python """ Pandoc filter that changes pandoc default HTML output for codeblocks @@ -24,16 +24,16 @@ the_title = "" def codeblocks(key, value, format, meta): if key == 'CodeBlock': [[id, classes, kvs], contents] = value - if format == "html" or format == "html5": - newcontents = [html('
\n' + contents + '
')] - if len(classes) == 0: - if contents.startswith("$"): - classes.append("shell") - else: - classes.append("code") + newcontents = [html('
\n' + contents + '
')] - return Div([id, classes, kvs], newcontents) + if len(classes) == 0: + if contents.startswith("$"): + classes.append("shell") + else: + classes.append("code") + + return Div([id, classes, kvs], newcontents) if key == 'Header': if value[0] == 1: the_title = stringify(value) From 8c05fe37afcbcd6a2fc2a7d8bbe028e6d8f59239 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 4 Mar 2014 22:55:32 +0100 Subject: [PATCH 268/352] Removed obsolete paragraph from Javascript documentation. --- Doc/Manual/Javascript.md | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md index 73f17eabb..36dfa7c2f 100644 --- a/Doc/Manual/Javascript.md +++ b/Doc/Manual/Javascript.md @@ -273,17 +273,6 @@ An integration of a native extension 'example' would look like this: return 0; } - -### Embedded V8 - -It is possible to create a custom application like `node.js` embedding a v8 engine. - -TODO: -- how to install v8 -- v8 version issues: command-line switch, pre-processor macro -- sample integration code - - ## Examples Some basic examples are shown here in more detail. From b5bc87667d62fa05a31ab85ba0b7894f83d7cdce Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 5 Mar 2014 01:10:55 +0100 Subject: [PATCH 269/352] Fix regressions. - Adapted to changes in UTL - Fixed detection of setters and getters. --- Lib/javascript/jsc/javascriptstrings.swg | 2 ++ Source/Modules/javascript.cxx | 23 +++++++++++++++++++---- Tools/javascript/Makefile.in | 7 ++++--- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg index 26908d9da..0581c1920 100644 --- a/Lib/javascript/jsc/javascriptstrings.swg +++ b/Lib/javascript/jsc/javascriptstrings.swg @@ -78,6 +78,7 @@ SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t siz SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize, SWIG_CharPtrLen, + SWIG_CharBufLen, SWIG_NewCopyCharArray, SWIG_DeleteCharArray, FragLimits, CHAR_MIN, CHAR_MAX) @@ -167,6 +168,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val) SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize, SWIG_CharPtrLen, + SWIG_CharBufLen, SWIG_As##CharName##Ptr, SWIG_From##CharName##Ptr, SWIG_As##CharName##Array, diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 748043619..53af47665 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -492,6 +492,14 @@ int JAVASCRIPT::top(Node *n) { return SWIG_OK; } +static const char *usage = (char *) "\ +Javascript Options (available with -javascript)\n\ + -jsc - creates a JavascriptCore extension \n\ + -v8 - creates a v8 extension \n\ + -node - creates a node.js extension \n\ + -debug-codetemplates - generates information about the origin of code templates.\n"; + + /* --------------------------------------------------------------------- * main() * @@ -522,6 +530,9 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { Swig_mark_arg(i); js_template_enable_debug = true; + } else if (strcmp(argv[i], "-help") == 0) { + fputs(usage, stdout); + return; } } } @@ -704,14 +715,18 @@ int JSEmitter::emitWrapperFunction(Node *n) { if (GetFlag(n, "allocate:smartpointeraccess")) { is_static = false; } - bool is_setter = GetFlag(n, "wrap:issetter"); + + bool is_member = GetFlag(n, "ismember"); + bool is_setter = GetFlag(n, "memberset") || GetFlag(n, "varset"); + bool is_getter = GetFlag(n, "memberget") || GetFlag(n, "varget"); if (is_setter) { - bool is_member = GetFlag(n, "memberset"); ret = emitSetter(n, is_member, is_static); - } else { - bool is_member = GetFlag(n, "memberget"); + } else if (is_getter) { ret = emitGetter(n, is_member, is_static); + } else { + Swig_print_node(n); } + } else { Printf(stderr, "Warning: unsupported wrapper function type\n"); Swig_print_node(n); diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in index f18cfa65d..d58412b50 100644 --- a/Tools/javascript/Makefile.in +++ b/Tools/javascript/Makefile.in @@ -15,7 +15,8 @@ CC = @CC@ # HACK: under OSX a g++ compiled interpreter is seg-faulting when loading module libraries # with 'c++' it works... probably some missing flags? JSCXX = @JSINTERPRETERCXX@ -CFLAGS = @BOOST_CPPFLAGS@ @PLATFLAGS@ +CFLAGS = @PLATCFLAGS@ +CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ LINKFLAGS = @JSINTERPRETERLINKFLAGS@ ROOT_DIR = @ROOT_DIR@ @@ -47,10 +48,10 @@ JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_ JS_INTERPRETER_OBJS = $(JS_INTERPRETER_SRC:.cxx=.o) %.o: %.cxx - $(JSCXX) $(JS_INTERPRETER_DEFINES) $(CFLAGS) $(JSINCLUDES) -o $@ -c $< + $(JSCXX) $(JS_INTERPRETER_DEFINES) $(CXXFLAGS) $(JSINCLUDES) -o $@ -c $< javascript: $(JS_INTERPRETER_OBJS) - $(JSCXX) $^ $(CFLAGS) -o javascript $(JSDYNAMICLINKING) $(LINKFLAGS) + $(JSCXX) $^ $(CXXFLAGS) -o javascript $(JSDYNAMICLINKING) $(LINKFLAGS) clean: rm -f *.o From 89610e984ea3732a7da7bfc6bea1ffed2039201e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 5 Mar 2014 01:39:26 +0100 Subject: [PATCH 270/352] Beautified Javascript module. --- Source/Modules/javascript.cxx | 574 ++++++++++++++++------------------ 1 file changed, 266 insertions(+), 308 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 53af47665..eae594727 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -50,27 +50,27 @@ public: ~JSEmitterState(); - DOH *global(); + DOH *global (); - DOH *global(const char* key, DOH *initial = 0); + DOH *global (const char *key, DOH *initial = 0); DOH *clazz(bool reset = false); - DOH *clazz(const char* key, DOH *initial = 0); + DOH *clazz(const char *key, DOH *initial = 0); DOH *function(bool reset = false); - DOH *function(const char* key, DOH *initial = 0); + DOH *function(const char *key, DOH *initial = 0); DOH *variable(bool reset = false); - DOH *variable(const char* key, DOH *initial = 0); + DOH *variable(const char *key, DOH *initial = 0); static int IsSet(DOH *val); private: - DOH *getState(const char* key, bool reset = false); + DOH *getState(const char *key, bool reset = false); Hash *_global; }; @@ -84,23 +84,23 @@ class Template { public: Template(const String *code); - Template(const String *code, const String *templateName); + Template(const String *code, const String *templateName); - Template(const Template& other); + Template(const Template & other); ~Template(); String *str(); - Template& replace(const String *pattern, const String *repl); + Template & replace(const String *pattern, const String *repl); - Template& print(DOH *doh); + Template & print(DOH *doh); - Template& pretty_print(DOH *doh); + Template & pretty_print(DOH *doh); - void operator=(const Template& t); + void operator=(const Template & t); - Template& trim(); + Template & trim(); private: @@ -133,9 +133,9 @@ public: V8 }; - JSEmitter(); + JSEmitter(); - virtual ~JSEmitter(); + virtual ~ JSEmitter(); /** * Opens output files and temporary output DOHs. @@ -220,7 +220,7 @@ public: */ Template getTemplate(const String *name); - State &getState(); + State & getState(); protected: @@ -255,7 +255,7 @@ protected: virtual String *emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg); - virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult=0, bool emitReturnVariable = true); + virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult = 0, bool emitReturnVariable = true); virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params); @@ -303,9 +303,8 @@ class JAVASCRIPT:public Language { public: - JAVASCRIPT(): emitter(NULL) {} - - ~JAVASCRIPT() { + JAVASCRIPT():emitter(NULL) { + } ~JAVASCRIPT() { delete emitter; } @@ -327,7 +326,7 @@ public: private: - JSEmitter *emitter; + JSEmitter * emitter; }; /* --------------------------------------------------------------------- @@ -515,24 +514,24 @@ void JAVASCRIPT::main(int argc, char *argv[]) { for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i], "-v8") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::V8; - SWIG_library_directory("javascript/v8"); + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); } else if (strcmp(argv[i], "-jsc") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::JavascriptCore; - SWIG_library_directory("javascript/jsc"); + Swig_mark_arg(i); + mode = JSEmitter::JavascriptCore; + SWIG_library_directory("javascript/jsc"); } else if (strcmp(argv[i], "-node") == 0) { - Swig_mark_arg(i); - mode = JSEmitter::V8; - SWIG_library_directory("javascript/v8"); - Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { - Swig_mark_arg(i); - js_template_enable_debug = true; + Swig_mark_arg(i); + js_template_enable_debug = true; } else if (strcmp(argv[i], "-help") == 0) { - fputs(usage, stdout); - return; + fputs(usage, stdout); + return; } } } @@ -591,12 +590,7 @@ extern "C" Language *swig_javascript(void) { * ----------------------------------------------------------------------------- */ JSEmitter::JSEmitter() -: templates(NewHash()), - namespaces(NULL), - current_namespace(NULL), - defaultResultName(NewString("result")), - f_wrappers(NULL) -{ +: templates(NewHash()), namespaces(NULL), current_namespace(NULL), defaultResultName(NewString("result")), f_wrappers(NULL) { } /* ----------------------------------------------------------------------------- @@ -614,8 +608,8 @@ JSEmitter::~JSEmitter() { * ----------------------------------------------------------------------------- */ int JSEmitter::registerTemplate(const String *name, const String *code) { - if (!State::IsSet(state.global(HAS_TEMPLATES))) { - SetFlag(state.global(), HAS_TEMPLATES); + if (!State::IsSet(state.global (HAS_TEMPLATES))) { + SetFlag(state.global (), HAS_TEMPLATES); } return Setattr(templates, name, code); } @@ -636,13 +630,13 @@ Template JSEmitter::getTemplate(const String *name) { return t; } -JSEmitterState &JSEmitter::getState() { +JSEmitterState & JSEmitter::getState() { return state; } -int JSEmitter::initialize(Node * /*n*/) { +int JSEmitter::initialize(Node * /*n */ ) { - if(namespaces != NULL) { + if (namespaces != NULL) { Delete(namespaces); } namespaces = NewHash(); @@ -702,10 +696,10 @@ int JSEmitter::emitWrapperFunction(Node *n) { if (kind) { if (Equal(kind, "function") - // HACK: sneaky.ctest revealed that typedef'd (global) functions must be - // detected via the 'view' attribute. - || (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler")) - ) { + // HACK: sneaky.ctest revealed that typedef'd (global) functions must be + // detected via the 'view' attribute. + || (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler")) + ) { bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); bool is_static = GetFlag(state.function(), IS_STATIC); ret = emitFunction(n, is_member, is_static); @@ -713,18 +707,18 @@ int JSEmitter::emitWrapperFunction(Node *n) { bool is_static = GetFlag(state.variable(), IS_STATIC); // HACK: smartpointeraccessed static variables are not treated as statics if (GetFlag(n, "allocate:smartpointeraccess")) { - is_static = false; + is_static = false; } bool is_member = GetFlag(n, "ismember"); bool is_setter = GetFlag(n, "memberset") || GetFlag(n, "varset"); bool is_getter = GetFlag(n, "memberget") || GetFlag(n, "varget"); if (is_setter) { - ret = emitSetter(n, is_member, is_static); + ret = emitSetter(n, is_member, is_static); } else if (is_getter) { - ret = emitGetter(n, is_member, is_static); + ret = emitGetter(n, is_member, is_static); } else { - Swig_print_node(n); + Swig_print_node(n); } } else { @@ -784,7 +778,7 @@ int JSEmitter::enterClass(Node *n) { int JSEmitter::enterFunction(Node *n) { state.function(RESET); state.function(NAME, Getattr(n, "sym:name")); - if(Equal(Getattr(n, "storage"), "static")) { + if (Equal(Getattr(n, "storage"), "static")) { SetFlag(state.function(), IS_STATIC); } return SWIG_OK; @@ -803,14 +797,13 @@ int JSEmitter::enterVariable(Node *n) { state.variable(NAME, Swig_scopename_last(Getattr(n, "sym:name"))); } - if(Equal(Getattr(n, "storage"), "static")) { + if (Equal(Getattr(n, "storage"), "static")) { SetFlag(state.variable(), IS_STATIC); } if (!Language::instance()->is_assignable(n)) { SetFlag(state.variable(), IS_IMMUTABLE); } - // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] if (Equal(Getattr(n, "type"), "a().char")) { SetFlag(state.variable(), IS_IMMUTABLE); @@ -829,7 +822,7 @@ int JSEmitter::emitCtor(Node *n) { //String *mangled_name = SwigType_manglestr(Getattr(n, "name")); String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); - if(is_overloaded) { + if (is_overloaded) { t_ctor = getTemplate("js_overloaded_ctor"); Append(wrap_name, Getattr(n, "sym:overname")); } @@ -869,14 +862,14 @@ int JSEmitter::emitCtor(Node *n) { DelWrapper(wrapper); // create a dispatching ctor - if(is_overloaded) { + if (is_overloaded) { if (!Getattr(n, "sym:nextSibling")) { String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); Template t_mainctor(getTemplate("js_ctor_dispatcher")); t_mainctor.replace("$jswrapper", wrap_name) - .replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS)) - .pretty_print(f_wrappers); + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS)) + .pretty_print(f_wrappers); state.clazz(CTOR, wrap_name); } } else { @@ -895,37 +888,37 @@ int JSEmitter::emitDtor(Node *n) { String *ctype = SwigType_lstr(p_classtype, ""); String *free = NewString(""); - // (Taken from JSCore implementation.) + // (Taken from JSCore implementation.) /* The if (Extend) block was taken from the Ruby implementation. * The problem is that in the case of an %extend to create a destructor for a struct to coordinate automatic memory cleanup with the Javascript collector, * the swig function was not being generated. More specifically: - struct MyData { - %extend { - ~MyData() { - FreeData($self); - } - } - }; - %newobject CreateData; - struct MyData* CreateData(void); - %delobject FreeData; - void FreeData(struct MyData* the_data); + struct MyData { + %extend { + ~MyData() { + FreeData($self); + } + } + }; + %newobject CreateData; + struct MyData* CreateData(void); + %delobject FreeData; + void FreeData(struct MyData* the_data); - where the use case is something like: - var my_data = example.CreateData(); - my_data = null; + where the use case is something like: + var my_data = example.CreateData(); + my_data = null; - This function was not being generated: - SWIGINTERN void delete_MyData(struct MyData *self){ - FreeData(self); - } + This function was not being generated: + SWIGINTERN void delete_MyData(struct MyData *self){ + FreeData(self); + } - I don't understand fully why it wasn't being generated. It just seems to happen in the Lua generator. - There is a comment about staticmemberfunctionHandler having an inconsistency and I tracked down dome of the SWIGINTERN void delete_* - code to that function in the Language base class. - The Ruby implementation seems to have an explicit check for if(Extend) and explicitly generates the code, so that's what I'm doing here. - The Ruby implementation does other stuff which I omit. - */ + I don't understand fully why it wasn't being generated. It just seems to happen in the Lua generator. + There is a comment about staticmemberfunctionHandler having an inconsistency and I tracked down dome of the SWIGINTERN void delete_* + code to that function in the Language base class. + The Ruby implementation seems to have an explicit check for if(Extend) and explicitly generates the code, so that's what I'm doing here. + The Ruby implementation does other stuff which I omit. + */ if (Extend) { String *wrap = Getattr(n, "wrap:code"); if (wrap) { @@ -933,77 +926,75 @@ int JSEmitter::emitDtor(Node *n) { } } - // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node // TODO: generate dtors more similar to other wrappers // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used. - if(SwigType_isarray(type)) { + if (SwigType_isarray(type)) { Printf(free, "delete [] (%s)", ctype); } else { Printf(free, "delete (%s)", ctype); } - String* destructor_action = Getattr(n, "wrap:action"); + String *destructor_action = Getattr(n, "wrap:action"); // Adapted from the JSCore implementation. /* The next challenge is to generate the correct finalize function for JavaScriptCore to call. Originally, it would use this fragment from javascriptcode.swg - %fragment ("JS_destructordefn", "templates") + %fragment ("JS_destructordefn", "templates") %{ void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) { - SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); - if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject); - if(t) free(t); + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject); + if(t) free(t); } %} But for the above example case of %extend to define a destructor on a struct, we need to override the system to not call free ((${type}*)t->swigCObject); - and substitute it with what the user has provided. + and substitute it with what the user has provided. To solve this, I created a variation fragment called JS_destructoroverridedefn: SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) { - ${type}* arg1 = (${type}*)t->swigCObject; - ${destructor_action} + ${type}* arg1 = (${type}*)t->swigCObject; + ${destructor_action} } if(t) free(t); - Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action") - to decide if the user has a preferred destructor action. - Based on that, I decide which fragment to use. - And in the case of the custom action, I substitute that action in. - I noticed that destructor_action has the form - delete_MyData(arg1); + Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action") + to decide if the user has a preferred destructor action. + Based on that, I decide which fragment to use. + And in the case of the custom action, I substitute that action in. + I noticed that destructor_action has the form + delete_MyData(arg1); The explicit arg1 is a little funny, so I structured the fragment to create a temporary variable called arg1 to make the generation easier. This might suggest this solution misunderstands a more complex case. - Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above. - So this code doesn't actually quite work as I expect. The end result is that the code still works because - destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is wierd. - I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free. + Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above. + So this code doesn't actually quite work as I expect. The end result is that the code still works because + destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is wierd. + I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free. - Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above. - But I don't fully understand the conditions of any of these things, and since it works for the moment, I don't want to break more stuff. - */ - if(destructor_action) { + Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above. + But I don't fully understand the conditions of any of these things, and since it works for the moment, I don't want to break more stuff. + */ + if (destructor_action) { Template t_dtor = getTemplate("js_dtoroverride"); state.clazz(DTOR, wrap_name); t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) - .replace("$jswrapper", wrap_name) - .replace("$jsfree", free) - .replace("$jstype", ctype); + .replace("$jswrapper", wrap_name) + .replace("$jsfree", free) + .replace("$jstype", ctype); t_dtor.replace("${destructor_action}", destructor_action); Wrapper_pretty_print(t_dtor.str(), f_wrappers); - } - else { + } else { Template t_dtor = getTemplate("js_dtor"); state.clazz(DTOR, wrap_name); t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jswrapper", wrap_name) - .replace("$jsfree", free) - .replace("$jstype", ctype) - .pretty_print(f_wrappers); + .replace("$jswrapper", wrap_name) + .replace("$jsfree", free) + .replace("$jstype", ctype) + .pretty_print(f_wrappers); } Delete(p_classtype); @@ -1091,7 +1082,7 @@ int JSEmitter::emitConstant(Node *n) { // a lot of SWIG internal constants were emitted // This didn't happen on other platforms yet... // we ignore those premature definitions - if (!State::IsSet(state.global(HAS_TEMPLATES))) { + if (!State::IsSet(state.global (HAS_TEMPLATES))) { return SWIG_ERROR; } @@ -1197,12 +1188,11 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { do { String *siblname = Getattr(sibl, "wrap:name"); - if (siblname) - { + if (siblname) { // handle function overloading Template t_dispatch_case = getTemplate("js_function_dispatch_case"); t_dispatch_case.replace("$jswrapper", siblname) - .replace("$jsargcount", Getattr(sibl, ARGCOUNT)); + .replace("$jsargcount", Getattr(sibl, ARGCOUNT)); Append(wrapper->code, t_dispatch_case.str()); } @@ -1219,7 +1209,7 @@ int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { String *overname = Getattr(n, "sym:overname"); int l1 = Len(wrap_name); int l2 = Len(overname); - Delslice(wrap_name, l1-l2, l1); + Delslice(wrap_name, l1 - l2, l1); Setattr(n, "wrap:name", wrap_name); state.function(WRAPPER_NAME, wrap_name); @@ -1267,9 +1257,11 @@ void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, Strin Parm *p; // adds a declaration for the result variable - if(emitReturnVariable) emit_return_variable(n, type, wrapper); + 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 (cresult == 0) + cresult = defaultResultName; tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode); bool should_own = GetFlag(n, "feature:new"); @@ -1294,11 +1286,11 @@ void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, Strin if (params) { for (p = params; p;) { if ((tm = Getattr(p, "tmap:argout"))) { - Replaceall(tm, "$input", Getattr(p, "emit:input")); - Printv(wrapper->code, tm, "\n", NIL); - p = Getattr(p, "tmap:argout:next"); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:argout:next"); } else { - p = nextSibling(p); + p = nextSibling(p); } } } @@ -1348,7 +1340,7 @@ int JSEmitter::switchNamespace(Node *n) { if (nspace == NULL) { // enums and constants do not have 'sym:nspace' set // so we try to get the namespace from the qualified name - if(Equal(Getattr(n, "nodeType"), "enumitem")) { + if (Equal(Getattr(n, "nodeType"), "enumitem")) { nspace = Swig_scopename_prefix(Getattr(n, "name")); } } @@ -1457,14 +1449,7 @@ private: }; JSCEmitter::JSCEmitter() -: JSEmitter(), - NULL_STR(NewString("NULL")), - VETO_SET(NewString("JS_veto_set_variable")), - f_wrap_cpp(NULL), - f_runtime(NULL), - f_header(NULL), - f_init(NULL) -{ +: JSEmitter(), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), f_init(NULL) { } JSCEmitter::~JSCEmitter() { @@ -1488,10 +1473,9 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma // determine an offset index, as members have an extra 'this' argument // except: static members and ctors. int startIdx = 0; - if (is_member && !is_static && mode!=Ctor) { + if (is_member && !is_static && mode != Ctor) { startIdx = 1; } - // store number of arguments for argument checks int num_args = emit_num_arguments(parms) - startIdx; String *argcount = NewString(""); @@ -1512,16 +1496,16 @@ void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Ma case Getter: case Function: if (is_member && !is_static && i == 0) { - Printv(arg, "thisObject", 0); + Printv(arg, "thisObject", 0); } else { - Printf(arg, "argv[%d]", i - startIdx); + Printf(arg, "argv[%d]", i - startIdx); } break; case Setter: if (is_member && !is_static && i == 0) { - Printv(arg, "thisObject", 0); + Printv(arg, "thisObject", 0); } else { - Printv(arg, "value", 0); + Printv(arg, "value", 0); } break; case Ctor: @@ -1559,9 +1543,9 @@ int JSCEmitter::initialize(Node *n) { f_init = NewString(""); f_header = NewString(""); - state.global(CREATE_NAMESPACES, NewString("")); - state.global(REGISTER_NAMESPACES, NewString("")); - state.global(INITIALIZER, NewString("")); + state.global (CREATE_NAMESPACES, NewString("")); + state.global (REGISTER_NAMESPACES, NewString("")); + state.global (INITIALIZER, NewString("")); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("begin", f_wrap_cpp); @@ -1594,10 +1578,10 @@ int JSCEmitter::dump(Node *n) { // compose the initializer function using a template Template initializer(getTemplate("js_initializer")); initializer.replace("$jsname", module) - .replace("$jsregisterclasses", state.global(INITIALIZER)) - .replace("$jscreatenamespaces", state.global(CREATE_NAMESPACES)) - .replace("$jsregisternamespaces", state.global(REGISTER_NAMESPACES)) - .pretty_print(f_init); + .replace("$jsregisterclasses", state.global (INITIALIZER)) + .replace("$jscreatenamespaces", state.global (CREATE_NAMESPACES)) + .replace("$jsregisternamespaces", state.global (REGISTER_NAMESPACES)) + .pretty_print(f_init); Printv(f_wrap_cpp, f_init, 0); @@ -1671,7 +1655,7 @@ int JSCEmitter::exitVariable(Node *n) { if (GetFlag(n, "ismember")) { if (GetFlag(state.variable(), IS_STATIC) - || Equal(Getattr(n, "nodeType"), "enumitem")) { + || Equal(Getattr(n, "nodeType"), "enumitem")) { Append(state.clazz(STATIC_VARIABLES), t_variable.str()); } else { Append(state.clazz(MEMBER_VARIABLES), t_variable.str()); @@ -1711,11 +1695,11 @@ int JSCEmitter::exitClass(Node *n) { //Append(f_wrappers, state.clazz(CTOR_WRAPPERS)); // for abstract classes add a vetoing ctor - if(GetFlag(state.clazz(), IS_ABSTRACT)) { + if (GetFlag(state.clazz(), IS_ABSTRACT)) { Template t_veto_ctor(getTemplate("js_veto_ctor")); t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) - .replace("$jsname", state.clazz(NAME)) - .pretty_print(f_wrappers); + .replace("$jsname", state.clazz(NAME)) + .pretty_print(f_wrappers); } /* adds a class template statement to initializer function */ @@ -1727,12 +1711,12 @@ int JSCEmitter::exitClass(Node *n) { if (base_class != NULL) { Template t_inherit(getTemplate("jsc_class_inherit")); t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsbaseclassmangled", SwigType_manglestr(Getattr(base_class, "name"))) - .pretty_print(jsclass_inheritance); + .replace("$jsbaseclassmangled", SwigType_manglestr(Getattr(base_class, "name"))) + .pretty_print(jsclass_inheritance); } else { Template t_inherit(getTemplate("jsc_class_noinherit")); t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .pretty_print(jsclass_inheritance); + .pretty_print(jsclass_inheritance); } t_classtemplate.replace("$jsmangledname", state.clazz(NAME_MANGLED)) @@ -1740,7 +1724,7 @@ int JSCEmitter::exitClass(Node *n) { .replace("$jsclass_inheritance", jsclass_inheritance) .replace("$jsctor", state.clazz(CTOR)) .replace("$jsdtor", state.clazz(DTOR)) - .pretty_print(state.global(INITIALIZER)); + .pretty_print(state.global (INITIALIZER)); Delete(jsclass_inheritance); /* Note: this makes sure that there is a swig_type added for this class */ @@ -1750,8 +1734,8 @@ int JSCEmitter::exitClass(Node *n) { Template t_registerclass(getTemplate("jsc_class_registration")); t_registerclass.replace("$jsname", state.clazz(NAME)) .replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsnspace", Getattr(state.clazz("nspace"),NAME_MANGLED)) - .pretty_print(state.global(INITIALIZER)); + .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED)) + .pretty_print(state.global (INITIALIZER)); return SWIG_OK; } @@ -1778,21 +1762,21 @@ int JSCEmitter::emitNamespaces() { Template namespace_definition(getTemplate("jsc_nspace_declaration")); namespace_definition.replace("$jsglobalvariables", variables) - .replace("$jsglobalfunctions", functions) - .replace("$jsnspace", name_mangled) - .pretty_print(f_wrap_cpp); + .replace("$jsglobalfunctions", functions) + .replace("$jsnspace", name_mangled) + .pretty_print(f_wrap_cpp); Template t_createNamespace(getTemplate("jsc_nspace_definition")); t_createNamespace.replace("$jsmangledname", name_mangled); - Append(state.global(CREATE_NAMESPACES), t_createNamespace.str()); + Append(state.global (CREATE_NAMESPACES), t_createNamespace.str()); // Don't register 'exports' as namespace. It is return to the application. if (!Equal("exports", name)) { Template t_registerNamespace(getTemplate("jsc_nspace_registration")); t_registerNamespace.replace("$jsmangledname", name_mangled) - .replace("$jsname", name) - .replace("$jsparent", parent_mangled); - Append(state.global(REGISTER_NAMESPACES), t_registerNamespace.str()); + .replace("$jsname", name) + .replace("$jsparent", parent_mangled); + Append(state.global (REGISTER_NAMESPACES), t_registerNamespace.str()); } } @@ -1808,13 +1792,13 @@ JSEmitter *swig_javascript_create_JSCEmitter() { * V8: JSEmitter implementation for V8 engine **********************************************************************/ -class V8Emitter: public JSEmitter { +class V8Emitter:public JSEmitter { public: V8Emitter(); - virtual ~V8Emitter(); + virtual ~ V8Emitter(); virtual int initialize(Node *n); virtual int dump(Node *n); virtual int close(); @@ -1853,37 +1837,32 @@ private: // the output cpp file File *f_wrap_cpp; - String* NULL_STR; + String *NULL_STR; String *VETO_SET; String *moduleName; }; V8Emitter::V8Emitter() -: JSEmitter(), - NULL_STR(NewString("0")), - VETO_SET(NewString("JS_veto_set_variable")) -{ +: JSEmitter(), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) { } -V8Emitter::~V8Emitter() -{ +V8Emitter::~V8Emitter() { Delete(NULL_STR); Delete(VETO_SET); } -int V8Emitter::initialize(Node *n) -{ +int V8Emitter::initialize(Node *n) { JSEmitter::initialize(n); - moduleName = Getattr(n,"name"); + moduleName = Getattr(n, "name"); // Get the output file name - String *outfile = Getattr(n,"outfile"); + String *outfile = Getattr(n, "outfile"); f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); if (!f_wrap_cpp) { - FileErrorDisplay(outfile); - SWIG_exit(EXIT_FAILURE); + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); } f_runtime = NewString(""); @@ -1912,12 +1891,11 @@ int V8Emitter::initialize(Node *n) return SWIG_OK; } -int V8Emitter::dump(Node *n) -{ +int V8Emitter::dump(Node *n) { /* Get the module name */ String *module = Getattr(n, "name"); - // write the swig banner + // write the swig banner Swig_banner(f_wrap_cpp); Template initializer_define(getTemplate("js_initializer_define")); @@ -1936,14 +1914,14 @@ int V8Emitter::dump(Node *n) // filled with sub-parts Template initializer(getTemplate("js_initializer")); initializer.replace("$jsname", moduleName) - .replace("$jsv8nspaces", f_init_namespaces) - .replace("$jsv8classtemplates", f_init_class_templates) - .replace("$jsv8wrappers", f_init_wrappers) - .replace("$jsv8inheritance", f_init_inheritance) - .replace("$jsv8classinstances", f_init_class_instances) - .replace("$jsv8staticwrappers", f_init_static_wrappers) - .replace("$jsv8registerclasses", f_init_register_classes) - .replace("$jsv8registernspaces", f_init_register_namespaces); + .replace("$jsv8nspaces", f_init_namespaces) + .replace("$jsv8classtemplates", f_init_class_templates) + .replace("$jsv8wrappers", f_init_wrappers) + .replace("$jsv8inheritance", f_init_inheritance) + .replace("$jsv8classinstances", f_init_class_instances) + .replace("$jsv8staticwrappers", f_init_static_wrappers) + .replace("$jsv8registerclasses", f_init_register_classes) + .replace("$jsv8registernspaces", f_init_register_namespaces); Printv(f_init, initializer.str(), 0); Printv(f_wrap_cpp, f_init, 0); @@ -1953,8 +1931,7 @@ int V8Emitter::dump(Node *n) return SWIG_OK; } -int V8Emitter::close() -{ +int V8Emitter::close() { Delete(f_runtime); Delete(f_header); Delete(f_class_templates); @@ -1972,8 +1949,7 @@ int V8Emitter::close() return SWIG_OK; } -int V8Emitter::enterClass(Node *n) -{ +int V8Emitter::enterClass(Node *n) { JSEmitter::enterClass(n); // emit declaration of a v8 class template @@ -1985,13 +1961,12 @@ int V8Emitter::enterClass(Node *n) return SWIG_OK; } -int V8Emitter::exitClass(Node *n) -{ - if(GetFlag(state.clazz(), IS_ABSTRACT)) { +int V8Emitter::exitClass(Node *n) { + if (GetFlag(state.clazz(), IS_ABSTRACT)) { Template t_veto_ctor(getTemplate("js_veto_ctor")); t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) - .replace("$jsname", state.clazz(NAME)) - .pretty_print(f_wrappers); + .replace("$jsname", state.clazz(NAME)) + .pretty_print(f_wrappers); } /* Note: this makes sure that there is a swig_type added for this class */ @@ -2018,33 +1993,31 @@ int V8Emitter::exitClass(Node *n) .pretty_print(f_init_class_instances); // emit inheritance setup - Node* baseClass = getBaseClass(n); - if(baseClass) { + Node *baseClass = getBaseClass(n); + if (baseClass) { String *base_name = Getattr(baseClass, "name"); Template t_inherit = getTemplate("jsv8_inherit"); String *base_name_mangled = SwigType_manglestr(base_name); - t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsbaseclass", base_name_mangled) - .trim() - .pretty_print(f_init_inheritance); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsbaseclass", 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"); t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.clazz(NAME)) - .replace("$jsparent", Getattr(state.clazz("nspace"),NAME_MANGLED)) + .replace("$jsname", state.clazz(NAME)) + .replace("$jsparent", Getattr(state.clazz("nspace"), NAME_MANGLED)) .trim() .pretty_print(f_init_register_classes); return SWIG_OK; } -int V8Emitter::enterVariable(Node* n) -{ +int V8Emitter::enterVariable(Node *n) { JSEmitter::enterVariable(n); state.variable(GETTER, NULL_STR); @@ -2053,43 +2026,40 @@ int V8Emitter::enterVariable(Node* n) return SWIG_OK; } -int V8Emitter::exitVariable(Node* n) -{ - if(GetFlag(n, "ismember")) { - if(GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem") ) { +int V8Emitter::exitVariable(Node *n) { + if (GetFlag(n, "ismember")) { + if (GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) { Template t_register = getTemplate("jsv8_register_static_variable"); t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)) - .trim(). - print(f_init_static_wrappers); + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim().print(f_init_static_wrappers); } else { Template t_register = getTemplate("jsv8_register_member_variable"); t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)) - .trim() - .print(f_init_wrappers); + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim() + .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"); t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED)) - .replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)) - .trim() - .print(f_init_wrappers); + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim() + .print(f_init_wrappers); } return SWIG_OK; } -int V8Emitter::exitFunction(Node* n) -{ +int V8Emitter::exitFunction(Node *n) { bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); // create a dispatcher for overloaded functions @@ -2103,33 +2073,32 @@ int V8Emitter::exitFunction(Node* n) return SWIG_OK; } } - // register the function at the specific context - if(is_member) { - if(GetFlag(state.function(), IS_STATIC)) { + if (is_member) { + if (GetFlag(state.function(), IS_STATIC)) { Template t_register = getTemplate("jsv8_register_static_function"); t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.function(NAME)) - .replace("$jswrapper", state.function(WRAPPER_NAME)) - .trim() - .print(f_init_static_wrappers); + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .print(f_init_static_wrappers); } else { Template t_register = getTemplate("jsv8_register_member_function"); t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.function(NAME)) - .replace("$jswrapper", state.function(WRAPPER_NAME)) - .trim() - .print(f_init_wrappers); + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .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"); t_register.replace("$jsparent", Getattr(current_namespace, NAME)) - .replace("$jsname", state.function(NAME)) - .replace("$jswrapper", state.function(WRAPPER_NAME)) - .trim() - .pretty_print(f_init_static_wrappers); + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .pretty_print(f_init_static_wrappers); } return SWIG_OK; @@ -2140,10 +2109,9 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar String *tm; int startIdx = 0; - if (is_member && !is_static && mode!=Ctor) { + if (is_member && !is_static && mode != Ctor) { startIdx = 1; } - // store number of arguments for argument checks int num_args = emit_num_arguments(parms) - startIdx; String *argcount = NewString(""); @@ -2162,23 +2130,23 @@ void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, Mar switch (mode) { case Getter: if (is_member && !is_static && i == 0) { - Printv(arg, "info.Holder()", 0); + Printv(arg, "info.Holder()", 0); } else { - Printf(arg, "args[%d]", i - startIdx); + Printf(arg, "args[%d]", i - startIdx); } break; case Function: if (is_member && !is_static && i == 0) { - Printv(arg, "args.Holder()", 0); + Printv(arg, "args.Holder()", 0); } else { - Printf(arg, "args[%d]", i - startIdx); + Printf(arg, "args[%d]", i - startIdx); } break; case Setter: if (is_member && !is_static && i == 0) { - Printv(arg, "info.Holder()", 0); + Printv(arg, "info.Holder()", 0); } else { - Printv(arg, "value", 0); + Printv(arg, "value", 0); } break; case Ctor: @@ -2214,7 +2182,6 @@ int V8Emitter::emitNamespaces() { if (Equal(parent, "")) { do_register = false; } - // Note: 'exports' is by convention the name of the object where // globals are stored into if (Equal(name, "exports")) { @@ -2225,16 +2192,16 @@ int V8Emitter::emitNamespaces() { // create namespace object and register it to the parent scope Template t_create_ns = getTemplate("jsv8_create_namespace"); t_create_ns.replace("$jsmangledname", name_mangled) - .trim() - .pretty_print(f_init_namespaces); + .trim() + .pretty_print(f_init_namespaces); } if (do_register) { Template t_register_ns = getTemplate("jsv8_register_namespace"); t_register_ns.replace("$jsmangledname", name_mangled) - .replace("$jsname", name) - .replace("$jsparent", parent_mangled) - .trim(); + .replace("$jsname", name) + .replace("$jsparent", parent_mangled) + .trim(); // prepend in order to achieve reversed order of registration statements Insert(f_init_register_namespaces, 0, t_register_ns.str()); @@ -2254,21 +2221,18 @@ JSEmitter *swig_javascript_create_V8Emitter() { **********************************************************************/ JSEmitterState::JSEmitterState() - : _global(NewHash()) -{ +: _global(NewHash()) { // initialize sub-hashes Setattr(_global, "class", NewHash()); Setattr(_global, "function", NewHash()); Setattr(_global, "variable", NewHash()); } -JSEmitterState::~JSEmitterState() -{ +JSEmitterState::~JSEmitterState() { Delete(_global); } -DOH *JSEmitterState::getState(const char* key, bool _new) -{ +DOH *JSEmitterState::getState(const char *key, bool _new) { if (_new) { Hash *hash = NewHash(); Setattr(_global, key, hash); @@ -2276,63 +2240,55 @@ DOH *JSEmitterState::getState(const char* key, bool _new) return Getattr(_global, key); } -DOH *JSEmitterState::global() { +DOH *JSEmitterState::global () { return _global; } -DOH *JSEmitterState::global(const char* key, DOH *initial) -{ - if(initial != 0) { +DOH *JSEmitterState::global (const char *key, DOH *initial) { + if (initial != 0) { Setattr(_global, key, initial); } return Getattr(_global, key); } -DOH *JSEmitterState::clazz(bool _new) -{ +DOH *JSEmitterState::clazz(bool _new) { return getState("class", _new); } -DOH *JSEmitterState::clazz(const char* key, DOH *initial) -{ +DOH *JSEmitterState::clazz(const char *key, DOH *initial) { DOH *c = clazz(); - if(initial != 0) { + if (initial != 0) { Setattr(c, key, initial); } return Getattr(c, key); } -DOH *JSEmitterState::function(bool _new) -{ +DOH *JSEmitterState::function(bool _new) { return getState("function", _new); } -DOH *JSEmitterState::function(const char* key, DOH *initial) -{ +DOH *JSEmitterState::function(const char *key, DOH *initial) { DOH *f = function(); - if(initial != 0) { + if (initial != 0) { Setattr(f, key, initial); } return Getattr(f, key); } -DOH *JSEmitterState::variable(bool _new) -{ +DOH *JSEmitterState::variable(bool _new) { return getState("variable", _new); } -DOH *JSEmitterState::variable(const char* key, DOH *initial) -{ +DOH *JSEmitterState::variable(const char *key, DOH *initial) { DOH *v = variable(); - if(initial != 0) { + if (initial != 0) { Setattr(v, key, initial); } return Getattr(v, key); } /*static*/ -int JSEmitterState::IsSet(DOH *val) -{ +int JSEmitterState::IsSet(DOH *val) { if (!val) { return 0; } else { @@ -2400,34 +2356,36 @@ String *Template::str() { return code; } -Template& Template::trim() { - const char* str = Char(code); - if (str == 0) return *this; +Template & Template::trim() { + const char *str = Char(code); + if (str == 0) + return *this; int length = Len(code); - if (length == 0) return *this; + if (length == 0) + return *this; int idx; - for(idx=0; idx < length; ++idx) { + for (idx = 0; idx < length; ++idx) { 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) { + for (idx = length - 1; idx >= start_pos; --idx) { if (str[idx] != ' ' && str[idx] != '\t' && str[idx] != '\r' && str[idx] != '\n') break; } int end_pos = idx; - int new_length = end_pos-start_pos+1; - char* newstr = new char[new_length+1]; - memcpy(newstr, str+start_pos, new_length); + int new_length = end_pos - start_pos + 1; + char *newstr = new char[new_length + 1]; + memcpy(newstr, str + start_pos, new_length); newstr[new_length] = 0; Delete(code); code = NewString(newstr); - delete[] newstr; + delete[]newstr; return *this; } @@ -2442,27 +2400,27 @@ Template& Template::trim() { * - returns a reference to the Template to allow chaining of methods. * ----------------------------------------------------------------------------- */ -Template& Template::replace(const String *pattern, const String *repl) { +Template & Template::replace(const String *pattern, const String *repl) { Replaceall(code, pattern, repl); return *this; } -Template& Template::print(DOH *doh) { +Template & Template::print(DOH *doh) { Printv(doh, str(), 0); return *this; } -Template& Template::pretty_print(DOH *doh) { +Template & Template::pretty_print(DOH *doh) { Wrapper_pretty_print(str(), doh); return *this; } -Template::Template(const Template& t) { +Template::Template(const Template & t) { code = NewString(t.code); templateName = NewString(t.templateName); } -void Template::operator=(const Template& t) { +void Template::operator=(const Template & t) { Delete(code); Delete(templateName); code = NewString(t.code); From 0e0ac021927d72f59503db91b6a9f57b323beb8b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 5 Mar 2014 01:50:46 +0100 Subject: [PATCH 271/352] Activate travis matrix for different Javascript interpreters. --- .travis.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6f21c4755..58b3e4ca6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,11 @@ matrix: - compiler: gcc env: SWIGLANG=java - compiler: gcc - env: SWIGLANG=javascript + env: SWIGLANG=javascript ENGINE=node + - compiler: gcc + env: SWIGLANG=javascript ENGINE=jsc + - compiler: gcc + env: SWIGLANG=javascript ENGINE=v8 - compiler: gcc env: SWIGLANG=lua - compiler: gcc From fe10555229b2d2636e16f16a9aa8b4b6ba1f6863 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 5 Mar 2014 01:51:29 +0100 Subject: [PATCH 272/352] Add check to skip javascript test-suite if default interpreter is not installed. --- configure.ac | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index dc446897d..ac392028b 100644 --- a/configure.ac +++ b/configure.ac @@ -1128,6 +1128,13 @@ else ;; esac + #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Look for Node.js which is the default javascript engine + # without it, the javascript test-suite will be skipped + #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AC_CHECK_PROGS(NODEJS, node) + #---------------------------------------------------------------- # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING) #---------------------------------------------------------------- @@ -2455,6 +2462,9 @@ fi AC_SUBST(SKIP_JAVA) SKIP_JAVASCRIPT= +if test -z "$JAVASCRIPT" || test -z "$NODEJS"; then + SKIP_JAVASCRIPT="1" +fi AC_SUBST(SKIP_JAVASCRIPT) SKIP_GUILE= From cb2627ac03e5dd5270eb1c8e4413fd41436fe310 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Wed, 5 Mar 2014 02:00:25 +0100 Subject: [PATCH 273/352] Merged branch 'devel' from https://github.com/oliver----/swig-v8 (squashed commit): commit fe10555229b2d2636e16f16a9aa8b4b6ba1f6863 Author: Oliver Buchtala Date: Wed Mar 5 01:51:29 2014 +0100 Add check to skip javascript test-suite if default interpreter is not installed. commit 0e0ac021927d72f59503db91b6a9f57b323beb8b Author: Oliver Buchtala Date: Wed Mar 5 01:50:46 2014 +0100 Activate travis matrix for different Javascript interpreters. commit 89610e984ea3732a7da7bfc6bea1ffed2039201e Author: Oliver Buchtala Date: Wed Mar 5 01:39:26 2014 +0100 Beautified Javascript module. commit b5bc87667d62fa05a31ab85ba0b7894f83d7cdce Author: Oliver Buchtala Date: Wed Mar 5 01:10:55 2014 +0100 Fix regressions. - Adapted to changes in UTL - Fixed detection of setters and getters. commit a234542543088140e4dd925b0060a93960db9eee Merge: 8c05fe3 c99417a Author: Oliver Buchtala Date: Wed Mar 5 01:09:26 2014 +0100 Merge branch 'master' into tmp Conflicts: .travis.yml Examples/Makefile.in Examples/test-suite/director_nspace.i Examples/test-suite/nspace.i Examples/test-suite/nspace_extend.i Source/Modules/lang.cxx configure.ac commit 8c05fe37afcbcd6a2fc2a7d8bbe028e6d8f59239 Author: Oliver Buchtala Date: Tue Mar 4 22:55:32 2014 +0100 Removed obsolete paragraph from Javascript documentation. commit 924f373a2f6a58c4a8d40e6f61434a6e3f6df50b Author: Oliver Buchtala Date: Tue Mar 4 22:51:19 2014 +0100 Fix pandoc filter. And add a script that helps to run pandoc with appropriate command line flags. commit 6b82dff8f35d9ca743670a6131a87d493514c6b6 Author: Oliver Buchtala Date: Tue Mar 4 22:50:23 2014 +0100 Minor tweaks in Javascript documentation. commit 1a7e12911ac96e8b788686076f35771ac248220d Author: Oliver Buchtala Date: Tue Mar 4 12:00:13 2014 +0100 Adding a chapter about Javascript tests and examples. commit a9b8b85c1c1b2bfe5b9b389e6f9406258371d512 Author: Oliver Buchtala Date: Tue Mar 4 11:00:26 2014 +0100 Minor change in Javascript configuration. commit dbd61e40e1c92aa02c3ce5170534687f7ae8d42f Author: Oliver Buchtala Date: Tue Mar 4 10:41:35 2014 +0100 Fix issues that were observed with newer JavascriptCore. commit 70385842df0c68c4e7e7eeb4531f703330edb831 Author: Oliver Buchtala Date: Fri Feb 28 10:40:41 2014 +0100 Add missing copy ctor for Javascript Code Template class. commit b20b0f4e4b1626030c4155f22313af3ee0fd4e00 Author: Oliver Buchtala Date: Thu Feb 27 01:02:06 2014 +0100 Removed CMake. Started a separate project which acts as a CMake shell around SWIG. commit 7e015e4acf3cb6644f2002d4457a589f1d76f69d Author: Oliver Buchtala Date: Wed Feb 26 23:26:19 2014 +0100 Fix regression in Javascript configuration. commit 348cb2026e2edad29003281ed9b0a2f43c10aa54 Author: Oliver Buchtala Date: Wed Feb 26 22:56:31 2014 +0100 Fix regressions in configuration of some Javascript examples. commit 94869c922861adc007e1cfffde279f2c4e554311 Author: Oliver Buchtala Date: Wed Feb 26 22:47:29 2014 +0100 More gitignores filtering Javascript related files. commit 424e3f47123f8a7746d12d02204b896e55b8444d Author: Oliver Buchtala Date: Wed Feb 26 22:46:24 2014 +0100 Fix custom javascript interpreter configuration for OSX. commit 15f12d9b59b9e8522853f010f9d443164774a6a6 Author: Oliver Buchtala Date: Wed Feb 26 22:44:37 2014 +0100 Make examples work with node.js and the custom interpreter. commit b216a739c45cfb595a5b70da7e811b6130148a63 Author: Oliver Buchtala Date: Wed Feb 26 20:51:38 2014 +0100 Introduced an extra Makefile for the custom javascript interpreter. commit bf1606c0f9261dcb4ae8d5c24aebc987a67e7510 Author: Oliver Buchtala Date: Wed Feb 26 11:10:09 2014 +0100 Fix travis configuration. commit 16a702c0aac717462b1eb94fc4640446943d9396 Author: Oliver Buchtala Date: Wed Feb 26 10:48:38 2014 +0100 Added a comment. commit e62c6126e9d6645eaff2b96d7847d4a8c681bb84 Author: Oliver Buchtala Date: Wed Feb 26 10:47:48 2014 +0100 Fix regressions in Javascript example configuration. commit 15550dab450f003c0b42d6a3353b137435793999 Author: Oliver Buchtala Date: Tue Feb 25 20:16:15 2014 +0100 Fix issue with strange constants under OSX. Receiving strange constant nodes before the real tree under OSX 10.8. Not so under Ubuntu 12.04. commit 84ba91dc63d817376486cecfd7188f56303e6e3b Author: Oliver Buchtala Date: Thu Feb 20 12:38:53 2014 +0100 Some fixes in example section of Javascript documentation. commit 1ffacaab5b7635da623de6c49c22684a1c46d549 Author: Oliver Buchtala Date: Thu Feb 20 12:30:57 2014 +0100 Add note about '-node' command line flag for Node.js code generation. commit 462674ea11fc227501a485a878efd1ae9e111126 Author: Oliver Buchtala Date: Thu Feb 20 12:28:06 2014 +0100 Added examples to Javascript module documentation. commit 3f22a3d639a2884b8cd50d57fc22b6df49a85cdf Author: Oliver Buchtala Date: Thu Feb 20 11:37:40 2014 +0100 Simplification in common javascript example Makefile. commit 8e65414a764f390e0db4f8ded0031ecdef16d896 Author: Oliver Buchtala Date: Thu Feb 20 11:37:15 2014 +0100 Add an extra argument for enabling nodejs support. This is essentially using the v8 emitter plus setting a #define. commit 7c1f66c29e4d0fd72e656b4bd27b2010c053b2c7 Author: Oliver Buchtala Date: Thu Feb 20 11:15:46 2014 +0100 Add more notes about how to install node. commit 48e7df8eb2f7cb87e57dd7a890fbaa9ec8598ac7 Author: Oliver Buchtala Date: Thu Feb 20 11:15:18 2014 +0100 Better error message when no Javascript emitter is specified. commit fd0e75843d3ec7816c85a5d1ab84bd9319c9b27e Author: Oliver Buchtala Date: Thu Feb 20 11:14:48 2014 +0100 Deactivated broken JS examples. commit 77ead7017caca778eb3143fa487856ee8dcd4b7b Author: Oliver Buchtala Date: Thu Feb 20 11:13:57 2014 +0100 Refactored configuration for javascript examples. commit 8df34d54d0957552a53fe5f1e6598849c4ac9f81 Author: Oliver Buchtala Date: Fri Feb 14 13:21:52 2014 +0100 Beginning to document v8 integration. commit 05146e2aed5b8e9df390acdd12b6e5cda2ed2e00 Author: Oliver Buchtala Date: Fri Feb 14 13:04:21 2014 +0100 Documented extending Node.js and Webkit's Javascript engine. commit 68472802721264ec8adee4f80ce7576eb3dd1a3e Author: Oliver Buchtala Date: Fri Feb 14 09:02:37 2014 +0100 Pandoc filter detects shell blocks when not explicitely given. Considered as shell if the first character is '$', as in $ swig -javascript Alternatively you can specify the class explicitely: ```shell swig -javascript ``` commit 1fca61c59ad7a825725b76d394de688774f296e8 Author: Oliver Buchtala Date: Fri Feb 14 09:00:04 2014 +0100 Conitnued documenting the Javascript module. commit 915b7094331bf99f5cf6ed31d5747d10ae1bebb9 Author: Oliver Buchtala Date: Fri Feb 14 00:02:05 2014 +0100 Not a real change. Using a macro to reset JSEmitterStates for the sake of readability. commit 8148b017f879f272616c8bb36b6bcd60232f9c4f Author: Oliver Buchtala Date: Fri Feb 14 00:01:15 2014 +0100 Add a pandoc filter to create compatible html. commit e829ea601f573b96efdf0e1ed602d90a7d39e29f Author: Oliver Buchtala Date: Fri Feb 14 00:00:37 2014 +0100 Add Javascript to chapters. commit fa8b350cd67a8850a866ee52250a6955ef17699f Author: Oliver Buchtala Date: Fri Feb 14 00:00:12 2014 +0100 More Javascript module documentation. commit 02c55fc52fb30da3cec7188b64d456c7dcf8fc9f Author: Oliver Buchtala Date: Thu Feb 13 21:18:06 2014 +0100 Next iteration on creating a documentation for the Javascript module. commit 1e34ecdc31c82d30141097f7744617361ebb748c Author: Oliver Buchtala Date: Thu Feb 13 19:25:16 2014 +0100 Next iteration on creating a documentation for the Javascript module. commit 41ec3fb67e65f3448e52c0eb7372d0331bc7b6ca Author: Oliver Buchtala Date: Fri Sep 27 02:54:42 2013 +0200 Travis configuration for Javascript branch. commit 48af60d82904f1eef37b9beac03f8412947e883e Author: Oliver Buchtala Date: Fri Sep 27 02:46:11 2013 +0200 Javascript examples. commit ecf9f96079067386a5f8bc83fadd4ac9e03f551c Author: Oliver Buchtala Date: Fri Sep 27 02:45:22 2013 +0200 Javascript documentation. commit 00053169cd5d69c42b1b1bbf58336776e1820c97 Author: Oliver Buchtala Date: Fri Sep 27 02:44:53 2013 +0200 CMake configuration. commit 6a366cc050f25b3d358d8f4d85e37011ada82726 Author: Oliver Buchtala Date: Fri Sep 27 03:23:37 2013 +0200 Fix regression. commit 6dcbbf07db310a78457d1c00e84a60761502ea5d Merge: 4492a3d c2d3da2 Author: Oliver Buchtala Date: Fri Sep 27 02:29:02 2013 +0200 Conflicts: .gitignore .project .travis.yml Examples/Makefile.in Examples/test-suite/director_nspace.i commit c2d3da2eeca2d1923d9c69dda70a8ce2f1b2cf1e Author: Oliver Buchtala Date: Thu Sep 26 05:14:34 2013 +0200 Fix test configuration. commit 582bd297690605d98ae758d164cc48e299ae34b3 Author: Oliver Buchtala Date: Thu Sep 26 04:55:34 2013 +0200 Trying to install former working version of nodejs. commit 7adf93ef0f86babb564b1458228f5b4666f414dc Author: Oliver Buchtala Date: Thu Sep 26 04:13:32 2013 +0200 Fix test configuration for nodejs. commit 335d926c449d22821eb916d0f862062b925c2ca6 Author: Oliver Buchtala Date: Tue Sep 24 03:56:19 2013 +0200 Add stub std_deque.i files. commit 51b36d1a1f0c9efe3ef3d25c8bd8c3dfecfa4a52 Author: Oliver Buchtala Date: Tue Sep 24 03:55:51 2013 +0200 Add non pretty printing function to Templates. commit dc62a69775f7eff6a11e7ca7f162ae960b53e671 Author: Oliver Buchtala Date: Tue Sep 24 03:55:10 2013 +0200 Fix bug with typedefd function pointers. commit 2efe63ebb2c87e2e8cde445ffdf964f6cc38869e Author: Oliver Buchtala Date: Tue Sep 24 01:50:33 2013 +0200 Add some test runners. commit b9ecf75f17c05bc58d6e6347877b5aedd92d2d28 Author: Oliver Buchtala Date: Tue Sep 24 01:50:13 2013 +0200 Fix emitter for member pointer constants. However, I am not happy with the constant emitter in general. Should not return dynamic values but register constant wrappers statically. commit 8bf966a65c2120d2bf050857587e7e7bd7cafd58 Author: Oliver Buchtala Date: Tue Sep 24 01:47:13 2013 +0200 Fix %nspace support and activated relevant tests. commit d34a6da08c1dd59ad14731f4ea6a7e8b3b6dd8b7 Author: Oliver Buchtala Date: Tue Sep 17 01:53:22 2013 +0200 Disable warnings for some v8 test-cases. commit b3c198ccee3dad34f75c4617900e53e1770f0ee9 Author: Oliver Buchtala Date: Mon Sep 16 22:28:14 2013 +0200 Fix regression. commit b99e8613ad7103bd99d7f6c7e24b774c73467201 Author: Oliver Buchtala Date: Mon Sep 16 21:56:52 2013 +0200 Bugfix in argument marshalling. commit dd4ed7f3d6bc6a13c271ac7ffb629115414113ec Author: Oliver Buchtala Date: Mon Sep 16 11:46:52 2013 +0200 Disable testcase 'typemap_variables' for v8. It uses output typemaps that are not compatible with the v8 API. commit 0528fd3ac3f6205ce642fa6997908df160030608 Author: Oliver Buchtala Date: Mon Sep 16 11:46:00 2013 +0200 Bugfix for Javascript generator. commit 147cec70f1226dead5d93afd711b99bc9e81827f Author: Oliver Buchtala Date: Mon Sep 16 04:54:57 2013 +0200 Replace $symname in generated function wrappers. commit eb9523b5caef732bbd1b259850e16dc8a9e11564 Author: Oliver Buchtala Date: Mon Sep 16 04:12:55 2013 +0200 Add missing macros. commit 3e28d1e28f81688184cf2c362fa01b7efaaad790 Author: Oliver Buchtala Date: Mon Sep 16 04:12:42 2013 +0200 Let v8 generated code include stdlib.h commit b6426bde2501e6304193644ddc6e8c933db4412e Author: Oliver Buchtala Date: Mon Sep 16 04:12:06 2013 +0200 Add cdata.i typemaps. commit 1f07195812f79a20bb1f37178e596dd0bab8ef2e Author: Oliver Buchtala Date: Mon Sep 16 03:53:00 2013 +0200 Rearrange generation of init block to have custom init code within the initializer body. commit 80ce36c445c704a105a70d6820baefb74a7cd0ec Author: Oliver Buchtala Date: Mon Sep 16 02:27:51 2013 +0200 Make JSC inheritance definition more robust. commit 973042302b017111b06305bedafe47798fcfad86 Author: Oliver Buchtala Date: Mon Sep 16 01:57:55 2013 +0200 Removed dead code. commit bf416876ddf24249f75eff9854e551d789dfab42 Author: Oliver Buchtala Date: Mon Sep 16 01:33:19 2013 +0200 Bugfix for JSC %typemap(out) std::string&. commit b7f827e42ce3073d44f163877f7712782740d1bf Author: Oliver Buchtala Date: Mon Sep 16 01:23:03 2013 +0200 Fix typemap declarations for (unsigned) long long. commit 68eff3e81efd46692206dcf2ea762931f94c63ce Merge: bb7bd50 018847b Author: Oliver Buchtala Date: Mon Sep 16 00:55:57 2013 +0200 Merge branch 'devel' of github.com:oliver----/swig-v8 into devel commit bb7bd50eabdf5cc2f07640227713ef75dc1c8fce Author: Oliver Buchtala Date: Mon Sep 16 00:55:43 2013 +0200 Add support for IN/OUTPUT typemaps. commit 018847b0002a445a1e7110e16dd108aac34564a9 Merge: acfed20 325b544 Author: Oliver Buchtala Date: Sun Sep 15 06:00:06 2013 -0700 Merge pull request #28 from whoozle/devel fixed newer v8 compilation commit 325b5445d67ccf60855aac970ecb6ba913e2b32b Author: Vladimir Menshakov Date: Sat Sep 14 16:19:47 2013 +0400 removed Clear before Dispose from newer v8 code, consider the following code: template void Persistent::Dispose() { if (this->IsEmpty()) return; //Clear will trigger this V8::DisposeGlobal(reinterpret_cast(this->val_)); ... } commit 89fd7ed9c1b1c1e0a1a5344018ab9d0a5ce711b0 Author: Vladimir Menshakov Date: Sat Sep 14 16:17:21 2013 +0400 fixed newer v8 compilation commit 477b2393b10f664696b8cf1e49c2b98deab39d79 Author: Oliver Buchtala Date: Thu Sep 12 05:26:22 2013 +0200 Add stub 'typemaps.i' files. commit acfed20eba1c72571f65048c62653bf339d5564b Author: Oliver Buchtala Date: Thu Sep 12 05:10:23 2013 +0200 Bugfix Javascript generator: valid name for dispatcher functions. commit 1a04e488bc5e17de266181f6b39e00e114f9ae8a Author: Oliver Buchtala Date: Thu Sep 12 05:40:59 2013 +0300 Fix Javascript generator for smartpointeraccessed variables. commit 8bf95c4356b61da9f510245310a0bd3c1fafe36f Author: Oliver Buchtala Date: Thu Sep 12 05:09:35 2013 +0300 Bugfix for Javascript generator: avoid duplicate action code generation. commit 09a210e037c8d5ca46ee4edc4c904f11b04cb893 Author: Oliver Buchtala Date: Thu Sep 12 04:09:21 2013 +0300 Bugfix in Javascript generator: detect member setter/getters correctly. commit c53e3e4dab9b6ab61e63880476721c61ec9ff940 Author: Oliver Buchtala Date: Tue Sep 10 14:45:33 2013 +0300 Fix configuration for nodejs based tests. - use $(SWIGOPT) - less verbose commit dd84e6f9e0b67737ca1031cd6bbb4dcc4eb84340 Author: Oliver Buchtala Date: Tue Sep 10 14:16:36 2013 +0300 Some fixes and cleanup in Javascript generator. - v8 generator uses the correct mangled name for class templates - removed symbols for template variables in favor of using the string literals directly, as it is easier to understand when debugging. commit 001f38c6a9ebd19dee26196e9b0ee2421b8cbe5f Author: Oliver Buchtala Date: Tue Sep 10 13:29:16 2013 +0300 Fix settings for building nodejs tests. Removed the `-node` command line flag. Instead one has to use `-v8 -DBUILDING_NODE_EXTENSION=1`. commit be35d94fdb8b274b443e2467d8a1b6d2dd0723c6 Author: Oliver Buchtala Date: Tue Sep 10 11:53:12 2013 +0300 Add support for PackedData to Javascript generator. commit e5ad9cdc0527b21cbabaad02a22efd8418459d99 Author: Oliver Buchtala Date: Mon Sep 9 22:26:30 2013 +0300 Added two more Javascript tests. - `abstract_inherit` - `char_strings` commit 571c516a0b096564b070350c9b90255db3422768 Author: Oliver Buchtala Date: Mon Sep 9 22:25:51 2013 +0300 Some fixes for the Javascript generator. - added missing `exception.i` - added missing generator block `wrappers` for v8 commit 3c5946d998f2bcecc88f04de8df7a6f3da292b32 Author: Oliver Buchtala Date: Mon Sep 9 17:38:44 2013 +0300 Redefined set of Javascript smoke tests. commit 407d8ef5acff62578c701da74cfdf9a752baffd1 Author: Oliver Buchtala Date: Mon Sep 9 17:34:53 2013 +0300 Clean up in `javascripttypemaps.swg`. - following the same layout/order as pytypemaps - added typemaps for `long long` and `unsigned long long`, which are only copies of those for `long` and `unsigned long` and hence are just experimental. commit fc4d9b665c5839df06501e736163bfeadb7503d1 Author: Oliver Buchtala Date: Mon Sep 9 16:28:29 2013 +0300 Fix v8 generator to use a non clashing name for built-in 'equals' method. commit b6c9c97b96bc3039ccb291d76a64d009fc81fbb7 Author: Oliver Buchtala Date: Mon Sep 9 15:05:11 2013 +0300 Fix Javascript generator to use %renamed variable names. commit 108143951da3859e0c056780706b6841231febb3 Author: Oliver Buchtala Date: Mon Sep 9 13:55:08 2013 +0300 Activate Javascript test-cases `rename_simple` and `rename_scope`. These reveal current deficiencies in the Javascript generator with `%rename`ing. commit 64da1173ddf8bd1fe04800e2afbe0f9c5d2dc818 Author: Oliver Buchtala Date: Mon Sep 9 13:23:47 2013 +0300 Activate Javascript testcases `rename1-4`. commit 1438d0cfb45f0f1b740eb8d1d366f694ba99d0b6 Author: Oliver Buchtala Date: Mon Sep 9 13:17:38 2013 +0300 Add `infinity` test-case to list of smoke tests. commit e01e337d752dbbfc58a06b87fe1169d3f6ada76f Author: Eric Wing Date: Thu Sep 5 14:50:15 2013 -0700 Added unit test using C99 INFINITY. This test actually tests a float conversion bug where converting to float imposed overflow checking which should not be there and causes this program to error out. This was seen originally in Javascript, but it turns out Python has the same bug. Lua does not have this bug. Other generators have not been tested. This test also tests the rename feature. The Javascript generator was not renaming the variable correctly. commit 1729fac3605d6649919ee508bcf8b03f904886f4 Author: Oliver Buchtala Date: Mon Sep 9 12:46:07 2013 +0300 Bug-fix for static variables as proposed by Kota Iguchi. Fixes #20. commit 8408e9b19395f9f7ffca586de80012473b6c3a4e Merge: 6b35c2d b49da78 Author: Oliver Buchtala Date: Fri Sep 6 19:50:51 2013 -0700 Merge pull request #19 from whoozle/devel fixed deprecation warnings for v8-3.21 commit 6b35c2d419eac4f71780a939254e8a459c075849 Author: Oliver Buchtala Date: Fri Sep 6 16:26:02 2013 +0300 Let Travis test all three targets. - nodejs: 0.10.12 - libwebgitgtk 1.0 - libv8 3.7.12 We should soon switch to a new v8 version or add an extra runner. commit 0facc7ecf9f48a98a6f66c557917657d3adb2d36 Author: Oliver Buchtala Date: Fri Sep 6 15:59:43 2013 +0300 Allow to run the test suite with our list of smoke tests. The javascript generator can not deal with the whole test-suite. Moreover, during development I want to have immediate feedback using a set of smoke tests. commit 492d3010ff33c1b6af9bca9472ad08e0330ffb42 Author: Oliver Buchtala Date: Fri Sep 6 01:40:23 2013 +0300 Javascript V8 test-cases always create cpp wrappers. commit 26b5acbbe850c3494f4b79c62f678a92f219f61a Author: Oliver Buchtala Date: Fri Sep 6 00:42:56 2013 +0300 Test-suite Makefile now supports testing for all three Javascript variants. - node.js - custom JavascriptCore interpreter - custom V8 interpreter commit 962207e0f33a322af3f9303f1e15ce9e28eb7281 Author: Oliver Buchtala Date: Fri Sep 6 00:41:18 2013 +0300 Rewritten Javascript autoconfiguration. commit 29ccb270afa761d57d6a6728ca49d92fe9d35bc0 Author: Oliver Buchtala Date: Fri Sep 6 00:40:29 2013 +0300 Renamed object provided to JS initializers. JSC initializer create a new module object. V8 initializer fill a provided 'exports' object. commit 4794fa1884215982384535d25bfcc8e37b496629 Author: Oliver Buchtala Date: Fri Sep 6 00:38:07 2013 +0300 Refactored custom javascript engines to support primitive 'require' statements. commit b49da78b0a6ef1d6e9f624c60710f79e709fca2e Author: Vladimir Menshakov Date: Thu Sep 5 19:50:15 2013 +0400 fixed deprecation warnings for v8-3.21 commit 740da9c733e505d52a918742bc0ac559d7e4ccf6 Merge: 8b0ee54 2a39abe Author: Oliver Buchtala Date: Wed Sep 4 09:18:42 2013 -0700 Merge pull request #17 from whoozle/devel fixed v8-3.20+ compilation and deprecation warnings. commit 2a39abebb684e7e5a2bf878b9d74c54de415bae1 Author: Vladimir Menshakov Date: Wed Sep 4 20:10:42 2013 +0400 moved common swig v8 definitions in javascriptruntime.swg, fixed obsoleted api calls commit 8b0ee5491a9f19a57fef83433d755cc0a9e40c40 Author: Oliver Buchtala Date: Wed Sep 4 18:04:40 2013 +0200 Added missing template configuration files for nodejs based tests. commit 315287b6563f4730468e4b882e569fa72893ba71 Author: Oliver Buchtala Date: Wed Sep 4 17:55:44 2013 +0200 Put the SWIG_V8_VERSION macro into "runtime" block. commit 4068f31c6b66f08c24f760f46da5b4a4d7b6f11b Author: Oliver Buchtala Date: Wed Sep 4 17:54:35 2013 +0200 Use a diffent name for the V8_VERSION provided via command line. commit b7db2a84c907b96e3371b8c8301b32421a10fef5 Author: Vladimir Menshakov Date: Wed Sep 4 19:33:48 2013 +0400 fixed return values and added missing newer v8 dtor wrapper. commit fec11a8def1e1bea9626fab8f17d05c253178bec Author: Oliver Buchtala Date: Wed Sep 4 13:07:07 2013 +0200 Allow exceptions in generated example/test node extensions. commit 54dd7e96c0f9623649947f8f6237a8f1be1ac770 Author: Oliver Buchtala Date: Wed Sep 4 12:47:24 2013 +0200 Fix cleanup configuration for javascript test-suite. commit 8778146b4b45d5033bb65701ab881b1edcc51b9b Author: Oliver Buchtala Date: Wed Sep 4 12:10:08 2013 +0200 Relax type check in SWIG_AsVal_int. The array_member test-case revealed that integers come in as `Numbers`. commit 0e78fc0ad7a962f2d3687c1fb32294e174e68dd5 Author: Oliver Buchtala Date: Tue Sep 3 18:50:46 2013 +0200 Fixing travis configuration. commit da48f3307f4ac358ca2d325f8c04b9a5afb90323 Author: Oliver Buchtala Date: Tue Sep 3 18:24:19 2013 +0200 Remove javascript autoconf detection (Temporarily). I want to cut it down to a minimum having only nodejs. We will activate the others (native JSC and V8) later. commit 262aca8ead684a53c4f2029db5f32a3505e348b3 Author: Oliver Buchtala Date: Tue Sep 3 17:16:40 2013 +0200 Fix in travis config. commit 83e6aa85b6e7f8097eb02179bb8f3faaeb06037b Author: Oliver Buchtala Date: Tue Sep 3 17:13:38 2013 +0200 Not a real change. commit 0aabfeb231d74ac997b28e816987fb033d6b2fd9 Author: Oliver Buchtala Date: Tue Sep 3 17:07:49 2013 +0200 Slight modification to travis config. commit fa27ff29769031cef7dbb3b1951ec6adde09b0cf Author: Oliver Buchtala Date: Tue Sep 3 17:03:08 2013 +0200 Add a travis configuration (experimental). commit 8bbd92883101584583e3139e442bc418100b4a45 Author: Oliver Buchtala Date: Tue Sep 3 16:57:40 2013 +0200 Make javascript test-suite work with nodejs. commit cef82c720f4875b9ddf53667e5396d3b80c7eefd Author: Oliver Buchtala Date: Tue Sep 3 14:41:35 2013 +0200 Replace old style v8 version switches. commit d3074ba4c1cc46bfebd3b09671f92965cab533ed Author: Oliver Buchtala Date: Tue Sep 3 14:02:52 2013 +0200 Fix error in SWIG_V8_GetInstancePtr. commit f70c0e16f292e1fab77fb9ae63f56e86c3ae90c4 Author: Kota Iguchi Date: Wed Aug 28 15:08:50 2013 +0900 Add "equals" to compare between pointers Add "getCPtr" to retrieve pointer value commit a29975c69a0bf0628d740232cab722387588eed2 Author: Kota Iguchi Date: Fri Aug 16 16:08:47 2013 +0900 Typemap for natural support for arrays commit 78a3cc9e3e4bdf6d55cb52ab8812c4127e6ad475 Author: Kota Iguchi Date: Fri Aug 16 10:15:37 2013 +0900 Added the finalize callback (JSObjectFinalizeCallback) commit 14a137adca1a101595e103893d7143aa43525791 Author: Oliver Buchtala Date: Tue Sep 3 06:27:14 2013 +0200 Fix regression. commit 5da54ca435741f74a7212d7034b11b9fa17046d7 Author: Oliver Buchtala Date: Tue Sep 3 06:26:54 2013 +0200 Convert javascript examples to nodejs. commit dbf2b1fe945714641322c2f758bde63140db37fa Author: Oliver Buchtala Date: Tue Sep 3 05:46:19 2013 +0200 Ignore javascript Example build files. commit 11e2179dd318d49665fe665022a2a5ea30c59392 Author: Oliver Buchtala Date: Tue Sep 3 05:40:22 2013 +0200 First example that addresses node.js as primary execution environment. commit a48438c562b3f1601e5bbc9cedcf9f124af97975 Author: Oliver Buchtala Date: Tue Sep 3 05:39:37 2013 +0200 Better v8 version handling. You should start to specify a version on command line, e.g., swig -javascript -v8 -DSWIG_V8_VERSION=0x032007 commit 5228c0eeab0e96930d18e1b0b0d732636adc882f Author: Oliver Buchtala Date: Tue Sep 3 05:36:41 2013 +0200 Add a dedicated mode for creating node modules. commit 5aba4c7ea657f086519acb950e19c416d808b74a Author: Oliver Buchtala Date: Tue Sep 3 05:35:03 2013 +0200 Starting from scratch with Examples configuration. commit cb5f4dc47eeac71a0c5f39618027382567cb53d4 Author: Vladimir Menshakov Date: Thu Aug 15 14:33:00 2013 +0400 ported to newer, more efficient v8 api commit c291675ccef1b058ea5e4c642f0f5b2e72b9e006 Merge: 046ca76 0732592 Author: Jason Turner Date: Fri Aug 9 14:09:43 2013 -0600 Merge branch 'devel' of https://github.com/ewmailing/swig-v8 into devel commit 0732592ed99759afab2f05e6be1723659e955464 Author: Kota Iguchi Date: Wed Aug 7 18:10:53 2013 -0700 Patch to support argout typemap for your swig-v8 branch. commit 32f9cce600452a6210b0eebfd1d598219b90d7bc Merge: 4503c53 306b265 Author: Oliver Buchtala Date: Sat Aug 31 03:47:43 2013 +0200 Merged whoozle branch with ewmailing branch. Conflicts: Lib/javascript/v8/javascriptcode.swg commit 306b265af99613948481a60d55fa902ae6a84c17 Merge: 65a0be8 b511e33 Author: Oliver Buchtala Date: Sat Aug 31 03:47:08 2013 +0200 Merge branch 'devel' of git://github.com/oliver----/swig-v8 into devel Conflicts: Lib/javascript/v8/javascriptcode.swg commit 4503c5390304202275a849eaa8473985adf86f02 Author: Eric Wing Date: Wed Aug 7 15:12:36 2013 -0700 Since this code uses assert, #include is needed. commit 65a0be8876959dd9a79bc3d7290af15ab646202d Author: Eric Wing Date: Thu Jul 11 20:04:01 2013 -0700 v8: variable name bug fix in my template modifications for pointers to structs. commit f8feeacb68593063914c58c60e408d8515295b7f Author: Eric Wing Date: Thu Jul 11 19:11:56 2013 -0700 v8: Removed the extern "C" around the initialize function because it makes no sense since it requires a C++ templates object as a parameter. commit ed729f7d3adaf675bbf7f1f800cdcbe17287d987 Author: Eric Wing Date: Thu Jul 11 19:09:17 2013 -0700 This brings over the memory leak fixes for pointers to structs with a %extend destructor from my Neha fork. The generator was not generating and connecting the needed code for the requested destructor to the v8 dtor finalizer. I did not realize this branch has some JavaScriptCore stuff in it too. Unfortunately, it seems to have its own unique problems (like creating C++ files when it should be generating C files). My changes are targeted for v8, and I don't think my JSCore changes fully reach in this JSCore implementation so more work would need to be done to get this branch working. I think my Neha fork is in better shape at the moment. Also, I did port over the 'NULL out the dtor function pointer' in the %nodefaultdtor fix to v8. Usage case: struct MyData { %extend { ~MyData() { FreeData($self); } } }; %newobject CreateData; struct MyData* CreateData(void); %delobject FreeData; void FreeData(struct MyData* the_data); where the use case is something like: var my_data = example.CreateData(); my_data = null; commit 046ca7686b5605fc7e729d5a4afbe28f2d2c6807 Author: Jason Turner Date: Sat Jul 27 12:35:36 2013 -0600 Adjust for v8::Persistent API which was deprecated @ 3.19.16 https://groups.google.com/forum/#!topic/v8-users/oBE_DTpRC08 commit d5df0bb72101d057b6d59cf7d683263e65288884 Author: Eric Wing Date: Wed Aug 7 15:11:49 2013 -0700 Added #if defined guard for V8_3_14 to allow users from the original SWIG v8 implementation to continue using the new changes. It works similarly to the BUILDING_NODE_EXTENSION in all but two places. This define must be explicitly set by users because there is no way to auto detect. (Perhaps a command line switch can be added to generate this on request?) commit cf9b7e89ac52badd89acc2ba2bb5072055837ce0 Author: Jason Turner Date: Sat Jul 27 09:50:03 2013 -0600 Get memory updates working with Node.js again. commit 3af7d543cb52623f962a48f91a129181af29901a Author: Vladimir Menshakov Date: Wed Aug 7 16:11:59 2013 +0400 fixed crash while instantiating generic-wrapped objects from external code, please review commit 9e74bdb97e049511be20322aa85884c1249d3606 Author: Vladimir Menshakov Date: Tue Aug 6 15:50:43 2013 +0400 added virtual dtor to V8ErrorHandler commit 868803ce2ad158326cb70d2e5667baf4014df31a Author: Oliver Buchtala Date: Sat Aug 31 03:44:44 2013 +0200 Merge replayed as done by c778d16abed35829b103d607a53c8f88e3b2d595 commit a190288e663e207375a42bfb7476ab1ca336f2af Author: Vladimir Menshakov Date: Thu Jul 18 21:03:56 2013 +0400 fixed overloaded functions multiplication commit 45bfc97ef437eb919bec2579dd39e3bbb0fd1c12 Author: Vladimir Menshakov Date: Thu Jul 18 19:15:38 2013 +0400 converted function templates to the persistent ones (fixed crash on large wrappers) commit 9b6a4870dd96656f0e9ec731e9b2dea856ae4939 Author: Vladimir Menshakov Date: Thu Jul 18 18:53:15 2013 +0400 added missing scope.Close() commit fe25e2dfc8fd4fa29702685684337444f5948cb1 Author: Vladimir Menshakov Date: Thu Jul 18 18:42:03 2013 +0400 replaced GetInternalField with GetAlignedPointer (it does not work with SetAlignedPointer, btw) commit 9111773400ba10b6b98fea7996d3dcbf53b97ecf Author: Vladimir Menshakov Date: Thu Jul 11 16:41:40 2013 +0400 generate v8-3.19.x compatible code commit 26a4f849485d03fe57ba47435f11953b019ae515 Author: Vladimir Menshakov Date: Thu Jul 11 15:06:08 2013 +0400 added missing javascript/v8 dir commit b511e33121c5167a9a206ddc2f3417f56d39afa9 Author: Oliver Buchtala Date: Fri May 3 18:23:36 2013 +0200 Remove std::iostream relicts from generated v8 wrapper code. commit d3aa8e06fb3d3eb49c05975108acf2c84b716774 Author: Oliver Buchtala Date: Wed Jan 30 18:50:03 2013 +0100 Bugfix: treat persistent V8 references correctly. V8 is somewhat inconvenient regarding invoke of destructors for C++ proxies. commit 827cef75a35ff9ff84c76c46abf483672c4dbcc4 Author: Oliver Buchtala Date: Fri Jan 25 17:09:13 2013 +0100 Add an ifndef-guard to resolve a warning when building nodejs extension. commit 31feff8586c880bf91f7b6bde61b9dbdc6be57c9 Author: Oliver Buchtala Date: Fri Jan 25 17:03:23 2013 +0100 Add missing return statement in v8 code template. commit 5da4f5794c45a09f3e8b641568d38ff650403752 Author: Oliver Buchtala Date: Fri Jan 25 14:20:51 2013 +0100 Add preprocessor define for building node.js extensions. commit 65560a8664f19aaa03392bba33a4ac435867fa35 Author: Oliver Buchtala Date: Fri Jan 25 14:07:06 2013 +0100 Fix v8 string conversion in case of null arguments. commit e3da21ee442913c5554203bf8699cab62a69ed15 Author: Oliver Buchtala Date: Tue Jan 22 19:28:44 2013 +0100 Add more ignores. commit a4036deda841a9894e7228c4fb80cebe86ff8efc Author: Oliver Buchtala Date: Tue Jan 22 19:26:29 2013 +0100 Add pre-processor defines to detect the javascript engine. commit b0cb875ac1a1899c8752b7df33b7c70ab5ff4b3c Merge: 8b10c47 2252524 Author: Oliver Buchtala Date: Tue Jan 22 19:24:12 2013 +0100 Merge branch 'devel' of github.com:oliver----/swig-v8 into devel commit 8b10c47ed80a42c4f47b339820333132188659c0 Author: Oliver Buchtala Date: Tue Jan 22 19:23:11 2013 +0100 Fix regression: add an include for Node.js header. commit 22525249f26e36d6603c7ee7bce58cefd8ff611f Author: Oliver Buchtala Date: Tue Jan 22 15:54:08 2013 +0100 Resolve compile warnings in v8_shell. commit 8eb9aa9e73fca795fbd6a716ba830366a4919405 Author: Oliver Buchtala Date: Tue Jan 22 15:53:39 2013 +0100 Add gitignore file. commit 04c0803f736ef8bd264d7a099a88b4258461547f Author: Oliver Buchtala Date: Fri Jan 18 15:35:45 2013 +0100 Fixes in configuration to detect JavascriptCore on MacOSX correctly. commit 4ac7065c3ba1b73cdf081eaae45ccc28853a4770 Author: Oliver Buchtala Date: Fri Jan 18 15:34:11 2013 +0100 Bugfix: in javascript interpreter load extensions on MacOSX correctly. commit 04cdde05636f22d8504389a3a92a5c39885f04ad Author: Oliver Buchtala Date: Fri Jan 18 15:33:04 2013 +0100 Add test to check javascript unicode strings. commit caa92740d3241e6aa34ee38a6dbcf846d72c3275 Author: Oliver Buchtala Date: Wed Jan 9 00:33:09 2013 +0100 Add an option to deactivate creation of an extra module object in javascript. This is useful, if the extension host calls the initializer with custom local variables. E.g., this is the case with node.js. commit 213c107b7f4762bf58f7d6a7c7f8b463e2068206 Author: Oliver Buchtala Date: Tue Jan 8 22:37:16 2013 +0100 Add a swig macro to register node.js extensions. commit 4fea3a403e5856565d51a5bf0b0a4cec4c03a583 Author: Oliver Buchtala Date: Tue Jan 8 22:36:32 2013 +0100 Generate an extra file part after the initializer for v8 modules. E.g., this is useful for creating node.js modules. commit 31844ac72adfd82c310c239434db579ba7f6670a Author: Oliver Buchtala Date: Tue Jan 8 22:34:38 2013 +0100 Simplify the signature of the v8 module intializer. commit 9d630ab930f83252e75d6e66e2912cbe75ca253f Author: Oliver Buchtala Date: Tue Jan 8 21:48:22 2013 +0100 Fix std::string support for v8. commit 2c4a90a37d7818f792417bfff73a88b9efcbdd01 Author: Oliver Buchtala Date: Tue Dec 4 01:36:51 2012 +0100 Generate defines for initializer function. commit be06ceea2686f65a29a5d46d5d675d4366e5571c Author: Oliver Buchtala Date: Sun Dec 2 23:51:47 2012 +0100 Fixes in std_string for JSC generator. commit 7fffd801e410749c37a818b22c5682375c5f9a1b Author: Oliver Buchtala Date: Sat Dec 1 13:21:22 2012 +0100 Fix std_string.i which generated compile errors in certain cases. commit fb9c4955fb4c39f66ea74dcd714bb34f593b3b40 Author: Oliver Buchtala Date: Thu Nov 29 03:20:49 2012 +0100 Not a real change: removed some trailing spaces. commit f9d6afbdfef0d3ef3fb0d5a1675a0b1f4d2a5630 Author: Oliver Buchtala Date: Thu Nov 29 03:19:00 2012 +0100 Add a missing return statement in JS shell. commit 9d2264456334c88a6b0b74940cc3e96add527325 Author: Oliver Buchtala Date: Thu Nov 29 03:17:27 2012 +0100 Rename a argument variable to avoid errors with overloaded functions. commit bad64925eddf9f78b5bddd6fe559973c51b7f59f Author: Oliver Buchtala Date: Fri Nov 23 01:59:54 2012 +0100 Configuration is now easier for building and running examples and tests using v8. commit caa6827dafc4cc5b0ea3b8c16922905c46bbbf29 Author: Oliver Buchtala Date: Fri Nov 23 01:09:11 2012 +0100 Javascript interpreter supports for JSC and V8 simultaneously. Before, one had to build two different versions. commit 008adca72f5917d8a80cc252572f0b1e80ed4e69 Author: Oliver Buchtala Date: Thu Nov 22 22:50:50 2012 +0100 Provide more control about the target object/namespace where a v8 module is registered to. commit 6754bf2b49862211eb67bc2a31ce79ae31de9034 Author: Oliver Buchtala Date: Sat Nov 17 03:41:22 2012 +0100 Generate cleanup code for %newobject. commit 058a27bf32c6fc082c3753af3aaffb1ab4d85e83 Author: Oliver Buchtala Date: Sat Nov 17 02:12:12 2012 +0100 Simplify creation of a Javascript shell. commit 57980975a0f86961b3a9545fd24f34575609c6c7 Author: Oliver Buchtala Date: Fri Nov 16 22:10:02 2012 +0100 Generate cleanup code. commit 94730dad7a5d00468d4b2798c7cbd04db6b1d30d Author: Oliver Buchtala Date: Sat Sep 8 01:16:54 2012 +0000 Beautify output of v8 emitter. Trimming some of the code templates. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13830 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 86cb62146661f89f9cd3dd76c721ddfed529b99d Author: Oliver Buchtala Date: Sat Sep 8 01:16:42 2012 +0000 Add comments to v8 code templates. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13829 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 217ffb11d0cbcfbcfbaa679bd815a80b897b1c8b Author: Oliver Buchtala Date: Sat Sep 8 01:16:26 2012 +0000 Fix regressions of latest commits. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13828 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9b06144d39f3f1b820ee90ad0bf1c2cf96cbaf6a Author: Oliver Buchtala Date: Sat Sep 8 01:16:09 2012 +0000 Fix handling of overloaded ctors in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13827 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 131a106204e060ac15bd2474c8a5501f82868284 Author: Oliver Buchtala Date: Sat Sep 8 01:15:51 2012 +0000 Improve names and comments of code templates for javascript emitters. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13826 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8b7a9fec2519aa5faac9c3bb26f7612ee1f5aefb Author: Oliver Buchtala Date: Sat Sep 8 01:15:29 2012 +0000 Add complex support to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13825 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 7c7d1cf3b9e8a1dfd92b3ca199e2ee0b8bf1cc6f Author: Oliver Buchtala Date: Sat Sep 8 01:15:12 2012 +0000 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 commit 296a5d028547c0a0a013a24e65cdcb9c3086fb52 Author: Oliver Buchtala Date: Sat Sep 8 01:14:48 2012 +0000 Minor change in javascript example Makefile configuration. Propagate global CFLAGS and CXXFLAGS to inner javascript targets. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13823 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 4616f9643ff5ce8aefe0594289c9a97230cabf09 Author: Oliver Buchtala Date: Sat Sep 8 01:14:37 2012 +0000 Adapt test-suite configuration to allow switching between js engines. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13822 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8948360725e853f2232188edd38a834ac1f87666 Author: Oliver Buchtala Date: Sat Sep 8 01:14:23 2012 +0000 Fix configuration_in for detecting v8 include and lib. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13821 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 20927938681c14e4f812879973f8e677c08d77b0 Author: Oliver Buchtala Date: Sat Sep 8 01:14:14 2012 +0000 Make v8 shell more quiet. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13820 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit f814a8e702dcfe2ae2f2480de372e78c5a997eb5 Author: Oliver Buchtala Date: Sat Sep 8 01:14:02 2012 +0000 Fix errors concerning object wrapping and cleanup in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13819 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8db76ddee10085765c41be3c5829ec0cce1e0933 Author: Oliver Buchtala Date: Sat Sep 8 01:13:42 2012 +0000 Remove generated file from repository. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13818 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 5425edc50894d32724b7cde8d11bce9fbd3fcdf8 Author: Oliver Buchtala Date: Sat Sep 8 01:13:29 2012 +0000 Add library flag for building v8 shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13817 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit da109ee764b0c48f93554f4cc093997fe530ec28 Author: Oliver Buchtala Date: Sat Sep 8 01:13:17 2012 +0000 Fix input string handling in v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13816 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 91fc0ff205f6f6679a0cb51716adc91a21524929 Author: Oliver Buchtala Date: Sat Sep 8 01:13:03 2012 +0000 Use a throwing default setter in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13815 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit a82e0a6e8f7ba258f29de6f8680e406a8b102ae5 Author: Oliver Buchtala Date: Sat Sep 8 01:12:46 2012 +0000 Fix c++ linking problem in example 'variables'. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13814 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 843c8a408cb76e22efc10ede577f17e2e5b7deb2 Author: Oliver Buchtala Date: Sat Sep 8 01:12:33 2012 +0000 Fix AsVal macros of long and int for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13813 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d13289cc918061b9ffea6aeb9fe1dba9990727e5 Author: Oliver Buchtala Date: Sat Sep 8 01:12:18 2012 +0000 Fix function dispatching for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13812 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 68f0f859f887f7be4c61d53b37ec8989c02833b9 Author: Oliver Buchtala Date: Sat Sep 8 01:11:51 2012 +0000 Fix name collision in generated v8 initializer. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13811 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit da6307a19ea5668757ab59f95e670f99bd64b61a Author: Oliver Buchtala Date: Sat Sep 8 01:11:32 2012 +0000 Enable overloading ctors for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13810 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 70383a1b61aacfb475f72652cf120515f11de2c1 Author: Oliver Buchtala Date: Sat Sep 8 01:11:11 2012 +0000 Enable string exceptions in v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13809 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 84e5476147cd141d1178cd25be35df6b01c5b92e Author: Oliver Buchtala Date: Sat Sep 8 01:10:57 2012 +0000 Add std::string support to v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13808 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit a4f8e4c1c3bbcd36a771313f2516717aa113b771 Author: Oliver Buchtala Date: Sat Sep 8 01:10:42 2012 +0000 Fix bug in v8 ctor emitter. This bug leaded to flaky crashes of v8 engine. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13807 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 2893df9f7394ef48424f0b88e44af702a11fdd95 Author: Oliver Buchtala Date: Sat Sep 8 01:10:27 2012 +0000 Several fixes in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13806 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit c4ab8790278b8ec1cb96f542985824af84e3144a Author: Oliver Buchtala Date: Sat Sep 8 01:10:10 2012 +0000 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. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13805 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 58e4f9703c78052ee60f3021724bc3274f3d329a Author: Oliver Buchtala Date: Sat Sep 8 01:09:57 2012 +0000 Fix handling of Char constants in JSC typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13804 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 915e65135cdf90a484bd1078eb3cfe15f192e50e Author: Oliver Buchtala Date: Sat Sep 8 01:09:43 2012 +0000 Minor fix in v8 shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13803 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit c3918f3f822a09b297f30ef060c9269dc97e0f39 Author: Oliver Buchtala Date: Sat Sep 8 01:09:31 2012 +0000 Add string support to v8 typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13802 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit bd752ff86b94a082235d0ff424729c7d5e043715 Author: Oliver Buchtala Date: Sat Sep 8 01:09:18 2012 +0000 In example Makefiles for v8 forward to CPP target. As v8 is C++ it is not possible to build wrappers in C. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13801 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 1862f43cfcd93a3f79cf652da70f22a438de4cf9 Author: Oliver Buchtala Date: Sat Sep 8 01:09:05 2012 +0000 Minor clean up in class example. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13800 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit f1e9b21dfd63df4b694bac471daa1f9359c88378 Author: Oliver Buchtala Date: Sat Sep 8 01:08:50 2012 +0000 Add missing swig_type_info registration in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13799 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 21bdb78f1ca2f016afb73c84b4286312f47d3175 Author: Oliver Buchtala Date: Sat Sep 8 01:08:33 2012 +0000 Activate SwigModuleInitializer for in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13798 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9a914af2b787b336228f779c519b39147e536a68 Author: Oliver Buchtala Date: Sat Sep 8 01:08:16 2012 +0000 Fix v8 shell to initialize v8 context in proper order. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13797 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 46cff47ada4ec3197798359425c165e09d4498a5 Author: Oliver Buchtala Date: Sat Sep 8 01:08:03 2012 +0000 Several fixes in generator for v8 initializer function. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13796 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 78f5b46381e4c93f3d1227a702761a8eda01f4ca Author: Oliver Buchtala Date: Sat Sep 8 01:07:43 2012 +0000 Fix class example. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13795 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 022c274256d5f61daa6a880d781b903cb82af677 Author: Oliver Buchtala Date: Sat Sep 8 01:07:21 2012 +0000 Minor fixes in v8 javascript shell. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13794 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit cda09239ad4b7f5367ea3382e4497cc8d830338b Author: Oliver Buchtala Date: Sat Sep 8 01:06:58 2012 +0000 Several fixes in v8 emitter and code templates. Achieves first compile of example "class" after re-integration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13793 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 0cae8fccd0cfdbcc6dc426c75102ac8a08430b5d Author: Oliver Buchtala Date: Sat Sep 8 01:06:39 2012 +0000 Minor refactor of marshalInputArgs for generalization. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13792 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9b0c8dae839def6e83b447230923630e819b64b4 Author: Oliver Buchtala Date: Sat Sep 8 01:06:26 2012 +0000 Add argcount checking to functions and ctors. Before argument counts were only checked for overloaded functions/ctors. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13791 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d5c5f7ebeebeef78bb847dea31bda75e65d5d197 Author: Oliver Buchtala Date: Sat Sep 8 01:06:08 2012 +0000 Generalize ctor overloading. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13790 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 72002392770b42c3c1a15a4167426635bf9128db Author: Oliver Buchtala Date: Sat Sep 8 01:05:51 2012 +0000 Fix regression in javascript's test-suite configuration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13789 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 78442b27647e2a3d7e45516c709632f8419b7fd6 Author: Oliver Buchtala Date: Sat Sep 8 01:05:37 2012 +0000 Several adaptations and fixes on the way to get V8 emitter running. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13788 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8d72616e6598dac37109fce3562c32c31188beb1 Author: Oliver Buchtala Date: Sat Sep 8 01:05:11 2012 +0000 Refactor emitter and code templates to use defined template variables. Also switched from "${...}" to $..., which is swig's common notation of typemap variables. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13787 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit cdd450fbe4b9fa9a756cb464dbb3f54e2791106a Author: Oliver Buchtala Date: Sat Sep 8 01:04:51 2012 +0000 Delete obsolete source file. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13786 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 5fab9c8a3857f2c0499790461160bdb4bc9d3602 Author: Oliver Buchtala Date: Sat Sep 8 01:04:40 2012 +0000 Minor cleanup in javascript shell implementation. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13785 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 0341e6b14c9f118ca2bfe853385df88779f0521b Author: Oliver Buchtala Date: Sat Sep 8 01:04:26 2012 +0000 Clean up example Makefiles. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13784 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 10dc758cadc7e0f27eee867a071ba199678e8a0a Author: Oliver Buchtala Date: Sat Sep 8 01:03:42 2012 +0000 Refactored javascript shell implementation to support JSC and v8. Also changed configuration in examples Makefile.in to allow switching modes. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13783 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 672208d8d20eef3214bf4f48fce009eb3f053a81 Author: Oliver Buchtala Date: Sat Sep 8 01:03:17 2012 +0000 Adapt overload example to reflect changes in module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13782 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit cbb5b711ab8d3038f993dc77f6397419cb7c1f7e Author: Oliver Buchtala Date: Sat Sep 8 01:03:00 2012 +0000 Fix examples after regressions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13781 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 52aef2699700c957015c8ce88c5c75f756ffc86f Author: Oliver Buchtala Date: Sat Sep 8 01:02:30 2012 +0000 Add examples check list for batch runs. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13780 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 07d5ec24cebcaa7a08425fa4780937b3bca9fae5 Author: Oliver Buchtala Date: Sat Sep 8 01:02:16 2012 +0000 Add support for type-based dispatching of overloaded functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13779 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit eff094ef3942c026a0711abad56af9a8a54d9b9a Author: Oliver Buchtala Date: Sat Sep 8 01:01:57 2012 +0000 Add test "constructor_copy". git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13778 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 548287c600e8bd900e6976158ffe9c007a390e5f Author: Oliver Buchtala Date: Sat Sep 8 01:01:41 2012 +0000 Update configuration to detect V8 and allow testing with V8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13777 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 4d9ca620abcfed848785ca4825f6a61648387829 Author: Oliver Buchtala Date: Sat Sep 8 01:00:15 2012 +0000 Refactored JSEmitters to share unified code. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13776 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 387da69e843e7359ba1fb70f0eadbd077e8cf461 Author: Oliver Buchtala Date: Sat Sep 8 00:59:55 2012 +0000 Pull namespace implementation up to be shared between js emitters. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13775 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 66ead9afb2501d02c9ded79309e64a5bc953da5a Author: Oliver Buchtala Date: Sat Sep 8 00:59:43 2012 +0000 Simplify implementation using new issetter flag. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13774 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d2debe32703c0d1f6b4ca22623b2d13e206be64b Author: Oliver Buchtala Date: Sat Sep 8 00:59:31 2012 +0000 Add more verbose temporary flags for setters in variable wrappers. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13773 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 16077503c86919dbedd3d76318a23323404f4f58 Author: Oliver Buchtala Date: Sat Sep 8 00:59:18 2012 +0000 Fix former workaround by concerning static member functions. "storage" attribute is removed by Language::staticmemberfunctionHandler which was resolved by a workaround before. Now, the implementation relies completely on state flags retrieved at a proper point. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13772 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit c470864d127561d55d36e115ffffffc33cf2ff96 Author: Oliver Buchtala Date: Sat Sep 8 00:59:03 2012 +0000 Remove some dead code and an obsolete member variable from JSEmitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13771 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 46624e24e5b6204ce7fd03be433ec1883fd98f96 Author: Oliver Buchtala Date: Sat Sep 8 00:58:49 2012 +0000 Remove member variable current_wrapper from JSEmitter. Instead each emitting function creates local wrapper instance. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13770 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8577ae41791303471a80fde1384f319ef5ababb9 Author: Oliver Buchtala Date: Sat Sep 8 00:58:37 2012 +0000 Minor clean up. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13769 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit b778c4816b63e12e72cb3c2a97e904411465329a Author: Oliver Buchtala Date: Sat Sep 8 00:58:23 2012 +0000 Remove a global variable from JSEmitter by making use of JSEmitterState. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13768 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9af3c4879bbd2103548afbfbff200eff6a78418a Author: Oliver Buchtala Date: Sat Sep 8 00:58:11 2012 +0000 Switch to global variable for enabling code template debug information. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13767 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit b39e2bfff0c1082c31149079075faa0999059953 Author: Oliver Buchtala Date: Sat Sep 8 00:57:57 2012 +0000 Refactor JSC emitter to reduce global state variables. Also meld v8 emitter into javascript.cxx (provisional). git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13766 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 35e6b73d2acbcc010bd239a83fbf16cecefe7b70 Author: Oliver Buchtala Date: Sat Sep 8 00:57:42 2012 +0000 Add swig configuration files for v8. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13765 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 050219d998c0a518b54366c6c543fa926e601e5b Author: Oliver Buchtala Date: Sat Sep 8 00:56:48 2012 +0000 Merge branch 'devel' of https://github.com/Neha03/gsoc2012-javascript into devel Conflicts: .project COPYRIGHT Doc/Manual/style.css Examples/Makefile.in Examples/test-suite/common.mk Lib/typemaps/strings.swg Makefile.in Source/DOH/fio.c Source/Makefile.am Source/Modules/emit.cxx Source/Modules/javascript.cxx configure.in git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13764 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 360ef44e09e9072702215c46306731ccbbbc1d03 Author: Oliver Buchtala Date: Sat Sep 8 00:52:41 2012 +0000 Clean up in v8 helper functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13763 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 229f2d0fa5ffb71c36201a7c70f86e778d256128 Author: Oliver Buchtala Date: Sat Sep 8 00:52:28 2012 +0000 Add v8 input typemap for cstrings. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13762 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8168750c1b43d42a24efa598a1da14c9f56a95f4 Author: Oliver Buchtala Date: Sat Sep 8 00:52:16 2012 +0000 Add example for string marshalling to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13761 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 67a3de9a93433585a8daca77d3e300713bf91762 Author: Oliver Buchtala Date: Sat Sep 8 00:52:02 2012 +0000 Add example for inheritance to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13760 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 32a32633ba1ad9fe12e07f90b1eeaee2665b2631 Author: Oliver Buchtala Date: Sat Sep 8 00:51:47 2012 +0000 Add support for static member variables and functions to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13759 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit e8dd979d165faa481b057a1b4cb145b3b789d36e Author: Oliver Buchtala Date: Sat Sep 8 00:51:29 2012 +0000 Update v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13758 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 0fd30dc60f462afa797acf84f0f0ad6cea0077a3 Author: Oliver Buchtala Date: Sat Sep 8 00:51:16 2012 +0000 Add examples to specification of v8 code generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13757 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit badf090cb5f2a3dd396b616ba0b997f562a28496 Author: Oliver Buchtala Date: Sat Sep 8 00:51:00 2012 +0000 Extend and rename v8 helper functions. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13756 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 65d4769af8792f4193cba47ef56547f9998c247c Author: Oliver Buchtala Date: Sat Sep 8 00:50:41 2012 +0000 Add initial support for argument marshalling using typemaps to v8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13755 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 0e60acfebde30181f93b1acfa57c65b50a13e6c5 Author: Oliver Buchtala Date: Sat Sep 8 00:50:19 2012 +0000 Minor restructuring in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13754 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 71bee1e78c52a65c5a159768c2f6f02cf3eb903f Author: Oliver Buchtala Date: Sat Sep 8 00:50:06 2012 +0000 Complement variable processing in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13753 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 8e0711cbc63ceb6b0adcc1a2ec4133b0fa198a25 Author: Oliver Buchtala Date: Sat Sep 8 00:49:44 2012 +0000 Fix memory related bug in generalized javascript emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13752 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 285badb95b03a3f1ee7a84fa1b473b06c477f35d Author: Oliver Buchtala Date: Sat Sep 8 00:49:32 2012 +0000 Improve v8 generator regarding registration of function wrappers. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13751 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 7ba26c8a26e52d2f499e20b866b273571c6264b8 Author: Oliver Buchtala Date: Sat Sep 8 00:49:15 2012 +0000 Minor change in v8 emitter. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13750 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 9a599be8ab6c3426362beb3dd572cd399620da8d Author: Oliver Buchtala Date: Sat Sep 8 00:49:02 2012 +0000 Fix order of registration in v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13749 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 886f17c34372ded14504ad684b71cd786faa8e42 Author: Oliver Buchtala Date: Sat Sep 8 00:48:43 2012 +0000 Implement namespace support for v8 generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13748 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 90bbc6430bf5fb8f234c5ea46a09ef5f528ec72d Author: Oliver Buchtala Date: Sat Sep 8 00:48:24 2012 +0000 Update v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13747 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 6c90d1eb6d46bd1dd52aa3121d38511974423d8b Author: Oliver Buchtala Date: Sat Sep 8 00:48:11 2012 +0000 Minor improvements in v8 emitter implementation git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13746 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 83ac7193155a0d91fad992f197a448591f3e829c Author: Oliver Buchtala Date: Sat Sep 8 00:47:51 2012 +0000 Add manual generated v8 wrapper examples to v8 specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13745 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit a0b71935f278ff342583e17cdf6e94d43ac77c58 Author: Oliver Buchtala Date: Sat Sep 8 00:47:38 2012 +0000 Update v8 code generator specification. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13744 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 3c30e2d382cbbacef66563bcc8d54289f9543339 Author: Oliver Buchtala Date: Sat Sep 8 00:47:19 2012 +0000 Add initial Javascript V8 emitter implementation. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13743 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 4bcfca05dd0eff51c4ecfa11ed182a6bcf147dbf Author: Oliver Buchtala Date: Sat Sep 8 00:46:31 2012 +0000 Add some implementation details to specification of v8 code generator. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13742 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit e888d7a892702aa0a3e42449737c8f1bfb747a2f Author: Oliver Buchtala Date: Sat Sep 8 00:46:18 2012 +0000 Add a document about mapping C++ language features to Javascript. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13741 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 5b5fdb171e720228b24c2f9fbb1667649693b3ab Author: Oliver Buchtala Date: Sat Sep 8 00:46:03 2012 +0000 Add a paragraph about control flow analysis to V8 specification. Control flow analysis for use cases: - static variables - simple class - class properties - class methods - static class variables and functions - inheritance. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13740 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit 5c3fef6367ba41982032dea8a2b29f6a7f62de9f Author: Oliver Buchtala Date: Sat Sep 8 00:45:49 2012 +0000 Add initial version of a CMake configuration. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13739 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit ba40fffd91bc07fc5020fe7870a6104863a39f94 Author: Oliver Buchtala Date: Sat Sep 8 00:45:35 2012 +0000 Add initial specification of code generator templates for V8 module. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13738 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d71a5f483a6ad3307ff306ce2c72cfcd0e361556 Author: Oliver Buchtala Date: Sat Sep 8 00:44:54 2012 +0000 Add module for Javascript target. This module comes with a design that allows different code emitter implementations. For the the phase of development the module is split into multiple files which will be merged together when development converges. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13737 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit c86ce942c2d0498169d4371bdd6c9acd503fdffa Author: Oliver Buchtala Date: Fri May 11 19:20:07 2012 +0000 Correct place of copyright entry. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13070 626c5289-ae23-0410-ae9c-e8d60b6d4f22 commit d6060ceced397c2dd3baaba94c783d0045ddc38e Author: Oliver Buchtala Date: Fri May 11 13:55:16 2012 +0000 Add copyright entry for Oliver Buchtala. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/oliverb-javascript-v8@13067 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- .gitignore | 8 + .travis.yml | 10 +- COPYRIGHT | 4 +- Doc/Manual/Javascript.html | 770 ++++++ Doc/Manual/chapters | 1 + Doc/Manual/style.css | 6 +- Examples/Makefile.in | 80 + Examples/javascript/check.list | 13 + Examples/javascript/class/Makefile | 3 + Examples/javascript/class/binding.gyp | 8 + Examples/javascript/class/example.cxx | 28 + Examples/javascript/class/example.h | 34 + Examples/javascript/class/example.i | 10 + Examples/javascript/class/example.js | 1 + Examples/javascript/class/runme.js | 46 + Examples/javascript/constant/Makefile | 3 + Examples/javascript/constant/binding.gyp | 8 + Examples/javascript/constant/example.h | 8 + Examples/javascript/constant/example.i | 24 + Examples/javascript/constant/example.js | 1 + Examples/javascript/constant/runme.js | 14 + Examples/javascript/enum/Makefile | 3 + Examples/javascript/enum/binding.gyp | 8 + Examples/javascript/enum/example.cxx | 37 + Examples/javascript/enum/example.h | 13 + Examples/javascript/enum/example.i | 11 + Examples/javascript/enum/example.js | 1 + Examples/javascript/enum/runme.js | 34 + Examples/javascript/exception/Makefile | 3 + Examples/javascript/exception/binding.gyp | 8 + Examples/javascript/exception/example.cxx | 1 + Examples/javascript/exception/example.h | 53 + Examples/javascript/exception/example.i | 12 + Examples/javascript/exception/example.js | 1 + Examples/javascript/exception/runme.js | 64 + Examples/javascript/functor/Makefile | 3 + Examples/javascript/functor/binding.gyp | 8 + Examples/javascript/functor/example.cxx | 0 Examples/javascript/functor/example.i | 25 + Examples/javascript/functor/example.js | 1 + Examples/javascript/functor/runme.js | 15 + Examples/javascript/js_example.mk | 52 + Examples/javascript/namespace/Makefile | 3 + Examples/javascript/namespace/binding.gyp | 8 + Examples/javascript/namespace/example.cxx | 36 + Examples/javascript/namespace/example.h | 20 + Examples/javascript/namespace/example.i | 10 + Examples/javascript/namespace/example.js | 1 + Examples/javascript/namespace/runme.js | 10 + Examples/javascript/operator/Makefile | 3 + Examples/javascript/operator/binding.gyp | 8 + Examples/javascript/operator/example.h | 36 + Examples/javascript/operator/example.i | 34 + Examples/javascript/operator/example.js | 1 + Examples/javascript/operator/runme.js | 25 + Examples/javascript/overload/Makefile | 3 + Examples/javascript/overload/binding.gyp | 8 + Examples/javascript/overload/example.h | 28 + Examples/javascript/overload/example.i | 16 + Examples/javascript/overload/example.js | 1 + Examples/javascript/overload/runme.js | 9 + Examples/javascript/pointer/Makefile | 3 + Examples/javascript/pointer/binding.gyp | 8 + Examples/javascript/pointer/example.cxx | 16 + Examples/javascript/pointer/example.i | 30 + Examples/javascript/pointer/example.js | 1 + Examples/javascript/pointer/runme.js | 35 + Examples/javascript/pointer/typemaps.i | 0 Examples/javascript/reference/Makefile | 3 + Examples/javascript/reference/binding.gyp | 8 + Examples/javascript/reference/example.cxx | 46 + Examples/javascript/reference/example.h | 26 + Examples/javascript/reference/example.i | 42 + Examples/javascript/reference/example.js | 1 + Examples/javascript/reference/runme.js | 67 + Examples/javascript/reference/swig_gdb.log | 22 + Examples/javascript/simple/Makefile | 3 + Examples/javascript/simple/binding.gyp | 8 + Examples/javascript/simple/example.cxx | 18 + Examples/javascript/simple/example.i | 7 + Examples/javascript/simple/example.js | 1 + Examples/javascript/simple/runme.js | 26 + Examples/javascript/template/Makefile | 3 + Examples/javascript/template/binding.gyp | 8 + Examples/javascript/template/example.h | 32 + Examples/javascript/template/example.i | 17 + Examples/javascript/template/example.js | 1 + Examples/javascript/template/runme.js | 30 + Examples/javascript/variables/Makefile | 3 + Examples/javascript/variables/binding.gyp | 8 + Examples/javascript/variables/example.cxx | 96 + Examples/javascript/variables/example.h | 6 + Examples/javascript/variables/example.i | 49 + Examples/javascript/variables/example.js | 1 + Examples/javascript/variables/runme.js | 68 + Examples/javascript/variables/swig_gdb.log | 9 + Examples/test-suite/common.mk | 7 +- Examples/test-suite/constructor_copy.i | 2 +- Examples/test-suite/director_nspace.i | 2 +- Examples/test-suite/infinity.i | 48 + Examples/test-suite/javascript/Makefile.in | 181 ++ .../javascript/abstract_access_runme.js | 6 + .../javascript/abstract_inherit_runme.js | 40 + .../javascript/abstract_typedef2_runme.js | 6 + .../javascript/abstract_typedef_runme.js | 8 + .../javascript/abstract_virtual_runme.js | 11 + .../javascript/array_member_runme.js | 22 + .../javascript/arrays_global_runme.js | 18 + .../test-suite/javascript/callback_runme.js | 30 + .../javascript/char_binary_runme.js | 38 + .../javascript/char_strings_runme.js | 11 + .../javascript/class_ignore_runme.js | 6 + .../javascript/class_scope_weird_runme.js | 6 + .../javascript/complextest_runme.js | 22 + .../test-suite/javascript/constover_runme.js | 33 + .../javascript/constructor_copy_runme.js | 42 + .../test-suite/javascript/cpp_enum_runme.js | 28 + .../javascript/cpp_namespace_runme.js | 47 + .../test-suite/javascript/cpp_static_runme.js | 9 + .../javascript/director_alternating_runme.js | 5 + .../test-suite/javascript/disown_runme.js | 22 + .../javascript/dynamic_cast_runme.js | 12 + Examples/test-suite/javascript/empty_runme.js | 1 + .../javascript/enum_template_runme.js | 8 + .../test-suite/javascript/infinity_runme.js | 4 + .../javascript/javascript_unicode_runme.js | 9 + .../namespace_virtual_method_runme.js | 3 + .../javascript/node_template/binding.gyp.in | 30 + .../javascript/node_template/index.js.in | 1 + .../javascript/nspace_extend_runme.js | 27 + .../test-suite/javascript/nspace_runme.js | 77 + .../javascript/overload_copy_runme.js | 4 + .../javascript/preproc_include_runme.js | 23 + .../test-suite/javascript/preproc_runme.js | 14 + .../test-suite/javascript/rename1_runme.js | 68 + .../test-suite/javascript/rename2_runme.js | 68 + .../test-suite/javascript/rename3_runme.js | 68 + .../test-suite/javascript/rename4_runme.js | 68 + .../javascript/rename_scope_runme.js | 17 + .../javascript/rename_simple_runme.js | 50 + .../javascript/ret_by_value_runme.js | 8 + Examples/test-suite/javascript/setup_test.sh | 6 + .../javascript/struct_value_runme.js | 11 + .../javascript/template_static_runme.js | 3 + .../javascript/typedef_class_runme.js | 7 + .../javascript/typedef_inherit_runme.js | 23 + .../javascript/typedef_scope_runme.js | 12 + .../javascript/typemap_arrays_runme.js | 5 + .../javascript/typemap_delete_runme.js | 5 + .../javascript/typemap_namespace_runme.js | 7 + .../javascript/typemap_ns_using_runme.js | 4 + .../test-suite/javascript/using1_runme.js | 4 + .../test-suite/javascript/using2_runme.js | 4 + .../test-suite/javascript/varargs_runme.js | 44 + Examples/test-suite/javascript_unicode.i | 10 + Examples/test-suite/nspace.i | 2 +- Examples/test-suite/nspace_extend.i | 2 +- Lib/javascript/jsc/arrays_javascript.i | 123 + Lib/javascript/jsc/ccomplex.i | 26 + Lib/javascript/jsc/cdata.i | 1 + Lib/javascript/jsc/complex.i | 6 + Lib/javascript/jsc/exception.i | 1 + Lib/javascript/jsc/javascript.swg | 19 + Lib/javascript/jsc/javascriptcode.swg | 418 +++ Lib/javascript/jsc/javascriptcomplex.swg | 146 + Lib/javascript/jsc/javascriptfragments.swg | 23 + Lib/javascript/jsc/javascripthelpers.swg | 69 + Lib/javascript/jsc/javascriptinit.swg | 67 + Lib/javascript/jsc/javascriptkw.swg | 40 + Lib/javascript/jsc/javascriptprimtypes.swg | 182 ++ Lib/javascript/jsc/javascriptrun.swg | 298 ++ Lib/javascript/jsc/javascriptruntime.swg | 19 + Lib/javascript/jsc/javascriptstrings.swg | 184 ++ Lib/javascript/jsc/javascripttypemaps.swg | 54 + Lib/javascript/jsc/std_common.i | 5 + Lib/javascript/jsc/std_complex.i | 19 + Lib/javascript/jsc/std_deque.i | 1 + Lib/javascript/jsc/std_except.i | 1 + Lib/javascript/jsc/std_map.i | 74 + Lib/javascript/jsc/std_pair.i | 34 + Lib/javascript/jsc/std_string.i | 69 + Lib/javascript/jsc/std_vector.i | 85 + Lib/javascript/jsc/stl.i | 10 + Lib/javascript/jsc/typemaps.i | 148 + Lib/javascript/v8/arrays_javascript.i | 125 + Lib/javascript/v8/ccomplex.i | 26 + Lib/javascript/v8/cdata.i | 1 + Lib/javascript/v8/complex.i | 6 + Lib/javascript/v8/exception.i | 1 + Lib/javascript/v8/javascript.swg | 19 + Lib/javascript/v8/javascriptcode.swg | 468 ++++ Lib/javascript/v8/javascriptcomplex.swg | 123 + Lib/javascript/v8/javascriptfragments.swg | 23 + Lib/javascript/v8/javascripthelpers.swg | 87 + Lib/javascript/v8/javascriptinit.swg | 118 + Lib/javascript/v8/javascriptkw.swg | 40 + Lib/javascript/v8/javascriptprimtypes.swg | 198 ++ Lib/javascript/v8/javascriptrun.swg | 462 ++++ Lib/javascript/v8/javascriptruntime.swg | 39 + Lib/javascript/v8/javascriptstrings.swg | 59 + Lib/javascript/v8/javascripttypemaps.swg | 43 + Lib/javascript/v8/node.i | 12 + Lib/javascript/v8/std_common.i | 5 + Lib/javascript/v8/std_complex.i | 19 + Lib/javascript/v8/std_deque.i | 1 + Lib/javascript/v8/std_except.i | 1 + Lib/javascript/v8/std_map.i | 74 + Lib/javascript/v8/std_pair.i | 33 + Lib/javascript/v8/std_string.i | 79 + Lib/javascript/v8/std_vector.i | 85 + Lib/javascript/v8/stl.i | 10 + Lib/javascript/v8/typemaps.i | 148 + Lib/typemaps/strings.swg | 4 +- Makefile.in | 19 +- Source/Makefile.am | 1 + Source/Modules/javascript.cxx | 2428 +++++++++++++++++ Source/Modules/swigmain.cxx | 2 + Tools/javascript/Makefile.in | 58 + Tools/javascript/javascript.cxx | 66 + Tools/javascript/js_shell.cxx | 156 ++ Tools/javascript/js_shell.h | 53 + Tools/javascript/jsc_shell.cxx | 233 ++ Tools/javascript/v8_shell.cxx | 310 +++ Tools/swigconfig.h.cmake | 89 + Tools/swigprinters.gdb | 24 + Tools/swigprinters.py | 574 ++++ configure.ac | 232 ++ swig-v8/swig-v8.xcodeproj/project.pbxproj | 153 ++ 228 files changed, 12567 insertions(+), 16 deletions(-) create mode 100644 Doc/Manual/Javascript.html create mode 100644 Examples/javascript/check.list create mode 100755 Examples/javascript/class/Makefile create mode 100644 Examples/javascript/class/binding.gyp create mode 100755 Examples/javascript/class/example.cxx create mode 100755 Examples/javascript/class/example.h create mode 100755 Examples/javascript/class/example.i create mode 100644 Examples/javascript/class/example.js create mode 100755 Examples/javascript/class/runme.js create mode 100755 Examples/javascript/constant/Makefile create mode 100644 Examples/javascript/constant/binding.gyp create mode 100644 Examples/javascript/constant/example.h create mode 100755 Examples/javascript/constant/example.i create mode 100644 Examples/javascript/constant/example.js create mode 100755 Examples/javascript/constant/runme.js create mode 100755 Examples/javascript/enum/Makefile create mode 100644 Examples/javascript/enum/binding.gyp create mode 100755 Examples/javascript/enum/example.cxx create mode 100755 Examples/javascript/enum/example.h create mode 100755 Examples/javascript/enum/example.i create mode 100644 Examples/javascript/enum/example.js create mode 100755 Examples/javascript/enum/runme.js create mode 100755 Examples/javascript/exception/Makefile create mode 100644 Examples/javascript/exception/binding.gyp create mode 100644 Examples/javascript/exception/example.cxx create mode 100644 Examples/javascript/exception/example.h create mode 100644 Examples/javascript/exception/example.i create mode 100644 Examples/javascript/exception/example.js create mode 100644 Examples/javascript/exception/runme.js create mode 100755 Examples/javascript/functor/Makefile create mode 100644 Examples/javascript/functor/binding.gyp create mode 100644 Examples/javascript/functor/example.cxx create mode 100644 Examples/javascript/functor/example.i create mode 100644 Examples/javascript/functor/example.js create mode 100644 Examples/javascript/functor/runme.js create mode 100644 Examples/javascript/js_example.mk create mode 100755 Examples/javascript/namespace/Makefile create mode 100644 Examples/javascript/namespace/binding.gyp create mode 100644 Examples/javascript/namespace/example.cxx create mode 100644 Examples/javascript/namespace/example.h create mode 100644 Examples/javascript/namespace/example.i create mode 100644 Examples/javascript/namespace/example.js create mode 100644 Examples/javascript/namespace/runme.js create mode 100755 Examples/javascript/operator/Makefile create mode 100644 Examples/javascript/operator/binding.gyp create mode 100644 Examples/javascript/operator/example.h create mode 100644 Examples/javascript/operator/example.i create mode 100644 Examples/javascript/operator/example.js create mode 100644 Examples/javascript/operator/runme.js create mode 100755 Examples/javascript/overload/Makefile create mode 100644 Examples/javascript/overload/binding.gyp create mode 100644 Examples/javascript/overload/example.h create mode 100644 Examples/javascript/overload/example.i create mode 100644 Examples/javascript/overload/example.js create mode 100644 Examples/javascript/overload/runme.js create mode 100755 Examples/javascript/pointer/Makefile create mode 100644 Examples/javascript/pointer/binding.gyp create mode 100755 Examples/javascript/pointer/example.cxx create mode 100755 Examples/javascript/pointer/example.i create mode 100644 Examples/javascript/pointer/example.js create mode 100755 Examples/javascript/pointer/runme.js create mode 100644 Examples/javascript/pointer/typemaps.i create mode 100755 Examples/javascript/reference/Makefile create mode 100644 Examples/javascript/reference/binding.gyp create mode 100755 Examples/javascript/reference/example.cxx create mode 100755 Examples/javascript/reference/example.h create mode 100755 Examples/javascript/reference/example.i create mode 100644 Examples/javascript/reference/example.js create mode 100755 Examples/javascript/reference/runme.js create mode 100644 Examples/javascript/reference/swig_gdb.log create mode 100755 Examples/javascript/simple/Makefile create mode 100644 Examples/javascript/simple/binding.gyp create mode 100644 Examples/javascript/simple/example.cxx create mode 100644 Examples/javascript/simple/example.i create mode 100644 Examples/javascript/simple/example.js create mode 100755 Examples/javascript/simple/runme.js create mode 100755 Examples/javascript/template/Makefile create mode 100644 Examples/javascript/template/binding.gyp create mode 100644 Examples/javascript/template/example.h create mode 100644 Examples/javascript/template/example.i create mode 100644 Examples/javascript/template/example.js create mode 100644 Examples/javascript/template/runme.js create mode 100755 Examples/javascript/variables/Makefile create mode 100644 Examples/javascript/variables/binding.gyp create mode 100755 Examples/javascript/variables/example.cxx create mode 100755 Examples/javascript/variables/example.h create mode 100755 Examples/javascript/variables/example.i create mode 100644 Examples/javascript/variables/example.js create mode 100755 Examples/javascript/variables/runme.js create mode 100644 Examples/javascript/variables/swig_gdb.log create mode 100644 Examples/test-suite/infinity.i create mode 100755 Examples/test-suite/javascript/Makefile.in create mode 100644 Examples/test-suite/javascript/abstract_access_runme.js create mode 100644 Examples/test-suite/javascript/abstract_inherit_runme.js create mode 100644 Examples/test-suite/javascript/abstract_typedef2_runme.js create mode 100644 Examples/test-suite/javascript/abstract_typedef_runme.js create mode 100644 Examples/test-suite/javascript/abstract_virtual_runme.js create mode 100644 Examples/test-suite/javascript/array_member_runme.js create mode 100644 Examples/test-suite/javascript/arrays_global_runme.js create mode 100644 Examples/test-suite/javascript/callback_runme.js create mode 100644 Examples/test-suite/javascript/char_binary_runme.js create mode 100644 Examples/test-suite/javascript/char_strings_runme.js create mode 100644 Examples/test-suite/javascript/class_ignore_runme.js create mode 100644 Examples/test-suite/javascript/class_scope_weird_runme.js create mode 100644 Examples/test-suite/javascript/complextest_runme.js create mode 100644 Examples/test-suite/javascript/constover_runme.js create mode 100644 Examples/test-suite/javascript/constructor_copy_runme.js create mode 100644 Examples/test-suite/javascript/cpp_enum_runme.js create mode 100644 Examples/test-suite/javascript/cpp_namespace_runme.js create mode 100644 Examples/test-suite/javascript/cpp_static_runme.js create mode 100644 Examples/test-suite/javascript/director_alternating_runme.js create mode 100644 Examples/test-suite/javascript/disown_runme.js create mode 100644 Examples/test-suite/javascript/dynamic_cast_runme.js create mode 100644 Examples/test-suite/javascript/empty_runme.js create mode 100644 Examples/test-suite/javascript/enum_template_runme.js create mode 100644 Examples/test-suite/javascript/infinity_runme.js create mode 100644 Examples/test-suite/javascript/javascript_unicode_runme.js create mode 100644 Examples/test-suite/javascript/namespace_virtual_method_runme.js create mode 100644 Examples/test-suite/javascript/node_template/binding.gyp.in create mode 100644 Examples/test-suite/javascript/node_template/index.js.in create mode 100644 Examples/test-suite/javascript/nspace_extend_runme.js create mode 100644 Examples/test-suite/javascript/nspace_runme.js create mode 100644 Examples/test-suite/javascript/overload_copy_runme.js create mode 100644 Examples/test-suite/javascript/preproc_include_runme.js create mode 100644 Examples/test-suite/javascript/preproc_runme.js create mode 100644 Examples/test-suite/javascript/rename1_runme.js create mode 100644 Examples/test-suite/javascript/rename2_runme.js create mode 100644 Examples/test-suite/javascript/rename3_runme.js create mode 100644 Examples/test-suite/javascript/rename4_runme.js create mode 100644 Examples/test-suite/javascript/rename_scope_runme.js create mode 100644 Examples/test-suite/javascript/rename_simple_runme.js create mode 100644 Examples/test-suite/javascript/ret_by_value_runme.js create mode 100644 Examples/test-suite/javascript/setup_test.sh create mode 100644 Examples/test-suite/javascript/struct_value_runme.js create mode 100644 Examples/test-suite/javascript/template_static_runme.js create mode 100644 Examples/test-suite/javascript/typedef_class_runme.js create mode 100644 Examples/test-suite/javascript/typedef_inherit_runme.js create mode 100644 Examples/test-suite/javascript/typedef_scope_runme.js create mode 100644 Examples/test-suite/javascript/typemap_arrays_runme.js create mode 100644 Examples/test-suite/javascript/typemap_delete_runme.js create mode 100644 Examples/test-suite/javascript/typemap_namespace_runme.js create mode 100644 Examples/test-suite/javascript/typemap_ns_using_runme.js create mode 100644 Examples/test-suite/javascript/using1_runme.js create mode 100644 Examples/test-suite/javascript/using2_runme.js create mode 100644 Examples/test-suite/javascript/varargs_runme.js create mode 100644 Examples/test-suite/javascript_unicode.i create mode 100644 Lib/javascript/jsc/arrays_javascript.i create mode 100644 Lib/javascript/jsc/ccomplex.i create mode 100644 Lib/javascript/jsc/cdata.i create mode 100644 Lib/javascript/jsc/complex.i create mode 100644 Lib/javascript/jsc/exception.i create mode 100644 Lib/javascript/jsc/javascript.swg create mode 100644 Lib/javascript/jsc/javascriptcode.swg create mode 100644 Lib/javascript/jsc/javascriptcomplex.swg create mode 100644 Lib/javascript/jsc/javascriptfragments.swg create mode 100644 Lib/javascript/jsc/javascripthelpers.swg create mode 100644 Lib/javascript/jsc/javascriptinit.swg create mode 100644 Lib/javascript/jsc/javascriptkw.swg create mode 100644 Lib/javascript/jsc/javascriptprimtypes.swg create mode 100644 Lib/javascript/jsc/javascriptrun.swg create mode 100644 Lib/javascript/jsc/javascriptruntime.swg create mode 100644 Lib/javascript/jsc/javascriptstrings.swg create mode 100644 Lib/javascript/jsc/javascripttypemaps.swg create mode 100755 Lib/javascript/jsc/std_common.i create mode 100644 Lib/javascript/jsc/std_complex.i create mode 100644 Lib/javascript/jsc/std_deque.i create mode 100644 Lib/javascript/jsc/std_except.i create mode 100755 Lib/javascript/jsc/std_map.i create mode 100755 Lib/javascript/jsc/std_pair.i create mode 100755 Lib/javascript/jsc/std_string.i create mode 100755 Lib/javascript/jsc/std_vector.i create mode 100755 Lib/javascript/jsc/stl.i create mode 100644 Lib/javascript/jsc/typemaps.i create mode 100644 Lib/javascript/v8/arrays_javascript.i create mode 100644 Lib/javascript/v8/ccomplex.i create mode 100644 Lib/javascript/v8/cdata.i create mode 100644 Lib/javascript/v8/complex.i create mode 100644 Lib/javascript/v8/exception.i create mode 100644 Lib/javascript/v8/javascript.swg create mode 100644 Lib/javascript/v8/javascriptcode.swg create mode 100644 Lib/javascript/v8/javascriptcomplex.swg create mode 100644 Lib/javascript/v8/javascriptfragments.swg create mode 100644 Lib/javascript/v8/javascripthelpers.swg create mode 100644 Lib/javascript/v8/javascriptinit.swg create mode 100644 Lib/javascript/v8/javascriptkw.swg create mode 100644 Lib/javascript/v8/javascriptprimtypes.swg create mode 100644 Lib/javascript/v8/javascriptrun.swg create mode 100644 Lib/javascript/v8/javascriptruntime.swg create mode 100644 Lib/javascript/v8/javascriptstrings.swg create mode 100644 Lib/javascript/v8/javascripttypemaps.swg create mode 100644 Lib/javascript/v8/node.i create mode 100755 Lib/javascript/v8/std_common.i create mode 100644 Lib/javascript/v8/std_complex.i create mode 100644 Lib/javascript/v8/std_deque.i create mode 100644 Lib/javascript/v8/std_except.i create mode 100755 Lib/javascript/v8/std_map.i create mode 100755 Lib/javascript/v8/std_pair.i create mode 100755 Lib/javascript/v8/std_string.i create mode 100755 Lib/javascript/v8/std_vector.i create mode 100755 Lib/javascript/v8/stl.i create mode 100644 Lib/javascript/v8/typemaps.i create mode 100644 Source/Modules/javascript.cxx create mode 100644 Tools/javascript/Makefile.in create mode 100644 Tools/javascript/javascript.cxx create mode 100644 Tools/javascript/js_shell.cxx create mode 100644 Tools/javascript/js_shell.h create mode 100644 Tools/javascript/jsc_shell.cxx create mode 100755 Tools/javascript/v8_shell.cxx create mode 100644 Tools/swigconfig.h.cmake create mode 100644 Tools/swigprinters.gdb create mode 100755 Tools/swigprinters.py create mode 100644 swig-v8/swig-v8.xcodeproj/project.pbxproj diff --git a/.gitignore b/.gitignore index 48826d914..8d72cea5d 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,8 @@ # Editor files and various other junk .*.sw? *.bak +*.log +.DS_Store # Local PCRE pcre @@ -23,6 +25,7 @@ pcre *.so *.so.* *.dylib +*.bundle # C/C++ static libraries, based on: # https://github.com/github/gitignore/blob/master/C.gitignore @@ -71,6 +74,7 @@ Examples/xml/Makefile Source/Include/stamp-h1 Source/Include/swigconfig.h Source/Makefile +Tools/javascript/Makefile .deps config.log config.status @@ -85,6 +89,7 @@ Source/CParse/parser.c Source/CParse/parser.h Source/eswig swig +Tools/javascript/javascript # Generated documentation Doc/Manual/CCache.html @@ -102,6 +107,7 @@ Examples/test-suite/d/*/ Examples/test-suite/go/*/ Examples/test-suite/guile/*/ Examples/test-suite/java/*/ +Examples/test-suite/javascript/*/ Examples/test-suite/lua/*/ Examples/test-suite/mzscheme/*/ Examples/test-suite/ocaml/*/ @@ -114,6 +120,8 @@ Examples/test-suite/r/*/ Examples/test-suite/ruby/*/ Examples/test-suite/tcl/*/ Examples/test-suite/uffi/*/ +*_wrap.c +*_wrap.cxx # Python generated files, based on: # https://github.com/github/gitignore/blob/master/Python.gitignore diff --git a/.travis.yml b/.travis.yml index 5d47074e9..58b3e4ca6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ -language: cpp +language: c compiler: - - clang - gcc env: - SWIGLANG= @@ -14,6 +13,12 @@ matrix: env: SWIGLANG=guile - compiler: gcc env: SWIGLANG=java + - compiler: gcc + env: SWIGLANG=javascript ENGINE=node + - compiler: gcc + env: SWIGLANG=javascript ENGINE=jsc + - compiler: gcc + env: SWIGLANG=javascript ENGINE=v8 - compiler: gcc env: SWIGLANG=lua - compiler: gcc @@ -43,6 +48,7 @@ before_install: - if test -z "$SWIGLANG"; then sudo apt-get -qq install yodl; fi - if test "$SWIGLANG" = "csharp"; then sudo apt-get -qq install mono-devel; fi - if test "$SWIGLANG" = "go"; then go env | sed -e 's/^/export /' > goenvsetup && source goenvsetup && rm -f goenvsetup; fi # Until configure.ac is fixed + - if test "$SWIGLANG" = "javascript"; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs libv8-dev libwebkitgtk-dev && sudo npm install -g node-gyp; fi - if test "$SWIGLANG" = "guile"; then sudo apt-get -qq install guile-2.0-dev; fi - if test "$SWIGLANG" = "lua"; then sudo apt-get -qq install lua5.1 liblua5.1-dev; fi - if test "$SWIGLANG" = "octave"; then sudo apt-get -qq install octave3.2 octave3.2-headers; fi diff --git a/COPYRIGHT b/COPYRIGHT index 3f4711a47..28b7f1f0d 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -15,7 +15,9 @@ Active SWIG Developers: Olly Betts (olly@survex.com) (PHP) Joseph Wang (joequant@gmail.com) (R) Xavier Delacour (xavier.delacour@gmail.com) (Octave) - David Nadlinger (code@klickverbot.at) (D) + David Nadlinger (code@klickverbot.at) + Oliver Buchtala (oliver.buchtala@gmail.com) (Javascript) + Neha Narang (narangneha03@gmail.com) (Javascript) Past SWIG developers and major contributors include: Dave Beazley (dave-swig@dabeaz.com) (SWIG core, Python, Tcl, Perl) diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html new file mode 100644 index 000000000..a53e2a7cd --- /dev/null +++ b/Doc/Manual/Javascript.html @@ -0,0 +1,770 @@ + + + + + + + SWIG AND JAVASCRIPT + + + + +
+
+

Overview

+

This chapter describes SWIG support for Javascript. The module is designed to support JavascriptCore and V8 as target engine. Currently only JavascriptCore support is implemented. JavaScriptCore is the built-in JavaScript engine for WebKit, whereas V8 is the engine used by Chromium.

+

JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. C++, on the other hand, is statically typed, compiled, general purpose programming language. The approach I followed here is "Test driven" where I have written the examples/test-cases to be supported for Javascript one-by-one and implemented the required module files in parallel. The support for Javascript would be added similar to other supported target languages in swig. Swig comes with an "Examples" directory for Javascript like other supported language. The directory contains examples for every supported feature of the target language. There is also a test-suite directory for javascript which contains additional tests.

+

Preliminaries

+

In order to use this module, you will need to have installed javascriptcore and you can install it by installing package libwebkit-dev You can find out some necessary compiler/linker flag by

+
pkg-config javascriptcoregtk-1.0 --cflags --libs
+
+

Using the module

+

To generate an extension for JavascriptCore one would call swig as follows

+

swig -c++ -javascript -jsc example.i +
+

This generates a C++ source file containing the wrapper.

+

How does Javascript talk to C++?

+

JavascriptCore provides a C-API which allows to extend a Javascript interpreter with native methods and structures. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is also possible to add your own commands and variables. A reference manual of this API can be found here.

+

Typically, when you add a new command to the javascript interpreter you need to do two things: first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process.

+

Wrapper functions

+

Suppose you have an ordinary C function like this :

+

int fact(int n) { + if (n <= 1) return 1; + else return n*fact(n-1); +} +
+

In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things :

+
    +
  • Gather function arguments and make sure they are valid.
  • +
  • Call the C function.
  • +
  • Convert the return value into a form recognized by the javascript.
  • +
+

As an example, the javascript wrapper function for the fact() function above example might look like the following :

+

JSValueRef wrap_fact(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + int arg1 = (int)JSValueToNumber(context, argv[0], NULL); + int arg2 = (int)JSValueToNumber(context, argv[1], NULL); + int result = (int)fact(arg1,arg2); + JSValueRef jsresult = JSValueMakeNumber(context, result); + return jsresult; +} +
+

Once you have created a wrapper function, the final step is to tell the javascript about the new function. This is done by register function called by the javascript when the module is loaded. For example, adding the above function to the javascript interpreter requires code like the following :

+

bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_globalvarsclassname = JSStringCreateWithUTF8CString(globalvarsclassname); + JSObjectSetProperty(context,js_globalvarsclassname,JSObjectMakeFunctionWithCallback(context, + js_globalvarsclassname, callback), kJSPropertyAttributeNone,NULL); + JSStringRelease(jsstring); + return true; +} + +int example_init(JSContextRef context) { + JSObjectRef global; + ... + jsc_registerFunction(context, global, "fact", wrap_fact); + ... +} +
+

When executed, javascript will now have a new command called "fact" that you can use like any other Javascript command. Although the process of adding a new function to javascript has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code.

+

Variable Linking

+

Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable:

+

double Foo = 3.5; +
+

To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called.

+

bool Foo_set(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef value, + JSValueRef* exception) +{ + JSValueRef jsresult; + double arg1 = (double)JSValueToNumber(context, value, NULL); + Foo = arg1; + jscresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef Foo_get(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef* exception) +{ + JSValueRef jsresult; + double result = (double)Foo; + jsresult = JSValueMakeNumber(context, result); + return jsresult; +} +
+

In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as Foo might implicitly call the get function. Similarly, typing Foo = 4 would call the underlying set function to change the value.

+

A tour of basic C/C++ wrapping

+

By default, SWIG tries to build a very natural javascript interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping.

+

Modules

+

The SWIG %module directive specifies the name of the Javascript module. If you specify %module example, then everything is wrapped into a Javascript 'example' module. Underneath the covers, this module consists of a cpp source file example.cpp. When choosing a module name, make sure you don't use the same name as a built-in Javascript command or standard module name.

+

Global variables

+

C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that javascript works.

+

// SWIG interface file with global variables +%module example +... +%inline %{ +extern double Foo; +extern int gcd(int x, int y); +%} +... +
+

Now look at the javascript:

+

print("Global variable Foo=" + example.Foo); +example.Foo = 3.1415926; +print("Variable Foo changed to=" + example.Foo); +print("GCD of x and y is=" + example.gcd(x,y)); +
+

Constants and enums

+

C/C++ constants are installed as javascript objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example:

+

#define ICONST 42 +#define FCONST 2.1828 +%constant int iconst = 37; +
+

In javascript they are treated as:

+

print("ICONST = " + example.ICONST + " (should be 42)\n"); +print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +print("iconst = " + example.iconst + " (should be 37)\n"); +
+

For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile. Enums are treated as constants.So if we have enums in c++ as:

+

void enum_test(color c, Foo::speed s); +
+

In javascript they are treated as:

+

example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); +
+

Inside the class

+

For class enums as below:

+

class Foo { +public: +Foo() { } +enum speed { IMPULSE, WARP, LUDICROUS }; +} +
+

In javascript they are treated as:

+

print(" Foo_IMPULSE =" + example.Foo.IMPULSE); +print(" Foo_WARP =" + example.Foo.WARP); +print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); +
+

Pointers

+

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface

+

/* File : example.i */ +%module example +%{ +extern void add(int *, int *, int *); +%} +
+

When wrapped, you will be able to use the functions in a natural way from javascript. For example:

+

// Call the add() function with some pointers +example.add(a, b, c); +
+

// In javascript the code look like as:

+

a = example.new_intp(); +example.intp_assign(a,37); +
+
    +
  • The first one creates an int-pointer instance.
  • +
  • The second one assigns it the value 37.
  • +
+

C++ classes

+

C++ classes are wrapped by javascript classes as well. For example, if you have this class,

+

class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; +}; +
+

you can use it in javascript like this:

+

print("Creating some objects:"); +c = new example.Circle(10); +print("area = " + c.area()); +
+

Class data members are accessed in the same manner as C structures.

+

Static class members and functions are mapped to javascript in a straight-forward manner:

+

class Spam { +public: + static void foo(); + static int bar; +}; +
+

In javascript, the static member can be access in this way:

+

// ----- Access a static member ----- +print("\nA access of static member is" + example.Spam.Foo); // access static member as properties of the class object. +
+

C++ inheritance

+

SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this

+

class A { +public: + void foo(); + virtual void bar(); +}; +class B: public A { +public: + virtual void bar(); +}; +
+

Those classes are wrapped into a hierarchy of javascript classes that reflect the same inheritance structure. All of the usual javascript utility functions work normally:

+

var a = new example.A(); +a.foo(); +a.bar(); +var b = new example.B(); +b.foo(); +b.bar(); +print("b.cPtr = " + b.getCPtr()); +
+

C++ overloaded functions

+

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:

+

void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} +
+

You can use them in javascript in a straightforward manner:

+

example.f(1); +example.f(1, 2); +example.f("bla"); +
+

C++ operators

+

Certain C++ overloaded operators can be handled automatically by SWIG. Though, in javascript operator overloading is not possible. Instead one has to make use of the %rename feature.

+

For example, consider a class like this:

+

/* File : example.h */ +#include <math.h> +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; +
+

When wrapped, it works like you expect:

+

a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +print ("a =" + a); +print ("b =" + b); + +c = a.plus(b); + +print("c =" + c); +print("a*b =" + a.times(b)); +print("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +print("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +print("f =" + f); +
+

One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this

+

class Complex { +... +friend Complex operator+(double, const Complex &c); +... +}; +
+

then SWIG ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:

+

%rename(Complex_add_dc) operator+(double, const Complex &);

+

There are ways to make this operator appear as part of the class using the %extend directive.

+

C++ namespaces:

+

SWIG is aware of C++ namespaces, but namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this,

+

%module example +namespace nspace { +extern int gcd(int x, int y); +extern double Foo; +class Circle +{ +public: + Circle(); + Circle(double r); + double area(); + double radius; + }; +} +
+

for namespaces, you use the %feature directive in interface file. %feature attaches a new attribute to any parse tree node that matches given prototype.

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%feature("nspace", 1); +%include "example.h" +
+

it works in javascript as follows:

+

print("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +print("Variable Foo changed to " + example.nspace.Foo); +print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); +print("Creating some objects:"); +c = new example.nspace.Circle(10); +print("area = " + c.area()); +
+

If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:

+

%rename(Bar_spam) Bar::spam; +namespace Foo { + int spam(); +} +namespace Bar { + int spam(); +} +
+

If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence.

+

C++ templates

+

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ +%template(maxint) max<int>; +%template(maxdouble) max<double>; +%template(vecint) vector<int>; +%template(vecdouble) vector<double>; +
+

In javascript:

+

//Call some templated functions +print(example.maxint(3,7)); +print(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +print(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +print(sum); +
+

Exception handling

+

The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into javascript exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following:

+

Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the javascript extension by writing the following in an interface file:

+

/* File : example.i */ +%module example +%{ +#include "example.h" +%} +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" +
+

Actually in JS there is no support for typed exceptions.For now there is support for integer and string exception. Example for integer exception

+

JSValueRef jsc_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +*exception = JSValueMakeNumber(context, 13); +int result = (int)gcd(arg1,arg2); +JSValueRef jsresult = JSValueMakeNumber(context, result); +
+

and for string exception:

+

JSValueRef wrap_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ +int arg1 = (int)JSValueToNumber(context, argv[0], NULL); +int arg2 = (int)JSValueToNumber(context, argv[1], NULL); +JSStringRef message = JSStringCreateWithUTF8CString("This is a test error."); +*exception = JSValueMakeString(context, message); +JSStringRelease(message); +int result = (int)gcd(arg1,arg2); +JSValueRef jscresult = JSValueMakeNumber(context, result); +return jsresult; +} +
+

How to use generated modules?

+

Basically there is no standard extension mechanism in Javascript. We provided a custom interpreter with extension abilities. If JSC is embedded into a custom application, one has to make use of a generated module initializer function that allows easy extension of interpreter. The basic approach is as follows:

+

Basic Mechanism

+
    +
  • Creating the context
  • +
  • Calling module initializer
  • +
  • Evaluate Javascript
  • +
+

Creating the context

+

JSGlobalContextRef context = JSGlobalContextCreate(NULL); +JSObjectRef globalObject = JSContextGetGlobalObject(context); +... +
+

Calling module initializer

+

extern int example_init(JSGlobalContextRef context); + ... + example_init(context); + ... +
+

Evaluate Javascript

+

// Evaluate the javascript +char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); +JSStringRef jsScript; +if(!scriptContent) { + printf("FAIL: runme script could not be loaded.\n"); + failed = 1; + } + else { + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(scriptContent); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); + if (!jsResult && ex) { + jsc_printError(context, ex, scriptPath); + failed = 1; + } + } + if (scriptContent != NULL) { + free(scriptContent); + } + JSStringRelease(jsScript); + JSGlobalContextRelease(context); + globalObject = 0; + for(std::vector<HANDLE>::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + dlclose(handle); + } + if (failed) { + printf("FAIL: Some tests failed.\n"); + return 1; + } +} +
+

Typemaps

+

A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from javascript to C, you might define a typemap like this:

+

%typemap(in) int { + $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} + printf("Received an integer : %d\n",$1); +} +
+

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int.

+

Javascript typemaps

+

The previous section illustrated an "in" typemap for converting javascript objects to C. A variety of different typemap methods are defined by the javascript module. For example, to convert a C integer back into a javascript object, you might define an "out" typemap like this:

+

%typemap(out) int { + $result = JSValueMakeNumber(context, $1); +} +
+

The Javascript module makes use of Swig's unified template library.

+

Typemap variables

+

Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

+

$1: A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Javascript.

+

$input: A javascript Object * holding a raw javascript object with an argument or variable value.

+

$result: A javascript Object * that holds the result to be returned to javascript.

+

$1_name: The parameter name that was matched.

+

$1_type: The actual C datatype matched by the typemap.

+

$1_ltype: An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.

+

$symname: The javascript name of the wrapper function being created.

+

Javascript: Specification of a Code Generator for JSC

+

The module implementation tries to accomplish a separation of logic and code generation by making use of code templates. In the following, the templates are explained.

+

Top Level structure

+

The generated code consists of the following blocks:

+

<RUNTIME> +<INCLUDES> +<HELPER_FUNCTIONS> +<FUNCTION_WRAPPERS> +<INITIALIZER> +
+
    +
  • RUNTIME: runtime code generated by swig
  • +
  • HELPER_FUNCTIONS: static, from swg-file
  • +
  • INCLUDES: static, module property
  • +
  • FUNCTION_WRAPPERS: dynamically growing, on method declarations
  • +
  • INITIALIZER: dynamically growing, aggregates everything
  • +
+

INCLUDES

+

#include <JavaScriptCore/JavaScript.h> +<USER_DEFINED_INCLUDES> +
+

USER_DEFINED_INCLUDES: a module property

+

HELPER_FUNCTIONS

+

A lot of boiler-plate code can be shifted into static helper functions:

+

bool JS_registerClass(JSGlobalContextRef& context, JSObjectRef& parentObject,const char* className, + JSClassDefinition* definition) { + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject,js_className, classObject,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef& context,JSObjectRef& namespaceObj,JSObjectRef& parentNamespace,const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace,js_name, namespaceObj,kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + return true; +} + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context,object,js_functionName,JSObjectMakeFunctionWithCallback(context, + js_functionName, callback), kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return val; +} +
+

FUNCTION_WRAPPERS

+

There are different types of function wrappers: - Member Functions - Getproperty / Setproperty - Global Functions (global/namespace/class) - Constructors / Destructors

+

Member Functions

+

JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • functionname: the name of generated wrapper for function
  • +
  • LOCALS: declarations for input arguments
  • +
  • CODE: contains input marshalling, the action, and output marshalling
  • +
+

Setproperty

+

bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • setname: the name of the generated wrapper for setproperty.
  • +
  • LOCALS: declarations for input arguments
  • +
  • CODE: contains input marshalling, and the action
  • +
+

Getproperty

+

JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + ${LOCALS} + ${CODE} + return jsresult; + + goto fail; + fail: + return NULL; +} +
+
    +
  • getname: the name of the generated wrapper for the getproperty
  • +
  • LOCALS: declarations for output arguments
  • +
  • CODE: contains the action, and output marshalling
  • +
+

Global Functions

+

JSStaticValue ${namespace}_values[] = { + ${jsglobalvariables} + { 0, 0, 0, 0 } +}; +JSStaticFunction ${namespace}_functions[] = { + ${jsglobalfunctions} + { 0, 0, 0 } +}; +JSClassDefinition ${namespace}_classDefinition; +
+

Variable declaration

+

{"${propertyname}",${getname}, ${setname}, kJSPropertyAttributeNone} +
+

This is used to fill variable definition tables. kJSPropertyAttributeNone is JSC specific and means that the variable has a getter and setter. Even for read-only variables a setter is used which throws an exception.

+

Constructor

+

~~

+

JSObjectRef wrap_createclassnamemangled{overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { ${LOCALS} ${CODE} return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN);

+
goto fail;
+fail:
+return NULL;
+
+

}

+
- `classname_mangled` is the mangled qualified class name,   e.g., `foo::A -> foo_A`
+- `LOCALS`: declarations for input arguments 
+- `CODE`: contains input marshalling, and the action 
+
+## Destructors
+
+

void wrap${classname_mangled}_finalize(JSObjectRef thisObject) { SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) delete (${type}*)(t->swigCObject); if(t) delete t; }

+

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + +## Initializer +
+

bool ${modulename}_initialize(JSGlobalContextRef context) { SWIG_InitializeModule(0);

+
JSObjectRef global_object = JSContextGetGlobalObject(context);
+
+/* Initialize the base swig type object */
+_SwigObject_objectDefinition.staticFunctions = _SwigObject_functions;
+_SwigObject_objectDefinition.staticValues = _SwigObject_values;
+_SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition);
+
+/* Create objects for namespaces */
+${create_namespaces}
+
+/* Create classes */
+${initializercode}
+
+/* Register namespaces */
+${register_namespaces}
+
+return true;
+
+

}

+

## Class template defintions + +A class is specified by a static part (`*_classDefinition`) and a dynamic part (`*_objectDefinition`). +
+

${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}objectDefinition); SWIGTYPE${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%}

+

Notes: +- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` + which is retrieved by `Swig_name_mangle(Getattr(n, "name"))` +- ClassDefinitions are built using the staticValues array and the staticFunction array. The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties to the class object. + +## Inheritance +
+

{${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef};

+

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` +- Note: multiple inheritance is not possible; thus we will always take the first parent class + +## Namespaces + +Namespaces are objects without class templates. i.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. +
+

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

+

## Registration + +The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. + +* Global functions +
+

JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper}

+

* Classes +
+

JS_registerClass(context, ${namespace}_object, "${classname}", &${classname_mangled}_classDefinition)

+

Note: every class template has an associated constructor function wrapper, which is registered here + +* Namespaces +
+

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

+

Namespaces are registered using: +
+

JS_registerNamespace(context, ${namespace}_object, ${parent_namespace}_object, "${namespace}");

+

~~

+
+ + diff --git a/Doc/Manual/chapters b/Doc/Manual/chapters index 45d35e793..c5f655254 100644 --- a/Doc/Manual/chapters +++ b/Doc/Manual/chapters @@ -23,6 +23,7 @@ D.html Go.html Guile.html Java.html +Javascript.html Lisp.html Lua.html Modula3.html diff --git a/Doc/Manual/style.css b/Doc/Manual/style.css index 02329e56f..7eabf91ae 100644 --- a/Doc/Manual/style.css +++ b/Doc/Manual/style.css @@ -25,7 +25,7 @@ div.indent { margin-right: 4em; } -div.code { +div.code, div:not(.code) pre { border-style: solid; border-width: 1px; padding: 2pt; @@ -82,3 +82,7 @@ div.indent p { margin-right: 0; } +h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { + text-decoration:none; + color: #000000; +} diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 218d8eca5..c06f09f9a 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -589,6 +589,86 @@ java_clean: rm -f core @EXTRA_CLEAN@ rm -f *.@OBJEXT@ *@JAVASO@ +################################################################## +##### JAVASCRIPT ###### +################################################################## + +# Note: These targets are also from within Makefiles in the Example directories. +# There is a common makefile, 'Examples/javascript/js_example.mk' to simplify +# create a configuration for a new example. + + +ROOT_DIR = @ROOT_DIR@ +JSCFLAGS = @JSCFLAGS@ +JSCXXFLAGS = @JSCXXFLAGS@ +JSINCLUDES = @JSCOREINC@ @JSV8INC@ +JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ +JSLIBRARYPREFIX = @JSLIBRARYPREFIX@ +JSSO =@JSSO@ +JSLDSHARED = @JSLDSHARED@ +JSCXXSHARED = @JSCXXSHARED@ + +SWIGJS = $(SWIG) -javascript + +# ---------------------------------------------------------------- +# Creating and building Javascript wrappers +# ---------------------------------------------------------------- + +javascript_wrapper: + $(SWIGJS) $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH) + +javascript_wrapper_cpp: $(SRCS) + $(SWIGJS) -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cxx $(INTERFACEPATH) + +javascript_build: $(SRCS) + $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) + $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +javascript_build_cpp:: $(SRCS) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) + $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +# TODO: make node-gyp configurable and detected via ./configure +javascript_build_node: $(SRCS) + node-gyp --loglevel=silent configure build 1>>/dev/null + +# These targets are used by the test-suite: + +javascript: $(SRCS) javascript_custom_interpreter + $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) + $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) + $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +javascript_cpp: $(SRCS) javascript_custom_interpreter + $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) + $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) + +# ----------------------------------------------------------------- +# Running a javascript example +# ----------------------------------------------------------------- + +javascript_custom_interpreter: + (cd $(ROOT_DIR)/Tools/javascript && $(MAKE) JSENGINE='$(JSENGINE)') + +javascript_run: javascript_custom_interpreter + $(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) -L $(TARGET) runme.js + +# TODO: make node configurable and detected via ./configure +javascript_run_node: + node runme.js + +# ----------------------------------------------------------------- +# Cleaning the javascript examples +# ----------------------------------------------------------------- + +javascript_clean: + rm -rf build + rm -f *_wrap* runme + rm -f core @EXTRA_CLEAN@ + rm -f *.@OBJEXT@ *@JSSO@ *.$(SO) + (cd $(ROOT_DIR)/Tools/javascript && $(MAKE) -s clean) + ################################################################## ##### ANDROID ###### ################################################################## diff --git a/Examples/javascript/check.list b/Examples/javascript/check.list new file mode 100644 index 000000000..040267812 --- /dev/null +++ b/Examples/javascript/check.list @@ -0,0 +1,13 @@ +class +constant +enum +#exception +functor +#namespace +operator +overload +pointer +#reference +simple +template +variables diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/class/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/class/binding.gyp b/Examples/javascript/class/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/class/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/class/example.cxx b/Examples/javascript/class/example.cxx new file mode 100755 index 000000000..e23fa6f73 --- /dev/null +++ b/Examples/javascript/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ +#include +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/javascript/class/example.h b/Examples/javascript/class/example.h new file mode 100755 index 000000000..64b7684fa --- /dev/null +++ b/Examples/javascript/class/example.h @@ -0,0 +1,34 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; diff --git a/Examples/javascript/class/example.i b/Examples/javascript/class/example.i new file mode 100755 index 000000000..75700b305 --- /dev/null +++ b/Examples/javascript/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/javascript/class/example.js b/Examples/javascript/class/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/class/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js new file mode 100755 index 000000000..e1d5d9797 --- /dev/null +++ b/Examples/javascript/class/runme.js @@ -0,0 +1,46 @@ +var example = require("./example"); + +// ----- Object creation ----- + +console.log("Creating some objects:"); +c = new example.Circle(10); +console.log("Created circle " + c); +s = new example.Square(10); +console.log("Created square " + s); + +// ----- Access a static member ----- +console.log("\nA total of " + example.Shape.nshapes + " shapes were created"); // access static member as properties of the class object + +// ----- Member data access ----- +// Set the location of the object. +// Note: methods in the base class Shape are used since +// x and y are defined there. + +c.x = 20; +c.y = 30; +s.x = -10; +s.y = 5; + +console.log("\nHere is their new position:"); +console.log("Circle = (" + c.x + "," + c.y + ")"); +console.log("Square = (" + s.x + "," + s.y + ")"); + +// ----- Call some methods ----- +console.log("\nHere are some properties of the shapes:"); +console.log("Circle:"); +console.log("area = " + c.area() + ""); +console.log("perimeter = " + c.perimeter() + ""); +console.log("\n"); +console.log("Square:"); +console.log("area = " + s.area() + ""); +console.log("perimeter = " + s.perimeter() + ""); + +// ----- Delete everything ----- +console.log("\nGuess I'll clean up now"); +// Note: this invokes the virtual destructor +delete c; +delete s; + +console.log(example.Shape.nshapes + " shapes remain"); + +console.log("Goodbye"); diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile new file mode 100755 index 000000000..a2570636e --- /dev/null +++ b/Examples/javascript/constant/Makefile @@ -0,0 +1,3 @@ +SRCS = + +include ../js_example.mk diff --git a/Examples/javascript/constant/binding.gyp b/Examples/javascript/constant/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/constant/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/constant/example.h b/Examples/javascript/constant/example.h new file mode 100644 index 000000000..2c88ebd1e --- /dev/null +++ b/Examples/javascript/constant/example.h @@ -0,0 +1,8 @@ +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" +#define EXTERN extern +#define FOO (ICONST + BAR) diff --git a/Examples/javascript/constant/example.i b/Examples/javascript/constant/example.i new file mode 100755 index 000000000..a6d28e7c9 --- /dev/null +++ b/Examples/javascript/constant/example.i @@ -0,0 +1,24 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/javascript/constant/example.js b/Examples/javascript/constant/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/constant/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/constant/runme.js b/Examples/javascript/constant/runme.js new file mode 100755 index 000000000..2188bf099 --- /dev/null +++ b/Examples/javascript/constant/runme.js @@ -0,0 +1,14 @@ +var example = require("./example"); + +console.log("ICONST = " + example.ICONST + " (should be 42)\n"); +console.log("FCONST = " + example.FCONST + " (should be 2.1828)\n"); +console.log("CCONST = " + example.CCONST + " (should be 'x')\n"); +console.log("CCONST2 = " + example.CCONST2 + " (this should be on a new line)\n"); +console.log("SCONST = " + example.SCONST + " (should be 'Hello World')\n"); +console.log("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')\n"); +console.log("EXPR = " + example.EXPR + " (should be 48.5484)\n"); +console.log("iconst = " + example.iconst + " (should be 37)\n"); +console.log("fconst = " + example.fconst + " (should be 3.14)\n"); + +console.log("EXTERN = " + example.EXTERN + " (should be undefined)\n"); +console.log("FOO = " + example.FOO + " (should be undefined)\n"); diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/enum/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/enum/binding.gyp b/Examples/javascript/enum/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/enum/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/enum/example.cxx b/Examples/javascript/enum/example.cxx new file mode 100755 index 000000000..6785e57ac --- /dev/null +++ b/Examples/javascript/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.c */ + +#include "example.h" +#include + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/javascript/enum/example.h b/Examples/javascript/enum/example.h new file mode 100755 index 000000000..9119cd9fc --- /dev/null +++ b/Examples/javascript/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/javascript/enum/example.i b/Examples/javascript/enum/example.i new file mode 100755 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/javascript/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/javascript/enum/example.js b/Examples/javascript/enum/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/enum/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js new file mode 100755 index 000000000..d4e89e8c8 --- /dev/null +++ b/Examples/javascript/enum/runme.js @@ -0,0 +1,34 @@ +var example = require("./example"); + +// ----- Object creation ----- + +// Print out the value of some enums +console.log("*** color ***"); +console.log(" RED =" + example.RED); +console.log(" BLUE =" + example.BLUE); +console.log(" GREEN =" + example.GREEN); + +console.log("\n*** Foo::speed ***"); +console.log(" Foo_IMPULSE =" + example.Foo.IMPULSE); +console.log(" Foo_WARP =" + example.Foo.WARP); +console.log(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); + +console.log("\nTesting use of enums with functions\n"); + +example.enum_test(example.RED, example.Foo.IMPULSE); +example.enum_test(example.BLUE, example.Foo.WARP); +example.enum_test(example.GREEN, example.Foo.LUDICROUS); +example.enum_test(1234,5678); + +console.log("\nTesting use of enum with class method"); +f = new example.Foo(); + +f.enum_test(example.Foo.IMPULSE); +f.enum_test(example.Foo.WARP); +f.enum_test(example.Foo.LUDICROUS); + +// enum value BLUE of enum color is accessed as property of cconst +console.log("example.BLUE= " + example.BLUE); + +// enum value LUDICROUS of enum Foo::speed is accessed as as property of cconst +console.log("example.speed.LUDICROUS= " + example.Foo.LUDICROUS); diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/exception/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/exception/binding.gyp b/Examples/javascript/exception/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/exception/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/exception/example.cxx b/Examples/javascript/exception/example.cxx new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Examples/javascript/exception/example.cxx @@ -0,0 +1 @@ + diff --git a/Examples/javascript/exception/example.h b/Examples/javascript/exception/example.h new file mode 100644 index 000000000..7cf917d01 --- /dev/null +++ b/Examples/javascript/exception/example.h @@ -0,0 +1,53 @@ +/* File : example.h */ + +#include +#ifndef SWIG +struct A { +}; +#endif + +class Exc { +public: + Exc(int c, const char *m) { + code = c; + strncpy(msg,m,256); + } + int code; + char msg[256]; +}; + +#if defined(_MSC_VER) + #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + +class Test { +public: + int simple() throw(int) { + throw(37); + return 1; + } + int message() throw(const char *) { + throw("I died."); + return 1; + } + int hosed() throw(Exc) { + throw(Exc(42,"Hosed")); + return 1; + } + int unknown() throw(A*) { + static A a; + throw &a; + return 1; + } + int multi(int x) throw(int, const char *, Exc) { + if (x == 1) throw(37); + if (x == 2) throw("Bleah!"); + if (x == 3) throw(Exc(42,"No-go-diggy-die")); + return 1; + } +}; + +#if defined(_MSC_VER) + #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow) +#endif + diff --git a/Examples/javascript/exception/example.i b/Examples/javascript/exception/example.i new file mode 100644 index 000000000..08672c3a8 --- /dev/null +++ b/Examples/javascript/exception/example.i @@ -0,0 +1,12 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/javascript/exception/example.js b/Examples/javascript/exception/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/exception/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js new file mode 100644 index 000000000..977f51ebc --- /dev/null +++ b/Examples/javascript/exception/runme.js @@ -0,0 +1,64 @@ +var example = require("./example"); + +console.log("Trying to catch some exceptions."); +t = new example.Test(); +try{ + t.unknown(); + throw -1; +} catch(error) +{ + if(error == -1) { + console.log("t.unknown() didn't throw"); + } else { + console.log("successfully catched throw in Test::unknown()."); + } +} + +try{ + t.simple(); + throw -1; +} +catch(error){ + if(error == -1) { + console.log("t.simple() did not throw"); + } else { + console.log("successfully catched throw in Test::simple()."); + } +} + +try{ + t.message(); + throw -1; +} catch(error){ + if(error == -1) { + console.log("t.message() did not throw"); + } else { + console.log("successfully catched throw in Test::message()."); + } +} + +try{ + t.hosed(); + throw -1; +} +catch(error){ + if(error == -1) { + console.log("t.hosed() did not throw"); + } else { + console.log("successfully catched throw in Test::hosed()."); + } +} + +for (var i=1; i<4; i++) { + try{ + t.multi(i); + throw -1; + } + catch(error){ + if(error == -1) { + console.log("t.multi(" + i + ") did not throw"); + } else { + console.log("successfully catched throw in Test::multi()."); + } + } +} diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/functor/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/functor/binding.gyp b/Examples/javascript/functor/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/functor/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/functor/example.cxx b/Examples/javascript/functor/example.cxx new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/functor/example.i b/Examples/javascript/functor/example.i new file mode 100644 index 000000000..0450c2124 --- /dev/null +++ b/Examples/javascript/functor/example.i @@ -0,0 +1,25 @@ +/* File : example.i */ +%module example + + +%inline %{ +// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 +template class Sum { + T res; +public: + Sum(T i = 0) : res(i) { } + void operator() (T x) { res += x; } + T result() const { return res; } +}; + +%} + +%rename(call) *::operator(); // the fn call operator + +// Instantiate a few versions +%template(intSum) Sum; +%template(doubleSum) Sum; + + + + diff --git a/Examples/javascript/functor/example.js b/Examples/javascript/functor/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/functor/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/functor/runme.js b/Examples/javascript/functor/runme.js new file mode 100644 index 000000000..dc12470f4 --- /dev/null +++ b/Examples/javascript/functor/runme.js @@ -0,0 +1,15 @@ +var example = require("./example"); + +a = new example.intSum(0); +b = new example.doubleSum(100.0); + +// Use the objects. They should be callable just like a normal +// javascript function. + +for (i=1;i<=100;i++) + a.call(i); // Note: function call + b.call(Math.sqrt(i)); // Note: function call + +console.log(a.result()); +console.log(b.result()); + diff --git a/Examples/javascript/js_example.mk b/Examples/javascript/js_example.mk new file mode 100644 index 000000000..6cb6eb113 --- /dev/null +++ b/Examples/javascript/js_example.mk @@ -0,0 +1,52 @@ +# Note: as a convention an example must be in a child directory of this. +# These paths are relative to such an example directory +EXAMPLES_TOP=../.. +SWIG_TOP=../../.. + +SWIG = $(SWIG_TOP)/preinst-swig + +# TODO: we could only set these only if not yet set... +JS_SCRIPT = runme.js +TARGET = example +INTERFACE = example.i + +ifneq (, $(ENGINE)) + JSENGINE=$(ENGINE) +else + JSENGINE=node +endif + +SWIGOPT=-$(JSENGINE) + +ifeq (node,$(JSENGINE)) + +build: wrapper + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_node + +else + +build: wrapper + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_cpp + +endif + +wrapper: + $(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp + +ifeq (node,$(JSENGINE)) + +check: build + $(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' javascript_run_node + +else + +check: build + $(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' TARGET='$(TARGET)' javascript_run + +endif + +clean: + $(MAKE) -f $(EXAMPLES_TOP)/Makefile javascript_clean diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/namespace/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/namespace/binding.gyp b/Examples/javascript/namespace/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/namespace/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/namespace/example.cxx b/Examples/javascript/namespace/example.cxx new file mode 100644 index 000000000..5beeb09fe --- /dev/null +++ b/Examples/javascript/namespace/example.cxx @@ -0,0 +1,36 @@ +/* File : example.c */ + +#include +#include "example.h" + +#define M_PI 3.14159 + + +/* A global variable */ +namespace nspace +{ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + +Circle::Circle(): radius(1.0) {} + +Circle::Circle(double r): radius(r) { + std::cout << "created Circle with r=" << radius << std::endl; +} + +double Circle::area() { + std::cout << "Circle::area called, r=" << radius << std::endl; + return M_PI*radius*radius; +} +} diff --git a/Examples/javascript/namespace/example.h b/Examples/javascript/namespace/example.h new file mode 100644 index 000000000..7f76c2f07 --- /dev/null +++ b/Examples/javascript/namespace/example.h @@ -0,0 +1,20 @@ + +namespace nspace { + +extern int gcd(int x, int y); +extern double Foo; + +class Circle +{ +public: + Circle(); + + Circle(double r); + + double area(); + + double radius; + +}; + +} diff --git a/Examples/javascript/namespace/example.i b/Examples/javascript/namespace/example.i new file mode 100644 index 000000000..e14b10b44 --- /dev/null +++ b/Examples/javascript/namespace/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +%feature("nspace", 1); + +%include "example.h" diff --git a/Examples/javascript/namespace/example.js b/Examples/javascript/namespace/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/namespace/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/namespace/runme.js b/Examples/javascript/namespace/runme.js new file mode 100644 index 000000000..08e0d3769 --- /dev/null +++ b/Examples/javascript/namespace/runme.js @@ -0,0 +1,10 @@ +var example = require("./example"); + +console.log("Global variable Foo=" + example.nspace.Foo); +example.nspace.Foo = 5; +console.log("Variable Foo changed to " + example.nspace.Foo); +console.log("GCD of number 6,18 is " + example.nspace.gcd(6,18)); + +console.log("Creating some objects:"); +c = new example.nspace.Circle(10); +console.log("area = " + c.area()); diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile new file mode 100755 index 000000000..a2570636e --- /dev/null +++ b/Examples/javascript/operator/Makefile @@ -0,0 +1,3 @@ +SRCS = + +include ../js_example.mk diff --git a/Examples/javascript/operator/binding.gyp b/Examples/javascript/operator/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/operator/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/operator/example.h b/Examples/javascript/operator/example.h new file mode 100644 index 000000000..4da6a2307 --- /dev/null +++ b/Examples/javascript/operator/example.h @@ -0,0 +1,36 @@ +/* File : example.h */ +#include + +class Complex { +private: + double rpart, ipart; +public: + Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } + Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } + Complex &operator=(const Complex &c) { + rpart = c.rpart; + ipart = c.ipart; + return *this; + } + Complex operator+(const Complex &c) const { + return Complex(rpart+c.rpart, ipart+c.ipart); + } + Complex operator-(const Complex &c) const { + return Complex(rpart-c.rpart, ipart-c.ipart); + } + Complex operator*(const Complex &c) const { + return Complex(rpart*c.rpart - ipart*c.ipart, + rpart*c.ipart + c.rpart*ipart); + } + Complex operator-() const { + return Complex(-rpart, -ipart); + } + + double re() const { return rpart; } + double im() const { return ipart; } +}; + + + + + diff --git a/Examples/javascript/operator/example.i b/Examples/javascript/operator/example.i new file mode 100644 index 000000000..7a1bd45e1 --- /dev/null +++ b/Examples/javascript/operator/example.i @@ -0,0 +1,34 @@ +/* File : example.i */ +%module example +#pragma SWIG nowarn=SWIGWARN_IGNORE_OPERATOR_EQ +%{ +#include "example.h" +%} + +/* This header file is a little tough to handle because it has overloaded + operators and constructors. We're going to try and deal with that here */ + +/* This turns the copy constructor in a function ComplexCopy() that can + be called */ + +%rename(assign) Complex::operator=; +%rename(plus) Complex::operator+; +%rename(minus) Complex::operator-(const Complex &) const; +%rename(uminus) Complex::operator-() const; +%rename(times) Complex::operator*; + +/* Now grab the original header file */ +%include "example.h" + +/* An output method that turns a complex into a short string */ +%extend Complex { + char *toString() { + static char temp[512]; + sprintf(temp,"(%g,%g)", $self->re(), $self->im()); + return temp; + } + static Complex* copy(const Complex& c) { + return new Complex(c); + } +}; + diff --git a/Examples/javascript/operator/example.js b/Examples/javascript/operator/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/operator/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/operator/runme.js b/Examples/javascript/operator/runme.js new file mode 100644 index 000000000..a700918d6 --- /dev/null +++ b/Examples/javascript/operator/runme.js @@ -0,0 +1,25 @@ +var example = require("./example"); + +a = new example.Complex(2,3); +b = new example.Complex(-5,10); + +console.log ("a =" + a); +console.log ("b =" + b); + +c = a.plus(b); + +console.log("c =" + c); +console.log("a*b =" + a.times(b)); +console.log("a-c =" + a.minus(c)); + +e = example.Complex.copy(a.minus(c)); +console.log("e =" + e); + +// Big expression +f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus()); +console.log("f =" + f); + + + + + diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile new file mode 100755 index 000000000..a2570636e --- /dev/null +++ b/Examples/javascript/overload/Makefile @@ -0,0 +1,3 @@ +SRCS = + +include ../js_example.mk diff --git a/Examples/javascript/overload/binding.gyp b/Examples/javascript/overload/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/overload/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/overload/example.h b/Examples/javascript/overload/example.h new file mode 100644 index 000000000..2f112f1e1 --- /dev/null +++ b/Examples/javascript/overload/example.h @@ -0,0 +1,28 @@ +#include + +void f() { + std::cout << "Called f()." << std::endl; +} + +void f(int val) { + std::cout << "Called f(int)." << std::endl; +} +void f(int val1, int val2) { + std::cout << "Called f(int, int)." << std::endl; +} + +void f(const char* s) { + std::cout << "Called f(const char*)." << std::endl; +} + +void f(bool val) { + std::cout << "Called f(bool)." << std::endl; +} + +void f(long val) { + std::cout << "Called f(long)." << std::endl; +} + +void f(double val) { + std::cout << "Called f(double)." << std::endl; +} diff --git a/Examples/javascript/overload/example.i b/Examples/javascript/overload/example.i new file mode 100644 index 000000000..b86689f8a --- /dev/null +++ b/Examples/javascript/overload/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* + Note: overloading is implemented in a sloppy way currently + i.e., only the number of arguments is taken into conideration + for dispatching. + To solve the problem one has to rename such conflicting methods. +*/ +%rename(f_double) f(double val); + +%include "example.h" diff --git a/Examples/javascript/overload/example.js b/Examples/javascript/overload/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/overload/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/overload/runme.js b/Examples/javascript/overload/runme.js new file mode 100644 index 000000000..1e6c861a6 --- /dev/null +++ b/Examples/javascript/overload/runme.js @@ -0,0 +1,9 @@ +var example = require("./example"); + +example.f(); +example.f(1); +example.f(1, 2); +example.f("bla"); +example.f(false); +example.f(11111111111); +example.f_double(1.0); diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/pointer/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/pointer/binding.gyp b/Examples/javascript/pointer/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/pointer/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/pointer/example.cxx b/Examples/javascript/pointer/example.cxx new file mode 100755 index 000000000..8762329fe --- /dev/null +++ b/Examples/javascript/pointer/example.cxx @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void subtract(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/javascript/pointer/example.i b/Examples/javascript/pointer/example.i new file mode 100755 index 000000000..38c67d7d2 --- /dev/null +++ b/Examples/javascript/pointer/example.i @@ -0,0 +1,30 @@ +/* File : example.i */ +%module example + +%{ +extern void add(int *, int *, int *); +extern void subtract(int *, int *, int *); +extern int divide(int, int, int *); +%} + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +extern void add(int *x, int *y, int *result); +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void subtract(int *INPUT, int *INPUT, int *OUTPUT); + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +extern int divide(int n, int d, int *r); + + + + diff --git a/Examples/javascript/pointer/example.js b/Examples/javascript/pointer/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/pointer/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/pointer/runme.js b/Examples/javascript/pointer/runme.js new file mode 100755 index 000000000..7f1e51c9e --- /dev/null +++ b/Examples/javascript/pointer/runme.js @@ -0,0 +1,35 @@ +var example = require("./example"); + +// First create some objects using the pointer library. +console.log("Testing the pointer library\n"); +a = example.new_intp(); +b = example.new_intp(); +c = example.new_intp(); + +example.intp_assign(a,37); +example.intp_assign(b,42); + +console.log(" a = " + example.intp_value(a) + "\n"); +console.log(" b = " + example.intp_value(b) + "\n"); +console.log(" c = " + example.intp_value(c) + "\n"); + +//// Call the add() function with some pointers +example.add(a, b, c); + +// +//// Now get the result +r = example.intp_value(c); +console.log(" 37 + 42 = " + r + "\n"); + +// Clean up the pointers +example.delete_intp(a); +example.delete_intp(b); +example.delete_intp(c); + +//// Now try the typemap library +//// This should be much easier. Now how it is no longer +//// necessary to manufacture pointers. +//"OUTPUT" Mapping is not supported +//console.log("Trying the typemap library"); +//r = example.subtract(37,42); +//console.log("37 - 42 =" + r); diff --git a/Examples/javascript/pointer/typemaps.i b/Examples/javascript/pointer/typemaps.i new file mode 100644 index 000000000..e69de29bb diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/reference/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/reference/binding.gyp b/Examples/javascript/reference/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/reference/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/reference/example.cxx b/Examples/javascript/reference/example.cxx new file mode 100755 index 000000000..8a513bf49 --- /dev/null +++ b/Examples/javascript/reference/example.cxx @@ -0,0 +1,46 @@ +/* File : example.cxx */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include "example.h" +#include +#include + +Vector operator+(const Vector &a, const Vector &b) { + Vector r; + r.x = a.x + b.x; + r.y = a.y + b.y; + r.z = a.z + b.z; + return r; +} + +char *Vector::print() { + static char temp[512]; + sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z); + return temp; +} + +VectorArray::VectorArray(int size) { + items = new Vector[size]; + maxsize = size; +} + +VectorArray::~VectorArray() { + delete [] items; +} + +Vector &VectorArray::operator[](int index) { + if ((index < 0) || (index >= maxsize)) { + printf("Panic! Array index out of bounds.\n"); + exit(1); + } + return items[index]; +} + +int VectorArray::size() { + return maxsize; +} + diff --git a/Examples/javascript/reference/example.h b/Examples/javascript/reference/example.h new file mode 100755 index 000000000..4915adb1b --- /dev/null +++ b/Examples/javascript/reference/example.h @@ -0,0 +1,26 @@ +/* File : example.h */ + +class Vector { +private: + double x,y,z; +public: + Vector() : x(0), y(0), z(0) { }; + Vector(double x, double y, double z) : x(x), y(y), z(z) { }; + friend Vector operator+(const Vector &a, const Vector &b); + char *print(); +}; + +class VectorArray { +private: + Vector *items; + int maxsize; +public: + VectorArray(int maxsize); + ~VectorArray(); + Vector &operator[](int); + int size(); +}; + + + + diff --git a/Examples/javascript/reference/example.i b/Examples/javascript/reference/example.i new file mode 100755 index 000000000..1cf19c82c --- /dev/null +++ b/Examples/javascript/reference/example.i @@ -0,0 +1,42 @@ +/* File : example.i */ + +/* This file has a few "typical" uses of C++ references. */ + +%module example + +%{ +#include "example.h" +%} + +class Vector { +public: + Vector(double x, double y, double z); + ~Vector(); + char *print(); +}; + +/* This helper function calls an overloaded operator */ +%inline %{ +Vector addv(Vector &a, Vector &b) { + return a+b; +} +%} + +/* Wrapper around an array of vectors class */ + +class VectorArray { +public: + VectorArray(int maxsize); + ~VectorArray(); + int size(); + + /* This wrapper provides an alternative to the [] operator */ + %extend { + Vector &get(int index) { + return (*$self)[index]; + } + void set(int index, Vector &a) { + (*$self)[index] = a; + } + } +}; diff --git a/Examples/javascript/reference/example.js b/Examples/javascript/reference/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/reference/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/reference/runme.js b/Examples/javascript/reference/runme.js new file mode 100755 index 000000000..935d2b948 --- /dev/null +++ b/Examples/javascript/reference/runme.js @@ -0,0 +1,67 @@ +// This file illustrates the manipulation of C++ references in Javascript. +var example = require("./example"); + +// ----- Object creation ----- + +console.log("Creating some objects:\n"); +a = new example.Vector(3,4,5); +b = new example.Vector(10,11,12); + +console.log(" created" + a.print()); +console.log(" created" + b.print()); + +// ----- Call an overloaded operator ----- + +// This calls the wrapper we placed around operator+(const Vector &a, const Vector &) +// It returns a new allocated object. + +console.log("Adding a+b\n"); +c = example.addv(a, b); +console.log("a+b = " + c.print()); + + +// TODO: Note: Unless we free the result, a memory leak will occur +//delete_Vector(c); + +// ----- Create a vector array ----- + +// Note: Using the high-level interface here +console.log("Creating an array of vectors\n"); +va = new example.VectorArray(10); +console.log("va = " + va + "\n"); + +// ----- Set some values in the array ----- + +// These operators copy the value of a and b to the vector array +va.set(0,a); +va.set(1,b); + +// This will work, but it will cause a memory leak! +va.set(2,example.addv(a,b)); + +// The non-leaky way to do it +//c = addv(a,b); +//va.set(3,c); +//delete_Vector(c); + +// Get some values from the array + +console.log("Getting some array values\n"); +for (i = 0; i < 5; i++) { + temp = va.get(i); + console.log(i,temp.print()); +} + +// Watch under resource meter to check on this +console.log("Making sure we don't leak memory.\n"); +for (i = 0; i < 1000000; i++) { + c = va.get(i % 10); +} +//---------TODO--------- +//----- Clean up ----- +//console.log("Cleaning up\n"); + +//example.delete_VectorArray(va); +//example.delete_Vector(a); +//example.delete_Vector(b); + diff --git a/Examples/javascript/reference/swig_gdb.log b/Examples/javascript/reference/swig_gdb.log new file mode 100644 index 000000000..57bca0306 --- /dev/null +++ b/Examples/javascript/reference/swig_gdb.log @@ -0,0 +1,22 @@ +Loaded swig printers +SwigStringPrinter: Could not convert const char* to string +SwigListIterator: Construction failed. + Cannot access memory at address 0x7d894828ec834853. +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigListIterator: Construction failed. + Cannot access memory at address 0x7d894828ec834853. +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not dereference struct String* +SwigStringPrinter: Could not dereference struct String* diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/simple/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/simple/binding.gyp b/Examples/javascript/simple/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/simple/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/simple/example.cxx b/Examples/javascript/simple/example.cxx new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/javascript/simple/example.cxx @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/javascript/simple/example.i b/Examples/javascript/simple/example.i new file mode 100644 index 000000000..24093b9bf --- /dev/null +++ b/Examples/javascript/simple/example.i @@ -0,0 +1,7 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +%} diff --git a/Examples/javascript/simple/example.js b/Examples/javascript/simple/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/simple/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/simple/runme.js b/Examples/javascript/simple/runme.js new file mode 100755 index 000000000..be2c18669 --- /dev/null +++ b/Examples/javascript/simple/runme.js @@ -0,0 +1,26 @@ +var example = require("./example"); + +/* Call our gcd() function */ + +x = 42; +y = 105; +g = example.gcd(x,y); +console.log("GCD of x and y is=" + g); + +/* Manipulate the Foo global variable */ + +/* Output its current value */ +console.log("Global variable Foo=" + example.Foo); + +/* Change its value */ +example.Foo = 3.1415926; + +/* See if the change took effect */ +console.log("Variable Foo changed to=" + example.Foo); + + + + + + + diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile new file mode 100755 index 000000000..a2570636e --- /dev/null +++ b/Examples/javascript/template/Makefile @@ -0,0 +1,3 @@ +SRCS = + +include ../js_example.mk diff --git a/Examples/javascript/template/binding.gyp b/Examples/javascript/template/binding.gyp new file mode 100644 index 000000000..69af46b22 --- /dev/null +++ b/Examples/javascript/template/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/template/example.h b/Examples/javascript/template/example.h new file mode 100644 index 000000000..7401df650 --- /dev/null +++ b/Examples/javascript/template/example.h @@ -0,0 +1,32 @@ +/* File : example.h */ + +// Some template definitions + +template T max(T a, T b) { return a>b ? a : b; } + +template class vector { + T *v; + int sz; + public: + vector(int _sz) { + v = new T[_sz]; + sz = _sz; + } + T &get(int index) { + return v[index]; + } + void set(int index, T &val) { + v[index] = val; + } +#ifdef SWIG + %extend { + T getitem(int index) { + return $self->get(index); + } + void setitem(int index, T val) { + $self->set(index,val); + } + } +#endif +}; + diff --git a/Examples/javascript/template/example.i b/Examples/javascript/template/example.i new file mode 100644 index 000000000..8f94c4da1 --- /dev/null +++ b/Examples/javascript/template/example.i @@ -0,0 +1,17 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + +/* Now instantiate some specific template declarations */ + +%template(maxint) max; +%template(maxdouble) max; +%template(vecint) vector; +%template(vecdouble) vector; + diff --git a/Examples/javascript/template/example.js b/Examples/javascript/template/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/template/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/template/runme.js b/Examples/javascript/template/runme.js new file mode 100644 index 000000000..55894dfd5 --- /dev/null +++ b/Examples/javascript/template/runme.js @@ -0,0 +1,30 @@ +var example = require("./example"); + +//Call some templated functions +console.log(example.maxint(3,7)); +console.log(example.maxdouble(3.14,2.18)); + +// Create some class + +iv = new example.vecint(100); +dv = new example.vecdouble(1000); + +for(i=0;i<=100;i++) + iv.setitem(i,2*i); + +for(i=0;i<=1000;i++) + dv.setitem(i, 1.0/(i+1)); + +sum = 0; +for(i=0;i<=100;i++) + sum = sum + iv.getitem(i); + +console.log(sum); + +sum = 0.0; +for(i=0;i<=1000;i++) + sum = sum + dv.getitem(i); +console.log(sum); + +delete iv; +delete dv; diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile new file mode 100755 index 000000000..b0934786a --- /dev/null +++ b/Examples/javascript/variables/Makefile @@ -0,0 +1,3 @@ +SRCS = example.cxx + +include ../js_example.mk diff --git a/Examples/javascript/variables/binding.gyp b/Examples/javascript/variables/binding.gyp new file mode 100644 index 000000000..54eebfaa0 --- /dev/null +++ b/Examples/javascript/variables/binding.gyp @@ -0,0 +1,8 @@ +{ + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +} diff --git a/Examples/javascript/variables/example.cxx b/Examples/javascript/variables/example.cxx new file mode 100755 index 000000000..3ad4c2323 --- /dev/null +++ b/Examples/javascript/variables/example.cxx @@ -0,0 +1,96 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include +#include +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +#ifdef __cplusplus // Note: for v8 this must be linkable with g++, without extern cstrvar is mangled +extern const char cstrvar[] = "Goodbye"; +#else +const char cstrvar[] = "Goodbye"; +#endif +const +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/javascript/variables/example.h b/Examples/javascript/variables/example.h new file mode 100755 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/javascript/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/javascript/variables/example.i b/Examples/javascript/variables/example.i new file mode 100755 index 000000000..591b871ed --- /dev/null +++ b/Examples/javascript/variables/example.i @@ -0,0 +1,49 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + diff --git a/Examples/javascript/variables/example.js b/Examples/javascript/variables/example.js new file mode 100644 index 000000000..79cd3913f --- /dev/null +++ b/Examples/javascript/variables/example.js @@ -0,0 +1 @@ +module.exports = require("./build/Release/example"); diff --git a/Examples/javascript/variables/runme.js b/Examples/javascript/variables/runme.js new file mode 100755 index 000000000..d07861713 --- /dev/null +++ b/Examples/javascript/variables/runme.js @@ -0,0 +1,68 @@ +var example = require("./example"); + +// Try to set the values of some global variables +example.ivar = 42; +example.svar = -31000; +example.lvar = 65537; +example.uivar = 123456; +example.usvar = 61000; +example.ulvar = 654321; +example.scvar = -13; +example.ucvar = 251; +example.cvar = "S"; +example.fvar = 3.14159; +example.dvar = 2.1828; +example.strvar = "Hello World"; +example.iptrvar= example.new_int(37); +example.ptptr = example.new_Point(37,42); +example.name = "Bill"; + +// Now console.log out the values of the variables +console.log("Variables (values console.loged from Python)" + "\n"); +console.log("ivar = " + example.ivar + "\n"); +console.log("svar = " + example.svar + "\n"); +console.log("lvar = " + example.lvar + "\n"); +console.log("uivar = " + example.uivar + "\n"); +console.log("usvar = " + example.usvar + "\n"); +console.log("ulvar = " + example.ulvar + "\n"); +console.log("scvar = " + example.scvar + "\n"); +console.log("ucvar = " + example.ucvar + "\n"); +console.log("fvar = " + example.fvar + "\n"); +console.log("dvar = " + example.dvar + "\n"); +console.log("cvar = " + example.cvar + "\n"); +console.log("strvar = " + example.strvar+ "\n"); +console.log("cstrvar = " + example.cstrvar+ "\n"); +console.log("iptrvar = " + example.iptrvar+ "\n"); +console.log("name = " + example.name + "\n"); +console.log("ptptr = " + example.ptptr + ": " + example.Point_print(example.ptptr) + "\n"); +console.log("pt = " + example.pt + ": " + example.Point_print(example.pt) + "\n"); + + +console.log("\nVariables (values console.loged from C)"); + +example.print_vars(); + +console.log("\nNow I'm going to try and modify some read only variables"); + +console.log("Tring to set 'path'"); +try{ + example.path = "Whoa!"; + console.log("Hey, what's going on?!?! This shouldn't work"); +} +catch(e){ + console.log("Good."); +} + +console.log("Trying to set 'status'"); +try{ + example.status = 0; + console.log("Hey, what's going on?!?! This shouldn't work"); +} catch(e){ + console.log("Good."); +} + +console.log("\nI'm going to try and update a structure variable.\n"); +example.pt = example.ptptr; +console.log("The new value is: "); +example.pt_print(); +console.log("You should see the value: " + example.Point_print(example.ptptr)); diff --git a/Examples/javascript/variables/swig_gdb.log b/Examples/javascript/variables/swig_gdb.log new file mode 100644 index 000000000..2fe437110 --- /dev/null +++ b/Examples/javascript/variables/swig_gdb.log @@ -0,0 +1,9 @@ +Loaded swig printers +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string +SwigStringPrinter: Could not convert const char* to string diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index b9239315a..14f13bed8 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -98,6 +98,7 @@ C_TEST_BROKEN += \ tag_no_clash_with_variable # C++ test cases. (Can be run individually using: make testcase.cpptest) +ifndef SKIP_CPP_CASES CPP_TEST_CASES += \ abstract_access \ abstract_inherit \ @@ -489,6 +490,7 @@ CPP_TEST_CASES += \ voidtest \ wallkw \ wrapmacro +endif # C++11 test cases. CPP11_TEST_CASES = \ @@ -562,6 +564,7 @@ CPP_TEST_CASES += $(CPP11_TEST_CASES) endif # C test cases. (Can be run individually using: make testcase.ctest) +ifndef SKIP_C_CASES C_TEST_CASES += \ arrays \ bom_utf8 \ @@ -612,9 +615,10 @@ C_TEST_CASES += \ typemap_subst \ union_parameter \ unions - +endif # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest) +ifndef SKIP_MULTI_CPP_CASES MULTI_CPP_TEST_CASES += \ clientdata_prop \ imports \ @@ -623,6 +627,7 @@ MULTI_CPP_TEST_CASES += \ mod \ template_typedef_import \ multi_import +endif # Custom tests - tests with additional commandline options wallkw.cpptest: SWIGOPT += -Wallkw diff --git a/Examples/test-suite/constructor_copy.i b/Examples/test-suite/constructor_copy.i index bfbd706f4..8e92e7840 100644 --- a/Examples/test-suite/constructor_copy.i +++ b/Examples/test-suite/constructor_copy.i @@ -73,7 +73,7 @@ public: %include "std_vector.i" -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGR) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGJAVASCRIPT) #define SWIG_GOOD_VECTOR %ignore std::vector::vector(size_type); %ignore std::vector::resize(size_type); diff --git a/Examples/test-suite/director_nspace.i b/Examples/test-suite/director_nspace.i index fdea75e2f..f24227c68 100644 --- a/Examples/test-suite/director_nspace.i +++ b/Examples/test-suite/director_nspace.i @@ -40,7 +40,7 @@ namespace TopLevel %include // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT) %nspace TopLevel::Bar::Foo; %nspace TopLevel::Bar::FooBar; #else diff --git a/Examples/test-suite/infinity.i b/Examples/test-suite/infinity.i new file mode 100644 index 000000000..41741eb94 --- /dev/null +++ b/Examples/test-suite/infinity.i @@ -0,0 +1,48 @@ +%module infinity + +#include + +/* C99 defines INFINITY + Because INFINITY may be defined by compiler built-ins, we can't use #define. + Instead, expose the variable MYINFINITY and then use %rename to make it INFINITY in the scripting language. +*/ +%rename(INFINITY) MYINFINITY; + + +%inline %{ +#include + +/* C99 math.h defines INFINITY. If not available, this is the fallback. */ +#ifndef INFINITY + #ifdef _MSC_VER + union MSVC_EVIL_FLOAT_HACK + { + unsigned __int8 Bytes[4]; + float Value; + }; + static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}}; + #define INFINITY (INFINITY_HACK.Value) + #endif + + #ifdef __GNUC__ + #define INFINITY (__builtin_inf()) + #elif defined(__clang__) + #if __has_builtin(__builtin_inf) + #define INFINITY (__builtin_inf()) + #endif + #endif + + #ifndef INFINITY + #define INFINITY (1e1000) + #endif +#endif + +/* This will allow us to bind the real INFINITY value through SWIG via MYINFINITY. Use %rename to fix the name. */ +const double MYINFINITY = INFINITY; + +/* Use of float is intentional because the original bug was in the float conversion due to overflow checking. */ +float use_infinity(float inf_val) +{ + return inf_val; +} +%} diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in new file mode 100755 index 000000000..49652f0bd --- /dev/null +++ b/Examples/test-suite/javascript/Makefile.in @@ -0,0 +1,181 @@ +####################################################################### +# Makefile for javascript test-suite +####################################################################### + +LANGUAGE = javascript +SCRIPTSUFFIX = _runme.js +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = @top_builddir@ +SWIG = $(top_builddir)/preinst_swig + +ifneq (, $(ENGINE)) + JSENGINE=$(ENGINE) +else + JSENGINE=node +endif + +# Note: the javascript generator is not ready yet for the real game. +# To be able keep the behavior continously tested that is expected to work already +# we have a 'light' version of the test-suite +# This will be removed and replaced by a list of 'BROKEN_TEST_CASES' when +# the number gets smaller (currently we have about 65 broken tests for JSC, and 85 for V8) + +ifneq (,$(SMOKE)) + +C_TEST_CASES = \ + preproc \ + preproc_include + +CPP_TEST_CASES = \ + abstract_access \ + abstract_typedef \ + abstract_typedef2 \ + abstract_virtual \ + arrays_global \ + array_member \ + char_binary \ + class_ignore \ + class_scope_weird \ + complextest \ + constover \ + constructor_copy \ + cpp_enum \ + cpp_namespace \ + cpp_static \ + enum_template \ + namespace_virtual_method \ + nspace \ + nspace_extend \ + overload_copy \ + rename_simple \ + rename_scope \ + ret_by_value \ + struct_value \ + template_static \ + typedef_class \ + typedef_inherit \ + typedef_scope \ + typemap_arrays \ + typemap_delete \ + typemap_namespace \ + typemap_ns_using \ + using1 \ + using2 \ + javascript_unicode + +SKIP_CPP_CASES = @SKIP_CPP_CASES@ +SKIP_C_CASES = @SKIP_C_CASES@ +SKIP_CPP_STD_CASES = @SKIP_CPP_STD_CASES@ +SKIP_MULTI_CPP_CASES = @SKIP_MULTI_CPP_CASES@ + +endif + +include $(srcdir)/../common.mk + +_setup = \ + if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ + echo "$(ACTION)ing testcase $* (with run test) under javascript ($(JSENGINE))" ; \ + else \ + echo "$(ACTION)ing testcase $* under javascript ($(JSENGINE))" ; \ + fi; + +ifneq (jsc,$(ENGINE)) + + # This test can not be run with v8 as it uses v8 API incompatible output typemaps + typemap_variables.cpptest: + echo "skipping testcase typemap_variables under javascript ($(JSENGINE))." + + # with v8 we have to generate C++ wrappers only + # these tests did raise warnings which are ignored + nested.ctest: SWIGOPT += -w312,-325 + nested_structs.ctest: SWIGOPT += -w312,-325 + unions.ctest: SWIGOPT += -w312,-325 + +endif + +ifeq (node,$(JSENGINE)) + + SWIGOPT += -v8 -DBUILDING_NODE_EXTENSION=1 + + # shut up some warnings + # contract macro has an empty 'else' at the end... + aggregate.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" + contract.cpptest: GYP_CFLAGS = \"-Wno-empty-body\" + + # dunno... ignoring generously + apply_signed_char.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" + constant_pointers.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" + enum_thorough.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\" + + __setup = \ + sh ./setup_test.sh $* $(GYP_CFLAGS); \ + $(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i; + + nodejs_swig_and_compile = \ + node-gyp --loglevel=silent --directory $* configure build 1>>/dev/null + + run_testcase = \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + node $(srcdir)/$*$(SCRIPTSUFFIX); \ + fi + + %.cpptest: + $(_setup) + $(__setup) + $(nodejs_swig_and_compile) + $(run_testcase) + + %.ctest: + $(_setup) + $(__setup) + $(nodejs_swig_and_compile) + $(run_testcase) + + %.multicpptest: + $(_setup) + +else + + SWIGOPT += -$(JSENGINE) + + run_testcase = \ + if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \ + $(top_srcdir)/Tools/javascript/javascript -$(JSENGINE) $(srcdir)/$*$(SCRIPTSUFFIX); \ + fi + + %.cpptest: + $(_setup) + +$(swig_and_compile_cpp) + $(run_testcase) + + %.multicpptest: + $(_setup) + +$(swig_and_compile_multi_cpp) + $(run_testcase) + +endif + +ifeq (v8,$(ENGINE)) + %.ctest: + $(_setup) + +$(swig_and_compile_cpp) + $(run_testcase) + +endif + +ifeq (jsc,$(ENGINE)) + %.ctest: + $(_setup) + +$(swig_and_compile_c) + $(run_testcase) +endif + +%.clean: + rm -rf $* + +clean: + rm -f *_wrap.cxx + rm -f *_wrap.c + rm -f *.so + rm -f *.o diff --git a/Examples/test-suite/javascript/abstract_access_runme.js b/Examples/test-suite/javascript/abstract_access_runme.js new file mode 100644 index 000000000..8f87d2105 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_access_runme.js @@ -0,0 +1,6 @@ +var abstract_access = require("./abstract_access"); + +var d = new abstract_access.D() +if (d.do_x() != 1) { + throw "Error"; +} diff --git a/Examples/test-suite/javascript/abstract_inherit_runme.js b/Examples/test-suite/javascript/abstract_inherit_runme.js new file mode 100644 index 000000000..3af2eae74 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_inherit_runme.js @@ -0,0 +1,40 @@ +var abstract_inherit = require("./abstract_inherit"); + +// Shouldn't be able to instantiate any of these classes +// since none of them implements the pure virtual function +// declared in the base class (Foo). +var Foo = abstract_inherit.Foo; +var Bar = abstract_inherit.Bar; +var Spam = abstract_inherit.Spam; + +var caughtException = false; +try { + new Foo(); +} catch (err) { + caughtException = true; +} +if (!caughtException) { + throw new Error("Foo should be instantiated as it is abstract"); +} + +caughtException = false; +try { + new Bar(); +} catch (err) { + caughtException = true; +} + +if (!caughtException) { + throw new Error("Bar should be instantiated as it is abstract"); +} + +caughtException = false; +try { + new Spam(); +} catch (err) { + caughtException = true; +} + +if (!caughtException) { + throw new Error("Spam should be instantiated as it is abstract"); +} diff --git a/Examples/test-suite/javascript/abstract_typedef2_runme.js b/Examples/test-suite/javascript/abstract_typedef2_runme.js new file mode 100644 index 000000000..c177e49c3 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_typedef2_runme.js @@ -0,0 +1,6 @@ +var abstract_typedef2 = require("./abstract_typedef2"); + +var a = new abstract_typedef2.A_UF(); + +if (a == undefined) + throw "Error"; diff --git a/Examples/test-suite/javascript/abstract_typedef_runme.js b/Examples/test-suite/javascript/abstract_typedef_runme.js new file mode 100644 index 000000000..abcfc581d --- /dev/null +++ b/Examples/test-suite/javascript/abstract_typedef_runme.js @@ -0,0 +1,8 @@ +var abstract_typedef = require("./abstract_typedef"); + +var e = new abstract_typedef.Engine(); +var a = new abstract_typedef.A() + +if (a.write(e) != 1) { + throw "Error"; +} diff --git a/Examples/test-suite/javascript/abstract_virtual_runme.js b/Examples/test-suite/javascript/abstract_virtual_runme.js new file mode 100644 index 000000000..9e2814e41 --- /dev/null +++ b/Examples/test-suite/javascript/abstract_virtual_runme.js @@ -0,0 +1,11 @@ +var abstract_virtual = require("./abstract_virtual"); + +d = new abstract_virtual.D() + +if (d == undefined) + throw "Error"; + +e = new abstract_virtual.E() + +if (e == undefined) + throw "Error"; diff --git a/Examples/test-suite/javascript/array_member_runme.js b/Examples/test-suite/javascript/array_member_runme.js new file mode 100644 index 000000000..8c4ef1da5 --- /dev/null +++ b/Examples/test-suite/javascript/array_member_runme.js @@ -0,0 +1,22 @@ +var array_member = require("./array_member"); + +var f = new array_member.Foo(); +f.data = array_member.global_data; + +for (var i=0; i<8; i++) { + if (array_member.get_value(f.data,i) != array_member.get_value(array_member.global_data,i)) { + throw "Bad array assignment (1)"; + } +} + +for (var i=0; i<8; i++) { + array_member.set_value(f.data,i,-i); +} + +array_member.global_data = f.data; + +for (var i=0; i<8; i++){ + if (array_member.get_value(f.data,i) != array_member.get_value(array_member.global_data,i)) { + throw "Bad array assignment (2)"; + } +} diff --git a/Examples/test-suite/javascript/arrays_global_runme.js b/Examples/test-suite/javascript/arrays_global_runme.js new file mode 100644 index 000000000..fdb365f83 --- /dev/null +++ b/Examples/test-suite/javascript/arrays_global_runme.js @@ -0,0 +1,18 @@ +var arrays_global = require("./arrays_global"); + +arrays_global.array_i = arrays_global.array_const_i; + +arrays_global.BeginString_FIX44a; +arrays_global.BeginString_FIX44b; +arrays_global.BeginString_FIX44c; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44b = "12"+'\0'+"45"; +arrays_global.BeginString_FIX44b; +arrays_global.BeginString_FIX44d; +arrays_global.BeginString_FIX44e; +arrays_global.BeginString_FIX44f; + +arrays_global.test_a("hello","hi","chello","chi"); + +arrays_global.test_b("1234567","hi"); diff --git a/Examples/test-suite/javascript/callback_runme.js b/Examples/test-suite/javascript/callback_runme.js new file mode 100644 index 000000000..9b1ef01a3 --- /dev/null +++ b/Examples/test-suite/javascript/callback_runme.js @@ -0,0 +1,30 @@ +var callback = require("./callback"); + +if (callback.foo(2) !== 2) { + throw new Error("Failed."); +} +if (callback.A_bar(2) !== 4) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.foo) != callback.foo(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, foo) != callback.foo(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.A_bar) != callback.A_bar(3)) { + throw new Error("Failed."); +} +if (callback.foobar(3, callback.foof) != callback.foof(3)) { + throw new Error("Failed."); +} +if (callback.foobar_i(3, callback.foo_i) != callback.foo_i(3)) { + throw new Error("Failed."); +} +if (callback.foobar_d(3.5, callback.foo_d) != callback.foo_d(3.5)) { + throw new Error("Failed."); +} +var a = new callback.A(); +if (callback.foobarm(3, a, callback.A.foom_cb_ptr) != a.foom(3)) { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/char_binary_runme.js b/Examples/test-suite/javascript/char_binary_runme.js new file mode 100644 index 000000000..42abe6060 --- /dev/null +++ b/Examples/test-suite/javascript/char_binary_runme.js @@ -0,0 +1,38 @@ +var char_binary = require("./char_binary"); + +var t = new char_binary.Test(); +if (t.strlen('hile') != 4) { + print(t.strlen('hile')); + throw("bad multi-arg typemap 1"); +} + +if (t.strlen('hil\0') != 4) { + throw("bad multi-arg typemap 2"); +} + +/* + * creating a raw char* + */ +var pc = char_binary.new_pchar(5); +char_binary.pchar_setitem(pc, 0, 'h'); +char_binary.pchar_setitem(pc, 1, 'o'); +char_binary.pchar_setitem(pc, 2, 'l'); +char_binary.pchar_setitem(pc, 3, 'a'); +char_binary.pchar_setitem(pc, 4, 0); + + +if (t.strlen(pc) != 4) { + throw("bad multi-arg typemap (3)"); +} + +char_binary.var_pchar = pc; +if (char_binary.var_pchar != "hola") { + print(char_binary.var_pchar); + throw("bad pointer case (1)"); +} + +char_binary.var_namet = pc; +if (char_binary.var_namet != "hola") { + throw("bad pointer case (2)"); +} +char_binary.delete_pchar(pc); diff --git a/Examples/test-suite/javascript/char_strings_runme.js b/Examples/test-suite/javascript/char_strings_runme.js new file mode 100644 index 000000000..cca50d851 --- /dev/null +++ b/Examples/test-suite/javascript/char_strings_runme.js @@ -0,0 +1,11 @@ +var char_strings = require("./char_strings"); + +var assertIsEqual = function(expected, actual) { + if (expected !== actual) { + throw new Error("Expected "+expected+", was "+actual); + } +}; + +assertIsEqual("hi there", char_strings.CharPingPong("hi there")); +assertIsEqual("hi there", char_strings.CharArrayPingPong("hi there")); +assertIsEqual("hi there", char_strings.CharArrayDimsPingPong("hi there")); diff --git a/Examples/test-suite/javascript/class_ignore_runme.js b/Examples/test-suite/javascript/class_ignore_runme.js new file mode 100644 index 000000000..f0a32a1c4 --- /dev/null +++ b/Examples/test-suite/javascript/class_ignore_runme.js @@ -0,0 +1,6 @@ +var class_ignore = require("./class_ignore"); + +a = new class_ignore.Bar(); + +if (class_ignore.do_blah(a) != "Bar::blah") + throw "Error"; diff --git a/Examples/test-suite/javascript/class_scope_weird_runme.js b/Examples/test-suite/javascript/class_scope_weird_runme.js new file mode 100644 index 000000000..ac745d023 --- /dev/null +++ b/Examples/test-suite/javascript/class_scope_weird_runme.js @@ -0,0 +1,6 @@ +var class_scope_weird = require("./class_scope_weird"); + +f = new class_scope_weird.Foo(); +g = new class_scope_weird.Foo(3); +if (f.bar(3) != 3) + throw RuntimeError; diff --git a/Examples/test-suite/javascript/complextest_runme.js b/Examples/test-suite/javascript/complextest_runme.js new file mode 100644 index 000000000..1fcc97648 --- /dev/null +++ b/Examples/test-suite/javascript/complextest_runme.js @@ -0,0 +1,22 @@ +var complextest = require("./complextest"); + +a = [-1,2]; + +expected = [-1, -2]; + +a_c = complextest.Conj(a); +if (a_c.toString() != expected.toString()) + throw "Error in Conj(a)"; + +a_c_f = complextest.Conjf(a); +if (a_c_f.toString() != expected.toString()) + throw "Error in Conjf(a)"; + +v = new complextest.VectorStdCplx(); +v.add([1,2]); +v.add([2,3]); +v.add([4,3]); +v.add(1); + +// TODO: how to check validity? +complextest.Copy_h(v); diff --git a/Examples/test-suite/javascript/constover_runme.js b/Examples/test-suite/javascript/constover_runme.js new file mode 100644 index 000000000..764d8b328 --- /dev/null +++ b/Examples/test-suite/javascript/constover_runme.js @@ -0,0 +1,33 @@ +var constover = require("./constover"); + +p = constover.test("test"); +if (p != "test") { + throw "test failed!"; +} + +p = constover.test_pconst("test"); +if (p != "test_pconst") { + throw "test_pconst failed!"; +} + +f = new constover.Foo(); + +p = f.test("test"); +if (p != "test") { + throw "member-test failed!"; +} + +p = f.test_pconst("test"); +if (p != "test_pconst") { + throw "member-test_pconst failed!"; +} + +p = f.test_constm("test"); +if (p != "test_constmethod") { + throw "member-test_constm failed!"; +} + +p = f.test_pconstm("test"); +if (p != "test_pconstmethod") { + throw "member-test_pconstm failed!"; +} diff --git a/Examples/test-suite/javascript/constructor_copy_runme.js b/Examples/test-suite/javascript/constructor_copy_runme.js new file mode 100644 index 000000000..39dce52ce --- /dev/null +++ b/Examples/test-suite/javascript/constructor_copy_runme.js @@ -0,0 +1,42 @@ +var constructor_copy = require("./constructor_copy"); + +f1 = new constructor_copy.Foo1(3); +f11 = new constructor_copy.Foo1(f1); + +if (f1.x != f11.x) { + throw "error in ctor copy for Foo1"; +} + +var good = 0; + +f8 = new constructor_copy.Foo8() +try { + f81 = new constructor_copy.Foo8(f8); + good = 0; +} catch (err) { + good = 1; +} + +if (good == 0) { + throw "Error: should not allow calling copy ctor for Foo8"; +} + + +bi = new constructor_copy.Bari(5); +bc = new constructor_copy.Bari(bi); + +if (bi.x != bc.x) { + throw "Error in copy ctor of Bari"; +} + +bd = new constructor_copy.Bard(5); +try { + bc = new constructor_copy.Bard(bd); + good = 0; +} catch (err) { + good = 1; +} + +if (good == 0) { + throw "Error: should not allow calling copy ctor for Bard"; +} diff --git a/Examples/test-suite/javascript/cpp_enum_runme.js b/Examples/test-suite/javascript/cpp_enum_runme.js new file mode 100644 index 000000000..35f7c60ac --- /dev/null +++ b/Examples/test-suite/javascript/cpp_enum_runme.js @@ -0,0 +1,28 @@ +var cpp_enum = require("./cpp_enum"); + +var f = new cpp_enum.Foo() + +if(f.hola != cpp_enum.Hello){ + print(f.hola); + throw "Error"; +} + +f.hola = cpp_enum.Foo.Hi +if(f.hola != cpp_enum.Foo.Hi){ + print(f.hola); + throw "Error"; +} + +f.hola = cpp_enum.Hello + +if(f.hola != cpp_enum.Hello){ + print(f.hola); + throw "Error"; +} + +cpp_enum.Foo.hi = cpp_enum.Hello +if(cpp_enum.Foo.hi != cpp_enum.Hello){ + print(cpp_enum.Foo.hi); + throw "Error"; +} + diff --git a/Examples/test-suite/javascript/cpp_namespace_runme.js b/Examples/test-suite/javascript/cpp_namespace_runme.js new file mode 100644 index 000000000..3bdfef3e9 --- /dev/null +++ b/Examples/test-suite/javascript/cpp_namespace_runme.js @@ -0,0 +1,47 @@ +var cpp_namespace = require("./cpp_namespace"); + +var n = cpp_namespace.fact(4); +if (n != 24){ + throw ("Bad return value error!"); +} +if (cpp_namespace.Foo != 42){ + throw ("Bad variable value error!"); +} + +t = new cpp_namespace.Test(); +if (t.method() != "Test::method"){ + throw ("Bad method return value error!"); +} +if (cpp_namespace.do_method(t) != "Test::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method2(t) != "Test::method"){ + throw ("Bad return value error!"); +} +cpp_namespace.weird("hello", 4); +delete t; + +t2 = new cpp_namespace.Test2(); +t3 = new cpp_namespace.Test3(); +t4 = new cpp_namespace.Test4(); +t5 = new cpp_namespace.Test5(); +if (cpp_namespace.foo3(42) != 42){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t2,40) != "Test2::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t3,40) != "Test3::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t4,40) != "Test4::method"){ + throw ("Bad return value error!"); +} + +if (cpp_namespace.do_method3(t5,40) != "Test5::method"){ + throw ("Bad return value error!"); +} diff --git a/Examples/test-suite/javascript/cpp_static_runme.js b/Examples/test-suite/javascript/cpp_static_runme.js new file mode 100644 index 000000000..2579aeafe --- /dev/null +++ b/Examples/test-suite/javascript/cpp_static_runme.js @@ -0,0 +1,9 @@ +var cpp_static = require("./cpp_static"); + +cpp_static.StaticFunctionTest.static_func(); +cpp_static.StaticFunctionTest.static_func_2(1); +cpp_static.StaticFunctionTest.static_func_3(1,2); +cpp_static.StaticMemberTest.static_int = 10; +if (cpp_static.StaticMemberTest.static_int != 10) +throw "error"; + diff --git a/Examples/test-suite/javascript/director_alternating_runme.js b/Examples/test-suite/javascript/director_alternating_runme.js new file mode 100644 index 000000000..a0411eace --- /dev/null +++ b/Examples/test-suite/javascript/director_alternating_runme.js @@ -0,0 +1,5 @@ +var director_alternating = require("./director_alternating"); + +id = director_alternating.getBar().id(); +if (id != director_alternating.idFromGetBar()) + throw ("Error, Got wrong id: " + str(id)); diff --git a/Examples/test-suite/javascript/disown_runme.js b/Examples/test-suite/javascript/disown_runme.js new file mode 100644 index 000000000..a4a6fd880 --- /dev/null +++ b/Examples/test-suite/javascript/disown_runme.js @@ -0,0 +1,22 @@ +var disown = require("./disown"); + +var a = new disown.A(); +var tmp = a.thisown; +a.thisown = 0 +if (a.thisown) { + throw new Error("Failed."); +} +a.thisown = 1 +if (!a.thisown) { + throw new Error("Failed."); +} +a.thisown = tmp +if (a.thisown != tmp) { + throw new Error("Failed."); +} + +var b = new disown.B(); +b.acquire(a); +if (a.thisown) { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/dynamic_cast_runme.js b/Examples/test-suite/javascript/dynamic_cast_runme.js new file mode 100644 index 000000000..0029cb0f8 --- /dev/null +++ b/Examples/test-suite/javascript/dynamic_cast_runme.js @@ -0,0 +1,12 @@ +var dynamic_cast = require("./dynamic_cast"); + +var f = new dynamic_cast.Foo(); +var b = new dynamic_cast.Bar(); + +var x = f.blah(); +var y = b.blah(); + +var a = dynamic_cast.do_test(y); +if (a != "Bar::test") { + throw new Error("Failed."); +} diff --git a/Examples/test-suite/javascript/empty_runme.js b/Examples/test-suite/javascript/empty_runme.js new file mode 100644 index 000000000..db06b3902 --- /dev/null +++ b/Examples/test-suite/javascript/empty_runme.js @@ -0,0 +1 @@ +var empty = require("./empty"); \ No newline at end of file diff --git a/Examples/test-suite/javascript/enum_template_runme.js b/Examples/test-suite/javascript/enum_template_runme.js new file mode 100644 index 000000000..20f8c3482 --- /dev/null +++ b/Examples/test-suite/javascript/enum_template_runme.js @@ -0,0 +1,8 @@ +var enum_template = require("./enum_template"); + +if (enum_template.MakeETest() != 1) + throw "RuntimeError"; + +if (enum_template.TakeETest(0) != null) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/infinity_runme.js b/Examples/test-suite/javascript/infinity_runme.js new file mode 100644 index 000000000..1dcf366c6 --- /dev/null +++ b/Examples/test-suite/javascript/infinity_runme.js @@ -0,0 +1,4 @@ +var infinity = require("./infinity"); + +var my_infinity = infinity.INFINTY; +var ret_val = infinity.use_infinity(my_infinity); diff --git a/Examples/test-suite/javascript/javascript_unicode_runme.js b/Examples/test-suite/javascript/javascript_unicode_runme.js new file mode 100644 index 000000000..f5f747aa7 --- /dev/null +++ b/Examples/test-suite/javascript/javascript_unicode_runme.js @@ -0,0 +1,9 @@ +var javascript_unicode = require("./javascript_unicode"); + +var str = "olé"; + +var copy = javascript_unicode.copy_string(str); + +if (str !== copy) { + print("Error: copy is not equal: original="+str+", copy="+copy); +} diff --git a/Examples/test-suite/javascript/namespace_virtual_method_runme.js b/Examples/test-suite/javascript/namespace_virtual_method_runme.js new file mode 100644 index 000000000..24d3bd487 --- /dev/null +++ b/Examples/test-suite/javascript/namespace_virtual_method_runme.js @@ -0,0 +1,3 @@ +var namespace_virtual_method = require("./namespace_virtual_method"); + +x = new namespace_virtual_method.Spam(); diff --git a/Examples/test-suite/javascript/node_template/binding.gyp.in b/Examples/test-suite/javascript/node_template/binding.gyp.in new file mode 100644 index 000000000..209774ae0 --- /dev/null +++ b/Examples/test-suite/javascript/node_template/binding.gyp.in @@ -0,0 +1,30 @@ +{ + "targets": [ + { + "target_name": "$testcase", + "sources":[ "../$testcase_wrap.cxx" ], + "include_dirs": ["../.."], + 'defines': [ + 'BUILDING_NODE_EXTENSION=1', + ], + 'conditions': [ + ['OS=="mac"', + { + 'xcode_settings': { + 'GCC_ENABLE_CPP_RTTI': 'YES', + 'GCC_ENABLE_CPP_EXCEPTIONS' : 'YES' + } + } + ], + ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', + { + 'cflags': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cflags], + 'cflags_cc': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cflags], + 'cflags!': [ '-fno-exceptions' ], + 'cflags_cc!': [ '-fno-exceptions', '-fno-rtti' ] + } + ] + ], + } + ], +} diff --git a/Examples/test-suite/javascript/node_template/index.js.in b/Examples/test-suite/javascript/node_template/index.js.in new file mode 100644 index 000000000..72330499d --- /dev/null +++ b/Examples/test-suite/javascript/node_template/index.js.in @@ -0,0 +1 @@ +module.exports = require('./build/Release/$testcase'); diff --git a/Examples/test-suite/javascript/nspace_extend_runme.js b/Examples/test-suite/javascript/nspace_extend_runme.js new file mode 100644 index 000000000..ab81c19d3 --- /dev/null +++ b/Examples/test-suite/javascript/nspace_extend_runme.js @@ -0,0 +1,27 @@ +var nspace_extend = require("./nspace_extend"); + +// constructors and destructors +var color1 = new nspace_extend.Outer.Inner1.Color(); +var color = new nspace_extend.Outer.Inner1.Color(color1); +delete color1; + +// class methods +color.colorInstanceMethod(20.0); +nspace_extend.Outer.Inner1.Color.colorStaticMethod(20.0); +var created = nspace_extend.Outer.Inner1.Color.create(); + + +// constructors and destructors +var color2 = new nspace_extend.Outer.Inner2.Color(); +color = new nspace_extend.Outer.Inner2.Color(color2); +delete color2; + +// class methods +color.colorInstanceMethod(20.0); +nspace_extend.Outer.Inner2.Color.colorStaticMethod(20.0); +created = nspace_extend.Outer.Inner2.Color.create(); + +// Same class different namespaces +var col1 = new nspace_extend.Outer.Inner1.Color(); +var col2 = nspace_extend.Outer.Inner2.Color.create(); +col2.colors(col1, col1, col2, col2, col2); diff --git a/Examples/test-suite/javascript/nspace_runme.js b/Examples/test-suite/javascript/nspace_runme.js new file mode 100644 index 000000000..929a6b21d --- /dev/null +++ b/Examples/test-suite/javascript/nspace_runme.js @@ -0,0 +1,77 @@ +var nspace = require("./nspace"); + +var color1 = new nspace.Outer.Inner1.Color(); +var color = new nspace.Outer.Inner1.Color(color1); +delete color1; + +// class methods +color.colorInstanceMethod(20.0); +nspace.Outer.Inner1.Color.colorStaticMethod(20.0); +var created = nspace.Outer.Inner1.Color.create(); + +// class enums +var someClass = new nspace.Outer.SomeClass(); +var channel = someClass.GetInner1ColorChannel(); +if (channel != nspace.Outer.Inner1.Color.Transmission) { + throw new Error("Failed."); +} + +// class anonymous enums +var val1 = nspace.Outer.Inner1.Color.ColorEnumVal1; +var val2 = nspace.Outer.Inner1.Color.ColorEnumVal2; +if (val1 !== 0 || val2 !== 0x22) { + throw new Error("Failed."); +} + +// instance member variables +color.instanceMemberVariable = 123; +if (color.instanceMemberVariable !== 123) { + throw new Error("Failed."); +} + +// static member variables +nspace.Outer.Inner1.Color.staticMemberVariable = 789; +if (nspace.Outer.Inner1.Color.staticMemberVariable !== 789) { + throw new Error("Failed."); +} + +if (nspace.Outer.Inner1.Color.staticConstMemberVariable !== 222) { + throw new Error("Failed."); +} + +if (nspace.Outer.Inner1.Color.staticConstEnumMemberVariable !== nspace.Outer.Inner1.Color.Transmission) { + throw new Error("Failed."); +} + +// Same class different namespaces +var col1 = new nspace.Outer.Inner1.Color(); +var col2 = nspace.Outer.Inner2.Color.create(); +col2.colors(col1, col1, col2, col2, col2); + +// TODO: why isn't it scoped in the namespace??? +nspace.namespaceFunction(color); +nspace.Outer.Inner1.namespaceVar = 111; +if (nspace.Outer.Inner1.namespaceVar !== 111) { + throw new Error("Failed."); +} + +// global enums +var outerChannel1 = someClass.GetInner1Channel(); +if (outerChannel1 != nspace.Outer.Inner1.Transmission1) { + throw new Error("Failed."); +} + +var outerChannel2 = someClass.GetInner2Channel(); +if (outerChannel2 !== nspace.Outer.Inner2.Transmission2) { + throw new Error("Failed."); +} + +// turn feature off / ignoring +var ns = new nspace.Outer.namespce(); +var nons = new nspace.NoNSpacePlease(); + +// Derived class +var blue3 = new nspace.Outer.Inner3.Blue(); +blue3.blueInstanceMethod(); +var blue4 = new nspace.Outer.Inner4.Blue(); +blue4.blueInstanceMethod(); diff --git a/Examples/test-suite/javascript/overload_copy_runme.js b/Examples/test-suite/javascript/overload_copy_runme.js new file mode 100644 index 000000000..1039ffda1 --- /dev/null +++ b/Examples/test-suite/javascript/overload_copy_runme.js @@ -0,0 +1,4 @@ +var overload_copy = require("./overload_copy"); + +f = new overload_copy.Foo(); +g = new overload_copy.Foo(f); diff --git a/Examples/test-suite/javascript/preproc_include_runme.js b/Examples/test-suite/javascript/preproc_include_runme.js new file mode 100644 index 000000000..4b827fbcc --- /dev/null +++ b/Examples/test-suite/javascript/preproc_include_runme.js @@ -0,0 +1,23 @@ +var preproc_include = require("./preproc_include"); + +if (preproc_include.multiply10(10) != 100) + throw "RuntimeError"; + +if (preproc_include.multiply20(10) != 200) + throw "RuntimeError"; + +if (preproc_include.multiply30(10) != 300) + throw "RuntimeError"; + +if (preproc_include.multiply40(10) != 400) + throw "RuntimeError"; + +if (preproc_include.multiply50(10) != 500) + throw "RuntimeError"; + +if (preproc_include.multiply60(10) != 600) + throw "RuntimeError"; + +if (preproc_include.multiply70(10) != 700) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/preproc_runme.js b/Examples/test-suite/javascript/preproc_runme.js new file mode 100644 index 000000000..669f9d1f0 --- /dev/null +++ b/Examples/test-suite/javascript/preproc_runme.js @@ -0,0 +1,14 @@ +var preproc = require("./preproc"); + +if (preproc.endif != 1) + throw "RuntimeError"; + +if (preproc.define != 1) + throw "RuntimeError"; + +if (preproc.defined != 1) + throw "RuntimeError"; + +if (2*preproc.one != preproc.two) + throw "RuntimeError"; + diff --git a/Examples/test-suite/javascript/rename1_runme.js b/Examples/test-suite/javascript/rename1_runme.js new file mode 100644 index 000000000..8374e6a89 --- /dev/null +++ b/Examples/test-suite/javascript/rename1_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename1"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename2_runme.js b/Examples/test-suite/javascript/rename2_runme.js new file mode 100644 index 000000000..bc6a95a59 --- /dev/null +++ b/Examples/test-suite/javascript/rename2_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename2"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename3_runme.js b/Examples/test-suite/javascript/rename3_runme.js new file mode 100644 index 000000000..9e57e80ea --- /dev/null +++ b/Examples/test-suite/javascript/rename3_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename3"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename4_runme.js b/Examples/test-suite/javascript/rename4_runme.js new file mode 100644 index 000000000..d651fc7a1 --- /dev/null +++ b/Examples/test-suite/javascript/rename4_runme.js @@ -0,0 +1,68 @@ +var rename = require("./rename4"); + +function part1() { + var xyz = new rename.XYZInt(); + notxyz = new rename.NotXYZInt(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother2(); + xyz.opT2(); + xyz.tMethod2(0); + xyz.tMethodNotXYZ2(notxyz); + xyz.opNotXYZ2(); + xyz.opXYZ2(); +} + +function part2() { + var xyz = new rename.XYZDouble(); + var notxyz = new rename.NotXYZDouble(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother1(); + xyz.opT1(); + xyz.tMethod1(0); + xyz.tMethodNotXYZ1(notxyz); + xyz.opNotXYZ1(); + xyz.opXYZ1(); +} + +function part3(){ + var xyz = new rename.XYZKlass(); + var notxyz = new rename.NotXYZKlass(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother3(); + xyz.opT3(); + xyz.tMethod3(new rename.Klass()); + xyz.tMethodNotXYZ3(notxyz); + xyz.opNotXYZ3(); + xyz.opXYZ3(); +} + +function part4() { + var xyz = new rename.XYZEnu(); + var notxyz = new rename.NotXYZEnu(); + xyz.opIntPtrA(); + xyz.opIntPtrB(); + xyz.opAnother4(); + xyz.opT4(); + xyz.tMethod4(rename.En1); + xyz.tMethodNotXYZ4(notxyz); + xyz.opNotXYZ4(); + xyz.opXYZ4(); +} + +function part5() { + var abc = new rename.ABC(); + abc.methodABC(abc); + var k = new rename.Klass(); + abc.methodKlass(k); + var a = abc.opABC(); + k = abc.opKlass(); +} + +part1(); +part2(); +part3(); +part4(); +part5(); diff --git a/Examples/test-suite/javascript/rename_scope_runme.js b/Examples/test-suite/javascript/rename_scope_runme.js new file mode 100644 index 000000000..c0226df69 --- /dev/null +++ b/Examples/test-suite/javascript/rename_scope_runme.js @@ -0,0 +1,17 @@ +var rename_scope = require("./rename_scope"); + +var a = new rename_scope.Natural_UP(); +var b = new rename_scope.Natural_BP(); + +if (a.rtest() !== 1) { + throw new Error("a.rtest(): Expected 1, was " + a.rtest()); +} + +if (b.rtest() !== 1) { + throw new Error("b.rtest(): Expected 1, was " + b.rtest()); +} + +var f = rename_scope.equals; +if (f === undefined) { + throw new Error("Equality operator has not been renamed."); +} diff --git a/Examples/test-suite/javascript/rename_simple_runme.js b/Examples/test-suite/javascript/rename_simple_runme.js new file mode 100644 index 000000000..918dd68a5 --- /dev/null +++ b/Examples/test-suite/javascript/rename_simple_runme.js @@ -0,0 +1,50 @@ +var rename_simple = require("./rename_simple"); +var NewStruct = rename_simple.NewStruct; + +var s = new NewStruct(); + +// renamed instance variable +if (s.NewInstanceVariable !== 111) { + throw new Error("NewInstanceVariable: Expected 111, was " + s.NewInstanceVariable); +} + +// renamed instance method +if (s.NewInstanceMethod() !== 222) { + throw new Error("NewInstanceMethod(): Expected 222, was " + s.NewInstanceMethod()); +} + +// renamed static method +if (NewStruct.NewStaticMethod() !== 333) { + throw new Error("NewInstanceMethod(): Expected 333, was " + NewStruct.NewStaticMethod()); +} + +// renamed static variable +if (NewStruct.NewStaticVariable !== 444) { + throw new Error("NewInstanceMethod(): Expected 444, was " + NewStruct.NewStaticVariable); +} + +// renamed global function +if (rename_simple.NewFunction() !== 555) { + throw new Error("rename_simple.NewFunction(): Expected 555, was " + rename_simple.NewFunction()); +} + +// renamed global variable +if (rename_simple.NewGlobalVariable !== 666) { + throw new Error("rename_simple.NewGlobalVariable: Expected 666, was " + rename_simple.NewGlobalVariable); +} + +// setting renamed variables +s.NewInstanceVariable = 1111; +if (s.NewInstanceVariable !== 1111) { + throw new Error("NewInstanceVariable: Expected 1111, was " + s.NewInstanceVariable); +} + +NewStruct.NewStaticVariable = 4444; +if (NewStruct.NewStaticVariable !== 4444) { + throw new Error("NewInstanceMethod(): Expected 4444, was " + NewStruct.NewStaticVariable); +} + +rename_simple.NewGlobalVariable = 6666; +if (rename_simple.NewGlobalVariable !== 6666) { + throw new Error("rename_simple.NewGlobalVariable: Expected 6666, was " + rename_simple.NewGlobalVariable); +} diff --git a/Examples/test-suite/javascript/ret_by_value_runme.js b/Examples/test-suite/javascript/ret_by_value_runme.js new file mode 100644 index 000000000..d9a77a20b --- /dev/null +++ b/Examples/test-suite/javascript/ret_by_value_runme.js @@ -0,0 +1,8 @@ +var ret_by_value = require("./ret_by_value"); + +a = ret_by_value.get_test(); +if (a.myInt != 100) + throw "RuntimeError"; + +if (a.myShort != 200) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/setup_test.sh b/Examples/test-suite/javascript/setup_test.sh new file mode 100644 index 000000000..913a74c4b --- /dev/null +++ b/Examples/test-suite/javascript/setup_test.sh @@ -0,0 +1,6 @@ +#!/bin/sh +if [ ! -d $1 ]; then + mkdir $1; +fi +sed -e "s/\$testcase/$1/" -e "s/\$cflags/$2/" < node_template/binding.gyp.in > $1/binding.gyp +sed s/\$testcase/$1/ node_template/index.js.in > $1/index.js diff --git a/Examples/test-suite/javascript/struct_value_runme.js b/Examples/test-suite/javascript/struct_value_runme.js new file mode 100644 index 000000000..d6b26f726 --- /dev/null +++ b/Examples/test-suite/javascript/struct_value_runme.js @@ -0,0 +1,11 @@ +var struct_value = require("./struct_value"); + +b = new struct_value.Bar(); + +b.a.x = 3; +if (b.a.x != 3) +throw "RuntimeError"; + +b.b.x = 3; +if (b.b.x != 3) +throw "RuntimeError" diff --git a/Examples/test-suite/javascript/template_static_runme.js b/Examples/test-suite/javascript/template_static_runme.js new file mode 100644 index 000000000..477d97249 --- /dev/null +++ b/Examples/test-suite/javascript/template_static_runme.js @@ -0,0 +1,3 @@ +var template_static = require("./template_static"); + +template_static.Foo.bar_double(1); diff --git a/Examples/test-suite/javascript/typedef_class_runme.js b/Examples/test-suite/javascript/typedef_class_runme.js new file mode 100644 index 000000000..3e4dc9093 --- /dev/null +++ b/Examples/test-suite/javascript/typedef_class_runme.js @@ -0,0 +1,7 @@ +var typedef_class = require("./typedef_class"); + +a = new typedef_class.RealA(); +a.a = 3; + +b = new typedef_class.B(); +b.testA(a); diff --git a/Examples/test-suite/javascript/typedef_inherit_runme.js b/Examples/test-suite/javascript/typedef_inherit_runme.js new file mode 100644 index 000000000..4abcc2536 --- /dev/null +++ b/Examples/test-suite/javascript/typedef_inherit_runme.js @@ -0,0 +1,23 @@ +var typedef_inherit = require("./typedef_inherit"); + +a = new typedef_inherit.Foo(); +b = new typedef_inherit.Bar(); + +x = typedef_inherit.do_blah(a); +if (x != "Foo::blah") + print("Whoa! Bad return" + x); + +x = typedef_inherit.do_blah(b); +if (x != "Bar::blah") + print("Whoa! Bad return" + x); + +c = new typedef_inherit.Spam(); +d = new typedef_inherit.Grok(); + +x = typedef_inherit.do_blah2(c); +if (x != "Spam::blah") + print("Whoa! Bad return" + x); + +x = typedef_inherit.do_blah2(d); +if (x != "Grok::blah") + print ("Whoa! Bad return" + x); diff --git a/Examples/test-suite/javascript/typedef_scope_runme.js b/Examples/test-suite/javascript/typedef_scope_runme.js new file mode 100644 index 000000000..0ac56884c --- /dev/null +++ b/Examples/test-suite/javascript/typedef_scope_runme.js @@ -0,0 +1,12 @@ +var typedef_scope = require("./typedef_scope"); + +b = new typedef_scope.Bar(); +x = b.test1(42,"hello"); +if (x != 42) + print("Failed!!"); + +x = b.test2(42,"hello"); +if (x != "hello") + print("Failed!!"); + + diff --git a/Examples/test-suite/javascript/typemap_arrays_runme.js b/Examples/test-suite/javascript/typemap_arrays_runme.js new file mode 100644 index 000000000..cd6827ac9 --- /dev/null +++ b/Examples/test-suite/javascript/typemap_arrays_runme.js @@ -0,0 +1,5 @@ +var typemap_arrays = require("./typemap_arrays"); + +if (typemap_arrays.sumA(null) != 60) + throw "RuntimeError, Sum is wrong"; + diff --git a/Examples/test-suite/javascript/typemap_delete_runme.js b/Examples/test-suite/javascript/typemap_delete_runme.js new file mode 100644 index 000000000..4b3174956 --- /dev/null +++ b/Examples/test-suite/javascript/typemap_delete_runme.js @@ -0,0 +1,5 @@ +var typemap_delete = require("./typemap_delete"); + +r = new typemap_delete.Rect(123); +if (r.val != 123) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/typemap_namespace_runme.js b/Examples/test-suite/javascript/typemap_namespace_runme.js new file mode 100644 index 000000000..614e0ffeb --- /dev/null +++ b/Examples/test-suite/javascript/typemap_namespace_runme.js @@ -0,0 +1,7 @@ +var typemap_namespace = require("./typemap_namespace"); + +if (typemap_namespace.test1("hello") != "hello") + throw "RuntimeError"; + +if (typemap_namespace.test2("hello") != "hello") + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/typemap_ns_using_runme.js b/Examples/test-suite/javascript/typemap_ns_using_runme.js new file mode 100644 index 000000000..9115c16ae --- /dev/null +++ b/Examples/test-suite/javascript/typemap_ns_using_runme.js @@ -0,0 +1,4 @@ +var typemap_ns_using = require("./typemap_ns_using"); + +if (typemap_ns_using.spam(37) != 37) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/using1_runme.js b/Examples/test-suite/javascript/using1_runme.js new file mode 100644 index 000000000..a2e37fcb6 --- /dev/null +++ b/Examples/test-suite/javascript/using1_runme.js @@ -0,0 +1,4 @@ +var using1 = require("./using1"); + +if (using1.spam(37) != 37) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/using2_runme.js b/Examples/test-suite/javascript/using2_runme.js new file mode 100644 index 000000000..aa5e9b15f --- /dev/null +++ b/Examples/test-suite/javascript/using2_runme.js @@ -0,0 +1,4 @@ +var using2 = require("./using2"); + +if (using2.spam(37) != 37) + throw "RuntimeError"; diff --git a/Examples/test-suite/javascript/varargs_runme.js b/Examples/test-suite/javascript/varargs_runme.js new file mode 100644 index 000000000..69d761e63 --- /dev/null +++ b/Examples/test-suite/javascript/varargs_runme.js @@ -0,0 +1,44 @@ +var varargs = require("./varargs"); + +if (varargs.test("Hello") != "Hello") { + throw new Error("Failed"); +} + +var f = new varargs.Foo("Greetings") +if (f.str != "Greetings") { + throw new Error("Failed"); +} + +if (f.test("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_def("Hello",1) != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_def("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello") != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello", 1) != "Hello") { + throw new Error("Failed"); +} + +if (varargs.test_plenty("Hello", 1, 2) != "Hello") { + throw new Error("Failed"); +} + +var thrown = false; +try { + varargs.test_plenty("Hello", 1, 2, 3); +} catch (err) { + thrown = true; +} +if (!thrown) { + throw new Error("Failed"); +} diff --git a/Examples/test-suite/javascript_unicode.i b/Examples/test-suite/javascript_unicode.i new file mode 100644 index 000000000..516eee5dd --- /dev/null +++ b/Examples/test-suite/javascript_unicode.i @@ -0,0 +1,10 @@ +%module javascript_unicode + +%newobject copy_string; + +%inline %{ +#include +const char* copy_string(const char* str) { + return strdup(str); +} +%} diff --git a/Examples/test-suite/nspace.i b/Examples/test-suite/nspace.i index 58c560412..3e4b3c214 100644 --- a/Examples/test-suite/nspace.i +++ b/Examples/test-suite/nspace.i @@ -2,7 +2,7 @@ %module nspace // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT) #if defined(SWIGJAVA) SWIG_JAVABODY_PROXY(public, public, SWIGTYPE) diff --git a/Examples/test-suite/nspace_extend.i b/Examples/test-suite/nspace_extend.i index e92ff8c1d..2f7c6fbe1 100644 --- a/Examples/test-suite/nspace_extend.i +++ b/Examples/test-suite/nspace_extend.i @@ -2,7 +2,7 @@ %module nspace_extend // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT) #if defined(SWIGJAVA) SWIG_JAVABODY_PROXY(public, public, SWIGTYPE) diff --git a/Lib/javascript/jsc/arrays_javascript.i b/Lib/javascript/jsc/arrays_javascript.i new file mode 100644 index 000000000..b9199d86b --- /dev/null +++ b/Lib/javascript/jsc/arrays_javascript.i @@ -0,0 +1,123 @@ +/* ----------------------------------------------------------------------------- + * arrays_javascript.i + * + * These typemaps give more natural support for arrays. The typemaps are not efficient + * as there is a lot of copying of the array values whenever the array is passed to C/C++ + * from JavaScript and vice versa. The JavaScript array is expected to be the same size as the C array. + * An exception is thrown if they are not. + * + * Example usage: + * Wrapping: + * + * %include + * %inline %{ + * extern int FiddleSticks[3]; + * %} + * + * Use from JavaScript like this: + * + * var fs = [10, 11, 12]; + * example.FiddleSticks = fs; + * fs = example.FiddleSticks; + * ----------------------------------------------------------------------------- */ + +%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} +%fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {} + +%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY] + (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if (JSValueIsObject(context, $input)) + { + // Convert into Array + array = JSValueToObject(context, $input, NULL); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); + + // Get primitive value from JSObject + res = SWIG_AsVal(int)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) int[], int[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + JSValueRef values[length]; + + for (i = 0; i < length; i++) + { + values[i] = SWIG_From(int)($1[i]); + } + + $result = JSObjectMakeArray(context, length, values, NULL); +} + +%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY] + (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if (JSValueIsObject(context, $input)) + { + // Convert into Array + array = JSValueToObject(context, $input, NULL); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL); + + // Get primitive value from JSObject + res = SWIG_AsVal(double)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) double[], double[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + JSValueRef values[length]; + + for (i = 0; i < length; i++) + { + values[i] = SWIG_From(double)($1[i]); + } + + $result = JSObjectMakeArray(context, length, values, NULL); +} diff --git a/Lib/javascript/jsc/ccomplex.i b/Lib/javascript/jsc/ccomplex.i new file mode 100644 index 000000000..50f0f95fe --- /dev/null +++ b/Lib/javascript/jsc/ccomplex.i @@ -0,0 +1,26 @@ +/* ----------------------------------------------------------------------------- + * ccomplex.i + * + * C complex typemaps + * ISO C99: 7.3 Complex arithmetic + * ----------------------------------------------------------------------------- */ + + +%include + +%{ +#include +%} + + +/* C complex constructor */ +#define CCplxConst(r, i) ((r) + I*(i)) + +%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag); + +/* declaring the typemaps */ +%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex); diff --git a/Lib/javascript/jsc/cdata.i b/Lib/javascript/jsc/cdata.i new file mode 100644 index 000000000..367965990 --- /dev/null +++ b/Lib/javascript/jsc/cdata.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/complex.i b/Lib/javascript/jsc/complex.i new file mode 100644 index 000000000..4c3b3c5e2 --- /dev/null +++ b/Lib/javascript/jsc/complex.i @@ -0,0 +1,6 @@ +#ifdef __cplusplus +%include +#else +%include +#endif + diff --git a/Lib/javascript/jsc/exception.i b/Lib/javascript/jsc/exception.i new file mode 100644 index 000000000..0246cfde8 --- /dev/null +++ b/Lib/javascript/jsc/exception.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/javascript.swg b/Lib/javascript/jsc/javascript.swg new file mode 100644 index 000000000..3a83b6495 --- /dev/null +++ b/Lib/javascript/jsc/javascript.swg @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------------- + * javascript.swg + * + * Javascript typemaps + * ----------------------------------------------------------------------------- */ + +%include + +%include + +%include + +%include + +%include + +%include + +%include diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg new file mode 100644 index 000000000..60c52b2b3 --- /dev/null +++ b/Lib/javascript/jsc/javascriptcode.swg @@ -0,0 +1,418 @@ +/* ----------------------------------------------------------------------------- + * js_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_veto_ctor: a vetoing ctor for abstract classes + * - $jswrapper: name of wrapper + * - $jsname: class name + * ----------------------------------------------------------------------------- */ +%fragment ("js_veto_ctor", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, + size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); + return 0; +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatcher: dispatcher for overloaded constructors + * - $jswrapper: name of wrapper + * - $jsname: class name + * - $jsdispatchcases: part containing code for dispatching + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatcher", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject, + size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSObjectRef thisObject = NULL; + + // switch all cases by means of series of if-returns. + $jsdispatchcases + + // default: + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsname"); + + fail: + return thisObject; +} +%} + +/* ----------------------------------------------------------------------------- + * js_overloaded_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ +%fragment ("js_overloaded_ctor", "templates") +%{ +JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + $jscode + return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatch_case: template for a dispatch case for calling an overloaded ctor. + * - $jsargcount: number of arguments of called ctor + * - $jswrapper: wrapper of called ctor + * + * Note: a try-catch-like mechanism is used to switch cases + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatch_case", "templates") +%{ + if(argc == $jsargcount) { + thisObject = $jswrapper(context, NULL, argc, argv, exception); + if(thisObject != NULL) { *exception=0; return thisObject; } /* reset exception and return */ + } +%} + + +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtor", "templates") +%{ +void $jswrapper(JSObjectRef thisObject) +{ + SwigPrivData* t = (SwigPrivData*) JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) free (($jstype)t->swigCObject); + if(t) free(t); +} +%} + +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * - ${destructor_action}: The custom destructor action to invoke. + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtoroverride", "templates") +%{ +void $jswrapper(JSObjectRef thisObject) +{ + SwigPrivData* t = (SwigPrivData*) JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) { + $jstype arg1 = ($jstype)t->swigCObject; + ${destructor_action} + } + if(t) free(t); +} +%} + +/* ----------------------------------------------------------------------------- + * js_getter: template for getter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_getter", "templates") +%{ +JSValueRef $jswrapper(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) +{ + $jslocals + JSValueRef jsresult; + + $jscode + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_setter: template for setter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_setter", "templates") +%{ +bool $jswrapper(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + $jslocals + $jscode + + return true; + + goto fail; + fail: + return false; +} +%} + +/* ----------------------------------------------------------------------------- + * js_function: template for function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function", "templates") +%{ +JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + JSValueRef jsresult; + + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_function_dispatcher: template for a function dispatcher for overloaded functions + * - $jswrapper: wrapper function name + * - $jsname: name of the wrapped function + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function_dispatcher", "templates") +%{ +JSValueRef $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + $jslocals + JSValueRef jsresult; + int res; + $jscode + + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); + return jsresult; + + goto fail; + fail: + return NULL; +} +%} + +/* ----------------------------------------------------------------------------- + * js_overloaded_function: template for a overloaded function + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_overloaded_function", "templates") +%{ +int $jswrapper(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception, JSValueRef* p_result) +{ + $jslocals + JSValueRef jsresult; + + if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + *p_result = jsresult; + return SWIG_OK; + + goto fail; + fail: + return SWIG_TypeError; +} +%} + +/* ----------------------------------------------------------------------------- + * js_function_dispatch_case: template for a case used in the function dispatcher + * - $jswrapper: wrapper function name + * - $jsargcount: number of arguments of overloaded function + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function_dispatch_case", "templates") +%{ + if(argc == $jsargcount) { + res = $jswrapper(context, function, thisObject, argc, argv, exception, &jsresult); + if(res == SWIG_OK) { *exception = 0; return jsresult; } + } +%} + +/* ----------------------------------------------------------------------------- + * jsc_variable_declaration: template for a variable table entry + * - $jsname: name of the variable + * - $jsgetter: wrapper of getter function + * - $jssetter: wrapper of setter function + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_variable_declaration", "templates") +%{ + {"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone}, +%} + + +/* ----------------------------------------------------------------------------- + * jsc_function_declaration: template for a function table entry + * - $jsname: name of the variable + * - $jswrapper: wrapper function + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_function_declaration", "templates") +%{ + {"$jsname", $jswrapper, kJSPropertyAttributeNone}, +%} + +/* ----------------------------------------------------------------------------- + * jsc_classtemplate_declaration: template for a namespace declaration + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_declaration", "templates") +%{ +JSClassDefinition $jsmangledname_classDefinition; + +JSClassDefinition $jsmangledname_objectDefinition; + +JSClassRef $jsmangledname_classRef; +%} + +/* ----------------------------------------------------------------------------- + * jsc_class_tables: template for a namespace declaration + * - $jsmangledname: mangled class name + * - $jsstaticclassvariables: list of static variable entries + * - $jsstaticclassfunctions: list of static function entries + * - $jsclassvariables: list of member variable entries + * - $jsclassfunctions: list of member function entries + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_tables", "templates") +%{ +JSStaticValue $jsmangledname_staticValues[] = { + $jsstaticclassvariables + { 0, 0, 0, 0 } +}; + +JSStaticFunction $jsmangledname_staticFunctions[] = { + $jsstaticclassfunctions + { 0, 0, 0 } +}; + +JSStaticValue $jsmangledname_values[] = { + $jsclassvariables + { 0, 0, 0, 0 } +}; + +JSStaticFunction $jsmangledname_functions[] = { + $jsclassfunctions + { 0, 0, 0 } +}; +%} + +/* ----------------------------------------------------------------------------- + * jsc_define_class_template: template for defining a class template + * - $jsmangledname: mangled class name + * - $jsmangledtype: mangled class type + * - $jsctor: wrapper of ctor + * - $jsbaseclass: mangled name of base class + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_definition", "templates") +%{ + $jsmangledname_classDefinition.staticFunctions = $jsmangledname_staticFunctions; + $jsmangledname_classDefinition.staticValues = $jsmangledname_staticValues; + $jsmangledname_classDefinition.callAsConstructor = $jsctor; + $jsmangledname_classDefinition.finalize = $jsdtor; + $jsmangledname_objectDefinition.staticValues = $jsmangledname_values; + $jsmangledname_objectDefinition.staticFunctions = $jsmangledname_functions; + $jsclass_inheritance + JSClassRef $jsmangledname_classRef = JSClassCreate(&$jsmangledname_objectDefinition); + SWIGTYPE_$jsmangledtype->clientdata = $jsmangledname_classRef; +%} + +%fragment ("jsc_class_inherit", templates) +%{ + if (SWIGTYPE_p$jsbaseclassmangled != NULL) { + $jsmangledname_objectDefinition.parentClass = (JSClassRef) SWIGTYPE_p$jsbaseclassmangled->clientdata; + } +%} + +%fragment ("jsc_class_noinherit", templates) +%{ + $jsmangledname_objectDefinition.parentClass = _SwigObject_classRef; +%} + + +/* ----------------------------------------------------------------------------- + * jsc_register_class: template for registration of a class + * - $jsname: class name + * - $jsmangledname: mangled class name + * - $jsnspace: mangled name of namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_class_registration", "templates") +%{ + JS_registerClass(context, $jsnspace_object, "$jsname", &$jsmangledname_classDefinition); +%} + + +/* ----------------------------------------------------------------------------- + * jsc_nspace_declaration: template for a namespace declaration + * - $jsnspace: mangled name of the namespace + * - $jsglobalvariables: list of variable entries + * - $jsglobalfunctions: list if fuction entries + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_declaration", "templates") +%{ +JSStaticValue $jsnspace_values[] = { + $jsglobalvariables + { 0, 0, 0, 0 } +}; + +JSStaticFunction $jsnspace_functions[] = { + $jsglobalfunctions + { 0, 0, 0 } +}; + +JSClassDefinition $jsnspace_classDefinition; +%} + +/* ----------------------------------------------------------------------------- + * jsc_nspace_definition: template for definition of a namespace object + * - $jsmangledname: mangled name of namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_definition", "templates") +%{ + $jsmangledname_classDefinition.staticFunctions = $jsmangledname_functions; + $jsmangledname_classDefinition.staticValues = $jsmangledname_values; + JSObjectRef $jsmangledname_object = JSObjectMake(context, JSClassCreate(&$jsmangledname_classDefinition), NULL); +%} + +/* ----------------------------------------------------------------------------- + * jsc_nspace_registration: template for registration of a namespace object + * - $jsname: name of namespace + * - $jsmangledname: mangled name of namespace + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ +%fragment ("jsc_nspace_registration", "templates") +%{ + JS_registerNamespace(context, $jsmangledname_object, $jsparent_object, "$jsname"); +%} diff --git a/Lib/javascript/jsc/javascriptcomplex.swg b/Lib/javascript/jsc/javascriptcomplex.swg new file mode 100644 index 000000000..7d165dce4 --- /dev/null +++ b/Lib/javascript/jsc/javascriptcomplex.swg @@ -0,0 +1,146 @@ +/* + Defines the As/From converters for double/float complex, you need to + provide complex Type, the Name you want to use in the converters, + the complex Constructor method, and the Real and Imag complex + accessor methods. + + See the std_complex.i and ccomplex.i for concret examples. +*/ + +/* the common from converter */ +%define %swig_fromcplx_conv(Type, Real, Imag) +%fragment(SWIG_From_frag(Type),"header", + fragment=SWIG_From_frag(double)) +{ +SWIGINTERNINLINE JSObjectRef +SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) +{ + JSValueRef vals[2]; + vals[0] = SWIG_From(double)(Real(c)); + vals[1] = SWIG_From(double)(Imag(c)); + return JSObjectMakeArray(context, 2, vals, NULL); +} +} +%enddef + +/* the double case */ +%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(double)) +{ +SWIGINTERN int +SWIG_AsVal_dec(Type) (JSValueRef o, Type* val) +{ + if (JSValueIsObject(context, o)) { + JSObjectRef array; + JSValueRef exception, js_re, js_im; + double re, im; + int res; + + exception = 0; + res = 0; + + array = JSValueToObject(context, o, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); + if(exception != 0) + return SWIG_TypeError; + + res = SWIG_AsVal(double)(js_re, &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(js_im, &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if (val) *val = Constructor(re, im); + return SWIG_OK; + } else { + double d; + int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(d, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +/* the float case */ +%define %swig_cplxflt_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(float)) { +SWIGINTERN int +SWIG_AsVal_dec(Type)(JSValueRef o, Type *val) +{ + if (JSValueIsObject(context, o)) { + JSObjectRef array; + JSValueRef exception, js_re, js_im; + double re, im; + int res; + + exception = 0; + res = 0; + + array = JSValueToObject(context, o, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_re = JSObjectGetPropertyAtIndex(context, array, 0, &exception); + if(exception != 0) + return SWIG_TypeError; + + js_im = JSObjectGetPropertyAtIndex(context, array, 1, &exception); + if(exception != 0) + return SWIG_TypeError; + + res = SWIG_AsVal(double)(js_re, &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(js_im, &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if ((-FLT_MAX <= re && re <= FLT_MAX) && (-FLT_MAX <= im && im <= FLT_MAX)) { + if (val) *val = Constructor(%numeric_cast(re, float), + %numeric_cast(im, float)); + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else { + float re; + int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(re, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} + +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ +%swig_cplxflt_conv(Type, Constructor, Real, Imag) + + +#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ +%swig_cplxdbl_conv(Type, Constructor, Real, Imag) diff --git a/Lib/javascript/jsc/javascriptfragments.swg b/Lib/javascript/jsc/javascriptfragments.swg new file mode 100644 index 000000000..4778bf033 --- /dev/null +++ b/Lib/javascript/jsc/javascriptfragments.swg @@ -0,0 +1,23 @@ +/* + + Create a file with this name, 'javascriptfragments.swg', in your working + directory and add all the %fragments you want to take precedence + over the default ones defined by swig. + + For example, if you add: + + %fragment(SWIG_AsVal_frag(int),"header") { + SWIGINTERNINLINE int + SWIG_AsVal(int)(PyObject *obj, int *val) + { + ; + } + } + + this will replace the code used to retrieve an integer value for all + the typemaps that need it, including: + + int, std::vector, std::list >, etc. + + +*/ diff --git a/Lib/javascript/jsc/javascripthelpers.swg b/Lib/javascript/jsc/javascripthelpers.swg new file mode 100644 index 000000000..820075ca6 --- /dev/null +++ b/Lib/javascript/jsc/javascripthelpers.swg @@ -0,0 +1,69 @@ +%insert(wrapper) %{ + +bool JS_registerClass(JSGlobalContextRef context, JSObjectRef parentObject, + const char* className, + JSClassDefinition* definition) { + + JSStringRef js_className = JSStringCreateWithUTF8CString(className); + JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); + JSObjectSetProperty(context, parentObject, + js_className, classObject, + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_className); + + return true; +} + +bool JS_registerNamespace(JSGlobalContextRef context, + JSObjectRef namespaceObj, JSObjectRef parentNamespace, + const char* name) +{ + JSStringRef js_name = JSStringCreateWithUTF8CString(name); + JSObjectSetProperty(context, parentNamespace, + js_name, namespaceObj, + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_name); + + return true; +} + + +bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) +{ + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context, object, js_functionName, + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} + +bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) +{ + char buffer[256]; + char msg[512]; + int res; + + JSStringGetUTF8CString(propertyName, buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } + + return false; +} + +JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { + JSValueRef val; + + JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); + val = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + + return val; +} +%} diff --git a/Lib/javascript/jsc/javascriptinit.swg b/Lib/javascript/jsc/javascriptinit.swg new file mode 100644 index 000000000..a32ba336c --- /dev/null +++ b/Lib/javascript/jsc/javascriptinit.swg @@ -0,0 +1,67 @@ +%insert(init) %{ +SWIGRUNTIME void +SWIG_JSC_SetModule(swig_module_info *swig_module) {} + +SWIGRUNTIME swig_module_info * +SWIG_JSC_GetModule(void) { + return 0; +} + +#define SWIG_GetModule(clientdata) SWIG_JSC_GetModule() +#define SWIG_SetModule(clientdata, pointer) SWIG_JSC_SetModule(pointer) +%} + +%insert(init) "swiginit.swg" + +%fragment ("js_initializer_define", "templates") %{ +#define SWIGJSC_INIT $jsname_initialize +%} + +// Open the initializer function +%insert(init) +%{ + +#ifdef __cplusplus +extern "C" { +#endif + +bool SWIGJSC_INIT (JSGlobalContextRef context, JSObjectRef *exports) { + SWIG_InitializeModule(0); +%} + +/* ----------------------------------------------------------------------------- + * js_initializer: template for the module initializer function + * - $jsname: module name + * - $jscreatenamespaces: part with code for creating namespace objects + * - $jscreateclasses: part with code for creating classes + * - $jsregisternamespaces: part with code for registration of namespaces + * ----------------------------------------------------------------------------- */ +%fragment ("js_initializer", "templates") %{ + /* Initialize the base swig type object */ + _SwigObject_objectDefinition.staticFunctions = _SwigObject_functions; + _SwigObject_objectDefinition.staticValues = _SwigObject_values; + _SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition); + + /* Initialize the PackedData class */ + _SwigPackedData_objectDefinition.staticFunctions = _SwigPackedData_functions; + _SwigPackedData_objectDefinition.staticValues = _SwigPackedData_values; + _SwigPackedData_objectDefinition.finalize = _wrap_SwigPackedData_delete; + _SwigPackedData_classRef = JSClassCreate(&_SwigPackedData_objectDefinition); + + /* Create objects for namespaces */ + $jscreatenamespaces + + /* Register classes */ + $jsregisterclasses + + /* Register namespaces */ + $jsregisternamespaces + + *exports = exports_object; + + return true; +} +#ifdef __cplusplus +} +#endif +%} diff --git a/Lib/javascript/jsc/javascriptkw.swg b/Lib/javascript/jsc/javascriptkw.swg new file mode 100644 index 000000000..c3c118391 --- /dev/null +++ b/Lib/javascript/jsc/javascriptkw.swg @@ -0,0 +1,40 @@ +#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_ +#define JAVASCRIPT_JAVASCRIPTKW_SWG_ + +/* Warnings for Java keywords */ +#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s") `x` + +/* Taken from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Reserved_Words */ + +JAVASCRIPTKW(break); +JAVASCRIPTKW(case); +JAVASCRIPTKW(catch); +JAVASCRIPTKW(continue); +JAVASCRIPTKW(default); +JAVASCRIPTKW(delete); +JAVASCRIPTKW(do); +JAVASCRIPTKW(else); +JAVASCRIPTKW(finally); +JAVASCRIPTKW(for); +JAVASCRIPTKW(function); +JAVASCRIPTKW(if); +JAVASCRIPTKW(in); +JAVASCRIPTKW(instanceof); +JAVASCRIPTKW(new); +JAVASCRIPTKW(return); +JAVASCRIPTKW(switch); +JAVASCRIPTKW(this); +JAVASCRIPTKW(throw); +JAVASCRIPTKW(try); +JAVASCRIPTKW(typeof); +JAVASCRIPTKW(var); +JAVASCRIPTKW(void); +JAVASCRIPTKW(while); +JAVASCRIPTKW(with); + +/* others bad names if any*/ +// for example %namewarn("321:clone() is a javascript bad method name") *::clone(); + +#undef JAVASCRIPTKW + +#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_ diff --git a/Lib/javascript/jsc/javascriptprimtypes.swg b/Lib/javascript/jsc/javascriptprimtypes.swg new file mode 100644 index 000000000..7e9898a24 --- /dev/null +++ b/Lib/javascript/jsc/javascriptprimtypes.swg @@ -0,0 +1,182 @@ +/* ------------------------------------------------------------ + * Primitive Types + * ------------------------------------------------------------ */ + +/* boolean */ + +%fragment(SWIG_From_frag(bool),"header") { +SWIGINTERNINLINE +JSValueRef SWIG_From_dec(bool)(bool value) +{ + return JSValueMakeBoolean(context, value); +} +} + +%fragment(SWIG_AsVal_frag(bool),"header", + fragment=SWIG_AsVal_frag(long)) { +SWIGINTERN +int SWIG_AsVal_dec(bool)(JSValueRef obj, bool *val) +{ + if(!JSValueIsBoolean(context, obj)) { + return SWIG_ERROR; + } + if (val) *val = JSValueToBoolean(context, obj); + return SWIG_OK; +} +} + +/* int */ + +%fragment(SWIG_From_frag(int),"header") { +SWIGINTERNINLINE JSValueRef + SWIG_From_dec(int)(int value) +{ + return JSValueMakeNumber(context, value); +} +} + +/* long */ + +%fragment(SWIG_From_frag(long),"header") { +SWIGINTERNINLINE JSValueRef +SWIG_From_dec(long)(long value) +{ + return JSValueMakeNumber(context, value); +} +} + +%fragment(SWIG_AsVal_frag(long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN int +SWIG_AsVal_dec(long)(JSValueRef obj, long* val) +{ + if (!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = (long) JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} + +/* unsigned long */ + +%fragment(SWIG_From_frag(unsigned long),"header", + fragment=SWIG_From_frag(long)) { +SWIGINTERNINLINE JSValueRef +SWIG_From_dec(unsigned long)(unsigned long value) +{ + return (value > LONG_MAX) ? + JSValueMakeNumber(context, value) : JSValueMakeNumber(context, %numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN int +SWIG_AsVal_dec(unsigned long)(JSValueRef obj, unsigned long *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + + long longVal = (long) JSValueToNumber(context, obj, NULL); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* long long */ +// Note: these are copied from 'long' and probably need fixing + +%fragment(SWIG_From_frag(long long),"header", + fragment=SWIG_From_frag(long), + fragment="") { +SWIGINTERNINLINE JSValueRef +SWIG_From_dec(long long)(long long value) +{ + return JSValueMakeNumber(context, value); +} +} + +%fragment(SWIG_AsVal_frag(long long),"header", + fragment=SWIG_AsVal_frag(long), + fragment="SWIG_CanCastAsInteger", + fragment="") { +SWIGINTERN int +SWIG_AsVal_dec(long long)(JSValueRef obj, long long* val) +{ + if (!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = (long long) JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} + +/* unsigned long long */ +// Note: these are copied from 'unsigned long' and probably need fixing + +%fragment(SWIG_From_frag(unsigned long long),"header", + fragment=SWIG_From_frag(long long), + fragment="") { +SWIGINTERN JSValueRef +SWIG_From_dec(unsigned long long)(unsigned long long value) +{ + return (value > LONG_MAX) ? + JSValueMakeNumber(context, value) : JSValueMakeNumber(context, %numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long long),"header", + fragment=SWIG_AsVal_frag(unsigned long), + fragment="SWIG_CanCastAsInteger", + fragment="") { +SWIGINTERN int +SWIG_AsVal_dec(unsigned long long)(JSValueRef obj, unsigned long long *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + + long long longVal = (unsigned long long) JSValueToNumber(context, obj, NULL); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* double */ + +%fragment(SWIG_From_frag(double),"header") { +SWIGINTERN JSValueRef +SWIG_From_dec(double) (double val) +{ + return JSValueMakeNumber(context, val); +} +} + +%fragment(SWIG_AsVal_frag(double),"header") { +SWIGINTERN int +SWIG_AsVal_dec(double)(JSValueRef obj, double *val) +{ + if(!JSValueIsNumber(context, obj)) { + return SWIG_TypeError; + } + if(val) *val = JSValueToNumber(context, obj, NULL); + + return SWIG_OK; +} +} diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg new file mode 100644 index 000000000..3463d2351 --- /dev/null +++ b/Lib/javascript/jsc/javascriptrun.swg @@ -0,0 +1,298 @@ +/* ---------------------------------------------------------------------------- + * Errors and exceptions + * + * ---------------------------------------------------------------------------*/ + +#define SWIG_Error(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_exception(code, msg) SWIG_JSC_exception(context, exception, code, msg) +#define SWIG_fail goto fail + +void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) { + JSStringRef message = JSStringCreateWithUTF8CString(type); + *exception = JSValueMakeString(context, message); + JSStringRelease(message); +} + +void SWIG_JSC_exception(JSContextRef context, JSValueRef *exception, int code, const char* msg) { + SWIG_Javascript_Raise(context, exception, msg); +} + +/* ---------------------------------------------------------------------------- + * The parent class of all Proxies + * + * ---------------------------------------------------------------------------*/ + +typedef struct { + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; +} SwigPrivData; + +JSValueRef _wrap_SwigObject_disown(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData *) JSObjectGetPrivate(obj); + + cdata->swigCMemOwn = false; + + jsresult = JSValueMakeUndefined(context); + return jsresult; +} + +JSValueRef _wrap_SwigObject_getCPtr(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + long result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData*) JSObjectGetPrivate(obj); + + result = (long) cdata->swigCObject; + jsresult = JSValueMakeNumber(context, result); + + return jsresult; +} + +JSValueRef _wrap_SwigObject_equals(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) +{ + JSValueRef jsresult; + bool result; + + JSObjectRef obj = JSValueToObject(context, thisObject, NULL); + SwigPrivData *cdata = (SwigPrivData*) JSObjectGetPrivate(obj); + + JSObjectRef obj2 = JSValueToObject(context, argv[0], NULL); + SwigPrivData *cdata2 = (SwigPrivData*) JSObjectGetPrivate(obj2); + + result = (cdata->swigCObject == cdata2->swigCObject); + jsresult = JSValueMakeBoolean(context, result); + + return jsresult; +} + +JSStaticValue _SwigObject_values[] = { + { + 0, 0, 0, 0 + } +}; + +JSStaticFunction _SwigObject_functions[] = { + { + "disown",_wrap_SwigObject_disown, kJSPropertyAttributeNone + }, + { + "equals",_wrap_SwigObject_equals, kJSPropertyAttributeNone + }, + { + "getCPtr",_wrap_SwigObject_getCPtr, kJSPropertyAttributeNone + }, + { + 0, 0, 0 + } +}; + +JSClassDefinition _SwigObject_objectDefinition; + +JSClassRef _SwigObject_classRef; + + +int SWIG_JSC_ConvertInstancePtr(JSContextRef context, JSObjectRef objRef, void** ptr, swig_type_info *info, int flags) { + SwigPrivData *cdata = (SwigPrivData *) JSObjectGetPrivate(objRef); + if(cdata == NULL) { + return SWIG_ERROR; + } + if(cdata->info != info) { + bool type_valid = false; + swig_cast_info *t = info->cast; + while(t != NULL) { + if(t->type == cdata->info) { + type_valid = true; + break; + } + t = t->next; + } + if(!type_valid) { + return SWIG_TypeError; + } + } + + *ptr = cdata->swigCObject; + + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + + return SWIG_OK; +} + +int SWIG_JSC_ConvertPtr(JSContextRef context, JSValueRef valRef, void** ptr, swig_type_info *info, int flags) { + if(!JSValueIsObject(context, valRef)) { + return SWIG_TypeError; + } + + JSObjectRef objRef = JSValueToObject(context, valRef, NULL); + if(objRef == NULL) { + return SWIG_ERROR; + } + + return SWIG_JSC_ConvertInstancePtr(context, objRef, ptr, info, flags); +} + +JSObjectRef SWIG_JSC_NewPointerObj(JSContextRef context, void *ptr, swig_type_info *info, int flags) { + + JSClassRef classRef; + if(info->clientdata == NULL) { + classRef = _SwigObject_classRef; + } else { + classRef = (JSClassRef) info->clientdata; + } + + JSObjectRef result = JSObjectMake(context, classRef, NULL); + + SwigPrivData* cdata = (SwigPrivData*) malloc(sizeof(SwigPrivData)); + cdata->swigCObject = ptr; + cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0; + cdata->info = info; + + JSObjectSetPrivate(result, cdata); + + return result; +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_JSC_ConvertPtr(context, obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_JSC_NewPointerObj(context, ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_JSC_ConvertInstancePtr(context, obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_JSC_NewPointerObj(context, thisvalue, type, flags) + +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_JSC_ConvertPtr(context, obj, pptr, type, 0) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_JSC_NewPointerObj(context, ptr, type, 0) + +/* ---------------------------------------------------------------------------- + * A class for packed data + * + * ---------------------------------------------------------------------------*/ + +typedef struct { + void *data; + size_t size; + swig_type_info *type; +} SwigPackedData; + +JSStaticValue _SwigPackedData_values[] = { + { + 0, 0, 0, 0 + } +}; +JSStaticFunction _SwigPackedData_functions[] = { + { + 0, 0, 0 + } +}; +JSClassDefinition _SwigPackedData_objectDefinition; +JSClassRef _SwigPackedData_classRef; + +SWIGRUNTIMEINLINE +int SwigJSCPacked_Check(JSContextRef context, JSValueRef valRef) { + return JSValueIsObjectOfClass(context, valRef, _SwigPackedData_classRef); +} + +SWIGRUNTIME +swig_type_info* SwigJSCPacked_UnpackData(JSContextRef context, JSValueRef valRef, void *ptr, size_t size) { + if (SwigJSCPacked_Check(context, valRef)) { + JSObjectRef objRef = JSValueToObject(context, valRef, NULL); + SwigPackedData *sobj = (SwigPackedData *) JSObjectGetPrivate(objRef); + if (sobj->size != size) return 0; + memcpy(ptr, sobj->data, size); + return sobj->type; + } else { + return 0; + } +} + +SWIGRUNTIME +int SWIG_JSC_ConvertPacked(JSContextRef context, JSValueRef valRef, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigJSCPacked_UnpackData(context, valRef, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +SWIGRUNTIME +JSValueRef SWIG_JSC_NewPackedObj(JSContextRef context, void *data, size_t size, swig_type_info *type) { + + JSClassRef classRef = _SwigObject_classRef; + JSObjectRef result = JSObjectMake(context, classRef, NULL); + + SwigPackedData* cdata = (SwigPackedData*) malloc(sizeof(SwigPackedData)); + cdata->data = data; + cdata->size = size; + cdata->type = type; + + JSObjectSetPrivate(result, cdata); + + return result; +} + +/* SwigPackedData wrappers */ + +void _wrap_SwigPackedData_delete(JSObjectRef obj) +{ + SwigPackedData* cdata = (SwigPackedData*) JSObjectGetPrivate(obj); + if (cdata) { + free(cdata->data); + } +} + +/* for C++ member pointers, ie, member methods */ + +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_JSC_ConvertPacked(context, obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIG_JSC_NewPackedObj(context, ptr, sz, type) + + +/* --------------------------------------------------------------------------- + * Support for IN/OUTPUT typemaps (see Lib/typemaps/inoutlist.swg) + * + * ---------------------------------------------------------------------------*/ + +unsigned int SWIGJSC_ArrayLength(JSContextRef context, JSObjectRef arr) { + static JSStringRef LENGTH = 0; + JSValueRef exception = NULL; + JSValueRef js_length; + double length; + + if (LENGTH == 0) { + LENGTH = JSStringCreateWithUTF8CString("length"); + } + + js_length = JSObjectGetProperty(context, arr, LENGTH, &exception); + if (exception == 0 && JSValueIsNumber(context, js_length)) { + length = JSValueToNumber(context, js_length, 0); + return (unsigned int) length; + } else { + return 0; + } +} + +SWIGRUNTIME +JSValueRef SWIGJSC_AppendOutput(JSContextRef context, JSValueRef value, JSValueRef obj) { + JSObjectRef arr; + unsigned int length; + + if (JSValueIsUndefined(context, value)) { + arr = JSObjectMakeArray(context, 0, 0, 0); + } else { + arr = JSValueToObject(context, value, 0); + } + + length = SWIGJSC_ArrayLength(context, arr); + JSObjectSetPropertyAtIndex(context, arr, length, obj, 0); +} diff --git a/Lib/javascript/jsc/javascriptruntime.swg b/Lib/javascript/jsc/javascriptruntime.swg new file mode 100644 index 000000000..8f8390890 --- /dev/null +++ b/Lib/javascript/jsc/javascriptruntime.swg @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------------- + * javascriptruntime.swg + * + * Javascript support code + * ----------------------------------------------------------------------------- */ + +%insert(runtime) %{ +#include +#include +#include +#include +#include +#include +%} + +%insert(runtime) "swigrun.swg"; /* SWIG API */ +%insert(runtime) "swigerrors.swg"; /* SWIG errors */ + +%insert(runtime) "javascriptrun.swg"; /* SWIG errors */ diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg new file mode 100644 index 000000000..0581c1920 --- /dev/null +++ b/Lib/javascript/jsc/javascriptstrings.swg @@ -0,0 +1,184 @@ +/* ------------------------------------------------------------ + * utility methods for char strings + * ------------------------------------------------------------ */ +%fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERN int +SWIG_JSC_AsCharPtrAndSize(JSContextRef context, JSValueRef valRef, char** cptr, size_t* psize, int *alloc) +{ + if(JSValueIsString(context, valRef)) { + JSStringRef js_str = JSValueToStringCopy(context, valRef, NULL); + size_t len = JSStringGetMaximumUTF8CStringSize(js_str); + char* cstr = (char*) malloc(len * sizeof(char)); + /* JSStringGetUTF8CString returns the length including 0-terminator */ + len = JSStringGetUTF8CString(js_str, cstr, len); + + if(alloc) *alloc = SWIG_NEWOBJ; + if(psize) *psize = len; + if(cptr) *cptr = cstr; + + return SWIG_OK; + } else { + if(JSValueIsObject(context, valRef)) { + JSObjectRef obj = JSValueToObject(context, valRef, NULL); + // try if the object is a wrapped char[] + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + return SWIG_TypeError; + } else { + return SWIG_TypeError; + } + } +} +} + +%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERNINLINE JSValueRef +SWIG_JSC_FromCharPtrAndSize(JSContextRef context, const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + // TODO: handle extra long strings + //swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + //return pchar_descriptor ? + // SWIG_InternalNewPointerObj(%const_cast(carray,char *), pchar_descriptor, 0) : SWIG_Py_Void(); + return JSValueMakeUndefined(context); + } else { + JSStringRef jsstring; + if(size < 2) { + char c[size+1]; + int i; + for(i=0;i + +/* Look for user fragments file. */ +%include + +/* Javascript fragments for fundamental types */ +%include + +/* Javascript fragments for char* strings */ +%include + +/* ------------------------------------------------------------ + * Unified typemap section + * ------------------------------------------------------------ */ + +#define SWIG_Object JSValueRef +#define VOID_Object JSValueMakeUndefined(context) + +/* append output */ +#define SWIG_AppendOutput(result, obj) SWIGJSC_AppendOutput(context, result, obj) + +/* set constant */ +#define SWIG_SetConstant(name, obj) + +/* raise */ +#define SWIG_Raise(obj, type, desc) SWIG_Javascript_Raise(context, exception, type) + +%insert("runtime") %{ +#define SWIG_JSC_FROM_DECL_ARGS(arg1) (JSContextRef context, arg1) +#define SWIG_JSC_FROM_CALL_ARGS(arg1) (context, arg1) +#define SWIG_JSC_AS_DECL_ARGS(arg1, arg2) (JSContextRef context, arg1, arg2) +#define SWIG_JSC_AS_CALL_ARGS(arg1, arg2) (context, arg1, arg2) +%} + +/* Include the unified typemap library */ +%include diff --git a/Lib/javascript/jsc/std_common.i b/Lib/javascript/jsc/std_common.i new file mode 100755 index 000000000..cee11e8ca --- /dev/null +++ b/Lib/javascript/jsc/std_common.i @@ -0,0 +1,5 @@ +%include + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; + diff --git a/Lib/javascript/jsc/std_complex.i b/Lib/javascript/jsc/std_complex.i new file mode 100644 index 000000000..088a4fe7b --- /dev/null +++ b/Lib/javascript/jsc/std_complex.i @@ -0,0 +1,19 @@ +/* + * STD C++ complex typemaps + */ + +%include + +%{ +#include +%} + +/* defining the complex as/from converters */ + +%swig_cplxdbl_convn(std::complex, std::complex, std::real, std::imag) +%swig_cplxflt_convn(std::complex, std::complex, std::real, std::imag) + +/* defining the typemaps */ + +%typemaps_primitive(%checkcode(CPLXDBL), std::complex); +%typemaps_primitive(%checkcode(CPLXFLT), std::complex); diff --git a/Lib/javascript/jsc/std_deque.i b/Lib/javascript/jsc/std_deque.i new file mode 100644 index 000000000..cb98f6c2f --- /dev/null +++ b/Lib/javascript/jsc/std_deque.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/std_except.i b/Lib/javascript/jsc/std_except.i new file mode 100644 index 000000000..af98428f6 --- /dev/null +++ b/Lib/javascript/jsc/std_except.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/jsc/std_map.i b/Lib/javascript/jsc/std_map.i new file mode 100755 index 000000000..e7812f38a --- /dev/null +++ b/Lib/javascript/jsc/std_map.i @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------------- + * std_map.i + * + * SWIG typemaps for std::map + * ----------------------------------------------------------------------------- */ + +%include + +// ------------------------------------------------------------------------ +// std::map +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class map { + // add typemaps here + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + map(); + map(const map &); + + unsigned int size() const; + bool empty() const; + void clear(); + %extend { + const T& get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + void set(const K& key, const T& x) { + (*self)[key] = x; + } + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + }; + +// Legacy macros (deprecated) +%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) +#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary" +%enddef + +} diff --git a/Lib/javascript/jsc/std_pair.i b/Lib/javascript/jsc/std_pair.i new file mode 100755 index 000000000..fe45ee676 --- /dev/null +++ b/Lib/javascript/jsc/std_pair.i @@ -0,0 +1,34 @@ +/* ----------------------------------------------------------------------------- + * std_pair.i + * + * SWIG typemaps for std::pair + * ----------------------------------------------------------------------------- */ + +%include +%include + +// ------------------------------------------------------------------------ +// std::pair +// ------------------------------------------------------------------------ + +%{ +#include +%} + +namespace std { + + template struct pair { + + pair(); + pair(T first, U second); + pair(const pair& p); + + template pair(const pair &p); + + T first; + U second; + }; + + // add specializations here + +} diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i new file mode 100755 index 000000000..fb1bd62b5 --- /dev/null +++ b/Lib/javascript/jsc/std_string.i @@ -0,0 +1,69 @@ +/* ----------------------------------------------------------------------------- + * std_string.i + * + * Typemaps for const std::string&. + * To use non-const std::string references use the following %apply: + * %apply const std::string & {std::string &}; + * + * ----------------------------------------------------------------------------- */ + +%{ +#include + +std::string SWIGJSC_valueToString(JSContextRef context, JSValueRef value) { + JSStringRef jsstring = JSValueToStringCopy(context, value, /* JSValueRef *exception */ 0); + unsigned int length = JSStringGetLength(jsstring); + char *cstr = new char[length + 1]; + JSStringGetUTF8CString(jsstring, cstr, length + 1); + + // create a copy + std::string result(cstr); + + JSStringRelease(jsstring); + delete[] cstr; + + return result; +} + +JSValueRef SWIGJSC_stringToValue(JSContextRef context, const std::string& s) +{ + JSValueRef result; + JSStringRef jsstring = JSStringCreateWithUTF8CString(s.c_str()); + result = JSValueMakeString(context, jsstring); + JSStringRelease(jsstring); + return result; +} +%} + +namespace std { + %naturalvar string; + + class string; + + + %typemap(in) string + %{ + $1 = SWIGJSC_valueToString(context, $input); + %} + + %typemap(in) const string & + %{ + $1 = new std::string(SWIGJSC_valueToString(context, $input)); + %} + + %typemap(freearg) const string & + %{ + delete $1; + %} + + %typemap(out) string + %{ + $result = SWIGJSC_stringToValue(context, $1); + %} + + %typemap(out) const string & + %{ + $result = SWIGJSC_stringToValue(context, *$1); + %} + +} diff --git a/Lib/javascript/jsc/std_vector.i b/Lib/javascript/jsc/std_vector.i new file mode 100755 index 000000000..3f29b19c7 --- /dev/null +++ b/Lib/javascript/jsc/std_vector.i @@ -0,0 +1,85 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * ----------------------------------------------------------------------------- */ + +%include + +%{ +#include +#include +%} + +namespace std { + + template class vector { + public: + typedef size_t size_type; + typedef T value_type; + typedef const value_type& const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + public: + typedef size_t size_type; + typedef bool value_type; + typedef bool const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i +%include +%include +%include +%include + diff --git a/Lib/javascript/jsc/typemaps.i b/Lib/javascript/jsc/typemaps.i new file mode 100644 index 000000000..d3d8afb19 --- /dev/null +++ b/Lib/javascript/jsc/typemaps.i @@ -0,0 +1,148 @@ +/* ----------------------------------------------------------------------------- + * typemaps.i + * + * Pointer handling + * These mappings provide support for input/output arguments and common + * uses for C/C++ pointers. + * ----------------------------------------------------------------------------- */ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +/* +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + long long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned long long *INPUT + unsigned char *INPUT + bool *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +*/ + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +/* +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Python tuple. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + long long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned long long *OUTPUT + unsigned char *OUTPUT + bool *OUTPUT + float *OUTPUT + double *OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Python output of the function would be a tuple containing both +output values. + +*/ + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + +/* +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Python tuple. + + int *INOUT + short *INOUT + long *INOUT + long long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned long long *INOUT + unsigned char *INOUT + bool *INOUT + float *INOUT + double *INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include + void neg(double *INOUT); + +or you can use the %apply directive : + + %include + %apply double *INOUT { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Python). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Python variable you might do this : + + x = neg(x) + +Note : previous versions of SWIG used the symbol 'BOTH' to mark +input/output arguments. This is still supported, but will be slowly +phased out in future releases. + +*/ + +%include diff --git a/Lib/javascript/v8/arrays_javascript.i b/Lib/javascript/v8/arrays_javascript.i new file mode 100644 index 000000000..22b50be8f --- /dev/null +++ b/Lib/javascript/v8/arrays_javascript.i @@ -0,0 +1,125 @@ +/* ----------------------------------------------------------------------------- + * arrays_javascript.i + * + * These typemaps give more natural support for arrays. The typemaps are not efficient + * as there is a lot of copying of the array values whenever the array is passed to C/C++ + * from JavaScript and vice versa. The JavaScript array is expected to be the same size as the C array. + * An exception is thrown if they are not. + * + * Example usage: + * Wrapping: + * + * %include + * %inline %{ + * extern int FiddleSticks[3]; + * %} + * + * Use from JavaScript like this: + * + * var fs = [10, 11, 12]; + * example.FiddleSticks = fs; + * fs = example.FiddleSticks; + * ----------------------------------------------------------------------------- */ + +%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {} +%fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {} + +%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY] + (int length = 0, v8::Local array, v8::Local jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if ($input->IsArray()) + { + // Convert into Array + array = v8::Local::Cast($input); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = array->Get(i); + + // Get primitive value from JSObject + res = SWIG_AsVal(int)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) int[], int[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + v8::Local array = v8::Array::New(length); + + for (i = 0; i < length; i++) + { + array->Set(i, SWIG_From(int)($1[i])); + } + + + $result = array; +} + +%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY] + (int length = 0, v8::Local array, v8::Local jsvalue, int i = 0, int res = 0, $*1_ltype temp) { + if ($input->IsArray()) + { + // Convert into Array + array = v8::Local::Cast($input); + + length = $1_dim0; + + $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length); + + // Get each element from array + for (i = 0; i < length; i++) + { + jsvalue = array->Get(i); + + // Get primitive value from JSObject + res = SWIG_AsVal(double)(jsvalue, &temp); + if (!SWIG_IsOK(res)) + { + SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double"); + } + arg$argnum[i] = temp; + } + + } + else + { + SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef"); + } +} + +%typemap(freearg) double[], double[ANY] { + free($1); +} + +%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0) +{ + length = $1_dim0; + v8::Local array = v8::Array::New(length); + + for (i = 0; i < length; i++) + { + array->Set(i, SWIG_From(double)($1[i])); + } + + + $result = array; +} diff --git a/Lib/javascript/v8/ccomplex.i b/Lib/javascript/v8/ccomplex.i new file mode 100644 index 000000000..8eda920bb --- /dev/null +++ b/Lib/javascript/v8/ccomplex.i @@ -0,0 +1,26 @@ +/* ----------------------------------------------------------------------------- + * ccomplex.i + * + * C complex typemaps + * ISO C99: 7.3 Complex arithmetic + * ----------------------------------------------------------------------------- */ + + +%include + +%{ +#include +%} + + +/* C complex constructor */ +#define CCplxConst(r, i) ((r) + I*(i)) + +%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag); +%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag); + +/* declaring the typemaps */ +%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex); +%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex); diff --git a/Lib/javascript/v8/cdata.i b/Lib/javascript/v8/cdata.i new file mode 100644 index 000000000..367965990 --- /dev/null +++ b/Lib/javascript/v8/cdata.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/complex.i b/Lib/javascript/v8/complex.i new file mode 100644 index 000000000..4c3b3c5e2 --- /dev/null +++ b/Lib/javascript/v8/complex.i @@ -0,0 +1,6 @@ +#ifdef __cplusplus +%include +#else +%include +#endif + diff --git a/Lib/javascript/v8/exception.i b/Lib/javascript/v8/exception.i new file mode 100644 index 000000000..0246cfde8 --- /dev/null +++ b/Lib/javascript/v8/exception.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/javascript.swg b/Lib/javascript/v8/javascript.swg new file mode 100644 index 000000000..3a83b6495 --- /dev/null +++ b/Lib/javascript/v8/javascript.swg @@ -0,0 +1,19 @@ +/* ----------------------------------------------------------------------------- + * javascript.swg + * + * Javascript typemaps + * ----------------------------------------------------------------------------- */ + +%include + +%include + +%include + +%include + +%include + +%include + +%include diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg new file mode 100644 index 000000000..9bcb33176 --- /dev/null +++ b/Lib/javascript/v8/javascriptcode.swg @@ -0,0 +1,468 @@ +/* ----------------------------------------------------------------------------- + * js_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ + +%fragment("js_ctor", "templates") %{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + $jscode + + SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + SWIGV8_RETURN(self); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_veto_ctor: a vetoing ctor for abstract classes + * - $jswrapper: name of wrapper + * - $jsname: class name + * ----------------------------------------------------------------------------- */ +%fragment ("js_veto_ctor", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + SWIG_exception(SWIG_ERROR, "Class $jsname can not be instantiated"); + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatcher: dispatcher for overloaded constructors + * - $jswrapper: name of wrapper + * - $jsname: class name + * - $jsdispatchcases: part containing code for dispatching + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatcher", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + OverloadErrorHandler errorHandler; + v8::Handle self; + + // switch all cases by means of series of if-returns. + $jsdispatchcases + + // default: + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname"); + +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_overloaded_ctor: template for wrapping a ctor. + * - $jswrapper: wrapper of called ctor + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * - $jsargcount: number of arguments + * - $jsmangledtype: mangled type of class + * ----------------------------------------------------------------------------- */ +%fragment("js_overloaded_ctor", "templates") %{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) { + v8::HandleScope scope; + v8::Handle self = args.Holder(); + $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + $jscode + + SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN); + SWIGV8_RETURN(self); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_ctor_dispatch_case: template for a dispatch case for calling an overloaded ctor. + * - $jsargcount: number of arguments of called ctor + * - $jswrapper: wrapper of called ctor + * + * Note: a try-catch-like mechanism is used to switch cases + * ----------------------------------------------------------------------------- */ +%fragment ("js_ctor_dispatch_case", "templates") +%{ + if(args.Length() == $jsargcount) { + errorHandler.err.Clear(); +#if SWIG_V8_VERSION < 0x031900 + self = $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return scope.Close(self); + } +#else + $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return; + } +#endif + } +%} + +/* ----------------------------------------------------------------------------- + * js_dtor: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtor", "templates") +%{ + +#if (SWIG_V8_VERSION < 0x031900) +void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) +{ + SWIGV8_Proxy *proxy = static_cast(parameter); +#else +void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) +{ +#endif + + if(proxy->swigCMemOwn && proxy->swigCObject) { +#ifdef SWIGRUNTIME_DEBUG + printf("Deleting wrapped instance: %s\n", proxy->info->name); +#endif + $jsfree proxy->swigCObject; + } + delete proxy; + + object.Clear(); +#if (SWIG_V8_VERSION < 0x031900) + object.Dispose(); +#elif (SWIG_V8_VERSION < 0x032100) + object->Dispose(isolate); +#else + object->Dispose(); +#endif +} +%} + +/* ----------------------------------------------------------------------------- + * js_dtoroverride: template for a destructor wrapper + * - $jsmangledname: mangled class name + * - $jstype: class type + * - ${destructor_action}: The custom destructor action to invoke. + * ----------------------------------------------------------------------------- */ +%fragment ("js_dtoroverride", "templates") +%{ +#if (SWIG_V8_VERSION < 0x031900) +void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) +{ + SWIGV8_Proxy *proxy = static_cast(parameter); +#else +void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SWIGV8_Proxy *proxy) +{ +#endif + if(proxy->swigCMemOwn && proxy->swigCObject) { + $jstype arg1 = ($jstype)proxy->swigCObject; + ${destructor_action} + } + delete proxy; + +#if (SWIG_V8_VERSION < 0x031900) + object.Dispose(); +#elif (SWIG_V8_VERSION < 0x032100) + object->Dispose(isolate); +#else + object->Dispose(); +#endif +} +%} + +/* ----------------------------------------------------------------------------- + * js_getter: template for getter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment("js_getter", "templates") +%{ +SwigV8ReturnValue $jswrapper(v8::Local property, const SwigV8PropertyCallbackInfo& info) { + v8::HandleScope scope; + v8::Handle jsresult; + $jslocals + $jscode + SWIGV8_RETURN_INFO(jsresult, info); + + goto fail; +fail: + SWIGV8_RETURN_INFO(v8::Undefined(), info); +} +%} + +/* ----------------------------------------------------------------------------- + * js_setter: template for setter function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment("js_setter", "templates") +%{ +void $jswrapper(v8::Local property, v8::Local value, + const SwigV8PropertyCallbackInfoVoid& info) { + v8::HandleScope scope; + $jslocals + $jscode + goto fail; +fail: + return; +} +%} + +/* ----------------------------------------------------------------------------- + * js_function: template for function wrappers + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment("js_function", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + v8::Handle jsresult; + $jslocals + if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper."); + + $jscode + SWIGV8_RETURN(jsresult); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_function_dispatcher: template for a function dispatcher for overloaded functions + * - $jswrapper: wrapper function name + * - $jsname: name of the wrapped function + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment("js_function_dispatcher", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) { + v8::HandleScope scope; + v8::Handle jsresult; + OverloadErrorHandler errorHandler; + $jscode + + SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for function $jsname."); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_overloaded_function: template for a overloaded function + * - $jswrapper: wrapper function name + * - $jslocals: locals part of wrapper + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_overloaded_function", "templates") +%{ +SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args, V8ErrorHandler& SWIGV8_ErrorHandler) +{ + v8::HandleScope scope; + v8::Handle jsresult; + $jslocals + $jscode + SWIGV8_RETURN(jsresult); + + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} +%} + +/* ----------------------------------------------------------------------------- + * js_function_dispatch_case: template for a case used in the function dispatcher + * - $jswrapper: wrapper function name + * - $jsargcount: number of arguments of overloaded function + * - $jscode: code part of wrapper + * ----------------------------------------------------------------------------- */ +%fragment ("js_function_dispatch_case", "templates") +%{ + + if(args.Length() == $jsargcount) { + errorHandler.err.Clear(); +#if (SWIG_V8_VERSION < 0x031900) + jsresult = $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return scope.Close(jsresult); + } +#else + $jswrapper(args, errorHandler); + if(errorHandler.err.IsEmpty()) { + return; + } +#endif + } +%} + +/* ----------------------------------------------------------------------------- + * jsv8_declare_class_template: template for a class template declaration. + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_declare_class_template", "templates") +%{ + SWIGV8_ClientData $jsmangledname_clientData; +%} + +/* ----------------------------------------------------------------------------- + * jsv8_define_class_template: template for a class template definition. + * - $jsmangledname: mangled class name + * - $jsmangledtype: mangled class type + * - $jsdtor: the dtor wrapper + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_define_class_template", "templates") +%{ + v8::Handle $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname"); +#if (SWIG_V8_VERSION < 0x031900) + $jsmangledname_clientData.class_templ = v8::Persistent::New($jsmangledname_class); +#else + $jsmangledname_clientData.class_templ.Reset(v8::Isolate::GetCurrent(), $jsmangledname_class); +#endif + $jsmangledname_clientData.dtor = $jsdtor; + if (SWIGTYPE_$jsmangledtype->clientdata == 0) { + SWIGTYPE_$jsmangledtype->clientdata = &$jsmangledname_clientData; + } +%} + + +/* ----------------------------------------------------------------------------- + * jsv8_inherit: template for an class inherit statement. + * - $jsmangledname: mangled class name + * - $jsbaseclass: mangled name of the base class + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_inherit", "templates") +%{ + if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty())) + { +#if (SWIG_V8_VERSION < 0x031900) + $jsmangledname_class->Inherit(static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ); +#else + $jsmangledname_class->Inherit( + v8::Handle::New( + v8::Isolate::GetCurrent(), + static_cast(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ) + ); +#endif + +#ifdef SWIGRUNTIME_DEBUG + printf("Inheritance successful $jsmangledname $jsbaseclass\n"); +#endif + } else { +#ifdef SWIGRUNTIME_DEBUG + printf("Unable to inherit baseclass, it didn't exist $jsmangledname $jsbaseclass\n"); +#endif + } +%} + +/* ----------------------------------------------------------------------------- + * jsv8_create_class_instance: template for creating an class object. + * - $jsname: class name + * - $jsmangledname: mangled class name + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_create_class_instance", "templates") +%{ + v8::Handle $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname"); + $jsmangledname_class_0->SetCallHandler($jsctor); + $jsmangledname_class_0->Inherit($jsmangledname_class); + $jsmangledname_class_0->SetHiddenPrototype(true); + v8::Handle $jsmangledname_obj = $jsmangledname_class_0->GetFunction(); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_class: template for a statement that registers a class in a parent namespace. + * - $jsname: class name + * - $jsmangledname: mangled class name + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_class", "templates") +%{ + $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_create_namespace: template for a statement that creates a namespace object. + * - $jsmangledname: mangled namespace name + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_create_namespace", "templates") +%{ + v8::Handle $jsmangledname_obj = v8::Object::New(); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_namespace: template for a statement that registers a namespace in a parent namespace. + * - $jsname: name of namespace + * - $jsmangledname: mangled name of namespace + * - $jsparent: mangled name of parent namespace + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_namespace", "templates") +%{ + $jsparent_obj->Set(v8::String::NewSymbol("$jsname"), $jsmangledname_obj); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_member_function: template for a statement that registers a member function. + * - $jsmangledname: mangled class name + * - $jsname: name of the function + * - $jswrapper: wrapper of the member function + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_member_function", "templates") +%{ + SWIGV8_AddMemberFunction($jsmangledname_class, "$jsname", $jswrapper); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_member_variable: template for a statement that registers a member variable. + * - $jsmangledname: mangled class name + * - $jsname: name of the function + * - $jsgetter: wrapper of the getter function + * - $jssetter: wrapper of the setter function + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_member_variable", "templates") +%{ + SWIGV8_AddMemberVariable($jsmangledname_class, "$jsname", $jsgetter, $jssetter); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_static_function: template for a statement that registers a static class function. + * - $jsname: function name + * - $jswrapper: wrapper of the function + * - $jsparent: mangled name of parent namespace + * + * Note: this template is also used for global functions. + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_static_function", "templates") +%{ + SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper); +%} + +/* ----------------------------------------------------------------------------- + * jsv8_register_static_variable: template for a statement that registers a static variable. + * - $jsname: variable name + * - $jsparent: mangled name of parent namespace + * - $jsgetter: wrapper of the getter function + * - $jssetter: wrapper of the setter function + * + * Note: this template is also used for global variables. + * ----------------------------------------------------------------------------- */ +%fragment("jsv8_register_static_variable", "templates") +%{ + SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter); +%} diff --git a/Lib/javascript/v8/javascriptcomplex.swg b/Lib/javascript/v8/javascriptcomplex.swg new file mode 100644 index 000000000..70c5baffb --- /dev/null +++ b/Lib/javascript/v8/javascriptcomplex.swg @@ -0,0 +1,123 @@ +/* + Defines the As/From converters for double/float complex, you need to + provide complex Type, the Name you want to use in the converters, + the complex Constructor method, and the Real and Imag complex + accessor methods. + + See the std_complex.i and ccomplex.i for concret examples. +*/ + +/* the common from converter */ +%define %swig_fromcplx_conv(Type, Real, Imag) +%fragment(SWIG_From_frag(Type),"header", + fragment=SWIG_From_frag(double)) +{ +SWIGINTERNINLINE v8::Handle +SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c) +{ + v8::HandleScope scope; + v8::Local vals = v8::Array::New(2); + + vals->Set(0, SWIG_From(double)(Real(c))); + vals->Set(1, SWIG_From(double)(Imag(c))); + return scope.Close(vals); +} +} +%enddef + +/* the double case */ +%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(double)) +{ +SWIGINTERN int +SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) +{ + v8::HandleScope scope; + + if (o->IsArray()) { + v8::Handle array = v8::Handle::Cast(o); + + if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); + double re, im; + int res; + + res = SWIG_AsVal(double)(array->Get(0), &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(array->Get(1), &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if (val) *val = Constructor(re, im); + return SWIG_OK; + } else if(o->IsNumber()){ + double d; + int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(d, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +/* the float case */ +%define %swig_cplxflt_conv(Type, Constructor, Real, Imag) +%fragment(SWIG_AsVal_frag(Type),"header", + fragment=SWIG_AsVal_frag(float)) { +SWIGINTERN int +SWIG_AsVal_dec(Type) (v8::Handle o, Type* val) +{ + v8::HandleScope scope; + + if (o->IsArray()) { + v8::Handle array = v8::Handle::Cast(o); + + if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2]."); + double re, im; + int res; + + res = SWIG_AsVal(double)(array->Get(0), &re); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + res = SWIG_AsVal(double)(array->Get(1), &im); + if(!SWIG_IsOK(res)) { + return SWIG_TypeError; + } + + if ((-FLT_MAX <= re && re <= FLT_MAX) && (-FLT_MAX <= im && im <= FLT_MAX)) { + if (val) *val = Constructor(%numeric_cast(re, float), + %numeric_cast(im, float)); + return SWIG_OK; + } else { + return SWIG_OverflowError; + } + } else if(o->IsNumber()){ + float re; + int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re)); + if (SWIG_IsOK(res)) { + if (val) *val = Constructor(re, 0.0); + return res; + } + } + return SWIG_TypeError; +} +} +%swig_fromcplx_conv(Type, Real, Imag); +%enddef + +#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \ +%swig_cplxflt_conv(Type, Constructor, Real, Imag) + + +#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \ +%swig_cplxdbl_conv(Type, Constructor, Real, Imag) diff --git a/Lib/javascript/v8/javascriptfragments.swg b/Lib/javascript/v8/javascriptfragments.swg new file mode 100644 index 000000000..4778bf033 --- /dev/null +++ b/Lib/javascript/v8/javascriptfragments.swg @@ -0,0 +1,23 @@ +/* + + Create a file with this name, 'javascriptfragments.swg', in your working + directory and add all the %fragments you want to take precedence + over the default ones defined by swig. + + For example, if you add: + + %fragment(SWIG_AsVal_frag(int),"header") { + SWIGINTERNINLINE int + SWIG_AsVal(int)(PyObject *obj, int *val) + { + ; + } + } + + this will replace the code used to retrieve an integer value for all + the typemaps that need it, including: + + int, std::vector, std::list >, etc. + + +*/ diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg new file mode 100644 index 000000000..8da6627e2 --- /dev/null +++ b/Lib/javascript/v8/javascripthelpers.swg @@ -0,0 +1,87 @@ +%insert(runtime) %{ + +// Note: since 3.19 there are new CallBack types, since 03.21.9 the old ones have been removed +#if SWIG_V8_VERSION < 0x031900 +typedef v8::InvocationCallback SwigV8FunctionCallback; +typedef v8::AccessorGetter SwigV8AccessorGetterCallback; +typedef v8::AccessorSetter SwigV8AccessorSetterCallback; +typedef v8::AccessorInfo SwigV8PropertyCallbackInfoVoid; +#else +typedef v8::FunctionCallback SwigV8FunctionCallback; +typedef v8::AccessorGetterCallback SwigV8AccessorGetterCallback; +typedef v8::AccessorSetterCallback SwigV8AccessorSetterCallback; +typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfoVoid; +#endif + +/** + * Creates a class template for a class with specified initialization function. + */ +v8::Handle SWIGV8_CreateClassTemplate(const char* symbol) { + v8::HandleScope scope; + v8::Local class_templ = v8::FunctionTemplate::New(); + class_templ->SetClassName(v8::String::NewSymbol(symbol)); + + v8::Handle inst_templ = class_templ->InstanceTemplate(); + inst_templ->SetInternalFieldCount(1); + + v8::Handle equals_templ = class_templ->PrototypeTemplate(); + equals_templ->Set(v8::String::NewSymbol("equals"), v8::FunctionTemplate::New(_SWIGV8_wrap_equals)); + + v8::Handle cptr_templ = class_templ->PrototypeTemplate(); + cptr_templ->Set(v8::String::NewSymbol("getCPtr"), v8::FunctionTemplate::New(_wrap_getCPtr)); + + return scope.Close(class_templ); +} + +/** + * Registers a class method with given name for a given class template. + */ +void SWIGV8_AddMemberFunction(v8::Handle class_templ, const char* symbol, + SwigV8FunctionCallback _func) { + v8::Handle proto_templ = class_templ->PrototypeTemplate(); + proto_templ->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)); +} + +/** + * Registers a class property with given name for a given class template. + */ +void SWIGV8_AddMemberVariable(v8::Handle class_templ, const char* symbol, + SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { + v8::Handle proto_templ = class_templ->InstanceTemplate(); + proto_templ->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); +} + +/** + * Registers a class method with given name for a given object. + */ +void SWIGV8_AddStaticFunction(v8::Handle obj, const char* symbol, + const SwigV8FunctionCallback& _func) { + obj->Set(v8::String::NewSymbol(symbol), v8::FunctionTemplate::New(_func)->GetFunction()); +} + +/** + * Registers a class method with given name for a given object. + */ +void SWIGV8_AddStaticVariable(v8::Handle obj, const char* symbol, + SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) { + obj->SetAccessor(v8::String::NewSymbol(symbol), getter, setter); +} + +void JS_veto_set_variable(v8::Local property, v8::Local value, + const SwigV8PropertyCallbackInfoVoid& info) +{ + char buffer[256]; + char msg[512]; + int res; + + property->WriteUtf8(buffer, 256); + res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); + + if(res<0) { + SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); + } else { + SWIG_exception(SWIG_ERROR, msg); + } +} + +%} // v8_helper_functions diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg new file mode 100644 index 000000000..de1fe91f4 --- /dev/null +++ b/Lib/javascript/v8/javascriptinit.swg @@ -0,0 +1,118 @@ +%insert(init) %{ + +#include + +SWIGRUNTIME void +SWIG_V8_SetModule(void *, swig_module_info *swig_module) { + v8::Local global_obj = v8::Context::GetCurrent()->Global(); + v8::Local mod = v8::External::New(swig_module); + assert(!mod.IsEmpty()); + global_obj->SetHiddenValue(v8::String::New("swig_module_info_data"), mod); +} + +SWIGRUNTIME swig_module_info * +SWIG_V8_GetModule(void *) { + v8::Local global_obj = v8::Context::GetCurrent()->Global(); + v8::Local moduleinfo = global_obj->GetHiddenValue(v8::String::New("swig_module_info_data")); + + if (moduleinfo.IsEmpty()) + { + // It's not yet loaded + return 0; + } + + v8::Local moduleinfo_extern = v8::Local::Cast(moduleinfo); + + if (moduleinfo_extern.IsEmpty()) + { + // Something's not right + return 0; + } + + void *ptr = moduleinfo_extern->Value(); + assert(ptr); + swig_module_info *retptr = static_cast(ptr); + assert(retptr); + return retptr; +} + +#define SWIG_GetModule(clientdata) SWIG_V8_GetModule(clientdata) +#define SWIG_SetModule(clientdata, pointer) SWIG_V8_SetModule(clientdata, pointer) + +%} + +%insert(init) "swiginit.swg" + +// Open the initializer function definition here + +%fragment ("js_initializer_define", "templates") %{ +#define SWIGV8_INIT $jsname_initialize +%} + +%insert(init) %{ +// Note: 'extern "C"'' disables name mangling which makes it easier to load the symbol manually +// TODO: is it ok to do that? +extern "C" +#if (NODE_MODULE_VERSION < 0x000C) +void SWIGV8_INIT (v8::Handle exports) +#else +void SWIGV8_INIT (v8::Handle exports, v8::Handle /*module*/) +#endif +{ + SWIG_InitializeModule(static_cast(&exports)); + + v8::HandleScope scope; + v8::Handle exports_obj = exports; +%} + + +/* ----------------------------------------------------------------------------- + * js_initializer: template for the module initializer function + * - $jsname: module name + * - $jsv8nspaces: part with code creating namespace objects + * - $jsv8classtemplates: part with code creating class templates + * - $jsv8wrappers: part with code that registers wrapper functions + * - $jsv8inheritance: part with inherit statements + * - $jsv8classinstances: part with code creating class objects + * - $jsv8staticwrappers: part with code adding static functions to class objects + * - $jsv8registerclasses: part with code that registers class objects in namespaces + * - $jsv8registernspaces: part with code that registers namespaces in parent namespaces + * ----------------------------------------------------------------------------- */ +%fragment("js_initializer", "templates") +%{ + // a class template for creating proxies of undefined types +#if (SWIG_V8_VERSION < 0x031900) + SWIGV8_SWIGTYPE_Proxy_class_templ = v8::Persistent::New(SWIGV8_CreateClassTemplate("SwigProxy")); +#else + SWIGV8_SWIGTYPE_Proxy_class_templ.Reset(v8::Isolate::GetCurrent(), SWIGV8_CreateClassTemplate("SwigProxy")); +#endif + + /* create objects for namespaces */ + $jsv8nspaces + + /* create class templates */ + $jsv8classtemplates + + /* register wrapper functions */ + $jsv8wrappers + + /* setup inheritances */ + $jsv8inheritance + + /* class instances */ + $jsv8classinstances + + /* add static class functions and variables */ + $jsv8staticwrappers + + /* register classes */ + $jsv8registerclasses + + /* create and register namespace objects */ + $jsv8registernspaces +} + +#if defined(BUILDING_NODE_EXTENSION) +NODE_MODULE($jsname, $jsname_initialize); +#endif +%} diff --git a/Lib/javascript/v8/javascriptkw.swg b/Lib/javascript/v8/javascriptkw.swg new file mode 100644 index 000000000..c3c118391 --- /dev/null +++ b/Lib/javascript/v8/javascriptkw.swg @@ -0,0 +1,40 @@ +#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_ +#define JAVASCRIPT_JAVASCRIPTKW_SWG_ + +/* Warnings for Java keywords */ +#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s") `x` + +/* Taken from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Reserved_Words */ + +JAVASCRIPTKW(break); +JAVASCRIPTKW(case); +JAVASCRIPTKW(catch); +JAVASCRIPTKW(continue); +JAVASCRIPTKW(default); +JAVASCRIPTKW(delete); +JAVASCRIPTKW(do); +JAVASCRIPTKW(else); +JAVASCRIPTKW(finally); +JAVASCRIPTKW(for); +JAVASCRIPTKW(function); +JAVASCRIPTKW(if); +JAVASCRIPTKW(in); +JAVASCRIPTKW(instanceof); +JAVASCRIPTKW(new); +JAVASCRIPTKW(return); +JAVASCRIPTKW(switch); +JAVASCRIPTKW(this); +JAVASCRIPTKW(throw); +JAVASCRIPTKW(try); +JAVASCRIPTKW(typeof); +JAVASCRIPTKW(var); +JAVASCRIPTKW(void); +JAVASCRIPTKW(while); +JAVASCRIPTKW(with); + +/* others bad names if any*/ +// for example %namewarn("321:clone() is a javascript bad method name") *::clone(); + +#undef JAVASCRIPTKW + +#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_ diff --git a/Lib/javascript/v8/javascriptprimtypes.swg b/Lib/javascript/v8/javascriptprimtypes.swg new file mode 100644 index 000000000..706a799b7 --- /dev/null +++ b/Lib/javascript/v8/javascriptprimtypes.swg @@ -0,0 +1,198 @@ +/* ------------------------------------------------------------ + * Primitive Types + * ------------------------------------------------------------ */ + +/* boolean */ + +%fragment(SWIG_From_frag(bool),"header") { +SWIGINTERNINLINE +v8::Handle +SWIG_From_dec(bool)(bool value) +{ + return v8::Boolean::New(value); +} +} + +%fragment(SWIG_AsVal_frag(bool),"header", + fragment=SWIG_AsVal_frag(long)) { +SWIGINTERN +int SWIG_AsVal_dec(bool)(v8::Handle obj, bool *val) +{ + if(!obj->IsBoolean()) { + return SWIG_ERROR; + } + + if (val) *val = obj->BooleanValue(); + return SWIG_OK; +} +} + +/* int */ + +%fragment(SWIG_From_frag(int),"header") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(int)(int value) +{ + return v8::Int32::New(value); +} +} + +%fragment(SWIG_AsVal_frag(int),"header") { +SWIGINTERN +int SWIG_AsVal_dec(int)(v8::Handle valRef, int* val) +{ + if (!valRef->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = valRef->IntegerValue(); + + return SWIG_OK; +} +} + +/* long */ + +%fragment(SWIG_From_frag(long),"header") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(long)(long value) +{ + return v8::Number::New(value); +} +} + +%fragment(SWIG_AsVal_frag(long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN +int SWIG_AsVal_dec(long)(v8::Handle obj, long* val) +{ + if (!obj->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = (long) obj->IntegerValue(); + + return SWIG_OK; +} +} + +/* unsigned long */ + +%fragment(SWIG_From_frag(unsigned long),"header", + fragment=SWIG_From_frag(long)) { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(unsigned long)(unsigned long value) +{ + return (value > LONG_MAX) ? + v8::Integer::NewFromUnsigned(value) : v8::Integer::New(%numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long),"header", + fragment="SWIG_CanCastAsInteger") { +SWIGINTERN +int SWIG_AsVal_dec(unsigned long)(v8::Handle obj, unsigned long *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + + long longVal = (long) obj->NumberValue(); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* long long */ +// Note: these are copied from 'long' and probably need fixing + +%fragment(SWIG_From_frag(long long),"header", + fragment=SWIG_From_frag(long), + fragment="") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(long long)(long long value) +{ + return v8::Number::New(value); +} +} + +%fragment(SWIG_AsVal_frag(long long),"header", + fragment=SWIG_AsVal_frag(long), + fragment="SWIG_CanCastAsInteger", + fragment="") { +SWIGINTERN +int SWIG_AsVal_dec(long long)(v8::Handle obj, long long* val) +{ + if (!obj->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = (long long) obj->IntegerValue(); + + return SWIG_OK; +} +} + +/* unsigned long long */ +// Note: these are copied from 'unsigned long' and probably need fixing + +%fragment(SWIG_From_frag(unsigned long long),"header", + fragment=SWIG_From_frag(long long), + fragment="") { +SWIGINTERNINLINE +v8::Handle SWIG_From_dec(unsigned long long)(unsigned long long value) +{ + return (value > LONG_MAX) ? + v8::Integer::NewFromUnsigned(value) : v8::Integer::New(%numeric_cast(value,long)); +} +} + +%fragment(SWIG_AsVal_frag(unsigned long long),"header", + fragment=SWIG_AsVal_frag(unsigned long), + fragment="SWIG_CanCastAsInteger", + fragment="") { +SWIGINTERN +int SWIG_AsVal_dec(unsigned long long)(v8::Handle obj, unsigned long long *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + + long long longVal = (long long) obj->NumberValue(); + + if(longVal < 0) { + return SWIG_OverflowError; + } + + if(val) *val = longVal; + + return SWIG_OK; +} +} + +/* double */ + +%fragment(SWIG_From_frag(double),"header") { +SWIGINTERN +v8::Handle SWIG_From_dec(double) (double val) +{ + return v8::Number::New(val); +} +} + +%fragment(SWIG_AsVal_frag(double),"header") { +SWIGINTERN +int SWIG_AsVal_dec(double)(v8::Handle obj, double *val) +{ + if(!obj->IsNumber()) { + return SWIG_TypeError; + } + if(val) *val = obj->NumberValue(); + + return SWIG_OK; +} +} + diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg new file mode 100644 index 000000000..2e0a46717 --- /dev/null +++ b/Lib/javascript/v8/javascriptrun.swg @@ -0,0 +1,462 @@ +/* --------------------------------------------------------------------------- + * Error handling + * + * ---------------------------------------------------------------------------*/ + +#define SWIG_Error(code, msg) SWIGV8_ErrorHandler.error(code, msg) +#define SWIG_exception(code, msg) SWIGV8_ErrorHandler.error(code, msg) +#define SWIG_fail goto fail +#define SWIGV8_OVERLOAD false + +void SWIG_V8_Raise(const char* msg) { + v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); +} + +/* + Note: There are two contexts for handling errors. + A static V8ErrorHandler is used in not overloaded methods. + For overloaded methods the throwing type checking mechanism is used + during dispatching. As V8 exceptions can not be resetted properly + the trick is to use a dynamic ErrorHandler with same local name as the global + one. + + - See defintion of SWIG_Error above. + - See code templates 'JS_function_dispatcher', 'JS_functionwrapper_overload', + and 'JS_function_dispatch_case' in javascriptcode.swg + +*/ +class V8ErrorHandler { +public: + virtual ~V8ErrorHandler() {} + virtual void error(int code, const char* msg) { + SWIG_V8_Raise(msg); + } +}; +// this is used in usually +V8ErrorHandler SWIGV8_ErrorHandler; + +// instances of this are used in overloaded functions +class OverloadErrorHandler: public V8ErrorHandler { +public: + virtual void error(int code, const char* msg) { + err = v8::Exception::Error(v8::String::New(msg)); + if(code != SWIG_TypeError) { + v8::ThrowException(err); + } + } + v8::Handle err; +}; + +// Note: these typedefs and defines are used to deal with v8 API changes since version 3.19.00 + +#if (SWIG_V8_VERSION < 0x031900) +typedef v8::Handle SwigV8ReturnValue; +typedef v8::Arguments SwigV8Arguments; +typedef v8::AccessorInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) return scope.Close(val) +#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val) +#else +typedef void SwigV8ReturnValue; +typedef v8::FunctionCallbackInfo SwigV8Arguments; +typedef v8::PropertyCallbackInfo SwigV8PropertyCallbackInfo; +#define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return +#define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return +#endif + + +/* --------------------------------------------------------------------------- + * Basic Proxy object + * + * ---------------------------------------------------------------------------*/ + +// Note: to trigger the v8 gc more often one can tell v8 about the memory consumption +// TODO: we could add a v8 specific parameter to control this value +#define SWIGV8_AVG_OBJ_SIZE 1000 + +class SWIGV8_Proxy { +public: + SWIGV8_Proxy(): swigCMemOwn(false), swigCObject(0), info(0) { + v8::V8::AdjustAmountOfExternalAllocatedMemory(SWIGV8_AVG_OBJ_SIZE); + }; + + ~SWIGV8_Proxy() { +#if (SWIG_V8_VERSION < 0x031900 || SWIG_V8_VERSION >= 0x032100) + handle.ClearWeak(); + handle.Dispose(); +#else + handle.ClearWeak(v8::Isolate::GetCurrent()); + handle.Dispose(v8::Isolate::GetCurrent()); +#endif + + handle.Clear(); + v8::V8::AdjustAmountOfExternalAllocatedMemory(-SWIGV8_AVG_OBJ_SIZE); + } + + bool swigCMemOwn; + void *swigCObject; + swig_type_info *info; + v8::Persistent handle; +}; + +class SWIGV8_ClientData { +public: + v8::Persistent class_templ; + +#if (SWIG_V8_VERSION < 0x031900) + void (*dtor) (v8::Persistent< v8::Value> object, void *parameter); +#else + void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy); +#endif +}; + +v8::Persistent SWIGV8_SWIGTYPE_Proxy_class_templ; + +int SWIG_V8_ConvertInstancePtr(v8::Handle objRef, void** ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); +#else + SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + + if(cdata == NULL) { + return SWIG_ERROR; + } + if(cdata->info != info) { + swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info); + if (!tc && cdata->info->name) { + tc = SWIG_TypeCheck(cdata->info->name, info); + } + bool type_valid = tc != 0; + if(!type_valid) { + return SWIG_TypeError; + } + } + *ptr = cdata->swigCObject; + if(flags & SWIG_POINTER_DISOWN) { + cdata->swigCMemOwn = false; + } + return SWIG_OK; +} + +#if (SWIG_V8_VERSION < 0x031900) +void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) +#else +void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) +#endif +{ +#if (SWIG_V8_VERSION < 0x031900) + SWIGV8_Proxy *proxy = static_cast(parameter); +#endif + + delete proxy; +} + +int SWIG_V8_GetInstancePtr(v8::Handle valRef, void** ptr) { + if(!valRef->IsObject()) { + return SWIG_TypeError; + } + v8::Handle objRef = valRef->ToObject(); + + if(objRef->InternalFieldCount() < 1) return SWIG_ERROR; + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + SWIGV8_Proxy *cdata = static_cast(v8::External::Unwrap(cdataRef)); +#else + SWIGV8_Proxy *cdata = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + + if(cdata == NULL) { + return SWIG_ERROR; + } + + *ptr = cdata->swigCObject; + + return SWIG_OK; +} + +void SWIGV8_SetPrivateData(v8::Handle 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; + +#if (SWIG_V8_VERSION < 0x031900) + obj->SetPointerInInternalField(0, cdata); + cdata->handle = v8::Persistent::New(obj); +#else + obj->SetAlignedPointerInInternalField(0, cdata); + cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); +#endif + +#if (SWIG_V8_VERSION < 0x031900) + // clientdata must be set for owned data as we need to register the dtor + if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { + cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); + } else { + cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor); + } + cdata->handle.MarkIndependent(); +#else + if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) { + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor); + } else { + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor); + } + +#if (SWIG_V8_VERSION < 0x032100) + cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); +#else + cdata->handle.MarkIndependent(); +#endif + +#endif +} + +int SWIG_V8_ConvertPtr(v8::Handle valRef, void** ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + + if(!valRef->IsObject()) { + return SWIG_TypeError; + } + v8::Handle objRef = valRef->ToObject(); + return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags); +} + +v8::Handle SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) { + v8::HandleScope scope; + v8::Handle class_templ; + +#if (SWIG_V8_VERSION < 0x031900) + if(info->clientdata != 0) { + class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ; + } else { + class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ; + } +#else + v8::Isolate *iso = v8::Isolate::GetCurrent(); + + if(info->clientdata != 0) { + class_templ = v8::Handle::New(iso, ((SWIGV8_ClientData*) info->clientdata)->class_templ); + } else { + class_templ = v8::Handle::New(iso, SWIGV8_SWIGTYPE_Proxy_class_templ); + } +#endif + + v8::Handle result = class_templ->InstanceTemplate()->NewInstance(); + SWIGV8_SetPrivateData(result, ptr, info, flags); + + return scope.Close(result); +} + +#define SWIG_ConvertPtr(obj, ptr, info, flags) SWIG_V8_ConvertPtr(obj, ptr, info, flags) +#define SWIG_NewPointerObj(ptr, info, flags) SWIG_V8_NewPointerObj(ptr, info, flags) + +#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_V8_ConvertInstancePtr(obj, pptr, type, flags) +#define SWIG_NewInstanceObj(thisvalue, type, flags) SWIG_V8_NewPointerObj(thisvalue, type, flags) + +#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_V8_ConvertPtr(obj, pptr, type, 0) +#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_V8_NewPointerObj(ptr, type, 0) + +#define SWIG_GetInstancePtr(obj, ptr) SWIG_V8_GetInstancePtr(obj, ptr) + +#if (SWIG_V8_VERSION < 0x031900) +v8::Handle _SWIGV8_wrap_equals(const v8::Arguments &args) { +#else +void _SWIGV8_wrap_equals(const v8::FunctionCallbackInfo& args) { +#endif + v8::HandleScope scope; + v8::Handle jsresult; + void *arg1 = (void *) 0 ; + void *arg2 = (void *) 0 ; + bool result; + int res1; + int res2; + + if(args.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for equals."); + + res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ERROR, "Could not get pointer from 'this' object for equals."); + } + res2 = SWIG_GetInstancePtr(args[0], &arg2); + if (!SWIG_IsOK(res2)) { + SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "equals" "', argument " "1"" of type '" "void *""'"); + } + + result = (bool)(arg1 == arg2); + jsresult = v8::Boolean::New(result); + + SWIGV8_RETURN(jsresult); + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} + +#if (SWIG_V8_VERSION < 0x031900) +v8::Handle _wrap_getCPtr(const v8::Arguments &args) { +#else +void _wrap_getCPtr(const v8::FunctionCallbackInfo& args) { +#endif + v8::HandleScope scope; + v8::Handle jsresult; + void *arg1 = (void *) 0 ; + long result; + int res1; + + res1 = SWIG_GetInstancePtr(args.Holder(), &arg1); + if (!SWIG_IsOK(res1)) { + SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "getCPtr" "', argument " "1"" of type '" "void *""'"); + } + + result = (long)arg1; + jsresult = v8::Number::New(result); + + SWIGV8_RETURN(jsresult); + goto fail; +fail: + SWIGV8_RETURN(v8::Undefined()); +} + +/* --------------------------------------------------------------------------- + * PackedData object + * + * ---------------------------------------------------------------------------*/ + +class SwigV8PackedData { +public: + SwigV8PackedData(void *data, size_t size, swig_type_info *type): data(data), size(size), type(type) {}; + + ~SwigV8PackedData() { + }; + + void* data; + size_t size; + swig_type_info *type; + + v8::Persistent handle; +}; + +SWIGRUNTIMEINLINE +int SwigV8Packed_Check(v8::Handle valRef) { + v8::HandleScope scope; + v8::Handle objRef = valRef->ToObject(); + if(objRef->InternalFieldCount() < 1) return false; + v8::Handle flag = objRef->GetHiddenValue(v8::String::New("__swig__packed_data__")); + return (flag->IsBoolean() && flag->BooleanValue()); +} + +SWIGRUNTIME +swig_type_info* SwigV8Packed_UnpackData(v8::Handle valRef, void *ptr, size_t size) { + if (SwigV8Packed_Check(valRef)) { + v8::HandleScope scope; + SwigV8PackedData *sobj; + + v8::Handle objRef = valRef->ToObject(); + +#if (SWIG_V8_VERSION < 0x031900) + v8::Handle cdataRef = objRef->GetInternalField(0); + sobj = static_cast(v8::External::Unwrap(cdataRef)); +#else + sobj = static_cast(objRef->GetAlignedPointerFromInternalField(0)); +#endif + if (sobj == NULL || sobj->size != size) return 0; + memcpy(ptr, sobj->data, size); + return sobj->type; + } else { + return 0; + } +} + +SWIGRUNTIME +int SWIGV8_ConvertPacked(v8::Handle valRef, void *ptr, size_t sz, swig_type_info *ty) { + swig_type_info *to = SwigV8Packed_UnpackData(valRef, ptr, sz); + if (!to) return SWIG_ERROR; + if (ty) { + if (to != ty) { + /* check type cast? */ + swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); + if (!tc) return SWIG_ERROR; + } + } + return SWIG_OK; +} + +#if (SWIG_V8_VERSION < 0x031900) +void _wrap_SwigV8PackedData_delete(v8::Persistent< v8::Value > object, void *parameter) +{ + SwigV8PackedData *cdata = static_cast(parameter); +#else +void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent< v8::Object > * object, SwigV8PackedData *cdata) +{ +#endif + + delete cdata; + +#if (SWIG_V8_VERSION < 0x031900) + object.Clear(); + object.Dispose(); +#elif (SWIG_V8_VERSION < 0x032100) + object->Dispose(isolate); +#else + object->Dispose(); +#endif +} + +SWIGRUNTIME +v8::Handle SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type) { + v8::HandleScope scope; + + SwigV8PackedData* cdata = new SwigV8PackedData(data, size, type); + v8::Handle obj = v8::Object::New(); + + obj->SetHiddenValue(v8::String::New("__swig__packed_data__"), v8::Boolean::New(true)); + +#if (SWIG_V8_VERSION < 0x031900) + obj->SetPointerInInternalField(0, cdata); + cdata->handle = v8::Persistent::New(obj); +#else + obj->SetAlignedPointerInInternalField(0, cdata); + cdata->handle.Reset(v8::Isolate::GetCurrent(), obj); +#endif + +#if (SWIG_V8_VERSION < 0x031900) + cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete); + cdata->handle.MarkIndependent(); +#else + cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, _wrap_SwigV8PackedData_delete); +# if (SWIG_V8_VERSION < 0x032100) + cdata->handle.MarkIndependent(v8::Isolate::GetCurrent()); +# else + cdata->handle.MarkIndependent(); +# endif +#endif + + return scope.Close(obj); +} + +#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIGV8_ConvertPacked(obj, ptr, sz, ty) +#define SWIG_NewMemberObj(ptr, sz, type) SWIGV8_NewPackedObj(ptr, sz, type) + + +/* --------------------------------------------------------------------------- + * Support for IN/OUTPUT typemaps (see Lib/typemaps/inoutlist.swg) + * + * ---------------------------------------------------------------------------*/ + +SWIGRUNTIME +v8::Handle SWIGV8_AppendOutput(v8::Handle result, v8::Handle obj) { + v8::HandleScope scope; + if (result->IsUndefined()) { + result = v8::Array::New(); + } + v8::Handle arr = v8::Handle::Cast(result); + arr->Set(arr->Length(), obj); + + return scope.Close(arr); +} diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg new file mode 100644 index 000000000..2e18d19bf --- /dev/null +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -0,0 +1,39 @@ +/* ----------------------------------------------------------------------------- + * javascriptruntime.swg + * + * ----------------------------------------------------------------------------- */ + +%define %swig_v8_define_version(version) +%insert("runtime") %{ +#ifndef SWIG_V8_VERSION +#define SWIG_V8_VERSION version +#endif +%} +%enddef + +#ifdef V8_VERSION +%swig_v8_define_version(V8_VERSION) +#else +// HACK: defining a default version +%swig_v8_define_version(0x031110) +#endif + +#ifdef BUILDING_NODE_EXTENSION +%insert("runtime") %{ +#include +%} +#endif + +%insert(runtime) %{ +#include + +#include +#include +#include +%} + +%insert(runtime) "swigrun.swg"; /* SWIG API */ +%insert(runtime) "swigerrors.swg"; /* SWIG errors */ + +%insert(runtime) "javascriptrun.swg" + diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg new file mode 100644 index 000000000..69b6836a8 --- /dev/null +++ b/Lib/javascript/v8/javascriptstrings.swg @@ -0,0 +1,59 @@ + +/* ------------------------------------------------------------ + * utility methods for char strings + * ------------------------------------------------------------ */ +%fragment("SWIG_AsCharPtrAndSize", "header", fragment="SWIG_pchar_descriptor") { +SWIGINTERN int +SWIG_AsCharPtrAndSize(v8::Handle valRef, char** cptr, size_t* psize, int *alloc) +{ + if(valRef->IsString()) { + v8::Handle js_str = valRef->ToString(); + + size_t len = js_str->Utf8Length() + 1; + char* cstr = new char[len]; + js_str->WriteUtf8(cstr, len); + + if(alloc) *alloc = SWIG_NEWOBJ; + if(psize) *psize = len; + if(cptr) *cptr = cstr; + + return SWIG_OK; + } else { + if(valRef->IsObject()) { + v8::Handle obj = valRef->ToObject(); + // try if the object is a wrapped char[] + swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); + if (pchar_descriptor) { + void* vptr = 0; + if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { + if (cptr) *cptr = (char *) vptr; + if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; + if (alloc) *alloc = SWIG_OLDOBJ; + return SWIG_OK; + } + } + return SWIG_TypeError; + } else { + return SWIG_TypeError; + } + } +} +} + +%fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") { +SWIGINTERNINLINE v8::Handle +SWIG_FromCharPtrAndSize(const char* carray, size_t size) +{ + if (carray) { + if (size > INT_MAX) { + // TODO: handle extra long strings + return v8::Undefined(); + } else { + v8::Handle js_str = v8::String::New(carray, size); + return js_str; + } + } else { + return v8::Undefined(); + } +} +} diff --git a/Lib/javascript/v8/javascripttypemaps.swg b/Lib/javascript/v8/javascripttypemaps.swg new file mode 100644 index 000000000..90317a1c7 --- /dev/null +++ b/Lib/javascript/v8/javascripttypemaps.swg @@ -0,0 +1,43 @@ +/* ------------------------------------------------------------ + * Typemap specializations for Javascript + * ------------------------------------------------------------ */ + +/* ------------------------------------------------------------ + * Fragment section + * ------------------------------------------------------------ */ + +/* Include fundamental fragemt definitions */ +%include + +/* Look for user fragments file. */ +%include + +/* Javascript fragments for fundamental types */ +%include + +/* Javascript fragments for char* strings */ +%include + + +/* ------------------------------------------------------------ + * Unified typemap section + * ------------------------------------------------------------ */ + +/* Javascript types */ + +#define SWIG_Object v8::Handle +#define VOID_Object v8::Undefined() + +/* Overload of the output/constant/exception/dirout handling */ + +/* append output */ +#define SWIG_AppendOutput(result, obj) SWIGV8_AppendOutput(result, obj) + +/* set constant */ +#define SWIG_SetConstant(name, obj) + +/* raise */ +#define SWIG_Raise(obj, type, desc) SWIG_V8_Raise(type) + +/* Include the unified typemap library */ +%include diff --git a/Lib/javascript/v8/node.i b/Lib/javascript/v8/node.i new file mode 100644 index 000000000..8bf9ef061 --- /dev/null +++ b/Lib/javascript/v8/node.i @@ -0,0 +1,12 @@ +%insert("begin") %{ +#ifndef BUILDING_NODE_EXTENSION +#define BUILDING_NODE_EXTENSION +#endif +%} + +%insert("runtime") %{ +// we are including relative to the src folder because of issues +// with other files which might be named "node.h" +#include +%} + diff --git a/Lib/javascript/v8/std_common.i b/Lib/javascript/v8/std_common.i new file mode 100755 index 000000000..cee11e8ca --- /dev/null +++ b/Lib/javascript/v8/std_common.i @@ -0,0 +1,5 @@ +%include + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; + diff --git a/Lib/javascript/v8/std_complex.i b/Lib/javascript/v8/std_complex.i new file mode 100644 index 000000000..088a4fe7b --- /dev/null +++ b/Lib/javascript/v8/std_complex.i @@ -0,0 +1,19 @@ +/* + * STD C++ complex typemaps + */ + +%include + +%{ +#include +%} + +/* defining the complex as/from converters */ + +%swig_cplxdbl_convn(std::complex, std::complex, std::real, std::imag) +%swig_cplxflt_convn(std::complex, std::complex, std::real, std::imag) + +/* defining the typemaps */ + +%typemaps_primitive(%checkcode(CPLXDBL), std::complex); +%typemaps_primitive(%checkcode(CPLXFLT), std::complex); diff --git a/Lib/javascript/v8/std_deque.i b/Lib/javascript/v8/std_deque.i new file mode 100644 index 000000000..cb98f6c2f --- /dev/null +++ b/Lib/javascript/v8/std_deque.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/std_except.i b/Lib/javascript/v8/std_except.i new file mode 100644 index 000000000..af98428f6 --- /dev/null +++ b/Lib/javascript/v8/std_except.i @@ -0,0 +1 @@ +%include diff --git a/Lib/javascript/v8/std_map.i b/Lib/javascript/v8/std_map.i new file mode 100755 index 000000000..e7812f38a --- /dev/null +++ b/Lib/javascript/v8/std_map.i @@ -0,0 +1,74 @@ +/* ----------------------------------------------------------------------------- + * std_map.i + * + * SWIG typemaps for std::map + * ----------------------------------------------------------------------------- */ + +%include + +// ------------------------------------------------------------------------ +// std::map +// ------------------------------------------------------------------------ + +%{ +#include +#include +#include +%} + +// exported class + +namespace std { + + template class map { + // add typemaps here + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef K key_type; + typedef T mapped_type; + map(); + map(const map &); + + unsigned int size() const; + bool empty() const; + void clear(); + %extend { + const T& get(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + return i->second; + else + throw std::out_of_range("key not found"); + } + void set(const K& key, const T& x) { + (*self)[key] = x; + } + void del(const K& key) throw (std::out_of_range) { + std::map::iterator i = self->find(key); + if (i != self->end()) + self->erase(i); + else + throw std::out_of_range("key not found"); + } + bool has_key(const K& key) { + std::map::iterator i = self->find(key); + return i != self->end(); + } + } + }; + +// Legacy macros (deprecated) +%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) +#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary" +%enddef + +%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) +#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary" +%enddef + +} diff --git a/Lib/javascript/v8/std_pair.i b/Lib/javascript/v8/std_pair.i new file mode 100755 index 000000000..8d6057223 --- /dev/null +++ b/Lib/javascript/v8/std_pair.i @@ -0,0 +1,33 @@ +/* ----------------------------------------------------------------------------- + * std_pair.i + * + * SWIG typemaps for std::pair + * ----------------------------------------------------------------------------- */ + +%include + +// ------------------------------------------------------------------------ +// std::pair +// ------------------------------------------------------------------------ + +%{ +#include +%} + +namespace std { + + template struct pair { + + pair(); + pair(T first, U second); + pair(const pair& p); + + template pair(const pair &p); + + T first; + U second; + }; + + // add specializations here + +} diff --git a/Lib/javascript/v8/std_string.i b/Lib/javascript/v8/std_string.i new file mode 100755 index 000000000..5ad1ead27 --- /dev/null +++ b/Lib/javascript/v8/std_string.i @@ -0,0 +1,79 @@ +/* ----------------------------------------------------------------------------- + * std_string.i + * + * Typemaps for std::string and const std::string&. + * + * To use non-const std::string references use the following %apply: + * %apply const std::string & {std::string &}; + * + * ----------------------------------------------------------------------------- */ + +%{ +#include +%} + +%fragment("SWIGV8_valueToString", "header", fragment="SWIG_AsCharPtrAndSize") { +std::string* SWIGV8_valueToStringPtr(v8::Handle val) { + + if (!val->IsString()) return 0; + + int alloc; + size_t size; + char* chars; + int res = SWIG_AsCharPtrAndSize(val, &chars, &size, &alloc); + + if(res != SWIG_OK) { + v8::ThrowException(v8::Exception::TypeError(v8::String::New("Could not convert to string."))); + return 0; + } + + // copies the data (again) + std::string *str = new std::string(chars); + + if (alloc) delete[] chars; + + return str; +} +} + +%fragment("SWIGV8_stringToValue", "header", fragment="SWIG_FromCharPtrAndSize") { +v8::Handle SWIGV8_stringToValue(const std::string &str) { + return SWIG_FromCharPtrAndSize(str.c_str(), str.length()); +} +} + +namespace std { + %naturalvar string; + + class string; + + %typemap(in, fragment="SWIGV8_valueToString") string (std::string* tmp) + %{ + tmp = SWIGV8_valueToStringPtr($input); + $1 = *tmp; + if (tmp == 0) { v8::ThrowException(v8::Exception::TypeError(v8::String::New("Null pointer."))); goto fail; } + if (tmp) delete tmp; + %} + + %typemap(in, fragment="SWIGV8_valueToString") const string & + %{ + $1 = SWIGV8_valueToStringPtr($input); + if ($1 == 0) { v8::ThrowException(v8::Exception::TypeError(v8::String::New("Null pointer."))); goto fail; } + %} + + %typemap(freearg) const string & + %{ + if ($1) delete $1; + %} + + %typemap(out, fragment="SWIGV8_stringToValue") string + %{ + $result = SWIGV8_stringToValue($1); + %} + + %typemap(out, fragment="SWIGV8_stringToValue") const string & + %{ + $result = SWIGV8_stringToValue(*$1); + %} + +} diff --git a/Lib/javascript/v8/std_vector.i b/Lib/javascript/v8/std_vector.i new file mode 100755 index 000000000..3f29b19c7 --- /dev/null +++ b/Lib/javascript/v8/std_vector.i @@ -0,0 +1,85 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * ----------------------------------------------------------------------------- */ + +%include + +%{ +#include +#include +%} + +namespace std { + + template class vector { + public: + typedef size_t size_type; + typedef T value_type; + typedef const value_type& const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i class vector { + public: + typedef size_t size_type; + typedef bool value_type; + typedef bool const_reference; + vector(); + vector(size_type n); + size_type size() const; + size_type capacity() const; + void reserve(size_type n); + %rename(isEmpty) empty; + bool empty() const; + void clear(); + %rename(add) push_back; + void push_back(const value_type& x); + %extend { + const_reference get(int i) throw (std::out_of_range) { + int size = int(self->size()); + if (i>=0 && isize()); + if (i>=0 && i +%include +%include +%include +%include + diff --git a/Lib/javascript/v8/typemaps.i b/Lib/javascript/v8/typemaps.i new file mode 100644 index 000000000..d3d8afb19 --- /dev/null +++ b/Lib/javascript/v8/typemaps.i @@ -0,0 +1,148 @@ +/* ----------------------------------------------------------------------------- + * typemaps.i + * + * Pointer handling + * These mappings provide support for input/output arguments and common + * uses for C/C++ pointers. + * ----------------------------------------------------------------------------- */ + +// INPUT typemaps. +// These remap a C pointer to be an "INPUT" value which is passed by value +// instead of reference. + +/* +The following methods can be applied to turn a pointer into a simple +"input" value. That is, instead of passing a pointer to an object, +you would use a real value instead. + + int *INPUT + short *INPUT + long *INPUT + long long *INPUT + unsigned int *INPUT + unsigned short *INPUT + unsigned long *INPUT + unsigned long long *INPUT + unsigned char *INPUT + bool *INPUT + float *INPUT + double *INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +*/ + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. The output value is appended to the result as +// a list element. + +/* +The following methods can be applied to turn a pointer into an "output" +value. When calling a function, no input value would be given for +a parameter, but an output value would be returned. In the case of +multiple output values, they are returned in the form of a Python tuple. + + int *OUTPUT + short *OUTPUT + long *OUTPUT + long long *OUTPUT + unsigned int *OUTPUT + unsigned short *OUTPUT + unsigned long *OUTPUT + unsigned long long *OUTPUT + unsigned char *OUTPUT + bool *OUTPUT + float *OUTPUT + double *OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters).K: + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Python output of the function would be a tuple containing both +output values. + +*/ + +// INOUT +// Mappings for an argument that is both an input and output +// parameter + +/* +The following methods can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" methods described earlier. Output values are +returned in the form of a Python tuple. + + int *INOUT + short *INOUT + long *INOUT + long long *INOUT + unsigned int *INOUT + unsigned short *INOUT + unsigned long *INOUT + unsigned long long *INOUT + unsigned char *INOUT + bool *INOUT + float *INOUT + double *INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include + void neg(double *INOUT); + +or you can use the %apply directive : + + %include + %apply double *INOUT { double *x }; + void neg(double *x); + +Unlike C, this mapping does not directly modify the input value (since +this makes no sense in Python). Rather, the modified input value shows +up as the return value of the function. Thus, to apply this function +to a Python variable you might do this : + + x = neg(x) + +Note : previous versions of SWIG used the symbol 'BOTH' to mark +input/output arguments. This is still supported, but will be slowly +phased out in future releases. + +*/ + +%include diff --git a/Lib/typemaps/strings.swg b/Lib/typemaps/strings.swg index e31e5037f..6bac0b98a 100644 --- a/Lib/typemaps/strings.swg +++ b/Lib/typemaps/strings.swg @@ -499,7 +499,7 @@ * --- String fragment methods --- * ------------------------------------------------------------ */ - +#ifndef %_typemap2_string %define %_typemap2_string(StringCode, CharCode, Char, CharName, SWIG_AsCharPtrAndSize, @@ -602,7 +602,7 @@ SWIG_AsVal_dec(Char)(SWIG_Object obj, Char *val) SWIG_DeleteCharArray) %enddef - +#endif /* ------------------------------------------------------------ * String typemaps and fragments, with default allocators diff --git a/Makefile.in b/Makefile.in index 4407d1316..f4d0be077 100644 --- a/Makefile.in +++ b/Makefile.in @@ -84,6 +84,7 @@ skip-uffi = test -n "@SKIP_UFFI@" skip-r = test -n "@SKIP_R@" skip-go = test -n "@SKIP_GO@" skip-d = test -n "@SKIP_D@" +skip-javascript = test -n "@SKIP_JAVASCRIPT@" # Additional dependencies for some tests skip-gcj = test -n "@SKIP_GCJ@" @@ -129,6 +130,7 @@ check-aliveness: @$(skip-r) || ./$(TARGET) -r -help @$(skip-go) || ./$(TARGET) -go -help @$(skip-d) || ./$(TARGET) -d -help + @$(skip-javascript) || ./$(TARGET) -javascript -help check-ccache: test -z "$(ENABLE_CCACHE)" || (cd $(CCACHE) && $(MAKE) check) @@ -139,6 +141,7 @@ check-versions: \ check-perl5-version \ check-python-version \ check-java-version \ + check-javascript-version \ check-android-version \ check-guile-version \ check-mzscheme-version \ @@ -196,7 +199,8 @@ check-examples: \ check-cffi-examples \ check-r-examples \ check-go-examples \ - check-d-examples + check-d-examples \ + check-javascript-examples tcl_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list) perl5_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list) @@ -221,6 +225,7 @@ cffi_examples := r_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/r/check.list) go_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list) d_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list) +javascript_examples:=$(shell sed '/^\#/d' $(srcdir)/Examples/javascript/check.list) # all examples check-%-examples : @@ -274,7 +279,8 @@ check-test-suite: \ check-chicken-test-suite \ check-r-test-suite \ check-go-test-suite \ - check-d-test-suite + check-d-test-suite \ + check-javascript-test-suite check-%-test-suite: @if test -z "$(skip-$*)"; then \ @@ -326,7 +332,8 @@ all-test-suite: \ all-chicken-test-suite \ all-r-test-suite \ all-go-test-suite \ - all-d-test-suite + all-d-test-suite \ + all-javascript-test-suite all-%-test-suite: @$(MAKE) $(FLAGS) check-$*-test-suite ACTION=all @@ -354,7 +361,8 @@ broken-test-suite: \ broken-chicken-test-suite \ broken-r-test-suite \ broken-go-test-suite \ - broken-d-test-suite + broken-d-test-suite \ + broken-javascript-test-suite broken-%-test-suite: @$(MAKE) $(FLAGS) check-$*-test-suite ACTION=broken @@ -467,7 +475,8 @@ install-main: @$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@ lib-languages = gcj typemaps tcl perl5 python guile java mzscheme ruby php ocaml octave \ - pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d + pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go d javascript javascript/jsc \ + javascript/v8 lib-modules = std diff --git a/Source/Makefile.am b/Source/Makefile.am index 49d571236..4dbede635 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -49,6 +49,7 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/guile.cxx \ Modules/java.cxx \ Modules/lang.cxx \ + Modules/javascript.cxx \ Modules/lua.cxx \ Modules/main.cxx \ Modules/modula3.cxx \ diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx new file mode 100644 index 000000000..eae594727 --- /dev/null +++ b/Source/Modules/javascript.cxx @@ -0,0 +1,2428 @@ +#include "swigmod.h" + +/** + * Enables extra debugging information in typemaps. + */ +bool js_template_enable_debug = false; + +// keywords used for state variables +#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" +#define IS_ABSTRACT "is_abstract" +#define GETTER "getter" +#define SETTER "setter" +#define PARENT "parent" +#define CTOR "ctor" +#define CTOR_WRAPPERS "ctor_wrappers" +#define CTOR_DISPATCHERS "ctor_dispatchers" +#define DTOR "dtor" +#define ARGCOUNT "wrap:argc" + +// keys for global state variables +#define CREATE_NAMESPACES "create_namespaces" +#define REGISTER_NAMESPACES "register_namespaces" +#define INITIALIZER "initializer" + +// keys for class scoped state variables +#define MEMBER_VARIABLES "member_variables" +#define MEMBER_FUNCTIONS "member_functions" +#define STATIC_FUNCTIONS "static_functions" +#define STATIC_VARIABLES "static_variables" +#define HAS_TEMPLATES "has_templates" + +#define RESET true + +/** + * 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: + + JSEmitterState(); + + ~JSEmitterState(); + + DOH *global (); + + DOH *global (const char *key, DOH *initial = 0); + + DOH *clazz(bool reset = false); + + DOH *clazz(const char *key, DOH *initial = 0); + + DOH *function(bool reset = false); + + DOH *function(const char *key, DOH *initial = 0); + + DOH *variable(bool reset = false); + + DOH *variable(const char *key, DOH *initial = 0); + + static int IsSet(DOH *val); + +private: + + DOH *getState(const char *key, bool reset = false); + + Hash *_global; +}; + +/** + * A convenience class that wraps a code snippet used as template + * for code generation. + */ +class Template { + +public: + Template(const String *code); + + Template(const String *code, const String *templateName); + + Template(const Template & other); + + ~Template(); + + String *str(); + + Template & replace(const String *pattern, const String *repl); + + Template & print(DOH *doh); + + Template & pretty_print(DOH *doh); + + void operator=(const Template & t); + + Template & trim(); + +private: + + String *code; + String *templateName; + +}; + +/** + * JSEmitter represents an abstraction of javascript code generators + * for different javascript engines. + **/ +class JSEmitter { + +protected: + + typedef JSEmitterState State; + + enum MarshallingMode { + Setter, + Getter, + Ctor, + Function + }; + +public: + + enum JSEmitterType { + JavascriptCore, + V8 + }; + + JSEmitter(); + + virtual ~ JSEmitter(); + + /** + * Opens output files and temporary output DOHs. + */ + virtual int initialize(Node *n); + + /** + * Writes all collected code into the output file(s). + */ + virtual int dump(Node *n) = 0; + + /** + * Cleans up all open output DOHs. + */ + virtual int close() = 0; + + /** + * Switches the context for code generation. + * + * Classes, global variables and global functions may need to + * be registered in certain static tables. + * This method should be used to switch output DOHs correspondingly. + */ + virtual int switchNamespace(Node *); + + /** + * Invoked at the beginning of the classHandler. + */ + virtual int enterClass(Node *); + + /** + * Invoked at the end of the classHandler. + */ + virtual int exitClass(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the variableHandler. + */ + virtual int enterVariable(Node *); + + /** + * Invoked at the end of the variableHandler. + */ + virtual int exitVariable(Node *) { + return SWIG_OK; + }; + + /** + * Invoked at the beginning of the functionHandler. + */ + virtual int enterFunction(Node *); + + /** + * Invoked at the end of the functionHandler. + */ + virtual int exitFunction(Node *) { + return SWIG_OK; + }; + + /** + * Invoked by functionWrapper callback after call to Language::functionWrapper. + */ + virtual int emitWrapperFunction(Node *n); + + /** + * Invoked from constantWrapper after call to Language::constantWrapper. + **/ + virtual int emitConstant(Node *n); + + /** + * Registers a given code snippet for a given key name. + * + * This method is called by the fragmentDirective handler + * of the JAVASCRIPT language module. + **/ + int registerTemplate(const String *name, const String *code); + + /** + * Retrieve the code template registered for a given name. + */ + Template getTemplate(const String *name); + + State & getState(); + +protected: + + /** + * Generates code for a constructor function. + */ + virtual int emitCtor(Node *n); + + /** + * Generates code for a destructor function. + */ + virtual int emitDtor(Node *n); + + /** + * Generates code for a function. + */ + 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); + + /** + * Generates code for a setter function. + */ + 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 String *emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg); + + virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult = 0, bool emitReturnVariable = true); + + virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params); + + /** + * Helper function to retrieve the first parent class node. + */ + Node *getBaseClass(Node *n); + + Parm *skipIgnoredArgs(Parm *p); + + virtual int createNamespace(String *scope); + + virtual Hash *createNamespaceEntry(const char *name, const char *parent); + + virtual int emitNamespaces() = 0; + + +protected: + + Hash *templates; + + State state; + + // contains context specific data (DOHs) + // to allow generation of namespace related code + // which are switched on namespace change + Hash *namespaces; + Hash *current_namespace; + + String *defaultResultName; + + File *f_wrappers; +}; + +/* factory methods for concrete JSEmitters: */ + +JSEmitter *swig_javascript_create_JSCEmitter(); +JSEmitter *swig_javascript_create_V8Emitter(); + +/********************************************************************** + * JAVASCRIPT: swig module implementation + **********************************************************************/ + +class JAVASCRIPT:public Language { + +public: + + JAVASCRIPT():emitter(NULL) { + } ~JAVASCRIPT() { + delete emitter; + } + + virtual int functionHandler(Node *n); + virtual int globalfunctionHandler(Node *n); + virtual int variableHandler(Node *n); + virtual int globalvariableHandler(Node *n); + virtual int staticmemberfunctionHandler(Node *n); + 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); + +private: + + JSEmitter * emitter; +}; + +/* --------------------------------------------------------------------- + * functionWrapper() + * + * Low level code generator for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::functionWrapper(Node *n) { + + // note: the default implementation only prints a message + // Language::functionWrapper(n); + emitter->emitWrapperFunction(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * functionHandler() + * + * Function handler for generating wrappers for functions + * --------------------------------------------------------------------- */ +int JAVASCRIPT::functionHandler(Node *n) { + + if (GetFlag(n, "isextension") == 1) { + SetFlag(n, "ismember"); + } + + emitter->enterFunction(n); + Language::functionHandler(n); + emitter->exitFunction(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * globalfunctionHandler() + * + * Function handler for generating wrappers for functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::globalfunctionHandler(Node *n) { + emitter->switchNamespace(n); + Language::globalfunctionHandler(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * staticmemberfunctionHandler() + * + * Function handler for generating wrappers for static member functions + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::staticmemberfunctionHandler(Node *n) { + /* + * Note: storage=static is removed by Language::staticmemberfunctionHandler. + * So, don't rely on that after here. Instead use the state variable which is + * set by JSEmitter::enterFunction(). + */ + Language::staticmemberfunctionHandler(n); + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * variableHandler() + * + * Function handler for generating wrappers for variables + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::variableHandler(Node *n) { + + emitter->enterVariable(n); + Language::variableHandler(n); + emitter->exitVariable(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * globalvariableHandler() + * + * Function handler for generating wrappers for global variables + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::globalvariableHandler(Node *n) { + emitter->switchNamespace(n); + Language::globalvariableHandler(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * constantHandler() + * + * Function handler for generating wrappers for constants + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::constantWrapper(Node *n) { + emitter->switchNamespace(n); + + // Note: callbacks trigger this wrapper handler + // TODO: handle callback declarations + if (Equal(Getattr(n, "kind"), "function")) { + return SWIG_OK; + } + // TODO: the emitter for constants must be implemented in a cleaner way + // currently we treat it like a read-only variable + // however, there is a remaining bug with function pointer constants + // which could be fixed with a cleaner approach + emitter->emitConstant(n); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * classHandler() + * + * Function handler for generating wrappers for class + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::classHandler(Node *n) { + emitter->switchNamespace(n); + + emitter->enterClass(n); + Language::classHandler(n); + emitter->exitClass(n); + + return SWIG_OK; +} + +int JAVASCRIPT::fragmentDirective(Node *n) { + + // catch all fragment directives that have "templates" as location + // and register them at the emitter. + String *section = Getattr(n, "section"); + + if (Equal(section, "templates")) { + emitter->registerTemplate(Getattr(n, "value"), Getattr(n, "code")); + } else { + Swig_fragment_register(n); + } + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * top() + * + * Function handler for processing top node of the parse tree + * Wrapper code generation essentially starts from here + * --------------------------------------------------------------------- */ + +int JAVASCRIPT::top(Node *n) { + emitter->initialize(n); + + Language::top(n); + + emitter->dump(n); + emitter->close(); + + return SWIG_OK; +} + +static const char *usage = (char *) "\ +Javascript Options (available with -javascript)\n\ + -jsc - creates a JavascriptCore extension \n\ + -v8 - creates a v8 extension \n\ + -node - creates a node.js extension \n\ + -debug-codetemplates - generates information about the origin of code templates.\n"; + + +/* --------------------------------------------------------------------- + * main() + * + * Entry point for the JAVASCRIPT module + * --------------------------------------------------------------------- */ + +void JAVASCRIPT::main(int argc, char *argv[]) { + // Set javascript subdirectory in SWIG library + SWIG_library_directory("javascript"); + + int mode = -1; + + for (int i = 1; i < argc; i++) { + if (argv[i]) { + if (strcmp(argv[i], "-v8") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + } else if (strcmp(argv[i], "-jsc") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::JavascriptCore; + SWIG_library_directory("javascript/jsc"); + } else if (strcmp(argv[i], "-node") == 0) { + Swig_mark_arg(i); + mode = JSEmitter::V8; + SWIG_library_directory("javascript/v8"); + Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0); + } else if (strcmp(argv[i], "-debug-codetemplates") == 0) { + Swig_mark_arg(i); + js_template_enable_debug = true; + } else if (strcmp(argv[i], "-help") == 0) { + fputs(usage, stdout); + return; + } + } + } + + switch (mode) { + case JSEmitter::V8: + { + emitter = swig_javascript_create_V8Emitter(); + Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0); + break; + } + case JSEmitter::JavascriptCore: + { + emitter = swig_javascript_create_JSCEmitter(); + Preprocessor_define("SWIG_JAVASCRIPT_JSC 1", 0); + break; + } + default: + { + Printf(stderr, "SWIG Javascript: Unknown emitter type.\n"); + SWIG_exit(-1); + break; + } + } + + // Add a symbol to the parser for conditional compilation + Preprocessor_define("SWIGJAVASCRIPT 1", 0); + + // Add typemap definitions + SWIG_typemap_lang("javascript"); + + // Set configuration file + SWIG_config_file("javascript.swg"); + + allow_overloading(); +} + +/* ----------------------------------------------------------------------------- + * swig_javascript() - Instantiate module + * ----------------------------------------------------------------------------- */ + +static Language *new_swig_javascript() { + return new JAVASCRIPT(); +} + +extern "C" Language *swig_javascript(void) { + return new_swig_javascript(); +} + +/********************************************************************** + * Emitter implementations + **********************************************************************/ + +/* ----------------------------------------------------------------------------- + * JSEmitter() + * ----------------------------------------------------------------------------- */ + +JSEmitter::JSEmitter() +: templates(NewHash()), namespaces(NULL), current_namespace(NULL), defaultResultName(NewString("result")), f_wrappers(NULL) { +} + +/* ----------------------------------------------------------------------------- + * ~JSEmitter() + * ----------------------------------------------------------------------------- */ + +JSEmitter::~JSEmitter() { + Delete(templates); +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::RegisterTemplate() : Registers a code template + * + * Note: this is used only by JAVASCRIPT::fragmentDirective(). + * ----------------------------------------------------------------------------- */ + +int JSEmitter::registerTemplate(const String *name, const String *code) { + if (!State::IsSet(state.global (HAS_TEMPLATES))) { + SetFlag(state.global (), HAS_TEMPLATES); + } + return Setattr(templates, name, code); +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::getTemplate() : Provides a registered code template + * ----------------------------------------------------------------------------- */ + +Template JSEmitter::getTemplate(const String *name) { + String *templ = Getattr(templates, name); + + if (!templ) { + Printf(stderr, "Could not find template %s\n.", name); + SWIG_exit(EXIT_FAILURE); + } + + Template t(templ, name); + return t; +} + +JSEmitterState & JSEmitter::getState() { + return state; +} + +int JSEmitter::initialize(Node * /*n */ ) { + + if (namespaces != NULL) { + Delete(namespaces); + } + namespaces = NewHash(); + Hash *global_namespace = createNamespaceEntry("exports", 0); + + Setattr(namespaces, "::", global_namespace); + current_namespace = global_namespace; + + f_wrappers = NewString(""); + + return SWIG_OK; +} + +/* --------------------------------------------------------------------- + * skipIgnoredArgs() + * --------------------------------------------------------------------- */ + +Parm *JSEmitter::skipIgnoredArgs(Parm *p) { + while (checkAttribute(p, "tmap:in:numinputs", "0")) { + p = Getattr(p, "tmap:in:next"); + } + return p; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::getBaseClass() : the node of the base class or NULL + * + * Note: the first base class is provided. Multiple inheritance is not + * supported. + * ----------------------------------------------------------------------------- */ + +Node *JSEmitter::getBaseClass(Node *n) { + // retrieve the first base class that is not %ignored + List *baselist = Getattr(n, "bases"); + if (baselist) { + Iterator base = First(baselist); + while (base.item && GetFlag(base.item, "feature:ignore")) { + base = Next(base); + } + return base.item; + } + return NULL; +} + + /* ----------------------------------------------------------------------------- + * JSEmitter::emitWrapperFunction() : dispatches emitter functions. + * + * This allows to have small sized, dedicated emitting functions. + * All state dependent branching is done here. + * ----------------------------------------------------------------------------- */ + +int JSEmitter::emitWrapperFunction(Node *n) { + int ret = SWIG_OK; + + String *kind = Getattr(n, "kind"); + + if (kind) { + + if (Equal(kind, "function") + // HACK: sneaky.ctest revealed that typedef'd (global) functions must be + // detected via the 'view' attribute. + || (Equal(kind, "variable") && Equal(Getattr(n, "view"), "globalfunctionHandler")) + ) { + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); + bool is_static = GetFlag(state.function(), IS_STATIC); + ret = emitFunction(n, is_member, is_static); + } else if (Cmp(kind, "variable") == 0) { + bool is_static = GetFlag(state.variable(), IS_STATIC); + // HACK: smartpointeraccessed static variables are not treated as statics + if (GetFlag(n, "allocate:smartpointeraccess")) { + is_static = false; + } + + bool is_member = GetFlag(n, "ismember"); + bool is_setter = GetFlag(n, "memberset") || GetFlag(n, "varset"); + bool is_getter = GetFlag(n, "memberget") || GetFlag(n, "varget"); + if (is_setter) { + ret = emitSetter(n, is_member, is_static); + } else if (is_getter) { + ret = emitGetter(n, is_member, is_static); + } else { + Swig_print_node(n); + } + + } else { + Printf(stderr, "Warning: unsupported wrapper function type\n"); + Swig_print_node(n); + ret = SWIG_ERROR; + } + } else { + String *view = Getattr(n, "view"); + + if (Cmp(view, "constructorHandler") == 0) { + ret = emitCtor(n); + } else if (Cmp(view, "destructorHandler") == 0) { + ret = emitDtor(n); + } else { + Printf(stderr, "Warning: unsupported wrapper function type"); + Swig_print_node(n); + ret = SWIG_ERROR; + } + } + + return ret; +} + +int JSEmitter::enterClass(Node *n) { + state.clazz(RESET); + state.clazz(NAME, Getattr(n, "sym:name")); + state.clazz("nspace", current_namespace); + + // Creating a mangled name using the current namespace and the symbol name + String *mangled_name = NewString(""); + Printf(mangled_name, "%s_%s", Getattr(current_namespace, NAME_MANGLED), Getattr(n, "sym:name")); + state.clazz(NAME_MANGLED, SwigType_manglestr(mangled_name)); + Delete(mangled_name); + + state.clazz(TYPE, NewString(Getattr(n, "classtype"))); + + String *type = SwigType_manglestr(Getattr(n, "classtypeobj")); + String *classtype_mangled = NewString(""); + Printf(classtype_mangled, "p%s", type); + state.clazz(TYPE_MANGLED, classtype_mangled); + Delete(type); + + String *ctor_wrapper = NewString("_wrap_new_veto_"); + Append(ctor_wrapper, state.clazz(NAME)); + state.clazz(CTOR, ctor_wrapper); + state.clazz(CTOR_DISPATCHERS, NewString("")); + state.clazz(DTOR, NewString("0")); + + // HACK: assume that a class is abstract + // this is resolved by emitCtor (which is only called for non abstract classes) + SetFlag(state.clazz(), IS_ABSTRACT); + + return SWIG_OK; +} + +int JSEmitter::enterFunction(Node *n) { + state.function(RESET); + state.function(NAME, Getattr(n, "sym:name")); + if (Equal(Getattr(n, "storage"), "static")) { + SetFlag(state.function(), IS_STATIC); + } + return SWIG_OK; +} + +int JSEmitter::enterVariable(Node *n) { + // reset the state information for variables. + state.variable(RESET); + + // Retrieve a pure symbol name. Using 'sym:name' as a basis, as it considers %renamings. + if (Equal(Getattr(n, "view"), "memberconstantHandler")) { + // Note: this is kind of hacky/experimental + // For constants/enums 'sym:name' contains e.g., 'Foo_Hello' instead of 'Hello' + state.variable(NAME, Getattr(n, "memberconstantHandler:sym:name")); + } else { + state.variable(NAME, Swig_scopename_last(Getattr(n, "sym:name"))); + } + + if (Equal(Getattr(n, "storage"), "static")) { + SetFlag(state.variable(), IS_STATIC); + } + + if (!Language::instance()->is_assignable(n)) { + SetFlag(state.variable(), IS_IMMUTABLE); + } + // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[] + if (Equal(Getattr(n, "type"), "a().char")) { + SetFlag(state.variable(), IS_IMMUTABLE); + } + + return SWIG_OK; +} + +int JSEmitter::emitCtor(Node *n) { + + Wrapper *wrapper = NewWrapper(); + + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + Template t_ctor(getTemplate("js_ctor")); + + //String *mangled_name = SwigType_manglestr(Getattr(n, "name")); + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + if (is_overloaded) { + t_ctor = getTemplate("js_overloaded_ctor"); + Append(wrap_name, Getattr(n, "sym:overname")); + } + Setattr(n, "wrap:name", wrap_name); + // note: removing the is_abstract flag, as this emitter + // is supposed to be called for non-abstract classes only. + Setattr(state.clazz(), IS_ABSTRACT, 0); + + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemap. + // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere + Delete(wrapper->code); + wrapper->code = NewString(""); + + Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0)); + + marshalInputArgs(n, params, wrapper, Ctor, true, false); + String *action = emit_action(n); + Printv(wrapper->code, action, "\n", 0); + + emitCleanupCode(n, wrapper, params); + + t_ctor.replace("$jswrapper", wrap_name) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .replace("$jsargcount", Getattr(n, ARGCOUNT)) + .pretty_print(f_wrappers); + + Template t_ctor_case(getTemplate("js_ctor_dispatch_case")); + t_ctor_case.replace("$jswrapper", wrap_name) + .replace("$jsargcount", Getattr(n, ARGCOUNT)); + Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str()); + + DelWrapper(wrapper); + + // create a dispatching ctor + if (is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Template t_mainctor(getTemplate("js_ctor_dispatcher")); + t_mainctor.replace("$jswrapper", wrap_name) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS)) + .pretty_print(f_wrappers); + state.clazz(CTOR, wrap_name); + } + } else { + state.clazz(CTOR, wrap_name); + } + + return SWIG_OK; +} + +int JSEmitter::emitDtor(Node *n) { + + 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(""); + + // (Taken from JSCore implementation.) + /* The if (Extend) block was taken from the Ruby implementation. + * The problem is that in the case of an %extend to create a destructor for a struct to coordinate automatic memory cleanup with the Javascript collector, + * the swig function was not being generated. More specifically: + struct MyData { + %extend { + ~MyData() { + FreeData($self); + } + } + }; + %newobject CreateData; + struct MyData* CreateData(void); + %delobject FreeData; + void FreeData(struct MyData* the_data); + + where the use case is something like: + var my_data = example.CreateData(); + my_data = null; + + This function was not being generated: + SWIGINTERN void delete_MyData(struct MyData *self){ + FreeData(self); + } + + I don't understand fully why it wasn't being generated. It just seems to happen in the Lua generator. + There is a comment about staticmemberfunctionHandler having an inconsistency and I tracked down dome of the SWIGINTERN void delete_* + code to that function in the Language base class. + The Ruby implementation seems to have an explicit check for if(Extend) and explicitly generates the code, so that's what I'm doing here. + The Ruby implementation does other stuff which I omit. + */ + if (Extend) { + String *wrap = Getattr(n, "wrap:code"); + if (wrap) { + Printv(f_wrappers, wrap, NIL); + } + } + + // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node + // TODO: generate dtors more similar to other wrappers + // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used. + if (SwigType_isarray(type)) { + Printf(free, "delete [] (%s)", ctype); + } else { + Printf(free, "delete (%s)", ctype); + } + + String *destructor_action = Getattr(n, "wrap:action"); + // Adapted from the JSCore implementation. + /* The next challenge is to generate the correct finalize function for JavaScriptCore to call. + Originally, it would use this fragment from javascriptcode.swg + %fragment ("JS_destructordefn", "templates") + %{ + void _wrap_${classname_mangled}_finalize(JSObjectRef thisObject) + { + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject); + if(t) free(t); + } + %} + + But for the above example case of %extend to define a destructor on a struct, we need to override the system to not call + free ((${type}*)t->swigCObject); + and substitute it with what the user has provided. + To solve this, I created a variation fragment called JS_destructoroverridedefn: + SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); + if(t && t->swigCMemOwn) { + ${type}* arg1 = (${type}*)t->swigCObject; + ${destructor_action} + } + if(t) free(t); + + Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action") + to decide if the user has a preferred destructor action. + Based on that, I decide which fragment to use. + And in the case of the custom action, I substitute that action in. + I noticed that destructor_action has the form + delete_MyData(arg1); + The explicit arg1 is a little funny, so I structured the fragment to create a temporary variable called arg1 to make the generation easier. + This might suggest this solution misunderstands a more complex case. + + Also, there is a problem where destructor_action is always true for me, even when not requesting %extend as above. + So this code doesn't actually quite work as I expect. The end result is that the code still works because + destructor_action calls free like the original template. The one caveat is the string in destructor_action casts to char* which is wierd. + I think there is a deeper underlying SWIG issue because I don't think it should be char*. However, it doesn't really matter for free. + + Maybe the fix for the destructor_action always true problem is that this is supposed to be embedded in the if(Extend) block above. + But I don't fully understand the conditions of any of these things, and since it works for the moment, I don't want to break more stuff. + */ + if (destructor_action) { + Template t_dtor = getTemplate("js_dtoroverride"); + state.clazz(DTOR, wrap_name); + t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED)) + .replace("$jswrapper", wrap_name) + .replace("$jsfree", free) + .replace("$jstype", ctype); + + t_dtor.replace("${destructor_action}", destructor_action); + Wrapper_pretty_print(t_dtor.str(), f_wrappers); + } else { + Template t_dtor = getTemplate("js_dtor"); + state.clazz(DTOR, wrap_name); + t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jswrapper", wrap_name) + .replace("$jsfree", free) + .replace("$jstype", ctype) + .pretty_print(f_wrappers); + } + + Delete(p_classtype); + Delete(ctype); + Delete(free); + + return SWIG_OK; +} + +int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) { + Wrapper *wrapper = NewWrapper(); + Template t_getter(getTemplate("js_getter")); + + // prepare wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Setattr(n, "wrap:name", wrap_name); + state.variable(GETTER, wrap_name); + + // prepare local variables + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + + // prepare code part + String *action = emit_action(n); + marshalInputArgs(n, params, wrapper, Getter, is_member, is_static); + marshalOutput(n, params, wrapper, action); + + emitCleanupCode(n, wrapper, params); + + t_getter.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .pretty_print(f_wrappers); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitSetter(Node *n, bool is_member, bool is_static) { + + // skip variables that are immutable + if (State::IsSet(state.variable(IS_IMMUTABLE))) { + return SWIG_OK; + } + + Wrapper *wrapper = NewWrapper(); + + Template t_setter(getTemplate("js_setter")); + + // prepare wrapper name + String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name")); + Setattr(n, "wrap:name", wrap_name); + state.variable(SETTER, wrap_name); + + // prepare local variables + ParmList *params = Getattr(n, "parms"); + emit_parameter_variables(params, wrapper); + emit_attach_parmmaps(params, wrapper); + + // prepare code part + String *action = emit_action(n); + marshalInputArgs(n, params, wrapper, Setter, is_member, is_static); + Append(wrapper->code, action); + + emitCleanupCode(n, wrapper, params); + + t_setter.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .pretty_print(f_wrappers); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +/* ----------------------------------------------------------------------------- + * JSEmitter::emitConstant() : triggers code generation for constants + * ----------------------------------------------------------------------------- */ + +int JSEmitter::emitConstant(Node *n) { + // HACK: somehow it happened under OSX that before everything started + // a lot of SWIG internal constants were emitted + // This didn't happen on other platforms yet... + // we ignore those premature definitions + if (!State::IsSet(state.global (HAS_TEMPLATES))) { + return SWIG_ERROR; + } + + Wrapper *wrapper = NewWrapper(); + SwigType *type = Getattr(n, "type"); + String *name = Getattr(n, "name"); + String *iname = Getattr(n, "sym:name"); + String *wname = Swig_name_wrapper(name); + String *rawval = Getattr(n, "rawval"); + String *value = rawval ? rawval : Getattr(n, "value"); + + Template t_getter(getTemplate("js_getter")); + + // call the variable methods as a constants are + // registred in same way + enterVariable(n); + state.variable(GETTER, wname); + // TODO: why do we need this? + Setattr(n, "wrap:name", wname); + + // special treatment of member pointers + if (SwigType_type(type) == T_MPOINTER) { + // TODO: this could go into a code-template + String *mpointer_wname = NewString(""); + Printf(mpointer_wname, "_wrapConstant_%s", iname); + Setattr(n, "memberpointer:constant:wrap:name", mpointer_wname); + String *str = SwigType_str(type, mpointer_wname); + Printf(f_wrappers, "static %s = %s;\n", str, value); + Delete(str); + value = mpointer_wname; + } + + marshalOutput(n, 0, wrapper, NewString(""), value, false); + + t_getter.replace("$jswrapper", wname) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .pretty_print(f_wrappers); + + exitVariable(n); + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) { + Wrapper *wrapper = NewWrapper(); + Template t_function(getTemplate("js_function")); + + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + // prepare the function wrapper name + String *iname = Getattr(n, "sym:name"); + String *wrap_name = Swig_name_wrapper(iname); + if (is_overloaded) { + t_function = getTemplate("js_overloaded_function"); + 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, wrapper); + emit_attach_parmmaps(params, wrapper); + + // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generates an extra line of applied typemap. + // Deleting wrapper->code here fixes the problem, and seems to have no side effect elsewhere + Delete(wrapper->code); + wrapper->code = NewString(""); + + marshalInputArgs(n, params, wrapper, Function, is_member, is_static); + String *action = emit_action(n); + + marshalOutput(n, params, wrapper, action); + + emitCleanupCode(n, wrapper, params); + + Replaceall(wrapper->code, "$symname", iname); + + t_function.replace("$jswrapper", wrap_name) + .replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code) + .replace("$jsargcount", Getattr(n, ARGCOUNT)) + .pretty_print(f_wrappers); + + + DelWrapper(wrapper); + + return SWIG_OK; +} + +int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) { + Wrapper *wrapper = NewWrapper(); + + // Generate call list, go to first node + Node *sibl = n; + + while (Getattr(sibl, "sym:previousSibling")) + sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up + + do { + String *siblname = Getattr(sibl, "wrap:name"); + + if (siblname) { + // handle function overloading + Template t_dispatch_case = getTemplate("js_function_dispatch_case"); + t_dispatch_case.replace("$jswrapper", siblname) + .replace("$jsargcount", Getattr(sibl, ARGCOUNT)); + + Append(wrapper->code, t_dispatch_case.str()); + } + + } while ((sibl = Getattr(sibl, "sym:nextSibling"))); + + Template t_function(getTemplate("js_function_dispatcher")); + + // Note: this dispatcher function gets called after the last overloaded function has been created. + // At this time, n.wrap:name contains the name of the last wrapper function. + // To get a valid function name for the dispatcher function we take the last wrapper name and + // substract the extension "sym:overname", + String *wrap_name = NewString(Getattr(n, "wrap:name")); + String *overname = Getattr(n, "sym:overname"); + int l1 = Len(wrap_name); + int l2 = Len(overname); + Delslice(wrap_name, l1 - l2, l1); + + Setattr(n, "wrap:name", wrap_name); + state.function(WRAPPER_NAME, wrap_name); + + t_function.replace("$jslocals", wrapper->locals) + .replace("$jscode", wrapper->code); + + // call this here, to replace all variables + t_function.replace("$jswrapper", wrap_name) + .replace("$jsname", state.function(NAME)) + .pretty_print(f_wrappers); + + // Delete the state variable + DelWrapper(wrapper); + + return SWIG_OK; +} + +String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) { + // Get input typemap for current param + String *tm = Getattr(p, "tmap:in"); + 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"); + } 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(type, 0)); + } + + return tm; +} + +void JSEmitter::marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult, bool emitReturnVariable) { + SwigType *type = Getattr(n, "type"); + String *tm; + Parm *p; + + // 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; + + tm = Swig_typemap_lookup_out("out", n, cresult, wrapper, actioncode); + bool should_own = GetFlag(n, "feature:new"); + + if (tm) { + Replaceall(tm, "$objecttype", Swig_scopename_last(SwigType_str(SwigType_strip_qualifiers(type), 0))); + + if (should_own) { + 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")); + } + + if (params) { + for (p = params; p;) { + if ((tm = Getattr(p, "tmap:argout"))) { + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:argout:next"); + } else { + p = nextSibling(p); + } + } + } + + Replaceall(wrapper->code, "$result", "jsresult"); +} + +void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) { + Parm *p; + String *tm; + + for (p = params; p;) { + if ((tm = Getattr(p, "tmap:freearg"))) { + //addThrows(n, "tmap:freearg", p); + Replaceall(tm, "$input", Getattr(p, "emit:input")); + Printv(wrapper->code, tm, "\n", NIL); + p = Getattr(p, "tmap:freearg:next"); + } else { + p = nextSibling(p); + } + } + + if (GetFlag(n, "feature:new")) { + tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0); + if (tm != NIL) { + //addThrows(throws_hash, "newfree", n); + Printv(wrapper->code, tm, "\n", NIL); + } + } + +} + +int JSEmitter::switchNamespace(Node *n) { + // HACK: somehow this gets called when member functions are processed...ignoring + if (GetFlag(n, "ismember")) { + return SWIG_OK; + } + + String *nspace = Getattr(n, "sym:nspace"); + + // if nspace is deactivated, everything goes into the global scope + if (!GetFlag(n, "feature:nspace")) { + current_namespace = Getattr(namespaces, "::"); + return SWIG_OK; + } + + if (nspace == NULL) { + // enums and constants do not have 'sym:nspace' set + // so we try to get the namespace from the qualified name + if (Equal(Getattr(n, "nodeType"), "enumitem")) { + nspace = Swig_scopename_prefix(Getattr(n, "name")); + } + } + + if (nspace == NULL) { + current_namespace = Getattr(namespaces, "::"); + return SWIG_OK; + } + + String *scope = NewString(nspace); + // replace "." with "::" that we can use Swig_scopename_last + Replaceall(scope, ".", "::"); + + // if the scope is not yet registered + // create (parent) namespaces recursively + if (!Getattr(namespaces, scope)) { + createNamespace(scope); + } + current_namespace = Getattr(namespaces, scope); + + 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; +} + +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 + **********************************************************************/ + +class JSCEmitter:public JSEmitter { + +public: + + JSCEmitter(); + + virtual ~ JSCEmitter(); + + virtual int initialize(Node *n); + + virtual int dump(Node *n); + + virtual int close(); + + +protected: + + virtual int enterVariable(Node *n); + + virtual int exitVariable(Node *n); + + virtual int enterFunction(Node *n); + + virtual int exitFunction(Node *n); + + virtual int enterClass(Node *n); + + virtual int exitClass(Node *n); + + virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); + + virtual Hash *createNamespaceEntry(const char *name, const char *parent); + + virtual int emitNamespaces(); + +private: + + String *NULL_STR; + String *VETO_SET; + + // output file and major code parts + File *f_wrap_cpp; + File *f_runtime; + File *f_header; + File *f_init; + +}; + +JSCEmitter::JSCEmitter() +: JSEmitter(), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), f_init(NULL) { +} + +JSCEmitter::~JSCEmitter() { + Delete(NULL_STR); + Delete(VETO_SET); +} + + +/* --------------------------------------------------------------------- + * marshalInputArgs() + * + * Process all of the arguments passed into the argv array + * and convert them into C/C++ function arguments using the + * supplied typemaps. + * --------------------------------------------------------------------- */ + +void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { + Parm *p; + String *tm; + + // determine an offset index, as members have an extra 'this' argument + // except: static members and ctors. + int startIdx = 0; + if (is_member && !is_static && mode != Ctor) { + 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); + + // process arguments + int i = 0; + for (p = parms; p; i++) { + String *arg = NewString(""); + String *type = Getattr(p, "type"); + + // ignore varargs + if (SwigType_isvarargs(type)) + break; + + switch (mode) { + case Getter: + case Function: + if (is_member && !is_static && i == 0) { + Printv(arg, "thisObject", 0); + } else { + Printf(arg, "argv[%d]", i - startIdx); + } + break; + case Setter: + if (is_member && !is_static && i == 0) { + Printv(arg, "thisObject", 0); + } else { + Printv(arg, "value", 0); + } + break; + case Ctor: + Printf(arg, "argv[%d]", i); + break; + default: + throw "Illegal state."; + } + tm = emitInputTypemap(n, p, wrapper, arg); + Delete(arg); + if (tm) { + p = Getattr(p, "tmap:in:next"); + } else { + p = nextSibling(p); + } + } +} + +int JSCEmitter::initialize(Node *n) { + + JSEmitter::initialize(n); + + /* Get the output file name */ + String *outfile = Getattr(n, "outfile"); + + /* Initialize I/O */ + f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files()); + if (!f_wrap_cpp) { + FileErrorDisplay(outfile); + SWIG_exit(EXIT_FAILURE); + } + + /* Initialization of members */ + f_runtime = NewString(""); + f_init = NewString(""); + f_header = NewString(""); + + state.global (CREATE_NAMESPACES, NewString("")); + state.global (REGISTER_NAMESPACES, NewString("")); + state.global (INITIALIZER, NewString("")); + + /* Register file targets with the SWIG file handler */ + Swig_register_filebyname("begin", f_wrap_cpp); + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrappers); + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("init", f_init); + + return SWIG_OK; +} + +int JSCEmitter::dump(Node *n) { + /* Get the module name */ + String *module = Getattr(n, "name"); + + // write the swig banner + Swig_banner(f_wrap_cpp); + + Template initializer_define(getTemplate("js_initializer_define")); + initializer_define.replace("$jsname", module).pretty_print(f_header); + + SwigType_emit_type_table(f_runtime, f_wrappers); + + Printv(f_wrap_cpp, f_runtime, "\n", 0); + Printv(f_wrap_cpp, f_header, "\n", 0); + Printv(f_wrap_cpp, f_wrappers, "\n", 0); + + emitNamespaces(); + + // compose the initializer function using a template + Template initializer(getTemplate("js_initializer")); + initializer.replace("$jsname", module) + .replace("$jsregisterclasses", state.global (INITIALIZER)) + .replace("$jscreatenamespaces", state.global (CREATE_NAMESPACES)) + .replace("$jsregisternamespaces", state.global (REGISTER_NAMESPACES)) + .pretty_print(f_init); + + Printv(f_wrap_cpp, f_init, 0); + + return SWIG_OK; +} + +int JSCEmitter::close() { + Delete(f_runtime); + Delete(f_header); + Delete(f_wrappers); + Delete(f_init); + Delete(namespaces); + Delete(f_wrap_cpp); + return SWIG_OK; +} + +int JSCEmitter::enterFunction(Node *n) { + + JSEmitter::enterFunction(n); + + return SWIG_OK; +} + +int JSCEmitter::exitFunction(Node *n) { + Template t_function = getTemplate("jsc_function_declaration"); + + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); + bool is_overloaded = GetFlag(n, "sym:overloaded"); + + // handle overloaded functions + if (is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); + // create dispatcher + emitFunctionDispatcher(n, is_member); + } else { + //don't register wrappers of overloaded functions in function tables + return SWIG_OK; + } + } + + t_function.replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)); + + if (is_member) { + if (GetFlag(state.function(), IS_STATIC)) { + Append(state.clazz(STATIC_FUNCTIONS), t_function.str()); + } else { + Append(state.clazz(MEMBER_FUNCTIONS), t_function.str()); + } + } else { + Append(Getattr(current_namespace, "functions"), t_function.str()); + } + + return SWIG_OK; +} + +int JSCEmitter::enterVariable(Node *n) { + JSEmitter::enterVariable(n); + state.variable(GETTER, NULL_STR); + state.variable(SETTER, VETO_SET); + return SWIG_OK; +} + + +int JSCEmitter::exitVariable(Node *n) { + Template t_variable(getTemplate("jsc_variable_declaration")); + t_variable.replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)); + + if (GetFlag(n, "ismember")) { + if (GetFlag(state.variable(), IS_STATIC) + || Equal(Getattr(n, "nodeType"), "enumitem")) { + Append(state.clazz(STATIC_VARIABLES), t_variable.str()); + } else { + Append(state.clazz(MEMBER_VARIABLES), t_variable.str()); + } + } else { + Append(Getattr(current_namespace, "values"), t_variable.str()); + } + + return SWIG_OK; +} + +int JSCEmitter::enterClass(Node *n) { + JSEmitter::enterClass(n); + state.clazz(MEMBER_VARIABLES, NewString("")); + state.clazz(MEMBER_FUNCTIONS, NewString("")); + state.clazz(STATIC_VARIABLES, NewString("")); + state.clazz(STATIC_FUNCTIONS, NewString("")); + + Template t_class_decl = getTemplate("jsc_class_declaration"); + t_class_decl.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .pretty_print(f_wrappers); + + return SWIG_OK; +} + +int JSCEmitter::exitClass(Node *n) { + Template t_class_tables(getTemplate("jsc_class_tables")); + t_class_tables.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsclassvariables", state.clazz(MEMBER_VARIABLES)) + .replace("$jsclassfunctions", state.clazz(MEMBER_FUNCTIONS)) + .replace("$jsstaticclassfunctions", state.clazz(STATIC_FUNCTIONS)) + .replace("$jsstaticclassvariables", state.clazz(STATIC_VARIABLES)) + .pretty_print(f_wrappers); + + /* adds the ctor wrappers at this position */ + // Note: this is necessary to avoid extra forward declarations. + //Append(f_wrappers, state.clazz(CTOR_WRAPPERS)); + + // for abstract classes add a vetoing ctor + if (GetFlag(state.clazz(), IS_ABSTRACT)) { + Template t_veto_ctor(getTemplate("js_veto_ctor")); + t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) + .replace("$jsname", state.clazz(NAME)) + .pretty_print(f_wrappers); + } + + /* adds a class template statement to initializer function */ + Template t_classtemplate(getTemplate("jsc_class_definition")); + + /* prepare registration of base class */ + String *jsclass_inheritance = NewString(""); + Node *base_class = getBaseClass(n); + if (base_class != NULL) { + Template t_inherit(getTemplate("jsc_class_inherit")); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsbaseclassmangled", SwigType_manglestr(Getattr(base_class, "name"))) + .pretty_print(jsclass_inheritance); + } else { + Template t_inherit(getTemplate("jsc_class_noinherit")); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .pretty_print(jsclass_inheritance); + } + + t_classtemplate.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jsclass_inheritance", jsclass_inheritance) + .replace("$jsctor", state.clazz(CTOR)) + .replace("$jsdtor", state.clazz(DTOR)) + .pretty_print(state.global (INITIALIZER)); + Delete(jsclass_inheritance); + + /* Note: this makes sure that there is a swig_type added for this class */ + SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); + + /* adds a class registration statement to initializer function */ + Template t_registerclass(getTemplate("jsc_class_registration")); + t_registerclass.replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED)) + .pretty_print(state.global (INITIALIZER)); + + return SWIG_OK; +} + +Hash *JSCEmitter::createNamespaceEntry(const char *name, const char *parent) { + Hash *entry = JSEmitter::createNamespaceEntry(name, parent); + Setattr(entry, "functions", NewString("")); + Setattr(entry, "values", NewString("")); + return entry; +} + +int JSCEmitter::emitNamespaces() { + Iterator it; + for (it = First(namespaces); it.item; it = Next(it)) { + Hash *entry = it.item; + String *name = Getattr(entry, NAME); + String *name_mangled = Getattr(entry, NAME_MANGLED); + String *parent = Getattr(entry, PARENT); + String *parent_mangled = Swig_name_mangle(parent); + String *functions = Getattr(entry, "functions"); + String *variables = Getattr(entry, "values"); + + // skip the global namespace which is given by the application + + Template namespace_definition(getTemplate("jsc_nspace_declaration")); + namespace_definition.replace("$jsglobalvariables", variables) + .replace("$jsglobalfunctions", functions) + .replace("$jsnspace", name_mangled) + .pretty_print(f_wrap_cpp); + + Template t_createNamespace(getTemplate("jsc_nspace_definition")); + t_createNamespace.replace("$jsmangledname", name_mangled); + Append(state.global (CREATE_NAMESPACES), t_createNamespace.str()); + + // Don't register 'exports' as namespace. It is return to the application. + if (!Equal("exports", name)) { + Template t_registerNamespace(getTemplate("jsc_nspace_registration")); + t_registerNamespace.replace("$jsmangledname", name_mangled) + .replace("$jsname", name) + .replace("$jsparent", parent_mangled); + Append(state.global (REGISTER_NAMESPACES), t_registerNamespace.str()); + } + + } + + return SWIG_OK; +} + +JSEmitter *swig_javascript_create_JSCEmitter() { + return new JSCEmitter(); +} + +/********************************************************************** + * V8: JSEmitter implementation for V8 engine + **********************************************************************/ + +class V8Emitter:public JSEmitter { + +public: + + V8Emitter(); + + virtual ~ V8Emitter(); + virtual int initialize(Node *n); + virtual int dump(Node *n); + virtual int close(); + virtual int enterClass(Node *n); + virtual int exitClass(Node *n); + virtual int enterVariable(Node *n); + virtual int exitVariable(Node *n); + virtual int exitFunction(Node *n); + +protected: + + virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static); + virtual int emitNamespaces(); + +private: + + /* built-in parts */ + String *f_runtime; + String *f_header; + String *f_init; + String *f_post_init; + + /* part for class templates */ + String *f_class_templates; + + /* parts for initilizer */ + String *f_init_namespaces; + String *f_init_class_templates; + String *f_init_wrappers; + String *f_init_inheritance; + String *f_init_class_instances; + String *f_init_static_wrappers; + String *f_init_register_classes; + String *f_init_register_namespaces; + + // the output cpp file + File *f_wrap_cpp; + + String *NULL_STR; + String *VETO_SET; + String *moduleName; + +}; + +V8Emitter::V8Emitter() +: JSEmitter(), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) { +} + +V8Emitter::~V8Emitter() { + Delete(NULL_STR); + Delete(VETO_SET); +} + +int V8Emitter::initialize(Node *n) { + JSEmitter::initialize(n); + + moduleName = Getattr(n, "name"); + + // 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_init = NewString(""); + f_post_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("begin", f_wrap_cpp); + Swig_register_filebyname("runtime", f_runtime); + Swig_register_filebyname("header", f_header); + Swig_register_filebyname("wrapper", f_wrappers); + Swig_register_filebyname("init", f_init); + Swig_register_filebyname("post-init", f_post_init); + + return SWIG_OK; +} + +int V8Emitter::dump(Node *n) { + /* Get the module name */ + String *module = Getattr(n, "name"); + + // write the swig banner + Swig_banner(f_wrap_cpp); + + Template initializer_define(getTemplate("js_initializer_define")); + initializer_define.replace("$jsname", module).pretty_print(f_header); + + SwigType_emit_type_table(f_runtime, f_wrappers); + + 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_wrappers, "\n", 0); + + emitNamespaces(); + + // compose the initializer function using a template + // filled with sub-parts + Template initializer(getTemplate("js_initializer")); + initializer.replace("$jsname", moduleName) + .replace("$jsv8nspaces", f_init_namespaces) + .replace("$jsv8classtemplates", f_init_class_templates) + .replace("$jsv8wrappers", f_init_wrappers) + .replace("$jsv8inheritance", f_init_inheritance) + .replace("$jsv8classinstances", f_init_class_instances) + .replace("$jsv8staticwrappers", f_init_static_wrappers) + .replace("$jsv8registerclasses", f_init_register_classes) + .replace("$jsv8registernspaces", f_init_register_namespaces); + Printv(f_init, initializer.str(), 0); + + Printv(f_wrap_cpp, f_init, 0); + + Printv(f_wrap_cpp, f_post_init, 0); + + return SWIG_OK; +} + +int V8Emitter::close() { + Delete(f_runtime); + Delete(f_header); + Delete(f_class_templates); + 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); + Delete(f_init); + Delete(f_post_init); + Delete(f_wrap_cpp); + return SWIG_OK; +} + +int V8Emitter::enterClass(Node *n) { + JSEmitter::enterClass(n); + + // emit declaration of a v8 class template + Template t_decl_class(getTemplate("jsv8_declare_class_template")); + t_decl_class.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .trim() + .pretty_print(f_class_templates); + + return SWIG_OK; +} + +int V8Emitter::exitClass(Node *n) { + if (GetFlag(state.clazz(), IS_ABSTRACT)) { + Template t_veto_ctor(getTemplate("js_veto_ctor")); + t_veto_ctor.replace("$jswrapper", state.clazz(CTOR)) + .replace("$jsname", state.clazz(NAME)) + .pretty_print(f_wrappers); + } + + /* Note: this makes sure that there is a swig_type added for this class */ + String *clientData = NewString(""); + Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED)); + + /* Note: this makes sure that there is a swig_type added for this class */ + SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0")); + + // emit definition of v8 class template + Template t_def_class = getTemplate("jsv8_define_class_template"); + t_def_class.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledtype", state.clazz(TYPE_MANGLED)) + .replace("$jsdtor", state.clazz(DTOR)) + .trim() + .pretty_print(f_init_class_templates); + + Template t_class_instance = getTemplate("jsv8_create_class_instance"); + t_class_instance.replace("$jsname", state.clazz(NAME)) + .replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsctor", state.clazz(CTOR)) + .trim() + .pretty_print(f_init_class_instances); + + // emit inheritance setup + Node *baseClass = getBaseClass(n); + if (baseClass) { + String *base_name = Getattr(baseClass, "name"); + + Template t_inherit = getTemplate("jsv8_inherit"); + + String *base_name_mangled = SwigType_manglestr(base_name); + t_inherit.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsbaseclass", 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"); + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.clazz(NAME)) + .replace("$jsparent", Getattr(state.clazz("nspace"), NAME_MANGLED)) + .trim() + .pretty_print(f_init_register_classes); + + return SWIG_OK; +} + +int V8Emitter::enterVariable(Node *n) { + JSEmitter::enterVariable(n); + + state.variable(GETTER, NULL_STR); + state.variable(SETTER, VETO_SET); + + return SWIG_OK; +} + +int V8Emitter::exitVariable(Node *n) { + if (GetFlag(n, "ismember")) { + if (GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) { + Template t_register = getTemplate("jsv8_register_static_variable"); + t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim().print(f_init_static_wrappers); + } else { + Template t_register = getTemplate("jsv8_register_member_variable"); + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim() + .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"); + t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED)) + .replace("$jsname", state.variable(NAME)) + .replace("$jsgetter", state.variable(GETTER)) + .replace("$jssetter", state.variable(SETTER)) + .trim() + .print(f_init_wrappers); + } + + return SWIG_OK; +} + +int V8Emitter::exitFunction(Node *n) { + bool is_member = GetFlag(n, "ismember") | GetFlag(n, "feature:extend"); + + // create a dispatcher for overloaded functions + bool is_overloaded = GetFlag(n, "sym:overloaded"); + if (is_overloaded) { + if (!Getattr(n, "sym:nextSibling")) { + //state.function(WRAPPER_NAME, Swig_name_wrapper(Getattr(n, "name"))); + emitFunctionDispatcher(n, is_member); + } else { + //don't register wrappers of overloaded functions in function tables + return SWIG_OK; + } + } + // register the function at the specific context + if (is_member) { + if (GetFlag(state.function(), IS_STATIC)) { + Template t_register = getTemplate("jsv8_register_static_function"); + t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .print(f_init_static_wrappers); + } else { + Template t_register = getTemplate("jsv8_register_member_function"); + t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .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"); + t_register.replace("$jsparent", Getattr(current_namespace, NAME)) + .replace("$jsname", state.function(NAME)) + .replace("$jswrapper", state.function(WRAPPER_NAME)) + .trim() + .pretty_print(f_init_static_wrappers); + } + + return SWIG_OK; +} + +void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { + Parm *p; + String *tm; + + int startIdx = 0; + if (is_member && !is_static && mode != Ctor) { + 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; i++) { + String *arg = NewString(""); + String *type = Getattr(p, "type"); + + // ignore varargs + if (SwigType_isvarargs(type)) + break; + + switch (mode) { + case Getter: + if (is_member && !is_static && i == 0) { + Printv(arg, "info.Holder()", 0); + } else { + Printf(arg, "args[%d]", i - startIdx); + } + break; + case Function: + if (is_member && !is_static && i == 0) { + Printv(arg, "args.Holder()", 0); + } else { + Printf(arg, "args[%d]", i - startIdx); + } + break; + case Setter: + if (is_member && !is_static && i == 0) { + Printv(arg, "info.Holder()", 0); + } else { + Printv(arg, "value", 0); + } + break; + case Ctor: + Printf(arg, "args[%d]", i); + break; + default: + throw "Illegal state."; + } + + tm = emitInputTypemap(n, p, wrapper, arg); + Delete(arg); + + if (tm) { + p = Getattr(p, "tmap:in:next"); + } else { + p = nextSibling(p); + } + } +} + +int V8Emitter::emitNamespaces() { + Iterator it; + for (it = First(namespaces); it.item; it = Next(it)) { + Hash *entry = it.item; + String *name = Getattr(entry, NAME); + String *name_mangled = Getattr(entry, NAME_MANGLED); + String *parent = Getattr(entry, PARENT); + String *parent_mangled = Swig_name_mangle(parent); + + bool do_create = true; + bool do_register = true; + + if (Equal(parent, "")) { + do_register = false; + } + // Note: 'exports' is by convention the name of the object where + // globals are stored into + if (Equal(name, "exports")) { + do_create = false; + } + + if (do_create) { + // create namespace object and register it to the parent scope + Template t_create_ns = getTemplate("jsv8_create_namespace"); + t_create_ns.replace("$jsmangledname", name_mangled) + .trim() + .pretty_print(f_init_namespaces); + } + + if (do_register) { + Template t_register_ns = getTemplate("jsv8_register_namespace"); + t_register_ns.replace("$jsmangledname", name_mangled) + .replace("$jsname", name) + .replace("$jsparent", parent_mangled) + .trim(); + + // prepend in order to achieve reversed order of registration statements + Insert(f_init_register_namespaces, 0, t_register_ns.str()); + } + } + + return SWIG_OK; +} + +JSEmitter *swig_javascript_create_V8Emitter() { + return new V8Emitter(); +} + + +/********************************************************************** + * Helper implementations + **********************************************************************/ + +JSEmitterState::JSEmitterState() +: _global(NewHash()) { + // initialize sub-hashes + Setattr(_global, "class", NewHash()); + Setattr(_global, "function", NewHash()); + Setattr(_global, "variable", NewHash()); +} + +JSEmitterState::~JSEmitterState() { + Delete(_global); +} + +DOH *JSEmitterState::getState(const char *key, bool _new) { + if (_new) { + Hash *hash = NewHash(); + Setattr(_global, key, hash); + } + return Getattr(_global, key); +} + +DOH *JSEmitterState::global () { + return _global; +} + +DOH *JSEmitterState::global (const char *key, DOH *initial) { + if (initial != 0) { + Setattr(_global, key, initial); + } + return Getattr(_global, key); +} + +DOH *JSEmitterState::clazz(bool _new) { + return getState("class", _new); +} + +DOH *JSEmitterState::clazz(const char *key, DOH *initial) { + DOH *c = clazz(); + if (initial != 0) { + Setattr(c, key, initial); + } + return Getattr(c, key); +} + +DOH *JSEmitterState::function(bool _new) { + return getState("function", _new); +} + +DOH *JSEmitterState::function(const char *key, DOH *initial) { + DOH *f = function(); + if (initial != 0) { + Setattr(f, key, initial); + } + return Getattr(f, key); +} + +DOH *JSEmitterState::variable(bool _new) { + return getState("variable", _new); +} + +DOH *JSEmitterState::variable(const char *key, DOH *initial) { + DOH *v = variable(); + if (initial != 0) { + Setattr(v, key, initial); + } + return Getattr(v, key); +} + +/*static*/ +int JSEmitterState::IsSet(DOH *val) { + if (!val) { + return 0; + } else { + const char *cval = Char(val); + if (!cval) + return 0; + return (strcmp(cval, "0") != 0) ? 1 : 0; + } +} + +/* ----------------------------------------------------------------------------- + * Template::Template() : creates a Template class for given template code + * ----------------------------------------------------------------------------- */ + +Template::Template(const String *code_) { + + if (!code_) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + code = NewString(code_); + templateName = NewString(""); +} + +Template::Template(const String *code_, const String *templateName_) { + + if (!code_) { + Printf(stdout, "Template code was null. Illegal input for template."); + SWIG_exit(EXIT_FAILURE); + } + + code = NewString(code_); + templateName = NewString(templateName_); +} + + +/* ----------------------------------------------------------------------------- + * Template::~Template() : cleans up of Template. + * ----------------------------------------------------------------------------- */ + +Template::~Template() { + Delete(code); + Delete(templateName); +} + +/* ----------------------------------------------------------------------------- + * String* Template::str() : retrieves the current content of the template. + * ----------------------------------------------------------------------------- */ + +String *Template::str() { + if (js_template_enable_debug) { + String *pre_code = NewString(""); + String *post_code = NewString(""); + String *debug_code = NewString(""); + Printf(pre_code, "/* begin fragment(\"%s\") */", templateName); + Printf(post_code, "/* end fragment(\"%s\") */", templateName); + Printf(debug_code, "%s\n%s\n%s\n", pre_code, code, post_code); + + Delete(code); + Delete(pre_code); + Delete(post_code); + + code = debug_code; + } + return code; +} + +Template & Template::trim() { + const char *str = Char(code); + if (str == 0) + return *this; + + int length = Len(code); + 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') + 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') + break; + } + int end_pos = idx; + + int new_length = end_pos - start_pos + 1; + char *newstr = new char[new_length + 1]; + memcpy(newstr, str + start_pos, new_length); + newstr[new_length] = 0; + + Delete(code); + code = NewString(newstr); + delete[]newstr; + + return *this; +} + +/* ----------------------------------------------------------------------------- + * Template& Template::replace(const String* pattern, const String* repl) : + * + * replaces all occurences of a given pattern with a given replacement. + * + * - pattern: the pattern to be replaced + * - repl: the replacement string + * - returns a reference to the Template to allow chaining of methods. + * ----------------------------------------------------------------------------- */ + +Template & Template::replace(const String *pattern, const String *repl) { + Replaceall(code, pattern, repl); + return *this; +} + +Template & Template::print(DOH *doh) { + Printv(doh, str(), 0); + return *this; +} + +Template & Template::pretty_print(DOH *doh) { + Wrapper_pretty_print(str(), doh); + return *this; +} + +Template::Template(const Template & t) { + code = NewString(t.code); + templateName = NewString(t.templateName); +} + +void Template::operator=(const Template & t) { + Delete(code); + Delete(templateName); + code = NewString(t.code); + templateName = NewString(t.templateName); +} diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 7c9cded70..97b21710a 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -51,6 +51,7 @@ extern "C" { Language *swig_r(void); Language *swig_go(void); Language *swig_d(void); + Language *swig_javascript(void); } struct swig_module { @@ -92,6 +93,7 @@ static swig_module modules[] = { {"-tcl8", swig_tcl, 0}, {"-uffi", swig_uffi, "Common Lisp / UFFI"}, {"-xml", swig_xml, "XML"}, + {"-javascript", swig_javascript, "Javascript"}, {NULL, NULL, NULL} }; diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in new file mode 100644 index 000000000..d58412b50 --- /dev/null +++ b/Tools/javascript/Makefile.in @@ -0,0 +1,58 @@ +# ---------------------------------------------------------------- +# Compile a custom javascript interpreter +# ---------------------------------------------------------------- +# +# Note: +# There is no common CLI Javascript interpreter. +# V8 comes with one 'd8' which however does not provide a means +# to load extensions. Therefore, by default we use nodejs as +# environment. +# For testing native v8 and jsc extensions we provide our own +# interpreter (see 'Tools/javascript'). +# +# ---------------------------------------------------------------- +CC = @CC@ +# HACK: under OSX a g++ compiled interpreter is seg-faulting when loading module libraries +# with 'c++' it works... probably some missing flags? +JSCXX = @JSINTERPRETERCXX@ +CFLAGS = @PLATCFLAGS@ +CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ +LINKFLAGS = @JSINTERPRETERLINKFLAGS@ + +ROOT_DIR = @ROOT_DIR@ +JSCFLAGS = @JSCFLAGS@ +JSCXXFLAGS = @JSCXXFLAGS@ +JSINCLUDES = @JSCOREINC@ @JSV8INC@ +JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ +JSLIBRARYPREFIX = @JSLIBRARYPREFIX@ +JSSO =@JSSO@ +JSLDSHARED = @JSLDSHARED@ +JSCXXSHARED = @JSCXXSHARED@ +JSV8ENABLED = @JSV8ENABLED@ +JSCENABLED = @JSCENABLED@ + +# These settings are provided by 'configure' (see '/configure.in') +ifeq (1, $(JSV8ENABLED)) + JS_INTERPRETER_SRC_V8 = v8_shell.cxx + JS_INTERPRETER_ENABLE_V8 = -DENABLE_V8 +endif + +ifeq (1, $(JSCENABLED)) + JS_INTERPRETER_SRC_JSC = jsc_shell.cxx + JS_INTERPRETER_ENABLE_JSC = -DENABLE_JSC +endif + +JS_INTERPRETER_DEFINES = $(JS_INTERPRETER_ENABLE_JSC) $(JS_INTERPRETER_ENABLE_V8) +JS_INTERPRETER_SRC = javascript.cxx js_shell.cxx $(JS_INTERPRETER_SRC_JSC) $(JS_INTERPRETER_SRC_V8) + +JS_INTERPRETER_OBJS = $(JS_INTERPRETER_SRC:.cxx=.o) + +%.o: %.cxx + $(JSCXX) $(JS_INTERPRETER_DEFINES) $(CXXFLAGS) $(JSINCLUDES) -o $@ -c $< + +javascript: $(JS_INTERPRETER_OBJS) + $(JSCXX) $^ $(CXXFLAGS) -o javascript $(JSDYNAMICLINKING) $(LINKFLAGS) + +clean: + rm -f *.o + rm -f javascript diff --git a/Tools/javascript/javascript.cxx b/Tools/javascript/javascript.cxx new file mode 100644 index 000000000..5e7cc0b20 --- /dev/null +++ b/Tools/javascript/javascript.cxx @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include +#include + +#include "js_shell.h" + +void print_usage() { + std::cout << "javascript [-i] [-jsc|-v8] [-l module] " << std::endl; +} + +int main(int argc, char* argv[]) { + +#if defined(JAVASCRIPT_INTERPRETER_STOP) + std::cout << "Attach your Debugger and press any key to continue" << std::endl; + std::cin.get(); +#endif + + std::string scriptPath = ""; + + bool interactive = false; + JSShell* shell = 0; + + std::vector modulePath; + modulePath.push_back("."); + + for (int idx = 1; idx < argc; ++idx) { + if(strcmp(argv[idx], "-v8") == 0) { + shell = JSShell::Create(JSShell::V8); + } else if(strcmp(argv[idx], "-jsc") == 0) { + shell = JSShell::Create(JSShell::JSC); + } else if(strcmp(argv[idx], "-i") == 0) { + interactive = true; + } else if(strcmp(argv[idx], "-L") == 0) { + modulePath.push_back(argv[++idx]); + } else { + scriptPath = argv[idx]; + } + } + + if (shell == 0) { + shell = JSShell::Create(); + } + + shell->setModulePath(modulePath); + + bool failed = false; + + if(interactive) { + failed = !(shell->RunShell()); + } else { + failed = !(shell->RunScript(scriptPath)); + } + + if (failed) { + delete shell; + printf("FAIL: Error during execution of script.\n"); + return 1; + } + + delete shell; + + return 0; +} diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx new file mode 100644 index 000000000..539b83d65 --- /dev/null +++ b/Tools/javascript/js_shell.cxx @@ -0,0 +1,156 @@ +#include "js_shell.h" + +#include +#include +#include +#include +#include + +#ifdef __GNUC__ +#ifdef __APPLE__ +#define LIBRARY_EXT ".bundle" +#else +#define LIBRARY_EXT ".so" +#endif +#include +#define LOAD_LIBRARY(name) dlopen(name, RTLD_LAZY) +#define CLOSE_LIBRARY(handle) dlclose(handle) +#define LIBRARY_ERROR dlerror +#define LIBRARYFILE(name) std::string("lib").append(name).append(LIBRARY_EXT) +#else +#error "implement dll loading" +#endif + + +JSShell::~JSShell() { + + for(std::vector::iterator it = loaded_modules.begin(); + it != loaded_modules.end(); ++it) { + HANDLE handle = *it; + CLOSE_LIBRARY(handle); + } + +} + +// TODO: this could be done more intelligent... +// - can we achieve source file relative loading? +// - better path resolution +std::string JSShell::LoadModule(const std::string& name, HANDLE* library) { + + // works only for posix like OSs + size_t pathIdx = name.find_last_of("/"); + + std::string lib_name; + std::string module_name; + + if (pathIdx == std::string::npos) { + module_name = name; + lib_name = std::string(name).append(LIBRARY_EXT); + } else { + std::string path = name.substr(0, pathIdx+1); + module_name = name.substr(pathIdx+1); + lib_name = path.append(module_name).append(LIBRARY_EXT); + } + + std::string lib_path; + HANDLE handle = 0; + + for (int i = 0; i < module_path.size(); ++i) { + lib_path = module_path[i] + "/" + lib_name; + if (access( lib_path.c_str(), F_OK ) != -1) { + handle = LOAD_LIBRARY(lib_path.c_str()); + } + } + + if(handle == 0) { + std::cerr << "Could not find module " << lib_path << ":" + << std::endl << LIBRARY_ERROR() << std::endl; + return 0; + } + + loaded_modules.push_back(handle); + + *library = handle; + + return module_name; +} + +bool JSShell::RunScript(const std::string& scriptPath) { + std::string source = ReadFile(scriptPath); + if(!InitializeEngine()) return false; + + // Node.js compatibility: make `print` available as `console.log()` + ExecuteScript("var console = {}; console.log = print;", ""); + + if(!ExecuteScript(source, scriptPath)) { + return false; + } + + return DisposeEngine(); +} + +bool JSShell::RunShell() { + + if(!InitializeEngine()) return false; + + static const int kBufferSize = 1024; + while (true) { + char buffer[kBufferSize]; + printf("> "); + char* str = fgets(buffer, kBufferSize, stdin); + if (str == NULL) break; + std::string source(str); + ExecuteScript(source, "(shell)"); + } + printf("\n"); + return true; +} + +std::string JSShell::ReadFile(const std::string& fileName) +{ + std::string script; + + std::ifstream file(fileName.c_str()); + if (file.is_open()) { + while ( file.good() ) { + std::string line; + getline(file, line); + script.append(line); + script.append("\n"); + } + file.close(); + } else { + std::cout << "Unable to open file " << fileName << "." << std::endl; + } + + return script; +} + +#ifdef ENABLE_JSC +extern JSShell* JSCShell_Create(); +#endif +#ifdef ENABLE_V8 +extern JSShell* V8Shell_Create(); +#endif + +typedef JSShell*(*ShellFactory)(); + +static ShellFactory js_shell_factories[2] = { +#ifdef ENABLE_JSC +JSCShell_Create, +#else +0, +#endif +#ifdef ENABLE_V8 +V8Shell_Create, +#else +0, +#endif +}; + +JSShell *JSShell::Create(Engine engine) { + if(js_shell_factories[engine] == 0) { + throw "Engine not available."; + } + return js_shell_factories[engine](); +} diff --git a/Tools/javascript/js_shell.h b/Tools/javascript/js_shell.h new file mode 100644 index 000000000..1e2466b96 --- /dev/null +++ b/Tools/javascript/js_shell.h @@ -0,0 +1,53 @@ +#ifndef JS_SHELL_H +#define JS_SHELL_H + +#include +#include + +typedef void* HANDLE; +typedef void* MODULE; + +class JSShell { + +public: + enum Engine { + JSC = 0, + V8 + }; + +public: + + JSShell() {} + + virtual ~JSShell() = 0; + + static JSShell* Create(Engine engine = JSC); + + std::string LoadModule(const std::string& name, HANDLE* library); + + virtual bool RunScript(const std::string& scriptPath); + + virtual bool RunShell(); + + void setModulePath(const std::vector& modulePath) { + module_path = modulePath; + } + +protected: + + virtual bool InitializeEngine() = 0; + + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath) = 0; + + virtual bool DisposeEngine() = 0; + + static std::string ReadFile(const std::string& fileName); + +protected: + + std::vector loaded_modules; + std::vector module_path; + +}; + +#endif // JS_SHELL_H diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx new file mode 100644 index 000000000..292c4042b --- /dev/null +++ b/Tools/javascript/jsc_shell.cxx @@ -0,0 +1,233 @@ +#include + +#include "js_shell.h" + +#include +#include + +#ifdef __GNUC__ +#include +#define LOAD_SYMBOL(handle, name) dlsym(handle, name) +#else +#error "implement dll loading" +#endif + +class JSCShell: public JSShell { + +typedef int (*JSCIntializer)(JSGlobalContextRef context, JSObjectRef *module); + +public: + + JSCShell() {}; + + virtual ~JSCShell(); + +protected: + + virtual bool InitializeEngine(); + + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath); + + virtual bool DisposeEngine(); + +private: + + JSObjectRef Import(const std::string &moduleName); + + static JSValueRef Print(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + + static JSValueRef Require(JSContextRef context, JSObjectRef object, JSObjectRef globalobj, size_t argc, const JSValueRef args[], JSValueRef* ex); + + static bool RegisterFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback cbFunction); + + static void PrintError(JSContextRef, JSValueRef); + +private: + + JSGlobalContextRef context; +}; + +JSCShell::~JSCShell() { + if(context != 0) { + JSGlobalContextRelease(context); + context = 0; + } +} + +bool JSCShell::InitializeEngine() { + if(context != 0) { + JSGlobalContextRelease(context); + context = 0; + } + // TODO: check for initialization errors + context = JSGlobalContextCreate(NULL); + if(context == 0) return false; + JSObjectRef globalObject = JSContextGetGlobalObject(context); + + // store this for later use + JSClassDefinition __shell_classdef__ = JSClassDefinition(); + + JSClassRef __shell_class__ = JSClassCreate(&__shell_classdef__); + JSObjectRef __shell__ = JSObjectMake(context, __shell_class__, 0); + bool success = JSObjectSetPrivate(__shell__, (void*) (long) this); + if (!success) { + std::cerr << "Could not register the shell in the Javascript context" << std::endl; + return false; + } + JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__"); + JSObjectSetProperty(context, globalObject, shellKey, __shell__, kJSPropertyAttributeReadOnly, NULL); + JSStringRelease(shellKey); + + JSCShell::RegisterFunction(context, globalObject, "print", JSCShell::Print); + JSCShell::RegisterFunction(context, globalObject, "require", JSCShell::Require); + + return true; +} + +bool JSCShell::ExecuteScript(const std::string& source, const std::string& scriptPath) { + JSStringRef jsScript; + JSStringRef sourceURL; + JSValueRef ex; + jsScript = JSStringCreateWithUTF8CString(source.c_str()); + sourceURL = JSStringCreateWithUTF8CString(scriptPath.c_str()); + JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, sourceURL, 0, &ex); + JSStringRelease(jsScript); + if (jsResult == NULL && ex != NULL) { + JSCShell::PrintError(context, ex); + return false; + } + return true; +} + +bool JSCShell::DisposeEngine() { + JSGlobalContextRelease(context); + context = 0; + return true; +} + +JSValueRef JSCShell::Print(JSContextRef context, JSObjectRef object, + JSObjectRef globalobj, size_t argc, + const JSValueRef args[], JSValueRef* ex) { + if (argc > 0) + { + JSStringRef string = JSValueToStringCopy(context, args[0], NULL); + size_t numChars = JSStringGetMaximumUTF8CStringSize(string); + char *stringUTF8 = new char[numChars]; + JSStringGetUTF8CString(string, stringUTF8, numChars); + printf("%s\n", stringUTF8); + + delete[] stringUTF8; + } + + return JSValueMakeUndefined(context); +} + +// Attention: this feature should not create too high expectations. +// It is only capable of loading things relative to the execution directory +// and not relative to the parent script. +JSValueRef JSCShell::Require(JSContextRef context, JSObjectRef object, + JSObjectRef globalObj, size_t argc, + const JSValueRef args[], JSValueRef* ex) { + JSObjectRef module; + + JSStringRef shellKey = JSStringCreateWithUTF8CString("__shell__"); + JSValueRef shellAsVal = JSObjectGetProperty(context, globalObj, shellKey, NULL); + JSStringRelease(shellKey); + JSObjectRef shell = JSValueToObject(context, shellAsVal, 0); + JSCShell *_this = (JSCShell*) (long) JSObjectGetPrivate(shell); + + if (argc > 0) + { + JSStringRef string = JSValueToStringCopy(context, args[0], NULL); + size_t numChars = JSStringGetMaximumUTF8CStringSize(string); + char *stringUTF8 = new char[numChars]; + JSStringGetUTF8CString(string, stringUTF8, numChars); + + std::string modulePath(stringUTF8); + module = _this->Import(modulePath); + + delete[] stringUTF8; + } + + if (module) { + return module; + } else { + printf("Ooops.\n"); + return JSValueMakeUndefined(context); + } +} + +JSObjectRef JSCShell::Import(const std::string& module_path) { + + HANDLE library; + std::string module_name = LoadModule(module_path, &library); + + if (library == 0) { + printf("Could not load module."); + return 0; + } + + std::string symname = std::string(module_name).append("_initialize"); + + JSCIntializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); + if(init_function == 0) { + printf("Could not find module's initializer function."); + return 0; + } + + JSObjectRef module; + init_function(context, &module); + + return module; +} + +bool JSCShell::RegisterFunction(JSGlobalContextRef context, JSObjectRef object, + const char* functionName, JSObjectCallAsFunctionCallback callback) { + JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); + JSObjectSetProperty(context, object, js_functionName, + JSObjectMakeFunctionWithCallback(context, js_functionName, callback), + kJSPropertyAttributeNone, NULL); + JSStringRelease(js_functionName); + return true; +} + +void JSCShell::PrintError(JSContextRef ctx, JSValueRef err) { + char *buffer; + size_t length; + + JSStringRef string = JSValueToStringCopy(ctx, err, 0); + length = JSStringGetLength(string); + buffer = new char[length+1]; + JSStringGetUTF8CString(string, buffer, length+1); + std::string errMsg(buffer); + JSStringRelease(string); + delete[] buffer; + + JSObjectRef errObj = JSValueToObject(ctx, err, 0); + + if(errObj == 0) { + std::cerr << errMsg << std::endl; + return; + } + + JSStringRef sourceURLKey = JSStringCreateWithUTF8CString("sourceURL"); + JSStringRef sourceURLStr = JSValueToStringCopy(ctx, JSObjectGetProperty(ctx, errObj, sourceURLKey, 0), 0); + length = JSStringGetLength(sourceURLStr); + buffer = new char[length+1]; + JSStringGetUTF8CString(sourceURLStr, buffer, length+1); + std::string sourceURL(buffer); + delete[] buffer; + JSStringRelease(sourceURLStr); + JSStringRelease(sourceURLKey); + + JSStringRef lineKey = JSStringCreateWithUTF8CString("line"); + JSValueRef jsLine = JSObjectGetProperty(ctx, errObj, lineKey, 0); + int line = (int) JSValueToNumber(ctx, jsLine, 0); + JSStringRelease(lineKey); + + std::cerr << sourceURL << ":" << line << ":" << errMsg << std::endl; +} + +JSShell* JSCShell_Create() { + return new JSCShell(); +} diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx new file mode 100755 index 000000000..8a571e0f1 --- /dev/null +++ b/Tools/javascript/v8_shell.cxx @@ -0,0 +1,310 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include "js_shell.h" + +typedef int (*V8ExtensionInitializer) (v8::Handle module); + +class V8Shell: public JSShell { + +public: + V8Shell(); + + virtual ~V8Shell(); + + virtual bool RunScript(const std::string& scriptPath); + + virtual bool RunShell(); + + +protected: + + virtual bool InitializeEngine(); + + virtual bool ExecuteScript(const std::string& source, const std::string& scriptPath); + + virtual bool DisposeEngine(); + +private: + + v8::Handle Import(const std::string& moduleName); + + v8::Persistent CreateShellContext(); + + void ReportException(v8::TryCatch* handler); + + static v8::Handle Print(const v8::Arguments& args); + + static v8::Handle Require(const v8::Arguments& args); + + static v8::Handle Quit(const v8::Arguments& args); + + static v8::Handle Version(const v8::Arguments& args); + + static const char* ToCString(const v8::String::Utf8Value& value); + +protected: + + v8::Persistent context; +}; + +#ifdef __GNUC__ +#include +#define LOAD_SYMBOL(handle, name) dlsym(handle, name) +#else +#error "implement dll loading" +#endif + +V8Shell::V8Shell() +{ +} + +V8Shell::~V8Shell() { + context.Dispose(); + v8::V8::Dispose(); +} + +bool V8Shell::RunScript(const std::string& scriptPath) { + + if (!context.IsEmpty()) { + context.Dispose(); + } + + std::string source = ReadFile(scriptPath); + + context = CreateShellContext(); + if (context.IsEmpty()) { + printf("Could not create context.\n"); + return false; + } + context->Enter(); + //v8::Context::Scope context_scope(context); + v8::HandleScope scope; + + // Store a pointer to this shell for later use + v8::Handle global = context->Global(); + v8::Local __shell__ = v8::External::New((void*) (long) this); + global->SetHiddenValue(v8::String::New("__shell__"), __shell__); + + // Node.js compatibility: make `print` available as `console.log()` + ExecuteScript("var console = {}; console.log = print;", ""); + + if(!ExecuteScript(source, scriptPath)) { + return false; + } + + context->Exit(); + context.Dispose(); + v8::V8::Dispose(); + + return true; +} + +bool V8Shell::RunShell() { + + if (!context.IsEmpty()) { + context.Dispose(); + } + + context = CreateShellContext(); + if (context.IsEmpty()) { + printf("Could not create context.\n"); + return false; + } + + context->Enter(); + + v8::Context::Scope context_scope(context); + + ExecuteScript("var console = {}; console.log = print;", ""); + + static const int kBufferSize = 1024; + while (true) { + char buffer[kBufferSize]; + printf("> "); + char* str = fgets(buffer, kBufferSize, stdin); + if (str == NULL) break; + std::string source(str); + ExecuteScript(source, "(shell)"); + } + printf("\n"); + + context->Exit(); + context.Dispose(); + v8::V8::Dispose(); + + return true; +} + + +bool V8Shell::InitializeEngine() { + return true; +} + +bool V8Shell::ExecuteScript(const std::string& source, const std::string& name) { + v8::HandleScope handle_scope; + v8::TryCatch try_catch; + v8::Handle script = v8::Script::Compile(v8::String::New(source.c_str()), v8::String::New(name.c_str())); + + // Stop if script is empty + if (script.IsEmpty()) { + // Print errors that happened during compilation. + ReportException(&try_catch); + return false; + } + + v8::Handle result = script->Run(); + + // Print errors that happened during execution. + if (try_catch.HasCaught()) { + ReportException(&try_catch); + return false; + } else { + return true; + } +} + +bool V8Shell::DisposeEngine() { + return true; +} + +v8::Persistent V8Shell::CreateShellContext() { + v8::HandleScope scope; + + // Create a template for the global object. + v8::Handle global = v8::ObjectTemplate::New(); + + // Bind global functions + global->Set(v8::String::New("print"), v8::FunctionTemplate::New(V8Shell::Print)); + global->Set(v8::String::New("quit"), v8::FunctionTemplate::New(V8Shell::Quit)); + global->Set(v8::String::New("require"), v8::FunctionTemplate::New(V8Shell::Require)); + global->Set(v8::String::New("version"), v8::FunctionTemplate::New(V8Shell::Version)); + + v8::Persistent _context = v8::Context::New(NULL, global); + + return _context; +} + +v8::Handle V8Shell::Import(const std::string& module_path) +{ + v8::HandleScope scope; + + HANDLE library; + std::string module_name = LoadModule(module_path, &library); + + std::string symname = std::string(module_name).append("_initialize"); + + V8ExtensionInitializer init_function = reinterpret_cast((long) LOAD_SYMBOL(library, symname.c_str())); + + if(init_function == 0) { + printf("Could not find initializer function."); + return v8::Undefined(); + } + + v8::Local module = v8::Object::New(); + init_function(module); + return scope.Close(module); +} + +v8::Handle V8Shell::Print(const v8::Arguments& args) { + bool first = true; + for (int i = 0; i < args.Length(); i++) { + v8::HandleScope handle_scope; + if (first) { + first = false; + } else { + printf(" "); + } + v8::String::Utf8Value str(args[i]); + const char* cstr = V8Shell::ToCString(str); + printf("%s", cstr); + } + printf("\n"); + fflush(stdout); + return v8::Undefined(); +} + +v8::Handle V8Shell::Require(const v8::Arguments& args) { + v8::HandleScope scope; + + if (args.Length() != 1) { + printf("Illegal arguments for `require`"); + }; + + v8::String::Utf8Value str(args[0]); + const char* cstr = V8Shell::ToCString(str); + std::string moduleName(cstr); + + v8::Local global = v8::Context::GetCurrent()->Global(); + v8::Local hidden = global->GetHiddenValue(v8::String::New("__shell__")); + v8::Local __shell__ = v8::Local::Cast(hidden); + V8Shell* _this = (V8Shell*) (long) __shell__->Value(); + + v8::Handle module = _this->Import(moduleName); + + return scope.Close(module); +} + +v8::Handle V8Shell::Quit(const v8::Arguments& args) { + int exit_code = args[0]->Int32Value(); + fflush(stdout); + fflush(stderr); + exit(exit_code); + return v8::Undefined(); +} + +v8::Handle V8Shell::Version(const v8::Arguments& args) { + return v8::String::New(v8::V8::GetVersion()); +} + +void V8Shell::ReportException(v8::TryCatch* try_catch) { + v8::HandleScope handle_scope; + v8::String::Utf8Value exception(try_catch->Exception()); + const char* exception_string = V8Shell::ToCString(exception); + v8::Handle message = try_catch->Message(); + if (message.IsEmpty()) { + // V8 didn't provide any extra information about this error; just + // print the exception. + printf("%s\n", exception_string); + } else { + // Print (filename):(line number): (message). + v8::String::Utf8Value filename(message->GetScriptResourceName()); + const char* filename_string = V8Shell::ToCString(filename); + int linenum = message->GetLineNumber(); + printf("%s:%i: %s\n", filename_string, linenum, exception_string); + // Print line of source code. + v8::String::Utf8Value sourceline(message->GetSourceLine()); + const char* sourceline_string = V8Shell::ToCString(sourceline); + printf("%s\n", sourceline_string); + // Print wavy underline (GetUnderline is deprecated). + int start = message->GetStartColumn(); + for (int i = 0; i < start; i++) { + printf(" "); + } + int end = message->GetEndColumn(); + for (int i = start; i < end; i++) { + printf("^"); + } + printf("\n"); + v8::String::Utf8Value stack_trace(try_catch->StackTrace()); + if (stack_trace.length() > 0) { + const char* stack_trace_string = V8Shell::ToCString(stack_trace); + printf("%s\n", stack_trace_string); + } + } +} + +// Extracts a C string from a V8 Utf8Value. +const char* V8Shell::ToCString(const v8::String::Utf8Value& value) { + return *value ? *value : ""; +} + +JSShell* V8Shell_Create() { + return new V8Shell(); +} diff --git a/Tools/swigconfig.h.cmake b/Tools/swigconfig.h.cmake new file mode 100644 index 000000000..e4f0b42c4 --- /dev/null +++ b/Tools/swigconfig.h.cmake @@ -0,0 +1,89 @@ +/* Define to 1 if the system has the type `bool'. */ +#cmakedefine HAVE_BOOL 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `dl' library (-ldl). */ +#cmakedefine HAVE_LIBDL 1 + +/* Define to 1 if you have the `dld' library (-ldld). */ +#cmakedefine HAVE_LIBDLD 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define if popen is available */ +#cmakedefine HAVE_POPEN 1 + +/* Define if rxspencer is available */ +#cmakedefine HAVE_RXSPENCER 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +#cmakedefine NO_MINUS_C_MINUS_O 1 + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS 1 + +/* Name of package */ +#define PACKAGE "swig" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "http://www.swig.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "swig" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "swig @SWIG_VERSION@" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "swig" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "@SWIG_VERSION@" + +/* Compiler that built SWIG */ +#define SWIG_CXX "@SWIG_CXX@" + +/* Directory for SWIG system-independent libraries */ +#define SWIG_LIB "/usr/local/share/swig/2.0.0" + +/* Directory for SWIG system-independent libraries (Unix install on native + Windows) */ +#define SWIG_LIB_WIN_UNIX "C:/cygwin/usr/local/share/swig/2.0.0" + +/* Platform that SWIG is built for */ +#define SWIG_PLATFORM "i686-pc-cygwin" + +/* Version number of package */ +#define VERSION "@SWIG_VERSION@" + +/* Default language */ +#define SWIG_LANG "-tcl" + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif diff --git a/Tools/swigprinters.gdb b/Tools/swigprinters.gdb new file mode 100644 index 000000000..661aa3ea1 --- /dev/null +++ b/Tools/swigprinters.gdb @@ -0,0 +1,24 @@ +python +import sys +import os + +try: + global SWIG_PRINTER_DIR + sys.path.insert(0, SWIG_PRINTER_DIR) +except NameError: + raise RuntimeError(""" +--------------------------------------------------------- +Change ~/.gdbinit to be able to use swig pretty printers: +> set python SWIG_PRINTER_DIR = /Tools +> source /Tools/swigprinters.gdb +--------------------------------------------------------- +""") + +from swigprinters import register_swig_printers, enableGdbPrintWorkaround, \ + setChildrenRecursionLevel + +#enableGdbPrintWorkaround() +#setChildrenRecursionLevel(2) +register_swig_printers (None) + +end diff --git a/Tools/swigprinters.py b/Tools/swigprinters.py new file mode 100755 index 000000000..741565997 --- /dev/null +++ b/Tools/swigprinters.py @@ -0,0 +1,574 @@ +import gdb +import gdb.types +import itertools +import re + +log_file = None +GDB_FLATTENED_CHILDREN_WORKAROUND = False +CHILDREN_MAX_RECURSION_LEVEL = 0 + +# workaround: don't cast the following DOHs to it's actual type +# to avoid infinite pretty-print loops +cast_black_list = { + 'Hash': set(['parentNode', 'symtab', 'csymtab', 'sym:symtab', 'inherit', 'nextSibling', 'previousSibling']) +} + +def print_(msg): + global log_file; + + if True: + if log_file == None: + log_file = open('swig_gdb.log', 'w') + log_file.write(msg) + + print(msg) + +class SwigStringPrinter: + """ + Pretty print Swig String* types. + """ + + def __init__ (self, typename, val): + self.typename = typename + self.val = val + + try: + self.t_swigstr_ptr = gdb.lookup_type("struct String").pointer() + self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + except Exception as err: + print_("SwigStringPrinter: Could not retrieve gdb types.\n %s.\n"%(str(err))) + + def display_hint(self): + return 'string' + + def to_string(self): + ret = "" + + # Conversion taken from Swig Internals manual: + # http://peregrine.hpc.uwm.edu/Head-node-docs/swig/2.0.4/Devel/internals.html#7 + # (*(struct String *)(((DohBase *)s)->data)).str + + dohbase = None; + str_data = None; + char_ptr = None; + + try: + dohbase = self.val.reinterpret_cast(self.t_doh_base_ptr).dereference() + except Exception as err: + print_("SwigStringPrinter: Could not dereference DOHBase*\n"); + return ""; + + try: + str_data = dohbase['data'].reinterpret_cast(self.t_swigstr_ptr).dereference() + except Exception as err: + print_("SwigStringPrinter: Could not dereference struct String*\n"); + return ""; + + try: + char_ptr = str_data['str'] + except Exception as err: + print_("SwigStringPrinter: Could not access field (struct String).str\n"); + return ""; + + if char_ptr.is_lazy is True: + char_ptr.fetch_lazy () + + try: + ret = char_ptr.string() + except Exception as err: + print_("SwigStringPrinter: Could not convert const char* to string\n"); + return ""; + + return ret + +class SwigIterator: + + def __init__(self): + + self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + self.t_string_ptr = gdb.lookup_type("String").pointer() + self.t_node_ptr = gdb.lookup_type("Node").pointer() + self.t_hash_ptr = gdb.lookup_type("Hash").pointer() + self.t_file_ptr = gdb.lookup_type("File").pointer() + self.t_void_ptr = gdb.lookup_type("void").pointer() + + def cast_doh(self, doh, name = None): + + if doh == 0: + return doh + + doh = doh.reinterpret_cast(self.t_doh_base_ptr); + + val_base = doh.dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + + if not name == None and val_typestr in cast_black_list: + blacklist = cast_black_list[val_typestr] + if name in blacklist: + return doh + + if "String" == val_typestr: + doh = doh.reinterpret_cast(self.t_string_ptr) + elif "File" == val_typestr: + doh = doh.reinterpret_cast(self.t_file_ptr) + # BUG: GDB Pyhton can not handle cyclic references yet + # so these casts are deactivated + elif "Hash" == val_typestr: + doh = doh.reinterpret_cast(self.t_hash_ptr) + elif "Node" == val_typestr: + doh = doh.reinterpret_cast(self.t_node_ptr) + + return doh + +class SwigListIterator(SwigIterator): + + def __init__(self, val): + SwigIterator.__init__(self); + + try: + self.valid = False + + self.val = val.reinterpret_cast(self.t_doh_base_ptr) + val_base = self.val.dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + #print_("SwigListIterator: constructing iterator for value of type %s"%val_typestr) + + self.t_struct_list_ptr = gdb.lookup_type("struct List").pointer() + + doh_base = self.val.dereference() + self.l = doh_base['data'].reinterpret_cast(self.t_struct_list_ptr).dereference() + + self.address = 0 + self._index = 0 + self.key = 0 + self.item = 0 + + self.address = self.val.dereference().address + + self.is_first = True + self.valid = True + + except Exception as err: + print_("SwigListIterator: Construction failed.\n %s.\n"%(str(err))) + + def __iter__(self): + return self + + def List_first(self): + + self.object = None; + self._index = 0 + self.key = 0 + self.nitems = int(self.l['nitems']) + self.items = self.l['items'] + + if self.nitems > 0: + self.item = self.items[0] + else: + self.stop() + + def List_next(self): + self._index = self._index + 1 + if self._index >= self.nitems: + self.stop() + else: + self.item = self.items[self._index] + + def next(self): + + if not self.valid: + self.stop() + + if self.is_first: + self.is_first = False + try: + self.List_first() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + else: + try: + self.List_next() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + + key_str = "[%d]"%self._index + item = 0 + + try: + item = self.cast_doh(self.item) + except Exception as err: + print_("SwigListIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + return (key_str, item) + + def stop(self): + self.is_first = True + self.item = 0 + self.key = 0 + raise StopIteration + +class SwigHashIterator(SwigIterator): + + def __init__(self, val): + SwigIterator.__init__(self); + + try: + self.valid = False + + self.val = val.reinterpret_cast(self.t_doh_base_ptr) + + self.t_struct_hash_ptr = gdb.lookup_type("struct Hash").pointer() + self.t_struct_hash_node_ptr = gdb.lookup_type("struct HashNode").pointer() + + doh_base = self.val.dereference() + hash_ = doh_base['data'].reinterpret_cast(self.t_struct_hash_ptr).dereference() + self.hashtable = hash_['hashtable'] + self.hashsize = int(hash_['hashsize']) + self.nitems = int(hash_['nitems']) + + self.next_ = 0 + self.address = 0 + self.pos = 0; + self._current = 0 + self.item = 0 + self.key = 0 + self._index = 0 + + self.address = self.val.dereference().address + + self.is_first = True + self.valid = True + + except Exception as err: + print_("SwigHashIterator: Construction failed.\n %s.\n"%(str(err))) + + def __iter__(self): + return self + + def Hash_firstiter(self): + self._current = 0; + self.item = 0; + self.key = 0; + self._index = 0; + + while (self._index < self.hashsize) and (self.hashtable[self._index] == 0): + self._index = self._index+1; + + if self._index >= self.hashsize: + self.stop(); + + self._current = self.hashtable[self._index] + self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr); + self.item = self._current['object']; + self.key = self._current['key']; + + self._current = self._current['next']; + + + def Hash_nextiter(self): + if self._current == 0: + self._index = self._index + 1 + while (self._index < self.hashsize) and (self.hashtable[self._index] == 0): + self._index = self._index + 1 + + if self._index >= self.hashsize: + self.item = 0; + self.key = 0; + self._current = 0; + self.stop() + + self._current = self.hashtable[self._index]; + + self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr); + self.key = self._current['key']; + self.item = self._current['object']; + + self._current = self._current['next']; + + + def next(self): + + if not self.valid: + self.stop() + + if self.is_first: + self.is_first = False + try: + self.Hash_firstiter() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + else: + try: + self.Hash_nextiter() + except StopIteration: + raise StopIteration + except Exception as err: + print_("Error during iteration to first node: \n %s \n" %(str(err))) + self.stop() + + key_str = "" + item = 0 + try: + string_printer = SwigStringPrinter("String *", self.key) + key_str = string_printer.to_string() + except Exception as err: + print_("SwigHashIterator(%s): Exception during extracting key string:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + try: + item = self.cast_doh(self.item, key_str) + + except Exception as err: + print_("SwigHashIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) ) + self.stop() + + return (key_str, item) + + def stop(self): + self.is_first = True + raise StopIteration + +class AlternateKeyValueIterator(): + + def __init__(self, iterable): + self.it = iterable.__iter__() + self._next = None + self.count = -1 + + def __iter__(self): + return self + + def next(self): + if self._next == None: + key, value = self.it.next() + self._next = value + self.count = self.count + 1 + return ("[%d]"%self.count, key) + else: + value = self._next + self._next = None + return ("[%d]"%self.count, value) + +class NopIterator: + + def __init__(self): + pass + + def __iter__(self): + return self + + def next(self): + raise StopIteration + +class SwigListPrinter: + """ + Pretty print Swig List* types (also ParmList*). + """ + + def __init__ (self, typename, val): + + self.typename = typename + self.val = val + + it = SwigListIterator(val) + self.valid = it.valid + self.address = it.address + + + def display_hint(self): + return 'array' + + def to_string(self): + return "%s(%s)" % (str(self.typename), str(self.address)) + + def children(self): + + if not self.valid: + print_("SwigListPrinter: Invalid state.\n") + return NopIterator() + + try: + it = SwigListIterator(self.val) + return it + except Exception as err: + print_("SwigListPrinter: Error during creation of children iterator. \n %s \n" %(str(err))) + raise err + +class SwigHashPrinter: + """ + Pretty print Swig Hash* types (also Node*). + """ + + def __init__ (self, typename, val): + + self.typename = typename + self.val = val + it = SwigHashIterator(val) + self.valid = it.valid + self.address = it.address + self.level = 0; + + def display_hint(self): + return 'map' + + def to_string(self): + return "%s(%s)" % (str(self.typename), str(self.address)) + + def children(self): + global GDB_FLATTENED_CHILDREN_WORKAROUND + global CHILDREN_MAX_RECURSION_LEVEL + + if not self.valid: + print_("SwigHashPrinter: Invalid state.\n") + return NopIterator() + + if self.level > CHILDREN_MAX_RECURSION_LEVEL: + return NopIterator() + + try: + it = SwigHashIterator(self.val) + if GDB_FLATTENED_CHILDREN_WORKAROUND: + return AlternateKeyValueIterator(it) + return it + except Exception as err: + print_("SwigHashPrinter: Error during creation of children iterator. \n %s \n" %(str(err))) + raise err + +class SwigSimplePrinter: + def __init__ (self, typename, val): + self.typename = typename + self.val = val + + def display_hint(self): + return "string" + + def to_string(self): + return "%s(%s)"%(self.typename, str(self.val.address)) + +class SwigDelegatingPrinter: + + def __init__ (self, typename, val): + t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() + val_base = val.reinterpret_cast(t_doh_base_ptr).dereference() + val_type = val_base['type'].dereference() + val_typestr = val_type['objname'].string() + self.has_children = False + + if val_typestr == "Hash": + self.delegate = SwigHashPrinter(typename, val) + self.has_children = True + elif val_typestr == "List": + self.delegate = SwigListPrinter(typename, val) + self.has_children = True + elif val_typestr == "String": + self.delegate = SwigStringPrinter(typename, val) + else: + self.delegate = SwigSimplePrinter(typename, val) + + def display_hint(self): + return self.delegate.display_hint() + + def to_string(self): + return self.delegate.to_string() + + def children(self): + if not self.has_children: + return NopIterator() + + return self.delegate.children() + +class RxPrinter(object): + def __init__(self, name, function): + super(RxPrinter, self).__init__() + self.name = name + self.function = function + self.enabled = True + + def invoke(self, value): + if not self.enabled: + return None + return self.function(self.name, value) + +# A pretty-printer that conforms to the "PrettyPrinter" protocol from +# gdb.printing. It can also be used directly as an old-style printer. +class Printer(object): + def __init__(self, name): + super(Printer, self).__init__() + self.name = name + self.subprinters = [] + self.lookup = {} + self.enabled = True + self.compiled_rx = re.compile('^([a-zA-Z0-9_: *]+)$') + + def add(self, name, function): + if not self.compiled_rx.match(name): + raise ValueError, 'error: "%s" does not match' % name + + printer = RxPrinter(name, function) + self.subprinters.append(printer) + self.lookup[name] = printer + print('Added pretty printer for %s. ' % (name)) + + def __call__(self, val): + typename = str(val.type) + if typename in self.lookup: + ret = self.lookup[typename].invoke(val) + return ret + + # Cannot find a pretty printer. Return None. + return None + +swig_printer = None + +def register_swig_printers(obj): + global swig_printer + + if obj is None: + obj = gdb + + obj.pretty_printers.append(swig_printer) + +def build_swig_printer(): + global swig_printer + + swig_printer = Printer("swig") + swig_printer.add('String *', SwigStringPrinter) + swig_printer.add('const String *', SwigStringPrinter) + swig_printer.add('SwigType *', SwigStringPrinter) + swig_printer.add('Hash *', SwigHashPrinter) + swig_printer.add('const Hash *', SwigHashPrinter) + swig_printer.add('Node *', SwigHashPrinter) + swig_printer.add('const Node *', SwigHashPrinter) + swig_printer.add('Parm *', SwigHashPrinter) + swig_printer.add('const Parm *', SwigHashPrinter) + swig_printer.add('List *', SwigListPrinter) + swig_printer.add('const List *', SwigListPrinter) + swig_printer.add('ParmList *', SwigDelegatingPrinter) + swig_printer.add('const ParmList *', SwigDelegatingPrinter) + swig_printer.add('File *', SwigDelegatingPrinter) + #swig_printer.add('DOH *', SwigDelegatingPrinter) + #swig_printer.add('const DOH *', SwigDelegatingPrinter) + + print_("Loaded swig printers\n"); + +def enableGdbPrintWorkaround(): + global GDB_FLATTENED_CHILDREN_WORKAROUND + GDB_FLATTENED_CHILDREN_WORKAROUND = True + +def setChildrenRecursionLevel(level): + global CHILDREN_MAX_RECURSION_LEVEL + CHILDREN_MAX_RECURSION_LEVEL = level + +build_swig_printer() diff --git a/configure.ac b/configure.ac index f3414969e..1d5d9ace7 100644 --- a/configure.ac +++ b/configure.ac @@ -1087,6 +1087,231 @@ AC_SUBST(JAVALDSHARED) AC_SUBST(JAVACXXSHARED) AC_SUBST(JAVACFLAGS) +#---------------------------------------------------------------- +# Look for JAVASCRIPT +#---------------------------------------------------------------- +AC_ARG_WITH(javascript, AS_HELP_STRING([--without-javascript], [Disable JAVASCRIPT]), [with_javascript="$withval"], [with_javascript=yes]) + +# First, check for "--without-javascript" or "--with-javascript=no". +if test x"${with_javascript}" = xno -o x"${with_alllang}" = xno ; then + AC_MSG_NOTICE([Disabling Javascript]) + JAVASCRIPT= +else + JAVASCRIPT=1 + + #---------------------------------------------------------------- + # General Javascript settings shared by JSC and V8 + #---------------------------------------------------------------- + + case $host in + *-*-cygwin* | *-*-mingw*) + JSLIBRARYPREFIX="" + ;; + *) + JSLIBRARYPREFIX="lib" + ;; + esac + + case $host in + *-*-darwin*) + JSSO=".dylib" + JSLDSHARED='$(CC) -dynamiclib' + JSCXXSHARED='$(CXX) -dynamiclib' + # HACK: didn't manage to get dynamic module loading working with a g++ compiled interpreter + JSINTERPRETERCXX='c++' + JSINTERPRETERLINKFLAGS='-g -Wl,-search_paths_first -Wl,-headerpad_max_install_names' + ;; + *) + JSSO=$SO + JSLDSHARED='$(LDSHARED)' + JSCXXSHARED='$(CXXSHARED)' + JSINTERPRETERCXX='$(CXX)' + JSINTERPRETERLINKFLAGS='-ldl' + ;; + esac + + #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + # Look for Node.js which is the default javascript engine + # without it, the javascript test-suite will be skipped + #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + AC_CHECK_PROGS(NODEJS, node) + + #---------------------------------------------------------------- + # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING) + #---------------------------------------------------------------- + + # check for include files + AC_MSG_CHECKING(for include file JavaScriptCore/JavaScript.h) + AC_ARG_WITH(jscoreinc, [ --with-jscinc=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=]) + + if test -z "$JSCOREINCDIR"; then + JSCOREINCDIR="/usr/include/ /usr/local/include/" + + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) + JSCOREINCDIR="/usr/include/webkit-1.0/ /usr/include/webkitgtk-1.0/ /usr/local/include/webkit-1.0/JavaScriptCore/ $JSCOREINCDIR" + ;; + *-*-darwin*) + JSCOREINCDIR="/System/Library/Frameworks/JavaScriptCore.framework/Headers/ $JSCOREINCDIR" + ;; + *) + ;; + esac + fi + + for d in $JSCOREINCDIR ; do + if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then + AC_MSG_RESULT($d) + JSCOREINCDIR=$d + JSCOREINC=-I\"$d\" + break + fi + done + + if test "$JSCOREINC" = "" ; then + AC_MSG_RESULT(not found) + fi + + # check for JavaScriptCore/Webkit libraries + AC_ARG_WITH(jscorelib,[ --with-jsclib =path Set location of the JavaScriptCore/Webkit library directory],[JSCORELIB="-L$withval"], [JSCORELIB=]) + AC_MSG_CHECKING(for JavaScriptCore/Webkit library) + + # look for the library when not provided + if test -z "$JSCORELIB"; then + case $host in + *-*-linux*) + dirs="/usr/lib/ /usr/local/lib/" + for i in $dirs ; do + if test -r $i/libjavascriptcoregtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -ljavascriptcoregtk-1.0" + break + fi + + if test -r $i/libwebkitgtk-1.0.so; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkitgtk-1.0" + break + fi + + if test -r $i/libwebkit-1.0.la; then + AC_MSG_RESULT($i) + JSCORELIB="-L$i -lwebkit-1.0" + break + fi + done + + if test -z "$JSCORELIB"; then + AC_MSG_RESULT(not found) + JSCENABLED=0 + else + JSCOREDYNAMICLINKING="$JSCORELIB" + JSCENABLED=1 + fi + ;; + *-*-darwin*) + JSCOREDYNAMICLINKING="-framework JavaScriptCore" + JSCENABLED=1 + ;; + *) + ;; + esac + fi + + #---------------------------------------------------------------- + # Look for V8 settings (JSV8INCDIR, JSV8DYNAMICLINKING) + #---------------------------------------------------------------- + + # check for include files + AC_MSG_CHECKING(for include file v8.h) + AC_ARG_WITH(jsv8inc, [ --with-v8inc=path Set location of Javascript include directory], [JSV8INCDIR="$withval"]) + + # if not include dir is specified we try to find + if test -z "$JSV8INCDIR"; then + # Add in default directory for JavaScriptCore headers for Linux and MacOSX + case $host in + *-*-linux*) + JSV8INCDIR="/usr/include /usr/local/include/ $JSV8INCDIR" + ;; + *-*-darwin*) + JSV8INCDIR="$JSV8INCDIR" + ;; + *) + ;; + esac + fi + + for d in $JSV8INCDIR ; do + if test -r "$d/v8.h" ; then + JSV8INCDIR=$d + JSV8INC=-I\"$d\" + break + fi + done + + if test "$JSV8INC" = "" ; then + AC_MSG_RESULT(not found) + else + AC_MSG_RESULT($JSV8INCDIR) + fi + + # check for V8 library + AC_MSG_CHECKING(for v8 library) + AC_ARG_WITH(jsv8lib,[ --with-v8lib=path Set location of V8 library directory],[JSV8LIBDIR="$withval"], [JSV8LIB=]) + + v8libdirs="$JSV8LIBDIR /usr/lib/ /usr/local/lib/" + for d in $v8libdirs ; do + if test -r $d/libv8.so; then + JSV8LIBDIR=$d + JSV8LIB="-L$d -lv8" + break + fi + done + + if test "$JSV8LIB" = "" ; then + AC_MSG_RESULT(not found) + JSV8ENABLED=0 + else + AC_MSG_RESULT($JSV8LIBDIR) + JSV8ENABLED=1 + fi + + + # linking options + case $host in + *-*-darwin*) + JSV8DYNAMICLINKING="" # TODO: add osx configuration + ;; + *-*-linux*) + JSV8DYNAMICLINKING="$JSV8LIB" + ;; + *) + JSV8DYNAMICLINKING="" + ;; + esac + +fi + +AC_SUBST(JSCFLAGS) +AC_SUBST(JSCXXFLAGS) +AC_SUBST(JSLIBRARYPREFIX) +AC_SUBST(JSSO) +AC_SUBST(JSLDSHARED) +AC_SUBST(JSCXXSHARED) + +AC_SUBST(JSINTERPRETERCXX) +AC_SUBST(JSINTERPRETERLINKFLAGS) + +AC_SUBST(JSCOREINC) +AC_SUBST(JSCOREDYNAMICLINKING) +AC_SUBST(JSV8INC) +AC_SUBST(JSV8DYNAMICLINKING) + +AC_SUBST(JSCENABLED) +AC_SUBST(JSV8ENABLED) + #---------------------------------------------------------------- # Look for gcj #---------------------------------------------------------------- @@ -2238,6 +2463,11 @@ if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then fi AC_SUBST(SKIP_JAVA) +SKIP_JAVASCRIPT= +if test -z "$JAVASCRIPT" || test -z "$NODEJS"; then + SKIP_JAVASCRIPT="1" +fi +AC_SUBST(SKIP_JAVASCRIPT) SKIP_GUILE= if test -z "$GUILE" || test -z "$GUILE_LIBS" ; then @@ -2421,6 +2651,8 @@ AC_CONFIG_FILES([ Examples/test-suite/d/Makefile Examples/test-suite/guile/Makefile Examples/test-suite/java/Makefile + Examples/test-suite/javascript/Makefile + Tools/javascript/Makefile Examples/test-suite/mzscheme/Makefile Examples/test-suite/ocaml/Makefile Examples/test-suite/octave/Makefile diff --git a/swig-v8/swig-v8.xcodeproj/project.pbxproj b/swig-v8/swig-v8.xcodeproj/project.pbxproj new file mode 100644 index 000000000..d6fcad63b --- /dev/null +++ b/swig-v8/swig-v8.xcodeproj/project.pbxproj @@ -0,0 +1,153 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXGroup section */ + A7E4F27918BDF64900ED77C7 = { + isa = PBXGroup; + children = ( + ); + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXLegacyTarget section */ + A7E4F28018BDF64900ED77C7 /* swig-v8 */ = { + isa = PBXLegacyTarget; + buildArgumentsString = "$(ACTION)"; + buildConfigurationList = A7E4F28318BDF64900ED77C7 /* Build configuration list for PBXLegacyTarget "swig-v8" */; + buildPhases = ( + ); + buildToolPath = /usr/bin/make; + dependencies = ( + ); + name = "swig-v8"; + passBuildSettingsInEnvironment = 1; + productName = "swig-v8"; + }; +/* End PBXLegacyTarget section */ + +/* Begin PBXProject section */ + A7E4F27B18BDF64900ED77C7 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0450; + ORGANIZATIONNAME = "Oliver Buchtala"; + }; + buildConfigurationList = A7E4F27E18BDF64900ED77C7 /* Build configuration list for PBXProject "swig-v8" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = A7E4F27918BDF64900ED77C7; + projectDirPath = ""; + projectRoot = ""; + targets = ( + A7E4F28018BDF64900ED77C7 /* swig-v8 */, + ); + }; +/* End PBXProject section */ + +/* Begin XCBuildConfiguration section */ + A7E4F28118BDF64900ED77C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + A7E4F28218BDF64900ED77C7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_64_BIT)"; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_OBJC_EXCEPTIONS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.8; + SDKROOT = macosx; + }; + name = Release; + }; + A7E4F28418BDF64900ED77C7 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + DEBUGGING_SYMBOLS = YES; + GCC_GENERATE_DEBUGGING_SYMBOLS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + A7E4F28518BDF64900ED77C7 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + OTHER_CFLAGS = ""; + OTHER_LDFLAGS = ""; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + A7E4F27E18BDF64900ED77C7 /* Build configuration list for PBXProject "swig-v8" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A7E4F28118BDF64900ED77C7 /* Debug */, + A7E4F28218BDF64900ED77C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A7E4F28318BDF64900ED77C7 /* Build configuration list for PBXLegacyTarget "swig-v8" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A7E4F28418BDF64900ED77C7 /* Debug */, + A7E4F28518BDF64900ED77C7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + }; +/* End XCConfigurationList section */ + }; + rootObject = A7E4F27B18BDF64900ED77C7 /* Project object */; +} From 57491eaa8189205d0bcd77decd90d2097b1341d5 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 06:29:00 +0100 Subject: [PATCH 274/352] Add 'version' target for javascript. --- Examples/Makefile.in | 35 ++++++++++++++++++++++++++++++++++- configure.ac | 18 ++++++------------ 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index c06f09f9a..0cbc5f7f1 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -656,7 +656,40 @@ javascript_run: javascript_custom_interpreter # TODO: make node configurable and detected via ./configure javascript_run_node: - node runme.js + @NODEJS@ runme.js + +# ----------------------------------------------------------------- +# Version display +# ----------------------------------------------------------------- + +ifeq (, $(ENGINE)) +javascript_version: + @ if [ "@NODEJS@" != "" ]; then \ + echo "Node.js: `(@NODEJS@ --version)`"; \ + else \ + echo "Version depends on the interpreter"; \ + fi +endif + +ifeq (node, $(ENGINE)) +javascript_version: + @NODEJS@ --version +endif + +ifeq (jsc, $(ENGINE)) +javascript_version: + @ if [ "@JSCOREVERSION@" != "" ]; then \ + echo "@JSCOREVERSION@"; \ + else \ + echo "Unknown JavascriptCore version."; \ + fi +endif + +ifeq (v8, $(ENGINE)) +javascript_version: + echo "Unknown v8 version." +endif + # ----------------------------------------------------------------- # Cleaning the javascript examples diff --git a/configure.ac b/configure.ac index 1d5d9ace7..9b1d3205d 100644 --- a/configure.ac +++ b/configure.ac @@ -1145,6 +1145,8 @@ else AC_MSG_CHECKING(for include file JavaScriptCore/JavaScript.h) AC_ARG_WITH(jscoreinc, [ --with-jscinc=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=]) + JSCOREVERSION= + if test -z "$JSCOREINCDIR"; then JSCOREINCDIR="/usr/include/ /usr/local/include/" @@ -1187,18 +1189,7 @@ else if test -r $i/libjavascriptcoregtk-1.0.so; then AC_MSG_RESULT($i) JSCORELIB="-L$i -ljavascriptcoregtk-1.0" - break - fi - - if test -r $i/libwebkitgtk-1.0.so; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -lwebkitgtk-1.0" - break - fi - - if test -r $i/libwebkit-1.0.la; then - AC_MSG_RESULT($i) - JSCORELIB="-L$i -lwebkit-1.0" + JSCOREVERSION=`pkg-config --modversion javascriptcoregtk-1.0` break fi done @@ -1306,12 +1297,15 @@ AC_SUBST(JSINTERPRETERLINKFLAGS) AC_SUBST(JSCOREINC) AC_SUBST(JSCOREDYNAMICLINKING) +AC_SUBST(JSCOREVERSION) AC_SUBST(JSV8INC) AC_SUBST(JSV8DYNAMICLINKING) AC_SUBST(JSCENABLED) AC_SUBST(JSV8ENABLED) +AC_SUBST(NODEJS) + #---------------------------------------------------------------- # Look for gcj #---------------------------------------------------------------- From b5aa1df72b071183c71a33a92aa785eb5f6e3549 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 06:30:36 +0100 Subject: [PATCH 275/352] Generalized smoke test configuration. --- Examples/test-suite/common.mk | 33 ++++++++++++++++------ Examples/test-suite/javascript/Makefile.in | 13 ++------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index 14f13bed8..fff9cd38a 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -97,8 +97,11 @@ CPP_TEST_BROKEN += \ C_TEST_BROKEN += \ tag_no_clash_with_variable +# Note: this allows to override the global list of tests for the purpose of +# smoke testing to foster shorter test-driven development cycles +ifndef SMOKE_TESTS_ONLY + # C++ test cases. (Can be run individually using: make testcase.cpptest) -ifndef SKIP_CPP_CASES CPP_TEST_CASES += \ abstract_access \ abstract_inherit \ @@ -490,7 +493,11 @@ CPP_TEST_CASES += \ voidtest \ wallkw \ wrapmacro -endif + +endif #SMOKE_TESTS_ONLY + + +ifndef SMOKE_TESTS_ONLY # C++11 test cases. CPP11_TEST_CASES = \ @@ -527,8 +534,12 @@ CPP11_TEST_CASES = \ # cpp11_result_of \ # SWIG does not support # cpp11_strongly_typed_enumerations \ # SWIG not quite getting this right yet in all langs +endif # SMOKE_TESTS_ONLY + # Broken C++11 test cases. -CPP11_TEST_BROKEN = +CPP11_TEST_BROKEN = + +ifndef SMOKE_TESTS_ONLY # # Put all the heavy STD/STL cases here, where they can be skipped if needed @@ -554,17 +565,18 @@ CPP_STD_TEST_CASES += \ template_opaque # li_std_list +endif # SMOKE_TESTS_ONLY -ifndef SKIP_CPP_STD_CASES CPP_TEST_CASES += ${CPP_STD_TEST_CASES} -endif ifneq (,$(HAVE_CXX11_COMPILER)) CPP_TEST_CASES += $(CPP11_TEST_CASES) endif + +ifndef SMOKE_TESTS_ONLY + # C test cases. (Can be run individually using: make testcase.ctest) -ifndef SKIP_C_CASES C_TEST_CASES += \ arrays \ bom_utf8 \ @@ -615,10 +627,12 @@ C_TEST_CASES += \ typemap_subst \ union_parameter \ unions -endif + +endif # SMOKE_TESTS_ONLY + +ifndef SMOKE_TESTS_ONLY # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest) -ifndef SKIP_MULTI_CPP_CASES MULTI_CPP_TEST_CASES += \ clientdata_prop \ imports \ @@ -627,7 +641,8 @@ MULTI_CPP_TEST_CASES += \ mod \ template_typedef_import \ multi_import -endif + +endif # SMOKE_TESTS_ONLY # Custom tests - tests with additional commandline options wallkw.cpptest: SWIGOPT += -Wallkw diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in index 49652f0bd..259869f98 100755 --- a/Examples/test-suite/javascript/Makefile.in +++ b/Examples/test-suite/javascript/Makefile.in @@ -15,13 +15,7 @@ else JSENGINE=node endif -# Note: the javascript generator is not ready yet for the real game. -# To be able keep the behavior continously tested that is expected to work already -# we have a 'light' version of the test-suite -# This will be removed and replaced by a list of 'BROKEN_TEST_CASES' when -# the number gets smaller (currently we have about 65 broken tests for JSC, and 85 for V8) - -ifneq (,$(SMOKE)) +ifeq (1,$(SMOKE)) C_TEST_CASES = \ preproc \ @@ -64,10 +58,7 @@ CPP_TEST_CASES = \ using2 \ javascript_unicode -SKIP_CPP_CASES = @SKIP_CPP_CASES@ -SKIP_C_CASES = @SKIP_C_CASES@ -SKIP_CPP_STD_CASES = @SKIP_CPP_STD_CASES@ -SKIP_MULTI_CPP_CASES = @SKIP_MULTI_CPP_CASES@ +SMOKE_TESTS_ONLY=1 endif From f9268f223c0af545a2307ab74caf6ad3af5b9791 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 06:31:23 +0100 Subject: [PATCH 276/352] Development version for travis configuration. --- .travis.yml | 55 +++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index 58b3e4ca6..cf4ab32cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,38 +5,38 @@ env: - SWIGLANG= matrix: include: - - compiler: gcc - env: SWIGLANG=csharp - - compiler: gcc - env: SWIGLANG=go - - compiler: gcc - env: SWIGLANG=guile - - compiler: gcc - env: SWIGLANG=java - - compiler: gcc +# - compiler: gcc +# env: SWIGLANG=csharp +# - compiler: gcc +# env: SWIGLANG=go +# - compiler: gcc +# env: SWIGLANG=guile +# - compiler: gcc +# env: SWIGLANG=java +# - compiler: gcc env: SWIGLANG=javascript ENGINE=node - compiler: gcc env: SWIGLANG=javascript ENGINE=jsc - compiler: gcc env: SWIGLANG=javascript ENGINE=v8 - - compiler: gcc - env: SWIGLANG=lua - - compiler: gcc - env: SWIGLANG=octave SWIGJOBS=-j4 - - compiler: gcc - env: SWIGLANG=perl5 - - compiler: gcc - env: SWIGLANG=php - - compiler: gcc - env: SWIGLANG=python - - compiler: gcc - env: SWIGLANG=python PY3=1 - - compiler: gcc - env: SWIGLANG=python PY3=1 VER=3.3 - - compiler: gcc - env: SWIGLANG=ruby - - compiler: gcc - env: SWIGLANG=tcl +# - compiler: gcc +# env: SWIGLANG=lua +# - compiler: gcc +# env: SWIGLANG=octave SWIGJOBS=-j4 +# - compiler: gcc +# env: SWIGLANG=perl5 +# - compiler: gcc +# env: SWIGLANG=php +# - compiler: gcc +# env: SWIGLANG=python +# - compiler: gcc +# env: SWIGLANG=python PY3=1 +# - compiler: gcc +# env: SWIGLANG=python PY3=1 VER=3.3 +# - compiler: gcc +# env: SWIGLANG=ruby +# - compiler: gcc +# env: SWIGLANG=tcl allow_failures: # None before_install: @@ -69,3 +69,4 @@ script: branches: only: - master + - devel From c2f22bb2b82be91d217e4c88820d56ab66c77813 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 06:32:06 +0100 Subject: [PATCH 277/352] Fix regression in custom v8 interpreter. Issue showed up with newer v8 version. --- Tools/javascript/v8_shell.cxx | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx index 8a571e0f1..4c6334f2f 100755 --- a/Tools/javascript/v8_shell.cxx +++ b/Tools/javascript/v8_shell.cxx @@ -49,6 +49,8 @@ private: static const char* ToCString(const v8::String::Utf8Value& value); + virtual bool _ExecuteScript(const std::string& source, const std::string& scriptPath); + protected: v8::Persistent context; @@ -61,14 +63,9 @@ protected: #error "implement dll loading" #endif -V8Shell::V8Shell() -{ -} +V8Shell::V8Shell(){} -V8Shell::~V8Shell() { - context.Dispose(); - v8::V8::Dispose(); -} +V8Shell::~V8Shell() {} bool V8Shell::RunScript(const std::string& scriptPath) { @@ -84,7 +81,17 @@ bool V8Shell::RunScript(const std::string& scriptPath) { return false; } context->Enter(); - //v8::Context::Scope context_scope(context); + + bool success = _ExecuteScript(source, scriptPath); + + context->Exit(); + context.Dispose(); + v8::V8::Dispose(); + + return true; +} + +bool V8Shell::_ExecuteScript(const std::string& source, const std::string& scriptPath) { v8::HandleScope scope; // Store a pointer to this shell for later use @@ -99,10 +106,6 @@ bool V8Shell::RunScript(const std::string& scriptPath) { return false; } - context->Exit(); - context.Dispose(); - v8::V8::Dispose(); - return true; } From e6dd12444cf70a31f731521b1b9a8509facd0a19 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 07:37:30 +0100 Subject: [PATCH 278/352] Fix travis configuration. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cf4ab32cd..f186cb396 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,7 @@ matrix: # env: SWIGLANG=guile # - compiler: gcc # env: SWIGLANG=java -# - compiler: gcc + - compiler: gcc env: SWIGLANG=javascript ENGINE=node - compiler: gcc env: SWIGLANG=javascript ENGINE=jsc From f47ce19cb92871dce34470a756b980665b275d7c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 06:44:24 +0100 Subject: [PATCH 279/352] Revert "Development version for travis configuration." This reverts commit f9268f223c0af545a2307ab74caf6ad3af5b9791. --- .travis.yml | 53 ++++++++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/.travis.yml b/.travis.yml index f186cb396..58b3e4ca6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,38 +5,38 @@ env: - SWIGLANG= matrix: include: -# - compiler: gcc -# env: SWIGLANG=csharp -# - compiler: gcc -# env: SWIGLANG=go -# - compiler: gcc -# env: SWIGLANG=guile -# - compiler: gcc -# env: SWIGLANG=java + - compiler: gcc + env: SWIGLANG=csharp + - compiler: gcc + env: SWIGLANG=go + - compiler: gcc + env: SWIGLANG=guile + - compiler: gcc + env: SWIGLANG=java - compiler: gcc env: SWIGLANG=javascript ENGINE=node - compiler: gcc env: SWIGLANG=javascript ENGINE=jsc - compiler: gcc env: SWIGLANG=javascript ENGINE=v8 -# - compiler: gcc -# env: SWIGLANG=lua -# - compiler: gcc -# env: SWIGLANG=octave SWIGJOBS=-j4 -# - compiler: gcc -# env: SWIGLANG=perl5 -# - compiler: gcc -# env: SWIGLANG=php -# - compiler: gcc -# env: SWIGLANG=python -# - compiler: gcc -# env: SWIGLANG=python PY3=1 -# - compiler: gcc -# env: SWIGLANG=python PY3=1 VER=3.3 -# - compiler: gcc -# env: SWIGLANG=ruby -# - compiler: gcc -# env: SWIGLANG=tcl + - compiler: gcc + env: SWIGLANG=lua + - compiler: gcc + env: SWIGLANG=octave SWIGJOBS=-j4 + - compiler: gcc + env: SWIGLANG=perl5 + - compiler: gcc + env: SWIGLANG=php + - compiler: gcc + env: SWIGLANG=python + - compiler: gcc + env: SWIGLANG=python PY3=1 + - compiler: gcc + env: SWIGLANG=python PY3=1 VER=3.3 + - compiler: gcc + env: SWIGLANG=ruby + - compiler: gcc + env: SWIGLANG=tcl allow_failures: # None before_install: @@ -69,4 +69,3 @@ script: branches: only: - master - - devel From 40c4242d303bdf0fa10129f7e188dd27247f7cd4 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 06:46:58 +0100 Subject: [PATCH 280/352] Remove Javascript documentation source file. --- Doc/Manual/Javascript.md | 773 --------------------------------------- 1 file changed, 773 deletions(-) delete mode 100644 Doc/Manual/Javascript.md diff --git a/Doc/Manual/Javascript.md b/Doc/Manual/Javascript.md deleted file mode 100644 index 36dfa7c2f..000000000 --- a/Doc/Manual/Javascript.md +++ /dev/null @@ -1,773 +0,0 @@ -# SWIG and Javascript - -This chapter describes SWIG's support of Javascript. -It does not cover SWIG basics, but only information that is specific to this module. - -## Overview - -JavaScript is a prototype-based scripting language that is dynamic, weakly typed -and has first-class functions. Its arguably the most popular language for web development. -Beyond of being a browser-based scripting language, with [node.js](http://nodejs.org) -Javascript has found its way to a backend development language, too. - -Native Javascript extensions can be used for applications that embed a web-browser view or -that embed a Javascript engine (such as *node.js*). -Extending a general purpose web-browser is not possible as this would be severe security issue. - -SWIG Javasript currently supports **JavascriptCore**, the Javascript engine used by `Safari/Webkit`, and **v8**, which is used by `Chromium` and `node.js`. - -[WebKit](http://www.webkit.org/) is a modern browser -implementation available as open-source which can be embedded into an application. - -## Preliminaries - -### Running SWIG - -Suppose that you defined a SWIG module such as the following: - - %module example - %{ - #include "example.h" - %} - int gcd(int x, int y); - extern double Foo; - -To build a Javascript module, run SWIG using the `-javascript` option -and a desired target engine `-jsc`, `-v8`, or `-node`. -The generator for `node` is essentially delegating to the `v8` generator and adds -some necessary preprocessor definitions. - - $ swig -javascript -jsc example.i - -If building a C++ extension, add the -c++ option: - - $ swig -c++ -javascript -jsc example.i - -This creates a C/C++ source file example_wrap.c or example_wrap.cxx. The generated C source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application to create an extension module. - -The name of the wrapper file is derived from the name of the input file. -For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. -To change this, you can use the -o option. -The wrapped module will export one function which must be called to register the module with the Javascript interpreter. -For example, if your module is named `example` the corresponding initializer for JavascriptCore would be - - bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports) - -and for v8: - - void example_initialize (v8::Handle exports) - -### Running Tests and Examples - -The configuration for tests and examples currently supports Linux and Mac only, MinGW not yet. - -The default interpreter is `node.js` as it is available on all platforms and convenient to use. - -Running the examples with JavascriptCore requires `libjavascriptcoregtk-1.0` to be installed, e.g., under Ubuntu with - - $ sudo apt-get install libjavascriptcoregtk-1.0-dev - -Running with `V8` requires `libv8`: - - $ sudo apt-get install libv8-dev - -Examples can be run using - - $ make ENGINE=jsc check-javascript-examples - -`ENGINE` can be `node`, `jsc`, or `v8`. - -The test-suite can be run using - - $ make ENGINE=jsc check-javascript-test-suite - -A smaller, manually selected set of tests can be run using - - $ make SMOKE=1 ENGINE=jsc check-javascript-test-suite - - -Tests should run without any problems, i.e., have been tried out, on the following platforms/interpreters: - - - Ubuntu Precise 12.04 64bit - - JavascriptCore (Webkit 1.8.3) - - Node.js (0.10.26) - - v8 (3.7.12) - - Ubuntu Saucy 13.10 64bit - - JavascriptCore (Webkit 1.10.2) - - Node.js - - v8 (3.14.5) - - Mac OSX Mountain Lion 10.8 - - JavascriptCore (built-in) - - Node.js - - Windows 7 64bit (VS 2010) - - Node.js - -Note: a `CMake` based configuration can be found in the `cmake` branch on - [](https://github.com/oliver----/swig-v8) which can be used to generate a Visual Studio solution. It is rather limited building only the SWIG executable and Javascript examples. - -### Future work - -The Javascript module is not yet as mature as other modules and some things are still missing. -As it makes use of Swigs Unified typemap library (UTL), many typemaps are inherited. -We could work on that if requested: - -- More typemaps: compared to other modules there are only a few typemaps implemented. - For instance a lot of the `std_*.i` typemaps are missing, such as `std_iostream`, for instance. - -- Director support: this would allow to extend a C++ abstract base class in Javascript. - A pragmatic intermediate step for the most important usecase - would be to support Javascript callbacks as arguments. - -- We will try to find a way into - [Chromium Embedded Framework (CEF)](http://code.google.com/p/chromiumembedded/). - CEF is also open-source and available for all platforms. - However, at the moment it does not provide access to the native V8 engine, - making it impossible to extend the engine using the extensions created with this module. - - -## Integration - -This chapter gives a short introduction how to use a native Javascript extension: as a `node.js` module, and as an extension for an embedded Webkit. - - -### Creating `node.js` Extensions - -To install `node.js` you can download an installer from their -[web-site](https://launchpad.net/~chris-lea/+archive/node.js) for OSX and Windows. -For Linux you can either build the source yourself and to a `sudo checkinstall` -or stick to the (probably stone-age) packaged version. -For Ubuntu there is a [PPA](https://launchpad.net/~chris-lea/+archive/node.js/) available. - - $ sudo add-apt-repository ppa:chris-lea/node.js - $ sudo apt-get update - $ sudo apt-get install nodejs - -As `v8` is written in C++ and comes as a C++ library it is crucial to compile your module -using the same compiler flags as used for building v8. -To make things easier, `node.js` provides a build tool called `node-gyp`. - -You have to install it using `npm`: - - $ npm install -g node-gyp - - -`node-gyp` expects a configuration file named `binding.gyp` which is basically in JSON -format and conforms to the same format that is used with Google's build-tool `gyp`. - -`binding.gyp`: - - { - "targets": [ - { - "target_name": "example", - "sources": [ "example.cxx", "example_wrap.cxx" ] - } - ] - } - -First create the wrapper using SWIG: - - $ swig -javascript -node -c++ example.cxx - -Then run `node-gyp` - - $ node-gyp - -This will create a `build` folder containing the native module. -To use the extension you have to require it in your javascript source file. - - require("./build/Release/example") - - -A more detailed exlanation is given in section `Examples`. - - -#### Troubleshooting - -- *'module' object has no attribute 'script_main'* - - This happened when `gyp` was installed as distribution package. - It seems to be outdated. Removing it resolves the problem. - - $ sudo apt-get remove gyp - - -### Embedded Webkit - -Webkit is built-in for OSX and available as library for GTK. - - -#### OSX - -There is general information about programming with WebKit on -[Apple Developer Documentation](https://developer.apple.com/library/mac/documentation/cocoa/conceptual/DisplayWebContent/DisplayWebContent.html). -Details about `Cocoa` programming are not covered here. - -An integration of a native extension 'example' would look like this: - - #import "appDelegate.h" - - extern bool example_initialize(JSGlobalContextRef context); - - - @implementation ExampleAppDelegate - - @synthesize webView; - - - - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { - - // Start a webview with the bundled index.html file - NSString *path = [[NSBundle mainBundle] bundlePath]; - NSString *url = [NSString stringWithFormat: @"file://%@/Contents/Assets/index.html", path]; - - WebFrame *webframe = [webView mainFrame]; - JSGlobalContextRef context = [webframe globalContext]; - - example_initialize(context); - - [ [webView mainFrame] loadRequest: - [NSURLRequest requestWithURL: [NSURL URLWithString:url] ] - ]; - } - - @end - -#### GTK - -There is general information about programming GTK on the -[GTK documentation](https://developer.gnome.org/gtk2/), in the -[GTK tutorial](https://developer.gnome.org/gtk-tutorial), -and for Webkit there is a [Webkit GTK+ API Reference](http://webkitgtk.org/reference/webkitgtk/stable/index.html). - -An integration of a native extension 'example' would look like this: - - #include - #include - - extern bool example_initialize(JSGlobalContextRef context); - - int main(int argc, char* argv[]) - { - // Initialize GTK+ - gtk_init(&argc, &argv); - - ... - - // Create a browser instance - WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new()); - WebFrame *webframe = webkit_web_view_get_main_frame(webView); - JSGlobalContextRef context = webkit_web_frame_get_global_context(webFrame); - example_initialize(context); - - ... - - // Load a web page into the browser instance - webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/"); - - ... - - // Run the main GTK+ event loop - gtk_main(); - - return 0; - } - -## Examples - -Some basic examples are shown here in more detail. - -### Simple - -The common example `simple` looks like this: - - /* File : example.i */ - %module example - - %inline %{ - extern int gcd(int x, int y); - extern double Foo; - %} - -To make this available as node extension a `binding.gyp` has to be created: - - { - "targets": [ - { - "target_name": "example", - "sources": [ "example.cxx", "example_wrap.cxx" ] - } - ] - } - -Then `node-gyp` is used to build the extension: - - $ node-gyp configure build - - -From a 'nodejs` application this would be used this way: - - // import the extension via require - var example = require("./build/Release/example"); - - // calling the global method - var x = 42; - var y = 105; - var g = example.gcd(x,y); - - // Accessing the globak variable - var f = example.Foo; - example.Foo = 3.1415926; - -First the module `example` is loaded from the previously built extension. -Global methods and variables are available in the scope of the module. - -> Note: ECMAScript 5, the currently implemented Javascript standard, does not have modules. -> `node.js` and other implementations provide this mechanism defined by the -> [CommonJS](http://wiki.commonjs.org/wiki/CommonJS) group. -> For browsers this is provided by [Browserify](http://browserify.org), for instance. - -### Class - -The common example `class` defines three classes, `Shape`, `Circle`, and `Square`: - - class Shape { - public: - Shape() { - nshapes++; - } - virtual ~Shape() { - nshapes--; - }; - double x, y; - void move(double dx, double dy); - virtual double area(void) = 0; - virtual double perimeter(void) = 0; - static int nshapes; - }; - - class Circle : public Shape { - private: - double radius; - public: - Circle(double r) : radius(r) { }; - virtual double area(void); - virtual double perimeter(void); - }; - - class Square : public Shape { - private: - double width; - public: - Square(double w) : width(w) { }; - virtual double area(void); - virtual double perimeter(void); - }; - -`Circle` and `Square` inherit from `Shape`. `Shape` has a static variable `nshapes`, -a function `move` that can't be overridden (non-virtual), -and two abstract functions `area` and `perimeter` (pure virtual) that must be -overridden by the sub-classes. - -A `nodejs` extension is built the same way as for the `simple` example. - -In javascript it can be used this way: - - - var example = require("./build/Release/example"); - - // local aliases for convenience - var Shape = example.Shape; - var Circle = example.Circle; - var Square = example.Square; - - // creating new instances using the 'new' operator - var c = new Circle(10); - var s = new Square(10); - - // accessing a static member - Shape.nshapes; - - // accessing member variables - c.x = 20; - c.y = 30; - s.x = -10; - s.y = 5; - - // calling some methods - c.area(); - c.perimeter(); - s.area(); - s.perimeter(); - - // instantiation of Shape is not permitted - new Shape(); - -Running these commands in an interactive node shell results in the following output: - - $ node -i - > var example = require("./build/Release/example"); - undefined - > var Shape = example.Shape; - undefined - > var Circle = example.Circle; - undefined - > var Square = example.Square; - undefined - > var c = new Circle(10); - undefined - > var s = new Square(10); - undefined - > Shape.nshapes; - 2 - > c.x = 20; - 20 - > c.y = 30; - 30 - > s.x = -10; - -10 - > s.y = 5; - 5 - > c.area(); - 314.1592653589793 - > c.perimeter(); - 62.83185307179586 - > s.area(); - 100 - > s.perimeter(); - 40 - > c.move(40, 40) - undefined - > c.x - 60 - > c.y - 70 - > new Shape() - Error: Class Shape can not be instantiated - at repl:1:2 - at REPLServer.self.eval (repl.js:110:21) - at Interface. (repl.js:239:12) - at Interface.EventEmitter.emit (events.js:95:17) - at Interface._onLine (readline.js:202:10) - at Interface._line (readline.js:531:8) - at Interface._ttyWrite (readline.js:760:14) - at ReadStream.onkeypress (readline.js:99:10) - at ReadStream.EventEmitter.emit (events.js:98:17) - at emitKey (readline.js:1095:12) - - -> Note: In ECMAScript 5 there is no concept for classes. - Instead each function can be used as a constructor function which is executed by the 'new' - operator. Furthermore, during construction the key property `prototype` of the constructor function is used to attach a prototype instance to the created object. - A prototype is essentially an object itself that is the first-class delegate of a class - used whenever the access to a property of an object fails. - The very same prototype instance is shared among all instances of one type. - Prototypal inheritance is explained in more detail on in - [Inheritance and the prototype chain](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain), for instance. - - -## Implementation - -The Javascript Module implementation has take a very different approach than other modules -to be able to generate code for different Javascript interpreters. - -### Source Code - -The Javascript module is implemented in `Source/Modules/javascript.cxx`. -It dispatches the code generation to a `JSEmitter` instance, `V8Emitter` or `JSCEmitter`. Additionally there are some helpers: `Template`, for templated code generation, and `JSEmitterState`, which is used to manage state information during AST traversal. -This rough map shall make it easier to find a way through this huge source file: - - // module wide defines - - #define NAME "name" - ... - - // ############################### - // # Helper class declarations - - class JSEmitterState { ... }; - - class Template { ... }; - - // ############################### - // # JSEmitter declaration - - class JSEmitter { ... }; - - // Emitter factory declarations - - JSEmitter *swig_javascript_create_JSCEmitter(); - JSEmitter *swig_javascript_create_V8Emitter(); - - // ############################### - // # Javascript module - - // Javascript module declaration - - class JAVASCRIPT:public Language { ... }; - - // Javascript module implementation - - int JAVASCRIPT::functionWrapper(Node *n) { ... } - ... - - // Module factory implementation - - static Language *new_swig_javascript() { ... } - - extern "C" Language *swig_javascript(void) { ... } - - // ############################### - // # JSEmitter base implementation - - JSEmitter::JSEmitter() { ... } - - Template JSEmitter::getTemplate(const String *name) { ... } - ... - - // ############################### - // # JSCEmitter - - // JSCEmitter declaration - - class JSCEmitter: public JSEmitter { ... }; - - // JSCEmitter implementation - - JSCEmitter::JSCEmitter() { ... } - - void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { ... } - ... - - // JSCEmitter factory - - JSEmitter *swig_javascript_create_JSCEmitter() { ... } - - - // ############################### - // # V8Emitter - - // V8Emitter declaration - - class V8Emitter: public JSEmitter { ... }; - - // V8Emitter implementation - - V8Emitter::V8Emitter() { ... } - - int V8Emitter::initialize(Node *n) { ... } - - // V8Emitter factory - - JSEmitter *swig_javascript_create_V8Emitter() { ... } - - - // ############################### - // # Helper implementation (JSEmitterState, Template) - - JSEmitterState::JSEmitterState() { ... } - ... - - Template::Template(const String *code_) { ... } - ... - - -### Code Templates - -All generated code is created on the basis of code templates. -The templates for *JavascriptCore* can be found in `Lib/javascript/jsc/javascriptcode.swg`, -for *v8* in `Lib/javascript/v8/javascriptcode.swg`. - -To track the originating code template for generated code you can run - - $ swig -javascript -jsc -debug-codetemplates - -which wraps generated code with a descriptive comment - - /* begin fragment("temlate_name") */ - - ...generated code ... - - /* end fragment("temlate_name") */ - -The Template class is used like this: - - Template t_register = getTemplate("jsv8_register_static_variable"); - t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) - .replace("$jsname", state.variable(NAME)) - .replace("$jsgetter", state.variable(GETTER)) - .replace("$jssetter", state.variable(SETTER)) - .trim(). - print(f_init_static_wrappers); - -A code template is registered with the *JSEmitter* via `fragment(name, "template")`, e.g., - - %fragment ("jsc_variable_declaration", "templates") - %{ - {"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone}, - %} - -`Template` creates a copy of that string and `Template::replace` uses Swig's `Replaceall` -to replace variables in the template. `Template::trim` can be used to eliminate -leading and trailing whitespaces. `Template::print` is used to write the final template string -to a Swig `DOH` (based on `Printv`). All methods allow chaining. - -### Emitter - -The Javascript module delegates code generation to a `JSEmitter` instance. -The following extract shows the essential interface: - - class JSEmitter { - ... - - /** - * Opens output files and temporary output DOHs. - */ - virtual int initialize(Node *n); - - /** - * Writes all collected code into the output file(s). - */ - virtual int dump(Node *n) = 0; - - /** - * Cleans up all open output DOHs. - */ - virtual int close() = 0; - - ... - - /** - * Invoked at the beginning of the classHandler. - */ - virtual int enterClass(Node *); - - /** - * Invoked at the end of the classHandler. - */ - virtual int exitClass(Node *) { - return SWIG_OK; - }; - - /** - * Invoked at the beginning of the variableHandler. - */ - virtual int enterVariable(Node *); - - /** - * Invoked at the end of the variableHandler. - */ - virtual int exitVariable(Node *) { - return SWIG_OK; - }; - - /** - * Invoked at the beginning of the functionHandler. - */ - virtual int enterFunction(Node *); - - /** - * Invoked at the end of the functionHandler. - */ - virtual int exitFunction(Node *) { - return SWIG_OK; - }; - - /** - * Invoked by functionWrapper callback after call to Language::functionWrapper. - */ - virtual int emitWrapperFunction(Node *n); - - /** - * Invoked from constantWrapper after call to Language::constantWrapper. - **/ - virtual int emitConstant(Node *n); - - /** - * Registers a given code snippet for a given key name. - * - * This method is called by the fragmentDirective handler - * of the JAVASCRIPT language module. - **/ - int registerTemplate(const String *name, const String *code); - - /** - * Retrieve the code template registered for a given name. - */ - Template getTemplate(const String *name); - - State &getState(); - - ... - - } - -The module calls `initialize`, `dump`, and `close` from within the `top` method: - - int JAVASCRIPT::top(Node *n) { - emitter->initialize(n); - - Language::top(n); - - emitter->dump(n); - emitter->close(); - - return SWIG_OK; - } - -The methods `enterClass` and `exitClass` are called from within the `classHandler` method: - - int JAVASCRIPT::classHandler(Node *n) { - - emitter->enterClass(n); - Language::classHandler(n); - emitter->exitClass(n); - - return SWIG_OK; - } - -In `enterClass` the emitter stores state information that is necessary when processing class members. In `exitClass` the wrapper code for the whole class is generated. - - -### Emitter states - -For storing information during the AST traversal the emitter provides a `JSEmitterState` with -different slots to store data representing the scopes global, class, function, and variable. - - class JSEmitterState { - - public: - - JSEmitterState(); - - ~JSEmitterState(); - - DOH *global(); - - DOH *global(const char* key, DOH *initial = 0); - - DOH *clazz(bool reset = false); - - DOH *clazz(const char* key, DOH *initial = 0); - - DOH *function(bool reset = false); - - DOH *function(const char* key, DOH *initial = 0); - - DOH *variable(bool reset = false); - - DOH *variable(const char* key, DOH *initial = 0); - - static int IsSet(DOH *val); - - ... - }; - -When entering a scope, such as in `enterClass`, the corresponding state is reset and new data -is stored: - - state.clazz(RESET); - state.clazz(NAME, Getattr(n, "sym:name")); - -State information can be retrieved using `state.clazz(NAME)` or -with `Getattr` on `state.clazz()` which actually returns a `Hash` instance. From a40425ab08b0fc8f4b20e51280562feadf3a2f97 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 06:47:10 +0100 Subject: [PATCH 281/352] Remove pandoc toolchain. --- Doc/Manual/markdown_to_html.sh | 9 ------ Doc/Manual/pandoc_filter.py | 56 --------------------------------- Doc/Manual/pandoc_template.html | 10 ------ 3 files changed, 75 deletions(-) delete mode 100755 Doc/Manual/markdown_to_html.sh delete mode 100755 Doc/Manual/pandoc_filter.py delete mode 100644 Doc/Manual/pandoc_template.html diff --git a/Doc/Manual/markdown_to_html.sh b/Doc/Manual/markdown_to_html.sh deleted file mode 100755 index 925f62a64..000000000 --- a/Doc/Manual/markdown_to_html.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -if [ "$1" == "" ]; then - echo "Usage: markdown_to_html " - echo "-- Example: markdown_to_html Javascript" -else - pandoc -f markdown -t json $1.md | ./pandoc_filter.py | pandoc -f json -t html -s --template pandoc_template.html -o $1.html -fi - diff --git a/Doc/Manual/pandoc_filter.py b/Doc/Manual/pandoc_filter.py deleted file mode 100755 index 33ac3ffd6..000000000 --- a/Doc/Manual/pandoc_filter.py +++ /dev/null @@ -1,56 +0,0 @@ -#!/usr/bin/python - -""" -Pandoc filter that changes pandoc default HTML output for codeblocks -to match SWIG's format: - -
-
...
-
- -""" - -from pandocfilters import toJSONFilter, stringify, walk, RawBlock, Div, Str -import sys -import json -import re - -def html(x): - return RawBlock('html', x) - -SHELL = re.compile(r"\s*[$]") -the_title = "" - -def codeblocks(key, value, format, meta): - if key == 'CodeBlock': - [[id, classes, kvs], contents] = value - - newcontents = [html('
\n' + contents + '
')] - - if len(classes) == 0: - if contents.startswith("$"): - classes.append("shell") - else: - classes.append("code") - - return Div([id, classes, kvs], newcontents) - if key == 'Header': - if value[0] == 1: - the_title = stringify(value) - value[1][0] = "" - -def set_title(unMeta): - unMeta["title"] = {"t": "MetaInlines", "c": [Str(the_title)]} - -def __toJSONFilter(action): - doc = json.loads(sys.stdin.read()) - if len(sys.argv) > 1: - format = sys.argv[1] - else: - format = "" - altered = walk(doc, action, format, doc[0]['unMeta']) - set_title(altered[0]['unMeta']) - json.dump(altered, sys.stdout) - -if __name__ == "__main__": - __toJSONFilter(codeblocks) diff --git a/Doc/Manual/pandoc_template.html b/Doc/Manual/pandoc_template.html deleted file mode 100644 index d8cbc12ad..000000000 --- a/Doc/Manual/pandoc_template.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - - $pagetitle$ - - -$body$ - - From 7ce16cc56d1053ec3e2bdc984933167517fdfb8b Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Thu, 6 Mar 2014 07:54:11 +0100 Subject: [PATCH 282/352] Remove cmake relict. --- Tools/swigconfig.h.cmake | 89 ---------------------------------------- 1 file changed, 89 deletions(-) delete mode 100644 Tools/swigconfig.h.cmake diff --git a/Tools/swigconfig.h.cmake b/Tools/swigconfig.h.cmake deleted file mode 100644 index e4f0b42c4..000000000 --- a/Tools/swigconfig.h.cmake +++ /dev/null @@ -1,89 +0,0 @@ -/* Define to 1 if the system has the type `bool'. */ -#cmakedefine HAVE_BOOL 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the `dl' library (-ldl). */ -#cmakedefine HAVE_LIBDL 1 - -/* Define to 1 if you have the `dld' library (-ldld). */ -#cmakedefine HAVE_LIBDLD 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_MEMORY_H 1 - -/* Define if popen is available */ -#cmakedefine HAVE_POPEN 1 - -/* Define if rxspencer is available */ -#cmakedefine HAVE_RXSPENCER 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRINGS_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_STRING_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_SYS_TYPES_H 1 - -/* Define to 1 if you have the header file. */ -#cmakedefine HAVE_UNISTD_H 1 - -/* Define to 1 if your C compiler doesn't accept -c and -o together. */ -#cmakedefine NO_MINUS_C_MINUS_O 1 - -/* Define to 1 if you have the ANSI C header files. */ -#cmakedefine STDC_HEADERS 1 - -/* Name of package */ -#define PACKAGE "swig" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "http://www.swig.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "swig" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "swig @SWIG_VERSION@" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "swig" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "@SWIG_VERSION@" - -/* Compiler that built SWIG */ -#define SWIG_CXX "@SWIG_CXX@" - -/* Directory for SWIG system-independent libraries */ -#define SWIG_LIB "/usr/local/share/swig/2.0.0" - -/* Directory for SWIG system-independent libraries (Unix install on native - Windows) */ -#define SWIG_LIB_WIN_UNIX "C:/cygwin/usr/local/share/swig/2.0.0" - -/* Platform that SWIG is built for */ -#define SWIG_PLATFORM "i686-pc-cygwin" - -/* Version number of package */ -#define VERSION "@SWIG_VERSION@" - -/* Default language */ -#define SWIG_LANG "-tcl" - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if defined(_MSC_VER) -# define _CRT_SECURE_NO_DEPRECATE -#endif From f43741c3b7fc0679cc338cec4b3696f1f1ef0bf0 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 31 Mar 2014 00:37:02 +0200 Subject: [PATCH 283/352] Remove gdb pretty printing. This will be provided in a separate branch. --- Tools/swigprinters.gdb | 24 -- Tools/swigprinters.py | 574 ----------------------------------------- 2 files changed, 598 deletions(-) delete mode 100644 Tools/swigprinters.gdb delete mode 100755 Tools/swigprinters.py diff --git a/Tools/swigprinters.gdb b/Tools/swigprinters.gdb deleted file mode 100644 index 661aa3ea1..000000000 --- a/Tools/swigprinters.gdb +++ /dev/null @@ -1,24 +0,0 @@ -python -import sys -import os - -try: - global SWIG_PRINTER_DIR - sys.path.insert(0, SWIG_PRINTER_DIR) -except NameError: - raise RuntimeError(""" ---------------------------------------------------------- -Change ~/.gdbinit to be able to use swig pretty printers: -> set python SWIG_PRINTER_DIR = /Tools -> source /Tools/swigprinters.gdb ---------------------------------------------------------- -""") - -from swigprinters import register_swig_printers, enableGdbPrintWorkaround, \ - setChildrenRecursionLevel - -#enableGdbPrintWorkaround() -#setChildrenRecursionLevel(2) -register_swig_printers (None) - -end diff --git a/Tools/swigprinters.py b/Tools/swigprinters.py deleted file mode 100755 index 741565997..000000000 --- a/Tools/swigprinters.py +++ /dev/null @@ -1,574 +0,0 @@ -import gdb -import gdb.types -import itertools -import re - -log_file = None -GDB_FLATTENED_CHILDREN_WORKAROUND = False -CHILDREN_MAX_RECURSION_LEVEL = 0 - -# workaround: don't cast the following DOHs to it's actual type -# to avoid infinite pretty-print loops -cast_black_list = { - 'Hash': set(['parentNode', 'symtab', 'csymtab', 'sym:symtab', 'inherit', 'nextSibling', 'previousSibling']) -} - -def print_(msg): - global log_file; - - if True: - if log_file == None: - log_file = open('swig_gdb.log', 'w') - log_file.write(msg) - - print(msg) - -class SwigStringPrinter: - """ - Pretty print Swig String* types. - """ - - def __init__ (self, typename, val): - self.typename = typename - self.val = val - - try: - self.t_swigstr_ptr = gdb.lookup_type("struct String").pointer() - self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() - except Exception as err: - print_("SwigStringPrinter: Could not retrieve gdb types.\n %s.\n"%(str(err))) - - def display_hint(self): - return 'string' - - def to_string(self): - ret = "" - - # Conversion taken from Swig Internals manual: - # http://peregrine.hpc.uwm.edu/Head-node-docs/swig/2.0.4/Devel/internals.html#7 - # (*(struct String *)(((DohBase *)s)->data)).str - - dohbase = None; - str_data = None; - char_ptr = None; - - try: - dohbase = self.val.reinterpret_cast(self.t_doh_base_ptr).dereference() - except Exception as err: - print_("SwigStringPrinter: Could not dereference DOHBase*\n"); - return ""; - - try: - str_data = dohbase['data'].reinterpret_cast(self.t_swigstr_ptr).dereference() - except Exception as err: - print_("SwigStringPrinter: Could not dereference struct String*\n"); - return ""; - - try: - char_ptr = str_data['str'] - except Exception as err: - print_("SwigStringPrinter: Could not access field (struct String).str\n"); - return ""; - - if char_ptr.is_lazy is True: - char_ptr.fetch_lazy () - - try: - ret = char_ptr.string() - except Exception as err: - print_("SwigStringPrinter: Could not convert const char* to string\n"); - return ""; - - return ret - -class SwigIterator: - - def __init__(self): - - self.t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() - self.t_string_ptr = gdb.lookup_type("String").pointer() - self.t_node_ptr = gdb.lookup_type("Node").pointer() - self.t_hash_ptr = gdb.lookup_type("Hash").pointer() - self.t_file_ptr = gdb.lookup_type("File").pointer() - self.t_void_ptr = gdb.lookup_type("void").pointer() - - def cast_doh(self, doh, name = None): - - if doh == 0: - return doh - - doh = doh.reinterpret_cast(self.t_doh_base_ptr); - - val_base = doh.dereference() - val_type = val_base['type'].dereference() - val_typestr = val_type['objname'].string() - - if not name == None and val_typestr in cast_black_list: - blacklist = cast_black_list[val_typestr] - if name in blacklist: - return doh - - if "String" == val_typestr: - doh = doh.reinterpret_cast(self.t_string_ptr) - elif "File" == val_typestr: - doh = doh.reinterpret_cast(self.t_file_ptr) - # BUG: GDB Pyhton can not handle cyclic references yet - # so these casts are deactivated - elif "Hash" == val_typestr: - doh = doh.reinterpret_cast(self.t_hash_ptr) - elif "Node" == val_typestr: - doh = doh.reinterpret_cast(self.t_node_ptr) - - return doh - -class SwigListIterator(SwigIterator): - - def __init__(self, val): - SwigIterator.__init__(self); - - try: - self.valid = False - - self.val = val.reinterpret_cast(self.t_doh_base_ptr) - val_base = self.val.dereference() - val_type = val_base['type'].dereference() - val_typestr = val_type['objname'].string() - #print_("SwigListIterator: constructing iterator for value of type %s"%val_typestr) - - self.t_struct_list_ptr = gdb.lookup_type("struct List").pointer() - - doh_base = self.val.dereference() - self.l = doh_base['data'].reinterpret_cast(self.t_struct_list_ptr).dereference() - - self.address = 0 - self._index = 0 - self.key = 0 - self.item = 0 - - self.address = self.val.dereference().address - - self.is_first = True - self.valid = True - - except Exception as err: - print_("SwigListIterator: Construction failed.\n %s.\n"%(str(err))) - - def __iter__(self): - return self - - def List_first(self): - - self.object = None; - self._index = 0 - self.key = 0 - self.nitems = int(self.l['nitems']) - self.items = self.l['items'] - - if self.nitems > 0: - self.item = self.items[0] - else: - self.stop() - - def List_next(self): - self._index = self._index + 1 - if self._index >= self.nitems: - self.stop() - else: - self.item = self.items[self._index] - - def next(self): - - if not self.valid: - self.stop() - - if self.is_first: - self.is_first = False - try: - self.List_first() - except StopIteration: - raise StopIteration - except Exception as err: - print_("Error during iteration to first node: \n %s \n" %(str(err))) - self.stop() - else: - try: - self.List_next() - except StopIteration: - raise StopIteration - except Exception as err: - print_("Error during iteration to first node: \n %s \n" %(str(err))) - self.stop() - - key_str = "[%d]"%self._index - item = 0 - - try: - item = self.cast_doh(self.item) - except Exception as err: - print_("SwigListIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) ) - self.stop() - - return (key_str, item) - - def stop(self): - self.is_first = True - self.item = 0 - self.key = 0 - raise StopIteration - -class SwigHashIterator(SwigIterator): - - def __init__(self, val): - SwigIterator.__init__(self); - - try: - self.valid = False - - self.val = val.reinterpret_cast(self.t_doh_base_ptr) - - self.t_struct_hash_ptr = gdb.lookup_type("struct Hash").pointer() - self.t_struct_hash_node_ptr = gdb.lookup_type("struct HashNode").pointer() - - doh_base = self.val.dereference() - hash_ = doh_base['data'].reinterpret_cast(self.t_struct_hash_ptr).dereference() - self.hashtable = hash_['hashtable'] - self.hashsize = int(hash_['hashsize']) - self.nitems = int(hash_['nitems']) - - self.next_ = 0 - self.address = 0 - self.pos = 0; - self._current = 0 - self.item = 0 - self.key = 0 - self._index = 0 - - self.address = self.val.dereference().address - - self.is_first = True - self.valid = True - - except Exception as err: - print_("SwigHashIterator: Construction failed.\n %s.\n"%(str(err))) - - def __iter__(self): - return self - - def Hash_firstiter(self): - self._current = 0; - self.item = 0; - self.key = 0; - self._index = 0; - - while (self._index < self.hashsize) and (self.hashtable[self._index] == 0): - self._index = self._index+1; - - if self._index >= self.hashsize: - self.stop(); - - self._current = self.hashtable[self._index] - self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr); - self.item = self._current['object']; - self.key = self._current['key']; - - self._current = self._current['next']; - - - def Hash_nextiter(self): - if self._current == 0: - self._index = self._index + 1 - while (self._index < self.hashsize) and (self.hashtable[self._index] == 0): - self._index = self._index + 1 - - if self._index >= self.hashsize: - self.item = 0; - self.key = 0; - self._current = 0; - self.stop() - - self._current = self.hashtable[self._index]; - - self._current = self._current.reinterpret_cast(self.t_struct_hash_node_ptr); - self.key = self._current['key']; - self.item = self._current['object']; - - self._current = self._current['next']; - - - def next(self): - - if not self.valid: - self.stop() - - if self.is_first: - self.is_first = False - try: - self.Hash_firstiter() - except StopIteration: - raise StopIteration - except Exception as err: - print_("Error during iteration to first node: \n %s \n" %(str(err))) - self.stop() - else: - try: - self.Hash_nextiter() - except StopIteration: - raise StopIteration - except Exception as err: - print_("Error during iteration to first node: \n %s \n" %(str(err))) - self.stop() - - key_str = "" - item = 0 - try: - string_printer = SwigStringPrinter("String *", self.key) - key_str = string_printer.to_string() - except Exception as err: - print_("SwigHashIterator(%s): Exception during extracting key string:\n %s\n" % (str(self.address), str(err)) ) - self.stop() - - try: - item = self.cast_doh(self.item, key_str) - - except Exception as err: - print_("SwigHashIterator(%s): Exception during casting of value doh:\n %s\n" % (str(self.address), str(err)) ) - self.stop() - - return (key_str, item) - - def stop(self): - self.is_first = True - raise StopIteration - -class AlternateKeyValueIterator(): - - def __init__(self, iterable): - self.it = iterable.__iter__() - self._next = None - self.count = -1 - - def __iter__(self): - return self - - def next(self): - if self._next == None: - key, value = self.it.next() - self._next = value - self.count = self.count + 1 - return ("[%d]"%self.count, key) - else: - value = self._next - self._next = None - return ("[%d]"%self.count, value) - -class NopIterator: - - def __init__(self): - pass - - def __iter__(self): - return self - - def next(self): - raise StopIteration - -class SwigListPrinter: - """ - Pretty print Swig List* types (also ParmList*). - """ - - def __init__ (self, typename, val): - - self.typename = typename - self.val = val - - it = SwigListIterator(val) - self.valid = it.valid - self.address = it.address - - - def display_hint(self): - return 'array' - - def to_string(self): - return "%s(%s)" % (str(self.typename), str(self.address)) - - def children(self): - - if not self.valid: - print_("SwigListPrinter: Invalid state.\n") - return NopIterator() - - try: - it = SwigListIterator(self.val) - return it - except Exception as err: - print_("SwigListPrinter: Error during creation of children iterator. \n %s \n" %(str(err))) - raise err - -class SwigHashPrinter: - """ - Pretty print Swig Hash* types (also Node*). - """ - - def __init__ (self, typename, val): - - self.typename = typename - self.val = val - it = SwigHashIterator(val) - self.valid = it.valid - self.address = it.address - self.level = 0; - - def display_hint(self): - return 'map' - - def to_string(self): - return "%s(%s)" % (str(self.typename), str(self.address)) - - def children(self): - global GDB_FLATTENED_CHILDREN_WORKAROUND - global CHILDREN_MAX_RECURSION_LEVEL - - if not self.valid: - print_("SwigHashPrinter: Invalid state.\n") - return NopIterator() - - if self.level > CHILDREN_MAX_RECURSION_LEVEL: - return NopIterator() - - try: - it = SwigHashIterator(self.val) - if GDB_FLATTENED_CHILDREN_WORKAROUND: - return AlternateKeyValueIterator(it) - return it - except Exception as err: - print_("SwigHashPrinter: Error during creation of children iterator. \n %s \n" %(str(err))) - raise err - -class SwigSimplePrinter: - def __init__ (self, typename, val): - self.typename = typename - self.val = val - - def display_hint(self): - return "string" - - def to_string(self): - return "%s(%s)"%(self.typename, str(self.val.address)) - -class SwigDelegatingPrinter: - - def __init__ (self, typename, val): - t_doh_base_ptr = gdb.lookup_type("DohBase").pointer() - val_base = val.reinterpret_cast(t_doh_base_ptr).dereference() - val_type = val_base['type'].dereference() - val_typestr = val_type['objname'].string() - self.has_children = False - - if val_typestr == "Hash": - self.delegate = SwigHashPrinter(typename, val) - self.has_children = True - elif val_typestr == "List": - self.delegate = SwigListPrinter(typename, val) - self.has_children = True - elif val_typestr == "String": - self.delegate = SwigStringPrinter(typename, val) - else: - self.delegate = SwigSimplePrinter(typename, val) - - def display_hint(self): - return self.delegate.display_hint() - - def to_string(self): - return self.delegate.to_string() - - def children(self): - if not self.has_children: - return NopIterator() - - return self.delegate.children() - -class RxPrinter(object): - def __init__(self, name, function): - super(RxPrinter, self).__init__() - self.name = name - self.function = function - self.enabled = True - - def invoke(self, value): - if not self.enabled: - return None - return self.function(self.name, value) - -# A pretty-printer that conforms to the "PrettyPrinter" protocol from -# gdb.printing. It can also be used directly as an old-style printer. -class Printer(object): - def __init__(self, name): - super(Printer, self).__init__() - self.name = name - self.subprinters = [] - self.lookup = {} - self.enabled = True - self.compiled_rx = re.compile('^([a-zA-Z0-9_: *]+)$') - - def add(self, name, function): - if not self.compiled_rx.match(name): - raise ValueError, 'error: "%s" does not match' % name - - printer = RxPrinter(name, function) - self.subprinters.append(printer) - self.lookup[name] = printer - print('Added pretty printer for %s. ' % (name)) - - def __call__(self, val): - typename = str(val.type) - if typename in self.lookup: - ret = self.lookup[typename].invoke(val) - return ret - - # Cannot find a pretty printer. Return None. - return None - -swig_printer = None - -def register_swig_printers(obj): - global swig_printer - - if obj is None: - obj = gdb - - obj.pretty_printers.append(swig_printer) - -def build_swig_printer(): - global swig_printer - - swig_printer = Printer("swig") - swig_printer.add('String *', SwigStringPrinter) - swig_printer.add('const String *', SwigStringPrinter) - swig_printer.add('SwigType *', SwigStringPrinter) - swig_printer.add('Hash *', SwigHashPrinter) - swig_printer.add('const Hash *', SwigHashPrinter) - swig_printer.add('Node *', SwigHashPrinter) - swig_printer.add('const Node *', SwigHashPrinter) - swig_printer.add('Parm *', SwigHashPrinter) - swig_printer.add('const Parm *', SwigHashPrinter) - swig_printer.add('List *', SwigListPrinter) - swig_printer.add('const List *', SwigListPrinter) - swig_printer.add('ParmList *', SwigDelegatingPrinter) - swig_printer.add('const ParmList *', SwigDelegatingPrinter) - swig_printer.add('File *', SwigDelegatingPrinter) - #swig_printer.add('DOH *', SwigDelegatingPrinter) - #swig_printer.add('const DOH *', SwigDelegatingPrinter) - - print_("Loaded swig printers\n"); - -def enableGdbPrintWorkaround(): - global GDB_FLATTENED_CHILDREN_WORKAROUND - GDB_FLATTENED_CHILDREN_WORKAROUND = True - -def setChildrenRecursionLevel(level): - global CHILDREN_MAX_RECURSION_LEVEL - CHILDREN_MAX_RECURSION_LEVEL = level - -build_swig_printer() From 233b24431043e5cb4ec881cdf71d54008e83189e Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 31 Mar 2014 02:15:54 +0200 Subject: [PATCH 284/352] Remove inadvertently added xcode file. --- swig-v8/swig-v8.xcodeproj/project.pbxproj | 153 ---------------------- 1 file changed, 153 deletions(-) delete mode 100644 swig-v8/swig-v8.xcodeproj/project.pbxproj diff --git a/swig-v8/swig-v8.xcodeproj/project.pbxproj b/swig-v8/swig-v8.xcodeproj/project.pbxproj deleted file mode 100644 index d6fcad63b..000000000 --- a/swig-v8/swig-v8.xcodeproj/project.pbxproj +++ /dev/null @@ -1,153 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXGroup section */ - A7E4F27918BDF64900ED77C7 = { - isa = PBXGroup; - children = ( - ); - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXLegacyTarget section */ - A7E4F28018BDF64900ED77C7 /* swig-v8 */ = { - isa = PBXLegacyTarget; - buildArgumentsString = "$(ACTION)"; - buildConfigurationList = A7E4F28318BDF64900ED77C7 /* Build configuration list for PBXLegacyTarget "swig-v8" */; - buildPhases = ( - ); - buildToolPath = /usr/bin/make; - dependencies = ( - ); - name = "swig-v8"; - passBuildSettingsInEnvironment = 1; - productName = "swig-v8"; - }; -/* End PBXLegacyTarget section */ - -/* Begin PBXProject section */ - A7E4F27B18BDF64900ED77C7 /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0450; - ORGANIZATIONNAME = "Oliver Buchtala"; - }; - buildConfigurationList = A7E4F27E18BDF64900ED77C7 /* Build configuration list for PBXProject "swig-v8" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = A7E4F27918BDF64900ED77C7; - projectDirPath = ""; - projectRoot = ""; - targets = ( - A7E4F28018BDF64900ED77C7 /* swig-v8 */, - ); - }; -/* End PBXProject section */ - -/* Begin XCBuildConfiguration section */ - A7E4F28118BDF64900ED77C7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - }; - name = Debug; - }; - A7E4F28218BDF64900ED77C7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ARCHS = "$(ARCHS_STANDARD_64_BIT)"; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.8; - SDKROOT = macosx; - }; - name = Release; - }; - A7E4F28418BDF64900ED77C7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - DEBUGGING_SYMBOLS = YES; - GCC_GENERATE_DEBUGGING_SYMBOLS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - A7E4F28518BDF64900ED77C7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - OTHER_CFLAGS = ""; - OTHER_LDFLAGS = ""; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - A7E4F27E18BDF64900ED77C7 /* Build configuration list for PBXProject "swig-v8" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A7E4F28118BDF64900ED77C7 /* Debug */, - A7E4F28218BDF64900ED77C7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - A7E4F28318BDF64900ED77C7 /* Build configuration list for PBXLegacyTarget "swig-v8" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - A7E4F28418BDF64900ED77C7 /* Debug */, - A7E4F28518BDF64900ED77C7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - }; -/* End XCConfigurationList section */ - }; - rootObject = A7E4F27B18BDF64900ED77C7 /* Project object */; -} From 23bbb59f8efa21d5a2a1337fb939b585778bef4c Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 31 Mar 2014 02:45:06 +0200 Subject: [PATCH 285/352] Update Javascript.html. --- Doc/Manual/Javascript.html | 1425 +++++++++++++++++------------------- 1 file changed, 676 insertions(+), 749 deletions(-) diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html index a53e2a7cd..d088aadfb 100644 --- a/Doc/Manual/Javascript.html +++ b/Doc/Manual/Javascript.html @@ -1,770 +1,697 @@ - - + + - - - - SWIG AND JAVASCRIPT - + + - - -
-

Overview

-

This chapter describes SWIG support for Javascript. The module is designed to support JavascriptCore and V8 as target engine. Currently only JavascriptCore support is implemented. JavaScriptCore is the built-in JavaScript engine for WebKit, whereas V8 is the engine used by Chromium.

-

JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. C++, on the other hand, is statically typed, compiled, general purpose programming language. The approach I followed here is "Test driven" where I have written the examples/test-cases to be supported for Javascript one-by-one and implemented the required module files in parallel. The support for Javascript would be added similar to other supported target languages in swig. Swig comes with an "Examples" directory for Javascript like other supported language. The directory contains examples for every supported feature of the target language. There is also a test-suite directory for javascript which contains additional tests.

-

Preliminaries

-

In order to use this module, you will need to have installed javascriptcore and you can install it by installing package libwebkit-dev You can find out some necessary compiler/linker flag by

-
pkg-config javascriptcoregtk-1.0 --cflags --libs
-
-

Using the module

-

To generate an extension for JavascriptCore one would call swig as follows

-

swig -c++ -javascript -jsc example.i -
-

This generates a C++ source file containing the wrapper.

-

How does Javascript talk to C++?

-

JavascriptCore provides a C-API which allows to extend a Javascript interpreter with native methods and structures. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is also possible to add your own commands and variables. A reference manual of this API can be found here.

-

Typically, when you add a new command to the javascript interpreter you need to do two things: first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process.

-

Wrapper functions

-

Suppose you have an ordinary C function like this :

-

int fact(int n) { - if (n <= 1) return 1; - else return n*fact(n-1); -} -
-

In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things :

-
    -
  • Gather function arguments and make sure they are valid.
  • -
  • Call the C function.
  • -
  • Convert the return value into a form recognized by the javascript.
  • -
-

As an example, the javascript wrapper function for the fact() function above example might look like the following :

-

JSValueRef wrap_fact(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - int arg1 = (int)JSValueToNumber(context, argv[0], NULL); - int arg2 = (int)JSValueToNumber(context, argv[1], NULL); - int result = (int)fact(arg1,arg2); - JSValueRef jsresult = JSValueMakeNumber(context, result); - return jsresult; -} -
-

Once you have created a wrapper function, the final step is to tell the javascript about the new function. This is done by register function called by the javascript when the module is loaded. For example, adding the above function to the javascript interpreter requires code like the following :

-

bool jsc_registerFunction(JSGlobalContextRef context, JSObjectRef object, - const char* functionName, JSObjectCallAsFunctionCallback callback) -{ - JSStringRef js_globalvarsclassname = JSStringCreateWithUTF8CString(globalvarsclassname); - JSObjectSetProperty(context,js_globalvarsclassname,JSObjectMakeFunctionWithCallback(context, - js_globalvarsclassname, callback), kJSPropertyAttributeNone,NULL); - JSStringRelease(jsstring); - return true; -} - -int example_init(JSContextRef context) { - JSObjectRef global; - ... - jsc_registerFunction(context, global, "fact", wrap_fact); - ... -} -
-

When executed, javascript will now have a new command called "fact" that you can use like any other Javascript command. Although the process of adding a new function to javascript has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code.

-

Variable Linking

-

Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpreter. For example, suppose you had the following variable:

-

double Foo = 3.5; -
-

To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called.

-

bool Foo_set(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef value, - JSValueRef* exception) -{ - JSValueRef jsresult; - double arg1 = (double)JSValueToNumber(context, value, NULL); - Foo = arg1; - jscresult = JSValueMakeUndefined(context); - return jsresult; -} - -JSValueRef Foo_get(JSContextRef context, JSObjectRef globalobj, JSStringRef propertyName, JSValueRef* exception) -{ - JSValueRef jsresult; - double result = (double)Foo; - jsresult = JSValueMakeNumber(context, result); - return jsresult; -} -
-

In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as Foo might implicitly call the get function. Similarly, typing Foo = 4 would call the underlying set function to change the value.

-

A tour of basic C/C++ wrapping

-

By default, SWIG tries to build a very natural javascript interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping.

-

Modules

-

The SWIG %module directive specifies the name of the Javascript module. If you specify %module example, then everything is wrapped into a Javascript 'example' module. Underneath the covers, this module consists of a cpp source file example.cpp. When choosing a module name, make sure you don't use the same name as a built-in Javascript command or standard module name.

-

Global variables

-

C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that javascript works.

-

// SWIG interface file with global variables -%module example -... -%inline %{ -extern double Foo; -extern int gcd(int x, int y); -%} -... -
-

Now look at the javascript:

-

print("Global variable Foo=" + example.Foo); -example.Foo = 3.1415926; -print("Variable Foo changed to=" + example.Foo); -print("GCD of x and y is=" + example.gcd(x,y)); -
-

Constants and enums

-

C/C++ constants are installed as javascript objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example:

-

#define ICONST 42 -#define FCONST 2.1828 -%constant int iconst = 37; -
-

In javascript they are treated as:

-

print("ICONST = " + example.ICONST + " (should be 42)\n"); -print("FCONST = " + example.FCONST + " (should be 2.1828)\n"); -print("iconst = " + example.iconst + " (should be 37)\n"); -
-

For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile. Enums are treated as constants.So if we have enums in c++ as:

-

void enum_test(color c, Foo::speed s); -
-

In javascript they are treated as:

-

example.enum_test(example.RED, example.Foo.IMPULSE); -example.enum_test(example.BLUE, example.Foo.WARP); -example.enum_test(example.GREEN, example.Foo.LUDICROUS); -
-

Inside the class

-

For class enums as below:

-

class Foo { -public: -Foo() { } -enum speed { IMPULSE, WARP, LUDICROUS }; -} -
-

In javascript they are treated as:

-

print(" Foo_IMPULSE =" + example.Foo.IMPULSE); -print(" Foo_WARP =" + example.Foo.WARP); -print(" Foo_LUDICROUS =" + example.Foo.LUDICROUS); -
-

Pointers

-

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface

-

/* File : example.i */ +

SWIG and Javascript

+

This chapter describes SWIG's support of Javascript. It does not cover SWIG basics, but only information that is specific to this module.

+

Overview

+

JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. Beyond of being a browser-based scripting language, with node.js Javascript has found its way to a backend development language, too.

+

Native Javascript extensions can be used for applications that embed a web-browser view or that embed a Javascript engine (such as node.js). Extending a general purpose web-browser is not possible as this would be severe security issue.

+

SWIG Javasript currently supports JavascriptCore, the Javascript engine used by Safari/Webkit, and v8, which is used by Chromium and node.js.

+

WebKit is a modern browser implementation available as open-source which can be embedded into an application.

+

Preliminaries

+

Running SWIG

+

Suppose that you defined a SWIG module such as the following:

+
+
 %module example
 %{
-extern void add(int *, int *, int *);
+#include "example.h"
 %}
-
-

When wrapped, you will be able to use the functions in a natural way from javascript. For example:

-

// Call the add() function with some pointers -example.add(a, b, c); -
-

// In javascript the code look like as:

-

a = example.new_intp(); -example.intp_assign(a,37); -
+int gcd(int x, int y); +extern double Foo;
+
+

To build a Javascript module, run SWIG using the -javascript option and a desired target engine -jsc, -v8, or -node. The generator for node is essentially delegating to the v8 generator and adds some necessary preprocessor definitions.

+
+
+$ swig -javascript -jsc example.i
+
+

If building a C++ extension, add the -c++ option:

+
+
+$ swig -c++ -javascript -jsc example.i
+
+

This creates a C/C++ source file example_wrap.c or example_wrap.cxx. The generated C source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application to create an extension module.

+

The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. The wrapped module will export one function which must be called to register the module with the Javascript interpreter. For example, if your module is named example the corresponding initializer for JavascriptCore would be

+
+
+bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports)
+
+

and for v8:

+
+
+void example_initialize (v8::Handle exports)
+
+

Running Tests and Examples

+

The configuration for tests and examples currently supports Linux and Mac only, MinGW not yet.

+

The default interpreter is node.js as it is available on all platforms and convenient to use.

+

Running the examples with JavascriptCore requires libjavascriptcoregtk-1.0 to be installed, e.g., under Ubuntu with

+
+
+$ sudo apt-get install libjavascriptcoregtk-1.0-dev
+
+

Running with V8 requires libv8:

+
+
+$ sudo apt-get install libv8-dev
+
+

Examples can be run using

+
+
+$ make ENGINE=jsc check-javascript-examples
+
+

ENGINE can be node, jsc, or v8.

+

The test-suite can be run using

+
+
+$ make ENGINE=jsc check-javascript-test-suite
+
+

A smaller, manually selected set of tests can be run using

+
+
+$ make SMOKE=1 ENGINE=jsc check-javascript-test-suite
+
+

Tests should run without any problems, i.e., have been tried out, on the following platforms/interpreters:

+
+
+- Ubuntu Precise 12.04 64bit
+    - JavascriptCore (Webkit 1.8.3)
+    - Node.js (0.10.26)
+    - v8 (3.7.12)
+- Ubuntu Saucy 13.10 64bit
+    - JavascriptCore (Webkit 1.10.2)
+    - Node.js
+    - v8 (3.14.5)
+- Mac OSX Mountain Lion 10.8
+    - JavascriptCore (built-in)
+    - Node.js
+- Windows 7 64bit (VS 2010)
+    - Node.js
+
+

Note: a CMake based configuration can be found in the cmake branch on which can be used to generate a Visual Studio solution. It is rather limited building only the SWIG executable and Javascript examples.

+

Future work

+

The Javascript module is not yet as mature as other modules and some things are still missing. As it makes use of Swigs Unified typemap library (UTL), many typemaps are inherited. We could work on that if requested:

    -
  • The first one creates an int-pointer instance.
  • -
  • The second one assigns it the value 37.
  • +
  • More typemaps: compared to other modules there are only a few typemaps implemented. For instance a lot of the std_*.i typemaps are missing, such as std_iostream, for instance.

  • +
  • Director support: this would allow to extend a C++ abstract base class in Javascript. A pragmatic intermediate step for the most important usecase would be to support Javascript callbacks as arguments.

  • +
  • We will try to find a way into Chromium Embedded Framework (CEF). CEF is also open-source and available for all platforms. However, at the moment it does not provide access to the native V8 engine, making it impossible to extend the engine using the extensions created with this module.

-

C++ classes

-

C++ classes are wrapped by javascript classes as well. For example, if you have this class,

-

class Circle +

Integration

+

This chapter gives a short introduction how to use a native Javascript extension: as a node.js module, and as an extension for an embedded Webkit.

+

Creating node.js Extensions

+

To install node.js you can download an installer from their web-site for OSX and Windows. For Linux you can either build the source yourself and to a sudo checkinstall or stick to the (probably stone-age) packaged version. For Ubuntu there is a PPA available.

+
+
+$ sudo add-apt-repository ppa:chris-lea/node.js
+$ sudo apt-get update
+$ sudo apt-get install nodejs
+
+

As v8 is written in C++ and comes as a C++ library it is crucial to compile your module using the same compiler flags as used for building v8. To make things easier, node.js provides a build tool called node-gyp.

+

You have to install it using npm:

+
+
+$ npm install -g node-gyp
+
+

node-gyp expects a configuration file named binding.gyp which is basically in JSON format and conforms to the same format that is used with Google's build-tool gyp.

+

binding.gyp:

+
+
 {
-public:
-    Circle();    
-    Circle(double r);    
-    double area();
-    double radius;
-};
-
-

you can use it in javascript like this:

-

print("Creating some objects:"); -c = new example.Circle(10); -print("area = " + c.area()); -
-

Class data members are accessed in the same manner as C structures.

-

Static class members and functions are mapped to javascript in a straight-forward manner:

-

class Spam { -public: - static void foo(); - static int bar; -}; -
-

In javascript, the static member can be access in this way:

-

// ----- Access a static member ----- -print("\nA access of static member is" + example.Spam.Foo); // access static member as properties of the class object. -
-

C++ inheritance

-

SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this

-

class A { -public: - void foo(); - virtual void bar(); -}; -class B: public A { -public: - virtual void bar(); -}; -
-

Those classes are wrapped into a hierarchy of javascript classes that reflect the same inheritance structure. All of the usual javascript utility functions work normally:

-

var a = new example.A(); -a.foo(); -a.bar(); -var b = new example.B(); -b.foo(); -b.bar(); -print("b.cPtr = " + b.getCPtr()); -
-

C++ overloaded functions

-

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:

-

void f(int val) { - std::cout << "Called f(int)." << std::endl; + "targets": [ + { + "target_name": "example", + "sources": [ "example.cxx", "example_wrap.cxx" ] + } + ] +}
+
+

First create the wrapper using SWIG:

+
+
+$ swig -javascript -node -c++ example.cxx
+
+

Then run node-gyp

+
+
+$ node-gyp
+
+

This will create a build folder containing the native module. To use the extension you have to require it in your javascript source file.

+
+
+require("./build/Release/example")
+
+

A more detailed exlanation is given in section Examples.

+

Troubleshooting

+
    +
  • 'module' object has no attribute 'script_main'
  • +
+

This happened when gyp was installed as distribution package. It seems to be outdated. Removing it resolves the problem.

+
+
+$ sudo apt-get remove gyp
+
+

Embedded Webkit

+

Webkit is built-in for OSX and available as library for GTK.

+

OSX

+

There is general information about programming with WebKit on Apple Developer Documentation. Details about Cocoa programming are not covered here.

+

An integration of a native extension 'example' would look like this:

+
+
+#import "appDelegate.h"
+
+extern bool example_initialize(JSGlobalContextRef context);
+
+
+@implementation ExampleAppDelegate
+
+@synthesize webView;
+
+
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+
+  // Start a webview with the bundled index.html file
+  NSString *path = [[NSBundle mainBundle] bundlePath];
+  NSString *url =  [NSString stringWithFormat: @"file://%@/Contents/Assets/index.html", path];
+
+  WebFrame *webframe = [webView mainFrame];
+  JSGlobalContextRef context = [webframe globalContext];
+
+  example_initialize(context);
+
+  [ [webView mainFrame] loadRequest:
+    [NSURLRequest requestWithURL: [NSURL URLWithString:url] ]
+  ];
 }
-void f(int val1, int val2) {
-  std::cout << "Called f(int, int)." << std::endl;
-}
-void f(const char* s) {
-  std::cout << "Called f(const char*)." << std::endl;
-}
-
-

You can use them in javascript in a straightforward manner:

-

example.f(1); -example.f(1, 2); -example.f("bla"); -
-

C++ operators

-

Certain C++ overloaded operators can be handled automatically by SWIG. Though, in javascript operator overloading is not possible. Instead one has to make use of the %rename feature.

-

For example, consider a class like this:

-

/* File : example.h */ -#include <math.h> -class Complex { -private: - double rpart, ipart; -public: - Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } - Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } - Complex &operator=(const Complex &c) { - rpart = c.rpart; - ipart = c.ipart; - return *this; - } - Complex operator+(const Complex &c) const { - return Complex(rpart+c.rpart, ipart+c.ipart); - } - Complex operator-(const Complex &c) const { - return Complex(rpart-c.rpart, ipart-c.ipart); - } - Complex operator*(const Complex &c) const { - return Complex(rpart*c.rpart - ipart*c.ipart, - rpart*c.ipart + c.rpart*ipart); - } - Complex operator-() const { - return Complex(-rpart, -ipart); - } - double re() const { return rpart; } - double im() const { return ipart; } -}; -
-

When wrapped, it works like you expect:

-

a = new example.Complex(2,3); -b = new example.Complex(-5,10); +@end
+
+

GTK

+

There is general information about programming GTK on the GTK documentation, in the GTK tutorial, and for Webkit there is a Webkit GTK+ API Reference.

+

An integration of a native extension 'example' would look like this:

+
+
+#include 
+#include 
 
-print ("a   =" + a);
-print ("b   =" + b);
+extern bool example_initialize(JSGlobalContextRef context);
 
-c = a.plus(b);
+int main(int argc, char* argv[])
+{
+    // Initialize GTK+
+    gtk_init(&argc, &argv);
 
-print("c   =" + c);
-print("a*b =" + a.times(b));
-print("a-c =" + a.minus(c));
+    ...
 
-e = example.Complex.copy(a.minus(c));
-print("e   =" + e);
+    // Create a browser instance
+    WebKitWebView *webView = WEBKIT_WEB_VIEW(webkit_web_view_new());
+    WebFrame *webframe = webkit_web_view_get_main_frame(webView);
+    JSGlobalContextRef context = webkit_web_frame_get_global_context(webFrame);
+    example_initialize(context);
 
-// Big expression
-f = a.plus(b).times(c.plus(b.times(e))).plus(a.uminus());
-print("f   =" + f);
-
-

One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this

-

class Complex { -... -friend Complex operator+(double, const Complex &c); -... -}; -
-

then SWIG ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:

-

%rename(Complex_add_dc) operator+(double, const Complex &);

-

There are ways to make this operator appear as part of the class using the %extend directive.

-

C++ namespaces:

-

SWIG is aware of C++ namespaces, but namespace names do not appear in the module nor do namespaces result in a module that is broken up into submodules or packages. For example, if you have a file like this,

-

%module example -namespace nspace { + ... + + // Load a web page into the browser instance + webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/"); + + ... + + // Run the main GTK+ event loop + gtk_main(); + + return 0; +}
+
+

Examples

+

Some basic examples are shown here in more detail.

+

Simple

+

The common example simple looks like this:

+
+
+/* File : example.i */
+%module example
+
+%inline %{
 extern int    gcd(int x, int y);
 extern double Foo;
-class Circle
-{
-public:
-   Circle();
-   Circle(double r);
-   double area();
-   double radius;
-   };
-}
-
-

for namespaces, you use the %feature directive in interface file. %feature attaches a new attribute to any parse tree node that matches given prototype.

-

/* File : example.i */ -%module example -%{ -#include "example.h" -%} -%feature("nspace", 1); -%include "example.h" -
-

it works in javascript as follows:

-

print("Global variable Foo=" + example.nspace.Foo); -example.nspace.Foo = 5; -print("Variable Foo changed to " + example.nspace.Foo); -print("GCD of number 6,18 is " + example.nspace.gcd(6,18)); -print("Creating some objects:"); -c = new example.nspace.Circle(10); -print("area = " + c.area()); -
-

If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:

-

%rename(Bar_spam) Bar::spam; -namespace Foo { - int spam(); -} -namespace Bar { - int spam(); -} -
-

If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve. SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence.

-

C++ templates

-

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:

-

/* File : example.i */ -%module example -%{ -#include "example.h" -%} -/* Let's just grab the original header file here */ -%include "example.h" - -/* Now instantiate some specific template declarations */ -%template(maxint) max<int>; -%template(maxdouble) max<double>; -%template(vecint) vector<int>; -%template(vecdouble) vector<double>; -
-

In javascript:

-

//Call some templated functions -print(example.maxint(3,7)); -print(example.maxdouble(3.14,2.18)); - -// Create some class - -iv = new example.vecint(100); -dv = new example.vecdouble(1000); - -for(i=0;i<=100;i++) - iv.setitem(i,2*i); - -for(i=0;i<=1000;i++) - dv.setitem(i, 1.0/(i+1)); - -sum = 0; -for(i=0;i<=100;i++) - sum = sum + iv.getitem(i); - -print(sum); - -sum = 0.0; -for(i=0;i<=1000;i++) - sum = sum + dv.getitem(i); -print(sum); -
-

Exception handling

-

The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into javascript exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following:

-

Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the javascript extension by writing the following in an interface file:

-

/* File : example.i */ -%module example -%{ -#include "example.h" -%} -%include "std_string.i" - -/* Let's just grab the original header file here */ -%include "example.h" -
-

Actually in JS there is no support for typed exceptions.For now there is support for integer and string exception. Example for integer exception

-

JSValueRef jsc_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ -int arg1 = (int)JSValueToNumber(context, argv[0], NULL); -int arg2 = (int)JSValueToNumber(context, argv[1], NULL); -*exception = JSValueMakeNumber(context, 13); -int result = (int)gcd(arg1,arg2); -JSValueRef jsresult = JSValueMakeNumber(context, result); -
-

and for string exception:

-

JSValueRef wrap_gcd(JSContextRef context, JSObjectRef function, JSObjectRef globalobj, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ -int arg1 = (int)JSValueToNumber(context, argv[0], NULL); -int arg2 = (int)JSValueToNumber(context, argv[1], NULL); -JSStringRef message = JSStringCreateWithUTF8CString("This is a test error."); -*exception = JSValueMakeString(context, message); -JSStringRelease(message); -int result = (int)gcd(arg1,arg2); -JSValueRef jscresult = JSValueMakeNumber(context, result); -return jsresult; -} -
-

How to use generated modules?

-

Basically there is no standard extension mechanism in Javascript. We provided a custom interpreter with extension abilities. If JSC is embedded into a custom application, one has to make use of a generated module initializer function that allows easy extension of interpreter. The basic approach is as follows:

-

Basic Mechanism

-
    -
  • Creating the context
  • -
  • Calling module initializer
  • -
  • Evaluate Javascript
  • -
-

Creating the context

-

JSGlobalContextRef context = JSGlobalContextCreate(NULL); -JSObjectRef globalObject = JSContextGetGlobalObject(context); -... -
-

Calling module initializer

-

extern int example_init(JSGlobalContextRef context); - ... - example_init(context); - ... -
-

Evaluate Javascript

-

// Evaluate the javascript -char* scriptContent = jsccreateStringWithContentsOfFile(scriptPath.c_str()); -JSStringRef jsScript; -if(!scriptContent) { - printf("FAIL: runme script could not be loaded.\n"); - failed = 1; - } - else { - JSValueRef ex; - jsScript = JSStringCreateWithUTF8CString(scriptContent); - JSValueRef jsResult = JSEvaluateScript(context, jsScript, 0, 0, 0, &ex); - if (!jsResult && ex) { - jsc_printError(context, ex, scriptPath); - failed = 1; - } - } - if (scriptContent != NULL) { - free(scriptContent); - } - JSStringRelease(jsScript); - JSGlobalContextRelease(context); - globalObject = 0; - for(std::vector<HANDLE>::iterator it = loaded_modules.begin(); - it != loaded_modules.end(); ++it) { - HANDLE handle = *it; - dlclose(handle); - } - if (failed) { - printf("FAIL: Some tests failed.\n"); - return 1; - } -} -
-

Typemaps

-

A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from javascript to C, you might define a typemap like this:

-

%typemap(in) int { - $1 = ($1_ltype)JSValueToNumber(context, $input, NULL); %} - printf("Received an integer : %d\n",$1); -} -
-

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int.

-

Javascript typemaps

-

The previous section illustrated an "in" typemap for converting javascript objects to C. A variety of different typemap methods are defined by the javascript module. For example, to convert a C integer back into a javascript object, you might define an "out" typemap like this:

-

%typemap(out) int { - $result = JSValueMakeNumber(context, $1); -} -
-

The Javascript module makes use of Swig's unified template library.

-

Typemap variables

-

Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

-

$1: A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Javascript.

-

$input: A javascript Object * holding a raw javascript object with an argument or variable value.

-

$result: A javascript Object * that holds the result to be returned to javascript.

-

$1_name: The parameter name that was matched.

-

$1_type: The actual C datatype matched by the typemap.

-

$1_ltype: An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.

-

$symname: The javascript name of the wrapper function being created.

-

Javascript: Specification of a Code Generator for JSC

-

The module implementation tries to accomplish a separation of logic and code generation by making use of code templates. In the following, the templates are explained.

-

Top Level structure

-

The generated code consists of the following blocks:

-

<RUNTIME> -<INCLUDES> -<HELPER_FUNCTIONS> -<FUNCTION_WRAPPERS> -<INITIALIZER> -
-
    -
  • RUNTIME: runtime code generated by swig
  • -
  • HELPER_FUNCTIONS: static, from swg-file
  • -
  • INCLUDES: static, module property
  • -
  • FUNCTION_WRAPPERS: dynamically growing, on method declarations
  • -
  • INITIALIZER: dynamically growing, aggregates everything
  • -
-

INCLUDES

-

#include <JavaScriptCore/JavaScript.h> -<USER_DEFINED_INCLUDES> -
-

USER_DEFINED_INCLUDES: a module property

-

HELPER_FUNCTIONS

-

A lot of boiler-plate code can be shifted into static helper functions:

-

bool JS_registerClass(JSGlobalContextRef& context, JSObjectRef& parentObject,const char* className, - JSClassDefinition* definition) { - JSStringRef js_className = JSStringCreateWithUTF8CString(className); - JSObjectRef classObject = JSObjectMake(context, JSClassCreate(definition), NULL); - JSObjectSetProperty(context, parentObject,js_className, classObject,kJSPropertyAttributeNone, NULL); - JSStringRelease(js_className); - return true; -} - -bool JS_registerNamespace(JSGlobalContextRef& context,JSObjectRef& namespaceObj,JSObjectRef& parentNamespace,const char* name) -{ - JSStringRef js_name = JSStringCreateWithUTF8CString(name); - JSObjectSetProperty(context, parentNamespace,js_name, namespaceObj,kJSPropertyAttributeNone, NULL); - JSStringRelease(js_name); - return true; -} - -bool JS_registerFunction(JSGlobalContextRef context, JSObjectRef object, const char* functionName, JSObjectCallAsFunctionCallback callback) -{ - JSStringRef js_functionName = JSStringCreateWithUTF8CString(functionName); - JSObjectSetProperty(context,object,js_functionName,JSObjectMakeFunctionWithCallback(context, - js_functionName, callback), kJSPropertyAttributeNone, NULL); - JSStringRelease(js_functionName); - return true; -} -bool JS_veto_set_variable(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - char buffer[256]; - char msg[512]; - int res; - JSStringGetUTF8CString(propertyName, buffer, 256); - res = sprintf(msg, "Tried to write read-only variable: %s.", buffer); - if(res<0) { - SWIG_exception(SWIG_ERROR, "Tried to write read-only variable."); - } else { - SWIG_exception(SWIG_ERROR, msg); - } - return false; -} - -JSValueRef JS_CharPtrToJSValue(JSContextRef context, char* cstr) { - JSValueRef val; - JSStringRef jsstring = JSStringCreateWithUTF8CString((char*) cstr); - val = JSValueMakeString(context, jsstring); - JSStringRelease(jsstring); - return val; -} -
-

FUNCTION_WRAPPERS

-

There are different types of function wrappers: - Member Functions - Getproperty / Setproperty - Global Functions (global/namespace/class) - Constructors / Destructors

-

Member Functions

-

JSValueRef ${functionname}(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) -{ - ${LOCALS} - ${CODE} - return jsresult; - - goto fail; - fail: - return NULL; -} -
-
    -
  • functionname: the name of generated wrapper for function
  • -
  • LOCALS: declarations for input arguments
  • -
  • CODE: contains input marshalling, the action, and output marshalling
  • -
-

Setproperty

-

bool ${setname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception) -{ - ${LOCALS} - ${CODE} - return jsresult; - - goto fail; - fail: - return NULL; -} -
-
    -
  • setname: the name of the generated wrapper for setproperty.
  • -
  • LOCALS: declarations for input arguments
  • -
  • CODE: contains input marshalling, and the action
  • -
-

Getproperty

-

JSValueRef ${getname}(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception) -{ - ${LOCALS} - ${CODE} - return jsresult; - - goto fail; - fail: - return NULL; -} -
-
    -
  • getname: the name of the generated wrapper for the getproperty
  • -
  • LOCALS: declarations for output arguments
  • -
  • CODE: contains the action, and output marshalling
  • -
-

Global Functions

-

JSStaticValue ${namespace}_values[] = { - ${jsglobalvariables} - { 0, 0, 0, 0 } -}; -JSStaticFunction ${namespace}_functions[] = { - ${jsglobalfunctions} - { 0, 0, 0 } -}; -JSClassDefinition ${namespace}_classDefinition; -
-

Variable declaration

-

{"${propertyname}",${getname}, ${setname}, kJSPropertyAttributeNone} -
-

This is used to fill variable definition tables. kJSPropertyAttributeNone is JSC specific and means that the variable has a getter and setter. Even for read-only variables a setter is used which throws an exception.

-

Constructor

-

~~

-

JSObjectRef wrap_createclassnamemangled{overloadext}(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception) { ${LOCALS} ${CODE} return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_${type_mangled}, SWIG_POINTER_OWN);

-
goto fail;
-fail:
-return NULL;
-
-

}

-
- `classname_mangled` is the mangled qualified class name,   e.g., `foo::A -> foo_A`
-- `LOCALS`: declarations for input arguments 
-- `CODE`: contains input marshalling, and the action 
-
-## Destructors
-
-

void wrap${classname_mangled}_finalize(JSObjectRef thisObject) { SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject); if(t && t->swigCMemOwn) delete (${type}*)(t->swigCObject); if(t) delete t; }

-

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` - -## Initializer -
-

bool ${modulename}_initialize(JSGlobalContextRef context) { SWIG_InitializeModule(0);

-
JSObjectRef global_object = JSContextGetGlobalObject(context);
-
-/* Initialize the base swig type object */
-_SwigObject_objectDefinition.staticFunctions = _SwigObject_functions;
-_SwigObject_objectDefinition.staticValues = _SwigObject_values;
-_SwigObject_classRef = JSClassCreate(&_SwigObject_objectDefinition);
-
-/* Create objects for namespaces */
-${create_namespaces}
-
-/* Create classes */
-${initializercode}
-
-/* Register namespaces */
-${register_namespaces}
-
-return true;
-
-

}

-

## Class template defintions - -A class is specified by a static part (`*_classDefinition`) and a dynamic part (`*_objectDefinition`). -
-

${classname_mangled}_classDefinition.staticFunctions = ${classname_mangled}_staticFunctions; ${classname_mangled}_classDefinition.staticValues = ${classname_mangled}_staticValues; ${classname_mangled}_classDefinition.callAsConstructor = _wrap_create_${classname_mangled}; ${classname_mangled}_objectDefinition.staticValues = ${classname_mangled}_values; ${classname_mangled}_objectDefinition.staticFunctions = ${classname_mangled}_functions; ${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef; JSClassRef ${classname_mangled}_classRef = JSClassCreate(&${classname_mangled}objectDefinition); SWIGTYPE${classtype_mangled}->clientdata = ${classname_mangled}_classRef;%}

-

Notes: -- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` - which is retrieved by `Swig_name_mangle(Getattr(n, "name"))` -- ClassDefinitions are built using the staticValues array and the staticFunction array. The staticValues and staticFunctions arrays are the simplest and most efficient means for vending custom properties to the class object. - -## Inheritance -
-

{${classname_mangled}_objectDefinition.parentClass = ${base_classname}_classRef};

-

- `classname_mangled` is the mangled qualified class name, e.g., `foo::A -> foo_A` -- Note: multiple inheritance is not possible; thus we will always take the first parent class - -## Namespaces - -Namespaces are objects without class templates. i.e., instances are created, referenced locally, used as contexts for other registrations, and stored in the according parent contexts. -
-

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

-

## Registration - -The registration part consists of registering classes at contexts (i.e., global or namespace), methods and properties at classes or contexts, and namespaces as objects at parent contexts. - -* Global functions -
-

JS_registerFunction(${context}, ${context_object}, "${functionname}", ${functionwrapper}

-

* Classes -
-

JS_registerClass(context, ${namespace}_object, "${classname}", &${classname_mangled}_classDefinition)

-

Note: every class template has an associated constructor function wrapper, which is registered here - -* Namespaces -
-

${namespace}_classDefinition.staticFunctions = ${namespace}_functions; ${namespace}_classDefinition.staticValues = ${namespace}_values; JSObjectRef ${namespace}_object = JSObjectMake(context, JSClassCreate(&${namespace}_classDefinition), NULL);

-

Namespaces are registered using: -
-

JS_registerNamespace(context, ${namespace}_object, ${parent_namespace}_object, "${namespace}");

-

~~

+%}
+

To make this available as node extension a binding.gyp has to be created:

+
+
+{
+  "targets": [
+    {
+      "target_name": "example",
+      "sources": [ "example.cxx", "example_wrap.cxx" ]
+    }
+  ]
+}
+
+

Then node-gyp is used to build the extension:

+
+
+$ node-gyp configure build
+
+

From a 'nodejs` application this would be used this way:

+
+
+// import the extension via require
+var example = require("./build/Release/example");
+
+// calling the global method
+var x = 42;
+var y = 105;
+var g = example.gcd(x,y);
+
+// Accessing the globak variable
+var f = example.Foo;
+example.Foo = 3.1415926;
+
+

First the module example is loaded from the previously built extension. Global methods and variables are available in the scope of the module.

+
+

Note: ECMAScript 5, the currently implemented Javascript standard, does not have modules. node.js and other implementations provide this mechanism defined by the CommonJS group. For browsers this is provided by Browserify, for instance.

+
+

Class

+

The common example class defines three classes, Shape, Circle, and Square:

+
+
+class Shape {
+public:
+  Shape() {
+    nshapes++;
+  }
+  virtual ~Shape() {
+    nshapes--;
+  };
+  double  x, y;
+  void    move(double dx, double dy);
+  virtual double area(void) = 0;
+  virtual double perimeter(void) = 0;
+  static  int nshapes;
+};
+
+class Circle : public Shape {
+private:
+  double radius;
+public:
+  Circle(double r) : radius(r) { };
+  virtual double area(void);
+  virtual double perimeter(void);
+};
+
+class Square : public Shape {
+private:
+  double width;
+public:
+  Square(double w) : width(w) { };
+  virtual double area(void);
+  virtual double perimeter(void);
+};
+
+

Circle and Square inherit from Shape. Shape has a static variable nshapes, a function move that can't be overridden (non-virtual), and two abstract functions area and perimeter (pure virtual) that must be overridden by the sub-classes.

+

A nodejs extension is built the same way as for the simple example.

+

In javascript it can be used this way:

+
+
+var example = require("./build/Release/example");
+
+// local aliases for convenience
+var Shape = example.Shape;
+var Circle = example.Circle;
+var Square = example.Square;
+
+// creating new instances using the 'new' operator
+var c = new Circle(10);
+var s = new Square(10);
+
+// accessing a static member
+Shape.nshapes;
+
+// accessing member variables
+c.x = 20;
+c.y = 30;
+s.x = -10;
+s.y = 5;
+
+// calling some methods
+c.area();
+c.perimeter();
+s.area();
+s.perimeter();
+
+// instantiation of Shape is not permitted
+new Shape();
+
+

Running these commands in an interactive node shell results in the following output:

+
+
+$ node -i
+> var example = require("./build/Release/example");
+undefined
+> var Shape = example.Shape;
+undefined
+> var Circle = example.Circle;
+undefined
+> var Square = example.Square;
+undefined
+> var c = new Circle(10);
+undefined
+> var s = new Square(10);
+undefined
+> Shape.nshapes;
+2
+> c.x = 20;
+20
+> c.y = 30;
+30
+> s.x = -10;
+-10
+> s.y = 5;
+5
+> c.area();
+314.1592653589793
+> c.perimeter();
+62.83185307179586
+> s.area();
+100
+> s.perimeter();
+40
+> c.move(40, 40)
+undefined
+> c.x
+60
+> c.y
+70
+> new Shape()
+Error: Class Shape can not be instantiated
+at repl:1:2
+at REPLServer.self.eval (repl.js:110:21)
+at Interface. (repl.js:239:12)
+at Interface.EventEmitter.emit (events.js:95:17)
+at Interface._onLine (readline.js:202:10)
+at Interface._line (readline.js:531:8)
+at Interface._ttyWrite (readline.js:760:14)
+at ReadStream.onkeypress (readline.js:99:10)
+at ReadStream.EventEmitter.emit (events.js:98:17)
+at emitKey (readline.js:1095:12)
+
+
+

Note: In ECMAScript 5 there is no concept for classes. Instead each function can be used as a constructor function which is executed by the 'new' operator. Furthermore, during construction the key property prototype of the constructor function is used to attach a prototype instance to the created object. A prototype is essentially an object itself that is the first-class delegate of a class used whenever the access to a property of an object fails. The very same prototype instance is shared among all instances of one type. Prototypal inheritance is explained in more detail on in Inheritance and the prototype chain, for instance.

+
+

Implementation

+

The Javascript Module implementation has take a very different approach than other modules to be able to generate code for different Javascript interpreters.

+

Source Code

+

The Javascript module is implemented in Source/Modules/javascript.cxx. It dispatches the code generation to a JSEmitter instance, V8Emitter or JSCEmitter. Additionally there are some helpers: Template, for templated code generation, and JSEmitterState, which is used to manage state information during AST traversal. This rough map shall make it easier to find a way through this huge source file:

+
+
+// module wide defines
+
+#define NAME "name"
+...
+
+// ###############################
+// #  Helper class declarations
+
+class JSEmitterState { ... };
+
+class Template { ... };
+
+// ###############################
+// # JSEmitter declaration
+
+class JSEmitter { ... };
+
+// Emitter factory declarations
+
+JSEmitter *swig_javascript_create_JSCEmitter();
+JSEmitter *swig_javascript_create_V8Emitter();
+
+// ###############################
+// # Javascript module
+
+// Javascript module declaration
+
+class JAVASCRIPT:public Language { ... };
+
+// Javascript module implementation
+
+int JAVASCRIPT::functionWrapper(Node *n) { ... }
+...
+
+// Module factory implementation
+
+static Language *new_swig_javascript() { ... }
+
+extern "C" Language *swig_javascript(void) { ... }
+
+// ###############################
+// # JSEmitter base implementation
+
+JSEmitter::JSEmitter() { ... }
+
+Template JSEmitter::getTemplate(const String *name) { ... }
+...
+
+// ###############################
+// # JSCEmitter
+
+// JSCEmitter declaration
+
+class JSCEmitter: public JSEmitter { ... };
+
+// JSCEmitter implementation
+
+JSCEmitter::JSCEmitter() { ... }
+
+void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) { ... }
+...
+
+// JSCEmitter factory
+
+JSEmitter *swig_javascript_create_JSCEmitter() { ... }
+
+
+// ###############################
+// # V8Emitter
+
+// V8Emitter declaration
+
+class V8Emitter: public JSEmitter { ... };
+
+// V8Emitter implementation
+
+V8Emitter::V8Emitter() { ... }
+
+int V8Emitter::initialize(Node *n) { ... }
+
+// V8Emitter factory
+
+JSEmitter *swig_javascript_create_V8Emitter() { ... }
+
+
+// ###############################
+// # Helper implementation (JSEmitterState, Template)
+
+JSEmitterState::JSEmitterState() { ... }
+...
+
+Template::Template(const String *code_) { ... }
+...
+
+

Code Templates

+

All generated code is created on the basis of code templates. The templates for JavascriptCore can be found in Lib/javascript/jsc/javascriptcode.swg, for v8 in Lib/javascript/v8/javascriptcode.swg.

+

To track the originating code template for generated code you can run

+
+
+$ swig -javascript -jsc -debug-codetemplates
+
+

which wraps generated code with a descriptive comment

+
+
+/* begin fragment("temlate_name") */
+
+...generated code ...
+
+/* end fragment("temlate_name") */
+
+

The Template class is used like this:

+
+
+Template t_register = getTemplate("jsv8_register_static_variable");
+t_register.replace("$jsparent", state.clazz(NAME_MANGLED))
+    .replace("$jsname", state.variable(NAME))
+    .replace("$jsgetter", state.variable(GETTER))
+    .replace("$jssetter", state.variable(SETTER))
+    .trim().
+    print(f_init_static_wrappers);
+
+

A code template is registered with the JSEmitter via fragment(name, "template"), e.g.,

+
+
+%fragment ("jsc_variable_declaration", "templates")
+%{
+  {"$jsname", $jsgetter, $jssetter, kJSPropertyAttributeNone},
+%}
+
+

Template creates a copy of that string and Template::replace uses Swig's Replaceall to replace variables in the template. Template::trim can be used to eliminate leading and trailing whitespaces. Template::print is used to write the final template string to a Swig DOH (based on Printv). All methods allow chaining.

+

Emitter

+

The Javascript module delegates code generation to a JSEmitter instance. The following extract shows the essential interface:

+
+
+class JSEmitter {
+  ...
+
+  /**
+   * Opens output files and temporary output DOHs.
+   */
+  virtual int initialize(Node *n);
+
+  /**
+   * Writes all collected code into the output file(s).
+   */
+  virtual int dump(Node *n) = 0;
+
+  /**
+   * Cleans up all open output DOHs.
+   */
+  virtual int close() = 0;
+
+  ...
+
+  /**
+   * Invoked at the beginning of the classHandler.
+   */
+  virtual int enterClass(Node *);
+
+  /**
+   * Invoked at the end of the classHandler.
+   */
+  virtual int exitClass(Node *) {
+    return SWIG_OK;
+  };
+
+  /**
+   * Invoked at the beginning of the variableHandler.
+   */
+  virtual int enterVariable(Node *);
+
+  /**
+   * Invoked at the end of the variableHandler.
+   */
+  virtual int exitVariable(Node *) {
+    return SWIG_OK;
+  };
+
+  /**
+   * Invoked at the beginning of the functionHandler.
+   */
+  virtual int enterFunction(Node *);
+
+  /**
+   * Invoked at the end of the functionHandler.
+   */
+  virtual int exitFunction(Node *) {
+    return SWIG_OK;
+  };
+
+  /**
+   * Invoked by functionWrapper callback after call to Language::functionWrapper.
+   */
+  virtual int emitWrapperFunction(Node *n);
+
+  /**
+   * Invoked from constantWrapper after call to Language::constantWrapper.
+   **/
+  virtual int emitConstant(Node *n);
+
+  /**
+   * Registers a given code snippet for a given key name.
+   *
+   * This method is called by the fragmentDirective handler
+   * of the JAVASCRIPT language module.
+   **/
+  int registerTemplate(const String *name, const String *code);
+
+  /**
+   * Retrieve the code template registered for a given name.
+   */
+  Template getTemplate(const String *name);
+
+  State &getState();
+
+  ...
+
+}
+
+

The module calls initialize, dump, and close from within the top method:

+
+
+int JAVASCRIPT::top(Node *n) {
+  emitter->initialize(n);
+
+  Language::top(n);
+
+  emitter->dump(n);
+  emitter->close();
+
+  return SWIG_OK;
+}
+
+

The methods enterClass and exitClass are called from within the classHandler method:

+
+
+int JAVASCRIPT::classHandler(Node *n) {
+
+  emitter->enterClass(n);
+  Language::classHandler(n);
+  emitter->exitClass(n);
+
+  return SWIG_OK;
+}
+
+

In enterClass the emitter stores state information that is necessary when processing class members. In exitClass the wrapper code for the whole class is generated.

+

Emitter states

+

For storing information during the AST traversal the emitter provides a JSEmitterState with different slots to store data representing the scopes global, class, function, and variable.

+
+
+class JSEmitterState {
+
+public:
+
+  JSEmitterState();
+
+  ~JSEmitterState();
+
+  DOH *global();
+
+  DOH *global(const char* key, DOH *initial = 0);
+
+  DOH *clazz(bool reset = false);
+
+  DOH *clazz(const char* key, DOH *initial = 0);
+
+  DOH *function(bool reset = false);
+
+  DOH *function(const char* key, DOH *initial = 0);
+
+  DOH *variable(bool reset = false);
+
+  DOH *variable(const char* key, DOH *initial = 0);
+
+  static int IsSet(DOH *val);
+
+  ...
+};
+
+

When entering a scope, such as in enterClass, the corresponding state is reset and new data is stored:

+
+
+state.clazz(RESET);
+state.clazz(NAME, Getattr(n, "sym:name"));
+
+

State information can be retrieved using state.clazz(NAME) or with Getattr on state.clazz() which actually returns a Hash instance.

From a8c3f853784eefd57ec6e6b3c94bdfeee0125a9d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 31 Mar 2014 02:59:33 +0200 Subject: [PATCH 286/352] Insert a workaround for c_delete and c_delete_function for v8. --- Examples/test-suite/c_delete.i | 2 +- Examples/test-suite/c_delete_function.i | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Examples/test-suite/c_delete.i b/Examples/test-suite/c_delete.i index 632340629..28b2ae78e 100644 --- a/Examples/test-suite/c_delete.i +++ b/Examples/test-suite/c_delete.i @@ -4,7 +4,7 @@ #pragma SWIG nowarn=SWIGWARN_PARSE_KEYWORD -#if !defined(SWIGOCTAVE) /* Octave compiles wrappers as C++ */ +#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) /* Octave and Javascript/v8 compiles wrappers as C++ */ %inline %{ struct delete { diff --git a/Examples/test-suite/c_delete_function.i b/Examples/test-suite/c_delete_function.i index 3739ceadc..0aac423ac 100644 --- a/Examples/test-suite/c_delete_function.i +++ b/Examples/test-suite/c_delete_function.i @@ -2,7 +2,7 @@ /* check C++ delete keyword is okay in C wrappers */ -#if !defined(SWIGOCTAVE) /* Octave compiles wrappers as C++ */ +#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) /* Octave and Javascript/v8 compiles wrappers as C++ */ %inline %{ double delete(double d) { return d; } From faab78439cc37ae056f2535d08c6e871ec1ea5cd Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 31 Mar 2014 03:09:43 +0200 Subject: [PATCH 287/352] Updated Javascript documentation. Added note about v8 being c++ only. --- Doc/Manual/Javascript.html | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html index d088aadfb..7acf37fe3 100644 --- a/Doc/Manual/Javascript.html +++ b/Doc/Manual/Javascript.html @@ -45,6 +45,9 @@ bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports)
 void example_initialize (v8::Handle exports)
+
+

Note: be aware that v8 comes as a C++ API, and thus, the generated modules must be compiled as C++.

+

Running Tests and Examples

The configuration for tests and examples currently supports Linux and Mac only, MinGW not yet.

The default interpreter is node.js as it is available on all platforms and convenient to use.

@@ -91,13 +94,14 @@ $ make SMOKE=1 ENGINE=jsc check-javascript-test-suite - Windows 7 64bit (VS 2010) - Node.js -

Note: a CMake based configuration can be found in the cmake branch on which can be used to generate a Visual Studio solution. It is rather limited building only the SWIG executable and Javascript examples.

+
+

Note: a CMake based configuration can be found in the cmake which can be used to generate a VisualStudio solution. It is rather limited and can only be used for building the SWIG executable.

+

Future work

The Javascript module is not yet as mature as other modules and some things are still missing. As it makes use of Swigs Unified typemap library (UTL), many typemaps are inherited. We could work on that if requested:

  • More typemaps: compared to other modules there are only a few typemaps implemented. For instance a lot of the std_*.i typemaps are missing, such as std_iostream, for instance.

  • Director support: this would allow to extend a C++ abstract base class in Javascript. A pragmatic intermediate step for the most important usecase would be to support Javascript callbacks as arguments.

  • -
  • We will try to find a way into Chromium Embedded Framework (CEF). CEF is also open-source and available for all platforms. However, at the moment it does not provide access to the native V8 engine, making it impossible to extend the engine using the extensions created with this module.

Integration

This chapter gives a short introduction how to use a native Javascript extension: as a node.js module, and as an extension for an embedded Webkit.

@@ -113,7 +117,7 @@ $ sudo apt-get install nodejs

You have to install it using npm:

-$ npm install -g node-gyp
+$ sudo npm install -g node-gyp

node-gyp expects a configuration file named binding.gyp which is basically in JSON format and conforms to the same format that is used with Google's build-tool gyp.

binding.gyp:

@@ -224,6 +228,10 @@ int main(int argc, char* argv[]) return 0; } +

Creating Applications with node-webkit

+
+

TODO: documentation is coming soon

+

Examples

Some basic examples are shown here in more detail.

Simple

From ea94c22062c5bb9de1f9435d17e7ae48cca79b53 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 31 Mar 2014 03:46:51 +0200 Subject: [PATCH 288/352] Document Javascript related preprocessor macros. --- Doc/Manual/Preprocessor.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html index d5c41dde7..745570ca4 100644 --- a/Doc/Manual/Preprocessor.html +++ b/Doc/Manual/Preprocessor.html @@ -115,6 +115,9 @@ SWIGCLISP Defined when using CLISP SWIGCSHARP Defined when using C# SWIGGUILE Defined when using Guile SWIGJAVA Defined when using Java +SWIGJAVASCRIPT Defined when using Javascript +SWIG_JAVASCRIPT_JSC Defined when using Javascript for JavascriptCore +SWIG_JAVASCRIPT_V8 Defined when using Javascript for v8 or node.js SWIGLUA Defined when using Lua SWIGMODULA3 Defined when using Modula-3 SWIGMZSCHEME Defined when using Mzscheme From a485d89e62be9476f9e9aa1aaa2bd040be002cf9 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Mon, 31 Mar 2014 04:15:34 +0200 Subject: [PATCH 289/352] Optimized travis before_install for Javascript. --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 58b3e4ca6..8b0d6b568 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,7 +48,9 @@ before_install: - if test -z "$SWIGLANG"; then sudo apt-get -qq install yodl; fi - if test "$SWIGLANG" = "csharp"; then sudo apt-get -qq install mono-devel; fi - if test "$SWIGLANG" = "go"; then go env | sed -e 's/^/export /' > goenvsetup && source goenvsetup && rm -f goenvsetup; fi # Until configure.ac is fixed - - if test "$SWIGLANG" = "javascript"; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs libv8-dev libwebkitgtk-dev && sudo npm install -g node-gyp; fi + - if [ "$SWIGLANG" == "javascript" ] && [ "$ENGINE" == "node" ]; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs && sudo npm install -g node-gyp; fi + - if [ "$SWIGLANG" == "javascript" ] && [ "$ENGINE" == "jsc" ]; then sudo apt-get install -qq libwebkitgtk-dev; fi + - if [ "$SWIGLANG" == "javascript" ] && [ "$ENGINE" == "v8" ]; then sudo apt-get install -qq libv8-dev; fi - if test "$SWIGLANG" = "guile"; then sudo apt-get -qq install guile-2.0-dev; fi - if test "$SWIGLANG" = "lua"; then sudo apt-get -qq install lua5.1 liblua5.1-dev; fi - if test "$SWIGLANG" = "octave"; then sudo apt-get -qq install octave3.2 octave3.2-headers; fi From a550bddab1104b73167cf62926f4515e3d37e034 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 1 Apr 2014 19:54:16 +0100 Subject: [PATCH 290/352] Add javascript to Sections.html --- Doc/Manual/Sections.html | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html index 877ca2fae..99d1dfe0d 100644 --- a/Doc/Manual/Sections.html +++ b/Doc/Manual/Sections.html @@ -42,6 +42,7 @@ Last update : SWIG-3.0.1 (in progress)
  • Go support
  • Guile support
  • Java support
  • +
  • Javascript support
  • Common Lisp support
  • Lua support
  • Modula3 support
  • From e095566720218ec4dba095e34ac6fc4333972024 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 1 Apr 2014 20:09:44 +0100 Subject: [PATCH 291/352] Turn on Travis testing on javascript branch --- .travis.yml | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8b0d6b568..69764de7a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,42 +1,17 @@ language: c compiler: - gcc + - clang env: - SWIGLANG= matrix: include: - - compiler: gcc - env: SWIGLANG=csharp - - compiler: gcc - env: SWIGLANG=go - - compiler: gcc - env: SWIGLANG=guile - - compiler: gcc - env: SWIGLANG=java - compiler: gcc env: SWIGLANG=javascript ENGINE=node - compiler: gcc env: SWIGLANG=javascript ENGINE=jsc - compiler: gcc env: SWIGLANG=javascript ENGINE=v8 - - compiler: gcc - env: SWIGLANG=lua - - compiler: gcc - env: SWIGLANG=octave SWIGJOBS=-j4 - - compiler: gcc - env: SWIGLANG=perl5 - - compiler: gcc - env: SWIGLANG=php - - compiler: gcc - env: SWIGLANG=python - - compiler: gcc - env: SWIGLANG=python PY3=1 - - compiler: gcc - env: SWIGLANG=python PY3=1 VER=3.3 - - compiler: gcc - env: SWIGLANG=ruby - - compiler: gcc - env: SWIGLANG=tcl allow_failures: # None before_install: @@ -71,3 +46,4 @@ script: branches: only: - master + - javascript From 6b220a5e7f3f6041ce04ae8af5f8e71c6965f685 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 1 Apr 2014 20:15:10 +0100 Subject: [PATCH 292/352] Travis file code consistency --- .travis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 69764de7a..b0eb54d9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,9 +23,9 @@ before_install: - if test -z "$SWIGLANG"; then sudo apt-get -qq install yodl; fi - if test "$SWIGLANG" = "csharp"; then sudo apt-get -qq install mono-devel; fi - if test "$SWIGLANG" = "go"; then go env | sed -e 's/^/export /' > goenvsetup && source goenvsetup && rm -f goenvsetup; fi # Until configure.ac is fixed - - if [ "$SWIGLANG" == "javascript" ] && [ "$ENGINE" == "node" ]; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs && sudo npm install -g node-gyp; fi - - if [ "$SWIGLANG" == "javascript" ] && [ "$ENGINE" == "jsc" ]; then sudo apt-get install -qq libwebkitgtk-dev; fi - - if [ "$SWIGLANG" == "javascript" ] && [ "$ENGINE" == "v8" ]; then sudo apt-get install -qq libv8-dev; fi + - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "node"; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs && sudo npm install -g node-gyp; fi + - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "jsc"; then sudo apt-get install -qq libwebkitgtk-dev; fi + - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "v8"; then sudo apt-get install -qq libv8-dev; fi - if test "$SWIGLANG" = "guile"; then sudo apt-get -qq install guile-2.0-dev; fi - if test "$SWIGLANG" = "lua"; then sudo apt-get -qq install lua5.1 liblua5.1-dev; fi - if test "$SWIGLANG" = "octave"; then sudo apt-get -qq install octave3.2 octave3.2-headers; fi From 921189415a4c46f8854217358d3cb698f619969d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 10 Apr 2014 07:58:02 +0100 Subject: [PATCH 293/352] Remove junk files --- Examples/javascript/reference/swig_gdb.log | 22 ---------------------- Examples/javascript/variables/swig_gdb.log | 9 --------- 2 files changed, 31 deletions(-) delete mode 100644 Examples/javascript/reference/swig_gdb.log delete mode 100644 Examples/javascript/variables/swig_gdb.log diff --git a/Examples/javascript/reference/swig_gdb.log b/Examples/javascript/reference/swig_gdb.log deleted file mode 100644 index 57bca0306..000000000 --- a/Examples/javascript/reference/swig_gdb.log +++ /dev/null @@ -1,22 +0,0 @@ -Loaded swig printers -SwigStringPrinter: Could not convert const char* to string -SwigListIterator: Construction failed. - Cannot access memory at address 0x7d894828ec834853. -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigListIterator: Construction failed. - Cannot access memory at address 0x7d894828ec834853. -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not dereference struct String* -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not dereference struct String* -SwigStringPrinter: Could not dereference struct String* -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not dereference struct String* -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not dereference struct String* -SwigStringPrinter: Could not dereference struct String* diff --git a/Examples/javascript/variables/swig_gdb.log b/Examples/javascript/variables/swig_gdb.log deleted file mode 100644 index 2fe437110..000000000 --- a/Examples/javascript/variables/swig_gdb.log +++ /dev/null @@ -1,9 +0,0 @@ -Loaded swig printers -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string -SwigStringPrinter: Could not convert const char* to string From 244ad06c2511336d5a4dabf5ef67b8a5b81e12bd Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 10 Apr 2014 08:11:33 +0100 Subject: [PATCH 294/352] Alphabetical order for Javascript in -help output --- Source/Modules/swigmain.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx index 97b21710a..8a0861d17 100644 --- a/Source/Modules/swigmain.cxx +++ b/Source/Modules/swigmain.cxx @@ -74,6 +74,7 @@ static swig_module modules[] = { {"-go", swig_go, "Go"}, {"-guile", swig_guile, "Guile"}, {"-java", swig_java, "Java"}, + {"-javascript", swig_javascript, "Javascript"}, {"-lua", swig_lua, "Lua"}, {"-modula3", swig_modula3, "Modula 3"}, {"-mzscheme", swig_mzscheme, "Mzscheme"}, @@ -93,7 +94,6 @@ static swig_module modules[] = { {"-tcl8", swig_tcl, 0}, {"-uffi", swig_uffi, "Common Lisp / UFFI"}, {"-xml", swig_xml, "XML"}, - {"-javascript", swig_javascript, "Javascript"}, {NULL, NULL, NULL} }; From 0e0f65aeadb13f0ebd2d06eba04a04395ed2c06d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 10 Apr 2014 08:13:06 +0100 Subject: [PATCH 295/352] Tidy up Example makefile for Javascript --- Examples/Makefile.in | 21 ++++++++------------- configure.ac | 2 -- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 0cbc5f7f1..5c203b398 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -599,33 +599,28 @@ java_clean: ROOT_DIR = @ROOT_DIR@ -JSCFLAGS = @JSCFLAGS@ -JSCXXFLAGS = @JSCXXFLAGS@ JSINCLUDES = @JSCOREINC@ @JSV8INC@ JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ -JSLIBRARYPREFIX = @JSLIBRARYPREFIX@ JSSO =@JSSO@ JSLDSHARED = @JSLDSHARED@ JSCXXSHARED = @JSCXXSHARED@ -SWIGJS = $(SWIG) -javascript - # ---------------------------------------------------------------- # Creating and building Javascript wrappers # ---------------------------------------------------------------- javascript_wrapper: - $(SWIGJS) $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH) + $(SWIG) -javascript $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH) javascript_wrapper_cpp: $(SRCS) - $(SWIGJS) -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cxx $(INTERFACEPATH) + $(SWIG) -javascript -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cxx $(INTERFACEPATH) javascript_build: $(SRCS) - $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) + $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) javascript_build_cpp:: $(SRCS) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) # TODO: make node-gyp configurable and detected via ./configure @@ -635,13 +630,13 @@ javascript_build_node: $(SRCS) # These targets are used by the test-suite: javascript: $(SRCS) javascript_custom_interpreter - $(SWIGJS) $(SWIGOPT) $(INTERFACEPATH) - $(CC) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) + $(SWIG) -javascript $(SWIGOPT) $(INTERFACEPATH) + $(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES) $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO) javascript_cpp: $(SRCS) javascript_custom_interpreter - $(SWIGJS) -c++ $(SWIGOPT) $(INTERFACEPATH) - $(CXX) -c $(CCSHARED) $(CFLAGS) $(JSCFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) + $(SWIG) -javascript -c++ $(SWIGOPT) $(INTERFACEPATH) + $(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES) $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO) # ----------------------------------------------------------------- diff --git a/configure.ac b/configure.ac index 91ec3883a..876940065 100644 --- a/configure.ac +++ b/configure.ac @@ -1285,8 +1285,6 @@ else fi -AC_SUBST(JSCFLAGS) -AC_SUBST(JSCXXFLAGS) AC_SUBST(JSLIBRARYPREFIX) AC_SUBST(JSSO) AC_SUBST(JSLDSHARED) From a3ad811cee7915d612561fd47e678fe5e214f39a Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 10 Apr 2014 19:15:46 +0100 Subject: [PATCH 296/352] Makefile and autoconf file tidy up for Javascript --- Source/Makefile.am | 2 +- Tools/javascript/Makefile.in | 2 -- configure.ac | 4 ++-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Source/Makefile.am b/Source/Makefile.am index 4dbede635..9e02e37f0 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -48,8 +48,8 @@ eswig_SOURCES = CParse/cscanner.c \ Modules/go.cxx \ Modules/guile.cxx \ Modules/java.cxx \ - Modules/lang.cxx \ Modules/javascript.cxx \ + Modules/lang.cxx \ Modules/lua.cxx \ Modules/main.cxx \ Modules/modula3.cxx \ diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in index d58412b50..373c5d952 100644 --- a/Tools/javascript/Makefile.in +++ b/Tools/javascript/Makefile.in @@ -20,8 +20,6 @@ CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ LINKFLAGS = @JSINTERPRETERLINKFLAGS@ ROOT_DIR = @ROOT_DIR@ -JSCFLAGS = @JSCFLAGS@ -JSCXXFLAGS = @JSCXXFLAGS@ JSINCLUDES = @JSCOREINC@ @JSV8INC@ JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@ JSLIBRARYPREFIX = @JSLIBRARYPREFIX@ diff --git a/configure.ac b/configure.ac index 876940065..304e1215e 100644 --- a/configure.ac +++ b/configure.ac @@ -2634,7 +2634,6 @@ AC_DEFINE_UNQUOTED(SWIG_LIB_WIN_UNIX, ["$SWIG_LIB_WIN_UNIX"], [Directory for SWI AC_CONFIG_FILES([ Makefile swig.spec - Source/Makefile Examples/Makefile Examples/xml/Makefile Examples/test-suite/errors/Makefile @@ -2644,7 +2643,6 @@ AC_CONFIG_FILES([ Examples/test-suite/guile/Makefile Examples/test-suite/java/Makefile Examples/test-suite/javascript/Makefile - Tools/javascript/Makefile Examples/test-suite/mzscheme/Makefile Examples/test-suite/ocaml/Makefile Examples/test-suite/octave/Makefile @@ -2661,6 +2659,8 @@ AC_CONFIG_FILES([ Examples/test-suite/uffi/Makefile Examples/test-suite/r/Makefile Examples/test-suite/go/Makefile + Source/Makefile + Tools/javascript/Makefile ]) AC_CONFIG_FILES([preinst-swig], [chmod +x preinst-swig]) AC_CONFIG_FILES([CCache/ccache_swig_config.h]) From 547454684ec4a95b56432c43af0ee347589a82ee Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 10 Apr 2014 20:04:17 +0100 Subject: [PATCH 297/352] a few Javascript clarifications in configure.ac --- configure.ac | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/configure.ac b/configure.ac index 304e1215e..b214ed9e4 100644 --- a/configure.ac +++ b/configure.ac @@ -1088,9 +1088,9 @@ AC_SUBST(JAVACXXSHARED) AC_SUBST(JAVACFLAGS) #---------------------------------------------------------------- -# Look for JAVASCRIPT +# Look for Javascript #---------------------------------------------------------------- -AC_ARG_WITH(javascript, AS_HELP_STRING([--without-javascript], [Disable JAVASCRIPT]), [with_javascript="$withval"], [with_javascript=yes]) +AC_ARG_WITH(javascript, AS_HELP_STRING([--without-javascript], [Disable Javascript]), [with_javascript="$withval"], [with_javascript=yes]) # First, check for "--without-javascript" or "--with-javascript=no". if test x"${with_javascript}" = xno -o x"${with_alllang}" = xno ; then @@ -1130,10 +1130,9 @@ else ;; esac - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #---------------------------------------------------------------- # Look for Node.js which is the default javascript engine - # without it, the javascript test-suite will be skipped - #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + #---------------------------------------------------------------- AC_CHECK_PROGS(NODEJS, node) @@ -1142,7 +1141,7 @@ else #---------------------------------------------------------------- # check for include files - AC_MSG_CHECKING(for include file JavaScriptCore/JavaScript.h) + AC_MSG_CHECKING(for JavaScriptCore/JavaScript.h) AC_ARG_WITH(jscoreinc, [ --with-jscinc=path Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=]) JSCOREVERSION= @@ -1216,8 +1215,8 @@ else #---------------------------------------------------------------- # check for include files - AC_MSG_CHECKING(for include file v8.h) - AC_ARG_WITH(jsv8inc, [ --with-v8inc=path Set location of Javascript include directory], [JSV8INCDIR="$withval"]) + AC_MSG_CHECKING(for V8 Javascript v8.h) + AC_ARG_WITH(jsv8inc, [ --with-v8inc=path Set location of Javascript v8 include directory], [JSV8INCDIR="$withval"]) # if not include dir is specified we try to find if test -z "$JSV8INCDIR"; then @@ -1249,8 +1248,8 @@ else fi # check for V8 library - AC_MSG_CHECKING(for v8 library) - AC_ARG_WITH(jsv8lib,[ --with-v8lib=path Set location of V8 library directory],[JSV8LIBDIR="$withval"], [JSV8LIB=]) + AC_MSG_CHECKING(for V8 Javascript library) + AC_ARG_WITH(jsv8lib,[ --with-v8lib=path Set location of V8 Javascript library directory],[JSV8LIBDIR="$withval"], [JSV8LIB=]) v8libdirs="$JSV8LIBDIR /usr/lib/ /usr/local/lib/" for d in $v8libdirs ; do From d8b3b4e4749995ad735513e2f60e719fba42a4da Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 15 Apr 2014 20:54:16 +0100 Subject: [PATCH 298/352] Improve missing JS engine error message --- Doc/Manual/Javascript.html | 7 ++++--- Source/Modules/javascript.cxx | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html index 7acf37fe3..8d8f436ca 100644 --- a/Doc/Manual/Javascript.html +++ b/Doc/Manual/Javascript.html @@ -8,9 +8,10 @@

    SWIG and Javascript

    This chapter describes SWIG's support of Javascript. It does not cover SWIG basics, but only information that is specific to this module.

    Overview

    -

    JavaScript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. Beyond of being a browser-based scripting language, with node.js Javascript has found its way to a backend development language, too.

    -

    Native Javascript extensions can be used for applications that embed a web-browser view or that embed a Javascript engine (such as node.js). Extending a general purpose web-browser is not possible as this would be severe security issue.

    -

    SWIG Javasript currently supports JavascriptCore, the Javascript engine used by Safari/Webkit, and v8, which is used by Chromium and node.js.

    +

    Javascript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. +Javascript has gone beyond being a browser-based scripting language and with node.js, it is also used as a backend development language.

    +

    Native Javascript extensions can be used for applications that embed a web-browser view or that embed a Javascript engine (such as node.js). Extending a general purpose web-browser is not possible as this would be a severe security issue.

    +

    SWIG Javascript currently supports JavascriptCore, the Javascript engine used by Safari/Webkit, and v8, which is used by Chromium and node.js.

    WebKit is a modern browser implementation available as open-source which can be embedded into an application.

    Preliminaries

    Running SWIG

    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index eae594727..72dc5c210 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -551,7 +551,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) { } default: { - Printf(stderr, "SWIG Javascript: Unknown emitter type.\n"); + Printf(stderr, "SWIG Javascript: Unknown emitter type. Please specify one of -jsc -v8 or -node.\n"); SWIG_exit(-1); break; } From 362583c63601abb0b6a39ea04c1a490cd432393d Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Wed, 16 Apr 2014 07:35:49 +0100 Subject: [PATCH 299/352] Javascript html documentation tidy up --- Doc/Manual/Javascript.html | 129 +++++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 57 deletions(-) diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html index 8d8f436ca..329ee4421 100644 --- a/Doc/Manual/Javascript.html +++ b/Doc/Manual/Javascript.html @@ -5,16 +5,21 @@ -

    SWIG and Javascript

    + +

    SWIG and Javascript

    This chapter describes SWIG's support of Javascript. It does not cover SWIG basics, but only information that is specific to this module.

    -

    Overview

    + +

    Overview

    Javascript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development. Javascript has gone beyond being a browser-based scripting language and with node.js, it is also used as a backend development language.

    Native Javascript extensions can be used for applications that embed a web-browser view or that embed a Javascript engine (such as node.js). Extending a general purpose web-browser is not possible as this would be a severe security issue.

    SWIG Javascript currently supports JavascriptCore, the Javascript engine used by Safari/Webkit, and v8, which is used by Chromium and node.js.

    WebKit is a modern browser implementation available as open-source which can be embedded into an application.

    -

    Preliminaries

    -

    Running SWIG

    + +

    Preliminaries

    + +

    Running SWIG

    +

    Suppose that you defined a SWIG module such as the following:

    @@ -44,13 +49,14 @@ bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports)

    and for v8:

    -void example_initialize (v8::Handle exports)
    +void example_initialize(v8::Handle exports)
    -
    -

    Note: be aware that v8 comes as a C++ API, and thus, the generated modules must be compiled as C++.

    -
    -

    Running Tests and Examples

    -

    The configuration for tests and examples currently supports Linux and Mac only, MinGW not yet.

    +

    +

    Note: be aware that v8 has a C++ API, and thus, the generated modules must be compiled as C++.

    +

    + +

    Running Tests and Examples

    +

    The configuration for tests and examples currently supports Linux and Mac only and not MinGW (Windows) yet.

    The default interpreter is node.js as it is available on all platforms and convenient to use.

    Running the examples with JavascriptCore requires libjavascriptcoregtk-1.0 to be installed, e.g., under Ubuntu with

    @@ -65,18 +71,13 @@ $ sudo apt-get install libv8-dev

    Examples can be run using

    -$ make ENGINE=jsc check-javascript-examples
    +$ make check-javascript-examples ENGINE=jsc

    ENGINE can be node, jsc, or v8.

    The test-suite can be run using

    -$ make ENGINE=jsc check-javascript-test-suite
    -
    -

    A smaller, manually selected set of tests can be run using

    -
    -
    -$ make SMOKE=1 ENGINE=jsc check-javascript-test-suite
    +$ make check-javascript-test-suite ENGINE=jsc

    Tests should run without any problems, i.e., have been tried out, on the following platforms/interpreters:

    @@ -95,19 +96,20 @@ $ make SMOKE=1 ENGINE=jsc check-javascript-test-suite - Windows 7 64bit (VS 2010) - Node.js
    -
    -

    Note: a CMake based configuration can be found in the cmake which can be used to generate a VisualStudio solution. It is rather limited and can only be used for building the SWIG executable.

    -
    -

    Future work

    -

    The Javascript module is not yet as mature as other modules and some things are still missing. As it makes use of Swigs Unified typemap library (UTL), many typemaps are inherited. We could work on that if requested:

    +

    + +

    Future work

    +

    The Javascript module is not yet as mature as other modules and some things are still missing. As it makes use of SWIG's Unified Typemap Library (UTL), many typemaps are inherited. We could work on that if requested:

    • More typemaps: compared to other modules there are only a few typemaps implemented. For instance a lot of the std_*.i typemaps are missing, such as std_iostream, for instance.

    • Director support: this would allow to extend a C++ abstract base class in Javascript. A pragmatic intermediate step for the most important usecase would be to support Javascript callbacks as arguments.

    -

    Integration

    + +

    Integration

    This chapter gives a short introduction how to use a native Javascript extension: as a node.js module, and as an extension for an embedded Webkit.

    -

    Creating node.js Extensions

    -

    To install node.js you can download an installer from their web-site for OSX and Windows. For Linux you can either build the source yourself and to a sudo checkinstall or stick to the (probably stone-age) packaged version. For Ubuntu there is a PPA available.

    + +

    Creating node.js Extensions

    +

    To install node.js you can download an installer from their web-site for OSX and Windows. For Linux you can either build the source yourself and run sudo checkinstall or keep to the (probably stone-age) packaged version. For Ubuntu there is a PPA available.

     $ sudo add-apt-repository ppa:chris-lea/node.js
    @@ -143,24 +145,27 @@ $ swig -javascript -node -c++ example.cxx
     $ node-gyp
    -

    This will create a build folder containing the native module. To use the extension you have to require it in your javascript source file.

    +

    This will create a build folder containing the native module. To use the extension you need to 'require' it in your Javascript source file:

     require("./build/Release/example")
    -

    A more detailed exlanation is given in section Examples.

    -

    Troubleshooting

    +

    A more detailed explanation is given in the Examples section.

    + +

    Troubleshooting

    • 'module' object has no attribute 'script_main'
    -

    This happened when gyp was installed as distribution package. It seems to be outdated. Removing it resolves the problem.

    +

    This error happens when gyp is installed as a distribution package. It seems to be outdated. Removing it resolves the problem.

     $ sudo apt-get remove gyp
    -

    Embedded Webkit

    -

    Webkit is built-in for OSX and available as library for GTK.

    -

    OSX

    + +

    Embedded Webkit

    +

    Webkit is pre-installed on OSX and available as a library for GTK.

    + +

    OSX

    There is general information about programming with WebKit on Apple Developer Documentation. Details about Cocoa programming are not covered here.

    An integration of a native extension 'example' would look like this:

    @@ -193,8 +198,9 @@ extern bool example_initialize(JSGlobalContextRef context); @end
    -

    GTK

    -

    There is general information about programming GTK on the GTK documentation, in the GTK tutorial, and for Webkit there is a Webkit GTK+ API Reference.

    + +

    GTK

    +

    There is general information about programming GTK at GTK documentation and in the GTK tutorial, and for Webkit there is a Webkit GTK+ API Reference.

    An integration of a native extension 'example' would look like this:

    @@ -229,13 +235,16 @@ int main(int argc, char* argv[])
         return 0;
     }
    -

    Creating Applications with node-webkit

    -
    + +

    Creating Applications with node-webkit

    +

    TODO: documentation is coming soon

    -
    -

    Examples

    +

    + +

    Examples

    Some basic examples are shown here in more detail.

    -

    Simple

    + +

    Simple

    The common example simple looks like this:

    @@ -247,7 +256,7 @@ extern int    gcd(int x, int y);
     extern double Foo;
     %}
    -

    To make this available as node extension a binding.gyp has to be created:

    +

    To make this available as a node extension a binding.gyp has to be created:

     {
    @@ -264,7 +273,7 @@ extern double Foo;
     
     $ node-gyp configure build
    -

    From a 'nodejs` application this would be used this way:

    +

    From a 'nodejs` application the extension would be used like this:

     // import the extension via require
    @@ -280,10 +289,11 @@ var f = example.Foo;
     example.Foo = 3.1415926;

    First the module example is loaded from the previously built extension. Global methods and variables are available in the scope of the module.

    -
    -

    Note: ECMAScript 5, the currently implemented Javascript standard, does not have modules. node.js and other implementations provide this mechanism defined by the CommonJS group. For browsers this is provided by Browserify, for instance.

    -
    -

    Class

    +

    +

    Note: ECMAScript 5, the currently implemented Javascript standard, does not have modules. node.js and other implementations provide this mechanism defined by the CommonJS group. For browsers this is provided by Browserify, for instance.

    +

    + +

    Class

    The common example class defines three classes, Shape, Circle, and Square:

    @@ -322,7 +332,7 @@ public:
     

    Circle and Square inherit from Shape. Shape has a static variable nshapes, a function move that can't be overridden (non-virtual), and two abstract functions area and perimeter (pure virtual) that must be overridden by the sub-classes.

    A nodejs extension is built the same way as for the simple example.

    -

    In javascript it can be used this way:

    +

    In Javascript it can be used as follows:

     var example = require("./build/Release/example");
    @@ -407,12 +417,14 @@ at ReadStream.onkeypress (readline.js:99:10)
     at ReadStream.EventEmitter.emit (events.js:98:17)
     at emitKey (readline.js:1095:12)
    -
    -

    Note: In ECMAScript 5 there is no concept for classes. Instead each function can be used as a constructor function which is executed by the 'new' operator. Furthermore, during construction the key property prototype of the constructor function is used to attach a prototype instance to the created object. A prototype is essentially an object itself that is the first-class delegate of a class used whenever the access to a property of an object fails. The very same prototype instance is shared among all instances of one type. Prototypal inheritance is explained in more detail on in Inheritance and the prototype chain, for instance.

    -
    -

    Implementation

    -

    The Javascript Module implementation has take a very different approach than other modules to be able to generate code for different Javascript interpreters.

    -

    Source Code

    +

    +

    Note: In ECMAScript 5 there is no concept for classes. Instead each function can be used as a constructor function which is executed by the 'new' operator. Furthermore, during construction the key property prototype of the constructor function is used to attach a prototype instance to the created object. A prototype is essentially an object itself that is the first-class delegate of a class used whenever the access to a property of an object fails. The very same prototype instance is shared among all instances of one type. Prototypal inheritance is explained in more detail on in Inheritance and the prototype chain, for instance.

    +

    + +

    Implementation

    +

    The Javascript Module implementation has taken a very different approach compared to other language modules in order to support different Javascript interpreters.

    + +

    Source Code

    The Javascript module is implemented in Source/Modules/javascript.cxx. It dispatches the code generation to a JSEmitter instance, V8Emitter or JSCEmitter. Additionally there are some helpers: Template, for templated code generation, and JSEmitterState, which is used to manage state information during AST traversal. This rough map shall make it easier to find a way through this huge source file:

    @@ -510,7 +522,8 @@ JSEmitterState::JSEmitterState() { ... }
     Template::Template(const String *code_) { ... }
     ...
    -

    Code Templates

    + +

    Code Templates

    All generated code is created on the basis of code templates. The templates for JavascriptCore can be found in Lib/javascript/jsc/javascriptcode.swg, for v8 in Lib/javascript/v8/javascriptcode.swg.

    To track the originating code template for generated code you can run

    @@ -520,11 +533,11 @@ $ swig -javascript -jsc -debug-codetemplates

    which wraps generated code with a descriptive comment

    -/* begin fragment("temlate_name") */
    +/* begin fragment("template_name") */
     
     ...generated code ...
     
    -/* end fragment("temlate_name") */
    +/* end fragment("template_name") */

    The Template class is used like this:

    @@ -546,7 +559,8 @@ t_register.replace("$jsparent", state.clazz(NAME_MANGLED)) %}

    Template creates a copy of that string and Template::replace uses Swig's Replaceall to replace variables in the template. Template::trim can be used to eliminate leading and trailing whitespaces. Template::print is used to write the final template string to a Swig DOH (based on Printv). All methods allow chaining.

    -

    Emitter

    + +

    Emitter

    The Javascript module delegates code generation to a JSEmitter instance. The following extract shows the essential interface:

    @@ -662,7 +676,8 @@ int JAVASCRIPT::classHandler(Node *n) {
     }

    In enterClass the emitter stores state information that is necessary when processing class members. In exitClass the wrapper code for the whole class is generated.

    -

    Emitter states

    + +

    Emitter states

    For storing information during the AST traversal the emitter provides a JSEmitterState with different slots to store data representing the scopes global, class, function, and variable.

    
    From 4837c5c9eb172d400a8e82e83b0bed2e2e36bda8 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Wed, 16 Apr 2014 07:50:28 +0100
    Subject: [PATCH 300/352] Add missing license info
    
    ---
     Source/Modules/javascript.cxx | 13 +++++++++++++
     1 file changed, 13 insertions(+)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index 72dc5c210..3ea632ef8 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -1,3 +1,16 @@
    +/* -----------------------------------------------------------------------------
    + * This file is part of SWIG, which is licensed as a whole under version 3 
    + * (or any later version) of the GNU General Public License. Some additional
    + * terms also apply to certain portions of SWIG. The full details of the SWIG
    + * license and copyrights can be found in the LICENSE and COPYRIGHT files
    + * included with the SWIG source code as distributed by the SWIG developers
    + * and at http://www.swig.org/legal.html.
    + *
    + * javascript.cxx
    + *
    + * Javascript language module for SWIG.
    + * ----------------------------------------------------------------------------- */
    +
     #include "swigmod.h"
     
     /**
    
    From c67cdd5b301bee08cab6d3cb3a0766578972c08c Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Wed, 16 Apr 2014 07:59:24 +0100
    Subject: [PATCH 301/352] Revert css style changes in javascript branch
    
    ---
     Doc/Manual/style.css | 6 +-----
     1 file changed, 1 insertion(+), 5 deletions(-)
    
    diff --git a/Doc/Manual/style.css b/Doc/Manual/style.css
    index 7eabf91ae..02329e56f 100644
    --- a/Doc/Manual/style.css
    +++ b/Doc/Manual/style.css
    @@ -25,7 +25,7 @@ div.indent {
       margin-right: 4em;
     }
     
    -div.code, div:not(.code) pre {
    +div.code {
       border-style: solid; 
       border-width: 1px; 
       padding: 2pt; 
    @@ -82,7 +82,3 @@ div.indent p {
       margin-right: 0;
     }
     
    -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
    -  text-decoration:none;
    -  color: #000000;
    -}
    
    From 9587c133c54146547b5650d2881a1c2b0c4b961a Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sat, 19 Apr 2014 15:55:12 +0100
    Subject: [PATCH 302/352] Fix typo in Javascript exception
    
    ---
     Lib/javascript/jsc/javascriptcode.swg | 2 +-
     Lib/javascript/v8/javascriptcode.swg  | 2 +-
     2 files changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg
    index 60c52b2b3..738b54d70 100644
    --- a/Lib/javascript/jsc/javascriptcode.swg
    +++ b/Lib/javascript/jsc/javascriptcode.swg
    @@ -53,7 +53,7 @@ JSObjectRef $jswrapper(JSContextRef context, JSObjectRef ctorObject,
         $jsdispatchcases
     
         // default:
    -    SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsname");
    +    SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for construction of $jsname");
     
         fail:
         return thisObject;
    diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg
    index 9bcb33176..67a81146e 100644
    --- a/Lib/javascript/v8/javascriptcode.swg
    +++ b/Lib/javascript/v8/javascriptcode.swg
    @@ -55,7 +55,7 @@ SwigV8ReturnValue $jswrapper(const SwigV8Arguments& args) {
       $jsdispatchcases
     
       // default:
    -  SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for contruction of $jsmangledname");
    +  SWIG_exception_fail(SWIG_ERROR, "Illegal arguments for construction of $jsmangledname");
     
     fail:
       SWIGV8_RETURN(v8::Undefined());
    
    From efc5af04e07a168c1fa6456f179b30ebfe08bad7 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sat, 19 Apr 2014 16:44:21 +0100
    Subject: [PATCH 303/352] Detect node-gyp at configure time and show version in
     javascript_version target
    
    ---
     Examples/Makefile.in                       | 24 ++++++++--------------
     Examples/test-suite/javascript/Makefile.in |  3 ++-
     configure.ac                               |  8 ++++++--
     3 files changed, 17 insertions(+), 18 deletions(-)
    
    diff --git a/Examples/Makefile.in b/Examples/Makefile.in
    index 5c203b398..25b3cb588 100644
    --- a/Examples/Makefile.in
    +++ b/Examples/Makefile.in
    @@ -604,6 +604,8 @@ JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@
     JSSO =@JSSO@
     JSLDSHARED = @JSLDSHARED@
     JSCXXSHARED = @JSCXXSHARED@
    +NODEJS = @NODEJS@
    +NODEGYP = @NODEGYP@
     
     # ----------------------------------------------------------------
     # Creating and building Javascript wrappers
    @@ -623,9 +625,8 @@ javascript_build_cpp:: $(SRCS)
     	$(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES)
     	$(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
     
    -# TODO: make node-gyp configurable and detected via ./configure
     javascript_build_node: $(SRCS)
    -	node-gyp --loglevel=silent configure build 1>>/dev/null
    +	$(NODEGYP) --loglevel=silent configure build 1>>/dev/null
     
     # These targets are used by the test-suite:
     
    @@ -649,42 +650,35 @@ javascript_custom_interpreter:
     javascript_run: javascript_custom_interpreter
     	$(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) -L $(TARGET) runme.js
     
    -# TODO: make node configurable and detected via ./configure
     javascript_run_node:
    -	@NODEJS@ runme.js
    +	$(NODEJS) runme.js
     
     # -----------------------------------------------------------------
     # Version display
     # -----------------------------------------------------------------
     
    -ifeq (, $(ENGINE))
     javascript_version:
    -	@ if [ "@NODEJS@" != "" ]; then \
    -		echo "Node.js: `(@NODEJS@ --version)`"; \
    +ifeq (, $(ENGINE))
    +	@ if [ "$(NODEJS)" != "" ]; then \
    +		echo "Node.js: `($(NODEJS) --version)`"; \
     	  else \
     	    echo "Version depends on the interpreter"; \
     	  fi
     endif
    -
     ifeq (node, $(ENGINE))
    -javascript_version:
    -	@NODEJS@ --version
    +	$(NODEJS) --version
     endif
    -
     ifeq (jsc, $(ENGINE))
    -javascript_version:
     	@ if [ "@JSCOREVERSION@" != "" ]; then \
     		echo "@JSCOREVERSION@"; \
     	  else \
     	    echo "Unknown JavascriptCore version."; \
     	  fi
     endif
    -
     ifeq (v8, $(ENGINE))
    -javascript_version:
     	echo "Unknown v8 version."
     endif
    -
    +	echo "node-gyp: `($(NODEGYP) --version)`"
     
     # -----------------------------------------------------------------
     # Cleaning the javascript examples
    diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
    index 259869f98..0d861173e 100755
    --- a/Examples/test-suite/javascript/Makefile.in
    +++ b/Examples/test-suite/javascript/Makefile.in
    @@ -3,6 +3,7 @@
     #######################################################################
     
     LANGUAGE     = javascript
    +NODEGYP = @NODEGYP@
     SCRIPTSUFFIX = _runme.js
     srcdir       = @srcdir@
     top_srcdir   = @top_srcdir@
    @@ -104,7 +105,7 @@ ifeq (node,$(JSENGINE))
     		$(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i;
     
     	nodejs_swig_and_compile = \
    -		node-gyp --loglevel=silent --directory $* configure build 1>>/dev/null
    +		$(NODEGYP) --loglevel=silent --directory $* configure build 1>>/dev/null
     
     	run_testcase = \
     		if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \
    diff --git a/configure.ac b/configure.ac
    index b214ed9e4..aac978ae3 100644
    --- a/configure.ac
    +++ b/configure.ac
    @@ -1131,11 +1131,14 @@ else
       esac
     
       #----------------------------------------------------------------
    -  # Look for Node.js which is the default javascript engine
    +  # Look for Node.js which is the default Javascript engine
       #----------------------------------------------------------------
     
       AC_CHECK_PROGS(NODEJS, node)
     
    +  # node-gyp is needed to run the test-suite/examples for all Javascript engines
    +  AC_CHECK_PROGS(NODEGYP, node-gyp)
    +
       #----------------------------------------------------------------
       # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING)
       #----------------------------------------------------------------
    @@ -1302,6 +1305,7 @@ AC_SUBST(JSCENABLED)
     AC_SUBST(JSV8ENABLED)
     
     AC_SUBST(NODEJS)
    +AC_SUBST(NODEGYP)
     
     #----------------------------------------------------------------
     # Look for gcj
    @@ -2455,7 +2459,7 @@ fi
     AC_SUBST(SKIP_JAVA)
     
     SKIP_JAVASCRIPT=
    -if test -z "$JAVASCRIPT" || test -z "$NODEJS"; then
    +if test -z "$JAVASCRIPT" || test -z "$NODEJS" || test -z "$NODEGYP"; then
         SKIP_JAVASCRIPT="1"
     fi
     AC_SUBST(SKIP_JAVASCRIPT)
    
    From aae63efcfeefa22f3df2a20ade00f2103eb61820 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sat, 19 Apr 2014 17:59:49 +0100
    Subject: [PATCH 304/352] Remove unnecessary blank lines from Javascript
     examples
    
    ---
     Examples/javascript/constant/runme.js     | 22 ++++++-------
     Examples/javascript/pointer/runme.js      | 10 +++---
     Examples/javascript/reference/runme.js    | 14 ++++----
     Examples/javascript/variables/example.cxx |  2 +-
     Examples/javascript/variables/runme.js    | 40 +++++++++++------------
     5 files changed, 44 insertions(+), 44 deletions(-)
    
    diff --git a/Examples/javascript/constant/runme.js b/Examples/javascript/constant/runme.js
    index 2188bf099..f4b55881e 100755
    --- a/Examples/javascript/constant/runme.js
    +++ b/Examples/javascript/constant/runme.js
    @@ -1,14 +1,14 @@
     var example = require("./example");
     
    -console.log("ICONST  = " + example.ICONST  + " (should be 42)\n");
    -console.log("FCONST  = " + example.FCONST  + " (should be 2.1828)\n");
    -console.log("CCONST  = " + example.CCONST  + " (should be 'x')\n");  
    -console.log("CCONST2 = " + example.CCONST2 + " (this should be on a new line)\n"); 
    -console.log("SCONST  = " + example.SCONST  + " (should be 'Hello World')\n");
    -console.log("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')\n");
    -console.log("EXPR    = " + example.EXPR    + " (should be 48.5484)\n");
    -console.log("iconst  = " + example.iconst  + " (should be 37)\n"); 
    -console.log("fconst  = " + example.fconst  + " (should be 3.14)\n"); 
    +console.log("ICONST  = " + example.ICONST  + " (should be 42)");
    +console.log("FCONST  = " + example.FCONST  + " (should be 2.1828)");
    +console.log("CCONST  = " + example.CCONST  + " (should be 'x')");  
    +console.log("CCONST2 = " + example.CCONST2 + " (this should be on a new line)"); 
    +console.log("SCONST  = " + example.SCONST  + " (should be 'Hello World')");
    +console.log("SCONST2 = " + example.SCONST2 + " (should be '\"Hello World\"')");
    +console.log("EXPR    = " + example.EXPR    + " (should be 48.5484)");
    +console.log("iconst  = " + example.iconst  + " (should be 37)"); 
    +console.log("fconst  = " + example.fconst  + " (should be 3.14)"); 
     
    -console.log("EXTERN = " + example.EXTERN   + " (should be undefined)\n");
    -console.log("FOO    = " + example.FOO      + " (should be undefined)\n");
    +console.log("EXTERN = " + example.EXTERN   + " (should be undefined)");
    +console.log("FOO    = " + example.FOO      + " (should be undefined)");
    diff --git a/Examples/javascript/pointer/runme.js b/Examples/javascript/pointer/runme.js
    index 7f1e51c9e..fb8cf0c74 100755
    --- a/Examples/javascript/pointer/runme.js
    +++ b/Examples/javascript/pointer/runme.js
    @@ -1,7 +1,7 @@
     var example = require("./example");
     
     // First create some objects using the pointer library.
    -console.log("Testing the pointer library\n");
    +console.log("Testing the pointer library");
     a = example.new_intp();
     b = example.new_intp();
     c = example.new_intp();
    @@ -9,9 +9,9 @@ c = example.new_intp();
     example.intp_assign(a,37);
     example.intp_assign(b,42);
     
    -console.log(" a = " + example.intp_value(a) + "\n");
    -console.log(" b = " + example.intp_value(b) + "\n");
    -console.log(" c = " + example.intp_value(c) + "\n");
    +console.log(" a = " + example.intp_value(a));
    +console.log(" b = " + example.intp_value(b));
    +console.log(" c = " + example.intp_value(c));
     
     //// Call the add() function with some pointers
     example.add(a, b, c);
    @@ -19,7 +19,7 @@ example.add(a, b, c);
     //
     //// Now get the result
     r = example.intp_value(c);
    -console.log(" 37 + 42 = " + r + "\n");
    +console.log(" 37 + 42 = " + r);
     
     // Clean up the pointers
     example.delete_intp(a);
    diff --git a/Examples/javascript/reference/runme.js b/Examples/javascript/reference/runme.js
    index 935d2b948..88c108314 100755
    --- a/Examples/javascript/reference/runme.js
    +++ b/Examples/javascript/reference/runme.js
    @@ -3,7 +3,7 @@ var example = require("./example");
     
     // ----- Object creation -----
     
    -console.log("Creating some objects:\n");
    +console.log("Creating some objects:");
     a = new example.Vector(3,4,5);
     b = new example.Vector(10,11,12);
     
    @@ -15,7 +15,7 @@ console.log("   created" + b.print());
     // This calls the wrapper we placed around operator+(const Vector &a, const Vector &) 
     // It returns a new allocated object.
     
    -console.log("Adding a+b\n");
    +console.log("Adding a+b");
     c = example.addv(a, b);
     console.log("a+b = " + c.print());
     
    @@ -26,9 +26,9 @@ console.log("a+b = " + c.print());
     // ----- Create a vector array -----
     
     // Note: Using the high-level interface here
    -console.log("Creating an array of vectors\n");
    +console.log("Creating an array of vectors");
     va = new example.VectorArray(10);
    -console.log("va = " + va + "\n");	 
    +console.log("va = " + va);	 
     
     // ----- Set some values in the array -----
     
    @@ -46,20 +46,20 @@ va.set(2,example.addv(a,b));
     
     // Get some values from the array
     
    -console.log("Getting some array values\n");
    +console.log("Getting some array values");
     for (i = 0; i < 5; i++) {
     	temp = va.get(i);
         console.log(i,temp.print());
     }
     
     // Watch under resource meter to check on this
    -console.log("Making sure we don't leak memory.\n");
    +console.log("Making sure we don't leak memory.");
     for (i = 0; i < 1000000; i++) {
         c = va.get(i % 10);
     }
     //---------TODO---------
     //----- Clean up -----
    -//console.log("Cleaning up\n");
    +//console.log("Cleaning up");
     
     //example.delete_VectorArray(va);
     //example.delete_Vector(a);
    diff --git a/Examples/javascript/variables/example.cxx b/Examples/javascript/variables/example.cxx
    index 3ad4c2323..f10390a9e 100755
    --- a/Examples/javascript/variables/example.cxx
    +++ b/Examples/javascript/variables/example.cxx
    @@ -56,7 +56,7 @@ void print_vars() {
       printf("dvar      = %g\n", dvar);
       printf("cvar      = %c\n", cvar);
       printf("strvar    = %s\n", strvar ? strvar : "(null)");
    -  printf("cstrvar   = %s\n", cstrvar ? cstrvar : "(null)");
    +  printf("cstrvar   = %s\n", cstrvar);
       printf("iptrvar   = %p\n", iptrvar);
       printf("name      = %s\n", name);
       printf("ptptr     = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0);
    diff --git a/Examples/javascript/variables/runme.js b/Examples/javascript/variables/runme.js
    index d07861713..537e17296 100755
    --- a/Examples/javascript/variables/runme.js
    +++ b/Examples/javascript/variables/runme.js
    @@ -18,27 +18,27 @@ example.ptptr  = example.new_Point(37,42);
     example.name   = "Bill";
     
     // Now console.log out the values of the variables
    -console.log("Variables (values console.loged from Python)" + "\n");
    -console.log("ivar      = " + example.ivar  + "\n");
    -console.log("svar      = " + example.svar  + "\n");
    -console.log("lvar      = " + example.lvar  + "\n");
    -console.log("uivar     = " + example.uivar + "\n");
    -console.log("usvar     = " + example.usvar + "\n");
    -console.log("ulvar     = " + example.ulvar + "\n");
    -console.log("scvar     = " + example.scvar + "\n");
    -console.log("ucvar     = " + example.ucvar + "\n");
    -console.log("fvar      = " + example.fvar  + "\n");
    -console.log("dvar      = " + example.dvar  + "\n");
    -console.log("cvar      = " + example.cvar  + "\n");
    -console.log("strvar    = " + example.strvar+ "\n");
    -console.log("cstrvar   = " + example.cstrvar+ "\n");
    -console.log("iptrvar   = " + example.iptrvar+ "\n");
    -console.log("name      = " + example.name + "\n");
    -console.log("ptptr     = " + example.ptptr + ": " + example.Point_print(example.ptptr) + "\n");
    -console.log("pt        = " + example.pt + ": " + example.Point_print(example.pt) + "\n");
    +console.log("Variables (values printed from Javascript)");
    +console.log("ivar      = " + example.ivar);
    +console.log("svar      = " + example.svar);
    +console.log("lvar      = " + example.lvar);
    +console.log("uivar     = " + example.uivar);
    +console.log("usvar     = " + example.usvar);
    +console.log("ulvar     = " + example.ulvar);
    +console.log("scvar     = " + example.scvar);
    +console.log("ucvar     = " + example.ucvar);
    +console.log("fvar      = " + example.fvar);
    +console.log("dvar      = " + example.dvar);
    +console.log("cvar      = " + example.cvar);
    +console.log("strvar    = " + example.strvar);
    +console.log("cstrvar   = " + example.cstrvar);
    +console.log("iptrvar   = " + example.iptrvar);
    +console.log("name      = " + example.name);
    +console.log("ptptr     = " + example.ptptr + ": " + example.Point_print(example.ptptr));
    +console.log("pt        = " + example.pt + ": " + example.Point_print(example.pt));
     
     
    -console.log("\nVariables (values console.loged from C)");
    +console.log("\nVariables (values printed from C)");
     
     example.print_vars();
     
    @@ -61,7 +61,7 @@ try{
         console.log("Good.");
     }
     
    -console.log("\nI'm going to try and update a structure variable.\n");
    +console.log("\nI'm going to try and update a structure variable.");
     example.pt = example.ptptr;
     console.log("The new value is: ");
     example.pt_print();
    
    From ffe4bd8f6074d01c9c25ed7bdc9c8a1170177db2 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sat, 19 Apr 2014 18:09:52 +0100
    Subject: [PATCH 305/352] ADD RUNPIPE and RUNTOOL to Javascript examples
    
    ---
     Examples/Makefile.in | 28 ++++++++++++++--------------
     1 file changed, 14 insertions(+), 14 deletions(-)
    
    diff --git a/Examples/Makefile.in b/Examples/Makefile.in
    index 25b3cb588..63c34ed29 100644
    --- a/Examples/Makefile.in
    +++ b/Examples/Makefile.in
    @@ -641,17 +641,17 @@ javascript_cpp: $(SRCS) javascript_custom_interpreter
     	$(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
     
     # -----------------------------------------------------------------
    -# Running a javascript example
    +# Running a Javascript example
     # -----------------------------------------------------------------
     
     javascript_custom_interpreter:
     	(cd $(ROOT_DIR)/Tools/javascript && $(MAKE) JSENGINE='$(JSENGINE)')
     
     javascript_run: javascript_custom_interpreter
    -	$(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) -L $(TARGET) runme.js
    +	$(RUNTOOL) $(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) -L $(TARGET) runme.js $(RUNPIPE)
     
     javascript_run_node:
    -	$(NODEJS) runme.js
    +	$(RUNTOOL) $(NODEJS) runme.js $(RUNPIPE)
     
     # -----------------------------------------------------------------
     # Version display
    @@ -659,21 +659,21 @@ javascript_run_node:
     
     javascript_version:
     ifeq (, $(ENGINE))
    -	@ if [ "$(NODEJS)" != "" ]; then \
    -		echo "Node.js: `($(NODEJS) --version)`"; \
    -	  else \
    -	    echo "Version depends on the interpreter"; \
    -	  fi
    +	@if [ "$(NODEJS)" != "" ]; then \
    +	  echo "Node.js: `($(NODEJS) --version)`"; \
    +	else \
    +	  echo "Version depends on the interpreter"; \
    +	fi
     endif
     ifeq (node, $(ENGINE))
     	$(NODEJS) --version
     endif
     ifeq (jsc, $(ENGINE))
    -	@ if [ "@JSCOREVERSION@" != "" ]; then \
    -		echo "@JSCOREVERSION@"; \
    -	  else \
    -	    echo "Unknown JavascriptCore version."; \
    -	  fi
    +	@if [ "@JSCOREVERSION@" != "" ]; then \
    +	  echo "@JSCOREVERSION@"; \
    +	else \
    +	  echo "Unknown JavascriptCore version."; \
    +	fi
     endif
     ifeq (v8, $(ENGINE))
     	echo "Unknown v8 version."
    @@ -681,7 +681,7 @@ endif
     	echo "node-gyp: `($(NODEGYP) --version)`"
     
     # -----------------------------------------------------------------
    -# Cleaning the javascript examples
    +# Cleaning the Javascript examples
     # -----------------------------------------------------------------
     
     javascript_clean:
    
    From ccaf3bfe79529a68da8d7704dedffce267bcf4f8 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sat, 19 Apr 2014 19:15:13 +0100
    Subject: [PATCH 306/352] Javascript test-suite makefile update
    
    Reword output to what is now on master
    Remove SMOKE targets - these could be re-introduced centrally if needed
    or otherwise partialcheck is a good alternative.
    ---
     Examples/test-suite/common.mk              | 25 ----------
     Examples/test-suite/javascript/Makefile.in | 53 ++--------------------
     2 files changed, 3 insertions(+), 75 deletions(-)
    
    diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
    index ec18d344c..a55d31f82 100644
    --- a/Examples/test-suite/common.mk
    +++ b/Examples/test-suite/common.mk
    @@ -92,15 +92,10 @@ CPP_TEST_BROKEN += \
     	template_expr \
     	$(CPP11_TEST_BROKEN)
     
    -
     # Broken C test cases. (Can be run individually using: make testcase.ctest)
     C_TEST_BROKEN += \
     	tag_no_clash_with_variable
     
    -# Note: this allows to override the global list of tests for the purpose of
    -# smoke testing to foster shorter test-driven development cycles
    -ifndef SMOKE_TESTS_ONLY
    -
     # C++ test cases. (Can be run individually using: make testcase.cpptest)
     CPP_TEST_CASES += \
     	abstract_access \
    @@ -497,11 +492,6 @@ CPP_TEST_CASES += \
     	wallkw \
     	wrapmacro
     
    -endif #SMOKE_TESTS_ONLY
    -
    -
    -ifndef SMOKE_TESTS_ONLY
    -
     # C++11 test cases.
     CPP11_TEST_CASES = \
     	cpp11_alignment \
    @@ -535,8 +525,6 @@ CPP11_TEST_CASES = \
     	cpp11_unrestricted_unions \
     	cpp11_userdefined_literals \
     
    -endif # SMOKE_TESTS_ONLY
    -
     # Broken C++11 test cases.
     CPP11_TEST_BROKEN = \
     #	cpp11_hash_tables \           # not fully implemented yet
    @@ -544,8 +532,6 @@ CPP11_TEST_BROKEN = \
     #	cpp11_variadic_templates \    # Broken for some languages (such as Java)
     #	cpp11_reference_wrapper \     # No typemaps
     
    -ifndef SMOKE_TESTS_ONLY
    -
     #
     # Put all the heavy STD/STL cases here, where they can be skipped if needed
     #
    @@ -570,17 +556,12 @@ CPP_STD_TEST_CASES += \
     	template_opaque
     #        li_std_list
     
    -endif # SMOKE_TESTS_ONLY
    -
     CPP_TEST_CASES += ${CPP_STD_TEST_CASES}
     
     ifneq (,$(HAVE_CXX11_COMPILER))
     CPP_TEST_CASES += $(CPP11_TEST_CASES)
     endif
     
    -
    -ifndef SMOKE_TESTS_ONLY
    -
     # C test cases. (Can be run individually using: make testcase.ctest)
     C_TEST_CASES += \
     	arrays \
    @@ -634,10 +615,6 @@ C_TEST_CASES += \
     	union_parameter \
     	unions
     
    -endif # SMOKE_TESTS_ONLY
    -
    -ifndef SMOKE_TESTS_ONLY
    -
     # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest)
     MULTI_CPP_TEST_CASES += \
     	clientdata_prop \
    @@ -648,8 +625,6 @@ MULTI_CPP_TEST_CASES += \
     	template_typedef_import \
     	multi_import
     
    -endif # SMOKE_TESTS_ONLY
    -
     # Custom tests - tests with additional commandline options
     wallkw.cpptest: SWIGOPT += -Wallkw
     preproc_include.ctest: SWIGOPT += -includeall
    diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
    index 0d861173e..2074f89af 100755
    --- a/Examples/test-suite/javascript/Makefile.in
    +++ b/Examples/test-suite/javascript/Makefile.in
    @@ -16,67 +16,20 @@ else
     	JSENGINE=node
     endif
     
    -ifeq (1,$(SMOKE))
    -
    -C_TEST_CASES = \
    -  preproc \
    -  preproc_include
    -
    -CPP_TEST_CASES = \
    -  abstract_access \
    -  abstract_typedef \
    -  abstract_typedef2 \
    -  abstract_virtual \
    -  arrays_global \
    -  array_member \
    -  char_binary \
    -  class_ignore \
    -  class_scope_weird \
    -  complextest \
    -  constover \
    -  constructor_copy \
    -  cpp_enum \
    -  cpp_namespace \
    -  cpp_static \
    -  enum_template \
    -  namespace_virtual_method \
    -  nspace \
    -  nspace_extend \
    -  overload_copy \
    -  rename_simple \
    -  rename_scope \
    -  ret_by_value \
    -  struct_value \
    -  template_static \
    -  typedef_class \
    -  typedef_inherit \
    -  typedef_scope \
    -  typemap_arrays \
    -  typemap_delete \
    -  typemap_namespace \
    -  typemap_ns_using \
    -  using1 \
    -  using2 \
    -  javascript_unicode
    -
    -SMOKE_TESTS_ONLY=1
    -
    -endif
    -
     include $(srcdir)/../common.mk
     
     _setup = \
     	if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then	  \
    -	  echo "$(ACTION)ing testcase $* (with run test) under javascript ($(JSENGINE))" ; \
    +	  echo "$(ACTION)ing $(LANGUAGE) ($(JSENGINE)) testcase $* (with run test)" ; \
     	else								  \
    -	  echo "$(ACTION)ing testcase $* under javascript ($(JSENGINE))" ;		  \
    +	  echo "$(ACTION)ing $(LANGUAGE) ($(JSENGINE)) testcase $*" ;     \
     	fi;
     
     ifneq (jsc,$(ENGINE))
     
       # This test can not be run with v8 as it uses v8 API incompatible output typemaps
       typemap_variables.cpptest:
    -		echo "skipping testcase typemap_variables under javascript ($(JSENGINE))."
    +	  echo "skipping $(LANGUAGE) ($(JSENGINE)) testcase $*" ;
     
       # with v8 we have to generate C++ wrappers only
       # these tests did raise warnings which are ignored
    
    From 088d3f631907fb3983400b41648be7a076c28ea1 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sun, 20 Apr 2014 13:53:20 +0100
    Subject: [PATCH 307/352] Restore missing make code in javascript branch
    
    ---
     Examples/test-suite/common.mk | 6 ++++++
     1 file changed, 6 insertions(+)
    
    diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
    index a55d31f82..67f99b0b1 100644
    --- a/Examples/test-suite/common.mk
    +++ b/Examples/test-suite/common.mk
    @@ -92,6 +92,7 @@ CPP_TEST_BROKEN += \
     	template_expr \
     	$(CPP11_TEST_BROKEN)
     
    +
     # Broken C test cases. (Can be run individually using: make testcase.ctest)
     C_TEST_BROKEN += \
     	tag_no_clash_with_variable
    @@ -532,6 +533,7 @@ CPP11_TEST_BROKEN = \
     #	cpp11_variadic_templates \    # Broken for some languages (such as Java)
     #	cpp11_reference_wrapper \     # No typemaps
     
    +
     #
     # Put all the heavy STD/STL cases here, where they can be skipped if needed
     #
    @@ -556,7 +558,10 @@ CPP_STD_TEST_CASES += \
     	template_opaque
     #        li_std_list
     
    +
    +ifndef SKIP_CPP_STD_CASES
     CPP_TEST_CASES += ${CPP_STD_TEST_CASES}
    +endif
     
     ifneq (,$(HAVE_CXX11_COMPILER))
     CPP_TEST_CASES += $(CPP11_TEST_CASES)
    @@ -615,6 +620,7 @@ C_TEST_CASES += \
     	union_parameter \
     	unions
     
    +
     # Multi-module C++ test cases . (Can be run individually using make testcase.multicpptest)
     MULTI_CPP_TEST_CASES += \
     	clientdata_prop \
    
    From f105590c0afc4e7da62d3eb45b86062acc6bc971 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sat, 19 Apr 2014 19:19:44 +0100
    Subject: [PATCH 308/352] Javascript node test-suite makefile fixes for
     parallel make
    
    ---
     Examples/test-suite/javascript/Makefile.in | 7 ++++---
     1 file changed, 4 insertions(+), 3 deletions(-)
    
    diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
    index 2074f89af..54fec63f9 100755
    --- a/Examples/test-suite/javascript/Makefile.in
    +++ b/Examples/test-suite/javascript/Makefile.in
    @@ -58,7 +58,8 @@ ifeq (node,$(JSENGINE))
     		$(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i;
     
     	nodejs_swig_and_compile = \
    -		$(NODEGYP) --loglevel=silent --directory $* configure build 1>>/dev/null
    +		$(NODEGYP) --loglevel=silent --directory $* configure 1>>/dev/null
    +		$(NODEGYP) --loglevel=silent --directory $* build 1>>/dev/null
     
     	run_testcase = \
     		if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \
    @@ -68,13 +69,13 @@ ifeq (node,$(JSENGINE))
       %.cpptest:
     		$(_setup)
     		$(__setup)
    -		$(nodejs_swig_and_compile)
    +		+$(nodejs_swig_and_compile)
     		$(run_testcase)
     
       %.ctest:
     		$(_setup)
     		$(__setup)
    -		$(nodejs_swig_and_compile)
    +		+$(nodejs_swig_and_compile)
     		$(run_testcase)
     
       %.multicpptest:
    
    From 1010fbaa8f64b325426927bd561a0359b99074ba Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sun, 20 Apr 2014 13:18:16 +0100
    Subject: [PATCH 309/352] Simple C string test
    
    Was added for Javascript, but was not being used in full test-suite.
    Rename from javascript_unicode to simple_string and provide for all
    languages.
    Rewrite to use portable C
    ---
     Examples/test-suite/common.mk                       |  1 +
     .../javascript/javascript_unicode_runme.js          |  9 ---------
     .../test-suite/javascript/string_simple_runme.js    | 10 ++++++++++
     Examples/test-suite/javascript_unicode.i            | 10 ----------
     Examples/test-suite/string_simple.i                 | 13 +++++++++++++
     5 files changed, 24 insertions(+), 19 deletions(-)
     delete mode 100644 Examples/test-suite/javascript/javascript_unicode_runme.js
     create mode 100644 Examples/test-suite/javascript/string_simple_runme.js
     delete mode 100644 Examples/test-suite/javascript_unicode.i
     create mode 100644 Examples/test-suite/string_simple.i
    
    diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
    index 67f99b0b1..b7a539035 100644
    --- a/Examples/test-suite/common.mk
    +++ b/Examples/test-suite/common.mk
    @@ -613,6 +613,7 @@ C_TEST_CASES += \
     	simple_array \
     	sizeof_pointer \
     	sneaky1 \
    +	string_simple \
     	struct_rename \
     	struct_initialization \
     	typedef_struct \
    diff --git a/Examples/test-suite/javascript/javascript_unicode_runme.js b/Examples/test-suite/javascript/javascript_unicode_runme.js
    deleted file mode 100644
    index f5f747aa7..000000000
    --- a/Examples/test-suite/javascript/javascript_unicode_runme.js
    +++ /dev/null
    @@ -1,9 +0,0 @@
    -var javascript_unicode = require("./javascript_unicode");
    -
    -var str = "olé";
    -
    -var copy = javascript_unicode.copy_string(str);
    -
    -if (str !== copy) {
    -	print("Error: copy is not equal: original="+str+", copy="+copy);
    -}
    diff --git a/Examples/test-suite/javascript/string_simple_runme.js b/Examples/test-suite/javascript/string_simple_runme.js
    new file mode 100644
    index 000000000..dbdd4136d
    --- /dev/null
    +++ b/Examples/test-suite/javascript/string_simple_runme.js
    @@ -0,0 +1,10 @@
    +var string_simple = require("./string_simple");
    +
    +// Test unicode string
    +var str = "olé";
    +
    +var copy = string_simple.copy_string(str);
    +
    +if (str !== copy) {
    +  throw "Error: copy is not equal: original="+str+", copy="+copy;
    +}
    diff --git a/Examples/test-suite/javascript_unicode.i b/Examples/test-suite/javascript_unicode.i
    deleted file mode 100644
    index 516eee5dd..000000000
    --- a/Examples/test-suite/javascript_unicode.i
    +++ /dev/null
    @@ -1,10 +0,0 @@
    -%module javascript_unicode
    -
    -%newobject copy_string;
    -
    -%inline %{
    -#include 
    -const char* copy_string(const char* str) {
    -	return strdup(str);
    -}
    -%}
    diff --git a/Examples/test-suite/string_simple.i b/Examples/test-suite/string_simple.i
    new file mode 100644
    index 000000000..5f5cc00bb
    --- /dev/null
    +++ b/Examples/test-suite/string_simple.i
    @@ -0,0 +1,13 @@
    +%module string_simple
    +
    +%newobject copy_string;
    +
    +%inline %{
    +#include 
    +const char* copy_string(const char* str) {
    +  size_t len = strlen(str);
    +  char* newstring = malloc(len + 1);
    +  strcpy(newstring, str);
    +  return newstring;
    +}
    +%}
    
    From bebd97e7f4b34f5fda27e886c72f249895c4cd2e Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Sun, 20 Apr 2014 14:25:49 +0100
    Subject: [PATCH 310/352] Restore and fix infinity testcase for Javascript
    
    ---
     Examples/test-suite/common.mk                    | 1 +
     Examples/test-suite/infinity.i                   | 9 ++++-----
     Examples/test-suite/javascript/infinity_runme.js | 2 +-
     3 files changed, 6 insertions(+), 6 deletions(-)
    
    diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
    index b7a539035..9c3685d08 100644
    --- a/Examples/test-suite/common.mk
    +++ b/Examples/test-suite/common.mk
    @@ -587,6 +587,7 @@ C_TEST_CASES += \
     	global_functions \
     	immutable_values \
     	inctest \
    +	infinity \
     	integers \
     	keyword_rename \
     	lextype \
    diff --git a/Examples/test-suite/infinity.i b/Examples/test-suite/infinity.i
    index 41741eb94..726150f02 100644
    --- a/Examples/test-suite/infinity.i
    +++ b/Examples/test-suite/infinity.i
    @@ -1,15 +1,12 @@
     %module infinity
     
    -#include 
    -
     /*  C99 defines INFINITY
         Because INFINITY may be defined by compiler built-ins, we can't use #define.
         Instead, expose the variable MYINFINITY and then use %rename to make it INFINITY in the scripting language.
     */
     %rename(INFINITY) MYINFINITY;
     
    -
    -%inline %{
    +%{
     #include 
     
     /* C99 math.h defines INFINITY. If not available, this is the fallback. */
    @@ -26,7 +23,7 @@
     
     	#ifdef __GNUC__
     		#define INFINITY (__builtin_inf())
    -    #elif defined(__clang__)
    +	#elif defined(__clang__)
     		#if __has_builtin(__builtin_inf)
     			#define INFINITY (__builtin_inf())
     		#endif
    @@ -36,7 +33,9 @@
     		#define INFINITY (1e1000)
     	#endif
     #endif
    +%}
     
    +%inline %{
     /* This will allow us to bind the real INFINITY value through SWIG via MYINFINITY. Use %rename to fix the name. */
     const double MYINFINITY = INFINITY;
     
    diff --git a/Examples/test-suite/javascript/infinity_runme.js b/Examples/test-suite/javascript/infinity_runme.js
    index 1dcf366c6..7b5182ff6 100644
    --- a/Examples/test-suite/javascript/infinity_runme.js
    +++ b/Examples/test-suite/javascript/infinity_runme.js
    @@ -1,4 +1,4 @@
     var infinity = require("./infinity");
     
    -var my_infinity = infinity.INFINTY;
    +var my_infinity = infinity.INFINITY;
     var ret_val = infinity.use_infinity(my_infinity);
    
    From 665ddb55d1f08a482d29c010f9c525955469c016 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Mon, 21 Apr 2014 08:08:22 +0100
    Subject: [PATCH 311/352] Suppress keyword warning in test-suite
    
    ---
     Examples/test-suite/c_delete.i          | 2 +-
     Examples/test-suite/c_delete_function.i | 2 ++
     2 files changed, 3 insertions(+), 1 deletion(-)
    
    diff --git a/Examples/test-suite/c_delete.i b/Examples/test-suite/c_delete.i
    index 28b2ae78e..0c69f9f41 100644
    --- a/Examples/test-suite/c_delete.i
    +++ b/Examples/test-suite/c_delete.i
    @@ -2,7 +2,7 @@
     
     /* check C++ delete keyword is okay in C wrappers */
     
    -#pragma SWIG nowarn=SWIGWARN_PARSE_KEYWORD
    +%warnfilter(SWIGWARN_PARSE_KEYWORD) delete;
     
     #if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) /* Octave and Javascript/v8 compiles wrappers as C++ */
     
    diff --git a/Examples/test-suite/c_delete_function.i b/Examples/test-suite/c_delete_function.i
    index 0aac423ac..8164d066b 100644
    --- a/Examples/test-suite/c_delete_function.i
    +++ b/Examples/test-suite/c_delete_function.i
    @@ -2,6 +2,8 @@
     
     /* check C++ delete keyword is okay in C wrappers */
     
    +%warnfilter(SWIGWARN_PARSE_KEYWORD) delete;
    +
     #if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) /* Octave and Javascript/v8 compiles wrappers as C++ */
     
     %inline %{
    
    From e730b16facf133f4940635d6156acb5f9089887e Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Mon, 21 Apr 2014 11:23:14 +0100
    Subject: [PATCH 312/352] Revert "Javascript node test-suite makefile fixes for
     parallel make"
    
    This reverts commit f105590c0afc4e7da62d3eb45b86062acc6bc971.
    ---
     Examples/test-suite/javascript/Makefile.in | 7 +++----
     1 file changed, 3 insertions(+), 4 deletions(-)
    
    diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
    index 54fec63f9..2074f89af 100755
    --- a/Examples/test-suite/javascript/Makefile.in
    +++ b/Examples/test-suite/javascript/Makefile.in
    @@ -58,8 +58,7 @@ ifeq (node,$(JSENGINE))
     		$(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i;
     
     	nodejs_swig_and_compile = \
    -		$(NODEGYP) --loglevel=silent --directory $* configure 1>>/dev/null
    -		$(NODEGYP) --loglevel=silent --directory $* build 1>>/dev/null
    +		$(NODEGYP) --loglevel=silent --directory $* configure build 1>>/dev/null
     
     	run_testcase = \
     		if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \
    @@ -69,13 +68,13 @@ ifeq (node,$(JSENGINE))
       %.cpptest:
     		$(_setup)
     		$(__setup)
    -		+$(nodejs_swig_and_compile)
    +		$(nodejs_swig_and_compile)
     		$(run_testcase)
     
       %.ctest:
     		$(_setup)
     		$(__setup)
    -		+$(nodejs_swig_and_compile)
    +		$(nodejs_swig_and_compile)
     		$(run_testcase)
     
       %.multicpptest:
    
    From e6d5abb7667777dfe8ab9b78ae22b0ec7234c11d Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Mon, 21 Apr 2014 11:37:19 +0100
    Subject: [PATCH 313/352] Only disable javascript tests if node-gyp is missing
     when testing node
    
    ---
     Examples/Makefile.in |  5 +++--
     configure.ac         | 11 ++++++++---
     2 files changed, 11 insertions(+), 5 deletions(-)
    
    diff --git a/Examples/Makefile.in b/Examples/Makefile.in
    index 63c34ed29..d195e553f 100644
    --- a/Examples/Makefile.in
    +++ b/Examples/Makefile.in
    @@ -661,12 +661,14 @@ javascript_version:
     ifeq (, $(ENGINE))
     	@if [ "$(NODEJS)" != "" ]; then \
     	  echo "Node.js: `($(NODEJS) --version)`"; \
    +	  echo "node-gyp: `($(NODEGYP) --version)`"; \
     	else \
     	  echo "Version depends on the interpreter"; \
     	fi
     endif
     ifeq (node, $(ENGINE))
    -	$(NODEJS) --version
    +	echo "Node.js: `($(NODEJS) --version)`"
    +	echo "node-gyp: `($(NODEGYP) --version)`"
     endif
     ifeq (jsc, $(ENGINE))
     	@if [ "@JSCOREVERSION@" != "" ]; then \
    @@ -678,7 +680,6 @@ endif
     ifeq (v8, $(ENGINE))
     	echo "Unknown v8 version."
     endif
    -	echo "node-gyp: `($(NODEGYP) --version)`"
     
     # -----------------------------------------------------------------
     # Cleaning the Javascript examples
    diff --git a/configure.ac b/configure.ac
    index aac978ae3..e9c47e361 100644
    --- a/configure.ac
    +++ b/configure.ac
    @@ -1136,8 +1136,13 @@ else
     
       AC_CHECK_PROGS(NODEJS, node)
     
    -  # node-gyp is needed to run the test-suite/examples for all Javascript engines
    -  AC_CHECK_PROGS(NODEGYP, node-gyp)
    +  if test -n "$NODEJS"; then
    +    # node-gyp is needed to run the test-suite/examples
    +    AC_CHECK_PROGS(NODEGYP, node-gyp)
    +    if test -z "$NODEGYP"; then
    +      NODEJS=
    +    fi
    +  fi
     
       #----------------------------------------------------------------
       # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING)
    @@ -2459,7 +2464,7 @@ fi
     AC_SUBST(SKIP_JAVA)
     
     SKIP_JAVASCRIPT=
    -if test -z "$JAVASCRIPT" || test -z "$NODEJS" || test -z "$NODEGYP"; then
    +if test -z "$JAVASCRIPT" || test -z "$NODEJS" ; then
         SKIP_JAVASCRIPT="1"
     fi
     AC_SUBST(SKIP_JAVASCRIPT)
    
    From 36679865f42d8e3bc0ecb2fd1503609b2e2f522c Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Wed, 23 Apr 2014 00:38:01 +0200
    Subject: [PATCH 314/352] Add 'fix' for Javascript/v8 to test 'enum_forward'.
    
    ---
     Examples/test-suite/enum_forward.i | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/Examples/test-suite/enum_forward.i b/Examples/test-suite/enum_forward.i
    index 1609fa8e9..c82e17be7 100644
    --- a/Examples/test-suite/enum_forward.i
    +++ b/Examples/test-suite/enum_forward.i
    @@ -1,7 +1,7 @@
     %module enum_forward
     
    -/* This contains C code that is not valid C++03 and Octave wrappers are always compiled as C++ */
    -#if !defined(SWIGOCTAVE)
    +/* This contains C code that is not valid C++03 and Octave, and Javascript(v8) wrappers are always compiled as C++ */
    +#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8)
     %{
     enum ForwardEnum1 { AAA, BBB };
     enum ForwardEnum2 { CCC, DDD };
    
    From 093f8995a8e95b8867e75f392cb2c0d49ff6d05c Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Wed, 23 Apr 2014 00:38:45 +0200
    Subject: [PATCH 315/352] Add cast to test 'string_simple' to avoid C++
     compiler error.
    
    ---
     Examples/test-suite/string_simple.i | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Examples/test-suite/string_simple.i b/Examples/test-suite/string_simple.i
    index 5f5cc00bb..c319aa1ef 100644
    --- a/Examples/test-suite/string_simple.i
    +++ b/Examples/test-suite/string_simple.i
    @@ -6,7 +6,7 @@
     #include 
     const char* copy_string(const char* str) {
       size_t len = strlen(str);
    -  char* newstring = malloc(len + 1);
    +  char* newstring = (char*) malloc(len + 1);
       strcpy(newstring, str);
       return newstring;
     }
    
    From f3e3fce6643cc996ac371a109d19d783993cef75 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Wed, 23 Apr 2014 02:25:07 +0200
    Subject: [PATCH 316/352] Fix configuration for ctest with Javascript/v8.
    
    ---
     Examples/Makefile.in                       | 11 +++++++++++
     Examples/test-suite/javascript/Makefile.in | 19 +++++--------------
     2 files changed, 16 insertions(+), 14 deletions(-)
    
    diff --git a/Examples/Makefile.in b/Examples/Makefile.in
    index d195e553f..dfd0ea9c9 100644
    --- a/Examples/Makefile.in
    +++ b/Examples/Makefile.in
    @@ -630,11 +630,22 @@ javascript_build_node: $(SRCS)
     
     # These targets are used by the test-suite:
     
    +ifeq (jsc, $(ENGINE))
    +
     javascript: $(SRCS) javascript_custom_interpreter
     	$(SWIG) -javascript $(SWIGOPT) $(INTERFACEPATH)
     	$(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES)
     	$(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
     
    +else # (v8 | node) # v8 and node must be compiled as c++
    +
    +javascript: $(SRCS) javascript_custom_interpreter
    +	$(SWIG) -javascript $(SWIGOPT) $(INTERFACEPATH)
    +	$(CXX) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES)
    +	$(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
    +
    +endif
    +
     javascript_cpp: $(SRCS) javascript_custom_interpreter
     	$(SWIG) -javascript -c++ $(SWIGOPT) $(INTERFACEPATH)
     	$(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES)
    diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
    index 2074f89af..eceb234d4 100755
    --- a/Examples/test-suite/javascript/Makefile.in
    +++ b/Examples/test-suite/javascript/Makefile.in
    @@ -89,6 +89,11 @@ else
     			$(top_srcdir)/Tools/javascript/javascript -$(JSENGINE) $(srcdir)/$*$(SCRIPTSUFFIX); \
     		fi
     
    +  %.ctest:
    +		$(_setup)
    +		+$(swig_and_compile_c)
    +		$(run_testcase)
    +
       %.cpptest:
     		$(_setup)
     		+$(swig_and_compile_cpp)
    @@ -101,20 +106,6 @@ else
     
     endif
     
    -ifeq (v8,$(ENGINE))
    -  %.ctest:
    -		$(_setup)
    -		+$(swig_and_compile_cpp)
    -		$(run_testcase)
    -
    -endif
    -
    -ifeq (jsc,$(ENGINE))
    -  %.ctest:
    -		$(_setup)
    -		+$(swig_and_compile_c)
    -		$(run_testcase)
    -endif
     
     %.clean:
     	rm -rf $*
    
    From 3c593f56de61fbd9108e7be4c0db4d5ec0575133 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Wed, 23 Apr 2014 02:26:24 +0200
    Subject: [PATCH 317/352] Turn on Swig_cparse_cplusplusout for Javascript/v8.
    
    ---
     Source/Modules/javascript.cxx | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index 3ea632ef8..321c6c6c2 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -554,6 +554,10 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
         {
           emitter = swig_javascript_create_V8Emitter();
           Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
    +      // V8 API is C++, so output must be C++ compatibile even when wrapping C code
    +      if (!cparse_cplusplus) {
    +	Swig_cparse_cplusplusout(1);
    +      }
           break;
         }
       case JSEmitter::JavascriptCore:
    
    From 953f2f91dc250fd5f2e2ce14bc3eae5450f66475 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Wed, 23 Apr 2014 02:26:47 +0200
    Subject: [PATCH 318/352] Fix generator for Javascript enums.
    
    ---
     Source/Modules/javascript.cxx | 18 ++++++++++++++++--
     1 file changed, 16 insertions(+), 2 deletions(-)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index 321c6c6c2..be73e4d1d 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -1,5 +1,5 @@
     /* -----------------------------------------------------------------------------
    - * This file is part of SWIG, which is licensed as a whole under version 3 
    + * This file is part of SWIG, which is licensed as a whole under version 3
      * (or any later version) of the GNU General Public License. Some additional
      * terms also apply to certain portions of SWIG. The full details of the SWIG
      * license and copyrights can be found in the LICENSE and COPYRIGHT files
    @@ -12,6 +12,7 @@
      * ----------------------------------------------------------------------------- */
     
     #include "swigmod.h"
    +#include "cparse.h"
     
     /**
      * Enables extra debugging information in typemaps.
    @@ -1109,7 +1110,20 @@ int JSEmitter::emitConstant(Node *n) {
       String *iname = Getattr(n, "sym:name");
       String *wname = Swig_name_wrapper(name);
       String *rawval = Getattr(n, "rawval");
    -  String *value = rawval ? rawval : Getattr(n, "value");
    +  String *value;
    +
    +  // HACK: there are several cases.
    +  // - rawval is set for numerical constants as
    +  //   #define MS_NOOVERRIDE -1111
    +  // - value is set for
    +  // - cppvalue needs to be used for c++
    +  if (rawval) {
    +    value = rawval;
    +  } else if (Getattr(n, "cppvalue")) {
    +    value = Getattr(n, "cppvalue");
    +  } else {
    +    value = Getattr(n, "value");
    +  }
     
       Template t_getter(getTemplate("js_getter"));
     
    
    From 1ab7a2359c11b10ae078c6139084344ca9010b49 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Wed, 23 Apr 2014 02:27:21 +0200
    Subject: [PATCH 319/352] SKIP_JAVASCRIPT only when there is none of
     v8/node/jsc.
    
    ---
     configure.ac | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/configure.ac b/configure.ac
    index e9c47e361..0445460fd 100644
    --- a/configure.ac
    +++ b/configure.ac
    @@ -2464,7 +2464,7 @@ fi
     AC_SUBST(SKIP_JAVA)
     
     SKIP_JAVASCRIPT=
    -if test -z "$JAVASCRIPT" || test -z "$NODEJS" ; then
    +if test -z "$JAVASCRIPT" || ( test -z "$NODEJS" && test -z "$JSCENABLED" && test -z "$JSV8ENABLED" ) ; then
         SKIP_JAVASCRIPT="1"
     fi
     AC_SUBST(SKIP_JAVASCRIPT)
    
    From 1d10a621926a6922b9c1ce45af49e020b93beb52 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Wed, 23 Apr 2014 02:56:53 +0200
    Subject: [PATCH 320/352] Fix configuration for Javascript/node ctests.
    
    ---
     Examples/test-suite/javascript/Makefile.in | 23 ++++++++++++----------
     1 file changed, 13 insertions(+), 10 deletions(-)
    
    diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
    index eceb234d4..b79f2c3f0 100755
    --- a/Examples/test-suite/javascript/Makefile.in
    +++ b/Examples/test-suite/javascript/Makefile.in
    @@ -53,11 +53,15 @@ ifeq (node,$(JSENGINE))
       constant_pointers.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
       enum_thorough.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
     
    -	__setup = \
    +	# Note: we need to use swig in C parse mode, but make node-gyp believe it is c++ (via file extension)
    +	swig_and_compile_c = \
     		sh ./setup_test.sh $* $(GYP_CFLAGS); \
    -		$(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i;
    +		$(SWIG) -javascript $(SWIGOPT) -o $*_wrap.cxx ../$*.i; \
    +		$(NODEGYP) --loglevel=silent --directory $* configure build 1>>/dev/null
     
    -	nodejs_swig_and_compile = \
    +	swig_and_compile_cpp = \
    +		sh ./setup_test.sh $* $(GYP_CFLAGS); \
    +		$(SWIG) -c++ -javascript $(SWIGOPT) ../$*.i; \
     		$(NODEGYP) --loglevel=silent --directory $* configure build 1>>/dev/null
     
     	run_testcase = \
    @@ -65,16 +69,15 @@ ifeq (node,$(JSENGINE))
     			node $(srcdir)/$*$(SCRIPTSUFFIX); \
     		fi
     
    -  %.cpptest:
    -		$(_setup)
    -		$(__setup)
    -		$(nodejs_swig_and_compile)
    -		$(run_testcase)
     
       %.ctest:
     		$(_setup)
    -		$(__setup)
    -		$(nodejs_swig_and_compile)
    +		$(swig_and_compile_c)
    +		$(run_testcase)
    +
    +  %.cpptest:
    +		$(_setup)
    +		$(swig_and_compile_cpp)
     		$(run_testcase)
     
       %.multicpptest:
    
    From fe3f00837c6186e0cee033e81e29ffdec82f8d7f Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Wed, 23 Apr 2014 03:46:46 +0200
    Subject: [PATCH 321/352] Fix regression in Javascript generator for enums.
    
    ---
     Source/Modules/javascript.cxx | 17 ++++++-----------
     1 file changed, 6 insertions(+), 11 deletions(-)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index be73e4d1d..7d4d6f7d6 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -48,6 +48,7 @@ bool js_template_enable_debug = false;
     #define STATIC_FUNCTIONS "static_functions"
     #define STATIC_VARIABLES "static_variables"
     #define HAS_TEMPLATES "has_templates"
    +#define FORCE_CPP "force_cpp"
     
     #define RESET true
     
    @@ -1110,19 +1111,11 @@ int JSEmitter::emitConstant(Node *n) {
       String *iname = Getattr(n, "sym:name");
       String *wname = Swig_name_wrapper(name);
       String *rawval = Getattr(n, "rawval");
    -  String *value;
    +  String *value = rawval ? rawval : Getattr(n, "value");
     
    -  // HACK: there are several cases.
    -  // - rawval is set for numerical constants as
    -  //   #define MS_NOOVERRIDE -1111
    -  // - value is set for
    -  // - cppvalue needs to be used for c++
    -  if (rawval) {
    -    value = rawval;
    -  } else if (Getattr(n, "cppvalue")) {
    +  // HACK: forcing usage of cppvalue for v8 (which turned out to fix typdef_struct.i, et. al)
    +  if (State::IsSet(state.global (FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {
         value = Getattr(n, "cppvalue");
    -  } else {
    -    value = Getattr(n, "value");
       }
     
       Template t_getter(getTemplate("js_getter"));
    @@ -1919,6 +1912,8 @@ int V8Emitter::initialize(Node *n) {
       Swig_register_filebyname("init", f_init);
       Swig_register_filebyname("post-init", f_post_init);
     
    +  state.global(FORCE_CPP, NewString("1"));
    +
       return SWIG_OK;
     }
     
    
    From a5e91f26a12fff73b1a421af1852b44c13cf0ad8 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Thu, 24 Apr 2014 20:54:16 +0100
    Subject: [PATCH 322/352] Cosmetic code changes in javascript.cxx
    
    ---
     Source/Modules/javascript.cxx | 107 ++++++++++------------------------
     1 file changed, 32 insertions(+), 75 deletions(-)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index 7d4d6f7d6..707bd5728 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -17,7 +17,7 @@
     /**
      * Enables extra debugging information in typemaps.
      */
    -bool js_template_enable_debug = false;
    +static bool js_template_enable_debug = false;
     
     // keywords used for state variables
     #define NAME "name"
    @@ -54,39 +54,26 @@ bool js_template_enable_debug = false;
     
     /**
      * A convenience class to manage state variables for emitters.
    - * The implementation delegates to swig Hash DOHs and provides
    + * The implementation delegates to SWIG Hash DOHs and provides
      * named sub-hashes for class, variable, and function states.
      */
     class JSEmitterState {
     
     public:
    -
       JSEmitterState();
    -
       ~JSEmitterState();
    -
    -  DOH *global ();
    -
    -  DOH *global (const char *key, DOH *initial = 0);
    -
    +  DOH *global();
    +  DOH *global(const char *key, DOH *initial = 0);
       DOH *clazz(bool reset = false);
    -
       DOH *clazz(const char *key, DOH *initial = 0);
    -
       DOH *function(bool reset = false);
    -
       DOH *function(const char *key, DOH *initial = 0);
    -
       DOH *variable(bool reset = false);
    -
       DOH *variable(const char *key, DOH *initial = 0);
    -
       static int IsSet(DOH *val);
     
     private:
    -
       DOH *getState(const char *key, bool reset = false);
    -
       Hash *_global;
     };
     
    @@ -98,30 +85,19 @@ class Template {
     
     public:
       Template(const String *code);
    -
    -   Template(const String *code, const String *templateName);
    -
    -   Template(const Template & other);
    -
    +  Template(const String *code, const String *templateName);
    +  Template(const Template & other);
       ~Template();
    -
       String *str();
    -
    -   Template & replace(const String *pattern, const String *repl);
    -
    -   Template & print(DOH *doh);
    -
    -   Template & pretty_print(DOH *doh);
    -
    +  Template & replace(const String *pattern, const String *repl);
    +  Template & print(DOH *doh);
    +  Template & pretty_print(DOH *doh);
       void operator=(const Template & t);
    -
    -   Template & trim();
    +  Template & trim();
     
     private:
    -
       String *code;
       String *templateName;
    -
     };
     
     /**
    @@ -311,7 +287,7 @@ JSEmitter *swig_javascript_create_JSCEmitter();
     JSEmitter *swig_javascript_create_V8Emitter();
     
     /**********************************************************************
    - * JAVASCRIPT: swig module implementation
    + * JAVASCRIPT: SWIG module implementation
      **********************************************************************/
     
     class JAVASCRIPT:public Language {
    @@ -319,7 +295,8 @@ class JAVASCRIPT:public Language {
     public:
     
       JAVASCRIPT():emitter(NULL) {
    -  } ~JAVASCRIPT() {
    +  }
    +  ~JAVASCRIPT() {
         delete emitter;
       }
     
    @@ -511,7 +488,7 @@ Javascript Options (available with -javascript)\n\
          -jsc                   - creates a JavascriptCore extension \n\
          -v8                    - creates a v8 extension \n\
          -node                  - creates a node.js extension \n\
    -     -debug-codetemplates   - generates information about the origin of code templates.\n";
    +     -debug-codetemplates   - generates information about the origin of code templates\n";
     
     
     /* ---------------------------------------------------------------------
    @@ -627,8 +604,8 @@ JSEmitter::~JSEmitter() {
      * ----------------------------------------------------------------------------- */
     
     int JSEmitter::registerTemplate(const String *name, const String *code) {
    -  if (!State::IsSet(state.global (HAS_TEMPLATES))) {
    -    SetFlag(state.global (), HAS_TEMPLATES);
    +  if (!State::IsSet(state.global(HAS_TEMPLATES))) {
    +    SetFlag(state.global(), HAS_TEMPLATES);
       }
       return Setattr(templates, name, code);
     }
    @@ -910,7 +887,7 @@ int JSEmitter::emitDtor(Node *n) {
       // (Taken from JSCore implementation.)
       /* The if (Extend) block was taken from the Ruby implementation.
        * The problem is that in the case of an %extend to create a destructor for a struct to coordinate automatic memory cleanup with the Javascript collector,
    -   * the swig function was not being generated. More specifically:
    +   * the SWIG function was not being generated. More specifically:
        struct MyData {
        %extend {
        ~MyData() {
    @@ -1427,36 +1404,21 @@ Hash *JSEmitter::createNamespaceEntry(const char *_name, const char *parent) {
     class JSCEmitter:public JSEmitter {
     
     public:
    -
       JSCEmitter();
    -
       virtual ~ JSCEmitter();
    -
       virtual int initialize(Node *n);
    -
       virtual int dump(Node *n);
    -
       virtual int close();
     
    -
     protected:
    -
       virtual int enterVariable(Node *n);
    -
       virtual int exitVariable(Node *n);
    -
       virtual int enterFunction(Node *n);
    -
       virtual int exitFunction(Node *n);
    -
       virtual int enterClass(Node *n);
    -
       virtual int exitClass(Node *n);
    -
       virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
    -
       virtual Hash *createNamespaceEntry(const char *name, const char *parent);
    -
       virtual int emitNamespaces();
     
     private:
    @@ -1567,9 +1529,9 @@ int JSCEmitter::initialize(Node *n) {
       f_init = NewString("");
       f_header = NewString("");
     
    -  state.global (CREATE_NAMESPACES, NewString(""));
    -  state.global (REGISTER_NAMESPACES, NewString(""));
    -  state.global (INITIALIZER, NewString(""));
    +  state.global(CREATE_NAMESPACES, NewString(""));
    +  state.global(REGISTER_NAMESPACES, NewString(""));
    +  state.global(INITIALIZER, NewString(""));
     
       /* Register file targets with the SWIG file handler */
       Swig_register_filebyname("begin", f_wrap_cpp);
    @@ -1585,7 +1547,7 @@ int JSCEmitter::dump(Node *n) {
       /* Get the module name */
       String *module = Getattr(n, "name");
     
    -  // write the swig banner
    +  // write the SWIG banner
       Swig_banner(f_wrap_cpp);
     
       Template initializer_define(getTemplate("js_initializer_define"));
    @@ -1602,9 +1564,9 @@ int JSCEmitter::dump(Node *n) {
       // compose the initializer function using a template
       Template initializer(getTemplate("js_initializer"));
       initializer.replace("$jsname", module)
    -  .replace("$jsregisterclasses", state.global (INITIALIZER))
    -  .replace("$jscreatenamespaces", state.global (CREATE_NAMESPACES))
    -  .replace("$jsregisternamespaces", state.global (REGISTER_NAMESPACES))
    +  .replace("$jsregisterclasses", state.global(INITIALIZER))
    +  .replace("$jscreatenamespaces", state.global(CREATE_NAMESPACES))
    +  .replace("$jsregisternamespaces", state.global(REGISTER_NAMESPACES))
       .pretty_print(f_init);
     
       Printv(f_wrap_cpp, f_init, 0);
    @@ -1670,7 +1632,6 @@ int JSCEmitter::enterVariable(Node *n) {
       return SWIG_OK;
     }
     
    -
     int JSCEmitter::exitVariable(Node *n) {
       Template t_variable(getTemplate("jsc_variable_declaration"));
       t_variable.replace("$jsname", state.variable(NAME))
    @@ -1748,7 +1709,7 @@ int JSCEmitter::exitClass(Node *n) {
           .replace("$jsclass_inheritance", jsclass_inheritance)
           .replace("$jsctor", state.clazz(CTOR))
           .replace("$jsdtor", state.clazz(DTOR))
    -  .pretty_print(state.global (INITIALIZER));
    +  .pretty_print(state.global(INITIALIZER));
       Delete(jsclass_inheritance);
     
       /* Note: this makes sure that there is a swig_type added for this class */
    @@ -1759,7 +1720,7 @@ int JSCEmitter::exitClass(Node *n) {
       t_registerclass.replace("$jsname", state.clazz(NAME))
           .replace("$jsmangledname", state.clazz(NAME_MANGLED))
           .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED))
    -  .pretty_print(state.global (INITIALIZER));
    +  .pretty_print(state.global(INITIALIZER));
     
       return SWIG_OK;
     }
    @@ -1792,7 +1753,7 @@ int JSCEmitter::emitNamespaces() {
     
         Template t_createNamespace(getTemplate("jsc_nspace_definition"));
         t_createNamespace.replace("$jsmangledname", name_mangled);
    -    Append(state.global (CREATE_NAMESPACES), t_createNamespace.str());
    +    Append(state.global(CREATE_NAMESPACES), t_createNamespace.str());
     
         // Don't register 'exports' as namespace. It is return to the application.
         if (!Equal("exports", name)) {
    @@ -1800,9 +1761,8 @@ int JSCEmitter::emitNamespaces() {
           t_registerNamespace.replace("$jsmangledname", name_mangled)
     	  .replace("$jsname", name)
     	  .replace("$jsparent", parent_mangled);
    -      Append(state.global (REGISTER_NAMESPACES), t_registerNamespace.str());
    +      Append(state.global(REGISTER_NAMESPACES), t_registerNamespace.str());
         }
    -
       }
     
       return SWIG_OK;
    @@ -1819,7 +1779,6 @@ JSEmitter *swig_javascript_create_JSCEmitter() {
     class V8Emitter:public JSEmitter {
     
     public:
    -
       V8Emitter();
     
       virtual ~ V8Emitter();
    @@ -1833,12 +1792,10 @@ public:
       virtual int exitFunction(Node *n);
     
     protected:
    -
       virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
       virtual int emitNamespaces();
     
     private:
    -
       /* built-in parts */
       String *f_runtime;
       String *f_header;
    @@ -1904,7 +1861,7 @@ int V8Emitter::initialize(Node *n) {
       f_init_register_classes = NewString("");
       f_init_register_namespaces = NewString("");
     
    -  // note: this is necessary for built-in generation of swig runtime code
    +  // note: this is necessary for built-in generation of SWIG runtime code
       Swig_register_filebyname("begin", f_wrap_cpp);
       Swig_register_filebyname("runtime", f_runtime);
       Swig_register_filebyname("header", f_header);
    @@ -1921,7 +1878,7 @@ int V8Emitter::dump(Node *n) {
       /* Get the module name */
       String *module = Getattr(n, "name");
     
    -  // write the swig banner
    +  // write the SWIG banner
       Swig_banner(f_wrap_cpp);
     
       Template initializer_define(getTemplate("js_initializer_define"));
    @@ -2266,11 +2223,11 @@ DOH *JSEmitterState::getState(const char *key, bool _new) {
       return Getattr(_global, key);
     }
     
    -DOH *JSEmitterState::global () {
    +DOH *JSEmitterState::global() {
       return _global;
     }
     
    -DOH *JSEmitterState::global (const char *key, DOH *initial) {
    +DOH *JSEmitterState::global(const char *key, DOH *initial) {
       if (initial != 0) {
         Setattr(_global, key, initial);
       }
    
    From dbf80cbaa50f27b7dea00b29bffb182fcb22cb8d Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Thu, 24 Apr 2014 22:18:12 +0100
    Subject: [PATCH 323/352] Javascript example Makefiles more consistent with
     other languages
    
    ---
     Examples/Makefile.in                          | 29 ++++++------
     Examples/javascript/class/Makefile            |  2 +-
     Examples/javascript/constant/Makefile         |  2 +-
     Examples/javascript/enum/Makefile             |  2 +-
     .../javascript/{js_example.mk => example.mk}  | 45 +++++--------------
     Examples/javascript/exception/Makefile        |  2 +-
     Examples/javascript/functor/Makefile          |  2 +-
     Examples/javascript/namespace/Makefile        |  2 +-
     Examples/javascript/operator/Makefile         |  2 +-
     Examples/javascript/overload/Makefile         |  2 +-
     Examples/javascript/pointer/Makefile          |  2 +-
     Examples/javascript/reference/Makefile        |  2 +-
     Examples/javascript/simple/Makefile           |  2 +-
     Examples/javascript/template/Makefile         |  2 +-
     Examples/javascript/variables/Makefile        |  2 +-
     15 files changed, 36 insertions(+), 64 deletions(-)
     rename Examples/javascript/{js_example.mk => example.mk} (64%)
    
    diff --git a/Examples/Makefile.in b/Examples/Makefile.in
    index dfd0ea9c9..01febf575 100644
    --- a/Examples/Makefile.in
    +++ b/Examples/Makefile.in
    @@ -597,7 +597,6 @@ java_clean:
     # There is a common makefile, 'Examples/javascript/js_example.mk' to simplify
     # create a configuration for a new example.
     
    -
     ROOT_DIR = @ROOT_DIR@
     JSINCLUDES = @JSCOREINC@ @JSV8INC@
     JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@
    @@ -621,29 +620,25 @@ javascript_build: $(SRCS)
     	$(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES)
     	$(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
     
    -javascript_build_cpp:: $(SRCS)
    +javascript_build_cpp: $(SRCS)
    +ifeq (node,$(JSENGINE))
    +	$(NODEGYP) --loglevel=silent configure build 1>>/dev/null
    +else
     	$(CXX) -c $(CCSHARED) $(CFLAGS) $(ICXXSRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES)
     	$(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
     
    -javascript_build_node: $(SRCS)
    -	$(NODEGYP) --loglevel=silent configure build 1>>/dev/null
    +endif
     
     # These targets are used by the test-suite:
     
    -ifeq (jsc, $(ENGINE))
    -
     javascript: $(SRCS) javascript_custom_interpreter
     	$(SWIG) -javascript $(SWIGOPT) $(INTERFACEPATH)
    +ifeq (jsc, $(ENGINE))
     	$(CC) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(INCLUDES) $(JSINCLUDES)
     	$(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
    -
     else # (v8 | node) # v8 and node must be compiled as c++
    -
    -javascript: $(SRCS) javascript_custom_interpreter
    -	$(SWIG) -javascript $(SWIGOPT) $(INTERFACEPATH)
     	$(CXX) -c $(CCSHARED) $(CFLAGS) $(ISRCS) $(SRCS) $(CXXSRCS) $(INCLUDES) $(JSINCLUDES)
     	$(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
    -
     endif
     
     javascript_cpp: $(SRCS) javascript_custom_interpreter
    @@ -658,11 +653,13 @@ javascript_cpp: $(SRCS) javascript_custom_interpreter
     javascript_custom_interpreter:
     	(cd $(ROOT_DIR)/Tools/javascript && $(MAKE) JSENGINE='$(JSENGINE)')
     
    +ifeq (node,$(JSENGINE))
    +javascript_run:
    +	$(RUNTOOL) $(NODEJS) $(RUNME).js $(RUNPIPE)
    +else
     javascript_run: javascript_custom_interpreter
    -	$(RUNTOOL) $(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) -L $(TARGET) runme.js $(RUNPIPE)
    -
    -javascript_run_node:
    -	$(RUNTOOL) $(NODEJS) runme.js $(RUNPIPE)
    +	$(RUNTOOL) $(ROOT_DIR)/Tools/javascript/javascript -$(JSENGINE) -L $(TARGET) $(RUNME).js $(RUNPIPE)
    +endif
     
     # -----------------------------------------------------------------
     # Version display
    @@ -698,7 +695,7 @@ endif
     
     javascript_clean:
     	rm -rf build
    -	rm -f *_wrap* runme
    +	rm -f *_wrap* $(RUNME)
     	rm -f core @EXTRA_CLEAN@
     	rm -f *.@OBJEXT@ *@JSSO@ *.$(SO)
     	(cd $(ROOT_DIR)/Tools/javascript && $(MAKE) -s clean)
    diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/class/Makefile
    +++ b/Examples/javascript/class/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile
    index a2570636e..ea04c7df8 100755
    --- a/Examples/javascript/constant/Makefile
    +++ b/Examples/javascript/constant/Makefile
    @@ -1,3 +1,3 @@
     SRCS =
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/enum/Makefile
    +++ b/Examples/javascript/enum/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/js_example.mk b/Examples/javascript/example.mk
    similarity index 64%
    rename from Examples/javascript/js_example.mk
    rename to Examples/javascript/example.mk
    index 6cb6eb113..274eff1a3 100644
    --- a/Examples/javascript/js_example.mk
    +++ b/Examples/javascript/example.mk
    @@ -1,14 +1,5 @@
     # Note: as a convention an example must be in a child directory of this.
     # These paths are relative to such an example directory
    -EXAMPLES_TOP=../..
    -SWIG_TOP=../../..
    -
    -SWIG = $(SWIG_TOP)/preinst-swig
    -
    -# TODO: we could only set these only if not yet set...
    -JS_SCRIPT = runme.js
    -TARGET = example
    -INTERFACE = example.i
     
     ifneq (, $(ENGINE))
     	JSENGINE=$(ENGINE)
    @@ -16,37 +7,21 @@ else
     	JSENGINE=node
     endif
     
    +EXAMPLES_TOP=../..
    +SWIG_TOP=../../..
    +SWIG = $(SWIG_TOP)/preinst-swig
    +TARGET = example
    +INTERFACE = example.i
     SWIGOPT=-$(JSENGINE)
     
    -ifeq (node,$(JSENGINE))
    -
    -build: wrapper
    -	$(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \
    -	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_node
    -
    -else
    -
    -build: wrapper
    -	$(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \
    -	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_cpp
    -
    -endif
    -
    -wrapper:
    -	$(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \
    -	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp
    -
    -ifeq (node,$(JSENGINE))
    -
    -check: build
    -	$(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' javascript_run_node
    -
    -else
    -
     check: build
     	$(MAKE) -f $(EXAMPLES_TOP)/Makefile JSENGINE='$(JSENGINE)' TARGET='$(TARGET)' javascript_run
     
    -endif
    +build:
    +	$(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \
    +	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp
    +	$(MAKE) -f $(EXAMPLES_TOP)/Makefile CXXSRCS='$(SRCS)' SWIG='$(SWIG)' \
    +	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_cpp
     
     clean:
     	$(MAKE) -f $(EXAMPLES_TOP)/Makefile javascript_clean
    diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/exception/Makefile
    +++ b/Examples/javascript/exception/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/functor/Makefile
    +++ b/Examples/javascript/functor/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/namespace/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/namespace/Makefile
    +++ b/Examples/javascript/namespace/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile
    index a2570636e..ea04c7df8 100755
    --- a/Examples/javascript/operator/Makefile
    +++ b/Examples/javascript/operator/Makefile
    @@ -1,3 +1,3 @@
     SRCS =
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile
    index a2570636e..ea04c7df8 100755
    --- a/Examples/javascript/overload/Makefile
    +++ b/Examples/javascript/overload/Makefile
    @@ -1,3 +1,3 @@
     SRCS =
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/pointer/Makefile
    +++ b/Examples/javascript/pointer/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/reference/Makefile
    +++ b/Examples/javascript/reference/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/simple/Makefile
    +++ b/Examples/javascript/simple/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile
    index a2570636e..ea04c7df8 100755
    --- a/Examples/javascript/template/Makefile
    +++ b/Examples/javascript/template/Makefile
    @@ -1,3 +1,3 @@
     SRCS =
     
    -include ../js_example.mk
    +include ../example.mk
    diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile
    index b0934786a..31846faae 100755
    --- a/Examples/javascript/variables/Makefile
    +++ b/Examples/javascript/variables/Makefile
    @@ -1,3 +1,3 @@
     SRCS = example.cxx
     
    -include ../js_example.mk
    +include ../example.mk
    
    From 889c8e24c7dd56b5303647e016c2b960657d310f Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Thu, 24 Apr 2014 22:49:48 +0100
    Subject: [PATCH 324/352] Javascript test-suite - warning suppression not
     needed
    
    ---
     Examples/test-suite/javascript/Makefile.in | 8 +-------
     1 file changed, 1 insertion(+), 7 deletions(-)
    
    diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
    index b79f2c3f0..7368ea9a3 100755
    --- a/Examples/test-suite/javascript/Makefile.in
    +++ b/Examples/test-suite/javascript/Makefile.in
    @@ -29,13 +29,7 @@ ifneq (jsc,$(ENGINE))
     
       # This test can not be run with v8 as it uses v8 API incompatible output typemaps
       typemap_variables.cpptest:
    -	  echo "skipping $(LANGUAGE) ($(JSENGINE)) testcase $*" ;
    -
    -  # with v8 we have to generate C++ wrappers only
    -  # these tests did raise warnings which are ignored
    -  nested.ctest: SWIGOPT += -w312,-325
    -  nested_structs.ctest: SWIGOPT += -w312,-325
    -  unions.ctest: SWIGOPT += -w312,-325
    +	  echo "skipping $(LANGUAGE) ($(JSENGINE)) testcase typemap_variables" ;
     
     endif
     
    
    From a80f4551db26fd2b52670e262fcc13a919906b31 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Fri, 25 Apr 2014 07:21:32 +0100
    Subject: [PATCH 325/352] Javascript variable naming convention corrections
    
    Also rename global -> globals just to placate the beautifier
    ---
     Source/Modules/javascript.cxx | 76 +++++++++++++++++------------------
     1 file changed, 38 insertions(+), 38 deletions(-)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index 707bd5728..2ac564486 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -62,8 +62,8 @@ class JSEmitterState {
     public:
       JSEmitterState();
       ~JSEmitterState();
    -  DOH *global();
    -  DOH *global(const char *key, DOH *initial = 0);
    +  DOH *globals();
    +  DOH *globals(const char *key, DOH *initial = 0);
       DOH *clazz(bool reset = false);
       DOH *clazz(const char *key, DOH *initial = 0);
       DOH *function(bool reset = false);
    @@ -74,7 +74,7 @@ public:
     
     private:
       DOH *getState(const char *key, bool reset = false);
    -  Hash *_global;
    +  Hash *globalHash;
     };
     
     /**
    @@ -604,8 +604,8 @@ JSEmitter::~JSEmitter() {
      * ----------------------------------------------------------------------------- */
     
     int JSEmitter::registerTemplate(const String *name, const String *code) {
    -  if (!State::IsSet(state.global(HAS_TEMPLATES))) {
    -    SetFlag(state.global(), HAS_TEMPLATES);
    +  if (!State::IsSet(state.globals(HAS_TEMPLATES))) {
    +    SetFlag(state.globals(), HAS_TEMPLATES);
       }
       return Setattr(templates, name, code);
     }
    @@ -1078,7 +1078,7 @@ int JSEmitter::emitConstant(Node *n) {
       // a lot of SWIG internal constants were emitted
       // This didn't happen on other platforms yet...
       // we ignore those premature definitions
    -  if (!State::IsSet(state.global (HAS_TEMPLATES))) {
    +  if (!State::IsSet(state.globals(HAS_TEMPLATES))) {
         return SWIG_ERROR;
       }
     
    @@ -1091,7 +1091,7 @@ int JSEmitter::emitConstant(Node *n) {
       String *value = rawval ? rawval : Getattr(n, "value");
     
       // HACK: forcing usage of cppvalue for v8 (which turned out to fix typdef_struct.i, et. al)
    -  if (State::IsSet(state.global (FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {
    +  if (State::IsSet(state.globals(FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {
         value = Getattr(n, "cppvalue");
       }
     
    @@ -1529,9 +1529,9 @@ int JSCEmitter::initialize(Node *n) {
       f_init = NewString("");
       f_header = NewString("");
     
    -  state.global(CREATE_NAMESPACES, NewString(""));
    -  state.global(REGISTER_NAMESPACES, NewString(""));
    -  state.global(INITIALIZER, NewString(""));
    +  state.globals(CREATE_NAMESPACES, NewString(""));
    +  state.globals(REGISTER_NAMESPACES, NewString(""));
    +  state.globals(INITIALIZER, NewString(""));
     
       /* Register file targets with the SWIG file handler */
       Swig_register_filebyname("begin", f_wrap_cpp);
    @@ -1564,9 +1564,9 @@ int JSCEmitter::dump(Node *n) {
       // compose the initializer function using a template
       Template initializer(getTemplate("js_initializer"));
       initializer.replace("$jsname", module)
    -  .replace("$jsregisterclasses", state.global(INITIALIZER))
    -  .replace("$jscreatenamespaces", state.global(CREATE_NAMESPACES))
    -  .replace("$jsregisternamespaces", state.global(REGISTER_NAMESPACES))
    +  .replace("$jsregisterclasses", state.globals(INITIALIZER))
    +  .replace("$jscreatenamespaces", state.globals(CREATE_NAMESPACES))
    +  .replace("$jsregisternamespaces", state.globals(REGISTER_NAMESPACES))
       .pretty_print(f_init);
     
       Printv(f_wrap_cpp, f_init, 0);
    @@ -1709,7 +1709,7 @@ int JSCEmitter::exitClass(Node *n) {
           .replace("$jsclass_inheritance", jsclass_inheritance)
           .replace("$jsctor", state.clazz(CTOR))
           .replace("$jsdtor", state.clazz(DTOR))
    -  .pretty_print(state.global(INITIALIZER));
    +  .pretty_print(state.globals(INITIALIZER));
       Delete(jsclass_inheritance);
     
       /* Note: this makes sure that there is a swig_type added for this class */
    @@ -1720,7 +1720,7 @@ int JSCEmitter::exitClass(Node *n) {
       t_registerclass.replace("$jsname", state.clazz(NAME))
           .replace("$jsmangledname", state.clazz(NAME_MANGLED))
           .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED))
    -  .pretty_print(state.global(INITIALIZER));
    +  .pretty_print(state.globals(INITIALIZER));
     
       return SWIG_OK;
     }
    @@ -1753,7 +1753,7 @@ int JSCEmitter::emitNamespaces() {
     
         Template t_createNamespace(getTemplate("jsc_nspace_definition"));
         t_createNamespace.replace("$jsmangledname", name_mangled);
    -    Append(state.global(CREATE_NAMESPACES), t_createNamespace.str());
    +    Append(state.globals(CREATE_NAMESPACES), t_createNamespace.str());
     
         // Don't register 'exports' as namespace. It is return to the application.
         if (!Equal("exports", name)) {
    @@ -1761,7 +1761,7 @@ int JSCEmitter::emitNamespaces() {
           t_registerNamespace.replace("$jsmangledname", name_mangled)
     	  .replace("$jsname", name)
     	  .replace("$jsparent", parent_mangled);
    -      Append(state.global(REGISTER_NAMESPACES), t_registerNamespace.str());
    +      Append(state.globals(REGISTER_NAMESPACES), t_registerNamespace.str());
         }
       }
     
    @@ -1869,7 +1869,7 @@ int V8Emitter::initialize(Node *n) {
       Swig_register_filebyname("init", f_init);
       Swig_register_filebyname("post-init", f_post_init);
     
    -  state.global(FORCE_CPP, NewString("1"));
    +  state.globals(FORCE_CPP, NewString("1"));
     
       return SWIG_OK;
     }
    @@ -2204,38 +2204,38 @@ JSEmitter *swig_javascript_create_V8Emitter() {
      **********************************************************************/
     
     JSEmitterState::JSEmitterState()
    -:  _global(NewHash()) {
    +:  globalHash(NewHash()) {
       // initialize sub-hashes
    -  Setattr(_global, "class", NewHash());
    -  Setattr(_global, "function", NewHash());
    -  Setattr(_global, "variable", NewHash());
    +  Setattr(globalHash, "class", NewHash());
    +  Setattr(globalHash, "function", NewHash());
    +  Setattr(globalHash, "variable", NewHash());
     }
     
     JSEmitterState::~JSEmitterState() {
    -  Delete(_global);
    +  Delete(globalHash);
     }
     
    -DOH *JSEmitterState::getState(const char *key, bool _new) {
    -  if (_new) {
    +DOH *JSEmitterState::getState(const char *key, bool new_key) {
    +  if (new_key) {
         Hash *hash = NewHash();
    -    Setattr(_global, key, hash);
    +    Setattr(globalHash, key, hash);
       }
    -  return Getattr(_global, key);
    +  return Getattr(globalHash, key);
     }
     
    -DOH *JSEmitterState::global() {
    -  return _global;
    +DOH *JSEmitterState::globals() {
    +  return globalHash;
     }
     
    -DOH *JSEmitterState::global(const char *key, DOH *initial) {
    +DOH *JSEmitterState::globals(const char *key, DOH *initial) {
       if (initial != 0) {
    -    Setattr(_global, key, initial);
    +    Setattr(globalHash, key, initial);
       }
    -  return Getattr(_global, key);
    +  return Getattr(globalHash, key);
     }
     
    -DOH *JSEmitterState::clazz(bool _new) {
    -  return getState("class", _new);
    +DOH *JSEmitterState::clazz(bool new_key) {
    +  return getState("class", new_key);
     }
     
     DOH *JSEmitterState::clazz(const char *key, DOH *initial) {
    @@ -2246,8 +2246,8 @@ DOH *JSEmitterState::clazz(const char *key, DOH *initial) {
       return Getattr(c, key);
     }
     
    -DOH *JSEmitterState::function(bool _new) {
    -  return getState("function", _new);
    +DOH *JSEmitterState::function(bool new_key) {
    +  return getState("function", new_key);
     }
     
     DOH *JSEmitterState::function(const char *key, DOH *initial) {
    @@ -2258,8 +2258,8 @@ DOH *JSEmitterState::function(const char *key, DOH *initial) {
       return Getattr(f, key);
     }
     
    -DOH *JSEmitterState::variable(bool _new) {
    -  return getState("variable", _new);
    +DOH *JSEmitterState::variable(bool new_key) {
    +  return getState("variable", new_key);
     }
     
     DOH *JSEmitterState::variable(const char *key, DOH *initial) {
    
    From 4edb6185016857138dd852b44cbf852485a79eb7 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Fri, 25 Apr 2014 07:26:27 +0100
    Subject: [PATCH 326/352] beautify javascript.cxx
    
    ---
     Source/Modules/javascript.cxx | 13 ++++++-------
     1 file changed, 6 insertions(+), 7 deletions(-)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index 2ac564486..0b4882c71 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -921,7 +921,6 @@ int JSEmitter::emitDtor(Node *n) {
           Printv(f_wrappers, wrap, NIL);
         }
       }
    -
       // HACK: this is only for the v8 emitter. maybe set an attribute wrap:action of node
       // TODO: generate dtors more similar to other wrappers
       // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used.
    @@ -1564,10 +1563,10 @@ int JSCEmitter::dump(Node *n) {
       // compose the initializer function using a template
       Template initializer(getTemplate("js_initializer"));
       initializer.replace("$jsname", module)
    -  .replace("$jsregisterclasses", state.globals(INITIALIZER))
    -  .replace("$jscreatenamespaces", state.globals(CREATE_NAMESPACES))
    -  .replace("$jsregisternamespaces", state.globals(REGISTER_NAMESPACES))
    -  .pretty_print(f_init);
    +      .replace("$jsregisterclasses", state.globals(INITIALIZER))
    +      .replace("$jscreatenamespaces", state.globals(CREATE_NAMESPACES))
    +      .replace("$jsregisternamespaces", state.globals(REGISTER_NAMESPACES))
    +      .pretty_print(f_init);
     
       Printv(f_wrap_cpp, f_init, 0);
     
    @@ -1709,7 +1708,7 @@ int JSCEmitter::exitClass(Node *n) {
           .replace("$jsclass_inheritance", jsclass_inheritance)
           .replace("$jsctor", state.clazz(CTOR))
           .replace("$jsdtor", state.clazz(DTOR))
    -  .pretty_print(state.globals(INITIALIZER));
    +      .pretty_print(state.globals(INITIALIZER));
       Delete(jsclass_inheritance);
     
       /* Note: this makes sure that there is a swig_type added for this class */
    @@ -1720,7 +1719,7 @@ int JSCEmitter::exitClass(Node *n) {
       t_registerclass.replace("$jsname", state.clazz(NAME))
           .replace("$jsmangledname", state.clazz(NAME_MANGLED))
           .replace("$jsnspace", Getattr(state.clazz("nspace"), NAME_MANGLED))
    -  .pretty_print(state.globals(INITIALIZER));
    +      .pretty_print(state.globals(INITIALIZER));
     
       return SWIG_OK;
     }
    
    From f68e47af3e03f828e269296bd1a3ff1c45a129d6 Mon Sep 17 00:00:00 2001
    From: William S Fulton 
    Date: Fri, 25 Apr 2014 07:57:32 +0100
    Subject: [PATCH 327/352] Restore missing copyright info in javascript branch
    
    ---
     COPYRIGHT | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/COPYRIGHT b/COPYRIGHT
    index 28b7f1f0d..1344630bb 100644
    --- a/COPYRIGHT
    +++ b/COPYRIGHT
    @@ -15,7 +15,7 @@ Active SWIG Developers:
      Olly Betts (olly@survex.com)                           (PHP)
      Joseph Wang (joequant@gmail.com)                       (R)
      Xavier Delacour (xavier.delacour@gmail.com)            (Octave)
    - David Nadlinger (code@klickverbot.at)
    + David Nadlinger (code@klickverbot.at)                  (D)
      Oliver Buchtala (oliver.buchtala@gmail.com)            (Javascript)
      Neha Narang (narangneha03@gmail.com)                   (Javascript)
     
    
    From cc16812c4f84fc3b8666321fb0369d289877b33a Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Sat, 26 Apr 2014 22:24:51 +0200
    Subject: [PATCH 328/352] Added a comment about V8_VERSION macro.
    
    ---
     Lib/javascript/v8/javascriptruntime.swg | 15 +++++++++++++++
     1 file changed, 15 insertions(+)
    
    diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg
    index 2e18d19bf..3ccbbd5b7 100644
    --- a/Lib/javascript/v8/javascriptruntime.swg
    +++ b/Lib/javascript/v8/javascriptruntime.swg
    @@ -3,6 +3,13 @@
      *
      * ----------------------------------------------------------------------------- */
     
    +// V8 Version Macro
    +// ----------------
    +// v8 does not (until now) provide a version macro - which is still discussed and may come soon.
    +// Until then, we set a default version which can be overridden via command line or via a define in
    +// the SWIG configuration.
    +// For example, `swig -javascript -v8 -DV8_VERSION=0x031110`
    +
     %define %swig_v8_define_version(version)
     %insert("runtime") %{
     #ifndef SWIG_V8_VERSION
    @@ -18,12 +25,20 @@
     %swig_v8_define_version(0x031110)
     #endif
     
    +
    +// Node support
    +// ------------
    +
     #ifdef BUILDING_NODE_EXTENSION
     %insert("runtime") %{
     #include 
     %}
     #endif
     
    +
    +// V8 runtime
    +// ----------
    +
     %insert(runtime) %{
     #include 
     
    
    From e8ef490716ac78bb0efa0f9ea75098da44df6d56 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Sat, 26 Apr 2014 22:25:09 +0200
    Subject: [PATCH 329/352] Removed obsolete 'node.i'.
    
    ---
     Lib/javascript/v8/node.i | 12 ------------
     1 file changed, 12 deletions(-)
     delete mode 100644 Lib/javascript/v8/node.i
    
    diff --git a/Lib/javascript/v8/node.i b/Lib/javascript/v8/node.i
    deleted file mode 100644
    index 8bf9ef061..000000000
    --- a/Lib/javascript/v8/node.i
    +++ /dev/null
    @@ -1,12 +0,0 @@
    -%insert("begin") %{
    -#ifndef BUILDING_NODE_EXTENSION
    -#define BUILDING_NODE_EXTENSION
    -#endif
    -%}
    -
    -%insert("runtime") %{
    -// we are including relative to the src folder because of issues
    -// with other files which might be named "node.h"
    -#include 
    -%}
    -
    
    From 226da453fca38fdad0af22ee5a70df54eed51316 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Sat, 26 Apr 2014 22:27:12 +0200
    Subject: [PATCH 330/352] Print error when specified multiple js engines.
    
    Plus, consolidated names: EmitterType, mode, engine -> engine.
    ---
     Source/Modules/javascript.cxx | 81 +++++++++++++++++++++--------------
     1 file changed, 50 insertions(+), 31 deletions(-)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index 0b4882c71..078204d20 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -19,6 +19,8 @@
      */
     static bool js_template_enable_debug = false;
     
    +#define ERR_MSG_ONLY_ONE_ENGINE_PLEASE "Only one engine can be specified at a time."
    +
     // keywords used for state variables
     #define NAME "name"
     #define NAME_MANGLED "name_mangled"
    @@ -36,6 +38,9 @@ static bool js_template_enable_debug = false;
     #define CTOR_DISPATCHERS "ctor_dispatchers"
     #define DTOR "dtor"
     #define ARGCOUNT "wrap:argc"
    +#define HAS_TEMPLATES "has_templates"
    +#define FORCE_CPP "force_cpp"
    +#define RESET true
     
     // keys for global state variables
     #define CREATE_NAMESPACES "create_namespaces"
    @@ -47,10 +52,7 @@ static bool js_template_enable_debug = false;
     #define MEMBER_FUNCTIONS "member_functions"
     #define STATIC_FUNCTIONS "static_functions"
     #define STATIC_VARIABLES "static_variables"
    -#define HAS_TEMPLATES "has_templates"
    -#define FORCE_CPP "force_cpp"
     
    -#define RESET true
     
     /**
      * A convenience class to manage state variables for emitters.
    @@ -119,12 +121,13 @@ protected:
     
     public:
     
    -  enum JSEmitterType {
    -    JavascriptCore,
    -    V8
    -  };
    +   enum JSEngine {
    +     JavascriptCore,
    +     V8,
    +     NodeJS
    +   };
     
    -   JSEmitter();
    +   JSEmitter(JSEngine engine);
     
        virtual ~ JSEmitter();
     
    @@ -266,6 +269,8 @@ protected:
     
     protected:
     
    +  JSEngine engine;
    +
       Hash *templates;
     
       State state;
    @@ -285,6 +290,7 @@ protected:
     
     JSEmitter *swig_javascript_create_JSCEmitter();
     JSEmitter *swig_javascript_create_V8Emitter();
    +JSEmitter *swig_javascript_create_NodeJSEmitter();
     
     /**********************************************************************
      * JAVASCRIPT: SWIG module implementation
    @@ -501,23 +507,31 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
       // Set javascript subdirectory in SWIG library
       SWIG_library_directory("javascript");
     
    -  int mode = -1;
    +  int engine = -1;
     
       for (int i = 1; i < argc; i++) {
         if (argv[i]) {
           if (strcmp(argv[i], "-v8") == 0) {
    +      	if (engine != -1) {
    +	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
    +	  SWIG_exit(-1);
    +      	}
     	Swig_mark_arg(i);
    -	mode = JSEmitter::V8;
    -	SWIG_library_directory("javascript/v8");
    +	engine = JSEmitter::V8;
           } else if (strcmp(argv[i], "-jsc") == 0) {
    +      	if (engine != -1) {
    +	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
    +	  SWIG_exit(-1);
    +      	}
     	Swig_mark_arg(i);
    -	mode = JSEmitter::JavascriptCore;
    -	SWIG_library_directory("javascript/jsc");
    +	engine = JSEmitter::JavascriptCore;
           } else if (strcmp(argv[i], "-node") == 0) {
    +      	if (engine) {
    +	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
    +	  SWIG_exit(-1);
    +      	}
     	Swig_mark_arg(i);
    -	mode = JSEmitter::V8;
    -	SWIG_library_directory("javascript/v8");
    -	Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0);
    +	engine = JSEmitter::NodeJS;
           } else if (strcmp(argv[i], "-debug-codetemplates") == 0) {
     	Swig_mark_arg(i);
     	js_template_enable_debug = true;
    @@ -528,11 +542,12 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
         }
       }
     
    -  switch (mode) {
    +  switch (engine) {
       case JSEmitter::V8:
         {
           emitter = swig_javascript_create_V8Emitter();
           Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
    +      SWIG_library_directory("javascript/v8");
           // V8 API is C++, so output must be C++ compatibile even when wrapping C code
           if (!cparse_cplusplus) {
     	Swig_cparse_cplusplusout(1);
    @@ -543,11 +558,20 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
         {
           emitter = swig_javascript_create_JSCEmitter();
           Preprocessor_define("SWIG_JAVASCRIPT_JSC 1", 0);
    +      SWIG_library_directory("javascript/jsc");
    +      break;
    +    }
    +  case JSEmitter::NodeJS:
    +    {
    +      emitter = swig_javascript_create_V8Emitter();
    +      Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
    +      Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0);
    +      SWIG_library_directory("javascript/v8");
           break;
         }
       default:
         {
    -      Printf(stderr, "SWIG Javascript: Unknown emitter type. Please specify one of -jsc -v8 or -node.\n");
    +      Printf(stderr, "SWIG Javascript: Unknown engine. Please specify one of '-jsc', '-v8' or '-node'.\n");
           SWIG_exit(-1);
           break;
         }
    @@ -585,8 +609,8 @@ extern "C" Language *swig_javascript(void) {
      * JSEmitter()
      * ----------------------------------------------------------------------------- */
     
    -JSEmitter::JSEmitter()
    -:  templates(NewHash()), namespaces(NULL), current_namespace(NULL), defaultResultName(NewString("result")), f_wrappers(NULL) {
    +JSEmitter::JSEmitter(JSEmitter::JSEngine engine)
    +:  engine(engine), templates(NewHash()), namespaces(NULL), current_namespace(NULL), defaultResultName(NewString("result")), f_wrappers(NULL) {
     }
     
     /* -----------------------------------------------------------------------------
    @@ -816,21 +840,20 @@ int JSEmitter::emitCtor(Node *n) {
     
       Template t_ctor(getTemplate("js_ctor"));
     
    -  //String *mangled_name = SwigType_manglestr(Getattr(n, "name"));
       String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
       if (is_overloaded) {
         t_ctor = getTemplate("js_overloaded_ctor");
         Append(wrap_name, Getattr(n, "sym:overname"));
       }
       Setattr(n, "wrap:name", wrap_name);
    -  // note: removing the is_abstract flag, as this emitter
    -  //       is supposed to be called for non-abstract classes only.
    +  // note: we can remove the is_abstract flag now, as this
    +  //       is called for non-abstract classes only.
       Setattr(state.clazz(), IS_ABSTRACT, 0);
     
       ParmList *params = Getattr(n, "parms");
       emit_parameter_variables(params, wrapper);
       emit_attach_parmmaps(params, wrapper);
    -  // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemap.
    +  // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemaps.
       // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere
       Delete(wrapper->code);
       wrapper->code = NewString("");
    @@ -1157,11 +1180,8 @@ int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) {
     
       marshalInputArgs(n, params, wrapper, Function, is_member, is_static);
       String *action = emit_action(n);
    -
       marshalOutput(n, params, wrapper, action);
    -
       emitCleanupCode(n, wrapper, params);
    -
       Replaceall(wrapper->code, "$symname", iname);
     
       t_function.replace("$jswrapper", wrap_name)
    @@ -1434,7 +1454,7 @@ private:
     };
     
     JSCEmitter::JSCEmitter()
    -:  JSEmitter(), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), f_init(NULL) {
    +:  JSEmitter(JSEmitter::JavascriptCore), NULL_STR(NewString("NULL")), VETO_SET(NewString("JS_veto_set_variable")), f_wrap_cpp(NULL), f_runtime(NULL), f_header(NULL), f_init(NULL) {
     }
     
     JSCEmitter::~JSCEmitter() {
    @@ -1794,7 +1814,7 @@ protected:
       virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
       virtual int emitNamespaces();
     
    -private:
    +protected:
       /* built-in parts */
       String *f_runtime;
       String *f_header;
    @@ -1824,7 +1844,7 @@ private:
     };
     
     V8Emitter::V8Emitter()
    -:  JSEmitter(), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) {
    +:  JSEmitter(JSEmitter::V8), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")) {
     }
     
     V8Emitter::~V8Emitter() {
    @@ -2197,7 +2217,6 @@ JSEmitter *swig_javascript_create_V8Emitter() {
       return new V8Emitter();
     }
     
    -
     /**********************************************************************
      * Helper implementations
      **********************************************************************/
    
    From 74825d2d1a4d07834a288f208ea23c5c1574b4a7 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Sat, 26 Apr 2014 22:47:57 +0200
    Subject: [PATCH 331/352] Fix regression of 226da4.
    
    ---
     Source/Modules/javascript.cxx | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index 078204d20..a067525c1 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -526,7 +526,7 @@ void JAVASCRIPT::main(int argc, char *argv[]) {
     	Swig_mark_arg(i);
     	engine = JSEmitter::JavascriptCore;
           } else if (strcmp(argv[i], "-node") == 0) {
    -      	if (engine) {
    +      	if (engine != -1) {
     	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
     	  SWIG_exit(-1);
           	}
    
    From 4c8a1ea5e88a3b3ac78f3e06eee4c2b4d9973c7c Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Sun, 27 Apr 2014 00:30:57 +0200
    Subject: [PATCH 332/352] Fix node-gyp configuration for example 'exception'.
    
    ---
     Examples/javascript/exception/binding.gyp | 23 ++++++++++++++++++++++-
     1 file changed, 22 insertions(+), 1 deletion(-)
    
    diff --git a/Examples/javascript/exception/binding.gyp b/Examples/javascript/exception/binding.gyp
    index 54eebfaa0..2be0a17a2 100644
    --- a/Examples/javascript/exception/binding.gyp
    +++ b/Examples/javascript/exception/binding.gyp
    @@ -2,7 +2,28 @@
       "targets": [
         {
           "target_name": "example",
    -      "sources": [ "example.cxx", "example_wrap.cxx" ]
    +      "sources": [ "example.cxx", "example_wrap.cxx" ],
    +      'defines': [
    +        'BUILDING_NODE_EXTENSION=1',
    +      ],
    +      'conditions': [
    +        ['OS=="mac"',
    +          {
    +            'xcode_settings': {
    +              'GCC_ENABLE_CPP_RTTI': 'YES',
    +              'GCC_ENABLE_CPP_EXCEPTIONS' : 'YES'
    +            }
    +          }
    +        ],
    +        ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"',
    +          {
    +            'cflags': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter"],
    +            'cflags_cc': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter"],
    +            'cflags!': [ '-fno-exceptions' ],
    +            'cflags_cc!': [ '-fno-exceptions', '-fno-rtti' ]
    +          }
    +        ]
    +      ]
         }
       ]
     }
    
    From d81fe244e3fb8a2677589769eec5375111a35a79 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Sun, 27 Apr 2014 00:34:19 +0200
    Subject: [PATCH 333/352] Prettify generated output in JS emitters.
    
    ---
     Source/Modules/javascript.cxx | 28 ++++++++++++++++------------
     1 file changed, 16 insertions(+), 12 deletions(-)
    
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index a067525c1..b26ee3365 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -1633,12 +1633,12 @@ int JSCEmitter::exitFunction(Node *n) {
     
       if (is_member) {
         if (GetFlag(state.function(), IS_STATIC)) {
    -      Append(state.clazz(STATIC_FUNCTIONS), t_function.str());
    +      t_function.pretty_print(state.clazz(STATIC_FUNCTIONS));
         } else {
    -      Append(state.clazz(MEMBER_FUNCTIONS), t_function.str());
    +      t_function.pretty_print(state.clazz(MEMBER_FUNCTIONS));
         }
       } else {
    -    Append(Getattr(current_namespace, "functions"), t_function.str());
    +    t_function.pretty_print(Getattr(current_namespace, "functions"));
       }
     
       return SWIG_OK;
    @@ -1660,12 +1660,12 @@ int JSCEmitter::exitVariable(Node *n) {
       if (GetFlag(n, "ismember")) {
         if (GetFlag(state.variable(), IS_STATIC)
     	|| Equal(Getattr(n, "nodeType"), "enumitem")) {
    -      Append(state.clazz(STATIC_VARIABLES), t_variable.str());
    +      t_variable.pretty_print(state.clazz(STATIC_VARIABLES));
         } else {
    -      Append(state.clazz(MEMBER_VARIABLES), t_variable.str());
    +      t_variable.pretty_print(state.clazz(MEMBER_VARIABLES));
         }
       } else {
    -    Append(Getattr(current_namespace, "values"), t_variable.str());
    +    t_variable.pretty_print(Getattr(current_namespace, "values"));
       }
     
       return SWIG_OK;
    @@ -2036,7 +2036,8 @@ int V8Emitter::exitVariable(Node *n) {
     	  .replace("$jsname", state.variable(NAME))
     	  .replace("$jsgetter", state.variable(GETTER))
     	  .replace("$jssetter", state.variable(SETTER))
    -	  .trim().print(f_init_static_wrappers);
    +	  .trim()
    +	  .pretty_print(f_init_static_wrappers);
         } else {
           Template t_register = getTemplate("jsv8_register_member_variable");
           t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
    @@ -2044,7 +2045,7 @@ int V8Emitter::exitVariable(Node *n) {
     	  .replace("$jsgetter", state.variable(GETTER))
     	  .replace("$jssetter", state.variable(SETTER))
     	  .trim()
    -	  .print(f_init_wrappers);
    +	  .pretty_print(f_init_wrappers);
         }
       } else {
         // Note: a global variable is treated like a static variable
    @@ -2055,7 +2056,7 @@ int V8Emitter::exitVariable(Node *n) {
     	.replace("$jsgetter", state.variable(GETTER))
     	.replace("$jssetter", state.variable(SETTER))
     	.trim()
    -	.print(f_init_wrappers);
    +	.pretty_print(f_init_wrappers);
       }
     
       return SWIG_OK;
    @@ -2083,14 +2084,14 @@ int V8Emitter::exitFunction(Node *n) {
     	  .replace("$jsname", state.function(NAME))
     	  .replace("$jswrapper", state.function(WRAPPER_NAME))
     	  .trim()
    -	  .print(f_init_static_wrappers);
    +	  .pretty_print(f_init_static_wrappers);
         } else {
           Template t_register = getTemplate("jsv8_register_member_function");
           t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
     	  .replace("$jsname", state.function(NAME))
     	  .replace("$jswrapper", state.function(WRAPPER_NAME))
     	  .trim()
    -	  .print(f_init_wrappers);
    +	  .pretty_print(f_init_wrappers);
         }
       } else {
         // Note: a global function is treated like a static function
    @@ -2206,7 +2207,10 @@ int V8Emitter::emitNamespaces() {
     	  .trim();
     
           // prepend in order to achieve reversed order of registration statements
    -      Insert(f_init_register_namespaces, 0, t_register_ns.str());
    +      String *tmp_register_stmt = NewString("");
    +      t_register_ns.pretty_print(tmp_register_stmt);
    +      Insert(f_init_register_namespaces, 0, tmp_register_stmt);
    +      Delete(tmp_register_stmt);
         }
       }
     
    
    From 7a7faab765f1b152ddf6ce51a1830300cef336e3 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Sun, 27 Apr 2014 00:34:49 +0200
    Subject: [PATCH 334/352] Fix bug and regression in javascript namespace
     generator.
    
    ---
     Examples/test-suite/javascript/nspace_runme.js |  3 +--
     Source/Modules/javascript.cxx                  | 14 +++++++-------
     2 files changed, 8 insertions(+), 9 deletions(-)
    
    diff --git a/Examples/test-suite/javascript/nspace_runme.js b/Examples/test-suite/javascript/nspace_runme.js
    index 929a6b21d..f1afff428 100644
    --- a/Examples/test-suite/javascript/nspace_runme.js
    +++ b/Examples/test-suite/javascript/nspace_runme.js
    @@ -48,8 +48,7 @@ var col1 = new nspace.Outer.Inner1.Color();
     var col2 = nspace.Outer.Inner2.Color.create();
     col2.colors(col1, col1, col2, col2, col2);
     
    -// TODO: why isn't it scoped in the namespace???
    -nspace.namespaceFunction(color);
    +nspace.Outer.Inner1.namespaceFunction(color);
     nspace.Outer.Inner1.namespaceVar = 111;
     if (nspace.Outer.Inner1.namespaceVar !== 111) {
       throw new Error("Failed.");
    diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
    index b26ee3365..5ec42c9c6 100644
    --- a/Source/Modules/javascript.cxx
    +++ b/Source/Modules/javascript.cxx
    @@ -1344,7 +1344,8 @@ void JSEmitter::emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params) {
     }
     
     int JSEmitter::switchNamespace(Node *n) {
    -  // HACK: somehow this gets called when member functions are processed...ignoring
    +  // HACK: somehow this gets called for member functions.
    +  // We can safely ignore them, as members are not associated to a namespace (only their class)
       if (GetFlag(n, "ismember")) {
         return SWIG_OK;
       }
    @@ -1358,13 +1359,12 @@ int JSEmitter::switchNamespace(Node *n) {
       }
     
       if (nspace == NULL) {
    -    // enums and constants do not have 'sym:nspace' set
    -    // so we try to get the namespace from the qualified name
    -    if (Equal(Getattr(n, "nodeType"), "enumitem")) {
    -      nspace = Swig_scopename_prefix(Getattr(n, "name"));
    -    }
    +    // It seems that only classes have 'sym:nspace' set.
    +    // We try to get the namespace from the qualified name (i.e., everything before the last '::')
    +    nspace = Swig_scopename_prefix(Getattr(n, "name"));
       }
     
    +  // If there is not even a scopename prefix then it must be global scope
       if (nspace == NULL) {
         current_namespace = Getattr(namespaces, "::");
         return SWIG_OK;
    @@ -2097,7 +2097,7 @@ int V8Emitter::exitFunction(Node *n) {
         // 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");
    -    t_register.replace("$jsparent", Getattr(current_namespace, NAME))
    +    t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED))
     	.replace("$jsname", state.function(NAME))
     	.replace("$jswrapper", state.function(WRAPPER_NAME))
     	.trim()
    
    From cb7a1f23f5631062e0c7cacffdb7f4578d6bef67 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Sun, 27 Apr 2014 00:37:21 +0200
    Subject: [PATCH 335/352] Enable javascript examples 'exception', 'namespace'.
    
    ---
     Examples/javascript/check.list | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/Examples/javascript/check.list b/Examples/javascript/check.list
    index 040267812..a4e4ccbbf 100644
    --- a/Examples/javascript/check.list
    +++ b/Examples/javascript/check.list
    @@ -1,9 +1,9 @@
     class
     constant
     enum
    -#exception
    +exception
     functor
    -#namespace
    +namespace
     operator
     overload
     pointer
    
    From 9149f5953b37a6fda8949e057e82de37e57b4f98 Mon Sep 17 00:00:00 2001
    From: Oliver Buchtala 
    Date: Mon, 28 Apr 2014 23:36:04 +0200
    Subject: [PATCH 336/352] Added some documentation on using 'node-webkit'.
    
    ---
     Doc/Manual/Javascript.html | 95 ++++++++++++++++++++++++++++++++++++--
     1 file changed, 91 insertions(+), 4 deletions(-)
    
    diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html
    index 329ee4421..e589d9d09 100644
    --- a/Doc/Manual/Javascript.html
    +++ b/Doc/Manual/Javascript.html
    @@ -14,7 +14,9 @@
     Javascript has gone beyond being a browser-based scripting language and with node.js, it is also used as a backend development language.

    Native Javascript extensions can be used for applications that embed a web-browser view or that embed a Javascript engine (such as node.js). Extending a general purpose web-browser is not possible as this would be a severe security issue.

    SWIG Javascript currently supports JavascriptCore, the Javascript engine used by Safari/Webkit, and v8, which is used by Chromium and node.js.

    -

    WebKit is a modern browser implementation available as open-source which can be embedded into an application.

    +

    WebKit is a modern browser implementation available as open-source which can be embedded into an application. +With node-webkit there is a platform which uses Google's Chromium as Web-Browser widget and node.js for javascript extensions. +

    Preliminaries

    @@ -40,8 +42,8 @@ $ swig -javascript -jsc example.i
     $ swig -c++ -javascript -jsc example.i
    -

    This creates a C/C++ source file example_wrap.c or example_wrap.cxx. The generated C source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application to create an extension module.

    -

    The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. The wrapped module will export one function which must be called to register the module with the Javascript interpreter. For example, if your module is named example the corresponding initializer for JavascriptCore would be

    +

    This creates a C/C++ source file example_wrap.c or example_wrap.cxx. The generated C source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application to create an extension module.

    +

    The name of the wrapper file is derived from the name of the input file. For example, if the input file is example.i, the name of the wrapper file is example_wrap.c. To change this, you can use the -o option. The wrapped module will export one function which must be called to register the module with the Javascript interpreter. For example, if your module is named example the corresponding initializer for JavascriptCore would be

     bool example_initialize(JSGlobalContextRef context, JSObjectRef *exports)
    @@ -238,9 +240,94 @@ int main(int argc, char* argv[])

    Creating Applications with node-webkit

    -

    TODO: documentation is coming soon

    +

    To get started with node-webkit there is a very informative set of wiki pages.

    +

    Similar to node.js, node-webkit is started from command line within a node.js project directory. +Native extensions are created in the very same way as for node.js, except that a customized gyp derivate has to be used: nw-gyp.

    +

    +A simple example would have the following structure: +

    + +
    +
    +- package.json
    +- app.html
    +- app.js
    +- node_modules
    +  / example
    +  ... (as known from node.js)
    +
    +
    + +

    +The configuration file essentially conforms to node.js syntax. +It has some extras to configure node-webkit. See the Manifest specification for more details. +

    + +

    + package.json: +

    +
    +
    +{
    +  "name": "example"
    +  "main": "app.html"
    +  "window": {
    +    "show": true,
    +    "width": 800,
    +    "height": 600
    +  }
    +}
    +
    + +

    +The 'main' property of package.json specifies a web-page to be rendered in +the main window.

    + +

    + app.html: +

    + +
    +
    +<html>
    +  <head>
    +    <script src="app.js"></script>
    +  </head>
    +  <body>
    +    <div>
    +      The greatest common divisor of
    +      <span id="x"></span> and
    +      <span id="y"></span> is
    +      <span id="z"></span>.
    +    </div>
    +  </body>
    +</html>
    +
    + +

    +As known from node.js one can use require to load javascript modules. +Additionally, node-webkit provides an API that allows to manipulate the window's menu, +open new windows, and many more things. +

    + +

    + app.js: +

    + +
    +
    window.onload = function() {
    +  var example = require("example");
    +  var x = 18;
    +  var y = 24;
    +  var z = example.gcd(x,y);
    +  document.querySelector('#x').innerHTML = x;
    +  document.querySelector('#y').innerHTML = y;
    +  document.querySelector('#z').innerHTML = z;
    +};
    +
    +

    Examples

    Some basic examples are shown here in more detail.

    From b30c6a452f1894b3376361e0c74c400b063bfb0d Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 29 Apr 2014 00:29:17 +0200 Subject: [PATCH 337/352] Make javascript 'nspace' conform to corresponding lua example. --- Examples/javascript/check.list | 2 +- Examples/javascript/namespace/example.cxx | 36 ------------- Examples/javascript/namespace/example.h | 20 -------- Examples/javascript/namespace/runme.js | 10 ---- .../javascript/{namespace => nspace}/Makefile | 2 +- .../{namespace => nspace}/binding.gyp | 2 +- Examples/javascript/nspace/example.h | 23 +++++++++ .../{namespace => nspace}/example.i | 4 +- .../{namespace => nspace}/example.js | 0 Examples/javascript/nspace/runme.js | 50 +++++++++++++++++++ 10 files changed, 78 insertions(+), 71 deletions(-) delete mode 100644 Examples/javascript/namespace/example.cxx delete mode 100644 Examples/javascript/namespace/example.h delete mode 100644 Examples/javascript/namespace/runme.js rename Examples/javascript/{namespace => nspace}/Makefile (54%) rename Examples/javascript/{namespace => nspace}/binding.gyp (54%) create mode 100644 Examples/javascript/nspace/example.h rename Examples/javascript/{namespace => nspace}/example.i (53%) rename Examples/javascript/{namespace => nspace}/example.js (100%) create mode 100644 Examples/javascript/nspace/runme.js diff --git a/Examples/javascript/check.list b/Examples/javascript/check.list index a4e4ccbbf..9707e77d4 100644 --- a/Examples/javascript/check.list +++ b/Examples/javascript/check.list @@ -3,7 +3,7 @@ constant enum exception functor -namespace +nspace operator overload pointer diff --git a/Examples/javascript/namespace/example.cxx b/Examples/javascript/namespace/example.cxx deleted file mode 100644 index 5beeb09fe..000000000 --- a/Examples/javascript/namespace/example.cxx +++ /dev/null @@ -1,36 +0,0 @@ -/* File : example.c */ - -#include -#include "example.h" - -#define M_PI 3.14159 - - -/* A global variable */ -namespace nspace -{ -double Foo = 3.0; - -/* Compute the greatest common divisor of positive integers */ -int gcd(int x, int y) { - int g; - g = y; - while (x > 0) { - g = x; - x = y % x; - y = g; - } - return g; -} - -Circle::Circle(): radius(1.0) {} - -Circle::Circle(double r): radius(r) { - std::cout << "created Circle with r=" << radius << std::endl; -} - -double Circle::area() { - std::cout << "Circle::area called, r=" << radius << std::endl; - return M_PI*radius*radius; -} -} diff --git a/Examples/javascript/namespace/example.h b/Examples/javascript/namespace/example.h deleted file mode 100644 index 7f76c2f07..000000000 --- a/Examples/javascript/namespace/example.h +++ /dev/null @@ -1,20 +0,0 @@ - -namespace nspace { - -extern int gcd(int x, int y); -extern double Foo; - -class Circle -{ -public: - Circle(); - - Circle(double r); - - double area(); - - double radius; - -}; - -} diff --git a/Examples/javascript/namespace/runme.js b/Examples/javascript/namespace/runme.js deleted file mode 100644 index 08e0d3769..000000000 --- a/Examples/javascript/namespace/runme.js +++ /dev/null @@ -1,10 +0,0 @@ -var example = require("./example"); - -console.log("Global variable Foo=" + example.nspace.Foo); -example.nspace.Foo = 5; -console.log("Variable Foo changed to " + example.nspace.Foo); -console.log("GCD of number 6,18 is " + example.nspace.gcd(6,18)); - -console.log("Creating some objects:"); -c = new example.nspace.Circle(10); -console.log("area = " + c.area()); diff --git a/Examples/javascript/namespace/Makefile b/Examples/javascript/nspace/Makefile similarity index 54% rename from Examples/javascript/namespace/Makefile rename to Examples/javascript/nspace/Makefile index 31846faae..ea04c7df8 100755 --- a/Examples/javascript/namespace/Makefile +++ b/Examples/javascript/nspace/Makefile @@ -1,3 +1,3 @@ -SRCS = example.cxx +SRCS = include ../example.mk diff --git a/Examples/javascript/namespace/binding.gyp b/Examples/javascript/nspace/binding.gyp similarity index 54% rename from Examples/javascript/namespace/binding.gyp rename to Examples/javascript/nspace/binding.gyp index 54eebfaa0..69af46b22 100644 --- a/Examples/javascript/namespace/binding.gyp +++ b/Examples/javascript/nspace/binding.gyp @@ -2,7 +2,7 @@ "targets": [ { "target_name": "example", - "sources": [ "example.cxx", "example_wrap.cxx" ] + "sources": [ "example_wrap.cxx" ] } ] } diff --git a/Examples/javascript/nspace/example.h b/Examples/javascript/nspace/example.h new file mode 100644 index 000000000..53066980a --- /dev/null +++ b/Examples/javascript/nspace/example.h @@ -0,0 +1,23 @@ +#ifndef _example_guardian_ +#define _example_guardian_ + +int module_function() { return 7; } +int module_variable = 9; + +namespace MyWorld { + class World { + public: + World() : world_max_count(9) {} + int create_world() { return 17; } + const int world_max_count; // = 9 + }; + namespace Nested { + class Dweller { + public: + enum Gender { MALE = 0, FEMALE = 1 }; + static int count() { return 19; } + }; + } +} + +#endif diff --git a/Examples/javascript/namespace/example.i b/Examples/javascript/nspace/example.i similarity index 53% rename from Examples/javascript/namespace/example.i rename to Examples/javascript/nspace/example.i index e14b10b44..c30f87fec 100644 --- a/Examples/javascript/namespace/example.i +++ b/Examples/javascript/nspace/example.i @@ -1,10 +1,10 @@ -/* File : example.i */ %module example %{ #include "example.h" %} -%feature("nspace", 1); +%nspace MyWorld::Nested::Dweller; +%nspace MyWorld::World; %include "example.h" diff --git a/Examples/javascript/namespace/example.js b/Examples/javascript/nspace/example.js similarity index 100% rename from Examples/javascript/namespace/example.js rename to Examples/javascript/nspace/example.js diff --git a/Examples/javascript/nspace/runme.js b/Examples/javascript/nspace/runme.js new file mode 100644 index 000000000..d6a49d8d4 --- /dev/null +++ b/Examples/javascript/nspace/runme.js @@ -0,0 +1,50 @@ +// File: runme.js + +// This file illustrates class C++ interface generated +// by SWIG. + +var example = require("./example"); + +// Calling a module function ( aka global function ) +if (example.module_function() !== 7) { + throw new Error("example.module_function() should equal 7"); +} +console.log("example.module_function(): " + example.module_function()); + +// Accessing a module (aka global) variable +if (example.module_variable !== 9) { + throw new Error("example.module_variable should equal 9"); +} +console.log("example.module_variable: " + example.module_variable); + +// Creating an instance of the class +var w1 = new example.MyWorld.World(); +console.log("Creating class instance: w1 = new example.MyWorld.World(): " + w1); + +// Accessing class members +if (w1.create_world() !== 17) { + throw new Error("w1.create_world() should equal 17"); +} +console.log("w1.create_world() = " + w1.create_world()); + +if (w1.world_max_count !== 9) { + throw new Error("w1.world_max_count should equal 9"); +} +console.log("w1.world_max_count = " + w1.world_max_count); + +// Accessing enums from class within namespace +if (example.MyWorld.Nested.Dweller.MALE !== 0) { + throw new Error("example.MyWorld.Nested.Dweller.MALE should equal 0"); +} +console.log("Accessing enums: ex.MyWorld.Nested.Dweller.MALE = " + example.MyWorld.Nested.Dweller.MALE); + +if (example.MyWorld.Nested.Dweller.FEMALE !== 1) { + throw new Error("example.MyWorld.Nested.Dweller.FEMALE should equal 1"); +} +console.log("Accessing enums: ex.MyWorld.Nested.Dweller.FEMALE = " + example.MyWorld.Nested.Dweller.FEMALE); + +// Accessing static member function +if (example.MyWorld.Nested.Dweller.count() !== 19) { + throw new Error("example.MyWorld.Nested.Dweller.count() should equal 19"); +} +console.log("Accessing static member function: ex.MyWorld.Nested.Dweller.count() = " + example.MyWorld.Nested.Dweller.count()); From c2f9bd88b1de7fd1252a4f9532a2626af17ebef6 Mon Sep 17 00:00:00 2001 From: Oliver Buchtala Date: Tue, 29 Apr 2014 00:37:33 +0200 Subject: [PATCH 338/352] Enable Javascript in director_nspace_director_name_collision.i. --- Examples/test-suite/director_nspace_director_name_collision.i | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/test-suite/director_nspace_director_name_collision.i b/Examples/test-suite/director_nspace_director_name_collision.i index 8fd27c968..190bdf4fa 100644 --- a/Examples/test-suite/director_nspace_director_name_collision.i +++ b/Examples/test-suite/director_nspace_director_name_collision.i @@ -34,7 +34,7 @@ namespace TopLevel %include // nspace feature only supported by these languages -#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) +#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT) %nspace TopLevel::A::Foo; %nspace TopLevel::B::Foo; #else From 73bb909baef9ee5f3933850a75dc107e654185cf Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Thu, 1 May 2014 14:37:58 +1200 Subject: [PATCH 339/352] [PHP] The generated __isset() method now returns true for read-only properties. --- CHANGES.current | 3 ++ Examples/test-suite/php/arrays_runme.php | 1 + Source/Modules/php.cxx | 43 ++++++++++++------------ 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 11682c9dd..826b1a2c5 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,9 @@ See the RELEASENOTES file for a summary of changes in each release. Version 3.0.1 (in progress) =========================== +2014-05-01: olly + [PHP] The generated __isset() method now returns true for read-only properties. + 2014-04-08: wsfulton SF Bug #1366 - Remove duplicate declarations of strtoimax and strtoumax in inttypes.i diff --git a/Examples/test-suite/php/arrays_runme.php b/Examples/test-suite/php/arrays_runme.php index 23490e61e..ae17d05e7 100644 --- a/Examples/test-suite/php/arrays_runme.php +++ b/Examples/test-suite/php/arrays_runme.php @@ -12,6 +12,7 @@ check::classname(simplestruct,$ss); $as=new arraystruct(); $as->array_c="abc"; check::equal($as->array_c,"a",'$as->array_c=="a"'); +check::equal(isset($as->array_const_i),TRUE,'isset($as->array_const_i)'); check::done(); ?> diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 86e1274a8..b07c82d3b 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -2054,7 +2054,6 @@ done: // Write property SET handlers ki = First(shadow_set_vars); - if (ki.key) { // This class has setters. Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n"); @@ -2077,17 +2076,6 @@ done: Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA); } Printf(s_phpclasses, "\t}\n"); - - /* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */ - Printf(s_phpclasses, "\n\tfunction __isset($var) {\n"); - Printf(s_phpclasses, "\t\tif (function_exists('%s_'.$var.'_set')) return true;\n", shadow_classname); - Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n"); - if (baseclass) { - Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass); - } else { - Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA); - } - Printf(s_phpclasses, "\t}\n"); } else { Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n"); Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_alter_newobject($this->%s,$value);\n", module, SWIG_PTR); @@ -2097,18 +2085,10 @@ done: Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA); } Printf(s_phpclasses, "\t}\n"); - Printf(s_phpclasses, "\n\tfunction __isset($var) {\n"); - Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n"); - if (baseclass) { - Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass); - } else { - Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA); - } - Printf(s_phpclasses, "\t}\n"); } + // Write property GET handlers ki = First(shadow_get_vars); - if (ki.key) { // This class has getters. Printf(s_phpclasses, "\n\tfunction __get($var) {\n"); @@ -2144,6 +2124,19 @@ done: Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA); } Printf(s_phpclasses, "\t}\n"); + + /* Create __isset for PHP 5.1 and later; PHP 5.0 will just ignore it. */ + /* __isset() should return true for read-only properties, so check for + * *_get() not *_set(). */ + Printf(s_phpclasses, "\n\tfunction __isset($var) {\n"); + Printf(s_phpclasses, "\t\tif (function_exists('%s_'.$var.'_get')) return true;\n", shadow_classname); + Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n"); + if (baseclass) { + Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass); + } else { + Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA); + } + Printf(s_phpclasses, "\t}\n"); } else { Printf(s_phpclasses, "\n\tfunction __get($var) {\n"); Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_get_newobject($this->%s);\n", module, SWIG_PTR); @@ -2153,6 +2146,14 @@ done: Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA); } Printf(s_phpclasses, "\t}\n"); + Printf(s_phpclasses, "\n\tfunction __isset($var) {\n"); + Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n"); + if (baseclass) { + Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass); + } else { + Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA); + } + Printf(s_phpclasses, "\t}\n"); } if (!class_has_ctor) { From 5792e97a44bd0d14c6479643efb22e5a4d46808e Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 May 2014 07:24:52 +0100 Subject: [PATCH 340/352] Javascript: ensure banner appears before %begin code --- Lib/javascript/v8/javascriptruntime.swg | 7 ++++--- Source/Modules/javascript.cxx | 10 ++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg index 3ccbbd5b7..ea11b0837 100644 --- a/Lib/javascript/v8/javascriptruntime.swg +++ b/Lib/javascript/v8/javascriptruntime.swg @@ -6,9 +6,10 @@ // V8 Version Macro // ---------------- // v8 does not (until now) provide a version macro - which is still discussed and may come soon. -// Until then, we set a default version which can be overridden via command line or via a define in -// the SWIG configuration. -// For example, `swig -javascript -v8 -DV8_VERSION=0x031110` +// Until then, we set a default version which can be overridden via command line using V8_VERSION: +// swig -javascript -v8 -DV8_VERSION=0x031110 +// Or code in the interface file using SWIG_V8_VERSION: +// %begin %{#define SWIG_V8_VERSION 0x031110%} %define %swig_v8_define_version(version) %insert("runtime") %{ diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 5ec42c9c6..93c21645f 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -1559,6 +1559,8 @@ int JSCEmitter::initialize(Node *n) { Swig_register_filebyname("runtime", f_runtime); Swig_register_filebyname("init", f_init); + Swig_banner(f_wrap_cpp); + return SWIG_OK; } @@ -1566,9 +1568,6 @@ int JSCEmitter::dump(Node *n) { /* Get the module name */ String *module = Getattr(n, "name"); - // write the SWIG banner - Swig_banner(f_wrap_cpp); - Template initializer_define(getTemplate("js_initializer_define")); initializer_define.replace("$jsname", module).pretty_print(f_header); @@ -1890,6 +1889,8 @@ int V8Emitter::initialize(Node *n) { state.globals(FORCE_CPP, NewString("1")); + Swig_banner(f_wrap_cpp); + return SWIG_OK; } @@ -1897,9 +1898,6 @@ int V8Emitter::dump(Node *n) { /* Get the module name */ String *module = Getattr(n, "name"); - // write the SWIG banner - Swig_banner(f_wrap_cpp); - Template initializer_define(getTemplate("js_initializer_define")); initializer_define.replace("$jsname", module).pretty_print(f_header); From 80953ccfc9be6dfeb01728b32d9a8d15d28ba9e9 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 29 Apr 2014 07:20:20 +0100 Subject: [PATCH 341/352] Fix some typos --- Examples/test-suite/lua/operator_overload_runme.lua | 2 +- Lib/lua/luarun.swg | 11 +++-------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/Examples/test-suite/lua/operator_overload_runme.lua b/Examples/test-suite/lua/operator_overload_runme.lua index f3753749b..5ba06ff08 100644 --- a/Examples/test-suite/lua/operator_overload_runme.lua +++ b/Examples/test-suite/lua/operator_overload_runme.lua @@ -79,7 +79,7 @@ assert(tostring(Op(1))=="Op(1)") assert(tostring(Op(-3))=="Op(-3)") --- check that operator overloads is correctly propogated accross hierarchy +-- check that operator overloads are correctly propogated down inheritance hierarchy a_d=OpDerived() b_d=OpDerived(5) diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg index 42efb9b8f..d038f4af1 100644 --- a/Lib/lua/luarun.swg +++ b/Lib/lua/luarun.swg @@ -1274,8 +1274,8 @@ SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L, swig_lua_clas #endif } -/* helpers to add user defined class metamedhods - __add, __sub etc. Necessity for those helpers - arise from the following issue: Lua runtime checks for metamethod existence with rawget function +/* Helpers to add user defined class metamedhods - __add, __sub etc. The helpers are needed + for the following issue: Lua runtime checks for metamethod existence with rawget function ignoring our SWIG-provided __index and __newindex functions. Thus our inheritance-aware method search algorithm doesn't work in such case. (Not to say that Lua runtime queries metamethod directly in metatable and not in object). @@ -1287,7 +1287,7 @@ SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L, swig_lua_clas SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L); /*forward declaration*/ -/* The real function that resolveds metamethod. +/* The real function that resolves a metamethod. * Function searches given class and all it's bases(recursively) for first instance of something that is * not equal to SWIG_Lua_resolve_metatmethod. (Almost always this 'something' is actuall metamethod implementation * and it is a SWIG-generated C function.). It returns value on the top of the L and there is no garbage below the @@ -1367,7 +1367,6 @@ SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L) */ SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *clss, const int metatable_index) { - /* metamethod name - on the top of the stack */ assert(lua_isstring(L,-1)); @@ -1382,7 +1381,6 @@ SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class * } lua_pop(L,1); - /* Iterating over immediate bases */ int success = 0; int i = 0; @@ -1410,7 +1408,6 @@ SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class * break; } - return success; } @@ -1430,7 +1427,6 @@ SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class if(is_inheritable) { /* if metamethod is inheritable */ SWIG_Lua_add_class_user_metamethod(L,clss,metatable_index); } - } lua_pop(L,1); /* remove inheritable metatmethods table */ @@ -1452,7 +1448,6 @@ SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class * a __getitem/__setitem method should be defined */ lua_pop(L,1); /* pop class metatable */ - } /* Register class static methods,attributes etc as well as constructor proxy */ From a6e5e97157140208a8e2184d759ac4c1270b37b2 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 May 2014 19:41:17 +0100 Subject: [PATCH 342/352] Javascript cosmetic changes --- Source/Modules/javascript.cxx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx index 93c21645f..20af76f9f 100644 --- a/Source/Modules/javascript.cxx +++ b/Source/Modules/javascript.cxx @@ -270,9 +270,7 @@ protected: protected: JSEngine engine; - Hash *templates; - State state; // contains context specific data (DOHs) @@ -280,9 +278,7 @@ protected: // which are switched on namespace change Hash *namespaces; Hash *current_namespace; - String *defaultResultName; - File *f_wrappers; }; @@ -324,7 +320,7 @@ public: private: - JSEmitter * emitter; + JSEmitter *emitter; }; /* --------------------------------------------------------------------- From f153193eaa794041a74df200def95b4ce89df8e4 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 May 2014 19:43:05 +0100 Subject: [PATCH 343/352] Remove unnecessary Javascript installs on Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b0eb54d9b..168ef2780 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ before_install: - if test -z "$SWIGLANG"; then sudo apt-get -qq install yodl; fi - if test "$SWIGLANG" = "csharp"; then sudo apt-get -qq install mono-devel; fi - if test "$SWIGLANG" = "go"; then go env | sed -e 's/^/export /' > goenvsetup && source goenvsetup && rm -f goenvsetup; fi # Until configure.ac is fixed - - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "node"; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs && sudo npm install -g node-gyp; fi + - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "node"; then sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs && sudo npm install -g node-gyp; fi - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "jsc"; then sudo apt-get install -qq libwebkitgtk-dev; fi - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "v8"; then sudo apt-get install -qq libv8-dev; fi - if test "$SWIGLANG" = "guile"; then sudo apt-get -qq install guile-2.0-dev; fi From 24ffe8fae06c5ee92aeef9c367652e3e949292df Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 May 2014 20:05:16 +0100 Subject: [PATCH 344/352] Revert "Remove unnecessary Javascript installs on Travis" This reverts commit f153193eaa794041a74df200def95b4ce89df8e4. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 168ef2780..b0eb54d9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ before_install: - if test -z "$SWIGLANG"; then sudo apt-get -qq install yodl; fi - if test "$SWIGLANG" = "csharp"; then sudo apt-get -qq install mono-devel; fi - if test "$SWIGLANG" = "go"; then go env | sed -e 's/^/export /' > goenvsetup && source goenvsetup && rm -f goenvsetup; fi # Until configure.ac is fixed - - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "node"; then sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs && sudo npm install -g node-gyp; fi + - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "node"; then sudo apt-get install -qq rlwrap python-software-properties && echo 'yes' | sudo add-apt-repository ppa:chris-lea/node.js && sudo apt-get -qq update && sudo apt-get install -qq nodejs && sudo npm install -g node-gyp; fi - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "jsc"; then sudo apt-get install -qq libwebkitgtk-dev; fi - if test "$SWIGLANG" = "javascript" -a "$ENGINE" = "v8"; then sudo apt-get install -qq libv8-dev; fi - if test "$SWIGLANG" = "guile"; then sudo apt-get -qq install guile-2.0-dev; fi From 6b25dfda60cea903311b9b807cd29fed648c9364 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 1 May 2014 20:11:06 +0100 Subject: [PATCH 345/352] Restore full Travis testing since javascript branch merge --- .travis.yml | 43 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index b0eb54d9b..890382c40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,51 @@ -language: c +language: cpp compiler: - - gcc - clang + - gcc env: - SWIGLANG= matrix: include: + - compiler: gcc + env: SWIGLANG=csharp + - compiler: gcc + env: SWIGLANG=go + - compiler: gcc + env: SWIGLANG=guile + - compiler: gcc + env: SWIGLANG=java - compiler: gcc env: SWIGLANG=javascript ENGINE=node - compiler: gcc env: SWIGLANG=javascript ENGINE=jsc - compiler: gcc env: SWIGLANG=javascript ENGINE=v8 + - compiler: gcc + env: SWIGLANG=lua + - compiler: gcc + env: SWIGLANG=octave SWIGJOBS=-j4 + - compiler: gcc + env: SWIGLANG=perl5 + - compiler: gcc + env: SWIGLANG=php + - compiler: gcc + env: SWIGLANG=python VER=2.4 + - compiler: gcc + env: SWIGLANG=python VER=2.5 + - compiler: gcc + env: SWIGLANG=python VER=2.6 + - compiler: gcc + env: SWIGLANG=python # 2.7 + - compiler: gcc + env: SWIGLANG=python PY3=3 # 3.2 + - compiler: gcc + env: SWIGLANG=python PY3=3 VER=3.3 + - compiler: gcc + env: SWIGLANG=python PY3=3 VER=3.4 + - compiler: gcc + env: SWIGLANG=ruby + - compiler: gcc + env: SWIGLANG=tcl allow_failures: # None before_install: @@ -31,10 +65,10 @@ before_install: - if test "$SWIGLANG" = "octave"; then sudo apt-get -qq install octave3.2 octave3.2-headers; fi - if test "$SWIGLANG" = "php"; then sudo apt-get install php5-cli php5-dev; fi - if test "$SWIGLANG" = "python" -a "$PY3" -a -z "$VER"; then sudo apt-get install -qq python3-dev; fi - - if test "$SWIGLANG" = "python" -a "$VER"; then sudo add-apt-repository -y ppa:fkrull/deadsnakes && sudo apt-get -qq update && sudo apt-get -qq install python${VER}-dev; fi + - if test "$SWIGLANG" = "python" -a "$VER"; then sudo add-apt-repository -y ppa:fkrull/deadsnakes && sudo apt-get -qq update && sudo apt-get -qq install python${VER}-dev && export CONFIGOPTS="--with-python${PY3}=python${VER}"; fi - if test "$SWIGLANG" = "tcl"; then sudo apt-get -qq install tcl8.4-dev; fi script: - - ./autogen.sh && ./configure + - ./autogen.sh && ./configure $CONFIGOPTS - make -s $SWIGJOBS - ./swig -version && ./swig -pcreversion - if test -z "$SWIGLANG"; then make -s $SWIGJOBS check-ccache; fi @@ -46,4 +80,3 @@ script: branches: only: - master - - javascript From 4e63c4f720728cc9b54e6033da897b5a785836eb Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Fri, 2 May 2014 18:40:54 +1200 Subject: [PATCH 346/352] Remove errnoeous note claiming C++ operator~ maps to Lua .. --- Doc/Manual/Lua.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html index c67e08834..269cb2801 100644 --- a/Doc/Manual/Lua.html +++ b/Doc/Manual/Lua.html @@ -993,7 +993,7 @@ The current list of operators which can be overloaded (and the alternative funct
  • __unm__ unary minus
  • __call__ operator() (often used in functor classes)
  • __pow__ the exponential fn (no C++ equivalent, Lua uses ^) -
  • __concat__ the concatenation operator (SWIG maps C++'s ~ to Lua's ..) +
  • __concat__ the concatenation operator (Lua's ..)
  • __eq__ operator==
  • __lt__ operator<
  • __le__ operator<= From 7cd9063b52d29bf3a5c6cee8d272b75a1012756b Mon Sep 17 00:00:00 2001 From: Karl Wette Date: Fri, 2 May 2014 16:01:55 +0200 Subject: [PATCH 347/352] Remove execute permissions from various non-executable files - source files and Makefiles need never be executable - scripts are run directly by their interpreters in the test suites, so also do not need to be executable --- Examples/guile/matrix/runme.scm | 0 Examples/javascript/class/Makefile | 0 Examples/javascript/class/example.cxx | 0 Examples/javascript/class/example.h | 0 Examples/javascript/class/example.i | 0 Examples/javascript/class/runme.js | 0 Examples/javascript/constant/Makefile | 0 Examples/javascript/constant/example.i | 0 Examples/javascript/constant/runme.js | 0 Examples/javascript/enum/Makefile | 0 Examples/javascript/enum/example.cxx | 0 Examples/javascript/enum/example.h | 0 Examples/javascript/enum/example.i | 0 Examples/javascript/enum/runme.js | 0 Examples/javascript/exception/Makefile | 0 Examples/javascript/functor/Makefile | 0 Examples/javascript/nspace/Makefile | 0 Examples/javascript/operator/Makefile | 0 Examples/javascript/overload/Makefile | 0 Examples/javascript/pointer/Makefile | 0 Examples/javascript/pointer/example.cxx | 0 Examples/javascript/pointer/example.i | 0 Examples/javascript/pointer/runme.js | 0 Examples/javascript/reference/Makefile | 0 Examples/javascript/reference/example.cxx | 0 Examples/javascript/reference/example.h | 0 Examples/javascript/reference/example.i | 0 Examples/javascript/reference/runme.js | 0 Examples/javascript/simple/Makefile | 0 Examples/javascript/simple/runme.js | 0 Examples/javascript/template/Makefile | 0 Examples/javascript/variables/Makefile | 0 Examples/javascript/variables/example.cxx | 0 Examples/javascript/variables/example.h | 0 Examples/javascript/variables/example.i | 0 Examples/javascript/variables/runme.js | 0 Examples/test-suite/javascript/Makefile.in | 0 Examples/test-suite/ocaml/makedebugtop | 0 Examples/test-suite/octave/iadd_runme.m | 0 Examples/test-suite/octave/overload_complicated_runme.m | 0 Examples/test-suite/perl5/char_binary_runme.pl | 0 Examples/test-suite/perl5/class_ignore_runme.pl | 0 Examples/test-suite/perl5/contract_runme.pl | 0 Examples/test-suite/perl5/enum_template_runme.pl | 0 Examples/test-suite/perl5/grouping_runme.pl | 0 Examples/test-suite/perl5/ignore_parameter_runme.pl | 0 Examples/test-suite/perl5/inherit_missing_runme.pl | 0 Examples/test-suite/perl5/li_std_except_runme.pl | 0 Examples/test-suite/perl5/minherit_runme.pl | 0 Examples/test-suite/perl5/naturalvar_runme.pl | 0 Examples/test-suite/perl5/preproc_runme.pl | 0 Examples/test-suite/perl5/primitive_types_runme.pl | 0 Examples/test-suite/perl5/reference_global_vars_runme.pl | 0 Examples/test-suite/perl5/rename_scope_runme.pl | 0 Examples/test-suite/perl5/return_const_value_runme.pl | 0 Examples/test-suite/perl5/run-perl-test.pl | 0 Examples/test-suite/perl5/sizet_runme.pl | 0 Examples/test-suite/perl5/sneaky1_runme.pl | 0 Examples/test-suite/perl5/template_typedef_cplx2_runme.pl | 0 Examples/test-suite/perl5/typedef_class_runme.pl | 0 Examples/test-suite/perl5/typename_runme.pl | 0 Examples/test-suite/perl5/using1_runme.pl | 0 Examples/test-suite/perl5/using2_runme.pl | 0 Examples/test-suite/perl5/wrapmacro_runme.pl | 0 Examples/test-suite/ruby/abstract_access_runme.rb | 0 Examples/test-suite/ruby/access_change_runme.rb | 0 Examples/test-suite/ruby/add_link_runme.rb | 0 Examples/test-suite/ruby/anonymous_bitfield_runme.rb | 0 Examples/test-suite/ruby/apply_signed_char_runme.rb | 0 Examples/test-suite/ruby/apply_strings_runme.rb | 0 Examples/test-suite/ruby/argout_runme.rb | 0 Examples/test-suite/ruby/arrays_runme.rb | 0 Examples/test-suite/ruby/cast_operator_runme.rb | 0 Examples/test-suite/ruby/casts_runme.rb | 0 Examples/test-suite/ruby/check_missing_tests.rb | 0 Examples/test-suite/ruby/class_ignore_runme.rb | 0 Examples/test-suite/ruby/const_const_runme.rb | 0 Examples/test-suite/ruby/constover_runme.rb | 0 Examples/test-suite/ruby/cpp_namespace_runme.rb | 0 Examples/test-suite/ruby/default_constructor_runme.rb | 0 Examples/test-suite/ruby/dynamic_cast_runme.rb | 0 Examples/test-suite/ruby/enum_thorough_runme.rb | 0 Examples/test-suite/ruby/function_typedef_runme.rb | 0 Examples/test-suite/ruby/imports_runme.rb | 0 Examples/test-suite/ruby/integers_runme.rb | 0 Examples/test-suite/ruby/li_cstring_runme.rb | 0 Examples/test-suite/ruby/li_math_runme.rb | 0 Examples/test-suite/ruby/li_std_functors_runme.rb | 0 Examples/test-suite/ruby/li_std_map_runme.rb | 0 Examples/test-suite/ruby/li_std_multimap_runme.rb | 0 Examples/test-suite/ruby/li_std_pair_runme.rb | 0 Examples/test-suite/ruby/li_std_queue_runme.rb | 0 Examples/test-suite/ruby/li_std_set_runme.rb | 0 Examples/test-suite/ruby/li_std_speed2_runme.rb | 0 Examples/test-suite/ruby/li_std_stack_runme.rb | 0 Examples/test-suite/ruby/li_std_stream_runme.rb | 0 Examples/test-suite/ruby/li_std_vector_enum_runme.rb | 0 Examples/test-suite/ruby/li_std_vector_runme.rb | 0 Examples/test-suite/ruby/namespace_typemap_runme.rb | 0 Examples/test-suite/ruby/overload_bool_runme.rb | 0 Examples/test-suite/ruby/overload_copy_runme.rb | 0 Examples/test-suite/ruby/overload_extend_runme.rb | 0 Examples/test-suite/ruby/overload_extendc_runme.rb | 0 Examples/test-suite/ruby/overload_simple_runme.rb | 0 Examples/test-suite/ruby/overload_template_runme.rb | 0 Examples/test-suite/ruby/primitive_ref_runme.rb | 0 Examples/test-suite/ruby/ruby_li_std_speed_runme.rb | 0 Examples/test-suite/ruby/sneaky1_runme.rb | 0 Examples/test-suite/ruby/std_containers_runme.rb | 0 Examples/test-suite/ruby/stl_new_runme.rb | 0 Examples/test-suite/ruby/swig_assert.rb | 0 Examples/test-suite/ruby/swig_gc.rb | 0 Examples/test-suite/ruby/template_inherit_runme.rb | 0 Examples/test-suite/ruby/template_ns4_runme.rb | 0 Examples/test-suite/ruby/template_ns_runme.rb | 0 Examples/test-suite/ruby/template_rename_runme.rb | 0 Examples/test-suite/ruby/typedef_inherit_runme.rb | 0 Examples/test-suite/ruby/typedef_scope_runme.rb | 0 Examples/test-suite/ruby/typemap_namespace_runme.rb | 0 Examples/test-suite/ruby/typename_runme.rb | 0 Lib/javascript/jsc/std_common.i | 0 Lib/javascript/jsc/std_map.i | 0 Lib/javascript/jsc/std_pair.i | 0 Lib/javascript/jsc/std_string.i | 0 Lib/javascript/jsc/std_vector.i | 0 Lib/javascript/jsc/stl.i | 0 Lib/javascript/v8/std_common.i | 0 Lib/javascript/v8/std_map.i | 0 Lib/javascript/v8/std_pair.i | 0 Lib/javascript/v8/std_string.i | 0 Lib/javascript/v8/std_vector.i | 0 Lib/javascript/v8/stl.i | 0 Tools/javascript/v8_shell.cxx | 0 133 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Examples/guile/matrix/runme.scm mode change 100755 => 100644 Examples/javascript/class/Makefile mode change 100755 => 100644 Examples/javascript/class/example.cxx mode change 100755 => 100644 Examples/javascript/class/example.h mode change 100755 => 100644 Examples/javascript/class/example.i mode change 100755 => 100644 Examples/javascript/class/runme.js mode change 100755 => 100644 Examples/javascript/constant/Makefile mode change 100755 => 100644 Examples/javascript/constant/example.i mode change 100755 => 100644 Examples/javascript/constant/runme.js mode change 100755 => 100644 Examples/javascript/enum/Makefile mode change 100755 => 100644 Examples/javascript/enum/example.cxx mode change 100755 => 100644 Examples/javascript/enum/example.h mode change 100755 => 100644 Examples/javascript/enum/example.i mode change 100755 => 100644 Examples/javascript/enum/runme.js mode change 100755 => 100644 Examples/javascript/exception/Makefile mode change 100755 => 100644 Examples/javascript/functor/Makefile mode change 100755 => 100644 Examples/javascript/nspace/Makefile mode change 100755 => 100644 Examples/javascript/operator/Makefile mode change 100755 => 100644 Examples/javascript/overload/Makefile mode change 100755 => 100644 Examples/javascript/pointer/Makefile mode change 100755 => 100644 Examples/javascript/pointer/example.cxx mode change 100755 => 100644 Examples/javascript/pointer/example.i mode change 100755 => 100644 Examples/javascript/pointer/runme.js mode change 100755 => 100644 Examples/javascript/reference/Makefile mode change 100755 => 100644 Examples/javascript/reference/example.cxx mode change 100755 => 100644 Examples/javascript/reference/example.h mode change 100755 => 100644 Examples/javascript/reference/example.i mode change 100755 => 100644 Examples/javascript/reference/runme.js mode change 100755 => 100644 Examples/javascript/simple/Makefile mode change 100755 => 100644 Examples/javascript/simple/runme.js mode change 100755 => 100644 Examples/javascript/template/Makefile mode change 100755 => 100644 Examples/javascript/variables/Makefile mode change 100755 => 100644 Examples/javascript/variables/example.cxx mode change 100755 => 100644 Examples/javascript/variables/example.h mode change 100755 => 100644 Examples/javascript/variables/example.i mode change 100755 => 100644 Examples/javascript/variables/runme.js mode change 100755 => 100644 Examples/test-suite/javascript/Makefile.in mode change 100755 => 100644 Examples/test-suite/ocaml/makedebugtop mode change 100755 => 100644 Examples/test-suite/octave/iadd_runme.m mode change 100755 => 100644 Examples/test-suite/octave/overload_complicated_runme.m mode change 100755 => 100644 Examples/test-suite/perl5/char_binary_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/class_ignore_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/contract_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/enum_template_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/grouping_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/ignore_parameter_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/inherit_missing_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/li_std_except_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/minherit_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/naturalvar_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/preproc_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/primitive_types_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/reference_global_vars_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/rename_scope_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/return_const_value_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/run-perl-test.pl mode change 100755 => 100644 Examples/test-suite/perl5/sizet_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/sneaky1_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/template_typedef_cplx2_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/typedef_class_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/typename_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/using1_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/using2_runme.pl mode change 100755 => 100644 Examples/test-suite/perl5/wrapmacro_runme.pl mode change 100755 => 100644 Examples/test-suite/ruby/abstract_access_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/access_change_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/add_link_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/anonymous_bitfield_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/apply_signed_char_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/apply_strings_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/argout_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/arrays_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/cast_operator_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/casts_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/check_missing_tests.rb mode change 100755 => 100644 Examples/test-suite/ruby/class_ignore_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/const_const_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/constover_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/cpp_namespace_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/default_constructor_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/dynamic_cast_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/enum_thorough_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/function_typedef_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/imports_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/integers_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_cstring_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_math_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_functors_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_map_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_multimap_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_pair_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_queue_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_set_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_speed2_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_stack_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_stream_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_vector_enum_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/li_std_vector_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/namespace_typemap_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/overload_bool_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/overload_copy_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/overload_extend_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/overload_extendc_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/overload_simple_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/overload_template_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/primitive_ref_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/ruby_li_std_speed_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/sneaky1_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/std_containers_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/stl_new_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/swig_assert.rb mode change 100755 => 100644 Examples/test-suite/ruby/swig_gc.rb mode change 100755 => 100644 Examples/test-suite/ruby/template_inherit_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/template_ns4_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/template_ns_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/template_rename_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/typedef_inherit_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/typedef_scope_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/typemap_namespace_runme.rb mode change 100755 => 100644 Examples/test-suite/ruby/typename_runme.rb mode change 100755 => 100644 Lib/javascript/jsc/std_common.i mode change 100755 => 100644 Lib/javascript/jsc/std_map.i mode change 100755 => 100644 Lib/javascript/jsc/std_pair.i mode change 100755 => 100644 Lib/javascript/jsc/std_string.i mode change 100755 => 100644 Lib/javascript/jsc/std_vector.i mode change 100755 => 100644 Lib/javascript/jsc/stl.i mode change 100755 => 100644 Lib/javascript/v8/std_common.i mode change 100755 => 100644 Lib/javascript/v8/std_map.i mode change 100755 => 100644 Lib/javascript/v8/std_pair.i mode change 100755 => 100644 Lib/javascript/v8/std_string.i mode change 100755 => 100644 Lib/javascript/v8/std_vector.i mode change 100755 => 100644 Lib/javascript/v8/stl.i mode change 100755 => 100644 Tools/javascript/v8_shell.cxx diff --git a/Examples/guile/matrix/runme.scm b/Examples/guile/matrix/runme.scm old mode 100755 new mode 100644 diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/class/example.cxx b/Examples/javascript/class/example.cxx old mode 100755 new mode 100644 diff --git a/Examples/javascript/class/example.h b/Examples/javascript/class/example.h old mode 100755 new mode 100644 diff --git a/Examples/javascript/class/example.i b/Examples/javascript/class/example.i old mode 100755 new mode 100644 diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js old mode 100755 new mode 100644 diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/constant/example.i b/Examples/javascript/constant/example.i old mode 100755 new mode 100644 diff --git a/Examples/javascript/constant/runme.js b/Examples/javascript/constant/runme.js old mode 100755 new mode 100644 diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/enum/example.cxx b/Examples/javascript/enum/example.cxx old mode 100755 new mode 100644 diff --git a/Examples/javascript/enum/example.h b/Examples/javascript/enum/example.h old mode 100755 new mode 100644 diff --git a/Examples/javascript/enum/example.i b/Examples/javascript/enum/example.i old mode 100755 new mode 100644 diff --git a/Examples/javascript/enum/runme.js b/Examples/javascript/enum/runme.js old mode 100755 new mode 100644 diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/nspace/Makefile b/Examples/javascript/nspace/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/pointer/example.cxx b/Examples/javascript/pointer/example.cxx old mode 100755 new mode 100644 diff --git a/Examples/javascript/pointer/example.i b/Examples/javascript/pointer/example.i old mode 100755 new mode 100644 diff --git a/Examples/javascript/pointer/runme.js b/Examples/javascript/pointer/runme.js old mode 100755 new mode 100644 diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/reference/example.cxx b/Examples/javascript/reference/example.cxx old mode 100755 new mode 100644 diff --git a/Examples/javascript/reference/example.h b/Examples/javascript/reference/example.h old mode 100755 new mode 100644 diff --git a/Examples/javascript/reference/example.i b/Examples/javascript/reference/example.i old mode 100755 new mode 100644 diff --git a/Examples/javascript/reference/runme.js b/Examples/javascript/reference/runme.js old mode 100755 new mode 100644 diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/simple/runme.js b/Examples/javascript/simple/runme.js old mode 100755 new mode 100644 diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile old mode 100755 new mode 100644 diff --git a/Examples/javascript/variables/example.cxx b/Examples/javascript/variables/example.cxx old mode 100755 new mode 100644 diff --git a/Examples/javascript/variables/example.h b/Examples/javascript/variables/example.h old mode 100755 new mode 100644 diff --git a/Examples/javascript/variables/example.i b/Examples/javascript/variables/example.i old mode 100755 new mode 100644 diff --git a/Examples/javascript/variables/runme.js b/Examples/javascript/variables/runme.js old mode 100755 new mode 100644 diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ocaml/makedebugtop b/Examples/test-suite/ocaml/makedebugtop old mode 100755 new mode 100644 diff --git a/Examples/test-suite/octave/iadd_runme.m b/Examples/test-suite/octave/iadd_runme.m old mode 100755 new mode 100644 diff --git a/Examples/test-suite/octave/overload_complicated_runme.m b/Examples/test-suite/octave/overload_complicated_runme.m old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/char_binary_runme.pl b/Examples/test-suite/perl5/char_binary_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/class_ignore_runme.pl b/Examples/test-suite/perl5/class_ignore_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/contract_runme.pl b/Examples/test-suite/perl5/contract_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/enum_template_runme.pl b/Examples/test-suite/perl5/enum_template_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/grouping_runme.pl b/Examples/test-suite/perl5/grouping_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/ignore_parameter_runme.pl b/Examples/test-suite/perl5/ignore_parameter_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/inherit_missing_runme.pl b/Examples/test-suite/perl5/inherit_missing_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/li_std_except_runme.pl b/Examples/test-suite/perl5/li_std_except_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/minherit_runme.pl b/Examples/test-suite/perl5/minherit_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/naturalvar_runme.pl b/Examples/test-suite/perl5/naturalvar_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/preproc_runme.pl b/Examples/test-suite/perl5/preproc_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/primitive_types_runme.pl b/Examples/test-suite/perl5/primitive_types_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/reference_global_vars_runme.pl b/Examples/test-suite/perl5/reference_global_vars_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/rename_scope_runme.pl b/Examples/test-suite/perl5/rename_scope_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/return_const_value_runme.pl b/Examples/test-suite/perl5/return_const_value_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/run-perl-test.pl b/Examples/test-suite/perl5/run-perl-test.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/sizet_runme.pl b/Examples/test-suite/perl5/sizet_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/sneaky1_runme.pl b/Examples/test-suite/perl5/sneaky1_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/template_typedef_cplx2_runme.pl b/Examples/test-suite/perl5/template_typedef_cplx2_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/typedef_class_runme.pl b/Examples/test-suite/perl5/typedef_class_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/typename_runme.pl b/Examples/test-suite/perl5/typename_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/using1_runme.pl b/Examples/test-suite/perl5/using1_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/using2_runme.pl b/Examples/test-suite/perl5/using2_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/perl5/wrapmacro_runme.pl b/Examples/test-suite/perl5/wrapmacro_runme.pl old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/abstract_access_runme.rb b/Examples/test-suite/ruby/abstract_access_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/access_change_runme.rb b/Examples/test-suite/ruby/access_change_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/add_link_runme.rb b/Examples/test-suite/ruby/add_link_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/anonymous_bitfield_runme.rb b/Examples/test-suite/ruby/anonymous_bitfield_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/apply_signed_char_runme.rb b/Examples/test-suite/ruby/apply_signed_char_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/apply_strings_runme.rb b/Examples/test-suite/ruby/apply_strings_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/argout_runme.rb b/Examples/test-suite/ruby/argout_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/arrays_runme.rb b/Examples/test-suite/ruby/arrays_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/cast_operator_runme.rb b/Examples/test-suite/ruby/cast_operator_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/casts_runme.rb b/Examples/test-suite/ruby/casts_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/check_missing_tests.rb b/Examples/test-suite/ruby/check_missing_tests.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/class_ignore_runme.rb b/Examples/test-suite/ruby/class_ignore_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/const_const_runme.rb b/Examples/test-suite/ruby/const_const_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/constover_runme.rb b/Examples/test-suite/ruby/constover_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/cpp_namespace_runme.rb b/Examples/test-suite/ruby/cpp_namespace_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/default_constructor_runme.rb b/Examples/test-suite/ruby/default_constructor_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/dynamic_cast_runme.rb b/Examples/test-suite/ruby/dynamic_cast_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/enum_thorough_runme.rb b/Examples/test-suite/ruby/enum_thorough_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/function_typedef_runme.rb b/Examples/test-suite/ruby/function_typedef_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/imports_runme.rb b/Examples/test-suite/ruby/imports_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/integers_runme.rb b/Examples/test-suite/ruby/integers_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_cstring_runme.rb b/Examples/test-suite/ruby/li_cstring_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_math_runme.rb b/Examples/test-suite/ruby/li_math_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_functors_runme.rb b/Examples/test-suite/ruby/li_std_functors_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_map_runme.rb b/Examples/test-suite/ruby/li_std_map_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_multimap_runme.rb b/Examples/test-suite/ruby/li_std_multimap_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_pair_runme.rb b/Examples/test-suite/ruby/li_std_pair_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_queue_runme.rb b/Examples/test-suite/ruby/li_std_queue_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_set_runme.rb b/Examples/test-suite/ruby/li_std_set_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_speed2_runme.rb b/Examples/test-suite/ruby/li_std_speed2_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_stack_runme.rb b/Examples/test-suite/ruby/li_std_stack_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_stream_runme.rb b/Examples/test-suite/ruby/li_std_stream_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_vector_enum_runme.rb b/Examples/test-suite/ruby/li_std_vector_enum_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/li_std_vector_runme.rb b/Examples/test-suite/ruby/li_std_vector_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/namespace_typemap_runme.rb b/Examples/test-suite/ruby/namespace_typemap_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/overload_bool_runme.rb b/Examples/test-suite/ruby/overload_bool_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/overload_copy_runme.rb b/Examples/test-suite/ruby/overload_copy_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/overload_extend_runme.rb b/Examples/test-suite/ruby/overload_extend_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/overload_extendc_runme.rb b/Examples/test-suite/ruby/overload_extendc_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/overload_simple_runme.rb b/Examples/test-suite/ruby/overload_simple_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/overload_template_runme.rb b/Examples/test-suite/ruby/overload_template_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/primitive_ref_runme.rb b/Examples/test-suite/ruby/primitive_ref_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/ruby_li_std_speed_runme.rb b/Examples/test-suite/ruby/ruby_li_std_speed_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/sneaky1_runme.rb b/Examples/test-suite/ruby/sneaky1_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/std_containers_runme.rb b/Examples/test-suite/ruby/std_containers_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/stl_new_runme.rb b/Examples/test-suite/ruby/stl_new_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/swig_assert.rb b/Examples/test-suite/ruby/swig_assert.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/swig_gc.rb b/Examples/test-suite/ruby/swig_gc.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/template_inherit_runme.rb b/Examples/test-suite/ruby/template_inherit_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/template_ns4_runme.rb b/Examples/test-suite/ruby/template_ns4_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/template_ns_runme.rb b/Examples/test-suite/ruby/template_ns_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/template_rename_runme.rb b/Examples/test-suite/ruby/template_rename_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/typedef_inherit_runme.rb b/Examples/test-suite/ruby/typedef_inherit_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/typedef_scope_runme.rb b/Examples/test-suite/ruby/typedef_scope_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/typemap_namespace_runme.rb b/Examples/test-suite/ruby/typemap_namespace_runme.rb old mode 100755 new mode 100644 diff --git a/Examples/test-suite/ruby/typename_runme.rb b/Examples/test-suite/ruby/typename_runme.rb old mode 100755 new mode 100644 diff --git a/Lib/javascript/jsc/std_common.i b/Lib/javascript/jsc/std_common.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/jsc/std_map.i b/Lib/javascript/jsc/std_map.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/jsc/std_pair.i b/Lib/javascript/jsc/std_pair.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/jsc/std_string.i b/Lib/javascript/jsc/std_string.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/jsc/std_vector.i b/Lib/javascript/jsc/std_vector.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/jsc/stl.i b/Lib/javascript/jsc/stl.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/v8/std_common.i b/Lib/javascript/v8/std_common.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/v8/std_map.i b/Lib/javascript/v8/std_map.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/v8/std_pair.i b/Lib/javascript/v8/std_pair.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/v8/std_string.i b/Lib/javascript/v8/std_string.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/v8/std_vector.i b/Lib/javascript/v8/std_vector.i old mode 100755 new mode 100644 diff --git a/Lib/javascript/v8/stl.i b/Lib/javascript/v8/stl.i old mode 100755 new mode 100644 diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx old mode 100755 new mode 100644 From d5b765d3888d82d8b6a420b80047278c81c4ef95 Mon Sep 17 00:00:00 2001 From: Karl Wette Date: Fri, 2 May 2014 16:16:11 +0200 Subject: [PATCH 348/352] Whitespace cleanup of all Makefiles* - some of the %.clean rules in the test-suite Makefiles were using a single tab as an empty rule, dangerous! I've replaced these with the safer '@exit 0'. --- CCache/Makefile.in | 4 +-- Doc/Manual/Makefile | 1 - Examples/Makefile.in | 6 ++--- Examples/test-suite/allegrocl/Makefile.in | 9 +++---- Examples/test-suite/cffi/Makefile.in | 9 +++---- Examples/test-suite/chicken/Makefile.in | 10 +++---- Examples/test-suite/clisp/Makefile.in | 9 +++---- Examples/test-suite/csharp/Makefile.in | 4 +-- Examples/test-suite/errors/Makefile.in | 7 +++-- Examples/test-suite/go/Makefile.in | 4 +-- Examples/test-suite/guile/Makefile.in | 10 +++---- Examples/test-suite/java/Makefile.in | 4 +-- Examples/test-suite/lua/Makefile.in | 10 +++---- Examples/test-suite/mzscheme/Makefile.in | 6 ++--- Examples/test-suite/ocaml/Makefile.in | 4 +-- Examples/test-suite/octave/Makefile.in | 20 +++++++------- Examples/test-suite/perl5/Makefile.in | 4 +-- Examples/test-suite/php/Makefile.in | 4 +-- Examples/test-suite/pike/Makefile.in | 5 ++-- Examples/test-suite/python/Makefile.in | 23 ++++++++-------- Examples/test-suite/r/Makefile.in | 12 ++++----- Examples/test-suite/ruby/Makefile.in | 6 ++--- Examples/test-suite/tcl/Makefile.in | 8 +++--- Examples/test-suite/uffi/Makefile.in | 9 +++---- Lib/guile/Makefile | 1 - Lib/mzscheme/Makefile | 1 - Lib/perl5/Makefile.in | 32 +++++++++-------------- Lib/perl5/Makefile.pl | 4 +-- Lib/python/Makefile.in | 32 ++++++++++------------- Lib/ruby/Makefile.swig | 2 +- Lib/tcl/Makefile.in | 32 ++++++++++------------- Makefile.in | 8 +++--- Source/Makefile.am | 5 ++-- 33 files changed, 138 insertions(+), 167 deletions(-) diff --git a/CCache/Makefile.in b/CCache/Makefile.in index d8f9042fe..abe78c277 100644 --- a/CCache/Makefile.in +++ b/CCache/Makefile.in @@ -69,9 +69,9 @@ distclean: clean maintainer-clean: distclean /bin/rm -f $(PACKAGE_NAME).1 web/ccache-man.html - + # FIXME: To fix this, test.sh needs to be able to take ccache from the # installed prefix, not from the source dir. -installcheck: +installcheck: @echo "WARNING! This is not really \"installcheck\" yet." $(MAKE) check diff --git a/Doc/Manual/Makefile b/Doc/Manual/Makefile index 42149ba3a..5112afa33 100644 --- a/Doc/Manual/Makefile +++ b/Doc/Manual/Makefile @@ -75,4 +75,3 @@ linkchecker: @echo Note linkchecker versions prior to 6.1 do not work properly wrt anchors @echo ----------------------------------------------------------------------- linkchecker --config=./linkchecker.config index.html - diff --git a/Examples/Makefile.in b/Examples/Makefile.in index 01febf575..326f678c7 100644 --- a/Examples/Makefile.in +++ b/Examples/Makefile.in @@ -88,7 +88,7 @@ endif ################################################################## CPP_DLLIBS = #-L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ - -L/usr/local/lib -lg++ -lstdc++ -lgcc + -L/usr/local/lib -lg++ -lstdc++ -lgcc # Solaris workshop 5.0 # CPP_DLLIBS = -L/opt/SUNWspro/lib -lCrun @@ -1621,7 +1621,7 @@ R_SCRIPT=$(RUNME).R r: $(SRCS) $(SWIG) -r $(SWIGOPT) $(INTERFACEPATH) ifneq ($(SRCS),) - $(CC) -g -c $(CFLAGS) $(R_CFLAGS) $(SRCS) $(INCLUDES) + $(CC) -g -c $(CFLAGS) $(R_CFLAGS) $(SRCS) $(INCLUDES) endif +( PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(ISRCS) $(OBJS) > /dev/null ) @@ -1632,7 +1632,7 @@ endif r_cpp: $(CXXSRCS) $(SWIG) -c++ -r $(SWIGOPT) -o $(RCXXSRCS) $(INTERFACEPATH) ifneq ($(CXXSRCS),) - $(CXX) -g -c $(CXXFLAGS) $(R_CFLAGS) $(CXXSRCS) $(INCLUDES) + $(CXX) -g -c $(CXXFLAGS) $(R_CFLAGS) $(CXXSRCS) $(INCLUDES) endif +( PKG_CPPFLAGS="$(INCLUDES)" $(COMPILETOOL) $(R) CMD SHLIB -o $(LIBPREFIX)$(TARGET)$(SO) $(RCXXSRCS) $(OBJS) > /dev/null ) diff --git a/Examples/test-suite/allegrocl/Makefile.in b/Examples/test-suite/allegrocl/Makefile.in index 5f75bfc08..697c15a45 100644 --- a/Examples/test-suite/allegrocl/Makefile.in +++ b/Examples/test-suite/allegrocl/Makefile.in @@ -12,7 +12,7 @@ top_builddir = @top_builddir@ # these cpp tests generate warnings/errors when compiling # the wrapper .cxx file. -CPP_TEST_BROKEN_CXX = +CPP_TEST_BROKEN_CXX = # the error is wrap:action code generated by swig. \ # error: can't convert [std::string] 'b' to 'bool' \ # might just need a bool overload op for std::string. \ @@ -71,7 +71,7 @@ CPP_TEST_CASES_ACL_UNSUPPORTED = \ extern_throws \ throw_exception \ using_pointers \ - + C_TEST_CASES_ACL_BROKEN = \ # 'cdate.i' module support \ li_cdata \ @@ -96,7 +96,7 @@ include $(srcdir)/../common.mk # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -106,7 +106,7 @@ include $(srcdir)/../common.mk +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -123,4 +123,3 @@ run_testcase = \ clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile allegrocl_clean - diff --git a/Examples/test-suite/cffi/Makefile.in b/Examples/test-suite/cffi/Makefile.in index aa8b40aec..473d395fd 100644 --- a/Examples/test-suite/cffi/Makefile.in +++ b/Examples/test-suite/cffi/Makefile.in @@ -14,13 +14,13 @@ include $(srcdir)/../common.mk # Overridden variables here # no C++ tests for now CPP_TEST_CASES = -#C_TEST_CASES += +#C_TEST_CASES += # Custom tests - tests with additional commandline options # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -30,7 +30,7 @@ CPP_TEST_CASES = +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -44,8 +44,7 @@ run_testcase = \ # Clean: (does nothing, we dont generate extra cffi code) %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile cffi_clean - diff --git a/Examples/test-suite/chicken/Makefile.in b/Examples/test-suite/chicken/Makefile.in index 3c2f3de54..4ee8cb0fa 100644 --- a/Examples/test-suite/chicken/Makefile.in +++ b/Examples/test-suite/chicken/Makefile.in @@ -3,7 +3,7 @@ ####################################################################### LANGUAGE = chicken -VARIANT = +VARIANT = SCRIPTSUFFIX = _runme.ss PROXYSUFFIX = _runme_proxy.ss srcdir = @srcdir@ @@ -17,7 +17,7 @@ SO = @SO@ # Skip the STD cases for now, except for li_std_string.i SKIP_CPP_STD_CASES = Yes -CPP_TEST_CASES += li_std_string +CPP_TEST_CASES += li_std_string EXTRA_TEST_CASES += chicken_ext_test.externaltest @@ -39,7 +39,7 @@ SWIGOPT += -nounit %.multiproxy: SCRIPTSUFFIX = $(PROXYSUFFIX) # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -55,7 +55,7 @@ SWIGOPT += -nounit $(MAKE) $*.cproxy; \ fi -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -92,7 +92,7 @@ run_testcase = \ # Clean %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile chicken_clean diff --git a/Examples/test-suite/clisp/Makefile.in b/Examples/test-suite/clisp/Makefile.in index 24655a60f..1fe3c23ac 100644 --- a/Examples/test-suite/clisp/Makefile.in +++ b/Examples/test-suite/clisp/Makefile.in @@ -14,13 +14,13 @@ include $(srcdir)/../common.mk # Overridden variables here # no C++ tests for now CPP_TEST_CASES = -#C_TEST_CASES += +#C_TEST_CASES += # Custom tests - tests with additional commandline options # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -30,7 +30,7 @@ CPP_TEST_CASES = +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -44,8 +44,7 @@ run_testcase = \ # Clean: (does nothing, we dont generate extra clisp code) %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile clisp_clean - diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in index 993699bc8..e54edcc35 100644 --- a/Examples/test-suite/csharp/Makefile.in +++ b/Examples/test-suite/csharp/Makefile.in @@ -40,7 +40,7 @@ csharp_lib_arrays.cpptest: CSHARPFLAGSSPECIAL = -unsafe csharp_swig2_compatibility.cpptest: SWIGOPT += -DSWIG2_CSHARP # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +(cd $* && $(swig_and_compile_cpp)) +$(run_testcase) @@ -50,7 +50,7 @@ csharp_swig2_compatibility.cpptest: SWIGOPT += -DSWIG2_CSHARP +(cd $* && $(swig_and_compile_c)) +$(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +(cd $* && $(swig_and_compile_multi_cpp)) +$(run_testcase) diff --git a/Examples/test-suite/errors/Makefile.in b/Examples/test-suite/errors/Makefile.in index 601dcd303..e4ba7b751 100644 --- a/Examples/test-suite/errors/Makefile.in +++ b/Examples/test-suite/errors/Makefile.in @@ -29,13 +29,13 @@ CPP_ERROR_TEST_CASES := $(filter cpp_%, $(ALL_ERROR_TEST_CASES)) C_ERROR_TEST_CASES := $(filter-out $(CPP_ERROR_TEST_CASES), $(ALL_ERROR_TEST_CASES)) ERROR_TEST_CASES := $(CPP_ERROR_TEST_CASES:=.cpptest) \ - $(C_ERROR_TEST_CASES:=.ctest) + $(C_ERROR_TEST_CASES:=.ctest) include $(srcdir)/../common.mk # Rules for the different types of tests -%.cpptest: +%.cpptest: echo "$(ACTION)ing errors testcase $*" -$(SWIG) -c++ -python -Wall -Fstandard $(SWIGOPT) $*.i 2>&1 | $(TODOS) > $*.$(ERROR_EXT) $(COMPILETOOL) diff -c $*.stderr $*.$(ERROR_EXT) @@ -46,9 +46,8 @@ include $(srcdir)/../common.mk $(COMPILETOOL) diff -c $*.stderr $*.$(ERROR_EXT) %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile $(LANGUAGE)_clean @rm -f *.$(ERROR_EXT) *.py - diff --git a/Examples/test-suite/go/Makefile.in b/Examples/test-suite/go/Makefile.in index 535d05a6e..64a84f820 100644 --- a/Examples/test-suite/go/Makefile.in +++ b/Examples/test-suite/go/Makefile.in @@ -29,7 +29,7 @@ include $(srcdir)/../common.mk .SUFFIXES: .cpptest .ctest .multicpptest # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase_cpp) @@ -39,7 +39,7 @@ include $(srcdir)/../common.mk +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_multi_testcase) diff --git a/Examples/test-suite/guile/Makefile.in b/Examples/test-suite/guile/Makefile.in index 0c7b3137c..493dde4f5 100644 --- a/Examples/test-suite/guile/Makefile.in +++ b/Examples/test-suite/guile/Makefile.in @@ -14,9 +14,9 @@ GUILE = @GUILE@ GUILE_RUNTIME= C_TEST_CASES = long_long \ - list_vector \ - multivalue \ - pointer_in_out + list_vector \ + multivalue \ + pointer_in_out include $(srcdir)/../common.mk @@ -28,7 +28,7 @@ INCLUDES += -I$(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/guile %.multicpptest: SWIGOPT += $(GUILE_RUNTIME) # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -38,7 +38,7 @@ INCLUDES += -I$(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/guile +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in index 059325c13..e4e803d2a 100644 --- a/Examples/test-suite/java/Makefile.in +++ b/Examples/test-suite/java/Makefile.in @@ -55,7 +55,7 @@ director_nspace.%: JAVA_PACKAGE = $*Package director_nspace_director_name_collision.%: JAVA_PACKAGE = $*Package # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +(cd $(JAVA_PACKAGE) && $(swig_and_compile_cpp)) $(run_testcase) @@ -65,7 +65,7 @@ director_nspace_director_name_collision.%: JAVA_PACKAGE = $*Package +(cd $(JAVA_PACKAGE) && $(swig_and_compile_c)) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +(cd $(JAVA_PACKAGE) && $(swig_and_compile_multi_cpp)) $(run_testcase) diff --git a/Examples/test-suite/lua/Makefile.in b/Examples/test-suite/lua/Makefile.in index 66a0d2da9..0950c9d91 100644 --- a/Examples/test-suite/lua/Makefile.in +++ b/Examples/test-suite/lua/Makefile.in @@ -28,7 +28,7 @@ LIBS = -L. lua_no_module_global.%: SWIGOPT += -nomoduleglobal # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -38,7 +38,7 @@ lua_no_module_global.%: SWIGOPT += -nomoduleglobal +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -52,7 +52,7 @@ run_testcase = \ # Clean: (does nothing, we dont generate extra lua code) %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile lua_clean @@ -60,5 +60,5 @@ clean: cvsignore: @echo '*wrap* *.so *.dll *.exp *.lib' @echo Makefile - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.lua; done - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.lua CVS/Entries ; then echo $${i}_runme.lua; fi; done + @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.lua; done + @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.lua CVS/Entries ; then echo $${i}_runme.lua; fi; done diff --git a/Examples/test-suite/mzscheme/Makefile.in b/Examples/test-suite/mzscheme/Makefile.in index fcaf33a48..67b8bddf2 100644 --- a/Examples/test-suite/mzscheme/Makefile.in +++ b/Examples/test-suite/mzscheme/Makefile.in @@ -18,7 +18,7 @@ include $(srcdir)/../common.mk # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -28,7 +28,7 @@ include $(srcdir)/../common.mk +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -42,7 +42,7 @@ run_testcase = \ # Clean %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile mzscheme_clean diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in index f16c3da95..63edec26a 100644 --- a/Examples/test-suite/ocaml/Makefile.in +++ b/Examples/test-suite/ocaml/Makefile.in @@ -10,7 +10,7 @@ srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ -C_TEST_CASES = +C_TEST_CASES = run_testcase = \ if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) -a \ @@ -21,7 +21,7 @@ run_testcase = \ $(COMPILETOOL) $(OCAMLC) -c $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \ $(COMPILETOOL) $(OCAMLC) swig.cmo -custom -g -cc '$(CXX)' -o runme $(srcdir)/$(*).cmo $(srcdir)/$(*)_runme.cmo $(srcdir)/$(*)_wrap.o && \ $(RUNTOOL) ./runme; \ - fi ; + fi ; check_quant: cat /dev/null > testing diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in index dc309e8c6..e48d36a64 100644 --- a/Examples/test-suite/octave/Makefile.in +++ b/Examples/test-suite/octave/Makefile.in @@ -21,7 +21,7 @@ CPP_TEST_BROKEN += \ li_std_set \ li_std_stream -#C_TEST_CASES += +#C_TEST_CASES += # # This test only works with modern C compilers @@ -39,7 +39,7 @@ CSRCS = $(srcdir)/octave_empty.c # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -49,7 +49,7 @@ CSRCS = $(srcdir)/octave_empty.c +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -72,13 +72,13 @@ clean: cvsignore: @echo '*wrap* *.mc *.so *.dll *.exp *.lib' @echo Makefile - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.m; done - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.m CVS/Entries ; then echo $${i}_runme.m; fi; done - @echo clientdata_prop_a.m - @echo clientdata_prop_b.m - @echo imports_a.m - @echo imports_b.m - @echo mod_a.m mod_b.m + @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.m; done + @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.m CVS/Entries ; then echo $${i}_runme.m; fi; done + @echo clientdata_prop_a.m + @echo clientdata_prop_b.m + @echo imports_a.m + @echo imports_b.m + @echo mod_a.m mod_b.m @echo hugemod.h hugemod_a.i hugemod_b.i hugemod_a.m hugemod_b.m hugemod_runme.m @echo template_typedef_import.m diff --git a/Examples/test-suite/perl5/Makefile.in b/Examples/test-suite/perl5/Makefile.in index 67eaf5c9a..68f32a54a 100644 --- a/Examples/test-suite/perl5/Makefile.in +++ b/Examples/test-suite/perl5/Makefile.in @@ -31,7 +31,7 @@ include $(srcdir)/../common.mk # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -41,7 +41,7 @@ include $(srcdir)/../common.mk +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) diff --git a/Examples/test-suite/php/Makefile.in b/Examples/test-suite/php/Makefile.in index fcdcac2b9..735a3137e 100644 --- a/Examples/test-suite/php/Makefile.in +++ b/Examples/test-suite/php/Makefile.in @@ -29,7 +29,7 @@ missingctests: missingtests: missingcpptests missingctests # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) +$(run_testcase) @@ -39,7 +39,7 @@ missingtests: missingcpptests missingctests +$(swig_and_compile_c) +$(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) +$(run_testcase) diff --git a/Examples/test-suite/pike/Makefile.in b/Examples/test-suite/pike/Makefile.in index 389dc74f8..c1ebb747b 100644 --- a/Examples/test-suite/pike/Makefile.in +++ b/Examples/test-suite/pike/Makefile.in @@ -18,7 +18,7 @@ include $(srcdir)/../common.mk # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -28,7 +28,7 @@ include $(srcdir)/../common.mk +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -46,4 +46,3 @@ run_testcase = \ clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile pike_clean - diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in index e7db32fb7..389aed9ea 100644 --- a/Examples/test-suite/python/Makefile.in +++ b/Examples/test-suite/python/Makefile.in @@ -26,7 +26,7 @@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ -PY2TO3 = 2to3 -x import +PY2TO3 = 2to3 -x import CPP_TEST_CASES += \ @@ -109,7 +109,7 @@ VALGRIND_OPT += --suppressions=pythonswig.supp # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: +$(convert_testcase) $(setup) +$(swig_and_compile_cpp) @@ -121,7 +121,7 @@ VALGRIND_OPT += --suppressions=pythonswig.supp +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: +$(convert_testcase) $(setup) +$(swig_and_compile_multi_cpp) @@ -131,7 +131,7 @@ VALGRIND_OPT += --suppressions=pythonswig.supp # Call 2to3 to generate Python 3.x test from the Python 2.x's *_runme.py file %$(PY3SCRIPTSUFFIX): %$(PY2SCRIPTSUFFIX) cp $< $@ - $(PY2TO3) -w $@ >/dev/null 2>&1 + $(PY2TO3) -w $@ >/dev/null 2>&1 # Runs the testcase. A testcase is only run if @@ -172,12 +172,12 @@ clean: cvsignore: @echo '*wrap* *.pyc *.so *.dll *.exp *.lib' @echo Makefile - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.py; done - @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.py CVS/Entries ; then echo $${i}_runme.py; fi; done - @echo clientdata_prop_a.py - @echo clientdata_prop_b.py - @echo imports_a.py - @echo imports_b.py + @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.py; done + @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do if grep -q $${i}_runme.py CVS/Entries ; then echo $${i}_runme.py; fi; done + @echo clientdata_prop_a.py + @echo clientdata_prop_b.py + @echo imports_a.py + @echo imports_b.py @echo mod_a.py mod_b.py @echo hugemod.h hugemod_a.i hugemod_b.i hugemod_a.py hugemod_b.py hugemod_runme.py @echo template_typedef_import.py @@ -185,9 +185,8 @@ cvsignore: hugemod_runme = hugemod$(SCRIPTPREFIX) hugemod: - perl hugemod.pl $(hugemod_runme) + perl hugemod.pl $(hugemod_runme) $(MAKE) hugemod_a.cpptest $(MAKE) hugemod_b.cpptest sh -c "time $(PYTHON) $(hugemod_runme)" sh -c "time $(PYTHON) $(hugemod_runme)" - diff --git a/Examples/test-suite/r/Makefile.in b/Examples/test-suite/r/Makefile.in index 18e2d4b25..32d9b85da 100644 --- a/Examples/test-suite/r/Makefile.in +++ b/Examples/test-suite/r/Makefile.in @@ -28,7 +28,7 @@ include $(srcdir)/../common.mk # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -38,14 +38,14 @@ include $(srcdir)/../common.mk +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_multitestcase) # Runs the testcase. -# -# Run the runme if it exists. If not just load the R wrapper to +# +# Run the runme if it exists. If not just load the R wrapper to # check for syntactic correctness run_testcase = \ if [ -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \ @@ -58,7 +58,7 @@ run_multitestcase = \ for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \ if [ -f $(srcdir)/$(SCRIPTPREFIX)$${f}$(SCRIPTSUFFIX) ]; then \ env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH PATH=.:"$$PATH" \ - $(RUNTOOL) $(RUNR) $(srcdir)/$(SCRIPTPREFIX)$${f}$(SCRIPTSUFFIX); \ + $(RUNTOOL) $(RUNR) $(srcdir)/$(SCRIPTPREFIX)$${f}$(SCRIPTSUFFIX); \ else \ $(RUNTOOL) $(RUNR) $(srcdir)/$(SCRIPTPREFIX)$${f}$(WRAPSUFFIX); \ fi; \ @@ -74,5 +74,3 @@ clean: rm -f $${f}.R $${f}.Rout ; \ done \ fi - - diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in index ab366ccd4..40985e532 100644 --- a/Examples/test-suite/ruby/Makefile.in +++ b/Examples/test-suite/ruby/Makefile.in @@ -42,7 +42,7 @@ SWIGOPT += -w801 -noautorename -features autodoc=4 ruby_naming.cpptest: SWIGOPT += -autorename # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -52,7 +52,7 @@ ruby_naming.cpptest: SWIGOPT += -autorename +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -66,7 +66,7 @@ run_testcase = \ # Clean %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile ruby_clean diff --git a/Examples/test-suite/tcl/Makefile.in b/Examples/test-suite/tcl/Makefile.in index 49d2a7826..6ab293fb9 100644 --- a/Examples/test-suite/tcl/Makefile.in +++ b/Examples/test-suite/tcl/Makefile.in @@ -4,7 +4,7 @@ LANGUAGE = tcl TCLSH = tclsh -SCRIPTSUFFIX = _runme.tcl +SCRIPTSUFFIX = _runme.tcl srcdir = @srcdir@ top_srcdir = @top_srcdir@ top_builddir = @top_builddir@ @@ -27,7 +27,7 @@ include $(srcdir)/../common.mk # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -37,7 +37,7 @@ include $(srcdir)/../common.mk +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -51,7 +51,7 @@ run_testcase = \ # Clean %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile tcl_clean diff --git a/Examples/test-suite/uffi/Makefile.in b/Examples/test-suite/uffi/Makefile.in index 8ad153961..5fd000a96 100644 --- a/Examples/test-suite/uffi/Makefile.in +++ b/Examples/test-suite/uffi/Makefile.in @@ -14,13 +14,13 @@ include $(srcdir)/../common.mk # Overridden variables here # no C++ tests for now CPP_TEST_CASES = -#C_TEST_CASES += +#C_TEST_CASES += # Custom tests - tests with additional commandline options # none! # Rules for the different types of tests -%.cpptest: +%.cpptest: $(setup) +$(swig_and_compile_cpp) $(run_testcase) @@ -30,7 +30,7 @@ CPP_TEST_CASES = +$(swig_and_compile_c) $(run_testcase) -%.multicpptest: +%.multicpptest: $(setup) +$(swig_and_compile_multi_cpp) $(run_testcase) @@ -44,8 +44,7 @@ run_testcase = \ # Clean: (does nothing, we dont generate extra uffi code) %.clean: - + @exit 0 clean: $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile uffi_clean - diff --git a/Lib/guile/Makefile b/Lib/guile/Makefile index 17f5feced..fba7fd5d3 100644 --- a/Lib/guile/Makefile +++ b/Lib/guile/Makefile @@ -1,4 +1,3 @@ co: co RCS/*.i* RCS/*.swg* - diff --git a/Lib/mzscheme/Makefile b/Lib/mzscheme/Makefile index 17f5feced..fba7fd5d3 100644 --- a/Lib/mzscheme/Makefile +++ b/Lib/mzscheme/Makefile @@ -1,4 +1,3 @@ co: co RCS/*.i* RCS/*.swg* - diff --git a/Lib/perl5/Makefile.in b/Lib/perl5/Makefile.in index 1fee86ccc..e0b3b74b8 100644 --- a/Lib/perl5/Makefile.in +++ b/Lib/perl5/Makefile.in @@ -1,6 +1,6 @@ # --------------------------------------------------------------- # SWIG Perl5 Makefile -# +# # This file can be used to build various Perl5 extensions with SWIG. # By default this file is set up for dynamic loading, but it can # be easily customized for static extensions by modifying various @@ -17,11 +17,11 @@ # script and should already reflect your machine. #---------------------------------------------------------------- -SRCS = -CXXSRCS = -OBJCSRCS = -OBJS = -INTERFACE = +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = WRAPFILE = $(INTERFACE:.i=_wrap.c) WRAPOBJ = $(INTERFACE:.i=_wrap.o) TARGET = module@SO@ # Use this kind of target for dynamic loading @@ -32,8 +32,8 @@ exec_prefix = @exec_prefix@ CC = @CC@ CXX = @CXX@ -OBJC = @CC@ -Wno-import # -Wno-import needed for gcc -CFLAGS = +OBJC = @CC@ -Wno-import # -Wno-import needed for gcc +CFLAGS = INCLUDES = LIBS = @@ -42,9 +42,9 @@ LIBS = # SWIGOPT = SWIG compiler options # SWIGCC = Compiler used to compile the wrapper file -SWIG = $(exec_prefix)/bin/swig -SWIGOPT = -perl5 -SWIGCC = $(CC) +SWIG = $(exec_prefix)/bin/swig +SWIGOPT = -perl5 +SWIGCC = $(CC) # SWIG Library files. Uncomment this to statically rebuild Perl #SWIGLIBS = -static -lperlmain.i @@ -67,12 +67,12 @@ BUILD = @LDSHARED@ # need to provide additional link libraries (this is not always required). #DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ - -L/usr/local/lib -lg++ -lstdc++ -lgcc + -L/usr/local/lib -lg++ -lstdc++ -lgcc # Perl installation PERL_INCLUDE = -I@PERL5EXT@ -PERL_LIB = -L@PERL5EXT@ -lperl +PERL_LIB = -L@PERL5EXT@ -lperl PERL_FLAGS = -Dbool=char -Dexplicit= # Build libraries (needed for static builds) @@ -118,9 +118,3 @@ $(TARGET): $(WRAPOBJ) $(ALLOBJS) clean: rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) - - - - - - diff --git a/Lib/perl5/Makefile.pl b/Lib/perl5/Makefile.pl index 05240f1e9..cffdc8e79 100644 --- a/Lib/perl5/Makefile.pl +++ b/Lib/perl5/Makefile.pl @@ -7,7 +7,7 @@ # 2. Run perl as 'perl Makefile.pl' # 3. Type 'make' to build your module # 4. Type 'make install' to install your module. -# +# # See "Programming Perl", 2nd. Ed, for more gory details than # you ever wanted to know. @@ -17,5 +17,3 @@ WriteMakefile( 'LIBS' => [''], # Custom libraries (if any) 'OBJECT' => '$module_wrap.o' # Object files ); - - diff --git a/Lib/python/Makefile.in b/Lib/python/Makefile.in index 71effea70..27c384449 100644 --- a/Lib/python/Makefile.in +++ b/Lib/python/Makefile.in @@ -1,6 +1,6 @@ # --------------------------------------------------------------- # SWIG Python Makefile -# +# # This file can be used to build various Python extensions with SWIG. # By default this file is set up for dynamic loading, but it can # be easily customized for static extensions by modifying various @@ -17,11 +17,11 @@ # script and should already reflect your machine. #---------------------------------------------------------------- -SRCS = -CXXSRCS = -OBJCSRCS = -OBJS = -INTERFACE = +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = WRAPFILE = $(INTERFACE:.i=_wrap.c) WRAPOBJ = $(INTERFACE:.i=_wrap.o) TARGET = module@SO@ # Use this kind of target for dynamic loading @@ -32,8 +32,8 @@ exec_prefix = @exec_prefix@ CC = @CC@ CXX = @CXX@ -OBJC = @CC@ -Wno-import # -Wno-import needed for gcc -CFLAGS = +OBJC = @CC@ -Wno-import # -Wno-import needed for gcc +CFLAGS = INCLUDES = LIBS = @@ -42,9 +42,9 @@ LIBS = # SWIGOPT = SWIG compiler options # SWIGCC = Compiler used to compile the wrapper file -SWIG = $(exec_prefix)/bin/swig -SWIGOPT = -python -SWIGCC = $(CC) +SWIG = $(exec_prefix)/bin/swig +SWIGOPT = -python +SWIGCC = $(CC) # SWIG Library files. Uncomment if rebuilding the Python interpreter #SWIGLIBS = -lembed.i @@ -67,11 +67,11 @@ BUILD = @LDSHARED@ # need to provide additional link libraries (this is not always required). #DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ - -L/usr/local/lib -lg++ -lstdc++ -lgcc + -L/usr/local/lib -lg++ -lstdc++ -lgcc # Python installation -PY_INCLUDE = -DHAVE_CONFIG_H @PYINCLUDE@ +PY_INCLUDE = -DHAVE_CONFIG_H @PYINCLUDE@ PY_LIB = @PYLIB@ # Build libraries (needed for static builds) @@ -107,7 +107,7 @@ all: $(TARGET) # Convert the wrapper file into an object file $(WRAPOBJ) : $(WRAPFILE) - $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDES) $(PY_INCLUDE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDES) $(PY_INCLUDE) $(WRAPFILE) : $(INTERFACE) $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIBS) $(INTERFACE) @@ -117,7 +117,3 @@ $(TARGET): $(WRAPOBJ) $(ALLOBJS) clean: rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) - - - - diff --git a/Lib/ruby/Makefile.swig b/Lib/ruby/Makefile.swig index a7f3ae3d2..648b32134 100644 --- a/Lib/ruby/Makefile.swig +++ b/Lib/ruby/Makefile.swig @@ -7,7 +7,7 @@ # 3. Type 'make -f Makefile.swig' to generate wrapper code and Makefile. # 4. Type 'make' to build your extension. # 5. Type 'make install' to install your extension. -# +# MODULE = yourmodule FEATURE = $(MODULE) diff --git a/Lib/tcl/Makefile.in b/Lib/tcl/Makefile.in index 2ab0f7b01..13d7d4653 100644 --- a/Lib/tcl/Makefile.in +++ b/Lib/tcl/Makefile.in @@ -1,10 +1,10 @@ # --------------------------------------------------------------- # SWIG Tcl Makefile -# +# # This file can be used to build various Tcl extensions with SWIG. # By default this file is set up for dynamic loading, but it can # be easily customized for static extensions by modifying various -# portions of the file. +# portions of the file. # # SRCS = C source files # CXXSRCS = C++ source files @@ -19,11 +19,11 @@ # application. #---------------------------------------------------------------- -SRCS = -CXXSRCS = -OBJCSRCS = -OBJS = -INTERFACE = +SRCS = +CXXSRCS = +OBJCSRCS = +OBJS = +INTERFACE = WRAPFILE = $(INTERFACE:.i=_wrap.c) WRAPOBJ = $(INTERFACE:.i=_wrap.o) TARGET = module@SO@ # Use this kind of target for dynamic loading @@ -34,8 +34,8 @@ exec_prefix = @exec_prefix@ CC = @CC@ CXX = @CXX@ -OBJC = @CC@ -Wno-import # -Wno-import needed for gcc -CFLAGS = +OBJC = @CC@ -Wno-import # -Wno-import needed for gcc +CFLAGS = INCLUDES = LIBS = @@ -44,9 +44,9 @@ LIBS = # SWIGOPT = SWIG compiler options # SWIGCC = Compiler used to compile the wrapper file -SWIG = $(exec_prefix)/bin/swig +SWIG = $(exec_prefix)/bin/swig SWIGOPT = -tcl # use -tcl8 for Tcl 8.0 -SWIGCC = $(CC) +SWIGCC = $(CC) # SWIG Library files. Uncomment if rebuilding tclsh #SWIGLIBS = -ltclsh.i @@ -69,7 +69,7 @@ BUILD = @LDSHARED@ # need to provide additional link libraries (this is not always required). #DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ - -L/usr/local/lib -lg++ -lstdc++ -lgcc + -L/usr/local/lib -lg++ -lstdc++ -lgcc # Tcl installation (where is Tcl located) @@ -85,7 +85,7 @@ SYSLIBS = $(LIBM) $(LIBC) @LIBS@ # Build options (uncomment only one of these) BUILD_LIBS = $(LIBS) # Dynamic loading -#BUILD_LIBS = $(TCL_LIB) -ltcl $(LIBS) $(SYSLIBS) # tclsh +#BUILD_LIBS = $(TCL_LIB) -ltcl $(LIBS) $(SYSLIBS) # tclsh # Compilation rules for non-SWIG components @@ -110,7 +110,7 @@ all: $(TARGET) # Convert the wrapper file into an object file $(WRAPOBJ) : $(WRAPFILE) - $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDES) $(TCL_INCLUDE) + $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDES) $(TCL_INCLUDE) $(WRAPFILE) : $(INTERFACE) $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIBS) $(INTERFACE) @@ -120,7 +120,3 @@ $(TARGET): $(WRAPOBJ) $(ALLOBJS) clean: rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) - - - - diff --git a/Makefile.in b/Makefile.in index f4d0be077..2eb1326ea 100644 --- a/Makefile.in +++ b/Makefile.in @@ -249,8 +249,8 @@ check-%-examples : # gcj individual example java.actionexample: @if $(skip-gcj); then \ - echo "skipping Examples/$(LANGUAGE)/java $(ACTION) (gcj test)"; \ - else \ + echo "skipping Examples/$(LANGUAGE)/java $(ACTION) (gcj test)"; \ + else \ echo $(ACTION)ing Examples/$(LANGUAGE)/java; \ (cd Examples/$(LANGUAGE)/java && $(MAKE) $(FLAGS) $(chk-set-env) $(ACTION)) \ fi @@ -481,13 +481,13 @@ lib-languages = gcj typemaps tcl perl5 python guile java mzscheme ruby php ocaml lib-modules = std -install-lib: +install-lib: @echo "Installing the SWIG library" @$(MKINSTDIRS) $(DESTDIR)$(SWIG_LIB) @for file in $(srcdir)/Lib/*.i $(srcdir)/Lib/*.swg ; do \ i=`basename $$file` ; \ echo "Installing $(DESTDIR)$(SWIG_LIB)/$$i"; \ - $(INSTALL_DATA) $$file $(DESTDIR)$(SWIG_LIB)/$$i; \ + $(INSTALL_DATA) $$file $(DESTDIR)$(SWIG_LIB)/$$i; \ done; @for lang in $(lib-languages) $(lib-modules); \ do \ diff --git a/Source/Makefile.am b/Source/Makefile.am index 9e02e37f0..d5331cba1 100644 --- a/Source/Makefile.am +++ b/Source/Makefile.am @@ -90,7 +90,7 @@ eswig_SOURCES = CParse/cscanner.c \ Swig/typeobj.c \ Swig/typemap.c \ Swig/typesys.c \ - Swig/wrapfunc.c + Swig/wrapfunc.c bin_PROGRAMS = eswig eswig_LDADD = @SWIGLIBS@ @@ -99,7 +99,7 @@ eswig_LDADD = @SWIGLIBS@ CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ # The executable is copied to the root directory for installation and running the test-suite. -# This occurs on each invocation of make and is a step towards providing support for multiple +# This occurs on each invocation of make and is a step towards providing support for multiple # build directories. all-local: eswig@EXEEXT@ cp -f $(top_builddir)/Source/eswig@EXEEXT@ $(top_builddir)/swig@EXEEXT@ @@ -145,4 +145,3 @@ beautify-file: indent -kr --honour-newlines --line-length160 --indent-level2 --braces-on-func-def-line --leave-optional-blank-lines $(SWIGTYPEDEFS) $(INDENTFILE) -o $(INDENTFILE).tmp; cat $(INDENTFILE).tmp | sed -e 's/const const /const /' > $(INDENTFILE); rm $(INDENTFILE).tmp; - From b6c1889c0891bebcbfd0256d445792a85de8cc91 Mon Sep 17 00:00:00 2001 From: Karl Wette Date: Thu, 24 Apr 2014 21:25:40 +0200 Subject: [PATCH 349/352] Fix {python|perl5|ruby|tcl}/java examples - in Lib/gcj/cni.i: remove JvAllocObject(), change JvCreateJavaVM() argument from void* to JvVMInitArgs* - in Examples/{python|perl5|ruby|tcl}/java/Makefile: pass full class name to gcjh, add Example.h as dependency, do not override CXX for compiling C++ sources - in Examples/python/java/example.i: add destructor to class to prevent memory loss complaint --- CHANGES.current | 18 ++++++++++++++++++ Examples/perl5/check.list | 1 + Examples/perl5/java/Makefile | 8 ++++---- Examples/python/java/Makefile | 9 +++++---- Examples/python/java/example.i | 4 ++++ Examples/ruby/java/Makefile | 8 ++++---- Examples/tcl/java/Makefile | 13 +++++-------- Lib/gcj/cni.i | 6 +----- Makefile.in | 2 +- 9 files changed, 43 insertions(+), 26 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 826b1a2c5..869f37785 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -8,6 +8,24 @@ Version 3.0.1 (in progress) 2014-05-01: olly [PHP] The generated __isset() method now returns true for read-only properties. +2014-04-24: kwwette + Fix {python|perl5|ruby|tcl}/java examples + + In Lib/gcj/cni.i, for compatibility with newer gcj versions: + + - remove JvAllocObject() which gcj no longer defines, from gcj Changelog: + 2004-04-16 Bryce McKinlay + * gcj/cni.h (JvAllocObject): Remove these obsolete, + undocumented CNI calls. + + - change JvCreateJavaVM() argument from void* to JvVMInitArgs*, from gcj Changelog: + 2005-02-23 Thomas Fitzsimmons + PR libgcj/16923 + ... + (JvCreateJavaVM): Declare vm_args as JvVMInitArgs* rather than void*. + + *** POTENTIAL INCOMPATIBILITY *** + 2014-04-08: wsfulton SF Bug #1366 - Remove duplicate declarations of strtoimax and strtoumax in inttypes.i diff --git a/Examples/perl5/check.list b/Examples/perl5/check.list index 78d45fc0b..dda849311 100644 --- a/Examples/perl5/check.list +++ b/Examples/perl5/check.list @@ -6,6 +6,7 @@ constants2 extend funcptr import +java multimap multiple_inheritance pointer diff --git a/Examples/perl5/java/Makefile b/Examples/perl5/java/Makefile index ff3aab0e7..3a0bb215d 100644 --- a/Examples/perl5/java/Makefile +++ b/Examples/perl5/java/Makefile @@ -8,15 +8,15 @@ LIBS = -lm check: build $(MAKE) -f $(TOP)/Makefile perl5_run -build: Example.class +build: Example.class Example.h $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' CXX="gcj" \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ CXXSHARED="gcj -fpic -shared Example.class" PERL5_CCFLAGS='' PERL5_EXP='' LIBS="-lstdc++" perl5_cpp clean: $(MAKE) -f $(TOP)/Makefile perl5_clean rm -f *.class Example.h -Example.class: Example.java +Example.class Example.h: Example.java gcj -fPIC -C -c -g Example.java - gcjh Example + gcjh Example.class diff --git a/Examples/python/java/Makefile b/Examples/python/java/Makefile index 12a9b512a..2ce219969 100644 --- a/Examples/python/java/Makefile +++ b/Examples/python/java/Makefile @@ -6,10 +6,11 @@ INTERFACE = example.i LIBS = -lm check: build + $(MAKE) -f $(TOP)/Makefile python_run -build: Example.class +build: Example.class Example.h $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' CXX="gcj" \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ CXXSHARED="gcj -fpic -shared Example.class" DEFS='' LIBS="-lstdc++" python_cpp clean: @@ -17,6 +18,6 @@ clean: rm -f $(TARGET).py rm -f *.class Example.h -Example.class: Example.java +Example.class Example.h: Example.java gcj -fPIC -C -c -g Example.java - gcjh Example + gcjh Example.class diff --git a/Examples/python/java/example.i b/Examples/python/java/example.i index 13d5b5e70..80e08870f 100644 --- a/Examples/python/java/example.i +++ b/Examples/python/java/example.i @@ -7,3 +7,7 @@ %include Example.h + +%extend Example { + ~Example() {} +} diff --git a/Examples/ruby/java/Makefile b/Examples/ruby/java/Makefile index 4d2493493..a71635baa 100644 --- a/Examples/ruby/java/Makefile +++ b/Examples/ruby/java/Makefile @@ -8,15 +8,15 @@ LIBS = -lm check: build $(MAKE) -f $(TOP)/Makefile ruby_run -build: Example.class +build: Example.class Example.h $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' CXX="gcj" \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ CXXSHARED="gcj -fpic -shared Example.class" LIBS="-lstdc++" DEFS='' ruby_cpp clean: $(MAKE) -f $(TOP)/Makefile ruby_clean rm -f *.class Example.h -Example.class: Example.java +Example.class Example.h: Example.java gcj -fPIC -C -c -g Example.java - gcjh Example + gcjh Example.class diff --git a/Examples/tcl/java/Makefile b/Examples/tcl/java/Makefile index 3a9212381..a3819ab7c 100644 --- a/Examples/tcl/java/Makefile +++ b/Examples/tcl/java/Makefile @@ -8,18 +8,15 @@ LIBS = -lm check: build $(MAKE) -f $(TOP)/Makefile tcl_run -build: Example.class +build: Example.class Example.h $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ - TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' CXX="gcj" \ - TCL_CXXSHARED="gcj -fpic -shared Example.class " LIBS="-lstdc++" DEFS='' tcl_cpp + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' \ + TCLCXXSHARED="gcj -fpic -shared Example.class " LIBS="-lstdc++" DEFS='' tcl_cpp clean: $(MAKE) -f $(TOP)/Makefile tcl_clean rm -f *.class Example.h -run: - tclsh runme.tcl - -Example.class: Example.java +Example.class Example.h: Example.java gcj -fPIC -C -c -g Example.java - gcjh Example + gcjh Example.class diff --git a/Lib/gcj/cni.i b/Lib/gcj/cni.i index b12148e91..fcc56687a 100644 --- a/Lib/gcj/cni.i +++ b/Lib/gcj/cni.i @@ -4,10 +4,6 @@ %include -extern jobject JvAllocObject (jclass cls); - -extern jobject JvAllocObject (jclass cls, jsize sz); - extern void JvInitClass (jclass cls); extern jstring JvAllocString (jsize sz); @@ -30,7 +26,7 @@ extern void *JvMalloc (jsize size); extern void JvFree (void *ptr); -extern jint JvCreateJavaVM (void* vm_args); +extern jint JvCreateJavaVM (JvVMInitArgs* vm_args); extern java::lang::Thread* JvAttachCurrentThread (jstring name, java::lang::ThreadGroup* group); diff --git a/Makefile.in b/Makefile.in index 2eb1326ea..06e4724c7 100644 --- a/Makefile.in +++ b/Makefile.in @@ -252,7 +252,7 @@ java.actionexample: echo "skipping Examples/$(LANGUAGE)/java $(ACTION) (gcj test)"; \ else \ echo $(ACTION)ing Examples/$(LANGUAGE)/java; \ - (cd Examples/$(LANGUAGE)/java && $(MAKE) $(FLAGS) $(chk-set-env) $(ACTION)) \ + (cd Examples/$(LANGUAGE)/java && $(MAKE) $(FLAGS) $(chk-set-env) $(ACTION) RUNPIPE=$(RUNPIPE)) \ fi # Checks testcases in the test-suite excluding those which are known to be broken From 66555ad2a7f8a0cfad9fff16fcace79346af8033 Mon Sep 17 00:00:00 2001 From: Karl Wette Date: Fri, 25 Apr 2014 00:12:06 +0200 Subject: [PATCH 350/352] Fix go configuration and SWIG_GCC_VERSION - in configure.ac: modify sed expression to only look at first line of gccgo --version, extract the last numeric token, and remove periods; this parses e.g. "gccgo (Debian 4.7.2-5) 4.7.2" - in goruntime.swg: fix typo in __GNUC_PATCHLEVEL__ (SF Bug #1298) --- CHANGES.current | 4 ++++ Lib/go/goruntime.swg | 2 +- configure.ac | 8 ++++++-- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGES.current b/CHANGES.current index 869f37785..8b67392b2 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -8,6 +8,10 @@ Version 3.0.1 (in progress) 2014-05-01: olly [PHP] The generated __isset() method now returns true for read-only properties. +2014-04-24: kwwette + [Go] Fix go ./configure parsing of gccgo --version, and + goruntime.swg typo in __GNUC_PATCHLEVEL__ (SF Bug #1298) + 2014-04-24: kwwette Fix {python|perl5|ruby|tcl}/java examples diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg index 612f83086..bbc602b0d 100644 --- a/Lib/go/goruntime.swg +++ b/Lib/go/goruntime.swg @@ -116,7 +116,7 @@ extern void _cgo_panic(const char *); file is the same as the version of gccgo. */ #define SWIG_GCC_VERSION \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC__PATH_LEVEL__) + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #if SWIG_GCC_VERSION < 40700 #define SwigDoCgocall() diff --git a/configure.ac b/configure.ac index 091749f53..d83e0d31b 100644 --- a/configure.ac +++ b/configure.ac @@ -2266,9 +2266,13 @@ else GOGCC=true GOVERSIONOPTION=--version AC_MSG_CHECKING([whether gccgo version is too old]) - go_version=`$GO $GOVERSIONOPTION | sed -e 's/[^0-9]* \([0-9.]*\) .*$/\1/' -e 's/[.]//g'` - if test "$go_version" -lt 470; then + go_version=[`$GO $GOVERSIONOPTION | sed -n '1p' | sed -e 's/^.* \([0-9.]*\) *$/\1/' -e 's/[.]//g'`] + if test "x$go_version" = x; then + AC_MSG_RESULT([could not determine gccgo version - disabling Go]) + GO= + elif test "$go_version" -lt 470; then AC_MSG_RESULT([yes - minimum version is 4.7.0]) + GO= else AC_MSG_RESULT([no]) if test "$go_version" -lt 480; then From 7cac2d35cb53f003ddb14fb0ac93753fea027da3 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Mon, 5 May 2014 16:04:37 +1200 Subject: [PATCH 351/352] Remove random extra assignment in example code --- Examples/lua/class/runme.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/Examples/lua/class/runme.lua b/Examples/lua/class/runme.lua index 2c3ad8ced..5d140defe 100644 --- a/Examples/lua/class/runme.lua +++ b/Examples/lua/class/runme.lua @@ -53,7 +53,6 @@ print("\nGuess I'll clean up now") -- Note: this invokes the virtual destructor c=nil s=nil -s = 3 -- call gc to make sure they are collected collectgarbage() From b115c984a97e5f20e9ad5979f1ad606fff549bc3 Mon Sep 17 00:00:00 2001 From: Olly Betts Date: Mon, 5 May 2014 16:14:31 +1200 Subject: [PATCH 352/352] More cleaning up of the class examples --- Examples/chicken/class/example.cxx | 10 +++++----- Examples/csharp/class/example.cxx | 10 +++++----- Examples/d/class/example.cxx | 10 +++++----- Examples/go/class/class.cxx | 10 +++++----- Examples/go/class/index.html | 8 ++++---- Examples/guile/class/example.cxx | 10 +++++----- Examples/javascript/class/example.cxx | 12 ++++++------ Examples/javascript/class/example.h | 18 +++++++++--------- Examples/javascript/class/example.i | 1 - Examples/lua/class/example.cxx | 10 +++++----- Examples/modula3/class/example.cxx | 10 +++++----- Examples/octave/class/example.cxx | 10 +++++----- Examples/r/class/example.cxx | 10 +++++----- 13 files changed, 64 insertions(+), 65 deletions(-) diff --git a/Examples/chicken/class/example.cxx b/Examples/chicken/class/example.cxx index 1e8e203dd..046304519 100644 --- a/Examples/chicken/class/example.cxx +++ b/Examples/chicken/class/example.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : example.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/csharp/class/example.cxx b/Examples/csharp/class/example.cxx index 1e8e203dd..046304519 100644 --- a/Examples/csharp/class/example.cxx +++ b/Examples/csharp/class/example.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : example.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/d/class/example.cxx b/Examples/d/class/example.cxx index 1e8e203dd..046304519 100644 --- a/Examples/d/class/example.cxx +++ b/Examples/d/class/example.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : example.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/go/class/class.cxx b/Examples/go/class/class.cxx index 1e8e203dd..f87c7ec8f 100644 --- a/Examples/go/class/class.cxx +++ b/Examples/go/class/class.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : class.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/go/class/index.html b/Examples/go/class/index.html index b39119d12..df93b5672 100644 --- a/Examples/go/class/index.html +++ b/Examples/go/class/index.html @@ -33,8 +33,8 @@ public: } virtual ~Shape() { nshapes--; - }; - double x, y; + } + double x, y; void move(double dx, double dy); virtual double area() = 0; virtual double perimeter() = 0; @@ -45,7 +45,7 @@ class Circle : public Shape { private: double radius; public: - Circle(double r) : radius(r) { }; + Circle(double r) : radius(r) { } virtual double area(); virtual double perimeter(); }; @@ -54,7 +54,7 @@ class Square : public Shape { private: double width; public: - Square(double w) : width(w) { }; + Square(double w) : width(w) { } virtual double area(); virtual double perimeter(); }; diff --git a/Examples/guile/class/example.cxx b/Examples/guile/class/example.cxx index 1e8e203dd..046304519 100644 --- a/Examples/guile/class/example.cxx +++ b/Examples/guile/class/example.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : example.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/javascript/class/example.cxx b/Examples/javascript/class/example.cxx index e23fa6f73..046304519 100644 --- a/Examples/javascript/class/example.cxx +++ b/Examples/javascript/class/example.cxx @@ -1,5 +1,5 @@ -/* File : example.c */ -#include +/* File : example.cxx */ + #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/javascript/class/example.h b/Examples/javascript/class/example.h index 64b7684fa..642130cd0 100644 --- a/Examples/javascript/class/example.h +++ b/Examples/javascript/class/example.h @@ -7,11 +7,11 @@ public: } virtual ~Shape() { nshapes--; - }; + } double x, y; void move(double dx, double dy); - virtual double area(void) = 0; - virtual double perimeter(void) = 0; + virtual double area() = 0; + virtual double perimeter() = 0; static int nshapes; }; @@ -19,16 +19,16 @@ class Circle : public Shape { private: double radius; public: - Circle(double r) : radius(r) { }; - virtual double area(void); - virtual double perimeter(void); + Circle(double r) : radius(r) { } + virtual double area(); + virtual double perimeter(); }; class Square : public Shape { private: double width; public: - Square(double w) : width(w) { }; - virtual double area(void); - virtual double perimeter(void); + Square(double w) : width(w) { } + virtual double area(); + virtual double perimeter(); }; diff --git a/Examples/javascript/class/example.i b/Examples/javascript/class/example.i index 75700b305..fbdf7249f 100644 --- a/Examples/javascript/class/example.i +++ b/Examples/javascript/class/example.i @@ -7,4 +7,3 @@ /* Let's just grab the original header file here */ %include "example.h" - diff --git a/Examples/lua/class/example.cxx b/Examples/lua/class/example.cxx index 1e8e203dd..046304519 100644 --- a/Examples/lua/class/example.cxx +++ b/Examples/lua/class/example.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : example.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/modula3/class/example.cxx b/Examples/modula3/class/example.cxx index 1e8e203dd..046304519 100644 --- a/Examples/modula3/class/example.cxx +++ b/Examples/modula3/class/example.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : example.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/octave/class/example.cxx b/Examples/octave/class/example.cxx index 1e8e203dd..046304519 100644 --- a/Examples/octave/class/example.cxx +++ b/Examples/octave/class/example.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : example.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; } diff --git a/Examples/r/class/example.cxx b/Examples/r/class/example.cxx index 1e8e203dd..046304519 100644 --- a/Examples/r/class/example.cxx +++ b/Examples/r/class/example.cxx @@ -1,4 +1,4 @@ -/* File : example.c */ +/* File : example.cxx */ #include "example.h" #define M_PI 3.14159265358979323846 @@ -11,18 +11,18 @@ void Shape::move(double dx, double dy) { int Shape::nshapes = 0; -double Circle::area(void) { +double Circle::area() { return M_PI*radius*radius; } -double Circle::perimeter(void) { +double Circle::perimeter() { return 2*M_PI*radius; } -double Square::area(void) { +double Square::area() { return width*width; } -double Square::perimeter(void) { +double Square::perimeter() { return 4*width; }