summaryrefslogtreecommitdiff
path: root/Libraries/LibJS/Interpreter.h
AgeCommit message (Collapse)Author
2020-07-01LibJS: Implement Proxy [[Call]] and [[Construct]] trapsMatthew Olsson
In order to do this, Proxy now extends Function rather than Object, and whether or not it returns true for is_function() depends on it's m_target.
2020-06-29LibJS: Initial class implementation; allow super expressions in objectJack Karamanian
literal methods; add EnvrionmentRecord fields and methods to LexicalEnvironment Adding EnvrionmentRecord's fields and methods lets us throw an exception when |this| is not initialized, which occurs when the super constructor in a derived class has not yet been called, or when |this| has already been initialized (the super constructor was already called).
2020-06-20LibJS: Make Interpreter::construct() take a GlobalObject&Andreas Kling
2020-06-20LibJS: Move native objects towards two-pass constructionAndreas Kling
To make sure that everything is set up correctly in objects before we start adding properties to them, we split cell allocation into 3 steps: 1. Allocate a cell of appropriate size from the Heap 2. Call the C++ constructor on the cell 3. Call initialize() on the constructed object The job of initialize() is to define all the initial properties. Doing it in a second pass guarantees that the Object has a valid Shape and can find its own GlobalObject.
2020-06-11LibJS: Consolidate error messages into ErrorTypes.hMatthew Olsson
Now, exceptions can be thrown with interpreter.throw_exception<T>(ErrorType:TYPE, "format", "args", "here").
2020-06-08LibJS: Make more Interpreter functions take a GlobalObject&Andreas Kling
2020-06-08LibJS: Interpreter::this_value() => this_value(GlobalObject&)Andreas Kling
Once the Interpreter has no global object attached to it, we have to provide it everywhere.
2020-06-08LibJS+js: Support getting last value from "_" variableLinus Groh
The interpreter now has an "underscore is last value" flag, which makes Interpreter::get_variable() return the last value if: - The m_underscore_is_last_value flag is enabled - The name of the variable lookup is "_" - The result of that lookup is an empty value That means "_" can still be used as a regular variable and will stop doing its magic once anything is assigned to it. Example REPL session: > 1 1 > _ + _ 2 > _ + _ 4 > _ = "foo" "foo" > 1 1 > _ "foo" > delete _ true > 1 1 > _ 1 >
2020-06-02LibJS: Move Interpreter::get_trace() to ConsoleClientLinus Groh
Having it globally on the interpreter is confusing as the last call frame is skipped, which is specific to console.trace().
2020-05-29LibJS: Integrate labels into the InterpreterMatthew Olsson
The interpreter now considers a statement or block's label when considering whether or not to break. All statements can be labelled.
2020-05-28LibJS: Add strict modeMatthew Olsson
Adds the ability for a scope (either a function or the entire program) to be in strict mode. Scopes default to non-strict mode. There are two ways to determine the strict-ness of the JS engine: 1. In the parser, this can be accessed with the parser_state variable m_is_strict_mode boolean. If true, the Parser is currently parsing in strict mode. This is done so that the Parser can generate syntax errors at parse time, which is required in some cases. 2. With Interpreter.is_strict_mode(). This allows strict mode checking at runtime as opposed to compile time. Additionally, in order to test this, a global isStrictMode() function has been added to the JS ReplObject under the test-mode flag.
2020-05-24Browser: Add JS ConsoleFalseHonesty
The JavaScript console can be opened with Control+I, or using the menu option. The console is currently a text box with JS syntax highlighting which will send commands to the document's interpreter. All output is printed to an HTML view in the console. The output is an HtmlView to easily allow complex output, such as expandable views for JS Objects in the long run.
2020-05-21LibJS: Make Interpreter::call() this_value a required argumentLinus Groh
Right now the default is an empty value, which we accidentally exposed in set{Interval,Timeout}() by not providing a custom this value, which should't happen at all. Let's just make it a required argument instead.
2020-05-05LibJS: Add some helpers and use them to re-implement Console functionsEmanuele Torre
Also add const overloads for some getters. Also const-qualify Interpreter::join_arguments().
2020-05-05LibJS: Move join_args() in InterpreterEmanuele Torre
It can be useful outside of Runtime/ConsoleObject.cpp. join_args() => Interpreter::join_arguments()
2020-05-02LibJS: Start implementing a Console class for the interpreterEmanuele Torre
The goal is to start factoring out core ConsoleObject functionality and to make ConsoleObject only a JS wrapper around Console.
2020-05-01LibJS: Implement most of the Reflect objectLinus Groh
2020-05-01LibJS: Implement console.count()Emanuele Torre
2020-04-29LibJS: Pass JS::Function around by reference moreAndreas Kling
2020-04-28LibJS: Allow "delete someGlobalVariable"Andreas Kling
This is solved by allowing Identifier nodes to produce a Reference with the global object as base.
2020-04-25LibJS: Stop using Optional<Value> in favor of Value's empty stateAndreas Kling
JS::Value already has the empty state ({} or Value() gives you one.) Use this instead of wrapping Value in Optional in some places. I've also added Value::value_or(Value) so you can easily provide a fallback value when one is not present.
2020-04-19LibJS: Add MarkedValueList and use it for argument passingAndreas Kling
A MarkedValueList is basically a Vector<JS::Value> that registers with the Heap and makes sure that the stored values don't get GC'd. Before this change, we were unsafely keeping Vector<JS::Value> in some places, which is out-of-reach for the live reference finding logic since Vector puts its elements on the heap by default. We now pass all the JavaScript tests even when running with "js -g", which does a GC on every heap allocation.
2020-04-18LibJS: Move the empty object shape from Interpreter to GlobalObjectAndreas Kling
The big remaining hurdle before a GlobalObject-agnostic Interpreter is the fact that Interpreter owns and vends the GlobalObject :^)
2020-04-18LibJS: Move builtin prototypes to the global objectAndreas Kling
This moves us towards being able to run JavaScript in different global objects without allocating a separate GC heap.
2020-04-18LibJS: Pass prototype to Error constructorsAndreas Kling
2020-04-15LibJS: Introduce LexicalEnvironmentAndreas Kling
This patch replaces the old variable lookup logic with a new one based on lexical environments. This brings us closer to the way JavaScript is actually specced, and also gives us some basic support for closures. The interpreter's call stack frames now have a pointer to the lexical environment for that frame. Each lexical environment can have a chain of parent environments. Before calling a Function, we first ask it to create_environment(). This gives us a new LexicalEnvironment for that function, which has the function's lexical parent's environment as its parent. This allows inner functions to access variables in their outer function: function foo() { <-- LexicalEnvironment A var x = 1; function() { <-- LexicalEnvironment B (parent: A) console.log(x); } } If we return the result of a function expression from a function, that new function object will keep a reference to its parent environment, which is how we get closures. :^) I'm pretty sure I didn't get everything right here, but it's a pretty good start. This is quite a bit slower than before, but also correcter!
2020-04-13LibJS: Remove Interpreter::declare_variable()Andreas Kling
Since declarations are now hoisted and handled on scope entry, the job of a VariableDeclaration becomes to actually initialize variables. As such, we can remove the part where we insert variables into the nearest relevant scope. Less work == more speed! :^)
2020-04-11LibJS: Add console.trace()Linus Groh
2020-04-11LibJS: Make Function and CallFrame aware of their function nameLinus Groh
2020-04-10LibJS: Use enumerator macros for boilerplate code around native typesAndreas Kling
2020-04-10LibJS: Add all the Error subclassesAndreas Kling
This patch adds instance, constructor and prototype classes for: - EvalError - InternalError - RangeError - ReferenceError - SyntaxError - TypeError - URIError Enumerator macros are used to reduce the amount of typing. :^)
2020-04-08LibJS: rename JS::DeclarationType => JS::DeclarationKindEmanuele Torre
Many other parsers call it with this name. Also Type can be confusing in this context since the DeclarationType is not the type (number, string, etc.) of the variables that are being declared by the VariableDeclaration.
2020-04-08LibJS: Add "constructor" property to constructor prototypesAndreas Kling
2020-04-07LibJS: Add Boolean constructor objectJack Karamanian
2020-04-06LibJS: Give argument vectors an inline capacity of 8Andreas Kling
This avoids one malloc/free pair for every function call if there are 8 arguments or fewer.
2020-04-05LibJS: Add support for "continue" inside "for" statements :^)Andreas Kling
2020-04-05LibJS: Make "break" actually work inside "switch"Andreas Kling
2020-04-04LibJS: Don't return the "last computed value" from Interpreter::run()Andreas Kling
Only return whatever a "return" statment told us to return. The last computed value is now available in Interpreter::last_value() instead, where the REPL can pick it up.
2020-04-04LibJS: Add NumberObject and make to_object() on number values create itAndreas Kling
2020-04-04LibJS: Add Function() and Function.prototypeLinus Groh
2020-04-02LibJS: Start implementing object shapesAndreas Kling
This patch adds JS::Shape, which implements a transition tree for our Object class. Object property keys, prototypes and attributes are now stored in a Shape, and each Object has a Shape. When adding a property to an Object, we make a transition from the old Shape to a new Shape. If we've made the same exact transition in the past (with another Object), we reuse the same transition and both objects may now share a Shape. This will become the foundation of inline caching and other engine optimizations in the future. :^)
2020-04-01LibJS: Add argument(i) and argument_count() to InterpreterAndreas Kling
Add some convenience accessors for retrieving arguments from the current call frame.
2020-04-01LibJS: Add Interpreter::create<GlobalObjectType>()Andreas Kling
Force Interpreter construction to go via a create() helper that takes the global object type as a template parameter.
2020-04-01LibWeb+LibJS: Move DOM Window object to dedicated classesAndreas Kling
LibWeb now creates a WindowObject which inherits from GlobalObject. Allocation of the global object is moved out of the Interpreter ctor to allow for specialized construction. The existing Window interfaces are moved to WindowObject with their implementation code in the new Window class.
2020-03-30LibJS: Start implementing Date :^)Linus Groh
This adds: - A global Date object (with `length` property and `now` function) - The Date constructor (no arguments yet) - The Date prototype (with `get*` functions)
2020-03-29LibJS: Implement basic execution of "switch" statementsAndreas Kling
The "break" keyword now unwinds to the nearest ScopeType::Breakable. There's no support for break labels yet, but we'll get there too.
2020-03-29LibJS+LibWeb: Function calls should always go through InterpreterAndreas Kling
This ensures that we set up a call frame with |this| and arguments.
2020-03-28LibJS: Rework how native functions are called to improve |this| valueAndreas Kling
Native functions now only get the Interpreter& as an argument. They can then extract |this| along with any indexed arguments it wants from it. This forces functions that want |this| to actually deal with calling interpreter.this_value().to_object(), and dealing with the possibility of a non-object |this|. This is still not great but let's keep massaging it forward.
2020-03-27LibJS: Allow function calls with missing argumentsAndreas Kling
We were interpreting "undefined" as a variable lookup failure in some cases and throwing a ReferenceError exception instead of treating it as the valid value "undefined". This patch wraps the result of variable lookup in Optional<>, which allows us to only throw ReferenceError when lookup actually fails.
2020-03-24LibJS: Implement "throw"Andreas Kling
You can now throw an expression to the nearest catcher! :^) To support throwing arbitrary values, I added an Exception class that sits as a wrapper around whatever is thrown. In the future it will be a logical place to store a call stack.