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

623 commits

Author SHA1 Message Date
Jack Karamanian
b0932b0aec LibJS: Allow null or undefined as a bound |this| value in strict mode 2020-06-03 08:19:03 +02:00
Linus Groh
4f6912c605 LibJS: Store basic traceback in Exception
Nothing fancy like line numbers, but Exception now stores a list of
function names up to the current call frame.
2020-06-02 15:22:34 +02:00
Linus Groh
a48080f62d LibJS: Move Interpreter::get_trace() to ConsoleClient
Having it globally on the interpreter is confusing as the last call frame
is skipped, which is specific to console.trace().
2020-06-02 15:22:34 +02:00
Linus Groh
9e3127785e LibJS: Remove dummy implementations from Console methods
Having these duplicated is not really useful, either we want console
output to go somewhere then implementing a console client is the way to
go, or we don't care about console output - in that case we don't need
to dbg() either.
2020-06-02 15:22:34 +02:00
Linus Groh
b32761f2e0 LibJS: Consider non-extensible objects in Reflect.setPrototypeOf() 2020-06-02 13:51:02 +02:00
Linus Groh
c1248a7fd8 LibJS: Implement Reflect.{isExtensible,preventExtensions}() 2020-06-02 13:51:02 +02:00
Linus Groh
b958e4f573 LibJS: Disallow changing the prototype of non-extensible objects
Object::set_prototype() now returns a boolean indicating success.
Setting the prototype to an identical object is always considered
successful, even if the object is non-extensible.
2020-06-02 13:51:02 +02:00
Linus Groh
8cf1ded478 LibJS: Don't assume Object.setPrototypeOf() prototype value is an object
We're crashing otherwise. Also it was not possible to set the prototype
to null.
2020-06-02 13:51:02 +02:00
Linus Groh
1a64bdd80c LibJS: Return specified object from Object.setPrototypeOf()
We were leaking an empty value.
2020-06-02 13:51:02 +02:00
Matthew Olsson
d5ae73a63b LibJS: Add Object.{isExtensible,preventExtensions}() 2020-06-02 08:50:26 +02:00
Sergey Bugaev
600fcd2d46 LibJS: Replace some parser assertions by syntax errors
When parsing JavaScript, we can get pretty much any sequnce of tokens,
and we shouldn't crash if it's not something that we normally expect.
Instead, emit syntax errors.
2020-06-01 17:37:44 +02:00
Sergey Bugaev
2fbc37befc LibJS: Fix undefined behavior in HeapBlock
In C++, it's invalid to cast a block of memory to a complex type without
invoking its constructor. It's even more invalid to simply cast a pointer to a
block of memory to a pointer to *an abstract type*.

To fix this, make sure FreelistEntry is a concrete type, and call its
constructor whenever appropriate.
2020-06-01 17:37:44 +02:00
Sergey Bugaev
53a94b8bbd LibJS: Fix casting a value to ScriptFunction without checking it's one 2020-06-01 17:37:44 +02:00
Sergey Bugaev
1274c244d5 LibJS: Fix out-of-bounds read when parsing escape sequences
We cannot look at i+1'th character until we verify it's there.
2020-06-01 17:37:44 +02:00
Matthew Olsson
ab576e610c LibJS: Rewrite Parser.parse_object_expression()
This rewrite drastically increases the accuracy of object literals.
Additionally, an "assertIsSyntaxError" function has been added to
test-common.js to assist in testing syntax errors.
2020-06-01 13:11:21 +02:00
Linus Groh
e33820b557 LibJS: Add String.fromCharCode() 2020-05-31 02:19:52 +02:00
Andreas Kling
29ab518003 LibJS: Show run-tests progress in the taskbar
Use the window progress escape sequence to indicate how far along in
the test collection we are while running tests. :^)
2020-05-30 23:00:35 +02:00
Jack Karamanian
d4e97b17ab LibJS: Use a non-arrow function to check the |this| value in the
callback for Array.prototype.{reduce,reduceRight}

Arrow functions always retain the |this| binding.

Running this code in Node:

[1, 2].reduce(() => { "use strict"; console.log(this === undefined) }

Output: false
2020-05-30 10:33:24 +02:00
Jack Karamanian
4a49c8412c LibJS: Add tests ensuring the |this| value can't be set for arrow
functions in Function.prototype.{call,apply}
2020-05-30 10:33:24 +02:00
Jack Karamanian
f4129ac422 LibJS: Use the function's bound |this| and bound arguments in
Interpreter::call()
2020-05-30 10:33:24 +02:00
Jack Karamanian
3ffb0a4e87 LibJS: Throw a TypeError when an arrow function is used as a constructor 2020-05-30 10:33:24 +02:00
Jack Karamanian
1110b1b444 LibJS: Don't define the "prototype" property for arrow functions 2020-05-30 10:33:24 +02:00
Jack Karamanian
45ccd9f8d9 LibJS: Set the bound |this| value to the |this| value of the current
scope for arrow functions
2020-05-30 10:33:24 +02:00
Jack Karamanian
c12125fa81 LibJS: Track whether ScriptFunctions and FunctionExpressions are arrow
functions
2020-05-30 10:33:24 +02:00
Jack Karamanian
5243e9974d LibJS: Remove unnecessary explicit from the 3 argument Function
constructor
2020-05-30 10:33:24 +02:00
Matthew Olsson
4e331a1fcf LibJS: Object.getOwnPropertyDescriptor works properly with accessors 2020-05-30 10:32:52 +02:00
Marcin Gasperowicz
4e8de753c9 LibJS: Parse arrow function expression with correct precedence
The parser was chomping on commas present after the arrow function expression. eg. [x=>x,2] would parse as [x=>(x,2)] instead of [(x=>x),2].

This is not the case anymore. I've added a small test to prove this.
2020-05-30 00:33:18 +02:00
FalseHonesty
2619d72eeb LibJS: Add all remaining tokens to MarkupGenerator's style converter 2020-05-29 22:14:45 +02:00
Matthew Olsson
d52ea37717 LibJS: Integrate labels into the Interpreter
The interpreter now considers a statement or block's label when
considering whether or not to break. All statements can be labelled.
2020-05-29 16:20:32 +02:00
Matthew Olsson
03615a7872 LibJS: Parse labels in continue and break statements 2020-05-29 16:20:32 +02:00
Matthew Olsson
10bf4ba3dc LibJS: Parse labelled statements
All statements now have an optional label string that can be null.
2020-05-29 16:20:32 +02:00
Matthew Olsson
5cd01ed79e LibJS: New expressions look for expressions with correct precedence 2020-05-29 15:56:39 +02:00
Linus Groh
688ca7b196 LibJS: Make Object::invoke() non-const
As suggested in #2431's code review.
2020-05-29 15:55:40 +02:00
Linus Groh
1dd44210b7 LibJS: Add Array.prototype.toLocaleString() 2020-05-29 08:00:02 +02:00
Linus Groh
70d2add22f LibJS: Add Object.prototype.toLocaleString() 2020-05-29 08:00:02 +02:00
Linus Groh
9755f8d297 LibJS: Add Object::invoke() 2020-05-29 08:00:02 +02:00
Emanuele Torre
937d0be762 Meta: Add a script check the presence of "#pragma once" in header files
.. and make travis run it.

I renamed check-license-headers.sh to check-style.sh and expanded it so
that it now also checks for the presence of "#pragma once" in .h files.

It also checks the presence of a (single) blank line above and below the
"#pragma once" line.

I also added "#pragma once" to all the files that need it: even the ones
we are not check.
I also added/removed blank lines in order to make the script not fail.

I also ran clang-format on the files I modified.
2020-05-29 07:59:45 +02:00
Matthew Olsson
664085b719 LibJS: Fix conditional expression precedence
This fixes the following from parsing incorrectly due to the comma
that occurs after the conditional:

  let o = {
    foo: true ? 1 : 2,
    bar: 'baz',
  };
2020-05-29 07:57:14 +02:00
Linus Groh
8ff4587f65 LibJS: Throw in strict mode when assigning property to primitive value 2020-05-29 07:45:22 +02:00
Marcin Gasperowicz
eadce65e04
LibJS: Implement standard semantics for relational operators (#2417)
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-28 17:19:59 +02:00
Matthew Olsson
cbe506020b LibJS: Strict mode assignment to 'eval' & 'arguments' is a syntax error 2020-05-28 17:18:42 +02:00
Matthew Olsson
786722149b LibJS: Add strict mode
Adds the ability for a scope (either a function or the entire program)
to be in strict mode. Scopes default to non-strict mode.

There are two ways to determine the strict-ness of the JS engine:

1. In the parser, this can be accessed with the parser_state variable
   m_is_strict_mode boolean. If true, the Parser is currently parsing in
   strict mode. This is done so that the Parser can generate syntax
   errors at parse time, which is required in some cases.

2. With Interpreter.is_strict_mode(). This allows strict mode checking
   at runtime as opposed to compile time.

Additionally, in order to test this, a global isStrictMode() function
has been added to the JS ReplObject under the test-mode flag.
2020-05-28 17:18:42 +02:00
Matthew Olsson
5ae9419a06 LibJS: Object index properties have descriptors; Handle sparse indices
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-28 17:17:13 +02:00
Matthew Olsson
cc54974431 LibJS: Fix out-of-range error in Parser::Error::source_location_hint 2020-05-28 17:02:16 +02:00
Linus Groh
99e775cee3 LibJS: Reformat ArrayPrototype.cpp 2020-05-27 19:51:52 +02:00
Matthew Olsson
dd08c992e8 LibJS: Simplify and normalize publicly-exposed Object functions
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-27 13:17:35 +02:00
Angel
199a6b40b3 LibJS: Add Array.prototype.fill 2020-05-26 20:34:44 +02:00
Emanuele Torre
d1bc1f5783
LibJS: Fix style inconsistencies in AST.h (#2403)
Our current configuration clang-format allows both of these styles:
------------------
    class A : B
        , C {
-----------------
    class A
        : B
        , C {
------------------

I was not able to find a setting of clang-format to only allow the
latter style (or disallow the first style), but let's at least be
consistent with the style within a file.
2020-05-26 19:52:03 +02:00
Paul Redmond
11405c5139
LibJS: Fix incorrect token column values (#2401)
- initializing m_line_column to 1 in the lexer results in incorrect
  column values in tokens on the first line of input.
- not incrementing m_line_column when EOF is reached results in
  an incorrect column value on the last token.
2020-05-26 19:00:30 +02:00
Linus Groh
2d47b30256 LibJS: Add Error::source_location_hint()
This util function on the Error struct will take the source and then
returns a string like this based on line and column information it has:

foo bar
    ^

Which can be shown in the repl for syntax errors :^)
2020-05-26 14:36:30 +02:00