From ecb0c74eb434bd92839815a4deb8d9de0d6a39b9 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Dec 2018 16:57:03 -0800 Subject: [PATCH 1/8] use eval for good [ci skip] --- src/library_fs.js | 14 +++++++------- src/modules.js | 17 ++++++++++------- src/parseTools.js | 47 ++++++----------------------------------------- 3 files changed, 23 insertions(+), 55 deletions(-) diff --git a/src/library_fs.js b/src/library_fs.js index abcf326efb629..98b6d26a323ec 100644 --- a/src/library_fs.js +++ b/src/library_fs.js @@ -5,16 +5,16 @@ mergeInto(LibraryManager.library, { $FS__deps: ['$ERRNO_CODES', '$ERRNO_MESSAGES', '__setErrNo', '$PATH', '$TTY', '$MEMFS', -#if __EMSCRIPTEN_HAS_idbfs_js__ +#if LibraryManager.has('library_idbfs.js') '$IDBFS', #endif -#if __EMSCRIPTEN_HAS_nodefs_js__ +#if LibraryManager.has('library_nodefs.js') '$NODEFS', #endif -#if __EMSCRIPTEN_HAS_workerfs_js__ +#if LibraryManager.has('library_workerfs.js') '$WORKERFS', #endif -#if __EMSCRIPTEN_HAS_noderawfs_js__ +#if LibraryManager.has('library_noderawfs.js') '$NODERAWFS', #endif 'stdin', 'stdout', 'stderr'], @@ -1418,13 +1418,13 @@ mergeInto(LibraryManager.library, { FS.filesystems = { 'MEMFS': MEMFS, -#if __EMSCRIPTEN_HAS_idbfs_js__ +#if LibraryManager.has('library_idbfs.js') 'IDBFS': IDBFS, #endif -#if __EMSCRIPTEN_HAS_nodefs_js__ +#if LibraryManager.has('library_nodefs.js') 'NODEFS': NODEFS, #endif -#if __EMSCRIPTEN_HAS_workerfs_js__ +#if LibraryManager.has('library_workerfs.js') 'WORKERFS': WORKERFS, #endif }; diff --git a/src/modules.js b/src/modules.js index e8100efa42040..20f0c2781d74c 100644 --- a/src/modules.js +++ b/src/modules.js @@ -97,6 +97,12 @@ var LibraryManager = { library: null, structs: {}, loaded: false, + libraries: [], + + has: function(name) { +//printErr(['has?', name, this.libraries.length, this.libraries.indexOf(name), this.libraries]); + return this.libraries.indexOf(name) >= 0; + }, load: function() { if (this.library) return; @@ -163,18 +169,15 @@ var LibraryManager = { libraries = libraries.concat(additionalLibraries); - // For each JS library library_xxx.js, add a preprocessor token __EMSCRIPTEN_HAS_xxx_js__ so that code can conditionally dead code eliminate out - // if a particular feature is not being linked in. - for (var i = 0; i < libraries.length; ++i) { - global['__EMSCRIPTEN_HAS_' + libraries[i].replace('.', '_').replace('library_', '') + '__'] = 1 - } - if (BOOTSTRAPPING_STRUCT_INFO) libraries = ['library_bootstrap_structInfo.js', 'library_formatString.js']; if (ONLY_MY_CODE) { - libraries = []; + libraries.length = 0; LibraryManager.library = {}; } + // Save the list for has() queries later. + this.libraries = libraries; + for (var i = 0; i < libraries.length; i++) { var filename = libraries[i]; var src = read(filename); diff --git a/src/parseTools.js b/src/parseTools.js index 5f5fd08e6e2a9..d7e6f234e08b3 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -41,48 +41,13 @@ function preprocess(text, filenameHint) { } else { if (line[1] == 'i') { if (line[2] == 'f') { // if +//printErr(line); var parts = line.split(' '); - var ident = parts[1]; - var op = parts[2]; - var value = parts[3]; - if (typeof value === 'string') { - // when writing - // #if option == 'stringValue' - // we need to get rid of the quotes - if (value[0] === '"' || value[0] === "'") { - assert(value[value.length - 1] == '"' || value[value.length - 1] == "'"); - value = value.substring(1, value.length - 1); - } - } - if (op) { - if (op === '==') { - showStack.push(ident in this && this[ident] == value); - } else if (op === '!=') { - showStack.push(!(ident in this && this[ident] == value)); - } else if (op === '<') { - showStack.push(ident in this && this[ident] < value); - } else if (op === '<=') { - showStack.push(ident in this && this[ident] <= value); - } else if (op === '>') { - showStack.push(ident in this && this[ident] > value); - } else if (op === '>=') { - showStack.push(ident in this && this[ident] >= value); - } else { - error('unsupported preprocessor op ' + op); - } - } else { - // Check if a value is truthy. - var short = ident[0] === '!' ? ident.substr(1) : ident; - var truthy = short in this; - if (truthy) { - truthy = !!this[short]; - } - if (ident[0] === '!') { - showStack.push(!truthy); - } else { - showStack.push(truthy); - } - } + var after = parts.slice(1).join(' '); +//printErr('-> ' + after); + var truthy = !!eval(after); +//printErr('===> ' + !!truthy); + showStack.push(truthy); } else if (line[2] == 'n') { // include var filename = line.substr(line.indexOf(' ')+1); if (filename.indexOf('"') === 0) { From 67aaafb6f63f172c79aacc0a1e52746aa32fbe60 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Dec 2018 17:38:34 -0800 Subject: [PATCH 2/8] remove code behind NO_DYNAMIC_EXECUTION, which was removed and so is always 0 --- src/embind/embind.js | 72 -------------------------------------------- src/embind/emval.js | 59 ------------------------------------ 2 files changed, 131 deletions(-) diff --git a/src/embind/embind.js b/src/embind/embind.js index 39e28182d47f3..eb69c7a1ff7f6 100644 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -50,11 +50,6 @@ var LibraryEmbind = { Module['flushPendingDeletes'] = flushPendingDeletes; Module['setDelayFunction'] = setDelayFunction; #if IN_TEST_HARNESS -#if NO_DYNAMIC_EXECUTION - // Without dynamic execution, dynamically created functions will have no - // names. This lets the test suite know that. - Module['NO_DYNAMIC_EXECUTION'] = true; -#endif #if EMBIND_STD_STRING_IS_UTF8 Module['EMBIND_STD_STRING_IS_UTF8'] = true; #endif @@ -194,12 +189,6 @@ var LibraryEmbind = { $createNamedFunction__deps: ['$makeLegalFunctionName'], $createNamedFunction: function(name, body) { name = makeLegalFunctionName(name); -#if NO_DYNAMIC_EXECUTION - return function() { - "use strict"; - return body.apply(this, arguments); - }; -#else /*jshint evil:true*/ return new Function( "body", @@ -208,7 +197,6 @@ var LibraryEmbind = { " return body.apply(this, arguments);\n" + "};\n" )(body); -#endif }, embind_repr: function(v) { @@ -847,11 +835,6 @@ var LibraryEmbind = { if (!(constructor instanceof Function)) { throw new TypeError('new_ called with constructor type ' + typeof(constructor) + " which is not a function"); } -#if NO_DYNAMIC_EXECUTION - if (constructor === Function) { - throw new Error('new_ cannot create a new Function with NO_DYNAMIC_EXECUTION.'); - } -#endif /* * Previously, the following line was just: @@ -913,49 +896,6 @@ var LibraryEmbind = { var returns = (argTypes[0].name !== "void"); -#if NO_DYNAMIC_EXECUTION - var argsWired = new Array(argCount - 2); - return function() { - if (arguments.length !== argCount - 2) { - throwBindingError('function ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + (argCount - 2) + ' args!'); - } -#if EMSCRIPTEN_TRACING - Module.emscripten_trace_enter_context('embind::' + humanName); -#endif - var destructors = needsDestructorStack ? [] : null; - var thisWired; - if (isClassMethodFunc) { - thisWired = argTypes[1].toWireType(destructors, this); - } - for (var i = 0; i < argCount - 2; ++i) { - argsWired[i] = argTypes[i + 2].toWireType(destructors, arguments[i]); - } - - var invokerFuncArgs = isClassMethodFunc ? - [cppTargetFunc, thisWired] : [cppTargetFunc]; - - var rv = cppInvokerFunc.apply(null, invokerFuncArgs.concat(argsWired)); - - if (needsDestructorStack) { - runDestructors(destructors); - } else { - for (var i = isClassMethodFunc ? 1 : 2; i < argTypes.length; i++) { - var param = i === 1 ? thisWired : argsWired[i - 2]; - if (argTypes[i].destructorFunction !== null) { - argTypes[i].destructorFunction(param); - } - } - } - -#if EMSCRIPTEN_TRACING - Module.emscripten_trace_exit_context(); -#endif - - if (returns) { - return argTypes[0].fromWireType(rv); - } - }; -#else var argsList = ""; var argsListWired = ""; for(var i = 0; i < argCount - 2; ++i) { @@ -1034,7 +974,6 @@ var LibraryEmbind = { var invokerFunction = new_(Function, args1).apply(null, args2); return invokerFunction; -#endif }, $embind__requireFunction__deps: ['$readLatin1String', '$throwBindingError'], @@ -1042,16 +981,6 @@ var LibraryEmbind = { signature = readLatin1String(signature); function makeDynCaller(dynCall) { -#if NO_DYNAMIC_EXECUTION - return function() { - var args = new Array(arguments.length + 1); - args[0] = rawFunction; - for (var i = 0; i < arguments.length; i++) { - args[i + 1] = arguments[i]; - } - return dynCall.apply(null, args); - }; -#else var args = []; for (var i = 1; i < signature.length; ++i) { args.push('a' + i); @@ -1063,7 +992,6 @@ var LibraryEmbind = { body += '};\n'; return (new Function('dynCall', 'rawFunction', body))(dynCall, rawFunction); -#endif } var fp; diff --git a/src/embind/emval.js b/src/embind/emval.js index c0267475a926c..ab200d1956617 100644 --- a/src/embind/emval.js +++ b/src/embind/emval.js @@ -151,19 +151,6 @@ var LibraryEmVal = { var obj = new constructor(arg0, arg1, arg2); return __emval_register(obj); } */ -#if NO_DYNAMIC_EXECUTION - var argsList = new Array(argCount + 1); - return function(constructor, argTypes, args) { - argsList[0] = constructor; - for (var i = 0; i < argCount; ++i) { - var argType = requireRegisteredType(HEAP32[(argTypes >> 2) + i], 'parameter ' + i); - argsList[i + 1] = argType.readValueFromPointer(args); - args += argType.argPackAdvance; - } - var obj = new (constructor.bind.apply(constructor, argsList)); - return __emval_register(obj); - }; -#else var argsList = ""; for(var i = 0; i < argCount; ++i) { argsList += (i!==0?", ":"")+"arg"+i; // 'arg0, arg1, ..., argn' @@ -186,7 +173,6 @@ var LibraryEmVal = { /*jshint evil:true*/ return (new Function("requireRegisteredType", "Module", "__emval_register", functionBody))( requireRegisteredType, Module, __emval_register); -#endif }, _emval_new__deps: ['$craftEmvalAllocator', '$emval_newers', '$requireHandle'], @@ -202,33 +188,8 @@ var LibraryEmVal = { return newer(handle, argTypes, args); }, -#if NO_DYNAMIC_EXECUTION - $emval_get_global: function() { - function testGlobal(obj) { - obj['$$$embind_global$$$'] = obj; - var success = typeof $$$embind_global$$$ === 'object' && obj['$$$embind_global$$$'] === obj; - if (!success) { - delete obj['$$$embind_global$$$']; - } - return success; - } - if (typeof $$$embind_global$$$ === 'object') { - return $$$embind_global$$$; - } - if (typeof global === 'object' && testGlobal(global)) { - $$$embind_global$$$ = global; - } else if (typeof window === 'object' && testGlobal(window)) { - $$$embind_global$$$ = window; - } - if (typeof $$$embind_global$$$ === 'object') { - return $$$embind_global$$$; - } - throw Error('unable to get global object.'); - }, -#else // appease jshint (technically this code uses eval) $emval_get_global: function() { return (function(){return Function;})()('return this')(); }, -#endif _emval_get_global__deps: ['_emval_register', '$getStringOrSymbol', '$emval_get_global'], _emval_get_global: function(name) { if(name===0){ @@ -354,25 +315,6 @@ var LibraryEmVal = { var types = __emval_lookupTypes(argCount, argTypes); var retType = types[0]; -#if NO_DYNAMIC_EXECUTION - var argN = new Array(argCount - 1); - var invokerFunction = function(handle, name, destructors, args) { - var offset = 0; - for (var i = 0; i < argCount - 1; ++i) { - argN[i] = types[i + 1].readValueFromPointer(args + offset); - offset += types[i + 1].argPackAdvance; - } - var rv = handle[name].apply(handle, argN); - for (var i = 0; i < argCount - 1; ++i) { - if (types[i + 1].deleteObject) { - types[i + 1].deleteObject(argN[i]); - } - } - if (!retType.isVoid) { - return retType.toWireType(destructors, rv); - } - }; -#else var signatureName = retType.name + "_$" + types.slice(1).map(function (t) { return t.name; }).join("_") + "$"; var params = ["retType"]; @@ -412,7 +354,6 @@ var LibraryEmVal = { params.push(functionBody); var invokerFunction = new_(Function, params).apply(null, args); -#endif return __emval_addMethodCaller(invokerFunction); }, From 72827426574467784a315ec980547ba814508c77 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Dec 2018 17:46:23 -0800 Subject: [PATCH 3/8] use our new preprocessing superpowers --- src/compiler.js | 4 ---- src/library_browser.js | 2 +- src/library_gl.js | 10 +++++----- src/library_vr.js | 2 +- src/support.js | 12 ++++++------ 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/src/compiler.js b/src/compiler.js index 3b0e8ecf3a697..424e9b3205885 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -169,10 +169,6 @@ EXPORTED_FUNCTIONS = set(EXPORTED_FUNCTIONS); EXCEPTION_CATCHING_WHITELIST = set(EXCEPTION_CATCHING_WHITELIST); IMPLEMENTED_FUNCTIONS = set(IMPLEMENTED_FUNCTIONS); -// TODO: Implement support for proper preprocessing, e.g. "#if A || B" and "#if defined(A) || defined(B)" to -// avoid needing this here. -USES_GL_EMULATION = FULL_ES2 || LEGACY_GL_EMULATION; - DEAD_FUNCTIONS.forEach(function(dead) { DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.push(dead.substr(1)); }); diff --git a/src/library_browser.js b/src/library_browser.js index 1dd1fcfc104c3..4c2176763f3f5 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -1188,7 +1188,7 @@ var LibraryBrowser = { // Signal GL rendering layer that processing of a new frame is about to start. This helps it optimize // VBO double-buffering and reduce GPU stalls. -#if USES_GL_EMULATION +#if FULL_ES2 || LEGACY_GL_EMULATION GL.newRenderingFrameStarted(); #endif diff --git a/src/library_gl.js b/src/library_gl.js index 4e42f472908c7..83d3b006efe0d 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -40,7 +40,7 @@ var LibraryGL = { syncs: [], #endif -#if USES_GL_EMULATION +#if FULL_ES2 || LEGACY_GL_EMULATION currArrayBuffer: 0, currElementArrayBuffer: 0, #endif @@ -77,7 +77,7 @@ var LibraryGL = { unpackAlignment: 4, // default alignment is 4 bytes init: function() { -#if USES_GL_EMULATION +#if FULL_ES2 || LEGACY_GL_EMULATION GL.createLog2ceilLookup(GL.MAX_TEMP_BUFFER_SIZE); #endif GL.miniTempBuffer = new Float32Array(GL.MINI_TEMP_BUFFER_SIZE); @@ -113,7 +113,7 @@ var LibraryGL = { miniTempBuffer: null, miniTempBufferViews: [0], // index i has the view of size i+1 -#if USES_GL_EMULATION +#if FULL_ES2 || LEGACY_GL_EMULATION // When user GL code wants to render from client-side memory, we need to upload the vertex data to a temp VBO // for rendering. Maintain a set of temp VBOs that are created-on-demand to appropriate sizes, and never destroyed. // Also, for best performance the VBOs are double-buffered, i.e. every second frame we switch the set of VBOs we @@ -3642,7 +3642,7 @@ var LibraryGL = { #endif var bufferObj = buffer ? GL.buffers[buffer] : null; -#if USES_GL_EMULATION +#if FULL_ES2 || LEGACY_GL_EMULATION if (target == GLctx.ARRAY_BUFFER) { GL.currArrayBuffer = buffer; #if LEGACY_GL_EMULATION @@ -4282,7 +4282,7 @@ var LibraryGL = { #endif GLctx['bindVertexArray'](GL.vaos[vao]); #endif -#if USES_GL_EMULATION +#if FULL_ES2 || LEGACY_GL_EMULATION var ibo = GLctx.getParameter(GLctx.ELEMENT_ARRAY_BUFFER_BINDING); GL.currElementArrayBuffer = ibo ? (ibo.name | 0) : 0; #endif diff --git a/src/library_vr.js b/src/library_vr.js index b1811ae651cab..1dd29cadbc2f9 100644 --- a/src/library_vr.js +++ b/src/library_vr.js @@ -195,7 +195,7 @@ var LibraryWebVR = { /* Prevent scheduler being called twice when loop is changed */ display.mainLoop.running = true; -#if USES_GL_EMULATION +#if FULL_ES2 || LEGACY_GL_EMULATION GL.newRenderingFrameStarted(); #endif diff --git a/src/support.js b/src/support.js index 0c857d0d11db7..532e2e1da24b2 100644 --- a/src/support.js +++ b/src/support.js @@ -603,15 +603,15 @@ Module['registerFunctions'] = registerFunctions; #endif // RELOCATABLE #endif // EMULATED_FUNCTION_POINTERS -#if WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS +#if WASM_BACKEND && RESERVED_FUNCTION_POINTERS var jsCallStartIndex = {{{ JSCALL_START_INDEX }}}; var jsCallSigOrder = {{{ JSON.stringify(JSCALL_SIG_ORDER) }}}; var jsCallNumSigs = Object.keys(jsCallSigOrder).length; var functionPointers = new Array(jsCallNumSigs * {{{ RESERVED_FUNCTION_POINTERS }}}); -#else // WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS == 0 +#else // WASM_BACKEND && RESERVED_FUNCTION_POINTERS == 0 var jsCallStartIndex = 1; var functionPointers = new Array({{{ RESERVED_FUNCTION_POINTERS }}}); -#endif // WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS +#endif // WASM_BACKEND && RESERVED_FUNCTION_POINTERS // 'sig' parameter is only used on LLVM wasm backend function addFunction(func, sig) { @@ -626,11 +626,11 @@ function addFunction(func, sig) { } #endif // ASSERTIONS #if EMULATED_FUNCTION_POINTERS == 0 -#if WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS +#if WASM_BACKEND && RESERVED_FUNCTION_POINTERS var base = jsCallSigOrder[sig] * {{{ RESERVED_FUNCTION_POINTERS }}}; -#else // WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS == 0 +#else // WASM_BACKEND && RESERVED_FUNCTION_POINTERS == 0 var base = 0; -#endif // WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS +#endif // WASM_BACKEND && RESERVED_FUNCTION_POINTERS for (var i = base; i < base + {{{ RESERVED_FUNCTION_POINTERS }}}; i++) { if (!functionPointers[i]) { functionPointers[i] = func; From 1071cd5372c1197b34a1e8579d18dfe3353ab602 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Tue, 11 Dec 2018 17:54:11 -0800 Subject: [PATCH 4/8] cleanup --- src/modules.js | 1 - src/parseTools.js | 3 --- 2 files changed, 4 deletions(-) diff --git a/src/modules.js b/src/modules.js index 20f0c2781d74c..18c7bf9b5ce07 100644 --- a/src/modules.js +++ b/src/modules.js @@ -100,7 +100,6 @@ var LibraryManager = { libraries: [], has: function(name) { -//printErr(['has?', name, this.libraries.length, this.libraries.indexOf(name), this.libraries]); return this.libraries.indexOf(name) >= 0; }, diff --git a/src/parseTools.js b/src/parseTools.js index d7e6f234e08b3..8700db430c3cd 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -41,12 +41,9 @@ function preprocess(text, filenameHint) { } else { if (line[1] == 'i') { if (line[2] == 'f') { // if -//printErr(line); var parts = line.split(' '); var after = parts.slice(1).join(' '); -//printErr('-> ' + after); var truthy = !!eval(after); -//printErr('===> ' + !!truthy); showStack.push(truthy); } else if (line[2] == 'n') { // include var filename = line.substr(line.indexOf(' ')+1); From 859af3dd55dea5697fd413094181ad50415b4cd1 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 12 Dec 2018 08:59:40 -0800 Subject: [PATCH 5/8] undo embind changes, they were wrong --- src/embind/embind.js | 72 ++++++++++++++++++++++++++++++++++++++++++++ src/embind/emval.js | 59 ++++++++++++++++++++++++++++++++++++ 2 files changed, 131 insertions(+) diff --git a/src/embind/embind.js b/src/embind/embind.js index eb69c7a1ff7f6..39e28182d47f3 100644 --- a/src/embind/embind.js +++ b/src/embind/embind.js @@ -50,6 +50,11 @@ var LibraryEmbind = { Module['flushPendingDeletes'] = flushPendingDeletes; Module['setDelayFunction'] = setDelayFunction; #if IN_TEST_HARNESS +#if NO_DYNAMIC_EXECUTION + // Without dynamic execution, dynamically created functions will have no + // names. This lets the test suite know that. + Module['NO_DYNAMIC_EXECUTION'] = true; +#endif #if EMBIND_STD_STRING_IS_UTF8 Module['EMBIND_STD_STRING_IS_UTF8'] = true; #endif @@ -189,6 +194,12 @@ var LibraryEmbind = { $createNamedFunction__deps: ['$makeLegalFunctionName'], $createNamedFunction: function(name, body) { name = makeLegalFunctionName(name); +#if NO_DYNAMIC_EXECUTION + return function() { + "use strict"; + return body.apply(this, arguments); + }; +#else /*jshint evil:true*/ return new Function( "body", @@ -197,6 +208,7 @@ var LibraryEmbind = { " return body.apply(this, arguments);\n" + "};\n" )(body); +#endif }, embind_repr: function(v) { @@ -835,6 +847,11 @@ var LibraryEmbind = { if (!(constructor instanceof Function)) { throw new TypeError('new_ called with constructor type ' + typeof(constructor) + " which is not a function"); } +#if NO_DYNAMIC_EXECUTION + if (constructor === Function) { + throw new Error('new_ cannot create a new Function with NO_DYNAMIC_EXECUTION.'); + } +#endif /* * Previously, the following line was just: @@ -896,6 +913,49 @@ var LibraryEmbind = { var returns = (argTypes[0].name !== "void"); +#if NO_DYNAMIC_EXECUTION + var argsWired = new Array(argCount - 2); + return function() { + if (arguments.length !== argCount - 2) { + throwBindingError('function ' + humanName + ' called with ' + arguments.length + ' arguments, expected ' + (argCount - 2) + ' args!'); + } +#if EMSCRIPTEN_TRACING + Module.emscripten_trace_enter_context('embind::' + humanName); +#endif + var destructors = needsDestructorStack ? [] : null; + var thisWired; + if (isClassMethodFunc) { + thisWired = argTypes[1].toWireType(destructors, this); + } + for (var i = 0; i < argCount - 2; ++i) { + argsWired[i] = argTypes[i + 2].toWireType(destructors, arguments[i]); + } + + var invokerFuncArgs = isClassMethodFunc ? + [cppTargetFunc, thisWired] : [cppTargetFunc]; + + var rv = cppInvokerFunc.apply(null, invokerFuncArgs.concat(argsWired)); + + if (needsDestructorStack) { + runDestructors(destructors); + } else { + for (var i = isClassMethodFunc ? 1 : 2; i < argTypes.length; i++) { + var param = i === 1 ? thisWired : argsWired[i - 2]; + if (argTypes[i].destructorFunction !== null) { + argTypes[i].destructorFunction(param); + } + } + } + +#if EMSCRIPTEN_TRACING + Module.emscripten_trace_exit_context(); +#endif + + if (returns) { + return argTypes[0].fromWireType(rv); + } + }; +#else var argsList = ""; var argsListWired = ""; for(var i = 0; i < argCount - 2; ++i) { @@ -974,6 +1034,7 @@ var LibraryEmbind = { var invokerFunction = new_(Function, args1).apply(null, args2); return invokerFunction; +#endif }, $embind__requireFunction__deps: ['$readLatin1String', '$throwBindingError'], @@ -981,6 +1042,16 @@ var LibraryEmbind = { signature = readLatin1String(signature); function makeDynCaller(dynCall) { +#if NO_DYNAMIC_EXECUTION + return function() { + var args = new Array(arguments.length + 1); + args[0] = rawFunction; + for (var i = 0; i < arguments.length; i++) { + args[i + 1] = arguments[i]; + } + return dynCall.apply(null, args); + }; +#else var args = []; for (var i = 1; i < signature.length; ++i) { args.push('a' + i); @@ -992,6 +1063,7 @@ var LibraryEmbind = { body += '};\n'; return (new Function('dynCall', 'rawFunction', body))(dynCall, rawFunction); +#endif } var fp; diff --git a/src/embind/emval.js b/src/embind/emval.js index ab200d1956617..c0267475a926c 100644 --- a/src/embind/emval.js +++ b/src/embind/emval.js @@ -151,6 +151,19 @@ var LibraryEmVal = { var obj = new constructor(arg0, arg1, arg2); return __emval_register(obj); } */ +#if NO_DYNAMIC_EXECUTION + var argsList = new Array(argCount + 1); + return function(constructor, argTypes, args) { + argsList[0] = constructor; + for (var i = 0; i < argCount; ++i) { + var argType = requireRegisteredType(HEAP32[(argTypes >> 2) + i], 'parameter ' + i); + argsList[i + 1] = argType.readValueFromPointer(args); + args += argType.argPackAdvance; + } + var obj = new (constructor.bind.apply(constructor, argsList)); + return __emval_register(obj); + }; +#else var argsList = ""; for(var i = 0; i < argCount; ++i) { argsList += (i!==0?", ":"")+"arg"+i; // 'arg0, arg1, ..., argn' @@ -173,6 +186,7 @@ var LibraryEmVal = { /*jshint evil:true*/ return (new Function("requireRegisteredType", "Module", "__emval_register", functionBody))( requireRegisteredType, Module, __emval_register); +#endif }, _emval_new__deps: ['$craftEmvalAllocator', '$emval_newers', '$requireHandle'], @@ -188,8 +202,33 @@ var LibraryEmVal = { return newer(handle, argTypes, args); }, +#if NO_DYNAMIC_EXECUTION + $emval_get_global: function() { + function testGlobal(obj) { + obj['$$$embind_global$$$'] = obj; + var success = typeof $$$embind_global$$$ === 'object' && obj['$$$embind_global$$$'] === obj; + if (!success) { + delete obj['$$$embind_global$$$']; + } + return success; + } + if (typeof $$$embind_global$$$ === 'object') { + return $$$embind_global$$$; + } + if (typeof global === 'object' && testGlobal(global)) { + $$$embind_global$$$ = global; + } else if (typeof window === 'object' && testGlobal(window)) { + $$$embind_global$$$ = window; + } + if (typeof $$$embind_global$$$ === 'object') { + return $$$embind_global$$$; + } + throw Error('unable to get global object.'); + }, +#else // appease jshint (technically this code uses eval) $emval_get_global: function() { return (function(){return Function;})()('return this')(); }, +#endif _emval_get_global__deps: ['_emval_register', '$getStringOrSymbol', '$emval_get_global'], _emval_get_global: function(name) { if(name===0){ @@ -315,6 +354,25 @@ var LibraryEmVal = { var types = __emval_lookupTypes(argCount, argTypes); var retType = types[0]; +#if NO_DYNAMIC_EXECUTION + var argN = new Array(argCount - 1); + var invokerFunction = function(handle, name, destructors, args) { + var offset = 0; + for (var i = 0; i < argCount - 1; ++i) { + argN[i] = types[i + 1].readValueFromPointer(args + offset); + offset += types[i + 1].argPackAdvance; + } + var rv = handle[name].apply(handle, argN); + for (var i = 0; i < argCount - 1; ++i) { + if (types[i + 1].deleteObject) { + types[i + 1].deleteObject(argN[i]); + } + } + if (!retType.isVoid) { + return retType.toWireType(destructors, rv); + } + }; +#else var signatureName = retType.name + "_$" + types.slice(1).map(function (t) { return t.name; }).join("_") + "$"; var params = ["retType"]; @@ -354,6 +412,7 @@ var LibraryEmVal = { params.push(functionBody); var invokerFunction = new_(Function, params).apply(null, args); +#endif return __emval_addMethodCaller(invokerFunction); }, From 139d54587a16d25ea9312adeb523f422dce079bb Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 12 Dec 2018 09:00:46 -0800 Subject: [PATCH 6/8] [ci skip] --- src/jsifier.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/jsifier.js b/src/jsifier.js index 9605cb063ff97..c11c8f3aa380d 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -42,9 +42,6 @@ var NEED_ALL_ASM2WASM_IMPORTS = BINARYEN_METHOD != 'native-wasm' || BINARYEN_TRA // the current compilation unit. var HAS_MAIN = ('_main' in IMPLEMENTED_FUNCTIONS) || MAIN_MODULE || SIDE_MODULE; -var WASM_BACKEND_WITH_RESERVED_FUNCTION_POINTERS = - WASM_BACKEND && RESERVED_FUNCTION_POINTERS; - // JSifier function JSify(data, functionsOnly) { var mainPass = !functionsOnly; From 704502f3da8b36eb6eb09508301277fb89a31218 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 12 Dec 2018 13:53:23 -0800 Subject: [PATCH 7/8] temporary workaround --- src/parseTools.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/parseTools.js b/src/parseTools.js index 8700db430c3cd..504d0a070c716 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -43,6 +43,10 @@ function preprocess(text, filenameHint) { if (line[2] == 'f') { // if var parts = line.split(' '); var after = parts.slice(1).join(' '); + // FIXME: temporary workaround for embind preprocessing issue that will be fixed by https://github.com/kripken/emscripten/pull/7653 + if (after === 'NO_DYNAMIC_EXECUTION') { + after = 'DYNAMIC_EXECUTION == 0'; + } var truthy = !!eval(after); showStack.push(truthy); } else if (line[2] == 'n') { // include From a886cf498359c6ae8a89c52fcf5a2ac3968bf450 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Wed, 12 Dec 2018 16:03:08 -0800 Subject: [PATCH 8/8] Revert "temporary workaround" This reverts commit 704502f3da8b36eb6eb09508301277fb89a31218. --- src/parseTools.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/parseTools.js b/src/parseTools.js index 504d0a070c716..8700db430c3cd 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -43,10 +43,6 @@ function preprocess(text, filenameHint) { if (line[2] == 'f') { // if var parts = line.split(' '); var after = parts.slice(1).join(' '); - // FIXME: temporary workaround for embind preprocessing issue that will be fixed by https://github.com/kripken/emscripten/pull/7653 - if (after === 'NO_DYNAMIC_EXECUTION') { - after = 'DYNAMIC_EXECUTION == 0'; - } var truthy = !!eval(after); showStack.push(truthy); } else if (line[2] == 'n') { // include