This patch adds `Array.prototype.reduceRight()` method to LibJS Runtime. The implementation is (to my best knowledge) conformant to https://tc39.es/ecma262/#sec-array.prototype.reduceright.
Short test in `LibJS/Tests/Array.prototype-generic-functions.js` demonstrates that the function can be applied to other objects besides `Array`.
This changes Accessor's m_{getter,setter} from Value to Function* which
seems like a better API to me - a getter/setter must either be a
function or missing, and the creation of an accessor with other values
must be prevented by the parser and Object.defineProperty() anyway.
Also add Accessor::set_{getter,setter}() so we can reuse an already
created accessor when evaluating an ObjectExpression with getter/setter
shorthand syntax.
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.
This patch adds `Array.prototype.reduce()` method to LibJS Runtime.
The implementation is (to my best knowledge) comformant to ECMA262.
The test `Array.prototype-generic-functions.js` demonstrates that the
function can be applied to other objects besides `Array`.
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"
Lagom now builds under macOS. Only two minor adjustments were required:
* LibCore TCP/UDP code can't use `SOCK_{NONBLOCK,CLOEXEC}` on macOS,
use ioctl() and fcntl() instead
* LibJS `Heap` code pthread usage ported to MacOS
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.
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.
This saves us both a bit of time and accuracy, as Serenity's strtod()
still is a little bit off sometimes - and stringifying the result and
parsing it again just increases that offset.
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.
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.
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.
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.
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.
Rather than printing them to stderr directly the parser now keeps a
Vector<Error>, which allows the "owner" of the parser to consume them
individually after parsing.
The Error struct has a message, line number, column number and a
to_string() helper function to format this information into a meaningful
error message.
The Function() constructor will now include an error message when
throwing a SyntaxError.
Giving the lexer the ability to generate errors adds unnecessary
complexity - also it only calls its syntax_error() function in one place
anyway ("unterminated string literal"). But since the lexer *also* emits
tokens like Eof or UnterminatedStringLiteral, it should be up to the
consumer of these tokens to decide what to do.
Also remove the option to not print errors to stderr as that's not
relevant anymore.
There are many cases which shouldn't even parse, like
null = ...
true = ...
false = ...
123 = ...
"foo" = ...
However this *is* valid syntax:
foo() = ...
So we still have to keep the current code doing a runtime check if the
LHS value is a resolvable reference. I believe this was declared valid
syntax to *in theory* allow functions returning references - though in
practice that isn't a thing.
Fixes#2204.