aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-09-16 15:30:54 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-09-16 15:30:54 -0700
commit16494fdfcf728ff7f45b452e63674ab605de040b (patch)
treec1592ab8f13d414cd7b983b606514818dfe94a05
parente742036d2eddbb0ceef08a68fb22223d55780de5 (diff)
parent4203afeb1a8cf66809aa79f400c0b2d05b51414c (diff)
Merge branch 'llvm-svn' of github.com:kripken/emscripten into llvm-svn
-rw-r--r--src/jsifier.js28
-rw-r--r--src/library.js160
-rw-r--r--src/parseTools.js2
-rw-r--r--src/preamble.js4
-rw-r--r--tests/exceptions/output.txt50
-rw-r--r--tests/exceptions/typed.cpp91
-rw-r--r--tests/runner.py9
-rwxr-xr-xtools/bindings_generator.py17
8 files changed, 342 insertions, 19 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index aa1e3c60..ab5c8720 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -209,6 +209,28 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
}
var constant = null;
if (item.external) {
+ // Import external global variables from the library if available.
+ var shortident = item.ident.slice(1);
+ if (LibraryManager.library[shortident] &&
+ LibraryManager.library[shortident].length &&
+ !BUILD_AS_SHARED_LIB) {
+ var val = LibraryManager.library[shortident];
+ var padding;
+ if (Runtime.isNumberType(item.type) || isPointerType(item.type)) {
+ padding = [item.type].concat(zeros(getNativeFieldSize(item.type)));
+ } else {
+ padding = makeEmptyStruct(item.type);
+ }
+ var padded = val.concat(padding.slice(val.length));
+ var js = item.ident + '=' + makePointer(JSON.stringify(padded), null, 'ALLOC_STATIC', item.type) + ';'
+ if (LibraryManager.library[shortident + '__postset']) {
+ js += '\n' + LibraryManager.library[shortident + '__postset'];
+ }
+ ret.push({
+ intertype: 'GlobalVariablePostSet',
+ JS: js
+ });
+ }
return ret;
} else {
function needsPostSet(value) {
@@ -723,6 +745,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
var ret = '(function() { try { __THREW__ = false; return '
+ call_ + ' '
+ '} catch(e) { '
+ + 'if (typeof e != "number") throw e; '
+ 'if (ABORT) throw e; __THREW__ = true; '
+ (EXCEPTION_DEBUG ? 'print("Exception: " + e + ", currently at: " + (new Error().stack)); ' : '')
+ 'return null } })(); if (!__THREW__) { ' + branch
@@ -806,10 +829,11 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
var argsTypes = [];
var varargs = [];
var varargsTypes = [];
+ var useJSArgs = (ident.slice(1) + '__jsargs') in LibraryManager.library;
params.forEach(function(param, i) {
var val = finalizeParam(param);
- if (!func || !func.hasVarArgs || i < func.numParams-1) {
+ if (!func || !func.hasVarArgs || i < func.numParams-1 || useJSArgs) {
args.push(val);
argsTypes.push(param.type);
} else {
@@ -823,7 +847,7 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
args = args.map(function(arg, i) { return indexizeFunctions(arg, argsTypes[i]) });
varargs = varargs.map(function(vararg, i) { return vararg === 0 ? 0 : indexizeFunctions(vararg, varargsTypes[i]) });
- if (func && func.hasVarArgs) {
+ if (func && func.hasVarArgs && !useJSArgs) {
if (varargs.length === 0) {
varargs = [0];
varargsTypes = ['i32'];
diff --git a/src/library.js b/src/library.js
index 84ea9243..1f32678d 100644
--- a/src/library.js
+++ b/src/library.js
@@ -255,7 +255,7 @@ LibraryManager.library = {
xhr.open('GET', obj.url, false);
// Some hints to the browser that we want binary data.
- xhr.responseType = 'arraybuffer';
+ if (typeof Uint8Array != 'undefined') xhr.responseType = 'arraybuffer';
if (xhr.overrideMimeType) {
xhr.overrideMimeType('text/plain; charset=x-user-defined');
}
@@ -316,7 +316,7 @@ LibraryManager.library = {
// Command line.
result = readline();
}
- if (!result) return null;
+ if (!result) result = '';
input.cache = intArrayFromString(result + '\n', true);
}
return input.cache.shift();
@@ -2112,6 +2112,7 @@ LibraryManager.library = {
ftruncate64: 'ftruncate',
__01open64_: 'open',
__01lseek64_: 'lseek',
+ __01truncate64_: 'truncate',
__01ftruncate64_: 'ftruncate',
// TODO: Check if any other aliases are needed.
@@ -3092,6 +3093,7 @@ LibraryManager.library = {
vsscanf: 'sscanf',
fopen64: 'fopen',
__01fopen64_: 'fopen',
+ __01freopen64_: 'freopen',
__01fseeko64_: 'fseek',
__01ftello64_: 'ftell',
__01tmpfile64_: 'tmpfile',
@@ -3598,6 +3600,11 @@ LibraryManager.library = {
return String_len(ptr);
},
+ // TODO: Implement when we have real unicode support.
+ mblen: function() {
+ return 1;
+ },
+
strspn: function(pstr, pset) {
var str = String_copy(pstr, true);
var set = String_copy(pset);
@@ -3622,6 +3629,14 @@ LibraryManager.library = {
} while ({{{ makeGetValue('psrc', 'i-1', 'i8') }}} != 0);
return pdest;
},
+ stpcpy: function(pdest, psrc) {
+ var i = 0;
+ do {
+ {{{ makeCopyValues('pdest+i', 'psrc+i', 1, 'i8') }}}
+ i ++;
+ } while ({{{ makeGetValue('psrc', 'i-1', 'i8') }}} != 0);
+ return pdest + i - 1;
+ },
strncpy: function(pdest, psrc, num) {
var padding = false, curr;
@@ -3992,25 +4007,75 @@ LibraryManager.library = {
return 1;
},
- // Exceptions - minimal support, only (...) for now (no actual exception objects can be caught)
+ // Exceptions
__cxa_allocate_exception: function(size) {
- return _malloc(size); // warning: leaked
+ return _malloc(size);
+ },
+ __cxa_free_exception: function(ptr) {
+ return _free(ptr);
},
- __cxa_throw: function(ptr, data, dunno) {
+ __cxa_throw__deps: ['llvm_eh_exception'],
+ __cxa_throw: function(ptr, type, destructor) {
#if EXCEPTION_DEBUG
- print('Compiled code throwing an exception, ' + [ptr,data,dunno] + ', at ' + new Error().stack);
+ print('Compiled code throwing an exception, ' + [ptr,type,destructor] + ', at ' + new Error().stack);
#endif
+ {{{ makeSetValue('_llvm_eh_exception.buf', '0', 'ptr', 'void*') }}}
+ {{{ makeSetValue('_llvm_eh_exception.buf', '4', 'type', 'void*') }}}
+ {{{ makeSetValue('_llvm_eh_exception.buf', '8', 'destructor', 'void*') }}}
throw ptr;
},
+ __cxa_rethrow__deps: ['llvm_eh_exception', '__cxa_end_catch'],
+ __cxa_rethrow: function() {
+ ___cxa_end_catch.rethrown = true;
+ throw {{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}};
+ },
+ llvm_eh_exception__postset: '_llvm_eh_exception.buf = allocate(12, "void*", ALLOC_STATIC);',
llvm_eh_exception: function() {
- return 'code-generated exception: ' + (new Error().stack);
+ return {{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}};
},
- llvm_eh_selector: function(exception, personality, num) {
+ llvm_eh_selector__jsargs: true,
+ llvm_eh_selector: function(unused_exception_value, personality/*, varargs*/) {
+ var type = {{{ makeGetValue('_llvm_eh_exception.buf', '4', 'void*') }}}
+ for (var i = 2; i < arguments.length; i++) {
+ if (arguments[i] == type) return type;
+ }
return 0;
},
+ llvm_eh_typeid_for: function(type) {
+ return type;
+ },
+ _Unwind_Resume_or_Rethrow: function(ptr) {
+ throw ptr;
+ },
__cxa_begin_catch: function(ptr) {
+ return ptr;
+ },
+ __cxa_end_catch__deps: ['llvm_eh_exception', '__cxa_free_exception'],
+ __cxa_end_catch: function() {
+ if (___cxa_end_catch.rethrown) {
+ ___cxa_end_catch.rethrown = false;
+ return;
+ }
+ // Clear state flag.
+ __THREW__ = false;
+ // Clear type.
+ {{{ makeSetValue('_llvm_eh_exception.buf', '4', '0', 'void*') }}}
+ // Call destructor if one is registered then clear it.
+ var ptr = {{{ makeGetValue('_llvm_eh_exception.buf', '0', 'void*') }}};
+ var destructor = {{{ makeGetValue('_llvm_eh_exception.buf', '8', 'void*') }}};
+ if (destructor) {
+ FUNCTION_TABLE[destructor](ptr);
+ {{{ makeSetValue('_llvm_eh_exception.buf', '8', '0', 'i32') }}}
+ }
+ // Free ptr if it isn't null.
+ if (ptr) {
+ ___cxa_free_exception(ptr);
+ {{{ makeSetValue('_llvm_eh_exception.buf', '0', '0', 'void*') }}}
+ }
},
- __cxa_end_catch: function(ptr) {
+ __cxa_get_exception_ptr__deps: ['llvm_eh_exception'],
+ __cxa_get_exception_ptr: function(ptr) {
+ return ptr;
},
__cxa_call_unexpected: function(exception) {
@@ -4018,9 +4083,29 @@ LibraryManager.library = {
throw exception;
},
+ terminate: '__cxa_call_unexpected',
+
__gxx_personality_v0: function() {
},
+ // RTTI hacks for exception handling, defining type_infos for common types.
+ // The values are dummies. We simply use the addresses of these statically
+ // allocated variables as unique identifiers.
+ // type_info for int.
+ _ZTIi: [0],
+ // type_info for long.
+ _ZTIl: [0],
+ // type_info for long long.
+ _ZTIx: [0],
+ // type_info for float.
+ _ZTIf: [0],
+ // type_info for double.
+ _ZTId: [0],
+ // type_info for char.
+ _ZTIc: [0],
+ // type_info for void.
+ _ZTIv: [0],
+
llvm_umul_with_overflow_i32: function(x, y) {
return {
f0: x*y,
@@ -4686,6 +4771,28 @@ LibraryManager.library = {
// sys/time.h
// ==========================================================================
+ __timespec_struct_layout: Runtime.generateStructInfo(null, '%struct.timespec'),
+ // TODO: Implement these for real.
+ clock_gettime__deps: ['__timespec_struct_layout'],
+ clock_gettime: function(clk_id, tp) {
+ // int clock_gettime(clockid_t clk_id, struct timespec *tp);
+ {{{ makeSetValue('tp', '___timespec_struct_layout.tv_sec', '0', 'i32') }}}
+ {{{ makeSetValue('tp', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}}
+ return 0;
+ },
+ clock_settime: function(clk_id, tp) {
+ // int clock_settime(clockid_t clk_id, const struct timespec *tp);
+ // Nothing.
+ return 0;
+ },
+ clock_getres__deps: ['__timespec_struct_layout'],
+ clock_getres: function(clk_id, res) {
+ // int clock_getres(clockid_t clk_id, struct timespec *res);
+ {{{ makeSetValue('res', '___timespec_struct_layout.tv_sec', '1', 'i32') }}}
+ {{{ makeSetValue('res', '___timespec_struct_layout.tv_nsec', '0', 'i32') }}}
+ return 0;
+ },
+
// TODO: Implement remaining functions.
// http://pubs.opengroup.org/onlinepubs/000095399/basedefs/sys/time.h.html
gettimeofday: function(ptr) {
@@ -4756,6 +4863,23 @@ LibraryManager.library = {
// TODO
return 0;
},
+ sigemptyset: function(set) {
+ // int sigemptyset(sigset_t *set);
+ // TODO: Implement for real; don't hardcode offsets.
+ {{{ makeSetValue('set', '0', '0', 'i32') }}}
+ {{{ makeSetValue('set', '4', '0', 'i32') }}}
+ {{{ makeSetValue('set', '8', '0', 'i32') }}}
+ {{{ makeSetValue('set', '12', '0', 'i32') }}}
+ return 0;
+ },
+ sigfillset: 'sigemptyset',
+ sigdelset: 'sigemptyset',
+ sigaction: function(set) {
+ // int sigemptyset(sigset_t *set);
+ // TODO: Implement for real.
+ return 0;
+ },
+ sigprocmask: 'sigaction',
__libc_current_sigrtmin: function() {
return 0;
},
@@ -5166,6 +5290,24 @@ LibraryManager.library = {
__errno_location: function() {
return ___setErrNo.ret;
},
+ // ==========================================================================
+ // sys/resource.h
+ // ==========================================================================
+
+ // TODO: Implement for real.
+ __rlimit_struct_layout: Runtime.generateStructInfo(null, '%struct.rlimit'),
+ getrlimit__deps: ['__rlimit_struct_layout'],
+ getrlimit: function(resource, rlp) {
+ // int getrlimit(int resource, struct rlimit *rlp);
+ {{{ makeSetValue('rlp', '___rlimit_struct_layout.rlim_cur', '-1', 'i32') }}} // RLIM_INFINITY
+ {{{ makeSetValue('rlp', '___rlimit_struct_layout.rlim_max', '-1', 'i32') }}} // RLIM_INFINITY
+ return 0;
+ },
+ setrlimit: function(resource, rlp) {
+ // int setrlimit(int resource, const struct rlimit *rlp)
+ return 0;
+ },
+ __01getrlimit64_: 'getrlimit',
// ==========================================================================
// pthread.h (stubs for mutexes only - no thread support yet!)
diff --git a/src/parseTools.js b/src/parseTools.js
index ceae2c61..f9f46b06 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1051,7 +1051,7 @@ function getGetElementPtrIndexes(item) {
}
curr = 0;
}
- type = typeData ? typeData.fields[curr] : '';
+ type = typeData && typeData.fields[curr] ? typeData.fields[curr] : '';
});
var ret = indexes[0];
for (var i = 1; i < indexes.length; i++) {
diff --git a/src/preamble.js b/src/preamble.js
index 8c2a9dcb..9dd7ffaa 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -321,7 +321,7 @@ function setValue(ptr, value, type) {
default: abort('invalid type for setValue: ' + type);
}
}
-this['setValue'] = setValue;
+Module['setValue'] = setValue;
// Parallel to setValue.
@@ -339,7 +339,7 @@ function getValue(ptr, type) {
}
return null;
}
-this['getValue'] = getValue;
+Module['getValue'] = getValue;
// Allocates memory for some data and initializes it properly.
diff --git a/tests/exceptions/output.txt b/tests/exceptions/output.txt
new file mode 100644
index 00000000..2db8345e
--- /dev/null
+++ b/tests/exceptions/output.txt
@@ -0,0 +1,50 @@
+*CREATING A FOO
+*CREATING A BAR
+*CREATING A QUUX
+start
+
+
+ throwing ExFooInstance
+*COPYING A FOO
+*COPYING A FOO
+outer catch foo: 11
+*DESTROYING A FOO (11)
+*DESTROYING A FOO (11)
+
+
+ throwing ExBarInstance
+*COPYING A BAR
+*COPYING A BAR
+inner re-throw: 22
+*DESTROYING A BAR (22)
+outer catch bar-ref: 22
+*DESTROYING A BAR (22)
+
+
+ throwing ExQuuxInstance
+*COPYING A QUUX
+*COPYING A QUUX
+inner catch quux: 33
+*DESTROYING A QUUX (33)
+*DESTROYING A QUUX (33)
+
+
+
+
+
+
+ throwing 42
+outer catch int: 42
+
+
+ throwing NULL
+outer catch-all
+
+
+ not throwing
+
+
+end
+*DESTROYING A QUUX (33)
+*DESTROYING A BAR (22)
+*DESTROYING A FOO (11)
diff --git a/tests/exceptions/typed.cpp b/tests/exceptions/typed.cpp
new file mode 100644
index 00000000..29bf548a
--- /dev/null
+++ b/tests/exceptions/typed.cpp
@@ -0,0 +1,91 @@
+#include <stdio.h>
+
+class ExFoo {
+public:
+ int x;
+ ExFoo(int x) { this->x = x; printf("*CREATING A FOO\n"); }
+ ExFoo(const ExFoo& other) { x=other.x; printf("*COPYING A FOO\n"); }
+ ~ExFoo() { printf("*DESTROYING A FOO (%d)\n", x); }
+} ExFooInstance(11);
+class ExBar {
+public:
+ int x;
+ ExBar(int x) { this->x = x; printf("*CREATING A BAR\n"); }
+ ExBar(const ExBar& other) { x=other.x; printf("*COPYING A BAR\n"); }
+ ~ExBar() { printf("*DESTROYING A BAR (%d)\n", x); }
+} ExBarInstance(22);
+class ExQuux {
+public:
+ int x;
+ ExQuux(int x) { this->x = x; printf("*CREATING A QUUX\n"); }
+ ExQuux(const ExQuux& other) { x=other.x; printf("*COPYING A QUUX\n"); }
+ ~ExQuux() { printf("*DESTROYING A QUUX (%d)\n", x); }
+} ExQuuxInstance(33);
+// NOTE: Throwing pointers and polymorphic matching not supported.
+// class ExChild : public ExQuux {
+// public:
+// ExChild(int x) : ExQuux(x) { printf("*CREATING A CHILD\n"); }
+// ExChild(const ExChild& other) : ExQuux(x) { x=other.x; printf("*COPYING CHILD\n"); }
+// ~ExChild() { printf("*DESTROYING A CHILD (%d)\n", x); }
+// } ExChildInstance(44);
+
+void magic(int which) {
+ try {
+ switch (which) {
+ case 0:
+ printf(" throwing ExFooInstance\n");
+ throw ExFooInstance;
+ case 1:
+ printf(" throwing ExBarInstance\n");
+ throw ExBarInstance;
+ case 2:
+ printf(" throwing ExQuuxInstance\n");
+ throw ExQuuxInstance;
+// NOTE: Throwing pointers and polymorphic matching not supported.
+// case 3:
+// printf(" throwing ExQuux ptr\n");
+// throw &ExQuuxInstance;
+// case 4:
+// printf(" throwing ExChildInstance\n");
+// throw ExChildInstance;
+ case 5:
+ printf(" throwing 42\n");
+ throw 42;
+ case 6:
+ printf(" throwing NULL\n");
+ throw (void*)0;
+ case 7:
+ printf(" not throwing\n");
+ }
+ } catch (ExQuux e1) {
+ printf("inner catch quux: %d\n", e1.x);
+ } catch (ExBar e2) {
+ printf("inner re-throw: %d\n", e2.x);
+ throw;
+ }
+}
+
+int main() {
+ printf("start\n\n\n");
+ for (int i = 0; i < 8; i++) {
+ try {
+ magic(i);
+ } catch (ExFoo e1) {
+ printf("outer catch foo: %d\n", e1.x);
+ } catch (ExBar& e2) {
+ printf("outer catch bar-ref: %d\n", e2.x);
+// NOTE: Throwing pointers and polymorphic matching not supported.
+// } catch (ExQuux& e3) {
+// printf("outer catch quux-ref: %d\n", e3.x);
+// } catch (ExQuux* e4) {
+// printf("outer catch quux-ptr: %d\n", e4->x);
+ } catch (int e5) {
+ printf("outer catch int: %d\n", e5);
+ } catch (...) {
+ printf("outer catch-all\n");
+ }
+ printf("\n\n");
+ }
+ printf("end\n");
+ return 0;
+}
diff --git a/tests/runner.py b/tests/runner.py
index d080694b..2af4de65 100644
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -180,7 +180,7 @@ class RunnerCore(unittest.TestCase):
def do_emscripten(self, filename, output_processor=None, append_ext=True, extra_args=[]):
# Run Emscripten
exported_settings = {}
- for setting in ['QUANTUM_SIZE', 'RELOOP', 'OPTIMIZE', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'AUTO_OPTIMIZE', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTIONS', 'FAST_MEMORY']:
+ for setting in ['QUANTUM_SIZE', 'RELOOP', 'OPTIMIZE', 'ASSERTIONS', 'USE_TYPED_ARRAYS', 'SAFE_HEAP', 'CHECK_OVERFLOWS', 'CORRECT_OVERFLOWS', 'CORRECT_SIGNS', 'CHECK_SIGNS', 'CORRECT_OVERFLOWS_LINES', 'CORRECT_SIGNS_LINES', 'CORRECT_ROUNDINGS', 'CORRECT_ROUNDINGS_LINES', 'INVOKE_RUN', 'SAFE_HEAP_LINES', 'INIT_STACK', 'AUTO_OPTIMIZE', 'EXPORTED_FUNCTIONS', 'EXPORTED_GLOBALS', 'BUILD_AS_SHARED_LIB', 'INCLUDE_FULL_LIBRARY', 'RUNTIME_TYPE_INFO', 'DISABLE_EXCEPTIONS', 'FAST_MEMORY', 'EXCEPTION_DEBUG']:
try:
value = eval(setting)
exported_settings[setting] = value
@@ -994,6 +994,13 @@ if 'benchmark' not in str(sys.argv):
DISABLE_EXCEPTIONS = 1
self.do_test(src, 'Compiled code throwing an exception')
+ def test_typed_exceptions(self):
+ global SAFE_HEAP; SAFE_HEAP = 0 # Throwing null will cause an ignorable null pointer access.
+ global EXCEPTION_DEBUG; EXCEPTION_DEBUG = 0 # Messes up expected output.
+ src = open(path_from_root('tests', 'exceptions', 'typed.cpp'), 'r').read()
+ expected = open(path_from_root('tests', 'exceptions', 'output.txt'), 'r').read()
+ self.do_test(src, expected)
+
def test_class(self):
src = '''
#include <stdio.h>
diff --git a/tools/bindings_generator.py b/tools/bindings_generator.py
index 87359fa0..0a1a75cc 100755
--- a/tools/bindings_generator.py
+++ b/tools/bindings_generator.py
@@ -442,8 +442,17 @@ function customizeVTable(object, replacementPairs) {
FUNCTION_TABLE.push(0);
setValue(vTable2 + Runtime.QUANTUM_SIZE*i, index, 'void*');
}
+ var args = [{ptr: 0}];
replacementPairs.forEach(function(pair) {
- pair.original.call(object);
+ // We need the wrapper function that converts arguments to not fail. Keep adding arguments til it works.
+ while(1) {
+ try {
+ pair['original'].apply(object, args);
+ break;
+ } catch(e) {
+ args.push(args[0]);
+ }
+ }
pair.originalIndex = getValue(vTable + canaryValue*Runtime.QUANTUM_SIZE, 'void*');
});
FUNCTION_TABLE = FUNCTION_TABLE.slice(0, functions);
@@ -453,7 +462,7 @@ function customizeVTable(object, replacementPairs) {
var replacements = {};
replacementPairs.forEach(function(pair) {
var replacementIndex = FUNCTION_TABLE.length;
- FUNCTION_TABLE.push(pair.replacement);
+ FUNCTION_TABLE.push(pair['replacement']);
FUNCTION_TABLE.push(0);
replacements[pair.originalIndex] = replacementIndex;
});
@@ -485,7 +494,7 @@ def generate_class(generating_classname, classname, clazz): # TODO: deprecate ge
# For abstract base classes, add a function definition on top. There is no constructor
gen_js.write('\nfunction ' + generating_classname_head + ('(){ throw "%s is abstract!" }\n' % generating_classname_head) + generate_wrapping_code(generating_classname_head))
if export:
- gen_js.write('''this['%s'] = %s;
+ gen_js.write('''Module['%s'] = %s;
''' % (generating_classname_head, generating_classname_head))
for method in clazz['final_methods'].itervalues():
@@ -658,7 +667,7 @@ function %s(%s) {
if export:
js_text += '''
-this['%s'] = %s;
+Module['%s'] = %s;
''' % (mname_suffixed, mname_suffixed)
else: