Browse Source

2019-07-21

- updated test262 tests
- updated to Unicode version 12.1.0
- fixed missing Date object in qjsc
- fixed multi-context creation
- misc ES2020 related fixes
- simplified power and division operators in bignum extension
- fixed several crash conditions
pull/11/head 20190721
Horunabu Hofutenho 1 year ago
parent
commit
6732c3be8a
No known key found for this signature in database GPG Key ID: 7EB80FA93BC3054C
31 changed files with 2770 additions and 3132 deletions
  1. +13
    -0
      Changelog
  2. +10
    -5
      Makefile
  3. +6
    -6
      TODO
  4. +1
    -1
      VERSION
  5. +16
    -30
      doc/jsbignum.html
  6. BIN
      doc/jsbignum.pdf
  7. +14
    -27
      doc/jsbignum.texi
  8. +7
    -6
      doc/quickjs.html
  9. BIN
      doc/quickjs.pdf
  10. +6
    -6
      doc/quickjs.texi
  11. +1
    -1
      libregexp.c
  12. +2082
    -2038
      libunicode-table.h
  13. +1
    -0
      qjsc.c
  14. +31
    -42
      qjscalc.js
  15. +0
    -2
      quickjs-atom.h
  16. +11
    -6
      quickjs-libc.c
  17. +308
    -286
      quickjs.c
  18. +9
    -0
      quickjs.h
  19. +1
    -1
      release.sh
  20. +2
    -2
      repl.js
  21. +39
    -8
      run-test262.c
  22. +23
    -6
      test262.conf
  23. +51
    -0
      test262_errors.txt
  24. +23
    -6
      test262bn.conf
  25. +56
    -0
      test262bn_errors.txt
  26. +6
    -0
      test262o.conf
  27. +27
    -651
      tests/test262.patch
  28. +1
    -1
      tests/test_builtin.js
  29. +1
    -1
      tests/test_std.js
  30. +19
    -0
      unicode_download.sh
  31. +5
    -0
      unicode_gen_def.h

+ 13
- 0
Changelog View File

@ -0,0 +1,13 @@
2019-07-21:
- updated test262 tests
- updated to Unicode version 12.1.0
- fixed missing Date object in qjsc
- fixed multi-context creation
- misc ES2020 related fixes
- simplified power and division operators in bignum extension
- fixed several crash conditions
2019-07-09:
- first public release

+ 10
- 5
Makefile View File

@ -226,7 +226,7 @@ qjscalc.c: qjsbnc qjscalc.js
./qjsbnc -c -o $@ qjscalc.js
ifneq ($(wildcard unicode/UnicodeData.txt),)
$(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o $(OBJDIR)/libunicode.bn.o \
$(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o $(OBJDIR)/libunicode.bn.o $(OBJDIR)/libunicode.bn.m32.o \
$(OBJDIR)/libunicode.nolto.o $(OBJDIR)/libunicode.bn.nolto.o: libunicode-table.h
libunicode-table.h: unicode_gen
@ -289,7 +289,7 @@ regexp_test: libregexp.c libunicode.c cutils.c
jscompress: jscompress.c
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ jscompress.c
unicode_gen: unicode_gen.c cutils.c libunicode.c
unicode_gen: unicode_gen.c cutils.c libunicode.c unicode_gen_def.h
$(CC) $(LDFLAGS) $(CFLAGS) -o $@ unicode_gen.c cutils.c
clean:
@ -318,7 +318,8 @@ endif
# example of static JS compilation
HELLO_SRCS=examples/hello.js
HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
-fno-date
hello.c: qjsc $(HELLO_SRCS)
./qjsc -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS)
@ -334,7 +335,8 @@ endif
# example of static JS compilation with modules
HELLO_MODULE_SRCS=examples/hello_module.js
HELLO_MODULE_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy -m
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
-fno-date -m
examples/hello_module: qjsc libquickjs$(LTOEXT).a $(HELLO_MODULE_SRCS)
./qjsc $(HELLO_MODULE_OPTS) -o $@ $(HELLO_MODULE_SRCS)
@ -362,9 +364,12 @@ clean_doc:
doc/%.pdf: doc/%.texi
texi2pdf --clean -o $@ -q $<
doc/%.html: doc/%.texi
doc/%.html.pre: doc/%.texi
makeinfo --html --no-headers --no-split --number-sections -o $@ $<
doc/%.html: doc/%.html.pre
sed -e 's|</style>|</style>\n<meta name="viewport" content="width=device-width, initial-scale=1.0">|' < $< > $@
###############################################################################
# tests

+ 6
- 6
TODO View File

@ -1,3 +1,4 @@
- fix regexp skip in js_parse_skip_parens_token()
- 64-bit atoms in 64-bit mode?
- rename CONFIG_ALL_UNICODE, CONFIG_BIGNUM, CONFIG_ATOMICS, CONFIG_CHECK_JSVALUE ?
- unify coding style and naming conventions
@ -11,7 +12,6 @@
and use the same wrappers in all phases
- use more generic method for line numbers in resolve_variables and resolve_labels
- bignum:
- fix div/pow div by zero exception in doc & code in bigint mode
- fix Atomics support
Memory:
@ -48,7 +48,7 @@ Optimizations:
- optimize destructuring assignments for global and local variables
- implement some form of tail-call-optimization
- debugger keyword support
- optmize OP_apply
- optimize OP_apply
- optimize f(...b)
Extensions:
@ -77,7 +77,7 @@ REPL:
- save history
- close all predefined methods in repl.js and jscalc.js
Test262o: 0/11266 errors, 459 excluded
Test262: 0/55855 errors, 504 excluded, 1559 skipped
Test262bn: 0/57176 errors, 724 excluded, 675 skipped
test262 commit: 94b1e80ab3440413df916cd56d29c5a2fa2ac451
Test262o: 0/11262 errors, 463 excluded
Test262: 51/56682 errors, 787 excluded, 6289 skipped
Test262bn: 56/58017 errors, 1007 excluded, 5398 skipped
test262 commit: 51d1abadce1de0b38594b7c9972ee60762f35dd0

+ 1
- 1
VERSION View File

@ -1 +1 @@
2019-07-09
2019-07-21

+ 16
- 30
doc/jsbignum.html View File

@ -39,6 +39,7 @@ span.sansserif {font-family:sans-serif; font-weight:normal}
ul.no-bullet {list-style: none}
-->
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
@ -202,10 +203,6 @@ value. A TypeError is raised if both constructors have the same
<dd><p><code>Symbol.operatorDiv</code>
</p>
</dd>
<dt><code>/ (math mode)</code></dt>
<dd><p><code>Symbol.operatorMathDiv</code>
</p>
</dd>
<dt><code>%</code></dt>
<dd><p><code>Symbol.operatorMod</code>
</p>
@ -214,10 +211,6 @@ value. A TypeError is raised if both constructors have the same
<dd><p><code>Symbol.operatorMathMod</code>
</p>
</dd>
<dt><code>^ (math mode)</code></dt>
<dd><p><code>Symbol.operatorMathPow</code>
</p>
</dd>
<dt><code>**</code></dt>
<dd><p><code>Symbol.operatorPow</code>
</p>
@ -388,7 +381,8 @@ both operands are Integer. Otherwise, a float is returned.
standard Javascript in this case.
</p>
<p>The binary operator <code>%</code> returns the truncated remainder of the
division.
division. When the result is an Integer type, a dividend of zero yields a
RangeError exception.
</p>
<p>The binary operator <code>%</code> in math mode returns the Euclidian
remainder of the division i.e. it is always positive.
@ -396,21 +390,15 @@ remainder of the division i.e. it is always positive.
<p>The binary operator <code>/</code> returns a float.
</p>
<p>The binary operator <code>/</code> in math mode returns a float if one of
the operands is float. Otherwise, <code>BigInt[Symbol.operatorMathDiv]</code> is
invoked (and returns a fraction for example).
the operands is float. Otherwise, <code>BigInt[Symbol.operatorDiv]</code> is
invoked.
</p>
<p>When the result is an Integer type, a dividend of zero yields a
RangeError exception.
</p>
<p>The returned type of <code>a ** b</code> or <code>a ^ b</code> (math mode) is
Float if <em>a</em> or <em>b</em> are Float. If <em>a</em> and <em>b</em> are
integers:
<p>The returned type of <code>a ** b</code> is Float if <em>a</em> or <em>b</em>
are Float. If <em>a</em> and <em>b</em> are integers:
</p><ul>
<li> <em>a = 0</em> and <em>b &lt; 0</em> generates a RangeError exception
</li><li> <em>|a| \geq 2</em> and <em>b &lt; 0</em> returns a Float in bigint mode. In math mode, <code>BigInt[Symbol.operatorMathPow]</code> is invoked (and returns a fraction for example)
<li> <em>b &lt; 0</em> returns a Float in bigint mode. In math mode, <code>BigInt[Symbol.operatorPow]</code> is invoked.
</li><li> otherwise an integer is returned.
</li><li> <em>b &gt;= 0</em> returns an integer.
</li></ul>
<p>The unary <code>-</code> and unary <code>+</code> return the same type as their
@ -975,20 +963,22 @@ is returned, no rounding is performed.
<p>A new <em>math mode</em> is enabled with the <code>&quot;use math&quot;</code>
directive. <code>&quot;use bigint&quot;</code> is implied in math mode. With this
mode, writing mathematical expressions is more intuitive, exact
results (fractions) can be computed for all operators and floating
results (e.g. fractions) can be computed for all operators and floating
point literals have the <code>BigFloat</code> type by default.
</p>
<p>It propagates the same way as the <em>strict mode</em>. In
this mode:
</p>
<ul>
<li> The <code>^</code> operator is a similar to the power operator (<code>**</code>), except that <code>a ^ b</code> invokes <code>BigInt[Symbol.operatorMathPow]</code> if <em>a</em> and <em>b</em> are integers and <em>|a| \geq 2</em> and <em>b &lt; 0</em>.
<li> The <code>^</code> operator is a similar to the power operator (<code>**</code>).
</li><li> The power operator (both <code>^</code> and <code>**</code>) grammar is modified so that <code>-2^2</code> is allowed and yields <code>-4</code>.
</li><li> The logical xor operator is still available with the <code>^^</code> operator.
</li><li> The division operator invokes <code>BigInt[Symbol.operatorMathDiv]</code> in case both operands are integers.
</li><li> The division operator invokes <code>BigInt[Symbol.operatorDiv]</code> in case both operands are integers.
</li><li> The power operator invokes <code>BigInt[Symbol.operatorPow]</code> in case both operands are integers and the exponent is strictly negative.
</li><li> The modulo operator returns the Euclidian remainder (always positive) instead of the truncated remainder.
@ -1002,20 +992,16 @@ this mode:
<a name="Symbol-constructor-1"></a>
<h4 class="subsection">5.2.1 <code>Symbol</code> constructor</h4>
<p>The following global symbols are added for the operator overloading:
<p>The following global symbol is added for the operator overloading:
</p><dl compact="compact">
<dt><code>operatorMathDiv</code></dt>
<dt><code>operatorMathMod</code></dt>
<dt><code>operatorMathPow</code></dt>
</dl>
<a name="Remaining-issues"></a>
<h3 class="section">5.3 Remaining issues</h3>
<ol>
<li> New functions (e.g. <code>Math.div</code> and <code>Math.mod</code>) could be added to be able to call the normal division and modulo operators when in math mode.
</li><li> A new floating point literal suffix could be added for <code>Number</code> literals.
<li> A new floating point literal suffix could be added for <code>Number</code> literals.
</li></ol>

BIN
doc/jsbignum.pdf View File


+ 14
- 27
doc/jsbignum.texi View File

@ -102,18 +102,12 @@ The operator is looked up with the following name:
@item /
@code{Symbol.operatorDiv}
@item / (math mode)
@code{Symbol.operatorMathDiv}
@item %
@code{Symbol.operatorMod}
@item % (math mode)
@code{Symbol.operatorMathMod}
@item ^ (math mode)
@code{Symbol.operatorMathPow}
@item **
@code{Symbol.operatorPow}
@ -266,7 +260,8 @@ The @code{+} operator also accepts strings as input and behaves like
standard Javascript in this case.
The binary operator @code{%} returns the truncated remainder of the
division.
division. When the result is an Integer type, a dividend of zero yields a
RangeError exception.
The binary operator @code{%} in math mode returns the Euclidian
remainder of the division i.e. it is always positive.
@ -274,21 +269,15 @@ remainder of the division i.e. it is always positive.
The binary operator @code{/} returns a float.
The binary operator @code{/} in math mode returns a float if one of
the operands is float. Otherwise, @code{BigInt[Symbol.operatorMathDiv]} is
invoked (and returns a fraction for example).
When the result is an Integer type, a dividend of zero yields a
RangeError exception.
the operands is float. Otherwise, @code{BigInt[Symbol.operatorDiv]} is
invoked.
The returned type of @code{a ** b} or @code{a ^ b} (math mode) is
Float if @math{a} or @math{b} are Float. If @math{a} and @math{b} are
integers:
The returned type of @code{a ** b} is Float if @math{a} or @math{b}
are Float. If @math{a} and @math{b} are integers:
@itemize
@item @math{a = 0} and @math{b < 0} generates a RangeError exception
@item @math{b < 0} returns a Float in bigint mode. In math mode, @code{BigInt[Symbol.operatorPow]} is invoked.
@item @math{|a| \geq 2} and @math{b < 0} returns a Float in bigint mode. In math mode, @code{BigInt[Symbol.operatorMathPow]} is invoked (and returns a fraction for example)
@item otherwise an integer is returned.
@item @math{b >= 0} returns an integer.
@end itemize
The unary @code{-} and unary @code{+} return the same type as their
@ -798,7 +787,7 @@ is returned, no rounding is performed.
A new @emph{math mode} is enabled with the @code{"use math"}
directive. @code{"use bigint"} is implied in math mode. With this
mode, writing mathematical expressions is more intuitive, exact
results (fractions) can be computed for all operators and floating
results (e.g. fractions) can be computed for all operators and floating
point literals have the @code{BigFloat} type by default.
It propagates the same way as the @emph{strict mode}. In
@ -806,13 +795,15 @@ this mode:
@itemize
@item The @code{^} operator is a similar to the power operator (@code{**}), except that @code{a ^ b} invokes @code{BigInt[Symbol.operatorMathPow]} if @math{a} and @math{b} are integers and @math{|a| \geq 2} and @math{b < 0}.
@item The @code{^} operator is a similar to the power operator (@code{**}).
@item The power operator (both @code{^} and @code{**}) grammar is modified so that @code{-2^2} is allowed and yields @code{-4}.
@item The logical xor operator is still available with the @code{^^} operator.
@item The division operator invokes @code{BigInt[Symbol.operatorMathDiv]} in case both operands are integers.
@item The division operator invokes @code{BigInt[Symbol.operatorDiv]} in case both operands are integers.
@item The power operator invokes @code{BigInt[Symbol.operatorPow]} in case both operands are integers and the exponent is strictly negative.
@item The modulo operator returns the Euclidian remainder (always positive) instead of the truncated remainder.
@ -824,19 +815,15 @@ this mode:
@subsection @code{Symbol} constructor
The following global symbols are added for the operator overloading:
The following global symbol is added for the operator overloading:
@table @code
@item operatorMathDiv
@item operatorMathMod
@item operatorMathPow
@end table
@section Remaining issues
@enumerate
@item New functions (e.g. @code{Math.div} and @code{Math.mod}) could be added to be able to call the normal division and modulo operators when in math mode.
@item A new floating point literal suffix could be added for @code{Number} literals.
@end enumerate

+ 7
- 6
doc/quickjs.html View File

@ -39,6 +39,7 @@ span.sansserif {font-family:sans-serif; font-weight:normal}
ul.no-bullet {list-style: none}
-->
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
@ -148,7 +149,7 @@ overloading.
</li><li> Almost complete ES2019 support including modules, asynchronous
generators and full Annex B support (legacy web compatibility).
</li><li> Passes 100% of the ECMAScript Test Suite tests.
</li><li> Passes nearly 100% of the ECMAScript Test Suite tests.
</li><li> Can compile Javascript sources to executables with no external dependency.
@ -337,7 +338,7 @@ QuickJS source code directory.
<div class="example">
<pre class="example">git clone https://github.com/tc39/test262.git test262
cd test262
git checkout 94b1e80ab3440413df916cd56d29c5a2fa2ac451
git checkout 51d1abadce1de0b38594b7c9972ee60762f35dd0
patch -p1 &lt; ../tests/test262.patch
cd ..
</pre></div>
@ -716,12 +717,12 @@ the signal.
<dd><p>POSIX signal numbers.
</p>
</dd>
<dt><code>setTimeout(delay, func)</code></dt>
<dt><code>setTimeout(func, delay)</code></dt>
<dd><p>Call the function <code>func</code> after <code>delay</code> ms. Return a handle
to the timer.
</p>
</dd>
<dt><code>clearTimer(handle)</code></dt>
<dt><code>clearTimeout(handle)</code></dt>
<dd><p>Cancel a timer.
</p>
</dd>
@ -823,14 +824,14 @@ is used to define a prototype for a given class in a given
JSContext. <code>JS_NewObjectClass()</code> sets this prototype in the
created object.
</p>
<p>Examples are available in <samp>js_libc.c</samp>.
<p>Examples are available in <samp>quickjs-libc.c</samp>.
</p>
<a name="C-Modules"></a>
<h4 class="subsection">3.4.7 C Modules</h4>
<p>Native ES6 modules are supported and can be dynamically or statically
linked. Look at the <samp>test_bjson</samp> and <samp>bjson.so</samp>
examples. The standard library <samp>js_libc.c</samp> is also a good example
examples. The standard library <samp>quickjs-libc.c</samp> is also a good example
of a native module.
</p>
<a name="Memory-handling"></a>

BIN
doc/quickjs.pdf View File


+ 6
- 6
doc/quickjs.texi View File

@ -38,7 +38,7 @@ overloading.
@item Almost complete ES2019 support including modules, asynchronous
generators and full Annex B support (legacy web compatibility).
@item Passes 100% of the ECMAScript Test Suite tests.
@item Passes nearly 100% of the ECMAScript Test Suite tests.
@item Can compile Javascript sources to executables with no external dependency.
@ -207,7 +207,7 @@ Alternatively, the test262 tests can be installed with:
@example
git clone https://github.com/tc39/test262.git test262
cd test262
git checkout 94b1e80ab3440413df916cd56d29c5a2fa2ac451
git checkout 51d1abadce1de0b38594b7c9972ee60762f35dd0
patch -p1 < ../tests/test262.patch
cd ..
@end example
@ -531,11 +531,11 @@ the signal.
@item SIGTERM
POSIX signal numbers.
@item setTimeout(delay, func)
@item setTimeout(func, delay)
Call the function @code{func} after @code{delay} ms. Return a handle
to the timer.
@item clearTimer(handle)
@item clearTimeout(handle)
Cancel a timer.
@item platform
@ -628,13 +628,13 @@ is used to define a prototype for a given class in a given
JSContext. @code{JS_NewObjectClass()} sets this prototype in the
created object.
Examples are available in @file{js_libc.c}.
Examples are available in @file{quickjs-libc.c}.
@subsection C Modules
Native ES6 modules are supported and can be dynamically or statically
linked. Look at the @file{test_bjson} and @file{bjson.so}
examples. The standard library @file{js_libc.c} is also a good example
examples. The standard library @file{quickjs-libc.c} is also a good example
of a native module.
@subsection Memory handling

+ 1
- 1
libregexp.c View File

@ -2407,7 +2407,7 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
for(;;) {
res = lre_exec_backtrack(s, capture, stack, stack_len,
pc1, cptr, TRUE);
if (res < 0)
if (res == -1)
return res;
if (!res)
break;

+ 2082
- 2038
libunicode-table.h
File diff suppressed because it is too large
View File


+ 1
- 0
qjsc.c View File

@ -63,6 +63,7 @@ static FILE *outfile;
static BOOL byte_swap;
static const FeatureEntry feature_list[] = {
{ "date", "Date" },
{ "eval", "Eval" },
{ "string-normalize", "StringNormalize" },
{ "regexp", "RegExp" },

+ 31
- 42
qjscalc.js View File

@ -45,7 +45,7 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
/* add non enumerable properties */
function add_props(obj, props) {
var i, val, prop, tab, desc, prop1;
var i, val, prop, tab, desc;
tab = Reflect.ownKeys(props);
for(i = 0; i < tab.length; i++) {
prop = tab[i];
@ -61,25 +61,6 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
desc.configurable = false;
}
Object.defineProperty(obj, prop, desc);
if (obj !== Integer) {
/* by default also add the non math operators */
switch(prop) {
case Symbol.operatorMathDiv:
prop1 = Symbol.operatorDiv;
break;
case Symbol.operatorMathMod:
prop1 = Symbol.operatorMod;
break;
case Symbol.operatorMathPow:
prop1 = Symbol.operatorPow;
break;
default:
prop1 = null;
break;
}
if (prop1)
Object.defineProperty(obj, prop1, desc);
}
}
}
@ -165,14 +146,14 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
return typeof a === "bigint";
},
[Symbol.operatorOrder]: OT_INT,
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
if (algebraicMode) {
return Fraction.toFraction(a, b);
} else {
return Float(a) / Float(b);
}
},
[Symbol.operatorMathPow](a, b) {
[Symbol.operatorPow](a, b) {
if (algebraicMode) {
return generic_pow(a, b);
} else {
@ -418,7 +399,7 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
b = Fraction(b);
return Fraction.toFraction(a.num * b.num, a.den * b.den);
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
a = Fraction(a);
b = Fraction(b);
return Fraction.toFraction(a.num * b.den, a.den * b.num);
@ -428,7 +409,12 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
var b1 = Fraction(b);
return a - Integer.ediv(a1.num * b1.den, a1.den * b1.num) * b;
},
[Symbol.operatorMathPow]: generic_pow,
[Symbol.operatorMod](a, b) {
var a1 = Fraction(a);
var b1 = Fraction(b);
return a - Integer.tdiv(a1.num * b1.den, a1.den * b1.num) * b;
},
[Symbol.operatorPow]: generic_pow,
[Symbol.operatorCmpEQ](a, b) {
a = Fraction(a);
b = Fraction(b);
@ -509,10 +495,10 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
[Symbol.operatorMul](a, b) {
return Number(a) * Number(b);
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
return Number(a) / Number(b);
},
[Symbol.operatorMathPow](a, b) {
[Symbol.operatorPow](a, b) {
return Number(a) ** Number(b);
},
});
@ -629,10 +615,10 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
[Symbol.operatorMul](a, b) {
return Float(a) * Float(b);
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
return Float(a) / Float(b);
},
[Symbol.operatorMathPow](a, b) {
[Symbol.operatorPow](a, b) {
return Float(a) ** Float(b);
},
});
@ -712,12 +698,12 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
return Complex.toComplex(a.re * b.re - a.im * b.im,
a.re * b.im + a.im * b.re);
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
a = Complex(a);
b = Complex(b);
return a * b.inverse();
},
[Symbol.operatorMathPow]: generic_pow,
[Symbol.operatorPow]: generic_pow,
[Symbol.operatorCmpEQ](a, b) {
a = Complex(a);
b = Complex(b);
@ -855,12 +841,12 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
return Mod(a.res * b.res, a.mod);
}
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
if (!(b instanceof Mod))
b = Mod(b, a.mod);
return Mod[Symbol.operatorMul](a, b.inverse());
},
[Symbol.operatorMathPow]: generic_pow,
[Symbol.operatorPow]: generic_pow,
[Symbol.operatorCmpEQ](a, b) {
if (!(a instanceof Mod) ||
!(b instanceof Mod))
@ -1151,17 +1137,20 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
}
return Polynomial(r);
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
if (b.constructor[Symbol.operatorOrder] <= OT_COMPLEX)
return a * (1 / b);
else
return RationalFunction(Polynomial(a),
Polynomial(b));
},
[Symbol.operatorMathPow]: generic_pow,
[Symbol.operatorPow]: generic_pow,
[Symbol.operatorMathMod](a, b) {
return Polynomial.divrem(a, b)[1];
},
[Symbol.operatorMod](a, b) {
return Polynomial.divrem(a, b)[1];
},
[Symbol.operatorCmpEQ](a, b) {
var n, i;
if (!(a instanceof Polynomial) ||
@ -1318,12 +1307,12 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
return PolyMod(a.res * b.res, a.mod);
}
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
if (!(b instanceof PolyMod))
b = PolyMod(b, a.mod);
return PolyMod[Symbol.operatorMul](a, b.inverse());
},
[Symbol.operatorMathPow]: generic_pow,
[Symbol.operatorPow]: generic_pow,
[Symbol.operatorCmpEQ](a, b) {
if (!(a instanceof PolyMod) ||
!(b instanceof PolyMod))
@ -1420,12 +1409,12 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
b = RationalFunction.toRationalFunction(b);
return RationalFunction(a.num * b.num, a.den * b.den);
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
a = RationalFunction.toRationalFunction(a);
b = RationalFunction.toRationalFunction(b);
return RationalFunction(a.num * b.den, a.den * b.num);
},
[Symbol.operatorMathPow]: generic_pow,
[Symbol.operatorPow]: generic_pow,
[Symbol.operatorCmpEQ](a, b) {
a = RationalFunction.toRationalFunction(a);
b = RationalFunction.toRationalFunction(b);
@ -1702,12 +1691,12 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
}
return r.trim();
},
[Symbol.operatorMathDiv](v1, v2) {
[Symbol.operatorDiv](v1, v2) {
if (!(v2 instanceof Series))
v2 = Series(v2, v1.length);
return Series[Symbol.operatorMul](v1, v2.inverse());
},
[Symbol.operatorMathPow](a, b) {
[Symbol.operatorPow](a, b) {
if (Integer.isInteger(b)) {
return generic_pow(a, b);
} else {
@ -2168,10 +2157,10 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
}
return r;
},
[Symbol.operatorMathDiv](a, b) {
[Symbol.operatorDiv](a, b) {
return Array[Symbol.operatorMul](a, b.inverse());
},
[Symbol.operatorMathPow]: generic_pow,
[Symbol.operatorPow]: generic_pow,
[Symbol.operatorCmpEQ](a, b) {
var n, i;
n = a.length;

+ 0
- 2
quickjs-atom.h View File

@ -266,9 +266,7 @@ DEF(Symbol_operatorNeg, "Symbol.operatorNeg")
DEF(Symbol_operatorNot, "Symbol.operatorNot")
DEF(Symbol_operatorInc, "Symbol.operatorInc")
DEF(Symbol_operatorDec, "Symbol.operatorDec")
DEF(Symbol_operatorMathDiv, "Symbol.operatorMathDiv")
DEF(Symbol_operatorMathMod, "Symbol.operatorMathMod")
DEF(Symbol_operatorMathPow, "Symbol.operatorMathPow")
#endif
#endif /* DEF */

+ 11
- 6
quickjs-libc.c View File

@ -487,6 +487,7 @@ static JSValue js_evalScript(JSContext *ctx, JSValueConst this_val,
JS_SetInterruptHandler(JS_GetRuntime(ctx), interrupt_handler, NULL);
}
ret = JS_Eval(ctx, str, len, "<evalScript>", JS_EVAL_TYPE_GLOBAL);
JS_FreeCString(ctx, str);
if (--eval_script_recurse == 0) {
/* remove the interrupt handler */
JS_SetInterruptHandler(JS_GetRuntime(ctx), NULL, NULL);
@ -1409,20 +1410,20 @@ static JSValue js_os_setTimeout(JSContext *ctx, JSValueConst this_val,
JSOSTimer *th;
JSValue obj;
if (JS_ToInt64(ctx, &delay, argv[0]))
return JS_EXCEPTION;
func = argv[1];
func = argv[0];
if (!JS_IsFunction(ctx, func))
return JS_ThrowTypeError(ctx, "not a function");
if (JS_ToInt64(ctx, &delay, argv[1]))
return JS_EXCEPTION;
obj = JS_NewObjectClass(ctx, js_os_timer_class_id);
if (JS_IsException(obj))
return obj;
th = js_mallocz(ctx, sizeof(*th));
th->has_object = TRUE;
if (!th) {
JS_FreeValue(ctx, obj);
return JS_EXCEPTION;
}
th->has_object = TRUE;
th->timeout = get_time_ms() + delay;
th->func = JS_DupValue(ctx, func);
list_add_tail(&th->link, &os_timers);
@ -1448,8 +1449,12 @@ static JSClassDef js_os_timer_class = {
static void call_handler(JSContext *ctx, JSValueConst func)
{
JSValue ret;
ret = JS_Call(ctx, func, JS_UNDEFINED, 0, NULL);
JSValue ret, func1;
/* 'func' might be destroyed when calling itself (if it frees the
handler), so must take extra care */
func1 = JS_DupValue(ctx, func);
ret = JS_Call(ctx, func1, JS_UNDEFINED, 0, NULL);
JS_FreeValue(ctx, func1);
if (JS_IsException(ret))
js_std_dump_error(ctx);
JS_FreeValue(ctx, ret);

+ 308
- 286
quickjs.c
File diff suppressed because it is too large
View File


+ 9
- 0
quickjs.h View File

@ -581,6 +581,15 @@ static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v)
return (JSValue)v;
}
static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
{
if (JS_VALUE_HAS_REF_COUNT(v)) {
JSRefCountHeader *p = JS_VALUE_GET_PTR(v);
p->ref_count++;
}
return (JSValue)v;
}
int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
static int inline JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)

+ 1
- 1
release.sh View File

@ -60,7 +60,7 @@ outdir="/tmp/${d}"
rm -rf $outdir
mkdir -p $outdir $outdir/doc $outdir/tests $outdir/examples
cp Makefile VERSION TODO readme.txt release.sh \
cp Makefile VERSION TODO Changelog readme.txt release.sh unicode_download.sh \
qjs.c qjsc.c qjscalc.js repl.js \
quickjs.c quickjs.h quickjs-atom.h \
quickjs-libc.c quickjs-libc.h quickjs-opcode.h \

+ 2
- 2
repl.js View File

@ -1101,9 +1101,9 @@ import * as os from "os";
std.puts("\x1b[H\x1b[J");
} else if (cmd === "q") {
std.exit(0);
} else if (cmd === "a") {
} else if (has_jscalc && cmd === "a") {
algebraicMode = true;
} else if (cmd === "n") {
} else if (has_jscalc && cmd === "n") {
algebraicMode = false;
} else {
std.puts("Unknown directive: " + cmd + "\n");

+ 39
- 8
run-test262.c View File

@ -41,6 +41,8 @@
/* enable test262 thread support to test SharedArrayBuffer and Atomics */
#define CONFIG_AGENT
/* cross-realm tests (not supported yet) */
//#define CONFIG_REALM
#define CMD_NAME "run-test262"
@ -432,7 +434,8 @@ typedef struct {
char *str;
} AgentReport;
static void add_helpers(JSContext *ctx, int argc, char **argv);
static JSValue add_helpers1(JSContext *ctx);
static void add_helpers(JSContext *ctx);
static pthread_mutex_t agent_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t agent_cond = PTHREAD_COND_INITIALIZER;
@ -464,7 +467,7 @@ static void *agent_start(void *arg)
JS_SetRuntimeInfo(rt, "agent");
JS_SetCanBlock(rt, TRUE);
add_helpers(ctx, 0, NULL);
add_helpers(ctx);
ret_val = JS_Eval(ctx, agent->script, strlen(agent->script),
"<evalScript>", JS_EVAL_TYPE_GLOBAL);
free(agent->script);
@ -717,7 +720,20 @@ static JSValue js_new_agent(JSContext *ctx)
}
#endif
static void add_helpers(JSContext *ctx, int argc, char **argv)
#ifdef CONFIG_REALM
static JSValue js_createRealm(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
JSContext *ctx1;
/* XXX: the context is not freed, need a refcount */
ctx1 = JS_NewContext(JS_GetRuntime(ctx));
if (!ctx1)
return JS_ThrowOutOfMemory(ctx);
return add_helpers1(ctx1);
}
#endif
static JSValue add_helpers1(JSContext *ctx)
{
JSValue global_obj;
JSValue obj262;
@ -742,9 +758,24 @@ static void add_helpers(JSContext *ctx, int argc, char **argv)
JS_SetPropertyStr(ctx, obj262, "agent", js_new_agent(ctx));
#endif
JS_SetPropertyStr(ctx, global_obj, "$262", obj262);
#ifdef CONFIG_REALM
JS_SetPropertyStr(ctx, obj262, "global",
JS_DupValue(ctx, global_obj));
JS_SetPropertyStr(ctx, obj262, "createRealm",
JS_NewCFunction(ctx, js_createRealm,
"createRealm", 0));
#endif
JS_SetPropertyStr(ctx, global_obj, "$262", JS_DupValue(ctx, obj262));
JS_FreeValue(ctx, global_obj);
return obj262;
}
static void add_helpers(JSContext *ctx)
{
JS_FreeValue(ctx, add_helpers1(ctx));
}
static char *load_file(const char *filename, size_t *lenp)
@ -1476,7 +1507,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
/* loader for ES6 modules */
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader_test, NULL);
add_helpers(ctx, 0, NULL);
add_helpers(ctx);
/* add backtrace if the isError property is present in a thrown
object */
@ -1535,7 +1566,7 @@ int run_test(const char *filename, int index)
namelist_t include_list = { 0 }, *ip = &include_list;
is_nostrict = is_onlystrict = is_negative = is_async = is_module = skip = FALSE;
can_block = FALSE;
can_block = TRUE;
error_type = NULL;
buf = load_file(filename, &buf_len);
@ -1588,8 +1619,8 @@ int run_test(const char *filename, int index)
is_module = TRUE;
skip |= skip_module;
}
else if (str_equal(option, "CanBlockIsTrue")) {
can_block = TRUE;
else if (str_equal(option, "CanBlockIsFalse")) {
can_block = FALSE;
}
free(option);
}

+ 23
- 6
test262.conf View File

@ -62,6 +62,10 @@ caller
class
class-fields-private=skip
class-fields-public=skip
class-methods-private=skip
class-static-fields-public=skip
class-static-fields-private=skip
class-static-methods-private=skip
computed-property-names
const
cross-realm=skip
@ -78,12 +82,18 @@ default-arg
default-parameters
destructuring-assignment
destructuring-binding
dynamic-import=skip
export-star-as-namespace-from-module=skip
FinalizationGroup=skip
Float32Array
Float64Array
for-of
generators
global
globalThis=skip
hashbang=skip
host-gc-required=skip
import.meta=skip
Int32Array
Int8Array
IsHTMLDDA=skip
json-superset
@ -93,10 +103,13 @@ new.target
numeric-separator-literal
object-rest
object-spread
Object.fromEntries=skip
Object.is
optional-catch-binding
Promise.allSettled=skip
Promise.prototype.finally
Proxy
proxy-missing-checks=skip
Reflect
Reflect.construct
Reflect.set
@ -105,6 +118,7 @@ regexp-dotall
regexp-lookbehind
regexp-named-groups
regexp-unicode-property-escapes
rest-parameters
Set
SharedArrayBuffer
string-trimming
@ -138,7 +152,9 @@ Uint16Array
Uint8Array
Uint8ClampedArray
WeakMap
WeakRef=skip
WeakSet
well-formed-json-stringify
[exclude]
# list excluded tests and directories here
@ -149,9 +165,6 @@ test262/test/intl402/
# these builtins are not supported:
test262/test/built-ins/BigInt/
# mislabelled feature Symbol.match -> Symbol.matchAll
test262/test/built-ins/Symbol/matchAll/prop-desc.js
# incompatible with the "caller" feature
test262/test/built-ins/Function/prototype/restricted-property-caller.js
test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
@ -162,8 +175,12 @@ test262/test/language/statements/debugger/statement.js
# bogus html close comment test with syntax error
test262/test/annexB/built-ins/Function/createdynfn-html-close-comment-params.js
# bogus test #14 compares 2 consecutive calls to Date(), may be different if unlucky
#test262/test/built-ins/Date/S15.9.2.1_A2.js
# bogus class tests
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-accessor-meth-valid.js
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-async-gen-meth-valid.js
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-async-meth-valid.js
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-gen-meth-valid.js
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-meth-valid.js
# slow tests
#test262/test/built-ins/RegExp/CharacterClassEscapes/

+ 51
- 0
test262_errors.txt View File

@ -0,0 +1,51 @@
test262/test/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-body.js:25: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
test262/test/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-body.js:25: strict mode: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
test262/test/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js:32: SyntaxError: redeclaration of err
test262/test/annexB/language/function-code/function-redeclaration-block.js:18: SyntaxError: invalid redefinition of lexical identifier
test262/test/annexB/language/function-code/function-redeclaration-switch.js:32: SyntaxError: invalid redefinition of lexical identifier
test262/test/annexB/language/statements/try/catch-redeclared-for-of-var.js:19: SyntaxError: invalid redefinition of lexical identifier
test262/test/annexB/language/statements/try/catch-redeclared-for-of-var.js:19: strict mode: SyntaxError: invalid redefinition of lexical identifier
test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:19: Test262Error: Expected SameValue(«true», «false») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:19: strict mode: Test262Error: Expected SameValue(«true», «false») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/stability.js:15: Test262Error: pre-sorted (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/stability.js:15: strict mode: Test262Error: pre-sorted (Testing with Float64Array.)
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-async-function.js:37: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-async-function.js:37: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-async-generator.js:37: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-async-generator.js:37: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-class.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-class.js:36: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-const.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-const.js:36: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-function.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-function.js:36: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-generator.js:37: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-generator.js:37: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-let.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-let.js:36: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/computed-property-names/class/static/method-number.js:9: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['1', '2', 'length', 'prototype', 'name', 'a', 'c'])` returns `true`
test262/test/language/computed-property-names/class/static/method-number.js:9: strict mode: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['1', '2', 'length', 'prototype', 'name', 'a', 'c'])` returns `true`
test262/test/language/computed-property-names/class/static/method-string.js:9: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['length', 'prototype', 'name', 'a', 'b', 'c', 'd'])` returns `true`
test262/test/language/computed-property-names/class/static/method-string.js:9: strict mode: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['length', 'prototype', 'name', 'a', 'b', 'c', 'd'])` returns `true`
test262/test/language/computed-property-names/class/static/method-symbol.js:10: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['length', 'prototype', 'name', 'a', 'c'])` returns `true`
test262/test/language/computed-property-names/class/static/method-symbol.js:10: strict mode: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['length', 'prototype', 'name', 'a', 'c'])` returns `true`
test262/test/language/expressions/await/async-await-interleaved.js:15: TypeError: $DONE() not called
test262/test/language/expressions/await/async-await-interleaved.js:15: strict mode: TypeError: $DONE() not called
test262/test/language/expressions/await/async-generator-interleaved.js:15: TypeError: $DONE() not called
test262/test/language/expressions/await/async-generator-interleaved.js:15: strict mode: TypeError: $DONE() not called
test262/test/language/expressions/await/await-monkey-patched-promise.js:16: TypeError: $DONE() not called
test262/test/language/expressions/await/await-monkey-patched-promise.js:16: strict mode: TypeError: $DONE() not called
test262/test/language/expressions/await/for-await-of-interleaved.js:15: TypeError: $DONE() not called
test262/test/language/expressions/await/for-await-of-interleaved.js:15: strict mode: TypeError: $DONE() not called
test262/test/language/statements/async-generator/return-undefined-implicit-and-explicit.js:74: TypeError: $DONE() not called
test262/test/language/statements/async-generator/return-undefined-implicit-and-explicit.js:74: strict mode: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-async-from-sync-iterator-inaccessible.js:38: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-async-from-sync-iterator-inaccessible.js:38: strict mode: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js:132: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js:132: strict mode: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/async-from-sync-iterator-continuation-abrupt-completion-get-constructor.js:20: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/async-from-sync-iterator-continuation-abrupt-completion-get-constructor.js:20: strict mode: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/ticks-with-async-iter-resolved-promise-and-constructor-lookup-two.js:45: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/ticks-with-async-iter-resolved-promise-and-constructor-lookup-two.js:45: strict mode: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/ticks-with-sync-iter-resolved-promise-and-constructor-lookup.js:58: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/ticks-with-sync-iter-resolved-promise-and-constructor-lookup.js:58: strict mode: TypeError: $DONE() not called

+ 23
- 6
test262bn.conf View File

@ -63,6 +63,10 @@ caller
class
class-fields-private=skip
class-fields-public=skip
class-methods-private=skip
class-static-fields-public=skip
class-static-fields-private=skip
class-static-methods-private=skip
computed-property-names
const
cross-realm=skip
@ -79,12 +83,18 @@ default-arg
default-parameters
destructuring-assignment
destructuring-binding
dynamic-import=skip
export-star-as-namespace-from-module=skip
FinalizationGroup=skip
Float32Array
Float64Array
for-of
generators
global
globalThis=skip
hashbang=skip
host-gc-required=skip
import.meta=skip
Int32Array
Int8Array
IsHTMLDDA=skip
json-superset
@ -94,10 +104,13 @@ new.target
numeric-separator-literal
object-rest
object-spread
Object.fromEntries=skip
Object.is
optional-catch-binding
Promise.allSettled=skip
Promise.prototype.finally
Proxy
proxy-missing-checks=skip
Reflect
Reflect.construct
Reflect.set
@ -106,6 +119,7 @@ regexp-dotall
regexp-lookbehind
regexp-named-groups
regexp-unicode-property-escapes
rest-parameters
Set
SharedArrayBuffer=skip
string-trimming
@ -139,7 +153,9 @@ Uint16Array
Uint8Array
Uint8ClampedArray
WeakMap
WeakRef=skip
WeakSet
well-formed-json-stringify
[exclude]
# list excluded tests and directories here
@ -151,9 +167,6 @@ test262/test/intl402/
test262/test/built-ins/Atomics/
test262/test/built-ins/SharedArrayBuffer/
# mislabelled feature Symbol.match -> Symbol.matchAll
test262/test/built-ins/Symbol/matchAll/prop-desc.js
# incompatible with the "caller" feature
test262/test/built-ins/Function/prototype/restricted-property-caller.js
test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
@ -164,8 +177,12 @@ test262/test/language/statements/debugger/statement.js
# bogus html close comment test with syntax error
test262/test/annexB/built-ins/Function/createdynfn-html-close-comment-params.js
# bogus test #14 compares 2 consecutive calls to Date(), may be different if unlucky
#test262/test/built-ins/Date/S15.9.2.1_A2.js
# bogus class tests
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-accessor-meth-valid.js
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-async-gen-meth-valid.js
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-async-meth-valid.js
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-gen-meth-valid.js
test262/test/language/statements/class/elements/syntax/valid/export-default-grammar-static-ctor-meth-valid.js
# slow tests
#test262/test/built-ins/RegExp/CharacterClassEscapes/

+ 56
- 0
test262bn_errors.txt View File

@ -0,0 +1,56 @@
test262/test/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-body.js:25: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
test262/test/annexB/built-ins/Function/createdynfn-no-line-terminator-html-close-comment-body.js:25: strict mode: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
test262/test/annexB/language/eval-code/direct/var-env-lower-lex-catch-non-strict.js:32: SyntaxError: redeclaration of err
test262/test/annexB/language/function-code/function-redeclaration-block.js:18: SyntaxError: invalid redefinition of lexical identifier
test262/test/annexB/language/function-code/function-redeclaration-switch.js:32: SyntaxError: invalid redefinition of lexical identifier
test262/test/annexB/language/statements/try/catch-redeclared-for-of-var.js:19: SyntaxError: invalid redefinition of lexical identifier
test262/test/annexB/language/statements/try/catch-redeclared-for-of-var.js:19: strict mode: SyntaxError: invalid redefinition of lexical identifier
test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:19: Test262Error: Expected SameValue(«true», «false») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:19: strict mode: Test262Error: Expected SameValue(«true», «false») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/stability.js:15: Test262Error: pre-sorted (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/stability.js:15: strict mode: Test262Error: pre-sorted (Testing with Float64Array.)
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-async-function.js:37: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-async-function.js:37: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-async-generator.js:37: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-async-generator.js:37: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-class.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-class.js:36: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-const.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-const.js:36: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-function.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-function.js:36: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-generator.js:37: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-generator.js:37: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-let.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/block-scope/syntax/redeclaration/inner-block-var-name-redeclaration-attempt-with-let.js:36: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/computed-property-names/class/static/method-number.js:9: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['1', '2', 'length', 'prototype', 'name', 'a', 'c'])` returns `true`
test262/test/language/computed-property-names/class/static/method-number.js:9: strict mode: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['1', '2', 'length', 'prototype', 'name', 'a', 'c'])` returns `true`
test262/test/language/computed-property-names/class/static/method-string.js:9: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['length', 'prototype', 'name', 'a', 'b', 'c', 'd'])` returns `true`
test262/test/language/computed-property-names/class/static/method-string.js:9: strict mode: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['length', 'prototype', 'name', 'a', 'b', 'c', 'd'])` returns `true`
test262/test/language/computed-property-names/class/static/method-symbol.js:10: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['length', 'prototype', 'name', 'a', 'c'])` returns `true`
test262/test/language/computed-property-names/class/static/method-symbol.js:10: strict mode: Test262Error: `compareArray(Object.getOwnPropertyNames(C), ['length', 'prototype', 'name', 'a', 'c'])` returns `true`
test262/test/language/expressions/await/async-await-interleaved.js:15: TypeError: $DONE() not called
test262/test/language/expressions/await/async-await-interleaved.js:15: strict mode: TypeError: $DONE() not called
test262/test/language/expressions/await/async-generator-interleaved.js:15: TypeError: $DONE() not called
test262/test/language/expressions/await/async-generator-interleaved.js:15: strict mode: TypeError: $DONE() not called
test262/test/language/expressions/await/await-monkey-patched-promise.js:16: TypeError: $DONE() not called
test262/test/language/expressions/await/await-monkey-patched-promise.js:16: strict mode: TypeError: $DONE() not called
test262/test/language/expressions/await/for-await-of-interleaved.js:15: TypeError: $DONE() not called
test262/test/language/expressions/await/for-await-of-interleaved.js:15: strict mode: TypeError: $DONE() not called
test262/test/language/literals/numeric/numeric-separator-literal-lol-00-err.js:39: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/literals/numeric/numeric-separator-literal-lol-01-err.js:39: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/literals/numeric/numeric-separator-literal-lol-07-err.js:41: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/literals/numeric/numeric-separator-literal-nonoctal-08-err.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/literals/numeric/numeric-separator-literal-nonoctal-09-err.js:36: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/async-generator/return-undefined-implicit-and-explicit.js:74: TypeError: $DONE() not called
test262/test/language/statements/async-generator/return-undefined-implicit-and-explicit.js:74: strict mode: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-async-from-sync-iterator-inaccessible.js:38: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-async-from-sync-iterator-inaccessible.js:38: strict mode: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js:132: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js:132: strict mode: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/async-from-sync-iterator-continuation-abrupt-completion-get-constructor.js:20: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/async-from-sync-iterator-continuation-abrupt-completion-get-constructor.js:20: strict mode: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/ticks-with-async-iter-resolved-promise-and-constructor-lookup-two.js:45: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/ticks-with-async-iter-resolved-promise-and-constructor-lookup-two.js:45: strict mode: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/ticks-with-sync-iter-resolved-promise-and-constructor-lookup.js:58: TypeError: $DONE() not called
test262/test/language/statements/for-await-of/ticks-with-sync-iter-resolved-promise-and-constructor-lookup.js:58: strict mode: TypeError: $DONE() not called

+ 6
- 0
test262o.conf View File

@ -400,5 +400,11 @@ test262o/test/suite/ch12/12.6/12.6.3/S12.6.3_A9.1.js
# ECMA 2019 optional-catch-binding feature allows try{}catch{}
test262o/test/suite/ch12/12.14/S12.14_A16_T4.js
# Syntax error instead of ReferenceError in ES2020
test262o/test/suite/ch11/11.13/11.13.1/11.13.1-1-1.js
test262o/test/suite/ch11/11.13/11.13.1/11.13.1-1-2.js
test262o/test/suite/ch11/11.13/11.13.1/11.13.1-1-3.js
test262o/test/suite/ch11/11.13/11.13.1/11.13.1-1-4.js
[tests]
# list test files or use config.testdir

+ 27
- 651
tests/test262.patch View File

@ -1,37 +1,22 @@
diff --git a/harness/doneprintHandle.js b/harness/doneprintHandle.js
index 2b4ab88..6c95f9f 100644
index a6ea799..b3dec87 100644
--- a/harness/doneprintHandle.js
+++ b/harness/doneprintHandle.js
@@ -11,7 +11,7 @@ function __consolePrintHandle__(msg){
function $DONE(){
if(!arguments[0])
- __consolePrintHandle__('Test262:AsyncTestComplete');
@@ -18,5 +18,6 @@ function $DONE(error) {
}
} else {
__consolePrintHandle__('Test262:AsyncTestComplete');
+ $async_done = true;
else
- __consolePrintHandle__('Test262:AsyncTestFailure:' + arguments[0]);
+ __consolePrintHandle__('Error:' + arguments[0]);
}
}
diff --git a/harness/regExpUtils.js b/harness/regExpUtils.js
index 362a6d16..d3dde03 100644
index 2abfee3..e7c07b1 100644
--- a/harness/regExpUtils.js
+++ b/harness/regExpUtils.js
@@ -5,6 +5,7 @@ description: |
@@ -5,24 +5,27 @@ description: |
Collection of functions used to assert the correctness of RegExp objects.
---*/
+/*
function buildString({ loneCodePoints, ranges }) {
const CHUNK_SIZE = 10000;
let result = String.fromCodePoint(...loneCodePoints);
@@ -21,6 +22,32 @@ function buildString({ loneCodePoints, ranges }) {
}
return result;
}
+*/
+
+var codePointRange;
+
+if ($262 && typeof $262.codePointRange === "function") {
+ /* use C function to build the codePointRange (much faster with
+ slow JS engines) */
@ -47,637 +32,28 @@ index 362a6d16..d3dde03 100644
+ }
+}
+
+function buildString({ loneCodePoints, ranges }) {
function buildString({ loneCodePoints, ranges }) {
- const CHUNK_SIZE = 10000;
- let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints);
- for (let i = 0; i < ranges.length; i++) {
- const range = ranges[i];
- const start = range[0];
- const end = range[1];
- const codePoints = [];
- for (let length = 0, codePoint = start; codePoint <= end; codePoint++) {
- codePoints[length++] = codePoint;
- if (length === CHUNK_SIZE) {
- result += Reflect.apply(String.fromCodePoint, null, codePoints);
- codePoints.length = length = 0;
- }
+ let result = String.fromCodePoint.apply(null, loneCodePoints);
+ for (const [start, end] of ranges) {
+ result += codePointRange(start, end + 1);
+ }
}
- result += Reflect.apply(String.fromCodePoint, null, codePoints);
- }
- return result;
+ return result;
+}
function testPropertyEscapes(regex, string, expression) {
if (!regex.test(string)) {
diff --git a/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js b/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js
index 652ef43..8d1a7ed 100644
--- a/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js
+++ b/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-flags-u.js
@@ -33,14 +33,16 @@ info: |
The production CharacterClassEscape :: W evaluates as follows:
Return the set of all characters not included in the set returned by CharacterClassEscape :: w.
features: [String.fromCodePoint]
+includes: [regExpUtils.js]
---*/
const chunks = [];
-const totalChunks = Math.ceil(0x10ffff / 0x10000);
-
-for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) {
- // split strings to avoid a super long one;
- chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint);
+const lastCodePoint = 0x10ffff;
+let codePoint = 0;
+while (codePoint <= lastCodePoint) {
+ let n = Math.min(0x10000, lastCodePoint - codePoint + 1);
+ chunks.push(codePointRange(codePoint, codePoint + n));
+ codePoint += n;
}
const re = /\d/ug;
diff --git a/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js b/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js
index 8683600..36d9f1c 100644
--- a/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js
+++ b/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier-flags-u.js
@@ -33,14 +33,16 @@ info: |
The production CharacterClassEscape :: W evaluates as follows:
Return the set of all characters not included in the set returned by CharacterClassEscape :: w.
features: [String.fromCodePoint]
+includes: [regExpUtils.js]
---*/
const chunks = [];
-const totalChunks = Math.ceil(0x10ffff / 0x10000);
-
-for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) {
- // split strings to avoid a super long one;
- chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint);
+const lastCodePoint = 0x10ffff;
+let codePoint = 0;
+while (codePoint <= lastCodePoint) {
+ let n = Math.min(0x10000, lastCodePoint - codePoint + 1);
+ chunks.push(codePointRange(codePoint, codePoint + n));
+ codePoint += n;
}
const re = /\d+/ug;
diff --git a/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier.js b/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier.js
index 20d6b38..e9c91f8 100644
--- a/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier.js
+++ b/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape-plus-quantifier.js
@@ -33,14 +33,16 @@ info: |
The production CharacterClassEscape :: W evaluates as follows:
Return the set of all characters not included in the set returned by CharacterClassEscape :: w.
features: [String.fromCodePoint]
+includes: [regExpUtils.js]
---*/
const chunks = [];
-const totalChunks = Math.ceil(0xffff / 0x10000);
-
-for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) {
- // split strings to avoid a super long one;
- chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint);
+const lastCodePoint = 0xffff;
+let codePoint = 0;
+while (codePoint <= lastCodePoint) {
+ let n = Math.min(0x10000, lastCodePoint - codePoint + 1);
+ chunks.push(codePointRange(codePoint, codePoint + n));
+ codePoint += n;
}
const re = /\d+/g;
diff --git a/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape.js b/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape.js
index d3aef45..b2c949b 100644
--- a/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape.js
+++ b/test/built-ins/RegExp/CharacterClassEscapes/character-class-digit-class-escape.js
@@ -33,14 +33,16 @@ info: |
The production CharacterClassEscape :: W evaluates as follows:
Return the set of all characters not included in the set returned by CharacterClassEscape :: w.
features: [String.fromCodePoint]
+includes: [regExpUtils.js]
---*/
const chunks = [];
-const totalChunks = Math.ceil(0xffff / 0x10000);
-
-for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) {
- // split strings to avoid a super long one;
- chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint);
+const lastCodePoint = 0xffff;
+let codePoint = 0;
+while (codePoint <= lastCodePoint) {
+ let n = Math.min(0x10000, lastCodePoint - codePoint + 1);
+ chunks.push(codePointRange(codePoint, codePoint + n));
+ codePoint += n;
}
const re = /\d/g;
diff --git a/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js b/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js
index ead3d68..beaf9cf 100644
--- a/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js
+++ b/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js
@@ -33,14 +33,16 @@ info: |
The production CharacterClassEscape :: W evaluates as follows:
Return the set of all characters not included in the set returned by CharacterClassEscape :: w.
features: [String.fromCodePoint]
+includes: [regExpUtils.js]
---*/
const chunks = [];
-const totalChunks = Math.ceil(0x10ffff / 0x10000);
-
-for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) {
- // split strings to avoid a super long one;
- chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint);
+const lastCodePoint = 0x10ffff;
+let codePoint = 0;
+while (codePoint <= lastCodePoint) {
+ let n = Math.min(0x10000, lastCodePoint - codePoint + 1);
+ chunks.push(codePointRange(codePoint, codePoint + n));
+ codePoint += n;
}
const re = /\D/ug;
diff --git a/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js b/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js
index 5c02690..0030b23 100644
--- a/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js
+++ b/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js
@@ -33,14 +33,16 @@ info: |
The production CharacterClassEscape :: W evaluates as follows:
Return the set of all characters not included in the set returned by CharacterClassEscape :: w.
features: [String.fromCodePoint]
+includes: [regExpUtils.js]
---*/
const chunks = [];
-const totalChunks = Math.ceil(0x10ffff / 0x10000);
-
-for (let codePoint = 0; codePoint < 0x10FFFF; codePoint++) {
- // split strings to avoid a super long one;
- chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint);
+const lastCodePoint = 0x10ffff;
+let codePoint = 0;
+while (codePoint <= lastCodePoint) {
+ let n = Math.min(0x10000, lastCodePoint - codePoint + 1);
+ chunks.push(codePointRange(codePoint, codePoint + n));
+ codePoint += n;
}
const re = /\D+/ug;
diff --git a/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js b/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js
index 960d9cf..b663be0 100644
--- a/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js
+++ b/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier.js
@@ -33,14 +33,16 @@ info: |
The production CharacterClassEscape :: W evaluates as follows:
Return the set of all characters not included in the set returned by CharacterClassEscape :: w.
features: [String.fromCodePoint]
+includes: [regExpUtils.js]
---*/
const chunks = [];
-const totalChunks = Math.ceil(0xffff / 0x10000);
-
-for (let codePoint = 0; codePoint < 0xFFFF; codePoint++) {
- // split strings to avoid a super long one;
- chunks[codePoint % totalChunks] += String.fromCodePoint(codePoint);
+const lastCodePoint = 0xffff;
+let codePoint = 0;
+while (codePoint <= lastCodePoint) {
+ let n = Math.min(0x10000, lastCodePoint - codePoint + 1);