summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Bytecode/BasicBlock.h
AgeCommit message (Collapse)Author
2021-10-25LibJS: Always inline the bytecode instruction iterator's operator++Andreas Kling
2021-10-25LibJS: Propagate exceptions across bytecode executable boundariesAndreas Kling
To support situations like this: function foo() { throw 1; } try { foo(); } catch (e) { } Each unwind context now keeps track of its origin executable. When an exception is thrown, we return from run() immediately if the nearest unwind context isn't in the current executable. This causes a natural unwind to the point where we find the catch/finally block(s) to jump into.
2021-06-15LibJS: Make basic block size customizableAli Mohammad Pur
And keep the default 4 KiB for the code generator.
2021-06-11LibJS: Automatically split linear bytecode into multiple blocksAli Mohammad Pur
...instead of crashing :^)
2021-06-10LibJS: Implement bytecode generation for try..catch..finallyGunnar Beutner
EnterUnwindContext pushes an unwind context (exception handler and/or finalizer) onto a stack. LeaveUnwindContext pops the unwind context from that stack. Upon return to the interpreter loop we check whether the VM has an exception pending. If no unwind context is available we return from the loop. If an exception handler is available we clear the VM's exception, put the exception value into the accumulator register, clear the unwind context's handler and jump to the handler. If no handler is available but a finalizer is available we save the exception value + metadata (for later use by ContinuePendingUnwind), clear the VM's exception, pop the unwind context and jump to the finalizer. ContinuePendingUnwind checks whether a saved exception is available. If no saved exception is available it jumps to the resume label. Otherwise it stores the exception into the VM. The Jump after LeaveUnwindContext could be integrated into the LeaveUnwindContext instruction. I've kept them separate for now to make the bytecode more readable. > try { 1; throw "x" } catch (e) { 2 } finally { 3 }; 4 1: [ 0] EnterScope [ 10] EnterUnwindContext handler:@4 finalizer:@3 [ 38] EnterScope [ 48] LoadImmediate 1 [ 60] NewString 1 ("x") [ 70] Throw <for non-terminated blocks: insert LeaveUnwindContext + Jump @3 here> 2: [ 0] LoadImmediate 4 3: [ 0] EnterScope [ 10] LoadImmediate 3 [ 28] ContinuePendingUnwind resume:@2 4: [ 0] SetVariable 0 (e) [ 10] EnterScope [ 20] LoadImmediate 2 [ 38] LeaveUnwindContext [ 3c] Jump @3 String Table: 0: e 1: x
2021-06-09LibJS: Store strings in a string tableGunnar Beutner
Instead of using Strings in the bytecode ops this adds a global string table to the Executable struct which individual operations can refer to using indices. This brings bytecode ops one step closer to being pointer free.
2021-06-09LibJS: Generate bytecode in basic blocks instead of one big blockAli Mohammad Pur
This limits the size of each block (currently set to 1K), and gets us closer to a canonical, more easily analysable bytecode format. As a result of this, "Labels" are now simply entries to basic blocks. Since there is no more 'conditional' jump (as all jumps are always taken), JumpIf{True,False} are unified to JumpConditional, and JumpIfNullish is renamed to JumpNullish. Also fixes #7914 as a result of reimplementing the loop logic.