literal methods; add EnvrionmentRecord fields and methods to
LexicalEnvironment
Adding EnvrionmentRecord's fields and methods lets us throw an exception
when |this| is not initialized, which occurs when the super constructor
in a derived class has not yet been called, or when |this| has already
been initialized (the super constructor was already called).
Previously, debugging a test with console.log statements was impossible,
because it would just cause the test to fail with no additional output.
Now, if the output of a test is not "PASS", the output will be printed
under the line where the test failed.
Empty output will have a special message attached to it -- useful when
a test author has forgotten to include `console.log("PASS")` at the end
of a test.
Includes all traps except the following: [[Call]], [[Construct]],
[[OwnPropertyKeys]].
An important implication of this commit is that any call to any virtual
Object method has the potential to throw an exception. These methods
were not checked in this commit -- a future commit will have to protect
these various method calls throughout the codebase.
This patch adds function declaration hoisting. The mechanism
is similar to var hoisting. Hoisted function declarations are to be put
before the hoisted var declarations, hence they have to be treated
separately.
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.
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.
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.
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.
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.
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.