Skip to content

Commit 1842b29

Browse files
WIP
1 parent f2d9663 commit 1842b29

17 files changed

+11030
-8649
lines changed

src/compiler.ts

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7079,36 +7079,48 @@ export class Compiler extends DiagnosticEmitter {
70797079
}
70807080
}
70817081

7082+
let allTrivial = (getSideEffects(functionArg, module.ref) & SideEffects.WritesGlobal) == 0;
7083+
if(operands && allTrivial) {
7084+
for(let i = 0; i < numOperands; ++i) {
7085+
if(!module.isTrivialExpression(operands[i])){
7086+
allTrivial = false;
7087+
break;
7088+
}
7089+
}
7090+
}
7091+
7092+
let stmts = new Array<ExpressionRef>();
7093+
let sizeTypeRef = this.options.sizeTypeRef;
7094+
7095+
if(!allTrivial){
7096+
let functionArgLocal = this.currentFlow.getTempLocal(this.options.usizeType);
7097+
let functionArgSetExpr = module.local_set(functionArgLocal.index, functionArg, true);
7098+
stmts.push(functionArgSetExpr);
7099+
functionArg = module.local_get(functionArgLocal.index, sizeTypeRef);
7100+
}
7101+
70827102
// We might be calling a varargs stub here, even if all operands have been
70837103
// provided, so we must set `argumentsLength` in any case. Inject setting it
70847104
// into the index argument, which becomes executed last after any operands.
70857105
let argumentsLength = this.ensureArgumentsLength();
7086-
let sizeTypeRef = this.options.sizeTypeRef;
7087-
if (getSideEffects(functionArg, module.ref) & SideEffects.WritesGlobal) {
7088-
let flow = this.currentFlow;
7089-
let temp = flow.getTempLocal(this.options.usizeType);
7090-
let tempIndex = temp.index;
7091-
functionArg = module.block(null, [
7092-
module.local_set(tempIndex, functionArg, true), // Function
7093-
module.global_set(argumentsLength, module.i32(numArguments)),
7094-
module.local_get(tempIndex, sizeTypeRef)
7095-
], sizeTypeRef);
7096-
} else { // simplify
7097-
functionArg = module.block(null, [
7098-
module.global_set(argumentsLength, module.i32(numArguments)),
7099-
functionArg
7100-
], sizeTypeRef);
7101-
}
7106+
7107+
7108+
let functionArgWithVararg = module.block(null, [
7109+
module.global_set(argumentsLength, module.i32(numArguments)),
7110+
functionArg
7111+
], sizeTypeRef);
7112+
71027113
if (operands) this.operandsTostack(signature, operands);
71037114
let expr = module.call_indirect(
71047115
null, // TODO: handle multiple tables
7105-
module.load(4, false, functionArg, TypeRef.I32), // ._index
7116+
module.load(4, false, functionArgWithVararg, TypeRef.I32), // ._index
71067117
operands,
71077118
signature.paramRefs,
71087119
signature.resultRefs
71097120
);
71107121
this.currentType = returnType;
7111-
return expr;
7122+
stmts.push(expr);
7123+
return module.flatten(stmts, returnType.toRef());
71127124
}
71137125

71147126
private compileCommaExpression(

src/module.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,6 +2901,13 @@ export class Module {
29012901

29022902
/** Makes a copy of a trivial expression (doesn't contain subexpressions). Returns `0` if non-trivial. */
29032903
tryCopyTrivialExpression(expr: ExpressionRef): ExpressionRef {
2904+
if (this.isTrivialExpression(expr)) {
2905+
return this.copyExpression(expr);
2906+
}
2907+
return 0;
2908+
}
2909+
2910+
isTrivialExpression(expr: ExpressionRef): bool {
29042911
switch (binaryen._BinaryenExpressionGetId(expr)) {
29052912
case ExpressionId.LocalGet:
29062913
case ExpressionId.GlobalGet:
@@ -2909,9 +2916,9 @@ export class Module {
29092916
case ExpressionId.Nop:
29102917
case ExpressionId.Unreachable:
29112918
case ExpressionId.DataDrop:
2912-
case ExpressionId.RefNull: return this.copyExpression(expr);
2919+
case ExpressionId.RefNull: return true;
29132920
}
2914-
return 0;
2921+
return false;
29152922
}
29162923

29172924
/** Makes a copy of any expression including all subexpressions. */

tests/compiler/call-rest.debug.wat

Lines changed: 58 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3403,14 +3403,19 @@
34033403
(local $7 i32)
34043404
(local $8 i32)
34053405
(local $9 i32)
3406+
(local $10 i32)
3407+
(local $11 i32)
34063408
global.get $~lib/memory/__stack_pointer
3407-
i32.const 8
3409+
i32.const 16
34083410
i32.sub
34093411
global.set $~lib/memory/__stack_pointer
34103412
call $~stack_check
34113413
global.get $~lib/memory/__stack_pointer
34123414
i64.const 0
34133415
i64.store
3416+
global.get $~lib/memory/__stack_pointer
3417+
i64.const 0
3418+
i64.store offset=8
34143419
memory.size
34153420
i32.const 16
34163421
i32.shl
@@ -3469,11 +3474,11 @@
34693474
i32.const 4
34703475
i32.const 560
34713476
call $~lib/rt/__newArray
3472-
local.set $9
3477+
local.set $11
34733478
global.get $~lib/memory/__stack_pointer
3474-
local.get $9
3479+
local.get $11
34753480
i32.store
3476-
local.get $9
3481+
local.get $11
34773482
call $call-rest/fn
34783483
i32.const 6
34793484
i32.eq
@@ -3493,11 +3498,11 @@
34933498
i32.const 4
34943499
i32.const 592
34953500
call $~lib/rt/__newArray
3496-
local.set $9
3501+
local.set $11
34973502
global.get $~lib/memory/__stack_pointer
3498-
local.get $9
3503+
local.get $11
34993504
i32.store
3500-
local.get $9
3505+
local.get $11
35013506
call $call-rest/fn
35023507
i32.const 15
35033508
i32.eq
@@ -3548,21 +3553,25 @@
35483553
call $~lib/builtins/abort
35493554
unreachable
35503555
end
3556+
global.get $~lib/memory/__stack_pointer
3557+
global.get $call-rest/indirect
3558+
local.tee $3
3559+
i32.store offset=4
35513560
i32.const 1
35523561
i32.const 2
35533562
i32.const 1
35543563
i32.const 2
35553564
i32.const 4
35563565
i32.const 656
35573566
call $~lib/rt/__newArray
3558-
local.set $9
3567+
local.set $11
35593568
global.get $~lib/memory/__stack_pointer
3560-
local.get $9
3569+
local.get $11
35613570
i32.store
3562-
local.get $9
3571+
local.get $11
35633572
i32.const 3
35643573
global.set $~argumentsLength
3565-
global.get $call-rest/indirect
3574+
local.get $3
35663575
i32.load
35673576
call_indirect (type $3)
35683577
i32.const 6
@@ -3576,21 +3585,25 @@
35763585
call $~lib/builtins/abort
35773586
unreachable
35783587
end
3588+
global.get $~lib/memory/__stack_pointer
3589+
global.get $call-rest/indirect
3590+
local.tee $5
3591+
i32.store offset=8
35793592
i32.const 1
35803593
i32.const 2
35813594
i32.const 3
35823595
i32.const 2
35833596
i32.const 4
35843597
i32.const 688
35853598
call $~lib/rt/__newArray
3586-
local.set $9
3599+
local.set $11
35873600
global.get $~lib/memory/__stack_pointer
3588-
local.get $9
3601+
local.get $11
35893602
i32.store
3590-
local.get $9
3603+
local.get $11
35913604
i32.const 3
35923605
global.set $~argumentsLength
3593-
global.get $call-rest/indirect
3606+
local.get $5
35943607
i32.load
35953608
call_indirect (type $3)
35963609
i32.const 15
@@ -3611,11 +3624,11 @@
36113624
global.set $~argumentsLength
36123625
i32.const 0
36133626
call $call-rest/Foo#constructor@varargs
3614-
local.set $9
3627+
local.set $11
36153628
global.get $~lib/memory/__stack_pointer
3616-
local.get $9
3629+
local.get $11
36173630
i32.store
3618-
local.get $9
3631+
local.get $11
36193632
call $call-rest/Foo#sum
36203633
i32.const 1
36213634
i32.eq
@@ -3635,11 +3648,11 @@
36353648
global.set $~argumentsLength
36363649
i32.const 0
36373650
call $call-rest/Foo#constructor@varargs
3638-
local.set $9
3651+
local.set $11
36393652
global.get $~lib/memory/__stack_pointer
3640-
local.get $9
3653+
local.get $11
36413654
i32.store
3642-
local.get $9
3655+
local.get $11
36433656
call $call-rest/Foo#sum
36443657
i32.const 3
36453658
i32.eq
@@ -3660,17 +3673,17 @@
36603673
i32.const 4
36613674
i32.const 800
36623675
call $~lib/rt/__newArray
3663-
local.set $9
3676+
local.set $11
36643677
global.get $~lib/memory/__stack_pointer
3665-
local.get $9
3666-
i32.store offset=4
3667-
local.get $9
3678+
local.get $11
3679+
i32.store offset=12
3680+
local.get $11
36683681
call $call-rest/Foo#constructor
3669-
local.set $9
3682+
local.set $11
36703683
global.get $~lib/memory/__stack_pointer
3671-
local.get $9
3684+
local.get $11
36723685
i32.store
3673-
local.get $9
3686+
local.get $11
36743687
call $call-rest/Foo#sum
36753688
i32.const 6
36763689
i32.eq
@@ -3691,17 +3704,17 @@
36913704
i32.const 4
36923705
i32.const 832
36933706
call $~lib/rt/__newArray
3694-
local.set $9
3707+
local.set $11
36953708
global.get $~lib/memory/__stack_pointer
3696-
local.get $9
3697-
i32.store offset=4
3698-
local.get $9
3709+
local.get $11
3710+
i32.store offset=12
3711+
local.get $11
36993712
call $call-rest/Foo#constructor
3700-
local.set $9
3713+
local.set $11
37013714
global.get $~lib/memory/__stack_pointer
3702-
local.get $9
3715+
local.get $11
37033716
i32.store
3704-
local.get $9
3717+
local.get $11
37053718
call $call-rest/Foo#sum
37063719
i32.const 15
37073720
i32.eq
@@ -3734,11 +3747,11 @@
37343747
i32.const 4
37353748
i32.const 896
37363749
call $~lib/rt/__newArray
3737-
local.set $9
3750+
local.set $11
37383751
global.get $~lib/memory/__stack_pointer
3739-
local.get $9
3752+
local.get $11
37403753
i32.store
3741-
local.get $9
3754+
local.get $11
37423755
call $call-rest/count<i32>
37433756
i32.const 1
37443757
i32.eq
@@ -3756,11 +3769,11 @@
37563769
i32.const 4
37573770
i32.const 928
37583771
call $~lib/rt/__newArray
3759-
local.set $9
3772+
local.set $11
37603773
global.get $~lib/memory/__stack_pointer
3761-
local.get $9
3774+
local.get $11
37623775
i32.store
3763-
local.get $9
3776+
local.get $11
37643777
call $call-rest/count<i32>
37653778
i32.const 3
37663779
i32.eq
@@ -3778,11 +3791,11 @@
37783791
i32.const 8
37793792
i32.const 1056
37803793
call $~lib/rt/__newArray
3781-
local.set $9
3794+
local.set $11
37823795
global.get $~lib/memory/__stack_pointer
3783-
local.get $9
3796+
local.get $11
37843797
i32.store
3785-
local.get $9
3798+
local.get $11
37863799
call $call-rest/count<~lib/string/String>
37873800
i32.const 3
37883801
i32.eq
@@ -3796,7 +3809,7 @@
37963809
unreachable
37973810
end
37983811
global.get $~lib/memory/__stack_pointer
3799-
i32.const 8
3812+
i32.const 16
38003813
i32.add
38013814
global.set $~lib/memory/__stack_pointer
38023815
)

0 commit comments

Comments
 (0)