Skip to content

Commit 42b592d

Browse files
authored
[JS API] Add CallRef (#8103)
1 parent 93f40ae commit 42b592d

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

src/js/binaryen.js-post.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2472,6 +2472,18 @@ function wrapModule(module, self = {}) {
24722472
}
24732473
};
24742474

2475+
self['call_ref'] = function(target, operands, type) {
2476+
return preserveStack(() =>
2477+
Module['_BinaryenCallRef'](module, target, i32sToStack(operands), operands.length, type, false)
2478+
);
2479+
};
2480+
2481+
self['return_call_ref'] = function(target, operands, type) {
2482+
return preserveStack(() =>
2483+
Module['_BinaryenCallRef'](module, target, i32sToStack(operands), operands.length, type, true)
2484+
);
2485+
}
2486+
24752487
self['any'] = {
24762488
'convert_extern'() {
24772489
return Module['_BinaryenRefAsAnyConvertExtern']();
@@ -5153,6 +5165,39 @@ Module['I31Get'] = makeExpressionWrapper(Module['_BinaryenI31GetId'](), {
51535165
}
51545166
});
51555167

5168+
Module['CallRef'] = makeExpressionWrapper(Module['_BinaryenCallRefId'](), {
5169+
'getNumOperands'(expr) {
5170+
return Module['_BinaryenCallRefGetNumOperands'](expr);
5171+
},
5172+
'getOperandAt'(expr, index) {
5173+
return Module['_BinaryenCallRefGetOperandAt'](expr, index);
5174+
},
5175+
'setOperandAt'(expr, index, operandExpr) {
5176+
Module['_BinaryenCallRefSetOperandAt'](expr, index, operandExpr);
5177+
},
5178+
'appendOperand'(expr, operandExpr) {
5179+
return Module['_BinaryenCallRefAppendOperand'](expr, operandExpr);
5180+
},
5181+
'insertOperandAt'(expr, index, operandExpr) {
5182+
Module['_BinaryenCallRefInsertOperandAt'](expr, index, operandExpr);
5183+
},
5184+
'removeOperandAt'(expr, index) {
5185+
return Module['_BinaryenCallRefRemoveOperandAt'](expr, index);
5186+
},
5187+
'getTarget'(expr) {
5188+
return Module['_BinaryenCallRefGetTarget'](expr);
5189+
},
5190+
'setTarget'(expr, targetExpr) {
5191+
Module['_BinaryenCallRefSetTarget'](expr, targetExpr);
5192+
},
5193+
'isReturn'(expr) {
5194+
return Boolean(Module['_BinaryenCallRefIsReturn'](expr));
5195+
},
5196+
'setReturn'(expr, isReturn) {
5197+
Module['_BinaryenCallRefSetReturn'](expr, isReturn);
5198+
}
5199+
});
5200+
51565201
// Function wrapper
51575202

51585203
Module['Function'] = (() => {

test/binaryen.js/expressions.js

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3409,3 +3409,97 @@ console.log("# I31Get");
34093409

34103410
module.dispose();
34113411
})();
3412+
3413+
console.log("# CallRef");
3414+
(function testCallRef() {
3415+
const module = new binaryen.Module();
3416+
3417+
const funcName = "tiny";
3418+
module.addFunction(funcName, binaryen.createType([binaryen.i32, binaryen.i32]), binaryen.none, [], module.nop());
3419+
const funcType = binaryen.Function(module.getFunction(funcName)).type;
3420+
const funcRef = binaryen.RefFunc(module.ref.func(funcName, funcType));
3421+
3422+
const operands = [
3423+
module.i32.const(6),
3424+
module.i32.const(7)
3425+
];
3426+
3427+
const theCallRef = binaryen.CallRef(module.call_ref(funcRef, operands, binaryen.none));
3428+
assert(theCallRef instanceof binaryen.CallRef);
3429+
assert(theCallRef instanceof binaryen.Expression);
3430+
assert(theCallRef.numOperands === operands.length);
3431+
assert(theCallRef.type === binaryen.none);
3432+
assert(binaryen.RefFunc(theCallRef.target).func === funcName);
3433+
3434+
const info = binaryen.getExpressionInfo(theCallRef);
3435+
assert(info.id === theCallRef.id);
3436+
assert(info.type === theCallRef.type);
3437+
assert(info.target === theCallRef.target);
3438+
assert(info.isReturn === theCallRef.isReturn());
3439+
3440+
assert(theCallRef.getNumOperands() === operands.length);
3441+
3442+
assert(theCallRef.getOperandAt(0) === operands[0]);
3443+
assert(theCallRef.getOperandAt(1) === operands[1]);
3444+
3445+
theCallRef.setOperandAt(0, operands[1]);
3446+
assert(theCallRef.getOperandAt(0), operands[1]);
3447+
theCallRef.setOperandAt(0, operands[0]);
3448+
assert(theCallRef.getOperandAt(0), operands[0]);
3449+
3450+
const newOperand = module.i32.const(8);
3451+
theCallRef.appendOperand(newOperand);
3452+
assert(theCallRef.getNumOperands() == 3);
3453+
assert(theCallRef.getOperandAt(2) === newOperand);
3454+
3455+
theCallRef.removeOperandAt(2);
3456+
assert(theCallRef.getNumOperands() == 2);
3457+
assert(theCallRef.getOperandAt(0) === operands[0]);
3458+
assert(theCallRef.getOperandAt(1) === operands[1]);
3459+
3460+
theCallRef.insertOperandAt(1, newOperand);
3461+
assert(theCallRef.getNumOperands() == 3);
3462+
assert(theCallRef.getOperandAt(0) === operands[0]);
3463+
assert(theCallRef.getOperandAt(1) === newOperand);
3464+
assert(theCallRef.getOperandAt(2) === operands[1]);
3465+
3466+
theCallRef.removeOperandAt(1);
3467+
assert(theCallRef.getNumOperands() == 2);
3468+
assert(theCallRef.getOperandAt(0) === operands[0]);
3469+
assert(theCallRef.getOperandAt(1) === operands[1]);
3470+
3471+
assert(theCallRef.isReturn() === false);
3472+
theCallRef.setReturn(true);
3473+
assert(theCallRef.isReturn() === true);
3474+
theCallRef.setReturn(false);
3475+
assert(theCallRef.isReturn() === false);
3476+
3477+
const theReturnCallRef = binaryen.CallRef(module.return_call_ref(funcRef, operands, binaryen.none));
3478+
assert(theReturnCallRef instanceof binaryen.CallRef);
3479+
assert(theReturnCallRef instanceof binaryen.Expression);
3480+
assert(theReturnCallRef.numOperands === operands.length);
3481+
assert(binaryen.RefFunc(theReturnCallRef.target).func === funcName);
3482+
assert(theReturnCallRef.isReturn() === true);
3483+
3484+
3485+
const targetRef = binaryen.RefFunc(theCallRef.getTarget());
3486+
assert(theCallRef.getTarget() == theCallRef.target);
3487+
assert(targetRef.func === funcName);
3488+
3489+
const newTargetName = "newTarget";
3490+
const newTargetRef = binaryen.RefFunc(module.ref.func(newTargetName, funcType));
3491+
theCallRef.setTarget(newTargetRef);
3492+
assert(binaryen.RefFunc(theCallRef.getTarget()).func === newTargetName);
3493+
3494+
theCallRef.setTarget(funcRef);
3495+
assert(binaryen.RefFunc(theCallRef.getTarget()).func === funcName);
3496+
3497+
console.log(theCallRef.toText());
3498+
assert(
3499+
theCallRef.toText()
3500+
==
3501+
"(call_ref $func.0\n (i32.const 6)\n (i32.const 7)\n (ref.func $tiny)\n)\n"
3502+
);
3503+
3504+
module.dispose();
3505+
})();

test/binaryen.js/expressions.js.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,3 +453,9 @@
453453
(local.get $2)
454454
)
455455

456+
# CallRef
457+
(call_ref $func.0
458+
(i32.const 6)
459+
(i32.const 7)
460+
(ref.func $tiny)
461+
)

0 commit comments

Comments
 (0)