aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS4
-rwxr-xr-xemcc16
-rw-r--r--emscripten-version.txt2
-rwxr-xr-xemscripten.py61
-rw-r--r--src/embind/embind.js130
-rw-r--r--src/library.js38
-rw-r--r--src/library_browser.js71
-rw-r--r--src/library_fs.js63
-rw-r--r--src/library_glfw.js2
-rw-r--r--src/library_sdl.js1
-rw-r--r--src/parseTools.js11
-rw-r--r--src/preamble.js20
-rw-r--r--src/relooper/Relooper.cpp11
-rw-r--r--src/settings.js11
-rw-r--r--src/shell.html7
-rw-r--r--src/shell_minimal.html7
-rw-r--r--system/include/emscripten/bind.h305
-rw-r--r--system/include/emscripten/emscripten.h8
-rw-r--r--system/lib/embind/bind.cpp1
-rw-r--r--tests/cases/redundantswitch_fastcomp.ll28
-rw-r--r--tests/cases/redundantswitch_fastcomp.txt2
-rw-r--r--tests/core/test_polymorph.in8
-rw-r--r--tests/core/test_polymorph.out4
-rw-r--r--tests/core/test_sscanf_hex.in24
-rw-r--r--tests/core/test_sscanf_hex.out3
-rw-r--r--tests/core/test_strptime_tm.in31
-rw-r--r--tests/core/test_strptime_tm.out19
-rw-r--r--tests/embind/embind.test.js15
-rw-r--r--tests/embind/embind_test.cpp5
-rw-r--r--tests/embind/imvu_test_adapter.js6
-rw-r--r--tests/fs/test_trackingdelegate.c39
-rw-r--r--tests/fs/test_trackingdelegate.out9
-rw-r--r--tests/fs/test_writeFile.cc43
-rw-r--r--tests/fs/test_writeFile.out3
-rw-r--r--tests/fuzz/20.cpp977
-rw-r--r--tests/fuzz/20.cpp.txt1
-rw-r--r--tests/fuzz/21.c2332
-rw-r--r--tests/fuzz/21.c.txt1
-rw-r--r--tests/test_browser.py4
-rw-r--r--tests/test_core.py35
-rw-r--r--tests/test_other.py117
-rw-r--r--tests/webidl/output.txt56
-rw-r--r--tests/webidl/post.js117
-rw-r--r--tests/webidl/test.cpp8
-rw-r--r--tests/webidl/test.h72
-rw-r--r--tests/webidl/test.idl64
-rw-r--r--third_party/WebIDL.py5030
-rw-r--r--third_party/__init__.py2
-rwxr-xr-xtools/bindings_generator.py55
-rwxr-xr-xtools/ffdb.py342
-rw-r--r--tools/js-optimizer.js121
-rw-r--r--tools/jsrun.py9
-rw-r--r--tools/shared.py9
-rw-r--r--tools/test-js-optimizer-asm-pre-f32.js8
-rw-r--r--tools/test-js-optimizer-asm-pre-output-f32.js8
-rw-r--r--tools/webidl_binder.py432
56 files changed, 10500 insertions, 308 deletions
diff --git a/AUTHORS b/AUTHORS
index e0038c77..7994f80e 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -136,5 +136,5 @@ a license to everyone to use it as detailed in LICENSE.)
* Thomas Borsos <thomasborsos@gmail.com>
* Ori Avtalion <ori@avtalion.name>
* Guillaume Blanc <guillaumeblanc.sc@gmail.com>
-
-
+* Usagi Ito <usagi@WonderRabbitProject.net>
+* Camilo Polymeris <cpolymeris@gmail.com>
diff --git a/emcc b/emcc
index c8e1814b..1629f5c7 100755
--- a/emcc
+++ b/emcc
@@ -1224,11 +1224,6 @@ try:
value = value.replace('\\\\', '/').replace('\\', '/') # Convert backslash paths to forward slashes on Windows as well, since the JS compiler otherwise needs the backslashes escaped (alternative is to escape all input paths passing to JS, which feels clumsier to read)
exec('shared.Settings.' + key + ' = ' + value)
- # Apply effects from settings
- if bind and shared.Settings.ASM_JS:
- logging.warning('disabling asm.js since embind is not ready for it yet')
- shared.Settings.ASM_JS = 0
-
fastcomp = os.environ.get('EMCC_FAST_COMPILER') != '0'
if fastcomp:
@@ -1245,7 +1240,6 @@ try:
assert shared.Settings.TARGET_ASMJS_UNKNOWN_EMSCRIPTEN == 1, 'fastcomp requires asmjs-unknown-emscripten'
assert shared.Settings.USE_TYPED_ARRAYS == 2, 'fastcomp assumes ta2'
assert not split_js_file, '--split-js is deprecated and not supported in fastcomp'
- assert not bind, 'embind not supported in fastcomp yet'
assert shared.Settings.MAX_SETJMPS == 20, 'changing MAX_SETJMPS is not supported in fastcomp yet'
assert shared.Settings.INIT_HEAP == 0, 'HEAP_INIT is not supported in fastcomp (and should never be needed except for debugging)'
assert not shared.Settings.RUNTIME_TYPE_INFO, 'RUNTIME_TYPE_INFO is not supported in fastcomp'
@@ -1372,9 +1366,11 @@ try:
for header in input_files:
assert header.endswith(HEADER_ENDINGS), 'if you have one header input, we assume you want to precompile headers, and cannot have source files or other inputs as well: ' + str(input_files) + ' : ' + header
args = newargs + shared.EMSDK_CXX_OPTS + input_files
- logging.debug("running (for precompiled headers: " + call + ' ' + ' '.join(args))
+ if specified_target:
+ args += ['-o', specified_target]
+ logging.debug("running (for precompiled headers): " + call + ' ' + ' '.join(args))
execute([call] + args) # let compiler frontend print directly, so colors are saved (PIPE kills that)
- sys.exit(1)
+ sys.exit(0)
def get_bitcode_file(input_file):
if final_suffix not in JS_CONTAINING_SUFFIXES:
@@ -1731,7 +1727,7 @@ try:
# with commaified code breaks late aggressive variable elimination)
if shared.Settings.SIMPLIFY_IFS and (debug_level == 0 or profiling) and shared.Settings.OUTLINING_LIMIT == 0: js_optimizer_queue += ['simplifyIfs']
- if opt_level >= 3 and shared.Settings.PRECISE_F32: js_optimizer_queue += ['optimizeFrounds']
+ if shared.Settings.PRECISE_F32: js_optimizer_queue += ['optimizeFrounds']
if closure and not shared.Settings.ASM_JS:
flush_js_optimizer_queue()
@@ -1750,7 +1746,7 @@ try:
js_optimizer_extra_info['sizeToOutline'] = shared.Settings.OUTLINING_LIMIT
if opt_level >= 2 and (not closure or shared.Settings.ASM_JS) and shared.Settings.RELOOP and debug_level < 3:
- if shared.Settings.ASM_JS and opt_level >= 3 and shared.Settings.OUTLINING_LIMIT == 0:
+ if shared.Settings.ASM_JS and opt_level >= 3:
js_optimizer_queue += ['registerizeHarder']
else:
js_optimizer_queue += ['registerize']
diff --git a/emscripten-version.txt b/emscripten-version.txt
index f488f67e..f9505a5c 100644
--- a/emscripten-version.txt
+++ b/emscripten-version.txt
@@ -1,2 +1,2 @@
-1.16.0
+1.17.0
diff --git a/emscripten.py b/emscripten.py
index 94c6b61c..e2aef648 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -455,7 +455,7 @@ def emscript(infile, settings, outfile, libraries=[], compiler_engine=None,
basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
- if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE']
+ if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_FT_MASK']
if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8']
if settings['ASSERTIONS']:
basic_funcs += ['nullFunc']
@@ -584,7 +584,7 @@ var asm = (function(global, env, buffer) {
var undef = 0;
var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
''' + ''.join(['''
- var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ['''
+ var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ([' const f0 = Math_fround(0);\n'] if settings.get('PRECISE_F32') else []) + ['''
// EMSCRIPTEN_START_FUNCS
function stackAlloc(size) {
size = size|0;
@@ -611,21 +611,21 @@ function setThrew(threw, value) {
}
function copyTempFloat(ptr) {
ptr = ptr|0;
- HEAP8[tempDoublePtr] = HEAP8[ptr];
- HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
- HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
- HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
+ HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0];
+ HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0];
+ HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0];
+ HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0];
}
function copyTempDouble(ptr) {
ptr = ptr|0;
- HEAP8[tempDoublePtr] = HEAP8[ptr];
- HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
- HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
- HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
- HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0];
- HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0];
- HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0];
- HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0];
+ HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0];
+ HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0];
+ HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0];
+ HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0];
+ HEAP8[tempDoublePtr+4>>0] = HEAP8[ptr+4>>0];
+ HEAP8[tempDoublePtr+5>>0] = HEAP8[ptr+5>>0];
+ HEAP8[tempDoublePtr+6>>0] = HEAP8[ptr+6>>0];
+ HEAP8[tempDoublePtr+7>>0] = HEAP8[ptr+7>>0];
}
''' + ''.join(['''
function setTempRet%d(value) {
@@ -754,6 +754,8 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
backend_args += ['-emscripten-reserved-function-pointers=%d' % settings['RESERVED_FUNCTION_POINTERS']]
if settings['ASSERTIONS'] > 0:
backend_args += ['-emscripten-assertions=%d' % settings['ASSERTIONS']]
+ if settings['ALIASING_FUNCTION_POINTERS'] == 0:
+ backend_args += ['-emscripten-no-aliasing-function-pointers']
backend_args += ['-O' + str(settings['OPT_LEVEL'])]
if DEBUG:
logging.debug('emscript: llvm backend: ' + ' '.join(backend_args))
@@ -1009,7 +1011,7 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
basic_funcs = ['abort', 'assert', 'asmPrintInt', 'asmPrintFloat'] + [m.replace('.', '_') for m in math_envs]
if settings['RESERVED_FUNCTION_POINTERS'] > 0: basic_funcs.append('jsCall')
- if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE']
+ if settings['SAFE_HEAP']: basic_funcs += ['SAFE_HEAP_LOAD', 'SAFE_HEAP_STORE', 'SAFE_FT_MASK']
if settings['CHECK_HEAP_ALIGN']: basic_funcs += ['CHECK_ALIGN_2', 'CHECK_ALIGN_4', 'CHECK_ALIGN_8']
if settings['ASSERTIONS']:
if settings['ASSERTIONS'] >= 2: import difflib
@@ -1080,8 +1082,9 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
}
''' % (sig, ',' if len(sig) > 1 else '', args, arg_coercions, ret))
+ ffi_args = ','.join([shared.JS.make_coercion('a' + str(i), sig[i], settings, ffi_arg=True) for i in range(1, len(sig))])
for i in range(settings['RESERVED_FUNCTION_POINTERS']):
- jsret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('jsCall(%d%s%s)' % (i, ',' if coerced_args else '', coerced_args), sig[0], settings)
+ jsret = ('return ' if sig[0] != 'v' else '') + shared.JS.make_coercion('jsCall(%d%s%s)' % (i, ',' if ffi_args else '', ffi_args), sig[0], settings, ffi_result=True)
function_tables_impls.append('''
function jsCall_%s_%s(%s) {
%s
@@ -1168,7 +1171,7 @@ var asm = (function(global, env, buffer) {
var nan = +env.NaN, inf = +env.Infinity;
var tempInt = 0, tempBigInt = 0, tempBigIntP = 0, tempBigIntS = 0, tempBigIntR = 0.0, tempBigIntI = 0, tempBigIntD = 0, tempValue = 0, tempDouble = 0.0;
''' + ''.join(['''
- var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ['''
+ var tempRet%d = 0;''' % i for i in range(10)]) + '\n' + asm_global_funcs] + [' var tempFloat = %s;\n' % ('Math_fround(0)' if settings.get('PRECISE_F32') else '0.0')] + ([' const f0 = Math_fround(0);\n'] if settings.get('PRECISE_F32') else []) + ['''
// EMSCRIPTEN_START_FUNCS
function stackAlloc(size) {
size = size|0;
@@ -1195,21 +1198,21 @@ function setThrew(threw, value) {
}
function copyTempFloat(ptr) {
ptr = ptr|0;
- HEAP8[tempDoublePtr] = HEAP8[ptr];
- HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
- HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
- HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
+ HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0];
+ HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0];
+ HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0];
+ HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0];
}
function copyTempDouble(ptr) {
ptr = ptr|0;
- HEAP8[tempDoublePtr] = HEAP8[ptr];
- HEAP8[tempDoublePtr+1|0] = HEAP8[ptr+1|0];
- HEAP8[tempDoublePtr+2|0] = HEAP8[ptr+2|0];
- HEAP8[tempDoublePtr+3|0] = HEAP8[ptr+3|0];
- HEAP8[tempDoublePtr+4|0] = HEAP8[ptr+4|0];
- HEAP8[tempDoublePtr+5|0] = HEAP8[ptr+5|0];
- HEAP8[tempDoublePtr+6|0] = HEAP8[ptr+6|0];
- HEAP8[tempDoublePtr+7|0] = HEAP8[ptr+7|0];
+ HEAP8[tempDoublePtr>>0] = HEAP8[ptr>>0];
+ HEAP8[tempDoublePtr+1>>0] = HEAP8[ptr+1>>0];
+ HEAP8[tempDoublePtr+2>>0] = HEAP8[ptr+2>>0];
+ HEAP8[tempDoublePtr+3>>0] = HEAP8[ptr+3>>0];
+ HEAP8[tempDoublePtr+4>>0] = HEAP8[ptr+4>>0];
+ HEAP8[tempDoublePtr+5>>0] = HEAP8[ptr+5>>0];
+ HEAP8[tempDoublePtr+6>>0] = HEAP8[ptr+6>>0];
+ HEAP8[tempDoublePtr+7>>0] = HEAP8[ptr+7>>0];
}
function setTempRet0(value) {
value = value|0;
diff --git a/src/embind/embind.js b/src/embind/embind.js
index 6ec07cd9..4821c77b 100644
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -1,4 +1,4 @@
-/*global Module*/
+/*global Module, asm*/
/*global _malloc, _free, _memcpy*/
/*global FUNCTION_TABLE, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32, HEAPF32, HEAPF64*/
/*global readLatin1String*/
@@ -622,10 +622,6 @@ function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cp
var isClassMethodFunc = (argTypes[1] !== null && classType !== null);
- if (!isClassMethodFunc && !FUNCTION_TABLE[cppTargetFunc]) {
- throwBindingError('Global function '+humanName+' is not defined!');
- }
-
// Free functions with signature "void function()" do not need an invoker that marshalls between wire types.
// TODO: This omits argument count check - enable only at -O3 or similar.
// if (ENABLE_UNSAFE_OPTS && argCount == 2 && argTypes[0].name == "void" && !isClassMethodFunc) {
@@ -662,8 +658,8 @@ function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cp
}
var dtorStack = needsDestructorStack ? "destructors" : "null";
- var args1 = ["throwBindingError", "classType", "invoker", "fn", "runDestructors", "retType", "classParam"];
- var args2 = [throwBindingError, classType, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]];
+ var args1 = ["throwBindingError", "invoker", "fn", "runDestructors", "retType", "classParam"];
+ var args2 = [throwBindingError, cppInvokerFunc, cppTargetFunc, runDestructors, argTypes[0], argTypes[1]];
if (isClassMethodFunc) {
invokerFnBody += "var thisWired = classParam.toWireType("+dtorStack+", this);\n";
@@ -708,10 +704,50 @@ function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cp
return invokerFunction;
}
-function __embind_register_function(name, argCount, rawArgTypesAddr, rawInvoker, fn) {
+function requireFunction(signature, rawFunction) {
+ signature = readLatin1String(signature);
+ var fp;
+ // asm.js does not define FUNCTION_TABLE
+ if (typeof FUNCTION_TABLE === "undefined") {
+ // asm.js does not give direct access to the function tables,
+ // and thus we must go through the dynCall interface which allows
+ // calling into a signature's function table by pointer value.
+ //
+ // https://github.com/dherman/asm.js/issues/83
+ //
+ // This has three main penalties:
+ // - dynCall is another function call in the path from JavaScript to C++.
+ // - JITs may not predict through the function table indirection at runtime.
+ // - Function.prototype.bind generally benchmarks poorly relative to
+ // function objects, but using 'arguments' would confound JITs and
+ // possibly allocate.
+ var dc = asm['dynCall_' + signature];
+ if (dc === undefined) {
+ // We will always enter this branch if the signature
+ // contains 'f' and PRECISE_F32 is not enabled.
+ //
+ // Try again, replacing 'f' with 'd'.
+ dc = asm['dynCall_' + signature.replace(/f/g, 'd')];
+ if (dc === undefined) {
+ throwBindingError("No dynCall invoker for signature: " + signature);
+ }
+ }
+ fp = dc.bind(undefined, rawFunction);
+ } else {
+ fp = FUNCTION_TABLE[rawFunction];
+ }
+
+ if (typeof fp !== "function") {
+ throwBindingError("unknown function pointer with signature " + signature + ": " + rawFunction);
+ }
+ return fp;
+}
+
+function __embind_register_function(name, argCount, rawArgTypesAddr, signature, rawInvoker, fn) {
var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
name = readLatin1String(name);
- rawInvoker = FUNCTION_TABLE[rawInvoker];
+
+ rawInvoker = requireFunction(signature, rawInvoker);
exposePublicSymbol(name, function() {
throwUnboundTypeError('Cannot call ' + name + ' due to unbound types', argTypes);
@@ -726,11 +762,11 @@ function __embind_register_function(name, argCount, rawArgTypesAddr, rawInvoker,
var tupleRegistrations = {};
-function __embind_register_value_array(rawType, name, rawConstructor, rawDestructor) {
+function __embind_register_value_array(rawType, name, constructorSignature, rawConstructor, destructorSignature, rawDestructor) {
tupleRegistrations[rawType] = {
name: readLatin1String(name),
- rawConstructor: FUNCTION_TABLE[rawConstructor],
- rawDestructor: FUNCTION_TABLE[rawDestructor],
+ rawConstructor: requireFunction(constructorSignature, rawConstructor),
+ rawDestructor: requireFunction(destructorSignature, rawDestructor),
elements: [],
};
}
@@ -738,18 +774,20 @@ function __embind_register_value_array(rawType, name, rawConstructor, rawDestruc
function __embind_register_value_array_element(
rawTupleType,
getterReturnType,
+ getterSignature,
getter,
getterContext,
setterArgumentType,
+ setterSignature,
setter,
setterContext
) {
tupleRegistrations[rawTupleType].elements.push({
getterReturnType: getterReturnType,
- getter: FUNCTION_TABLE[getter],
+ getter: requireFunction(getterSignature, getter),
getterContext: getterContext,
setterArgumentType: setterArgumentType,
- setter: FUNCTION_TABLE[setter],
+ setter: requireFunction(setterSignature, setter),
setterContext: setterContext,
});
}
@@ -818,13 +856,15 @@ var structRegistrations = {};
function __embind_register_value_object(
rawType,
name,
+ constructorSignature,
rawConstructor,
+ destructorSignature,
rawDestructor
) {
structRegistrations[rawType] = {
name: readLatin1String(name),
- rawConstructor: FUNCTION_TABLE[rawConstructor],
- rawDestructor: FUNCTION_TABLE[rawDestructor],
+ rawConstructor: requireFunction(constructorSignature, rawConstructor),
+ rawDestructor: requireFunction(destructorSignature, rawDestructor),
fields: [],
};
}
@@ -833,19 +873,21 @@ function __embind_register_value_object_field(
structType,
fieldName,
getterReturnType,
+ getterSignature,
getter,
getterContext,
setterArgumentType,
+ setterSignature,
setter,
setterContext
) {
structRegistrations[structType].fields.push({
fieldName: readLatin1String(fieldName),
getterReturnType: getterReturnType,
- getter: FUNCTION_TABLE[getter],
+ getter: requireFunction(getterSignature, getter),
getterContext: getterContext,
setterArgumentType: setterArgumentType,
- setter: FUNCTION_TABLE[setter],
+ setter: requireFunction(setterSignature, setter),
setterContext: setterContext,
});
}
@@ -1324,17 +1366,25 @@ function __embind_register_class(
rawPointerType,
rawConstPointerType,
baseClassRawType,
+ getActualTypeSignature,
getActualType,
+ upcastSignature,
upcast,
+ downcastSignature,
downcast,
name,
+ destructorSignature,
rawDestructor
) {
name = readLatin1String(name);
- rawDestructor = FUNCTION_TABLE[rawDestructor];
- getActualType = FUNCTION_TABLE[getActualType];
- upcast = FUNCTION_TABLE[upcast];
- downcast = FUNCTION_TABLE[downcast];
+ getActualType = requireFunction(getActualTypeSignature, getActualType);
+ if (upcast) {
+ upcast = requireFunction(upcastSignature, upcast);
+ }
+ if (downcast) {
+ downcast = requireFunction(downcastSignature, downcast);
+ }
+ rawDestructor = requireFunction(destructorSignature, rawDestructor);
var legalFunctionName = makeLegalFunctionName(name);
exposePublicSymbol(legalFunctionName, function() {
@@ -1424,11 +1474,12 @@ function __embind_register_class_constructor(
rawClassType,
argCount,
rawArgTypesAddr,
+ invokerSignature,
invoker,
rawConstructor
) {
var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
- invoker = FUNCTION_TABLE[invoker];
+ invoker = requireFunction(invokerSignature, invoker);
whenDependentTypesAreResolved([], [rawClassType], function(classType) {
classType = classType[0];
@@ -1474,9 +1525,12 @@ function downcastPointer(ptr, ptrClass, desiredClass) {
if (undefined === desiredClass.baseClass) {
return null; // no conversion
}
- // O(depth) stack space used
- return desiredClass.downcast(
- downcastPointer(ptr, ptrClass, desiredClass.baseClass));
+
+ var rv = downcastPointer(ptr, ptrClass, desiredClass.baseClass);
+ if (rv === null) {
+ return null;
+ }
+ return desiredClass.downcast(rv);
}
function upcastPointer(ptr, ptrClass, desiredClass) {
@@ -1513,12 +1567,13 @@ function __embind_register_class_function(
methodName,
argCount,
rawArgTypesAddr, // [ReturnType, ThisType, Args...]
+ invokerSignature,
rawInvoker,
context
) {
var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
methodName = readLatin1String(methodName);
- rawInvoker = FUNCTION_TABLE[rawInvoker];
+ rawInvoker = requireFunction(invokerSignature, rawInvoker);
whenDependentTypesAreResolved([], [rawClassType], function(classType) {
classType = classType[0];
@@ -1564,12 +1619,13 @@ function __embind_register_class_class_function(
methodName,
argCount,
rawArgTypesAddr,
+ invokerSignature,
rawInvoker,
fn
) {
var rawArgTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
methodName = readLatin1String(methodName);
- rawInvoker = FUNCTION_TABLE[rawInvoker];
+ rawInvoker = requireFunction(invokerSignature, rawInvoker);
whenDependentTypesAreResolved([], [rawClassType], function(classType) {
classType = classType[0];
var humanName = classType.name + '.' + methodName;
@@ -1609,14 +1665,16 @@ function __embind_register_class_property(
classType,
fieldName,
getterReturnType,
+ getterSignature,
getter,
getterContext,
setterArgumentType,
+ setterSignature,
setter,
setterContext
) {
fieldName = readLatin1String(fieldName);
- getter = FUNCTION_TABLE[getter];
+ getter = requireFunction(getterSignature, getter);
whenDependentTypesAreResolved([], [classType], function(classType) {
classType = classType[0];
@@ -1654,7 +1712,7 @@ function __embind_register_class_property(
};
if (setter) {
- setter = FUNCTION_TABLE[setter];
+ setter = requireFunction(setterSignature, setter);
var setterArgumentType = types[1];
desc.set = function(v) {
var ptr = validateThis(this, classType, humanName + ' setter');
@@ -1689,16 +1747,20 @@ function __embind_register_smart_ptr(
rawPointeeType,
name,
sharingPolicy,
+ get