Commit graph

230 commits

Author SHA1 Message Date
Saúl Ibarra Corretgé
a3132cabbc Merge JS_ToBigInt64Free into JS_ToInt64Free 2024-05-27 09:55:17 +02:00
Icemic
569f51fba2 Add JS_GetLength 2024-05-27 08:41:40 +02:00
Icemic
9a2a246b51 Add JS_FreePropertyEnum corresponding to JS_GetOwnPropertyNames 2024-05-27 08:41:40 +02:00
Charlie Gordon
921c1eef50
Simpler utf8_decode (#414)
- no longer pass the array length to `utf8_decode`
- add `utf8_decode_len` for border cases
- use switch based dispatch in `utf8_decode_len` to work around a gcc 12.2 optimizer bug
2024-05-27 08:15:52 +02:00
Charlie Gordon
9e67b47c0d
Improve number to string conversions (#400)
integer conversions:
- improve `u32toa_radix` and `u64toa_radix`, add `i32toa_radix`
- use `i32toa_radix` for small ints in `js_number_toString`

floating point conversions (`js_dtoa`):
- complete rewrite with fewer calls to `snprintf`
- remove `JS_DTOA_FORMAT`, define 4 possible modes for `js_dtoa`
- remove the radix argument in `js_dtoa`
- merge `js_dtoa1` into `js_dtoa`
- add `js_dtoa_infinite` for non finite values
- simplify sign handling
- handle locale specific decimal point transparently

helper function `js_fcvt`:
- simplify `js_fcvt`, remove `js_fcvt1`, reduce overhead
- round up manually instead of using `fesetround(FE_UPWARD)`.

helper function `js_ecvt`:
- document `js_ecvt` and `js_ecvt1` behavior
- avoid redundant `js_ecvt1` calls in `js_ecvt`
- fixed buffer contents, no buffer copies
- simplify decimal point handling
- round up manually instead of using `fesetround(FE_UPWARD)`.

miscellaneous:
- remove `CONFIG_PRINTF_RNDN`. This fixes some of the conversion errors
  on Windows. Updated the tests accordingly
- this fixes a v8.sh bug on macOS: `0.5.toFixed(0)` used to produce `0` instead of `1`
- add regression tests, update test_conv unit tests
- add benchmarks for `toFixed`, `toPrecision` and `toExponential` number methods
- benchmarks show all conversions are now 40 to 45% faster (M2)
2024-05-26 08:06:36 +02:00
Charlie Gordon
139b51fe4b
Simplify number parsing (#386)
- use single test in `js_strtod` loop.
- use more explicit `ATOD_xxx` flags
- remove `ATOD_TYPE_MASK`, use `ATOD_WANT_BIG_INT` instead
- remove unused arguments `flags` and `pexponent` in `js_string_to_bigint`
- merge `js_atof` and `js_atof2`, remove `slimb_t *pexponent` argument
- simplify and document `js_atof` parser, remove cumbersome labels,
- simplify `js_parseInt` test for zero radix for `ATOD_ACCEPT_HEX_PREFIX`
- simplify `next_token` number parsing, handle legacy octal in parser only
- simplify `JS_StringToBigInt`, use flags only.
- remove unused `slimb_t exponent` token field
- add number syntax tests
2024-05-26 00:17:04 +02:00
Charlie Gordon
1baa6763f8
Improve UTF-8 decoding and encoding functions (#410)
Ensure proper UTF-8 encoding (1 to 4 bytes).
Handle invalid encodings (return 0xFFFD and consume a single byte)
Individually encoded surrogate code points are accepted.

- add `utf8_scan()` to analyze a byte array for UTF-8 contents
  detects invalid encoding, computes number of codepoints and content kind:
  plain ASCII, 8-bit, 16-bit or larger codepoints.
- add `utf8_encode_len(c)` to compute the number of bytes to encode `c`
- rename `unicode_to_utf8` as `utf8_encode`
- rename `unicode_from_utf8` as `utf8_decode`
- add `utf8_decode_buf8(dest, size, src, len)` to decode a UTF-8 encoded
  byte array known to contain only ASCII and 8-bit codepoints.
- add `utf8_decode_buf16(dest, size, src, len)` to decode a UTF-8 encoded
  byte array into an array of 16-bit codepoints using UTF-16 surrogate pairs
  for non-BMP1 codepoints.
- add `utf8_encode_buf8(dest, size, src, len)` to encode an array of 8-bit
  codepoints as a UTF-8 encoded null terminated string
- add `utf16_encode_buf8(dest, size, src, len)` to decode an array of 16-bit
  codepoints (including surrogate pairs) as a UTF-8 encoded null terminated string
- detect invalid UTF-8 encoding in RegExp parser
- simplify `JS_AtomGetStrRT`, `JS_NewStringLen` using the above functions
- simplify UTF-8 decoding and error testing
2024-05-21 14:08:33 +02:00
KaruroChori
f588210641
Cherrypick https://github.com/bellard/quickjs/pull/289 (#404)
Co-authored-by: karurochari <nope>
2024-05-18 10:15:34 +02:00
Charlie Gordon
5a7e578482
Improve parsing error messages (#405)
- output more informative error messages in `js_parse_expect`.

The previous code was bogus:
```
    return js_parse_error(s, "expecting '%c'", tok);
```
this was causing a bug on `eval("do;")` where `tok` is `TOK_WHILE` (-70, 0xBA)
creating an invalid UTF-8 encoding (lone trailing byte).
This would ultimately have caused a failure in `JS_ThrowError2` if `JS_NewString`
failed when converting the error message to a string if the conversion detected the invalid
UTF-8 encoding and throwed an error (it currently does not, but should).

- test for `JS_NewString` failure in `JS_ThrowError2`
- test for `JS_FreeCString` failure in run-test262.c
- add more test cases
2024-05-14 20:36:10 +02:00
KaruroChori
99c6719b7d
Fix invalid exception for class method with name "get"
Ref: https://github.com/bellard/quickjs/pull/258
2024-05-14 09:16:26 +02:00
Charlie Gordon
b81d4deee4
Improve internal string allocation methods (#398)
String values are allocated as temporary or final results. This commit
attempts to improve the consistency and performance of this step.

- define `JS_NewString` as an inline function to allow simple expansion
  of `strlen()` for string literals
- document string contents constraints regarding UTF-8 encoding.
- rename `js_new_string8` as `js_new_string8_len`. takes `const char *`.
- new inline function `js_new_string8` takes `const char *`, computes
  string length with `strlen` and calls `js_new_string8_len`. No overhead
  for string literals
- rename `js_new_string16` to `js_new_string16_len`
- use internal string allocation functions where appropriate, remove overhead
- allocate extra byte for null terminator in source code string
2024-05-10 12:43:35 +02:00
Charlie Gordon
f9ecc1a598
Fix encoding bug in js_dtoa_radix (#399)
- fix radix conversion rounding code: incrementing the digit
  does not work for '9'.  We can assume ASCII so it works for
  all other digits, especially all letters
- also avoid recomputing the string length
2024-05-07 19:35:34 +02:00
Saúl Ibarra Corretgé
e5ae6cf106 Fix handling of memory limit
Default to 0, which is "disabled", just like the stack limit.
2024-05-06 11:22:16 +02:00
Charlie Gordon
a77873d657
Optimize String.fromCharCode and String.fromCodePoint (#391)
- test for common case: single integer argument and create string directly
2024-04-21 08:28:02 +02:00
Charlie Gordon
83726bb00c
Add utility functions for string to integer conversions (#366)
* Add utility functions, improve integer conversion functions

- move `is_be()` to cutils.h
- add `is_upper_ascii()` and `to_upper_ascii()`
- add extensive benchmark for integer conversion variants in **tests/test_conv.c**
- add `u32toa()`, `i32toa()`, `u64toa()`, `i64toa()` based on register shift variant
- add  `u32toa_radix()`, `u64toa_radix()`, `i64toa_radix()` based on length_loop variant
- use direct converters instead of `snprintf()`
- copy NaN and Infinity directly in `js_dtoa1()`
- optimize `js_number_toString()` for small integers
- use `JS_NewStringLen()` instead of `JS_NewString()` when possible
- add more precise conversion tests in microbench.js
- disable some benchmark tests for gcc (they cause ASAN failures)
2024-04-19 11:35:44 +02:00
Charlie Gordon
f326a7a195
Add strip option in qjsc to reduce object size (#388)
- `-s` strips the source code
- `-ss` strips source and line/column numbers information
- `qjsc repl.js` generates an object size of **105726** bytes
- `qjsc -s repl.js` generates an object size of **20853** bytes
- `qjsc -ss repl.js` generates an object size of only **16147** bytes
- compile repl.js with `-ss`
- bump byte code version to 12
2024-04-19 08:41:12 +02:00
Charlie Gordon
43dc65d605
Fix potential conversion errors (#384)
- fix undefined behavior in double to int conversions
- do not pass an `int64_t` to `js_bool()`
2024-04-16 23:18:02 +02:00
bptato
29b45337f0
Fix member accesses for non-decimal numeric literals (#377)
* Fix member accesses for non-decimal numeric literals
    e.g. 0x0.a should return undefined, not SyntaxError.
* Remove ineffective non-decimal float parsing code and redundant checks on `is_float && radix != 10`
    (The code already wasn't doing anything because of the `is_float` check.)
2024-04-16 14:17:50 +02:00
Charlie Gordon
5797f2a716
Improve DUMP_READ_OBJECT (#382)
- improve `JS_DumpString`: use `L` prefix for wide strings
- dump variable kind and flags for locals and closures
- disassemble byte code in DUMP_READ_OBJECT
- pass start_pos to `dump_byte_code` and `dump_single_byte_code`
- write constant pool before function bytecode (bump version to 11)
- update generated code
2024-04-16 09:24:21 +02:00
Cryse Hillmes
2c47b7beb1
Expose public equality comparison and sameness public API. (#373)
* Expose public equality comparison and sameness public API.
- add `JS_IsEqual` (operator `==`), returns an `int`: `-1` if an exception was thrown
- add `JS_IsStrictEqual` (operator `===`) always succeeds, returns a `JS_BOOL`
- add `JS_IsSameValue` always succeeds, returns a `JS_BOOL`
- add `JS_IsSameValueZero` always succeeds, returns a `JS_BOOL`
2024-04-16 08:46:22 +02:00
Saúl Ibarra Corretgé
18c632c754 Fix performance.now() to return a double 2024-04-15 16:16:04 +02:00
Charlie Gordon
7597fc7fb0
Fix potential atom leak in JS_ReadFunctionTag (#380) 2024-04-15 14:03:24 +02:00
Null
8dcdb92047
fix crash in js_typed_array_slice caused by memory overlap (#379)
Use memmove instead of memcpy to prevent UB.
Fixes: https://github.com/quickjs-ng/quickjs/issues/378
Co-authored-by: zhang.yuping <zhangyuping.ypz@bytedance.com>
2024-04-15 06:40:00 +02:00
Charlie Gordon
4fb2e38b8a
Simplify arrow function parsing (#360)
- parse arrow functions only in `js_parse_cond_expr`
- remove `PF_ARROW_FUNC` flag and simplify parsing functions with flags
2024-04-14 02:44:34 +02:00
Charlie Gordon
16e7661fa0
Improve dump option support (#344)
- DUMP_XXX defined as nothing or 0 produces unconditional output
- DUMP_XXX defined as a bitmask produces conditional output based
    on command line option -d<bitmask>
- add `JS_SetDumpFlags()` to select active dump options
- accept -d[<hex mask>] and --dump[=<hex mask>] to specify active
    dump options, generalize command line option handling
- improve DUMP_READ_OBJECT output, fix indentation issue
2024-04-14 02:00:19 +02:00
Saúl Ibarra Corretgé
38fa7d7cf6 Fix crash in FinalizationRegistry when the observed object is GC'd
In the pathological case shown in
https://github.com/quickjs-ng/quickjs/issues/367 both the object and the
registry will be destroyed as part of the GC phase of JS_FreeRuntime.
When the GC sweep happens it's possible we are holding on to a corpse so
avoid calling the registry callback in that case.

This is similar to how Weak{Map,Set} deal with iterators being freed as
part of a cycle.

Fixes: https://github.com/quickjs-ng/quickjs/issues/367
2024-04-12 12:23:58 +02:00
Charlie Gordon
6d801de3e5
Improve js_array_lastIndexOf and friends (#359)
- special case fast arrays in `js_array_lastIndexOf`
- simplify `js_array_indexOf` and `js_array_includes` for consistency.
2024-04-08 23:08:49 +02:00
Charlie Gordon
0658d9c3e9
Fix js_math_imul (#356)
- follow ECMA specification
- remove implementation defined signed conversion
2024-04-08 22:50:39 +02:00
Charlie Gordon
97c918662b
Fix crashes in DUMP output (#350)
- avoid crashing on invalid atoms in `JS_AtomGetStrRT`
- do not dump objects and function_bytecode during
  `JS_GC_PHASE_REMOVE_CYCLES` phase
- fix crash in `print_lines` on null source
2024-04-08 21:25:01 +02:00
Charlie Gordon
56593f419b
Fix JS_ReadString for wide strings on big endian targets (#354)
swap words of wide character strings upon loading on a big endian target.
2024-04-08 17:02:20 +02:00
Charlie Gordon
d308a13579
Use string_get for clarity (#352) 2024-04-07 19:35:32 +02:00
Charlie Gordon
3f06c95558
Use more functions for explicit surrogate handling (#353)
- add `is_surrogate`, `get_hi_surrogate` and `get_lo_surrogate`
- use surrogate functions instead of hard coded computations
2024-04-07 18:19:55 +02:00
Charlie Gordon
1db884b140
Unify JS_DumpValue functions (#349)
- merge `JS_DumpValue(ctx, val)` and `JS_DumpValueShort(rt, val)` as `JS_DumpValue(rt, val)`
- remove unused `JS_PrintValue(ctx, val)`
2024-04-07 16:25:55 +02:00
Charlie Gordon
b8a2cf40d8
Fix fix-js-get-string AM/PM computation for Date.prototype.toLocaleString (#355)
- Fix AM/PM computation for Date.prototype.toLocalString: 11:00 and 23:00 used to convert to -1:00
2024-04-07 16:25:03 +02:00
Charlie Gordon
d61988211c
Accept shell scripts in JS_DetectModule (#358)
- use `skip_shebang` in `JS_DetectModule` before scanning for
  `import` statements
2024-04-07 16:23:50 +02:00
Saúl Ibarra Corretgé
573a60bfc7 Fix compilation on MSVC 2022 in release mode
Fixes: https://github.com/quickjs-ng/quickjs/issues/309
2024-04-07 00:08:19 +02:00
Charlie Gordon
c15ef1f8dc
Add JS_TryGetProperty (#337)
* Optimize `JS_GetPropertyInt64` and `JS_TryGetPropertyInt64`

- add `js_get_fast_array_element()` to special case arrays and typed arrays
- use `js_get_fast_array_element()` in `JS_GetPropertyValue()`,
  `JS_TryGetPropertyInt64()` and `JS_GetPropertyInt64()`.
- simplify `js_array_at()`
2024-04-03 05:10:08 +02:00
Saúl Ibarra Corretgé
569b238ec4
Add cross-platform Atomics support
Fixes: https://github.com/quickjs-ng/quickjs/issues/1
2024-04-02 21:50:42 +02:00
Charlie Gordon
0de570988a
Fix strict name conformity cases (#335)
- reject *future strict reserved words* in `js_parse_function_check_names()`.
- add tests for reserved names in tests/test_language.js
- allow running tests/test_language.js with v8
- update v8.txt
2024-03-30 17:15:25 +01:00
Charlie Gordon
8b56215cc2
Fix more v8 errors (#336)
- change error message for `Object.create` invalid property descriptor
- disable v8 test cases for deprecated legacy RegExp static properties
  and invalid left hand side error type
- update v8.txt
- fix v8.sh behavior for single tests
2024-03-30 13:11:37 +01:00
Charlie Gordon
93d1742fc4
Small fixes in Date.parse (#333)
* Small fixes in Date.parse

- reject AM/PM suffix for hours > 12
- stricter time parser (fixes last v8 test)
- add explanatory comments
2024-03-27 12:48:08 +01:00
Ben Noordhuis
c7ca3febd3
Don't serialize IC opcodes (#334)
Translate IC opcodes to their non-IC variants before writing them out.
Before this commit they were not byte-swapped properly, breaking the
ability to load serialized bytecode containing ICs on systems with
different endianness. Inline caches are recomputed as needed now.

A pleasing side effect of this change is that serialized bytecode is,
on average, a little smaller because fewer atoms are duplicated now.
2024-03-27 12:07:11 +01:00
Charlie Gordon
f02ed184a2
Fix more error cases (#332)
* Fix more error cases

- fix more cases of missing `sf->cur_pc`.
- use more precise error messages for number conversion methods
- add test cases in test_builtin.js
- updated v8 test results
2024-03-26 13:22:37 +01:00
Saúl Ibarra Corretgé
c076339899 Expose JS_GetPropertyInt64 in the public API 2024-03-26 07:59:00 +01:00
Saúl Ibarra Corretgé
b8341ecafa Don't expose JS_{Get,Set}PropertyInternal in the public API 2024-03-26 07:59:00 +01:00
Charlie Gordon
3b50de4848
Improve consistency of JS_NewFloat64 API (#319)
* Improve consistency of JS_NewFloat64 API

- `JS_NewFloat64()` always creates a `JS_TAG_FLOAT64` value
- internal `js_float64()` always creates a `JS_TAG_FLOAT64` value
- add `js_int64` internal function for consistency
- rename `float_is_int32` as `double_is_int32`
- handle `INT32_MIN` in `double_is_int32`, use (somewhat) faster alternative
- add `js_number(d)` to create a `JS_TAG_FLOAT64` or a `JS_TAG_INT` value
  if possible
- add `JS_NewNumber()` API for the same purpose
- use non testing constructor for infinities in `js_atof2`
- always store internal time value as a float64
- merge `JS_NewBigInt64_1` into `JS_NewBigInt64`
- use comparisons instead of `(int32_t)` casts (implementation defined behavior)
2024-03-25 08:29:04 +01:00
Saúl Ibarra Corretgé
18f2898f52
Fix fully initializing JSStackFrame (#328)
Fixes: https://github.com/quickjs-ng/quickjs/issues/323
2024-03-24 22:06:57 +01:00
Saúl Ibarra Corretgé
1796b36db7 Remove JS_VALUE_GET_STRING from the public API
JSString is not part of the API.
2024-03-24 21:01:15 +01:00
Saúl Ibarra Corretgé
4a66289af4 Add JS_Newsymbol, an API for creating symbols
Example usage:

~~~
JSValue global = JS_GetGlobalObject(ctx);
JSValue sym = JS_NewSymbol(ctx, "my.secret.thing", TRUE);
JSAtom atom = JS_ValueToAtom(ctx, sym);
JS_DefinePropertyValue(ctx, global, atom, JS_NewString(ctx, "qjs!"), JS_PROP_C_W_E);
JS_FreeAtom(ctx, atom);
JS_FreeValue(ctx, sym);
JS_FreeValue(ctx, global);
~~~
2024-03-24 21:00:54 +01:00
Charlie Gordon
5e5b00c48c
Improve string parsing and JSON parsing (#316)
* Improve string parsing and JSON parsing

- fix JSON parsing of non ASCII string contents
- more precise string parsing errors
- more precise JSON parsing errors
- add `JS_ParseState::buf_start` to compute line/column
- fix HTML comment detection at start of source code
- improve v8 Failure messages (pulled and modified `formatFailureText` from **mjsunit.js**) 
- ignore more v8 tests
2024-03-22 11:19:36 +01:00