Commit graph

20 commits

Author SHA1 Message Date
Linus Groh
99be27b4a1 LibJS: Add "name" property to functions 2020-05-02 20:41:31 +02:00
mattco98
23ec578a01 LibJS: Implement correct attributes for (almost) all properties
Added the ability to include a u8 attributes parameter with all of the
various put methods in the Object class. They can be omitted, in which
case it defaults to "Writable | Enumerable | Configurable", just like
before this commit.

All of the attribute values for each property were gathered from
SpiderMonkey in the Firefox console. Some properties (e.g. all of the
canvas element properties) have undefined property descriptors... not
quite sure what that means. Those were left as the default specified
above.
2020-04-28 09:29:50 +02:00
Andreas Kling
fca08bd000 LibJS: Move builtin prototypes to the global object
This moves us towards being able to run JavaScript in different global
objects without allocating a separate GC heap.
2020-04-18 13:24:45 +02:00
Andreas Kling
bc1ece7f37 LibJS+LibWeb: Pass prototype to Object constructor
Everyone who constructs an Object must now pass a prototype object when
applicable. There's still a fair amount of code that passes something
fetched from the Interpreter, but this brings us closer to being able
to detach prototypes from Interpreter eventually.
2020-04-18 11:00:55 +02:00
Andreas Kling
f6d57c82f6 LibJS: Pass prototype to Function constructors 2020-04-18 10:28:22 +02:00
Andreas Kling
60d1ef6af4 LibJS: Remove no-op code in ScriptFunction constructor 2020-04-16 16:58:44 +02:00
Andreas Kling
54c95d44ce LibJS: Functions with no variables don't need to create environment
Just hand out the parent environment instead.
2020-04-15 22:17:17 +02:00
Andreas Kling
ed80952cb6 LibJS: Introduce LexicalEnvironment
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-15 22:07:20 +02:00
Linus Groh
eece424694 LibJS: Make Function and CallFrame aware of their function name 2020-04-11 14:10:42 +02:00
Andreas Kling
e5da1cc566 LibJS: Throw real TypeError, ReferenceError, etc objects
Instead of just throwing Error objects with a name string, we now throw
the real Error subclass types. :^)
2020-04-10 13:09:35 +02:00
Andreas Kling
5495f06af5 LibJS: Give argument vectors an inline capacity of 8
This avoids one malloc/free pair for every function call if there are
8 arguments or fewer.
2020-04-06 19:22:12 +02:00
Andreas Kling
1d468ed6d3 AK: Stop allowing implicit downcast with RefPtr and NonnullRefPtr
We were allowing this dangerous kind of thing:

RefPtr<Base> base;
RefPtr<Derived> derived = base;

This patch changes the {Nonnull,}RefPtr constructors so this is no
longer possible.

To downcast one of these pointers, there is now static_ptr_cast<T>:

RefPtr<Derived> derived = static_ptr_cast<Derived>(base);

Fixing this exposed a ton of cowboy-downcasts in various places,
which we're now forced to fix. :^)
2020-04-05 11:19:00 +02:00
Linus Groh
2944039d6b LibJS: Add Function() and Function.prototype 2020-04-04 15:58:49 +02:00
Linus Groh
4d931b524d LibJS: Add length property to ScriptFunction 2020-04-04 15:58:49 +02:00
Linus Groh
849e2c77e4 LibJS: Implement constructor/non-constructor function calls
This adds Function::construct() for constructor function calls via `new`
keyword. NativeFunction doesn't have constructor behaviour by default,
ScriptFunction simply calls call() in construct()
2020-04-01 20:18:36 +02:00
Andreas Kling
7c4e53f31e LibJS: Rework how native functions are called to improve |this| value
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-28 22:51:09 +01:00
Andreas Kling
cccbe43056 LibJS: Use FlyString for identifiers
This makes variable and property lookups a lot faster since comparing
two FlyStrings is O(1).
2020-03-22 13:03:43 +01:00
Andreas Kling
ddd69e3660 LibJS: Make the AST reference-counted
This allows function objects to outlive the original parsed program
without their ScopeNode disappearing.
2020-03-18 11:23:53 +01:00
Andreas Kling
0a71533aff LibJS: Pass argument value vectors as const Vector<Value>&
Now that Interpreter keeps all arguments in the CallFrame stack, we can
just pass a const-reference to the CallFrame's argument vector to each
function handler (instead of copying it.)
2020-03-17 16:24:53 +01:00
Andreas Kling
19452230cd LibJS: Add "Heap" and "Runtime" subdirectories
Let's try to keep LibJS tidy as it expands. :^)
2020-03-16 14:37:19 +01:00
Renamed from Libraries/LibJS/ScriptFunction.cpp (Browse further)