This change removes the mmap inside of Block in favor of a growing
vector of bytes. This is favorable for two reasons:
- We don't take more space than we need
- There is no limit to the growth of the vector (previously, if
the Block overstepped its 64kb boundary, it would just crash)
However, if that vector happens to resize, any pointer pointing into
that vector would become invalid. To avoid this, this commit adds an
InstructionHandle<Op> class which just stores a block and an offset
into that block.
This was missing from Value::is_array(), which is equivalent to the
spec's IsArray() abstract operation - it treats a Proxy value with an
Array target object as being an Array.
It can throw, so needs both the global object and an exception check
now.
This ensures that "while", do...while, "for" expressions have a
properly initialized result value even if the user terminated
the loop body via break or the loop body wasn't executed at all.
Previously SwitchStatement::execute() would return <empty> when hitting
break, continue or empty consequent block. This was not in line with
the standard.
This partially reverts c6ce7c9326.
The munmap part of that change was good, but we can't seal the blocks
since that breaks NewString and other ops that have String members.
This commit introduces the concept of an accumulator register to
LibJS's bytecode interpreter. The accumulator register is always
register 0, and most simple instructions use it for reading and
writing.
Not only does this slim down the AST, but it also simplifies a lot of
the code. For example, the generate_bytecode methods no longer need
to return an Optional<Register>, as any opcode which has a "return"
value will always put it into the accumulator.
This also renames the old Op::Load to Op::LoadImmediate, and uses
Op::Load to load from a register into the accumulator. There is
also an Op::Store to put the value in the accumulator into another
register.
Other software might not expect these to be defined and behave
differently if they _are_ defined, e.g. scummvm which checks if
the TODO macro is defined and fails to build if it is.
Previously, if you play a file, then stop, then play again, the stop
button will be permanently disabled until you open a file again.
The stop button should be enabled whenever a file is loaded.
This commit fixes the GUI bug by enabling the stop button whenever the
play button is clicked (if a file is currently loaded).