summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibJS/Bytecode/Interpreter.cpp
AgeCommit message (Collapse)Author
2023-05-14LibJS/Bytecode: Restore old environments when an exception is caughtAndreas Kling
Unwind contexts now remember the lexical and variable environments in effect when they were created. If an exception is caught, we revert to those environments in the running execution context.
2023-03-15LibJS+LibWeb: Wrap raw JS::Cell*/& fields in GCPtr/NonnullGCPtrMatthew Olsson
2023-03-06Everywhere: Stop using NonnullOwnPtrVectorAndreas Kling
Same as NonnullRefPtrVector: weird semantics, questionable benefits.
2023-02-26LibJS: Align codegen AwaitExpressions to YieldExpressionsHendiadyoin1
We use generators in bytecode to approximate async functions, but the code generated by AwaitExpressions did not have the value processing paths that Yield requires, eg the `generator.throw()` path, which is used by AsyncFunctionDriverWrapper to signal Promise rejections.
2023-02-26LibJS: Don't enter finally blocks upon `yield` in bytecode modeHendiadyoin1
2023-02-26LibJS: Generate unwind chains for continue in BytecodeHendiadyoin1
This works similar to `break` The `try-finally-continue` still do not pass with this, likely because of binding issues.
2023-02-26LibJS: Generate unwind chains for break in BytecodeHendiadyoin1
This uses a newly added instruction `ScheduleJump` This instruction tells the finally proceeding it, that instead of jumping to it's next block it should jump to the designated block.
2023-02-25Everywhere: Use _{short_,}string to create Strings from literalsLinus Groh
2023-02-16LibJS: Convert remaining usages of Value::TDSWOSE to Value::TSWOSETimothy Flynn
Note the couple of cases using MUST are just debugging statements.
2023-02-16LibJS+Everywhere: Deprecate Value::to_string_without_side_effectsTimothy Flynn
2023-01-09AK+Everywhere: Rename FlyString to DeprecatedFlyStringTimothy Flynn
DeprecatedFlyString relies heavily on DeprecatedString's StringImpl, so let's rename it to A) match the name of DeprecatedString, B) write a new FlyString class that is tied to String.
2022-12-06LibJS: Intercept returns through finally blocks in BytecodeHendiadyoin1
This is still not perfect, as we now actually crash in the `try-finally-continue` tests, while we now succeed all `try-catch-finally-*` tests. Note that we do not yet go through the finally block when exiting the unwind context through a break or continue.
2022-12-06LibJS: Don't try to manage unwind contexts in the execution loop in BCHendiadyoin1
We are already doing this in a good manner via the generated code, doing so in the execution loop as well will cause us to pop contexts multiple times, which is not very good.
2022-12-06AK+Everywhere: Rename String to DeprecatedStringLinus Groh
We have a new, improved string type coming up in AK (OOM aware, no null state), and while it's going to use UTF-8, the name UTF8String is a mouthful - so let's free up the String name by renaming the existing class. Making the old one have an annoying name will hopefully also help with quick adoption :^)
2022-12-03LibJS: Add an EliminateLoads pass to BytecodeHendiadyoin1
This pass tries to eliminate repeated lookups of variables by name, by remembering where these where last loaded to. For now the lookup cache needs to be fully cleared with each call or property access, because we do not have a way to check if these have any side effects on the currently visible scopes. Note that property accesses can cause getters/setters to be called, so these are treated as calls in all cases.
2022-12-03LibJS: Restore cached current_block on return in BytecodeHendiadyoin1
Otherwise debug prints will show the wrong block until we preform a jump
2022-11-26LibJS/Bytecode: Store unwind contexts inside RegisterWindowLuke Wilde
Unwind contexts need to be preserved as we exit and re-enter a generator. For example, this would previously crash when returning from the try statement after yielding as we lost the unwind context when yielding, but still have a LeaveUnwindContext instruction from running `perform_needed_unwinds` when generating the return statement. ```js function* a() { try { return (yield 1); } catch {} } iter = a(); iter.next(); iter.next(); ```
2022-11-01LibJS: Expose some information about the bytecode interpreters stateHendiadyoin1
This is quite helpful, when reporting internal errors.
2022-10-19LibJS: Disable bytecode optimizations by defaultAndreas Kling
The optimization passes are not stable, which makes test262 flaky. Address this by introducing a new OptimizationLevel::None and making it the default. This removes all the flakiness from test262 in my testing. We can enable optimizations by default again once they have been made stable. :^)
2022-08-23LibJS: Remove Bytecode::Register::global_object()Linus Groh
This is unused.
2022-08-23LibJS: Remove {Bytecode::,}Interpreter::global_object()Linus Groh
The basic idea is that a global object cannot just come out of nowhere, it must be associated to a realm - so get it from there, if needed. This is to enforce the changes from all the previous commits by not handing out global objects unless you actually have an initialized realm (either stored somewhere, or the VM's current realm).
2022-07-18LibJS/Bytecode: Determine strict mode on an executable basisLuke Wilde
An executable is generated for the top-level script and for each function. Strict mode can only be changed with the first statement of the top-level script and each function, which corresponds directly to Executable.
2022-04-18LibJS: Avoid copying the frame into the interpreter in BC generatorsAli Mohammad Pur
2022-03-18LibJS: Add infallible variant of VM::push_execution_context()Linus Groh
It makes no sense to require passing a global object and doing a stack space check in some cases where running out of stack is highly unlikely, we can't recover from errors, and currently ignore the result anyway. This is most commonly in constructors and when setting things up, rather than regular function calls.
2022-03-14LibJS: Leave unwind context if it has no finalizer when using handlerLuke Wilde
For example, a try/catch block with no finally. The try block and catch block do not need to unwind to a finally block, so the unwind context is no longer needed when we jump to the catch block. If we threw an exception in a catch block of a try/catch, there will be no handler or finalizer and the unit would continue on as if nothing happened. This would subsequently crash with the `m_saved_exception.is_null()` assertion failure when we next call a non-native function.
2022-02-13LibJS: More properly implement scoping rules in bytecode codegenAli Mohammad Pur
Now we emit CreateVariable and SetVariable with the appropriate initialization/environment modes, much closer to the spec. This makes a whole lot of things like let/const variables, function and variable hoisting and some other things work :^)
2022-02-13LibJS: Implement the NewClass opcodeAli Mohammad Pur
2022-02-08LibJS+Everywhere: Remove VM::exception() and most related functionsdavidot
This commit removes all exception related code: Remove VM::exception(), VM::throw_exception() etc. Any leftover throw_exception calls are moved to throw_completion. The one method left is clear_exception() which is now a no-op. Most of these calls are just to clear whatever exception might have been thrown when handling a Completion. So to have a cleaner commit this will be removed in a next commit. It also removes the actual Exception and TemporaryClearException classes since these are no longer used. In any spot where the exception was actually used an attempt was made to preserve that behavior. However since it is no longer tracked by the VM we cannot access exceptions which were thrown in previous calls. There are two such cases which might have different behavior: - In Web::DOM::Document::interpreter() the on_call_stack_emptied hook used to print any uncaught exception but this is now no longer possible as the VM does not store uncaught exceptions. - In js the code used to be interruptable by throwing an exception on the VM. This is no longer possible but was already somewhat fragile before as you could happen to throw an exception just before a VERIFY.
2022-02-08LibJS: Always pop the execution context if we pushed one for bytecodedavidot
2022-02-08LibJS: Convert Instruction::execute in bytecode to ThrowCompletionOrdavidot
This allows us to use TRY in these functions :^).
2022-01-24LibJS: Fix the execution context for the bytecode interpreterdavidot
Because we now push an execution context when creating the "normal" interpreter without valid environments we have to check for that case as well when running the bytecode interpreter.
2022-01-08LibJS: Remove now unused VM::{set_,}last_value()Linus Groh
This was effectively replaced by correct use of completions, including UpdateEmpty semantics.
2021-11-14LibJS: Convert push_execution_context() to ThrowCompletionOrLinus Groh
2021-11-12LibJS+LibTest+js: Convert BC::Interpreter::run to ThrowCompletionOr<>Ali Mohammad Pur
Note that this is just a shallow API change.
2021-11-12LibJS: Run the queued promise reaction jobs on bytecode interpreter exitAli Mohammad Pur
This is the same as what the AST interpreter does.
2021-11-12LibJS: Make Bytecode::Interpreter return the popped frameAli Mohammad Pur
And use it to _correctly_ implement state saving for generators. Prior to this, we were capturing the caller frame, which is completely irrelevant to the generator frame.
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-10-25LibJS: Make bytecode interpreter leave unwind context immediatelyAndreas Kling
We were missing some "break" statements, causing us to actually finish executing everything within "try" blocks before actually jumping to the "catch" and/or "finally" blocks.
2021-10-24LibJS: Move global "should dump bytecode" flag into LibJSAndreas Kling
This will allow us to trigger bytecode executable dumps when generating bytecode inside LibJS as well, not just in clients like js and test-js.
2021-09-13LibJS: Also set ExecutionContext::realm in Bytecode::Interpreter::run()Linus Groh
I forgot to consider the bytecode Interpreter when adding a Realm to the ExecutionContext. This should make it a lot less crashy again :^)
2021-09-12LibJS: Move the GlobalEnvironment from GlobalObject to RealmLinus Groh
This is where the spec wants to have it. Requires a couple of hacks as currently everything that needs a Realm actually has a GlobalObject, so we need to go via the Interpreter.
2021-09-12LibJS: Allocate a Realm next to GlobalObject in Interpreter::create()Linus Groh
Also pass a Realm reference to the Bytecode::Interpreter constructor, just like we pass the GlobalObject.
2021-08-10LibJS: Change ExecutionContext's arguments list to a MarkedValueListTimothy Flynn
The test262 tests under RegExp/property-escapes/generated will invoke Reflect.apply with up to 10,000 arguments at a time. In LibJS, when the call stack reached VM::call_internal, we transfer those arguments from a MarkedValueList to the execution context's arguments Vector. Because these types differ (MarkedValueList is a Vector<Value, 32>), the arguments are copied rather than moved. By changing the arguments vector to a MarkedValueList, we can properly move the passed arguments over. This shaves about 2 seconds off the following test262 test (from 15sec): RegExp/property-escapes/generated/General_Category_-_Decimal_Number.js
2021-07-01LibJS: Drop "Record" suffix from all the *Environment record classesAndreas Kling
"Records" in the spec are basically C++ classes, so let's drop this mouthful of a suffix.
2021-06-24LibJS: Rename CallFrame => ExecutionContextAndreas Kling
This struct represents what the ECMAScript specification calls an "execution context" so let's use the same terminology. :^)
2021-06-22LibJS: Begin implementing GlobalEnvironmentRecordAndreas Kling
These represent the outermost scope in the environment record hierarchy. The spec says they should be a "composite" of two things: - An ObjectEnvironmentRecord wrapping the global object - A DeclarativeEnvironmentRecord for other declarations It's not yet clear to me how this should work, so this patch only implements the first part, an object record wrapping the global object.
2021-06-22LibJS: Split the per-call-frame environment into lexical and variableAndreas Kling
To better follow the spec, we need to distinguish between the current execution context's lexical environment and variable environment. This patch moves us to having two record pointers, although both of them point at the same environment records for now.
2021-06-21LibJS: Rename Environment Records so they match the spec :^)Andreas Kling
This patch makes the following name changes: - ScopeObject => EnvironmentRecord - LexicalEnvironment => DeclarativeEnvironmentRecord - WithScope => ObjectEnvironmentRecord
2021-06-15LibJS: Add a basic pass manager and add some basic passesAli Mohammad Pur
This commit adds a bunch of passes, the most interesting of which is a pass that merges blocks together, and a pass that places blocks that flow into each other next to each other, and a very simply pass that removes duplicate basic blocks. Note that this does not remove the jump at the end of each block in that pass to avoid scope creep in the passes.
2021-06-12LibJS: Store and maintain an "execution generation" counterIdan Horowitz
This counter is increased each time a synchronous execution sequence completes, and will allow us to emulate the abstract operations AddToKeptObjects & ClearKeptObjects efficiently.