Skip to content

[emval] Simplify dynamic invoker creation. NFC #24619

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/lib/libembind.js
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ var LibraryEmbind = {
// TODO: Remove this completely once all function invokers are being dynamically generated.
var needsDestructorStack = usesDestructorStack(argTypes);

var returns = (argTypes[0].name !== 'void');
var returns = !argTypes[0].isVoid;

var expectedArgCount = argCount - 2;
#if ASSERTIONS
Expand Down Expand Up @@ -766,8 +766,8 @@ var LibraryEmbind = {
var invokerFn = InvokerFunctions[signature](...closureArgs);
#else

let [args, invokerFnBody] = createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync);
var invokerFn = new Function(...args, invokerFnBody)(...closureArgs);
let invokerFactory = createJsInvoker(argTypes, isClassMethodFunc, returns, isAsync);
var invokerFn = invokerFactory(...closureArgs);
#endif
#endif
return createNamedFunction(humanName, invokerFn);
Expand Down
6 changes: 3 additions & 3 deletions src/lib/libembind_gen.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,13 @@ var LibraryEmbind = {
for (const argType of this.argumentTypes) {
argTypes.push(this.convertToEmbindType(argType.type));
}
const signature = createJsInvokerSignature(argTypes, !!this.thisType, this.returnType.name !== 'void', this.isAsync)
const signature = createJsInvokerSignature(argTypes, !!this.thisType, !this.returnType.isVoid, this.isAsync)
if (emittedFunctions.has(signature)) {
return;
}
emittedFunctions.add(signature);
let [args, body] = createJsInvoker(argTypes, !!this.thisType, this.returnType.name !== 'void', this.isAsync);
out.push(`'${signature}': function(${args.join(',')}) {\n${body}},`);
let invokerFactory = createJsInvoker(argTypes, !!this.thisType, !this.returnType.isVoid, this.isAsync);
out.push(`'${signature}': ${invokerFactory},`);
}
},
$PointerDefinition: class {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/libembind_shared.js
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ var LibraryEmbindShared = {
args1.push('checkArgCount', 'minArgs', 'maxArgs');
invokerFnBody = `if (arguments.length !== ${args1.length}){ throw new Error(humanName + "Expected ${args1.length} closure arguments " + arguments.length + " given."); }\n${invokerFnBody}`;
#endif
return [args1, invokerFnBody];
return new Function(args1, invokerFnBody);
}
};

Expand Down
53 changes: 21 additions & 32 deletions src/lib/libemval.js
Original file line number Diff line number Diff line change
Expand Up @@ -297,52 +297,41 @@ var LibraryEmVal = {
return emval_returnValue(toReturnWire, destructorsRef, rv);
};
#else
var functionBody =
`return function (handle, methodName, destructorsRef, args) {\n`;

var offset = 0;
var argsList = []; // 'arg0, arg1, arg2, ... , argN'
var params = ['toValue'];
var args = [Emval.toValue];
for (var i = 0; i < argCount; ++i) {
argsList.push(`arg${i}`);
params.push(`argFromPtr${i}`);
args.push(argFromPtr[i]);
functionBody +=
` var arg${i} = argFromPtr${i}(args${offset ? '+' + offset : ''});\n`;
offset += GenericWireTypeSize;
}
var invoker;
var captures = {'toValue': Emval.toValue};
var args = argFromPtr.map((argFromPtr, i) => {
var captureName = `argFromPtr${i}`;
captures[captureName] = argFromPtr;
return `${captureName}(args${i ? '+' + i * GenericWireTypeSize : ''})`;
});
var functionBody;
switch (kind){
case {{{ cDefs['internal::EM_INVOKER_KIND::FUNCTION'] }}}:
invoker = 'toValue(handle)';
functionBody = 'toValue(handle)';
break;
case {{{ cDefs['internal::EM_INVOKER_KIND::CONSTRUCTOR'] }}}:
invoker = 'new (toValue(handle))';
functionBody = 'new (toValue(handle))';
break;
case {{{ cDefs['internal::EM_INVOKER_KIND::CAST'] }}}:
invoker = '';
functionBody = '';
break;
case {{{ cDefs['internal::EM_INVOKER_KIND::METHOD'] }}}:
params.push('getStringOrSymbol');
args.push(getStringOrSymbol);
invoker = 'toValue(handle)[getStringOrSymbol(methodName)]';
captures['getStringOrSymbol'] = getStringOrSymbol;
functionBody = 'toValue(handle)[getStringOrSymbol(methodName)]';
break;
}
functionBody +=
` var rv = ${invoker}(${argsList.join(', ')});\n`;
functionBody += `(${args})`;
if (!retType.isVoid) {
params.push('toReturnWire', 'emval_returnValue');
args.push(toReturnWire, emval_returnValue);
functionBody +=
' return emval_returnValue(toReturnWire, destructorsRef, rv);\n';
captures['toReturnWire'] = toReturnWire;
captures['emval_returnValue'] = emval_returnValue;
functionBody = `return emval_returnValue(toReturnWire, destructorsRef, ${functionBody})`;
}
functionBody +=
"};\n";
functionBody = `return function (handle, methodName, destructorsRef, args) {
${functionBody}
}`;

var invokerFunction = new Function(...params, functionBody)(...args);
var invokerFunction = new Function(Object.keys(captures), functionBody)(...Object.values(captures));
#endif
var functionName = `methodCaller<(${argTypes.map(t => t.name).join(', ')}) => ${retType.name}>`;
var functionName = `methodCaller<(${argTypes.map(t => t.name)}) => ${retType.name}>`;
return emval_addMethodCaller(createNamedFunction(functionName, invokerFunction));
},

Expand Down
8 changes: 4 additions & 4 deletions test/code_size/embind_hello_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 552,
"a.html.gz": 380,
"a.js": 7266,
"a.js.gz": 3321,
"a.js": 7255,
"a.js.gz": 3318,
"a.wasm": 7300,
"a.wasm.gz": 3348,
"total": 15118,
"total_gz": 7049
"total": 15107,
"total_gz": 7046
}
8 changes: 4 additions & 4 deletions test/code_size/embind_val_wasm.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"a.html": 552,
"a.html.gz": 380,
"a.js": 5367,
"a.js.gz": 2540,
"a.js": 5356,
"a.js.gz": 2531,
"a.wasm": 9101,
"a.wasm.gz": 4698,
"total": 15020,
"total_gz": 7618
"total": 15009,
"total_gz": 7609
}