aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc2
-rwxr-xr-xemscripten.py12
-rw-r--r--src/analyzer.js16
-rwxr-xr-xsrc/embind/embind.js631
-rwxr-xr-xsrc/embind/emval.js60
-rw-r--r--src/jsifier.js60
-rw-r--r--src/library.js63
-rw-r--r--src/library_browser.js6
-rw-r--r--src/library_gl.js8
-rw-r--r--src/preamble.js2
-rw-r--r--src/settings.js1
-rwxr-xr-xsystem/include/emscripten/bind.h192
-rw-r--r--system/include/emscripten/val.h57
-rwxr-xr-xsystem/include/emscripten/wire.h34
-rwxr-xr-xsystem/lib/embind/bind.cpp23
-rw-r--r--tests/cases/legalizer_ta2.ll1
-rw-r--r--tests/cases/longjmp_tiny.ll (renamed from tests/cases/longjmp_tiny_noasm.ll)0
-rw-r--r--tests/cases/longjmp_tiny.txt (renamed from tests/cases/longjmp_tiny_noasm.txt)0
-rw-r--r--tests/cases/longjmp_tiny_invoke.ll (renamed from tests/cases/longjmp_tiny_noasm_invoke.ll)0
-rw-r--r--tests/cases/longjmp_tiny_invoke.txt (renamed from tests/cases/longjmp_tiny_noasm_invoke.txt)0
-rw-r--r--tests/cases/longjmp_tiny_phi.ll (renamed from tests/cases/longjmp_tiny_phi_noasm.ll)0
-rw-r--r--tests/cases/longjmp_tiny_phi.txt (renamed from tests/cases/longjmp_tiny_phi_noasm.txt)0
-rw-r--r--tests/cases/longjmp_tiny_phi2.ll (renamed from tests/cases/longjmp_tiny_phi2_noasm.ll)0
-rw-r--r--tests/cases/longjmp_tiny_phi2.txt (renamed from tests/cases/longjmp_tiny_phi2_noasm.txt)0
-rw-r--r--tests/embind/embind.benchmark.js201
-rwxr-xr-xtests/embind/embind.test.js164
-rw-r--r--tests/embind/embind_benchmark.cpp344
-rw-r--r--tests/embind/embind_test.cpp124
-rw-r--r--tests/embind/shell.html94
-rw-r--r--tests/gl_stride.c152
-rw-r--r--tests/gl_stride.pngbin0 -> 345620 bytes
-rwxr-xr-xtests/runner.py24
-rw-r--r--tools/eliminator/asm-eliminator-test-output.js15
-rw-r--r--tools/eliminator/asm-eliminator-test.js15
-rw-r--r--tools/js-optimizer.js13
-rw-r--r--tools/shared.py4
36 files changed, 1879 insertions, 439 deletions
diff --git a/emcc b/emcc
index 7edc71e4..e25d9d91 100755
--- a/emcc
+++ b/emcc
@@ -1002,7 +1002,7 @@ try:
# Apply effects from settings
if shared.Settings.ASM_JS:
- assert opt_level == 2, 'asm.js requires -O2'
+ assert opt_level >= 1, 'asm.js requires -O1 or above'
if closure:
print >> sys.stderr, 'emcc: warning: disabling closure because it is not compatible with asm.js code generation'
diff --git a/emscripten.py b/emscripten.py
index 6e5f1e7c..6d384a96 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -426,7 +426,7 @@ function invoke_%s(%s) {
try {
%sModule.dynCall_%s(%s);
} catch(e) {
- asm.setThrew(1);
+ asm.setThrew(1, 0);
}
}
''' % (sig, args, 'return ' if sig[0] != 'v' else '', sig, args)
@@ -489,6 +489,8 @@ var asm = (function(global, env, buffer) {
var HEAPF64 = new global.Float64Array(buffer);
''' % (asm_setup,) + '\n' + asm_global_vars + '''
var __THREW__ = 0;
+ var threwValue = 0;
+ var setjmpId = 0;
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(['''
@@ -509,9 +511,13 @@ var asm = (function(global, env, buffer) {
top = top|0;
STACKTOP = top;
}
- function setThrew(threw) {
+ function setThrew(threw, value) {
threw = threw|0;
- __THREW__ = threw;
+ value = value|0;
+ if ((__THREW__|0) == 0) {
+ __THREW__ = threw;
+ threwValue = value;
+ }
}
''' + ''.join(['''
function setTempRet%d(value) {
diff --git a/src/analyzer.js b/src/analyzer.js
index df5a435e..3278139b 100644
--- a/src/analyzer.js
+++ b/src/analyzer.js
@@ -1389,21 +1389,21 @@ function analyzer(data, sidePass) {
var line = label.lines[j];
if ((line.intertype == 'call' || line.intertype == 'invoke') && line.ident == setjmp) {
// Add a new label
- var oldIdent = label.ident;
- var newIdent = func.labelIdCounter++;
+ var oldLabel = label.ident;
+ var newLabel = func.labelIdCounter++;
if (!func.setjmpTable) func.setjmpTable = [];
- func.setjmpTable.push([oldIdent, newIdent, line.assignTo]);
+ func.setjmpTable.push({ oldLabel: oldLabel, newLabel: newLabel, assignTo: line.assignTo });
func.labels.splice(i+1, 0, {
intertype: 'label',
- ident: newIdent,
+ ident: newLabel,
lineNum: label.lineNum + 0.5,
lines: label.lines.slice(j+1)
});
- func.labelsDict[newIdent] = func.labels[i+1];
+ func.labelsDict[newLabel] = func.labels[i+1];
label.lines = label.lines.slice(0, j+1);
label.lines.push({
intertype: 'branch',
- label: toNiceIdent(newIdent),
+ label: toNiceIdent(newLabel),
lineNum: line.lineNum + 0.01, // XXX legalizing might confuse this
});
// Correct phis
@@ -1412,8 +1412,8 @@ function analyzer(data, sidePass) {
if (phi.intertype == 'phi') {
for (var i = 0; i < phi.params.length; i++) {
var sourceLabelId = getActualLabelId(phi.params[i].label);
- if (sourceLabelId == oldIdent) {
- phi.params[i].label = newIdent;
+ if (sourceLabelId == oldLabel) {
+ phi.params[i].label = newLabel;
}
}
}
diff --git a/src/embind/embind.js b/src/embind/embind.js
index ee717f4b..988526b4 100755
--- a/src/embind/embind.js
+++ b/src/embind/embind.js
@@ -1,10 +1,10 @@
/*global Module*/
/*global _malloc, _free, _memcpy*/
-/*global FUNCTION_TABLE, HEAP32, HEAPU8*/
-/*global Pointer_stringify*/
+/*global FUNCTION_TABLE, HEAP8, HEAPU8, HEAP16, HEAPU16, HEAP32, HEAPU32*/
+/*global readLatin1String*/
/*global __emval_register, _emval_handle_array, __emval_decref*/
/*global ___getTypeName*/
-
+/*jslint sub:true*/ /* The symbols 'fromWireType' and 'toWireType' must be accessed via array notation to be closure-safe since craftInvokerFunction crafts functions as strings that can't be closured. */
var InternalError = Module.InternalError = extendError(Error, 'InternalError');
var BindingError = Module.BindingError = extendError(Error, 'BindingError');
var UnboundTypeError = Module.UnboundTypeError = extendError(BindingError, 'UnboundTypeError');
@@ -223,9 +223,26 @@ function whenDependentTypesAreResolved(myTypes, dependentTypes, getTypeConverter
}
}
+var __charCodes = (function() {
+ var codes = new Array(256);
+ for (var i = 0; i < 256; ++i) {
+ codes[i] = String.fromCharCode(i);
+ }
+ return codes;
+})();
+
+function readLatin1String(ptr) {
+ var ret = "";
+ var c = ptr;
+ while (HEAPU8[c]) {
+ ret += __charCodes[HEAPU8[c++]];
+ }
+ return ret;
+}
+
function getTypeName(type) {
var ptr = ___getTypeName(type);
- var rv = Pointer_stringify(ptr);
+ var rv = readLatin1String(ptr);
_free(ptr);
return rv;
}
@@ -247,34 +264,35 @@ function requireRegisteredType(rawType, humanName) {
}
function __embind_register_void(rawType, name) {
- name = Pointer_stringify(name);
+ name = readLatin1String(name);
registerType(rawType, {
name: name,
- fromWireType: function() {
+ 'fromWireType': function() {
return undefined;
},
});
}
function __embind_register_bool(rawType, name, trueValue, falseValue) {
- name = Pointer_stringify(name);
+ name = readLatin1String(name);
registerType(rawType, {
name: name,
- fromWireType: function(wt) {
+ 'fromWireType': function(wt) {
// ambiguous emscripten ABI: sometimes return values are
// true or false, and sometimes integers (0 or 1)
return !!wt;
},
- toWireType: function(destructors, o) {
+ 'toWireType': function(destructors, o) {
return o ? trueValue : falseValue;
},
+ destructorFunction: null, // This type does not need a destructor
});
}
// When converting a number from JS to C++ side, the valid range of the number is
// [minRange, maxRange], inclusive.
function __embind_register_integer(primitiveType, name, minRange, maxRange) {
- name = Pointer_stringify(name);
+ name = readLatin1String(name);
if (maxRange === -1) { // LLVM doesn't have signed and unsigned 32-bit types, so u32 literals come out as 'i32 -1'. Always treat those as max u32.
maxRange = 4294967295;
}
@@ -282,10 +300,10 @@ function __embind_register_integer(primitiveType, name, minRange, maxRange) {
name: name,
minRange: minRange,
maxRange: maxRange,
- fromWireType: function(value) {
+ 'fromWireType': function(value) {
return value;
},
- toWireType: function(destructors, value) {
+ 'toWireType': function(destructors, value) {
// todo: Here we have an opportunity for -O3 level "unsafe" optimizations: we could
// avoid the following two if()s and assume value is of proper type.
if (typeof value !== "number") {
@@ -296,17 +314,18 @@ function __embind_register_integer(primitiveType, name, minRange, maxRange) {
}
return value | 0;
},
+ destructorFunction: null, // This type does not need a destructor
});
}
function __embind_register_float(rawType, name) {
- name = Pointer_stringify(name);
+ name = readLatin1String(name);
registerType(rawType, {
name: name,
- fromWireType: function(value) {
+ 'fromWireType': function(value) {
return value;
},
- toWireType: function(destructors, value) {
+ 'toWireType': function(destructors, value) {
// todo: Here we have an opportunity for -O3 level "unsafe" optimizations: we could
// avoid the following if() and assume value is of proper type.
if (typeof value !== "number") {
@@ -314,15 +333,16 @@ function __embind_register_float(rawType, name) {
}
return value;
},
+ destructorFunction: null, // This type does not need a destructor
});
}
-function __embind_register_cstring(rawType, name) {
- name = Pointer_stringify(name);
+function __embind_register_std_string(rawType, name) {
+ name = readLatin1String(name);
registerType(rawType, {
name: name,
- fromWireType: function(value) {
- var length = HEAP32[value >> 2];
+ 'fromWireType': function(value) {
+ var length = HEAPU32[value >> 2];
var a = new Array(length);
for (var i = 0; i < length; ++i) {
a[i] = String.fromCharCode(HEAPU8[value + 4 + i]);
@@ -330,32 +350,102 @@ function __embind_register_cstring(rawType, name) {
_free(value);
return a.join('');
},
- toWireType: function(destructors, value) {
+ 'toWireType': function(destructors, value) {
+ if (value instanceof ArrayBuffer) {
+ value = new Uint8Array(value);
+ }
+
+ function getTAElement(ta, index) {
+ return ta[index];
+ }
+ function getStringElement(string, index) {
+ return string.charCodeAt(index);
+ }
+ var getElement;
+ if (value instanceof Uint8Array) {
+ getElement = getTAElement;
+ } else if (value instanceof Int8Array) {
+ getElement = getTAElement;
+ } else if (typeof value === 'string') {
+ getElement = getStringElement;
+ } else {
+ throwBindingError('Cannot pass non-string to std::string');
+ }
+
// assumes 4-byte alignment
var length = value.length;
var ptr = _malloc(4 + length);
- HEAP32[ptr >> 2] = length;
+ HEAPU32[ptr >> 2] = length;
+ for (var i = 0; i < length; ++i) {
+ var charCode = getElement(value, i);
+ if (charCode > 255) {
+ _free(ptr);
+ throwBindingError('String has UTF-16 code units that do not fit in 8 bits');
+ }
+ HEAPU8[ptr + 4 + i] = charCode;
+ }
+ if (destructors !== null) {
+ destructors.push(_free, ptr);
+ }
+ return ptr;
+ },
+ destructorFunction: function(ptr) { _free(ptr); },
+ });
+}
+
+function __embind_register_std_wstring(rawType, charSize, name) {
+ name = readLatin1String(name);
+ var HEAP, shift;
+ if (charSize === 2) {
+ HEAP = HEAPU16;
+ shift = 1;
+ } else if (charSize === 4) {
+ HEAP = HEAPU32;
+ shift = 2;
+ }
+ registerType(rawType, {
+ name: name,
+ 'fromWireType': function(value) {
+ var length = HEAPU32[value >> 2];
+ var a = new Array(length);
+ var start = (value + 4) >> shift;
+ for (var i = 0; i < length; ++i) {
+ a[i] = String.fromCharCode(HEAP[start + i]);
+ }
+ _free(value);
+ return a.join('');
+ },
+ 'toWireType': function(destructors, value) {
+ // assumes 4-byte alignment
+ var length = value.length;
+ var ptr = _malloc(4 + length * charSize);
+ HEAPU32[ptr >> 2] = length;
+ var start = (ptr + 4) >> shift;
for (var i = 0; i < length; ++i) {
- HEAPU8[ptr + 4 + i] = value.charCodeAt(i);
+ HEAP[start + i] = value.charCodeAt(i);
+ }
+ if (destructors !== null) {
+ destructors.push(_free, ptr);
}
- destructors.push(_free, ptr);
return ptr;
},
+ destructorFunction: function(ptr) { _free(ptr); },
});
}
function __embind_register_emval(rawType, name) {
- name = Pointer_stringify(name);
+ name = readLatin1String(name);
registerType(rawType, {
name: name,
- fromWireType: function(handle) {
+ 'fromWireType': function(handle) {
var rv = _emval_handle_array[handle].value;
__emval_decref(handle);
return rv;
},
- toWireType: function(destructors, value) {
+ 'toWireType': function(destructors, value) {
return __emval_register(value);
},
+ destructorFunction: null, // This type does not need a destructor
});
}
@@ -367,30 +457,142 @@ function runDestructors(destructors) {
}
}
-function makeInvoker(name, argCount, argTypes, invoker, fn) {
- if (!FUNCTION_TABLE[fn]) {
- throwBindingError('function '+name+' is not defined');
+// Function implementation of operator new, per
+// http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
+// 13.2.2
+// ES3
+function new_(constructor, argumentList) {
+ if (!(constructor instanceof Function)) {
+ throw new TypeError('new_ called with constructor type ' + typeof(constructor) + " which is not a function");
+ }
+
+ /*
+ * Previously, the following line was just:
+
+ function dummy() {};
+
+ * Unfortunately, Chrome was preserving 'dummy' as the object's name, even though at creation, the 'dummy' has the
+ * correct constructor name. Thus, objects created with IMVU.new would show up in the debugger as 'dummy', which
+ * isn't very helpful. Using IMVU.createNamedFunction addresses the issue. Doublely-unfortunately, there's no way
+ * to write a test for this behavior. -NRD 2013.02.22
+ */
+ var dummy = createNamedFunction(constructor.name, function(){});
+ dummy.prototype = constructor.prototype;
+ var obj = new dummy;
+
+ var r = constructor.apply(obj, argumentList);
+ return (r instanceof Object) ? r : obj;
+}
+
+// The path to interop from JS code to C++ code:
+// (hand-written JS code) -> (autogenerated JS invoker) -> (template-generated C++ invoker) -> (target C++ function)
+// craftInvokerFunction generates the JS invoker function for each function exposed to JS through embind.
+function craftInvokerFunction(humanName, argTypes, classType, cppInvokerFunc, cppTargetFunc) {
+ // humanName: a human-readable string name for the function to be generated.
+ // argTypes: An array that contains the embind type objects for all types in the function signature.
+ // argTypes[0] is the type object for the function return value.
+ // argTypes[1] is the type object for function this object/class type, or null if not crafting an invoker for a class method.
+ // argTypes[2...] are the actual function parameters.
+ // classType: The embind type object for the class to be bound, or null if this is not a method of a class.
+ // cppInvokerFunc: JS Function object to the C++-side function that interops into C++ code.
+ // cppTargetFunc: Function pointer (an integer to FUNCTION_TABLE) to the target C++ function the cppInvokerFunc will end up calling.
+ var argCount = argTypes.length;
+
+ if (argCount < 2) {
+ throwBindingError("argTypes array size mismatch! Must at least get return value and 'this' types!");
+ }
+
+ 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) {
+// return FUNCTION_TABLE[fn];
+// }
+
+ var argsList = "";
+ var argsListWired = "";
+ for(var i = 0; i < argCount-2; ++i) {
+ argsList += (i!==0?", ":"")+"arg"+i;
+ argsListWired += (i!==0?", ":"")+"arg"+i+"Wired";
}
- return createNamedFunction(makeLegalFunctionName(name), function() {
- if (arguments.length !== argCount - 1) {
- throwBindingError('function ' + name + ' called with ' + arguments.length + ' arguments, expected ' + (argCount - 1));
+
+ var invokerFnBody =
+ "return function "+makeLegalFunctionName(humanName)+"("+argsList+") {\n" +
+ "if (arguments.length !== "+(argCount - 2)+") {\n" +
+ "throwBindingError('function "+humanName+" called with ' + arguments.length + ' arguments, expected "+(argCount - 2)+" args!');\n" +
+ "}\n";
+
+ // Determine if we need to use a dynamic stack to store the destructors for the function parameters.
+ // TODO: Remove this completely once all function invokers are being dynamically generated.
+ var needsDestructorStack = false;
+
+ for(var i = 1; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here.
+ if (argTypes[i] !== null && argTypes[i].destructorFunction === undefined) { // The type does not define a destructor function - must use dynamic stack
+ needsDestructorStack = true;
+ break;
}
- var destructors = [];
- var args = new Array(argCount);
- args[0] = fn;
- for (var i = 1; i < argCount; ++i) {
- args[i] = argTypes[i].toWireType(destructors, arguments[i - 1]);
+ }
+
+ if (needsDestructorStack) {
+ invokerFnBody +=
+ "var destructors = [];\n";
+ }
+
+ 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]];
+
+ if (isClassMethodFunc) {
+ invokerFnBody += "var thisWired = classParam.toWireType("+dtorStack+", this);\n";
+ }
+
+ for(var i = 0; i < argCount-2; ++i) {
+ invokerFnBody += "var arg"+i+"Wired = argType"+i+".toWireType("+dtorStack+", arg"+i+"); // "+argTypes[i+2].name+"\n";
+ args1.push("argType"+i);
+ args2.push(argTypes[i+2]);
+ }
+
+ if (isClassMethodFunc) {
+ argsListWired = "thisWired" + (argsListWired.length > 0 ? ", " : "") + argsListWired;
+ }
+
+ var returns = (argTypes[0].name !== "void");
+
+ invokerFnBody +=
+ (returns?"var rv = ":"") + "invoker(fn"+(argsListWired.length>0?", ":"")+argsListWired+");\n";
+
+ if (needsDestructorStack) {
+ invokerFnBody += "runDestructors(destructors);\n";
+ } else {
+ for(var i = isClassMethodFunc?1:2; i < argTypes.length; ++i) { // Skip return value at index 0 - it's not deleted here. Also skip class type if not a method.
+ var paramName = (i === 1 ? "thisWired" : ("arg"+(i-2)+"Wired"));
+ if (argTypes[i].destructorFunction !== null) {
+ invokerFnBody += paramName+"_dtor("+paramName+"); // "+argTypes[i].name+"\n";
+ args1.push(paramName+"_dtor");
+ args2.push(argTypes[i].destructorFunction);
+ }
}
- var rv = invoker.apply(null, args);
- rv = argTypes[0].fromWireType(rv);
- runDestructors(destructors);
- return rv;
- });
+ }
+
+ if (returns) {
+ invokerFnBody += "return retType.fromWireType(rv);\n";
+ }
+ invokerFnBody += "}\n";
+
+ args1.push(invokerFnBody);
+
+ var invokerFunction = new_(Function, args1).apply(null, args2);
+ return invokerFunction;
}
function __embind_register_function(name, argCount, rawArgTypesAddr, rawInvoker, fn) {
var argTypes = heap32VectorToArray(argCount, rawArgTypesAddr);
- name = Pointer_stringify(name);
+ name = readLatin1String(name);
rawInvoker = FUNCTION_TABLE[rawInvoker];
exposePublicSymbol(name, function() {
@@ -398,7 +600,8 @@ function __embind_register_function(name, argCount, rawArgTypesAddr, rawInvoker,
}, argCount - 1);
whenDependentTypesAreResolved([], argTypes, function(argTypes) {
- replacePublicSymbol(name, makeInvoker(name, argCount, argTypes, rawInvoker, fn), argCount - 1);
+ var invokerArgsArray = [argTypes[0] /* return value */, null /* no class 'this'*/].concat(argTypes.slice(1) /* actual params */);
+ replacePublicSymbol(name, craftInvokerFunction(name, invokerArgsArray, null /* no class 'this'*/, rawInvoker, fn), argCount - 1);
return [];
});
}
@@ -407,7 +610,7 @@ var tupleRegistrations = {};
function __embind_register_tuple(rawType, name, rawConstructor, rawDestructor) {
tupleRegistrations[rawType] = {
- name: Pointer_stringify(name),
+ name: readLatin1String(name),
rawConstructor: FUNCTION_TABLE[rawConstructor],
rawDestructor: FUNCTION_TABLE[rawDestructor],
elements: [],
@@ -453,18 +656,18 @@ function __embind_finalize_tuple(rawTupleType) {
var setter = elt.setter;
var setterContext = elt.setterContext;
elt.read = function(ptr) {
- return getterReturnType.fromWireType(getter(getterContext, ptr));
+ return getterReturnType['fromWireType'](getter(getterContext, ptr));
};
elt.write = function(ptr, o) {
var destructors = [];
- setter(setterContext, ptr, setterArgumentType.toWireType(destructors, o));
+ setter(setterContext, ptr, setterArgumentType['toWireType'](destructors, o));
runDestructors(destructors);
};
});
return [{
name: reg.name,
- fromWireType: function(ptr) {
+ 'fromWireType': function(ptr) {
var rv = new Array(elementsLength);
for (var i = 0; i < elementsLength; ++i) {
rv[i] = elements[i].read(ptr);
@@ -472,7 +675,7 @@ function __embind_finalize_tuple(rawTupleType) {
rawDestructor(ptr);
return rv;
},
- toWireType: function(destructors, o) {
+ 'toWireType': function(destructors, o) {
if (elementsLength !== o.length) {
throw new TypeError("Incorrect number of tuple elements");
}
@@ -480,9 +683,12 @@ function __embind_finalize_tuple(rawTupleType) {
for (var i = 0; i < elementsLength; ++i) {
elements[i].write(ptr, o[i]);
}
- destructors.push(rawDestructor, ptr);
+ if (destructors !== null) {
+ destructors.push(rawDestructor, ptr);
+ }
return ptr;
},
+ destructorFunction: rawDestructor,
}];
});
}
@@ -496,7 +702,7 @@ function __embind_register_struct(
rawDestructor
) {
structRegistrations[rawType] = {
- name: Pointer_stringify(name),
+ name: readLatin1String(name),
rawConstructor: FUNCTION_TABLE[rawConstructor],
rawDestructor: FUNCTION_TABLE[rawDestructor],
fields: [],
@@ -514,7 +720,7 @@ function __embind_register_struct_field(
setterContext
) {
structRegistrations[structType].fields.push({
- fieldName: Pointer_stringify(fieldName),
+ fieldName: readLatin1String(fieldName),
getterReturnType: getterReturnType,
getter: FUNCTION_TABLE[getter],
getterContext: getterContext,
@@ -545,12 +751,12 @@ function __embind_finalize_struct(structType) {
var setterContext = field.setterContext;
fields[fieldName] = {
read: function(ptr) {
- return getterReturnType.fromWireType(
+ return getterReturnType['fromWireType'](
getter(getterContext, ptr));
},
write: function(ptr, o) {
var destructors = [];
- setter(setterContext, ptr, setterArgumentType.toWireType(destructors, o));
+ setter(setterContext, ptr, setterArgumentType['toWireType'](destructors, o));
runDestructors(destructors);
}
};
@@ -558,7 +764,7 @@ function __embind_finalize_struct(structType) {
return [{
name: reg.name,
- fromWireType: function(ptr) {
+ 'fromWireType': function(ptr) {
var rv = {};
for (var i in fields) {
rv[i] = fields[i].read(ptr);
@@ -566,7 +772,7 @@ function __embind_finalize_struct(structType) {
rawDestructor(ptr);
return rv;
},
- toWireType: function(destructors, o) {
+ 'toWireType': function(destructors, o) {
// todo: Here we have an opportunity for -O3 level "unsafe" optimizations:
// assume all fields are present without checking.
for (var fieldName in fields) {
@@ -578,55 +784,17 @@ function __embind_finalize_struct(structType) {
for (fieldName in fields) {
fields[fieldName].write(ptr, o[fieldName]);
}
- destructors.push(rawDestructor, ptr);
+ if (destructors !== null) {
+ destructors.push(rawDestructor, ptr);
+ }
return ptr;
},
+ destructorFunction: rawDestructor,
}];
});
}
-function RegisteredPointer(
- name,
- registeredClass,
- isReference,
- isConst,
-
- // smart pointer properties
- isSmartPointer,
- pointeeType,
- sharingPolicy,
- rawGetPointee,
- rawConstructor,
- rawShare,
- rawDestructor
-) {
- this.name = name;
- this.registeredClass = registeredClass;
- this.isReference = isReference;
- this.isConst = isConst;
-
- // smart pointer properties
- this.isSmartPointer = isSmartPointer;
- this.pointeeType = pointeeType;
- this.sharingPolicy = sharingPolicy;
- this.rawGetPointee = rawGetPointee;
- this.rawConstructor = rawConstructor;
- this.rawShare = rawShare;
- this.rawDestructor = rawDestructor;
-}
-
-RegisteredPointer.prototype.toWireType = function(destructors, handle) {
- var self = this;
- function throwCannotConvert() {
- var name;
- if (handle.$$.smartPtrType) {
- name = handle.$$.smartPtrType.name;
- } else {
- name = handle.$$.ptrType.name;
- }
- throwBindingError('Cannot convert argument of type ' + name + ' to parameter type ' + self.name);
- }
-
+var genericPointerToWireType = function(destructors, handle) {
if (handle === null) {
if (this.isReference) {