summaryrefslogtreecommitdiff
path: root/Libraries/LibJS/Runtime/Array.cpp
AgeCommit message (Collapse)Author
2020-10-13LibJS: Cache commonly used FlyStrings in the VMAndreas Kling
Roughly 7% of test-js runtime was spent creating FlyStrings from string literals. This patch frontloads that work and caches all the commonly used names in LibJS on a CommonPropertyNames struct that hangs off VM.
2020-09-27LibJS: Remove a bunch of unnecessary uses of Cell::interpreter()Andreas Kling
We'll want to get rid of all uses of this, to free up the engine from the old assumption that there's always an Interpreter available.
2020-09-27LibJS: Make native function/property callbacks take VM, not InterpreterAndreas Kling
More work on decoupling the general runtime from Interpreter. The goal is becoming clearer. Interpreter should be one possible way to execute code inside a VM. In the future we might have other ways :^)
2020-09-27LibJS: Move most of Interpreter into VMAndreas Kling
This patch moves the exception state, call stack and scope stack from Interpreter to VM. I'm doing this to help myself discover what the split between Interpreter and VM should be, by shuffling things around and seeing what falls where. With these changes, we no longer have a persistent lexical environment for the current global object on the Interpreter's call stack. Instead, we push/pop that environment on Interpreter::run() enter/exit. Since it should only be used to find the global "this", and not for variable storage (that goes directly into the global object instead!), I had to insert some short-circuiting when walking the environment parent chain during variable lookup. Note that this is a "stepping stone" commit, not a final design.
2020-06-23LibJS: Clarify Object (base class) construction somewhatAndreas Kling
Divide the Object constructor into three variants: - The regular one (takes an Object& prototype) - One for use by GlobalObject - One for use by objects without a prototype (e.g ObjectPrototype)
2020-06-20LibJS: Make Value::to_object() take a GlobalObject&Andreas Kling
2020-06-20LibJS: More Interpreter::global_object() removalAndreas Kling
Also let's settle on calling the operation of fetching the "this" value from the Interpreter and converting it to a specific Object pointer typed_this() since consistency is nice.
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-20LibJS: Pass GlobalObject& to native functions and property accessorsAndreas Kling
More work towards supporting multiple global objects. Native C++ code now get a GlobalObject& and don't have to ask the Interpreter for it. I've added macros for declaring and defining native callbacks since this was pretty tedious and this makes it easier next time we want to change any of these signatures.
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: 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-05-28LibJS: Object index properties have descriptors; Handle sparse indicesMatthew Olsson
This patch adds an IndexedProperties object for storing indexed properties within an Object. This accomplishes two goals: indexed properties now have an associated descriptor, and objects now gracefully handle sparse properties. The IndexedProperties class is a wrapper around two other classes, one for simple indexed properties storage, and one for general indexed property storage. Simple indexed property storage is the common-case, and is simply a vector of properties which all have attributes of default_attributes (writable, enumerable, and configurable). General indexed property storage is for a collection of indexed properties where EITHER one or more properties have attributes other than default_attributes OR there is a property with a large index (in particular, large is '200' or higher). Indexed properties are now treated relatively the same as storage within the various Object methods. Additionally, there is a custom iterator class for IndexedProperties which makes iteration easy. The iterator skips empty values by default, but can be configured otherwise. Likewise, it evaluates getters by default, but can be set not to.
2020-05-27LibJS: Simplify and normalize publicly-exposed Object functionsMatthew Olsson
Previously, the Object class had many different types of functions for each action. For example: get_by_index, get(PropertyName), get(FlyString). This is a bit verbose, so these methods have been shortened to simply use the PropertyName structure. The methods then internally call _by_index if necessary. Note that the _by_index have been made private to enforce this change. Secondly, a clear distinction has been made between "putting" and "defining" an object property. "Putting" should mean modifying a (potentially) already existing property. This is akin to doing "a.b = 'foo'". This implies two things about put operations: - They will search the prototype chain for setters and call them, if necessary. - If no property exists with a particular key, the put operation should create a new property with the default attributes (configurable, writable, and enumerable). In contrast, "defining" a property should completely overwrite any existing value without calling setters (if that property is configurable, of course). Thus, all of the many JS objects have had any "put" calls changed to "define_property" calls. Additionally, "put_native_function" and "put_native_property" have had their "put" replaced with "define". Finally, "put_own_property" has been made private, as all necessary functionality should be exposed with the put and define_property methods.
2020-05-18LibJS: Pass Interpreter& to Value::to_number() et al.Linus Groh
This patch is unfortunately rather large and might make some things feel bloated, but it is necessary to fix a few flaws in LibJS, primarily blindly coercing values to numbers without exception checks - i.e. interpreter.argument(0).to_i32(); // can fail!!! Some examples where the interpreter would actually crash: var o = { toString: () => { throw Error() } }; +o; o - 1; "foo".charAt(o); "bar".repeat(o); To fix this, we now have the following... to_double(Interpreter&) to_i32() to_i32(Interpreter&) to_size_t() to_size_t(Interpreter&) ...and a whole lot of exception checking. There's intentionally no to_double(), use as_double() directly instead. This way we still can use these convenient utility functions but don't need to check for exceptions if we are sure the value already is a number. Fixes #2267.
2020-05-18LibJS: Change Value::to_object(Heap& -> Interpreter&)Linus Groh
Passing a Heap& to it only to then call interpreter() on that is weird. Let's just give it the Interpreter& directly, like some of the other to_something() functions.
2020-05-01LibJS: Make Array.length non-configurableLinus Groh
This was incorrect, it's only writable.
2020-04-29LibJS: Set Array length attributes to "Configurable | Writable"mattco98
2020-04-23LibJS: Implement Array length setterLinus Groh
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+LibWeb: Pass prototype to Object constructorAndreas Kling
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-18LibJS: Make Array constructor take its prototypeAndreas Kling
Let's start moving towards native JS objects taking their prototype as a constructor argument. This will eventually allow us to move prototypes off of Interpreter and into GlobalObject.
2020-04-14LibJS: Remove shift, pop, push functions from Array objectLinus Groh
This abstraction isn't really that useful, as we can access the underlying Vector<Value> using elements() and operate on it directly.
2020-04-10LibJS: Throw real TypeError, ReferenceError, etc objectsAndreas Kling
Instead of just throwing Error objects with a name string, we now throw the real Error subclass types. :^)
2020-04-06LibJS: Add a number-indexed property storage to all ObjectsAndreas Kling
Objects can have both named and indexed properties. Previously we kept all property names as strings. This patch separates named and indexed properties and splits them between Object::m_storage and m_elements. This allows us to do much faster array-style access using numeric indices. It also makes the Array class much less special, since all Objects now have number-indexed storage. :^)
2020-03-29LibJS+LibWeb: Move native properties to separate getters/settersAndreas Kling
This was a bit cumbersome now, but it gets us closer to a format suited for code generation.
2020-03-28LibJS: Implement Array.prototype.{shift,pop}Linus Groh
2020-03-24LibJS: Use correct |this| value when getting/setting native propertiesAndreas Kling
2020-03-22LibJS: Use FlyString for identifiersAndreas Kling
This makes variable and property lookups a lot faster since comparing two FlyStrings is O(1).
2020-03-21LibJS: Virtualize access to an Object's own propertiesAndreas Kling
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-20LibJS: Add ArrayPrototype and implement Array.prototype.push()Andreas Kling
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-20LibJS: Parse ArrayExpression and start implementing Array objectsAndreas Kling
Note that property lookup is not functional yet.