summaryrefslogtreecommitdiff
path: root/Libraries/LibJS/Runtime/Value.cpp
AgeCommit message (Collapse)Author
2020-05-28LibJS: Implement standard semantics for relational operators (#2417)Marcin Gasperowicz
Previously, the relational operators where casting any value to double and comparing the results according to C++ semantics. This patch makes the relational operators in JS behave according to the standard specification. Since we don't have BigInt yet, the implementation doesn't take it into account. Moved PreferredType from Object to Value. Value::to_primitive now passes preferred_type to Object::to_primitive.
2020-05-23LibJS: Treat NaN in Value::to_i32() as zeroLinus Groh
Let's treat it as zero like the ECMAScript spec does in toInteger(). That way we can use to_i32() and don't have to care about weird input input values where a number is expected, i.e. "foo".charAt() === "f" "foo".charAt("bar") === "f" "foo".charAt(0) === "f"
2020-05-22LibJS: Make Array.prototype.push() genericLinus Groh
2020-05-21LibJS: Add getter/setter supportMatthew Olsson
This patch adds a GetterSetterPair object. Values can now store pointers to objects of this type. These objects are created when using Object.defineProperty and providing an accessor descriptor.
2020-05-18LibJS: Remove is_nan() check in as_size_t() and fix to_size_t()Linus Groh
We need to call as_double() on the freshly converted number, not the value itself.
2020-05-18LibJS: Rename to_{i32,size_t}() to as_{i32,size_t}() for clarityLinus Groh
As these parameter-less overloads don't change the value's type and just assume Type::Number, naming them as_i32() and as_size_t() is more appropriate.
2020-05-18LibJS: Check for exception after converting object to string primitiveLinus Groh
2020-05-18LibJS: Throw TypeError when coercing symbol to numberLinus Groh
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-17LibJS: Add symbol objectsmattco98
This commit adds the following classes: SymbolObject, SymbolConstructor, SymbolPrototype, and Symbol. This commit does not introduce any new functionality to the Object class, so they cannot be used as property keys in objects.
2020-05-15LibJS: Add side-effect-free version of Value::to_string()Andreas Kling
There are now two API's on Value: - Value::to_string(Interpreter&) -- may throw. - Value::to_string_without_side_effects() -- will never throw. These are some pretty big sweeping changes, so it's possible that I did some part the wrong way. We'll work it out as we go. :^) Fixes #2123.
2020-05-13LibJS: Trim whitespace from string before coercing to numberLinus Groh
2020-05-13LibJS: Make string to number coercion work for doublesLinus Groh
2020-05-13LibJS: Handle empty values in operator<<()Linus Groh
Otherwise something like dbg() << Value(); chokes on ASSERT_NOT_REACHED() in Value::to_string()
2020-05-08LibJS: Spec-compliant equality comparisonsMatthew Olsson
The ECMAScript spec defines multiple equality operations which are used all over the spec; this patch introduces them. Of course, the two primary equality operations are AbtractEquals ('==') and StrictEquals ('==='), which have been renamed to 'abstract_eq' and 'strict_eq' in this patch. In support of the two operations mentioned above, the following have also been added: SameValue, SameValueZero, and SameValueNonNumeric. These are important to have, because they are used elsewhere in the spec aside from the two primary equality comparisons.
2020-05-06LibJS: Add Value::{is, as}_function()Linus Groh
2020-05-01LibJS: Implement most of the Reflect objectLinus Groh
2020-05-01LibJS: Add Value::to_size_t()Linus Groh
2020-04-29LibJS: Throw error in Object::to_string() if string conversion failsLinus Groh
2020-04-29LibJS: Make Value::as_string() return a PrimitiveString referenceAndreas Kling
2020-04-29LibJS: Don't handle arrays separately in Value::to_number()Linus Groh
Now that Array.prototype.join() is producing the correct results we can remove the separate code path for arrays in Value::to_number() and treat them like all other objects - using to_primitive() with number as the preferred type and then calling to_number() on the result. This is how the spec descibes it. This also means we don't crash anymore when trying to coerce [<empty>] to a number - it now does the following: [<empty>] - to string - "" - to number - 0 [<empty>, <empty>] - to string - "," - to number - NaN
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-23LibJS: Fix left shift operatorLinus Groh
Typo causing it to compute lhs << lhs, not lhs << rhs as expected.
2020-04-23LibJS: Implement 'in' operatorLinus Groh
2020-04-23LibJS: Implement bitwise unsigned right shift operator (>>>)Linus Groh
2020-04-23LibJS: Implement bitwise right shift operator (>>)Linus Groh
2020-04-23LibJS: Implement bitwise left shift operator (<<)Linus Groh
2020-04-18LibJS: Pass prototype to BooleanObject constructorAndreas Kling
2020-04-18LibJS: Pass prototype to StringObject constructorAndreas Kling
2020-04-18LibJS: Pass prototype to NumberObject constructorAndreas Kling
2020-04-15LibJS: Adding two values should convert them to primitives firstAndreas Kling
2020-04-15LibJS: Pass the Interpreter& to binary/logical/unary helpersAndreas Kling
2020-04-12LibJS: Add js_negative_infinity()Linus Groh
Value(-js_infinity().as_double()) is kind of awkward.
2020-04-12LibJS: Handle Infinity in Value::to_number()Linus Groh
2020-04-12LibJS: Let's show a few more decimals when stringifying numeric valuesAndreas Kling
I'm not sure what the correct behavior is supposed to be, but at least this makes printing numbers show some more interesting detail for now.
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-08LibJS: Add Value::to_double() for convenienceAndreas Kling
2020-04-07LibJS: Add Boolean constructor objectJack Karamanian
2020-04-07LibJS: Return false for NaN numbers in Value::to_boolean()Jack Karamanian
2020-04-06LibJS: Inline JS::Value()Andreas Kling
I had this out of line for debugging reasons. Put it back inline.
2020-04-06LibJS: Support array holes, encoded as empty JS::ValueAndreas Kling
This patch adds a new kind of JS::Value, the empty value. It's what you get when you do JSValue() (or most commonly, {} in C++.) An empty Value signifies the absence of a value, and should never be visible to JavaScript itself. As of right now, it's used for array holes and as a return value when an exception has been thrown and we just want to unwind. This patch is a bit of a mess as I had to fix a whole bunch of code that was relying on JSValue() being undefined, etc.
2020-04-05LibJS: Implement exponentiation (** operator)Linus Groh
2020-04-05LibJS: Add support for floating point modulousBrian Gianforcaro
This change implements floating point mod based on the algorithm used in LibM's fmod() implementation. To avoid taking a dependency on LibM from LibJS I reimplemented the formula in LibJS. I've incuded some of the example MDM test cases as well. This surfaced and issue handling NaN which I've fixed as well.
2020-04-05LibJS: Correctness fixes for bitwise_or, address FIXME's in test.Brian Gianforcaro
2020-04-04LibJS: Add NumberObject and make to_object() on number values create itAndreas Kling
2020-04-04LibJS: Add basic support for modulo (%) in binary expressionsAndreas Kling
2020-04-02LibJS: Implement InfinityLinus Groh
2020-04-02LibJS: Implement unary plus / minusLinus Groh
2020-04-01LibJS: Make Value::as_object() return Object&Andreas Kling
Let's move towards using references over pointers in LibJS as well. I had originally steered away from it because that's how I've seen things done in other engines. But this is not the other engines. :^)