Age | Commit message (Collapse) | Author |
|
- Ensure that testing for array membership does strict equality tests
- Ensure that `(NaN in [ NaN ]) == true`
- Do not perform implicit value conversion when testing for object keys,
to avoid nonsensical results such as `([] in { "[ ]": true }) == true`
- Add test cases for the `in` operator
Fixes: #193
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Adjust expected testcase outputs after double format change in the
previous commit.
Fixes: 4c654df ("types: adjust double printing format")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
The compiler emitted incorrect bytecode for logical assignment operations
on property expressions. The generated instructions left the stack in an
unclean state when the assignment condition was not fulfilled, causing a
stack layout mismatch between compiler and vm, leading to undefined
variable accesses and other non-deterministic behavior.
Solve this issue by rewriting the bytecode generation to yield an
instruction sequence that does not leave garbage on the stack.
The implementation is not optimal yet, as an expression in the form
`obj.prop ||= val` will load `obj.prop` twice. This is acceptable for
now as the load operation has no side effect, but should be solved in
a better way by introducing new instructions that allow for swapping
stack slots, allowing the vm to operate on a copy of the loaded value.
Also rewrite the corresponding test case to trigger a runtime error
on code versions before this fix.
Fixes: fdc9b6a ("compiler: fix `??=`, `||=` and `&&=` logical assignment semantics")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Follow ES6 semantics and ensure that arrow functions with a block body
don't implicitly return the value of the last executed statement.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
When compiling logical assignment expressions, ensure that the right hand
side of the assignment is not evaluated when the assignment condition is
unfulfilled.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Ensure that regexp extension escapes are consistently handled;
substitute `\d`, `\D`, `\s`, `\S`, `\w` and `\W` with `[[:digit:]]`,
`[^[:digit:]]`, `[[:space:]]`, `[^[:space:]]`, `[[:alnum:]_]` and
`[^[:alnum:]_]` character classes respectively since not all POSIX
regexp implementations implement all of those extensions
- Preserve `\b`, `\B`, `\<` and `\>` boundary matches
Fixes: a45f2a3 ("lexer: improve regex literal handling")
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Do not treat slashes within bracket expressions as delimitters
- Do not escape slashes when stringifying regex sources
- Allow all escape sequence types in regex literals
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Recognize new number literal prefixes `0o` and `0O` for octal as well
as `0b` and `0B` for binary number literals
- Treat number literals with leading zeros as octal while parsing but
as decimal ones on implicit number conversions, means `012` will yield
`10` while `+"012"` or `"012" + 0` will yield `12`
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Implement support for ECMAScript 6 template literals which allow simple
interpolation of variable values into strings without resorting to
`sprintf()` or manual string concatenation.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Different libc implementations produce different syntax error messages
on invalid regular expression patterns, so rework the test case to
produce stable output across all environments.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Support ES2016 exponentiation (**) and exponentiation assignment (**=)
- Support ES2020 nullish coalescing (??) and logical nullish assignment (??=)
- Support ES2021 logical and assignment (&&=) and logical or assignment (||=)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
- Parse integer literals as unsigned numeric values in order to be able
to represent the entire unsigned 64bit value range
- Stop parsing minus-prefixed integer literals as negative numbers but
treat them as separate minus operator followed by a positive integer
instead
- Only store unsigned numeric constants in bytecode
- Rework numeric comparison logic to be able to handle full 64bit
unsigned integers
- If possible, yield unsigned 64 bit results for additions
- Simplify numeric value conversion API
- Compile code with -fwrapv for defined signed overflow semantics
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Introduce new operators `?.`, `?.[…]` and `?.(…)` to simplify looking up
deeply nested property chain in a secure manner.
The `?.` operator behaves like the `.` property access operator but yields
`null` if the left hand side is `null` or not an object.
Like `?.`, the `?.[…]` operator behaves like the `[…]` computed property
access but yields `null` if the left hand side is `null` or neither an
object or array.
Finally the `?.(…)` operator behaves like the function call operator `(…)`
but yields `null` if the left hand side is `null` or not a callable
function.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
In a loop statement like `for (let x = 1, y = 2; ...)` the initialization
statement was incorrectly interpreted as `let x = 1; y = 2` instead of the
correct `let ..., y = 2`, triggering reference error exceptions in strict
mode.
Solve the issue by continue parsing the rest of the comma expression
seqence as declaration list expression when the initializer is compiled
in local mode.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Support per-file and per-function `"use strict";` statement to opt into
strict variable handling from ucode source code.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Instead of relying on json_object values internally, use custom types to
represent the different ucode value types which brings a number of
advantages compared to the previous approach:
- Due to the use of tagged pointers, small integer, string and bool
values can be stored directly in the pointer addresses, vastly
reducing required heap memory
- Ability to create circular data structures such as
`let o; o = { test: o };`
- Ability to register custom `tostring()` function through prototypes
- Initial mark/sweep GC implementation to tear down circular object
graphs on VM deinit
The change also paves the way for possible future extensions such as
constant variables and meta methods for custom ressource types.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
|
|
Signed-off-by: Petr Štetiar <ynezz@true.cz>
|