1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-21 16:05:07 +00:00
Commit graph

843 commits

Author SHA1 Message Date
Andreas Kling
7a5ef0a87f LibJS: Disable HEAP_DEBUG logging on non-SerenityOS platforms
This makes it a bit easier to work with LibJS on Linux for now.
2020-03-25 09:49:14 +01:00
Andreas Kling
faddf3a1db LibJS: Implement "throw"
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.
2020-03-24 22:21:58 +01:00
Andreas Kling
db024a9cb1 LibJS: Remove debug spam in Error.prototype.name 2020-03-24 22:21:58 +01:00
Andreas Kling
7dc78b5e38 LibJS: Use correct |this| value when getting/setting native properties 2020-03-24 16:14:10 +01:00
Andreas Kling
343e224aa8 LibJS: Implement basic exception throwing
You can now throw exceptions by calling Interpreter::throw_exception().
Anyone who calls ASTNode::execute() needs to check afterwards if the
Interpreter now has an exception(), and if so, stop what they're doing
and simply return.

When catching an exception, we'll first execute the CatchClause node
if present. After that, we'll execute the finalizer block if present.

This is unlikely to be completely correct, but it's a start! :^)
2020-03-24 16:14:10 +01:00
Andreas Kling
c33d4aefc3 LibJS: Parse "try", "catch" and "finally"
This is the first step towards support exceptions. :^)
2020-03-24 16:14:10 +01:00
Andreas Kling
494df52961 LibJS: Actually leave the current function scope on "return"
We now unwind until the nearest function-level scope on the scope stack
when executing a return statement.
2020-03-23 19:22:24 +01:00
Andreas Kling
df524203b2 LibJS: Consume semicolon at the end of a statement
A bunch of code was relying on this not happenind, in particular the
parsing of "for" statements. Reorganized things so they work again.
2020-03-23 19:10:18 +01:00
Andreas Kling
fbb9e1b715 LibJS: Implement "else" parsing
We can now handle scripts with if/else in LibJS. Most of the changes
are about fixing IfStatement to store the consequent and alternate node
as Statements.

Interpreter now also runs Statements, rather than running ScopeNodes.
2020-03-23 16:52:58 +01:00
Andreas Kling
b2f005125d LibJS: Always collect all garbage when destroying Heap
When the Heap is going down, it's our last chance to run destructors,
so add a separate collector mode where we simply skip over the marking
phase and go directly to sweeping. This causes everything to get swept
and all live cells get destroyed.

This way, valgrind reports 0 leaks on exit. :^)
2020-03-23 14:11:19 +01:00
Andreas Kling
6dc4b23e2f LibJS: Teach the lexer to recognize ">=" and "<=" :^) 2020-03-23 14:10:23 +01:00
Andreas Kling
1dd71bd68f LibJS: Put some more Heap debug logging behind HEAP_DEBUG 2020-03-23 13:45:01 +01:00
Andreas Kling
79e065f0a2 LibJS: Port garbage collector to Linux
Well that was easy. LibJS can now run on Linux :^)
2020-03-23 13:14:57 +01:00
Andreas Kling
538537dfd0 LibJS: Use rand() for Math.random() on other systems
I bet we could be smarter here and use arc4random() on systems where
it is present. I'm not sure how to detect it though.
2020-03-23 13:14:04 +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
7c48c3c8e1 LibJS: Parse "if" statements
This patch implements basic parsing of "if" statements. We don't yet
support parsing "else", so I added a FIXME about that.
2020-03-21 18:40:17 +01:00
Andreas Kling
8b18674229 LibJS: Add Math.random() :^) 2020-03-21 17:52:12 +01:00
Andreas Kling
08b17d70af LibJS+LibWeb: Fix some inconsistencies in NativeFunction callbacks
These should always pass the arguments in a const Vector<JS::Value>&.
2020-03-21 14:43:44 +01:00
Andreas Kling
324b92fd06 LibJS: Virtualize access to an Object's own properties
Object now has virtual get_own_property() and put_own_property() member
functions that can be overridden to provide custom behavior.

We use these virtuals to move Array-specific access behavior to Array.
2020-03-21 14:37:34 +01:00
Andreas Kling
2a7dbac0c5 LibJS: Include the cell size in HeapBlock mmap names
HeapBlocks now show up in SystemMonitor as "LibJS: HeapBlock(32)" :^)
2020-03-21 13:12:16 +01:00
Andreas Kling
00feef8642 LibJS: Some optimizations for ObjectExpression
- move() the property map when constructing ObjectExpression instead of
  making a copy.
- Use key+value iterators to traverse the property map in the execute()
  and dump() functions.
2020-03-21 13:11:51 +01:00
Andreas Kling
6c3afca686 LibJS: Round cell sizes up to a multiple of 16 bytes
This increases HeapBlock utilization significantly (and reduces overall
memory usage.)
2020-03-21 11:49:18 +01:00
Andreas Kling
2106dafd62 LibJS: Delete fully-empty HeapBlocks after garbage collection
We now deallocate GC blocks when they are found to have no live cells
inside them.
2020-03-21 11:46:47 +01:00
0xtechnobabble
bc002f807a LibJS: Parse object expressions 2020-03-21 10:08:58 +01:00
Andreas Kling
bceabd7c4b LibJS: Add ArrayPrototype and implement Array.prototype.push()
This function is ultimately supposed to be generic and allow any |this|
that has a length property, but for now it only works on our own Array
object type.
2020-03-20 21:56:40 +01:00
Andreas Kling
8f7d4f67a4 LibJS: Support reading/writing elements in an Array via Object get/put
I'm not completely thrilled about Object::get() and Object::put() doing
special-case stuff for arrays, and we should probably come up with a
better abstraction for it.

But at least it works for now, which is really nice. :^)
2020-03-20 21:56:40 +01:00
Andreas Kling
a3d2e07446 LibJS: Parse computed MemberExpressions
MemberExpression comes in two flavors:

    computed: a[b]
non-computed: a.b

We can now parse both of the types. :^)
2020-03-20 21:56:40 +01:00
Andreas Kling
86642add2f LibJS: Allow default-constructing a JS::Value (undefined) 2020-03-20 21:56:40 +01:00
Andreas Kling
a82f64d3d6 LibJS: Parse ArrayExpression and start implementing Array objects
Note that property lookup is not functional yet.
2020-03-20 21:56:40 +01:00
Andreas Kling
5db8940c9e LibJS: Use StringBuilder::join() 2020-03-20 14:41:23 +01:00
Andreas Kling
218f082226 LibJS: Print a newline in each console.log() 2020-03-20 14:41:23 +01:00
Andreas Kling
73d28a0551 LibJS: Prefer FunctionDeclaration if a statement begins with "function" 2020-03-19 18:07:07 +01:00
Andreas Kling
1a10470c1d LibJS: Implement basic object property assignment
This is pretty naive, we just walk up the prototype chain and call any
NativeProperty setter that we find. If we don't find one, we put/set
the value as an own property of the object itself.
2020-03-19 17:44:06 +01:00
Andreas Kling
07679e347c LibJS: Parse FunctionExpressions
FunctionExpression is mostly like FunctionDeclaration, except the name
is optional. Share the parsing logic in parse_function_node<NodeType>.

This allows us to do nice things like:

    document.addEventListener("DOMContentLoaded", function() {
        alert("Hello friends!");
    });
2020-03-19 11:54:11 +01:00
Andreas Kling
b1b4c9844e LibJS: Add FunctionExpression AST node
Most of the code is shared with FunctionDeclaration, so the shared bits
are moved up into a common base called FunctionNode.
2020-03-19 11:12:08 +01:00
Andreas Kling
f0b49ae04b LibJS: Fix reference leak in ASTNode::append()
Using make<T> like this would create an unadopted object whose refcount
would never reach zero.
2020-03-19 11:02:20 +01:00
Andreas Kling
961b4f2577 LibJS: Add missing copyright headers 2020-03-18 20:21:06 +01:00
Andreas Kling
a119b61782 LibJS: Add Handle<T>, a strong C++ handle for keeping GC objects alive
This is pretty heavy and unoptimized, but it will do the trick for now.
Basically, Heap now has a HashTable<HandleImpl*> and you can call
JS::make_handle(T*) to construct a Handle<T> that guarantees that the
pointee will always survive GC until the Handle<T> is destroyed.
2020-03-18 20:03:17 +01:00
Andreas Kling
97674da502 LibJS: Tolerate NativeFunction::call() with non-object 'this' for now
I'm not exactly sure why we end up in this situation, we'll have to
look into it.
2020-03-18 17:13:22 +01:00
Andreas Kling
f64f7a4787 LibJS: Add Function to Forward.h 2020-03-18 17:13:22 +01:00
Andreas Kling
e96ef450f6 LibJS: Add Interpreter::call(Function*, this_value, arguments)
This helper function takes care of pushing/popping a call frame so you
don't need to worry about it.
2020-03-18 17:13:22 +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
Conrad Pankoff
46a897b59b LibJS: Implement typeof operator 2020-03-17 21:28:02 +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
bf9912cc59 LibJS: Protect function call "this" and arguments from GC
This patch adds a CallFrame stack to Interpreter, which keeps track of
the "this" value and all argument values passed in function calls.

Interpreter::gather_roots() scans the call stack, making sure that all
argument values get marked. :^)
2020-03-17 11:06:00 +01:00
Andreas Kling
cb2e7d1c5f LibJS+js: Add a debug option (js -g) to GC after every allocation
This is very useful for discovering collector bugs.
2020-03-16 19:18:46 +01:00
Andreas Kling
ab404a2f88 LibJS: Implement basic conservative garbage collection
We now scan the stack and CPU registers for potential pointers into the
GC heap, and include any valid Cell pointers in the set of roots.

This works pretty well but we'll also need to solve marking of things
passed to native functions, since those are currently in Vector<Value>
and the Vector storage is on the heap (not scanned.)
2020-03-16 19:14:09 +01:00
Andreas Kling
086f68e878 LibJS: Replace the global print() function with console.log() :^) 2020-03-16 14:58:20 +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
0xtechnobabble
dfbaa8e543 LibJS: Implement abstract equality and inequality 2020-03-16 13:42:13 +01:00