2020-09-06 release
This commit is contained in:
parent
8900766099
commit
7c312df422
26 changed files with 912 additions and 476 deletions
|
@ -1,3 +1,12 @@
|
||||||
|
2020-09-06:
|
||||||
|
|
||||||
|
- added logical assignment operators
|
||||||
|
- added IsHTMLDDA support
|
||||||
|
- faster for-of loops
|
||||||
|
- os.Worker now takes a module filename as parameter
|
||||||
|
- qjsc: added -D option to compile dynamically loaded modules or workers
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
2020-07-05:
|
2020-07-05:
|
||||||
|
|
||||||
- modified JS_GetPrototype() to return a live value
|
- modified JS_GetPrototype() to return a live value
|
||||||
|
|
4
TODO
4
TODO
|
@ -74,5 +74,5 @@ REPL:
|
||||||
Test262o: 0/11262 errors, 463 excluded
|
Test262o: 0/11262 errors, 463 excluded
|
||||||
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
|
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
|
||||||
|
|
||||||
Test262: 30/71095 errors, 870 excluded, 549 skipped
|
Test262: 30/71748 errors, 868 excluded, 474 skipped
|
||||||
Test262 commit: 281eb10b2844929a7c0ac04527f5b42ce56509fd
|
Test262 commit: 24c67328062383079ada85f4d253eb0526fd209b
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
2020-07-05
|
2020-09-06
|
||||||
|
|
21
cutils.c
21
cutils.c
|
@ -258,19 +258,30 @@ int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 0xc0 ... 0xdf:
|
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
||||||
|
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
|
||||||
|
case 0xc8: case 0xc9: case 0xca: case 0xcb:
|
||||||
|
case 0xcc: case 0xcd: case 0xce: case 0xcf:
|
||||||
|
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
||||||
|
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
||||||
|
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
||||||
|
case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
||||||
l = 1;
|
l = 1;
|
||||||
break;
|
break;
|
||||||
case 0xe0 ... 0xef:
|
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
||||||
|
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
||||||
|
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
||||||
|
case 0xec: case 0xed: case 0xee: case 0xef:
|
||||||
l = 2;
|
l = 2;
|
||||||
break;
|
break;
|
||||||
case 0xf0 ... 0xf7:
|
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
|
||||||
|
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
||||||
l = 3;
|
l = 3;
|
||||||
break;
|
break;
|
||||||
case 0xf8 ... 0xfb:
|
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
|
||||||
l = 4;
|
l = 4;
|
||||||
break;
|
break;
|
||||||
case 0xfc ... 0xfd:
|
case 0xfc: case 0xfd:
|
||||||
l = 5;
|
l = 5;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
<html>
|
<html>
|
||||||
<!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
|
<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
<title>Javascript Bignum Extensions</title>
|
<title>Javascript Bignum Extensions</title>
|
||||||
|
|
||||||
<meta name="description" content="Javascript Bignum Extensions">
|
<meta name="description" content="Javascript Bignum Extensions">
|
||||||
|
@ -10,6 +9,7 @@
|
||||||
<meta name="resource-type" content="document">
|
<meta name="resource-type" content="document">
|
||||||
<meta name="distribution" content="global">
|
<meta name="distribution" content="global">
|
||||||
<meta name="Generator" content="makeinfo">
|
<meta name="Generator" content="makeinfo">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
<link href="#SEC_Contents" rel="contents" title="Table of Contents">
|
<link href="#SEC_Contents" rel="contents" title="Table of Contents">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
<!--
|
<!--
|
||||||
|
|
BIN
doc/jsbignum.pdf
BIN
doc/jsbignum.pdf
Binary file not shown.
|
@ -1,8 +1,7 @@
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
<html>
|
<html>
|
||||||
<!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
|
<!-- Created by GNU Texinfo 6.1, http://www.gnu.org/software/texinfo/ -->
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
|
||||||
<title>QuickJS Javascript Engine</title>
|
<title>QuickJS Javascript Engine</title>
|
||||||
|
|
||||||
<meta name="description" content="QuickJS Javascript Engine">
|
<meta name="description" content="QuickJS Javascript Engine">
|
||||||
|
@ -10,6 +9,7 @@
|
||||||
<meta name="resource-type" content="document">
|
<meta name="resource-type" content="document">
|
||||||
<meta name="distribution" content="global">
|
<meta name="distribution" content="global">
|
||||||
<meta name="Generator" content="makeinfo">
|
<meta name="Generator" content="makeinfo">
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
<link href="#SEC_Contents" rel="contents" title="Table of Contents">
|
<link href="#SEC_Contents" rel="contents" title="Table of Contents">
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
<!--
|
<!--
|
||||||
|
@ -237,7 +237,7 @@ source is <code>import</code>.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><code>--bignum</code></dt>
|
<dt><code>--bignum</code></dt>
|
||||||
<dd><p>Enable the bignum extensions: BigDecimal object, BigFloat object and
|
<dd><p>Enable the bignum extensions: BigDecimal object, BigFloat object and
|
||||||
the <code>"use bigint"</code> and <code>"use math"</code> directives.
|
the <code>"use math"</code> directive.
|
||||||
</p>
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
<dt><code>-I file</code></dt>
|
<dt><code>-I file</code></dt>
|
||||||
|
@ -293,6 +293,13 @@ executable file.
|
||||||
<dd><p>Compile as Javascript module (default=autodetect).
|
<dd><p>Compile as Javascript module (default=autodetect).
|
||||||
</p>
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
|
<dt><code>-D module_name</code></dt>
|
||||||
|
<dd><p>Compile a dynamically loaded module and its dependencies. This option
|
||||||
|
is needed when your code uses the <code>import</code> keyword or the
|
||||||
|
<code>os.Worker</code> constructor because the compiler cannot statically
|
||||||
|
find the name of the dynamically loaded modules.
|
||||||
|
</p>
|
||||||
|
</dd>
|
||||||
<dt><code>-M module_name[,cname]</code></dt>
|
<dt><code>-M module_name[,cname]</code></dt>
|
||||||
<dd><p>Add initialization code for an external C module. See the
|
<dd><p>Add initialization code for an external C module. See the
|
||||||
<code>c_module</code> example.
|
<code>c_module</code> example.
|
||||||
|
@ -314,7 +321,7 @@ when the <code>-fno-x</code> options are used.
|
||||||
</dd>
|
</dd>
|
||||||
<dt><code>-fbignum</code></dt>
|
<dt><code>-fbignum</code></dt>
|
||||||
<dd><p>Enable the bignum extensions: BigDecimal object, BigFloat object and
|
<dd><p>Enable the bignum extensions: BigDecimal object, BigFloat object and
|
||||||
the <code>"use bigint"</code> and <code>"use math"</code> directives.
|
the <code>"use math"</code> directive.
|
||||||
</p>
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
@ -989,13 +996,14 @@ to the timer.
|
||||||
<code>"win32"</code> or <code>"js"</code>.
|
<code>"win32"</code> or <code>"js"</code>.
|
||||||
</p>
|
</p>
|
||||||
</dd>
|
</dd>
|
||||||
<dt><code>Worker(source)</code></dt>
|
<dt><code>Worker(module_filename)</code></dt>
|
||||||
<dd><p>Constructor to create a new thread (worker) with an API close to the
|
<dd><p>Constructor to create a new thread (worker) with an API close to the
|
||||||
<code>WebWorkers</code>. <code>source</code> is a string containing the module
|
<code>WebWorkers</code>. <code>module_filename</code> is a string specifying the
|
||||||
source which is executed in the newly created thread. Threads normally
|
module filename which is executed in the newly created thread. As for
|
||||||
don’t share any data and communicate between each other with
|
dynamically imported module, it is relative to the current script or
|
||||||
messages. Nested workers are not supported. An example is available in
|
module path. Threads normally don’t share any data and communicate
|
||||||
<samp>tests/test_worker.js</samp>.
|
between each other with messages. Nested workers are not supported. An
|
||||||
|
example is available in <samp>tests/test_worker.js</samp>.
|
||||||
</p>
|
</p>
|
||||||
<p>The worker class has the following static properties:
|
<p>The worker class has the following static properties:
|
||||||
</p>
|
</p>
|
||||||
|
|
BIN
doc/quickjs.pdf
BIN
doc/quickjs.pdf
Binary file not shown.
|
@ -120,7 +120,7 @@ Load as ES6 script (default=autodetect).
|
||||||
|
|
||||||
@item --bignum
|
@item --bignum
|
||||||
Enable the bignum extensions: BigDecimal object, BigFloat object and
|
Enable the bignum extensions: BigDecimal object, BigFloat object and
|
||||||
the @code{"use bigint"} and @code{"use math"} directives.
|
the @code{"use math"} directive.
|
||||||
|
|
||||||
@item -I file
|
@item -I file
|
||||||
@item --include file
|
@item --include file
|
||||||
|
@ -167,6 +167,12 @@ Set the C name of the generated data.
|
||||||
@item -m
|
@item -m
|
||||||
Compile as Javascript module (default=autodetect).
|
Compile as Javascript module (default=autodetect).
|
||||||
|
|
||||||
|
@item -D module_name
|
||||||
|
Compile a dynamically loaded module and its dependencies. This option
|
||||||
|
is needed when your code uses the @code{import} keyword or the
|
||||||
|
@code{os.Worker} constructor because the compiler cannot statically
|
||||||
|
find the name of the dynamically loaded modules.
|
||||||
|
|
||||||
@item -M module_name[,cname]
|
@item -M module_name[,cname]
|
||||||
Add initialization code for an external C module. See the
|
Add initialization code for an external C module. See the
|
||||||
@code{c_module} example.
|
@code{c_module} example.
|
||||||
|
@ -184,7 +190,7 @@ Disable selected language features to produce a smaller executable file.
|
||||||
|
|
||||||
@item -fbignum
|
@item -fbignum
|
||||||
Enable the bignum extensions: BigDecimal object, BigFloat object and
|
Enable the bignum extensions: BigDecimal object, BigFloat object and
|
||||||
the @code{"use bigint"} and @code{"use math"} directives.
|
the @code{"use math"} directive.
|
||||||
|
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
|
@ -764,13 +770,14 @@ Cancel a timer.
|
||||||
Return a string representing the platform: @code{"linux"}, @code{"darwin"},
|
Return a string representing the platform: @code{"linux"}, @code{"darwin"},
|
||||||
@code{"win32"} or @code{"js"}.
|
@code{"win32"} or @code{"js"}.
|
||||||
|
|
||||||
@item Worker(source)
|
@item Worker(module_filename)
|
||||||
Constructor to create a new thread (worker) with an API close to the
|
Constructor to create a new thread (worker) with an API close to the
|
||||||
@code{WebWorkers}. @code{source} is a string containing the module
|
@code{WebWorkers}. @code{module_filename} is a string specifying the
|
||||||
source which is executed in the newly created thread. Threads normally
|
module filename which is executed in the newly created thread. As for
|
||||||
don't share any data and communicate between each other with
|
dynamically imported module, it is relative to the current script or
|
||||||
messages. Nested workers are not supported. An example is available in
|
module path. Threads normally don't share any data and communicate
|
||||||
@file{tests/test_worker.js}.
|
between each other with messages. Nested workers are not supported. An
|
||||||
|
example is available in @file{tests/test_worker.js}.
|
||||||
|
|
||||||
The worker class has the following static properties:
|
The worker class has the following static properties:
|
||||||
|
|
||||||
|
|
20
libregexp.c
20
libregexp.c
|
@ -569,7 +569,8 @@ int lre_parse_escape(const uint8_t **pp, int allow_utf16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '0' ... '7':
|
case '0': case '1': case '2': case '3':
|
||||||
|
case '4': case '5': case '6': case '7':
|
||||||
c -= '0';
|
c -= '0';
|
||||||
if (allow_utf16 == 2) {
|
if (allow_utf16 == 2) {
|
||||||
/* only accept \0 not followed by digit */
|
/* only accept \0 not followed by digit */
|
||||||
|
@ -1410,7 +1411,9 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto normal_char;
|
goto normal_char;
|
||||||
case '1' ... '9':
|
case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8':
|
||||||
|
case '9':
|
||||||
{
|
{
|
||||||
const uint8_t *q = ++p;
|
const uint8_t *q = ++p;
|
||||||
|
|
||||||
|
@ -1434,7 +1437,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
}
|
}
|
||||||
goto normal_char;
|
goto normal_char;
|
||||||
}
|
}
|
||||||
return re_parse_error(s, "back reference out of range in reguar expression");
|
return re_parse_error(s, "back reference out of range in regular expression");
|
||||||
}
|
}
|
||||||
emit_back_reference:
|
emit_back_reference:
|
||||||
last_atom_start = s->byte_code.size;
|
last_atom_start = s->byte_code.size;
|
||||||
|
@ -2533,6 +2536,17 @@ int lre_get_flags(const uint8_t *bc_buf)
|
||||||
return bc_buf[RE_HEADER_FLAGS];
|
return bc_buf[RE_HEADER_FLAGS];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return NULL if no group names. Otherwise, return a pointer to
|
||||||
|
'capture_count - 1' zero terminated UTF-8 strings. */
|
||||||
|
const char *lre_get_groupnames(const uint8_t *bc_buf)
|
||||||
|
{
|
||||||
|
uint32_t re_bytecode_len;
|
||||||
|
if ((lre_get_flags(bc_buf) & LRE_FLAG_NAMED_GROUPS) == 0)
|
||||||
|
return NULL;
|
||||||
|
re_bytecode_len = get_u32(bc_buf + 3);
|
||||||
|
return (const char *)(bc_buf + 7 + re_bytecode_len);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
|
||||||
BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size)
|
BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size)
|
||||||
|
|
|
@ -44,6 +44,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
||||||
void *opaque);
|
void *opaque);
|
||||||
int lre_get_capture_count(const uint8_t *bc_buf);
|
int lre_get_capture_count(const uint8_t *bc_buf);
|
||||||
int lre_get_flags(const uint8_t *bc_buf);
|
int lre_get_flags(const uint8_t *bc_buf);
|
||||||
|
const char *lre_get_groupnames(const uint8_t *bc_buf);
|
||||||
int lre_exec(uint8_t **capture,
|
int lre_exec(uint8_t **capture,
|
||||||
const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen,
|
const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen,
|
||||||
int cbuf_type, void *opaque);
|
int cbuf_type, void *opaque);
|
||||||
|
|
26
libunicode.c
26
libunicode.c
|
@ -527,7 +527,13 @@ static int unicode_decomp_entry(uint32_t *res, uint32_t c,
|
||||||
} else {
|
} else {
|
||||||
d = unicode_decomp_data + unicode_decomp_table2[idx];
|
d = unicode_decomp_data + unicode_decomp_table2[idx];
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case DECOMP_TYPE_L1 ... DECOMP_TYPE_L7:
|
case DECOMP_TYPE_L1:
|
||||||
|
case DECOMP_TYPE_L2:
|
||||||
|
case DECOMP_TYPE_L3:
|
||||||
|
case DECOMP_TYPE_L4:
|
||||||
|
case DECOMP_TYPE_L5:
|
||||||
|
case DECOMP_TYPE_L6:
|
||||||
|
case DECOMP_TYPE_L7:
|
||||||
l = type - DECOMP_TYPE_L1 + 1;
|
l = type - DECOMP_TYPE_L1 + 1;
|
||||||
d += (c - code) * l * 2;
|
d += (c - code) * l * 2;
|
||||||
for(i = 0; i < l; i++) {
|
for(i = 0; i < l; i++) {
|
||||||
|
@ -535,7 +541,8 @@ static int unicode_decomp_entry(uint32_t *res, uint32_t c,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
case DECOMP_TYPE_LL1 ... DECOMP_TYPE_LL2:
|
case DECOMP_TYPE_LL1:
|
||||||
|
case DECOMP_TYPE_LL2:
|
||||||
{
|
{
|
||||||
uint32_t k, p;
|
uint32_t k, p;
|
||||||
l = type - DECOMP_TYPE_LL1 + 1;
|
l = type - DECOMP_TYPE_LL1 + 1;
|
||||||
|
@ -551,7 +558,11 @@ static int unicode_decomp_entry(uint32_t *res, uint32_t c,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return l;
|
return l;
|
||||||
case DECOMP_TYPE_S1 ... DECOMP_TYPE_S5:
|
case DECOMP_TYPE_S1:
|
||||||
|
case DECOMP_TYPE_S2:
|
||||||
|
case DECOMP_TYPE_S3:
|
||||||
|
case DECOMP_TYPE_S4:
|
||||||
|
case DECOMP_TYPE_S5:
|
||||||
l = type - DECOMP_TYPE_S1 + 1;
|
l = type - DECOMP_TYPE_S1 + 1;
|
||||||
d += (c - code) * l;
|
d += (c - code) * l;
|
||||||
for(i = 0; i < l; i++) {
|
for(i = 0; i < l; i++) {
|
||||||
|
@ -582,7 +593,14 @@ static int unicode_decomp_entry(uint32_t *res, uint32_t c,
|
||||||
case DECOMP_TYPE_B18:
|
case DECOMP_TYPE_B18:
|
||||||
l = 18;
|
l = 18;
|
||||||
goto decomp_type_b;
|
goto decomp_type_b;
|
||||||
case DECOMP_TYPE_B1 ... DECOMP_TYPE_B8:
|
case DECOMP_TYPE_B1:
|
||||||
|
case DECOMP_TYPE_B2:
|
||||||
|
case DECOMP_TYPE_B3:
|
||||||
|
case DECOMP_TYPE_B4:
|
||||||
|
case DECOMP_TYPE_B5:
|
||||||
|
case DECOMP_TYPE_B6:
|
||||||
|
case DECOMP_TYPE_B7:
|
||||||
|
case DECOMP_TYPE_B8:
|
||||||
l = type - DECOMP_TYPE_B1 + 1;
|
l = type - DECOMP_TYPE_B1 + 1;
|
||||||
decomp_type_b:
|
decomp_type_b:
|
||||||
{
|
{
|
||||||
|
|
43
qjs.c
43
qjs.c
|
@ -46,6 +46,7 @@ extern const uint32_t qjsc_repl_size;
|
||||||
#ifdef CONFIG_BIGNUM
|
#ifdef CONFIG_BIGNUM
|
||||||
extern const uint8_t qjsc_qjscalc[];
|
extern const uint8_t qjsc_qjscalc[];
|
||||||
extern const uint32_t qjsc_qjscalc_size;
|
extern const uint32_t qjsc_qjscalc_size;
|
||||||
|
static int bignum_ext;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
|
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
|
||||||
|
@ -101,6 +102,27 @@ static int eval_file(JSContext *ctx, const char *filename, int module)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* also used to initialize the worker context */
|
||||||
|
static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
||||||
|
{
|
||||||
|
JSContext *ctx;
|
||||||
|
ctx = JS_NewContext(rt);
|
||||||
|
if (!ctx)
|
||||||
|
return NULL;
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
if (bignum_ext) {
|
||||||
|
JS_AddIntrinsicBigFloat(ctx);
|
||||||
|
JS_AddIntrinsicBigDecimal(ctx);
|
||||||
|
JS_AddIntrinsicOperators(ctx);
|
||||||
|
JS_EnableBignumExt(ctx, TRUE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* system modules */
|
||||||
|
js_init_module_std(ctx, "std");
|
||||||
|
js_init_module_os(ctx, "os");
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
#define MALLOC_OVERHEAD 0
|
#define MALLOC_OVERHEAD 0
|
||||||
#else
|
#else
|
||||||
|
@ -294,7 +316,7 @@ int main(int argc, char **argv)
|
||||||
char *include_list[32];
|
char *include_list[32];
|
||||||
int i, include_count = 0;
|
int i, include_count = 0;
|
||||||
#ifdef CONFIG_BIGNUM
|
#ifdef CONFIG_BIGNUM
|
||||||
int load_jscalc, bignum_ext = 0;
|
int load_jscalc;
|
||||||
#endif
|
#endif
|
||||||
size_t stack_size = 0;
|
size_t stack_size = 0;
|
||||||
|
|
||||||
|
@ -426,6 +448,9 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (load_jscalc)
|
||||||
|
bignum_ext = 1;
|
||||||
|
|
||||||
if (trace_memory) {
|
if (trace_memory) {
|
||||||
js_trace_malloc_init(&trace_data);
|
js_trace_malloc_init(&trace_data);
|
||||||
rt = JS_NewRuntime2(&trace_mf, &trace_data);
|
rt = JS_NewRuntime2(&trace_mf, &trace_data);
|
||||||
|
@ -440,22 +465,14 @@ int main(int argc, char **argv)
|
||||||
JS_SetMemoryLimit(rt, memory_limit);
|
JS_SetMemoryLimit(rt, memory_limit);
|
||||||
if (stack_size != 0)
|
if (stack_size != 0)
|
||||||
JS_SetMaxStackSize(rt, stack_size);
|
JS_SetMaxStackSize(rt, stack_size);
|
||||||
|
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
||||||
js_std_init_handlers(rt);
|
js_std_init_handlers(rt);
|
||||||
ctx = JS_NewContext(rt);
|
ctx = JS_NewCustomContext(rt);
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
fprintf(stderr, "qjs: cannot allocate JS context\n");
|
fprintf(stderr, "qjs: cannot allocate JS context\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_BIGNUM
|
|
||||||
if (bignum_ext || load_jscalc) {
|
|
||||||
JS_AddIntrinsicBigFloat(ctx);
|
|
||||||
JS_AddIntrinsicBigDecimal(ctx);
|
|
||||||
JS_AddIntrinsicOperators(ctx);
|
|
||||||
JS_EnableBignumExt(ctx, TRUE);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* loader for ES6 modules */
|
/* loader for ES6 modules */
|
||||||
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
||||||
|
|
||||||
|
@ -472,10 +489,6 @@ int main(int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
js_std_add_helpers(ctx, argc - optind, argv + optind);
|
js_std_add_helpers(ctx, argc - optind, argv + optind);
|
||||||
|
|
||||||
/* system modules */
|
|
||||||
js_init_module_std(ctx, "std");
|
|
||||||
js_init_module_os(ctx, "os");
|
|
||||||
|
|
||||||
/* make 'std' and 'os' visible to non module code */
|
/* make 'std' and 'os' visible to non module code */
|
||||||
if (load_std) {
|
if (load_std) {
|
||||||
const char *str = "import * as std from 'std';\n"
|
const char *str = "import * as std from 'std';\n"
|
||||||
|
|
74
qjsc.c
74
qjsc.c
|
@ -326,6 +326,7 @@ static const char main_c_template1[] =
|
||||||
" JSRuntime *rt;\n"
|
" JSRuntime *rt;\n"
|
||||||
" JSContext *ctx;\n"
|
" JSContext *ctx;\n"
|
||||||
" rt = JS_NewRuntime();\n"
|
" rt = JS_NewRuntime();\n"
|
||||||
|
" js_std_set_worker_new_context_func(JS_NewCustomContext);\n"
|
||||||
" js_std_init_handlers(rt);\n"
|
" js_std_init_handlers(rt);\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -349,6 +350,7 @@ void help(void)
|
||||||
"-o output set the output filename\n"
|
"-o output set the output filename\n"
|
||||||
"-N cname set the C name of the generated data\n"
|
"-N cname set the C name of the generated data\n"
|
||||||
"-m compile as Javascript module (default=autodetect)\n"
|
"-m compile as Javascript module (default=autodetect)\n"
|
||||||
|
"-D module_name compile a dynamically loaded module or worker\n"
|
||||||
"-M module_name[,cname] add initialization code for an external C module\n"
|
"-M module_name[,cname] add initialization code for an external C module\n"
|
||||||
"-x byte swapped output\n"
|
"-x byte swapped output\n"
|
||||||
"-p prefix set the prefix of the generated C names\n"
|
"-p prefix set the prefix of the generated C names\n"
|
||||||
|
@ -494,6 +496,7 @@ int main(int argc, char **argv)
|
||||||
#ifdef CONFIG_BIGNUM
|
#ifdef CONFIG_BIGNUM
|
||||||
BOOL bignum_ext = FALSE;
|
BOOL bignum_ext = FALSE;
|
||||||
#endif
|
#endif
|
||||||
|
namelist_t dynamic_module_list;
|
||||||
|
|
||||||
out_filename = NULL;
|
out_filename = NULL;
|
||||||
output_type = OUTPUT_EXECUTABLE;
|
output_type = OUTPUT_EXECUTABLE;
|
||||||
|
@ -504,13 +507,14 @@ int main(int argc, char **argv)
|
||||||
verbose = 0;
|
verbose = 0;
|
||||||
use_lto = FALSE;
|
use_lto = FALSE;
|
||||||
stack_size = 0;
|
stack_size = 0;
|
||||||
|
memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
|
||||||
|
|
||||||
/* add system modules */
|
/* add system modules */
|
||||||
namelist_add(&cmodule_list, "std", "std", 0);
|
namelist_add(&cmodule_list, "std", "std", 0);
|
||||||
namelist_add(&cmodule_list, "os", "os", 0);
|
namelist_add(&cmodule_list, "os", "os", 0);
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = getopt(argc, argv, "ho:cN:f:mxevM:p:S:");
|
c = getopt(argc, argv, "ho:cN:f:mxevM:p:S:D:");
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
switch(c) {
|
switch(c) {
|
||||||
|
@ -576,6 +580,9 @@ int main(int argc, char **argv)
|
||||||
namelist_add(&cmodule_list, path, cname, 0);
|
namelist_add(&cmodule_list, path, cname, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
namelist_add(&dynamic_module_list, optarg, NULL, 0);
|
||||||
|
break;
|
||||||
case 'x':
|
case 'x':
|
||||||
byte_swap = TRUE;
|
byte_swap = TRUE;
|
||||||
break;
|
break;
|
||||||
|
@ -656,22 +663,22 @@ int main(int argc, char **argv)
|
||||||
cname = NULL;
|
cname = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(i = 0; i < dynamic_module_list.count; i++) {
|
||||||
|
if (!jsc_module_loader(ctx, dynamic_module_list.array[i].name, NULL)) {
|
||||||
|
fprintf(stderr, "Could not load dynamic module '%s'\n",
|
||||||
|
dynamic_module_list.array[i].name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (output_type != OUTPUT_C) {
|
if (output_type != OUTPUT_C) {
|
||||||
fputs(main_c_template1, fo);
|
fprintf(fo,
|
||||||
fprintf(fo, " ctx = JS_NewContextRaw(rt);\n");
|
"static JSContext *JS_NewCustomContext(JSRuntime *rt)\n"
|
||||||
|
"{\n"
|
||||||
if (stack_size != 0) {
|
" JSContext *ctx = JS_NewContextRaw(rt);\n"
|
||||||
fprintf(fo, " JS_SetMaxStackSize(rt, %u);\n",
|
" if (!ctx)\n"
|
||||||
(unsigned int)stack_size);
|
" return NULL;\n");
|
||||||
}
|
|
||||||
|
|
||||||
/* add the module loader if necessary */
|
|
||||||
if (feature_bitmap & (1 << FE_MODULE_LOADER)) {
|
|
||||||
fprintf(fo, " JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add the basic objects */
|
/* add the basic objects */
|
||||||
|
|
||||||
fprintf(fo, " JS_AddIntrinsicBaseObjects(ctx);\n");
|
fprintf(fo, " JS_AddIntrinsicBaseObjects(ctx);\n");
|
||||||
for(i = 0; i < countof(feature_list); i++) {
|
for(i = 0; i < countof(feature_list); i++) {
|
||||||
if ((feature_bitmap & ((uint64_t)1 << i)) &&
|
if ((feature_bitmap & ((uint64_t)1 << i)) &&
|
||||||
|
@ -689,8 +696,8 @@ int main(int argc, char **argv)
|
||||||
" JS_EnableBignumExt(ctx, 1);\n");
|
" JS_EnableBignumExt(ctx, 1);\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
fprintf(fo, " js_std_add_helpers(ctx, argc, argv);\n");
|
/* add the precompiled modules (XXX: could modify the module
|
||||||
|
loader instead) */
|
||||||
for(i = 0; i < init_module_list.count; i++) {
|
for(i = 0; i < init_module_list.count; i++) {
|
||||||
namelist_entry_t *e = &init_module_list.array[i];
|
namelist_entry_t *e = &init_module_list.array[i];
|
||||||
/* initialize the static C modules */
|
/* initialize the static C modules */
|
||||||
|
@ -702,12 +709,39 @@ int main(int argc, char **argv)
|
||||||
" }\n",
|
" }\n",
|
||||||
e->short_name, e->short_name, e->name);
|
e->short_name, e->short_name, e->name);
|
||||||
}
|
}
|
||||||
|
for(i = 0; i < cname_list.count; i++) {
|
||||||
|
namelist_entry_t *e = &cname_list.array[i];
|
||||||
|
if (e->flags) {
|
||||||
|
fprintf(fo, " js_std_eval_binary(ctx, %s, %s_size, 1);\n",
|
||||||
|
e->name, e->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(fo,
|
||||||
|
" return ctx;\n"
|
||||||
|
"}\n\n");
|
||||||
|
|
||||||
|
fputs(main_c_template1, fo);
|
||||||
|
|
||||||
|
if (stack_size != 0) {
|
||||||
|
fprintf(fo, " JS_SetMaxStackSize(rt, %u);\n",
|
||||||
|
(unsigned int)stack_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the module loader if necessary */
|
||||||
|
if (feature_bitmap & (1 << FE_MODULE_LOADER)) {
|
||||||
|
fprintf(fo, " JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fo,
|
||||||
|
" ctx = JS_NewCustomContext(rt);\n"
|
||||||
|
" js_std_add_helpers(ctx, argc, argv);\n");
|
||||||
|
|
||||||
for(i = 0; i < cname_list.count; i++) {
|
for(i = 0; i < cname_list.count; i++) {
|
||||||
namelist_entry_t *e = &cname_list.array[i];
|
namelist_entry_t *e = &cname_list.array[i];
|
||||||
fprintf(fo, " js_std_eval_binary(ctx, %s, %s_size, %s);\n",
|
if (!e->flags) {
|
||||||
e->name, e->name,
|
fprintf(fo, " js_std_eval_binary(ctx, %s, %s_size, 0);\n",
|
||||||
e->flags ? "1" : "0");
|
e->name, e->name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fputs(main_c_template2, fo);
|
fputs(main_c_template2, fo);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1826,7 +1826,7 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
|
||||||
j = emin + i;
|
j = emin + i;
|
||||||
if (j == -1) {
|
if (j == -1) {
|
||||||
if (a[i] != 0)
|
if (a[i] != 0)
|
||||||
throw RangError("cannot represent integ(1/X)");
|
throw RangeError("cannot represent integ(1/X)");
|
||||||
} else {
|
} else {
|
||||||
r[i] = a[i] / (j + 1);
|
r[i] = a[i] / (j + 1);
|
||||||
}
|
}
|
||||||
|
@ -1853,7 +1853,7 @@ var Integer, Float, Fraction, Complex, Mod, Polynomial, PolyMod, RationalFunctio
|
||||||
log() {
|
log() {
|
||||||
var a = this, r;
|
var a = this, r;
|
||||||
if (a.emin != 0)
|
if (a.emin != 0)
|
||||||
throw Range("log argument must have a non zero constant term");
|
throw RangeError("log argument must have a non zero constant term");
|
||||||
r = integ(deriv(a) / a);
|
r = integ(deriv(a) / a);
|
||||||
/* add the constant term */
|
/* add the constant term */
|
||||||
r += global.log(a[0]);
|
r += global.log(a[0]);
|
||||||
|
|
100
quickjs-libc.c
100
quickjs-libc.c
|
@ -2993,9 +2993,8 @@ typedef struct {
|
||||||
} JSWorkerData;
|
} JSWorkerData;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* source code of the worker */
|
char *filename; /* module filename */
|
||||||
char *eval_buf;
|
char *basename; /* module base name */
|
||||||
size_t eval_buf_len;
|
|
||||||
JSWorkerMessagePipe *recv_pipe, *send_pipe;
|
JSWorkerMessagePipe *recv_pipe, *send_pipe;
|
||||||
} WorkerFuncArgs;
|
} WorkerFuncArgs;
|
||||||
|
|
||||||
|
@ -3005,6 +3004,7 @@ typedef struct {
|
||||||
} JSSABHeader;
|
} JSSABHeader;
|
||||||
|
|
||||||
static JSClassID js_worker_class_id;
|
static JSClassID js_worker_class_id;
|
||||||
|
static JSContext *(*js_worker_new_context_func)(JSRuntime *rt);
|
||||||
|
|
||||||
static int atomic_add_int(int *ptr, int v)
|
static int atomic_add_int(int *ptr, int v)
|
||||||
{
|
{
|
||||||
|
@ -3136,7 +3136,6 @@ static void *worker_func(void *opaque)
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
JSThreadState *ts;
|
JSThreadState *ts;
|
||||||
JSContext *ctx;
|
JSContext *ctx;
|
||||||
JSValue retval;
|
|
||||||
|
|
||||||
rt = JS_NewRuntime();
|
rt = JS_NewRuntime();
|
||||||
if (rt == NULL) {
|
if (rt == NULL) {
|
||||||
|
@ -3145,12 +3144,16 @@ static void *worker_func(void *opaque)
|
||||||
}
|
}
|
||||||
js_std_init_handlers(rt);
|
js_std_init_handlers(rt);
|
||||||
|
|
||||||
|
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
||||||
|
|
||||||
/* set the pipe to communicate with the parent */
|
/* set the pipe to communicate with the parent */
|
||||||
ts = JS_GetRuntimeOpaque(rt);
|
ts = JS_GetRuntimeOpaque(rt);
|
||||||
ts->recv_pipe = args->recv_pipe;
|
ts->recv_pipe = args->recv_pipe;
|
||||||
ts->send_pipe = args->send_pipe;
|
ts->send_pipe = args->send_pipe;
|
||||||
|
|
||||||
ctx = JS_NewContext(rt);
|
/* function pointer to avoid linking the whole JS_NewContext() if
|
||||||
|
not needed */
|
||||||
|
ctx = js_worker_new_context_func(rt);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
fprintf(stderr, "JS_NewContext failure");
|
fprintf(stderr, "JS_NewContext failure");
|
||||||
}
|
}
|
||||||
|
@ -3159,18 +3162,11 @@ static void *worker_func(void *opaque)
|
||||||
|
|
||||||
js_std_add_helpers(ctx, -1, NULL);
|
js_std_add_helpers(ctx, -1, NULL);
|
||||||
|
|
||||||
/* system modules */
|
if (!JS_RunModule(ctx, args->basename, args->filename))
|
||||||
js_init_module_std(ctx, "std");
|
|
||||||
js_init_module_os(ctx, "os");
|
|
||||||
|
|
||||||
retval = JS_Eval(ctx, args->eval_buf, args->eval_buf_len,
|
|
||||||
"<worker>", JS_EVAL_TYPE_MODULE);
|
|
||||||
free(args->eval_buf);
|
|
||||||
free(args);
|
|
||||||
|
|
||||||
if (JS_IsException(retval))
|
|
||||||
js_std_dump_error(ctx);
|
js_std_dump_error(ctx);
|
||||||
JS_FreeValue(ctx, retval);
|
free(args->filename);
|
||||||
|
free(args->basename);
|
||||||
|
free(args);
|
||||||
|
|
||||||
js_std_loop(ctx);
|
js_std_loop(ctx);
|
||||||
|
|
||||||
|
@ -3216,52 +3212,53 @@ static JSValue js_worker_ctor(JSContext *ctx, JSValueConst new_target,
|
||||||
int argc, JSValueConst *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
JSRuntime *rt = JS_GetRuntime(ctx);
|
JSRuntime *rt = JS_GetRuntime(ctx);
|
||||||
WorkerFuncArgs *args;
|
WorkerFuncArgs *args = NULL;
|
||||||
const char *str;
|
|
||||||
size_t str_len;
|
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
pthread_attr_t attr;
|
pthread_attr_t attr;
|
||||||
JSValue obj = JS_UNDEFINED;
|
JSValue obj = JS_UNDEFINED;
|
||||||
int ret;
|
int ret;
|
||||||
|
const char *filename = NULL, *basename;
|
||||||
|
JSAtom basename_atom;
|
||||||
|
|
||||||
/* XXX: in order to avoid problems with resource liberation, we
|
/* XXX: in order to avoid problems with resource liberation, we
|
||||||
don't support creating workers inside workers */
|
don't support creating workers inside workers */
|
||||||
if (!is_main_thread(rt))
|
if (!is_main_thread(rt))
|
||||||
return JS_ThrowTypeError(ctx, "cannot create a worker inside a worker");
|
return JS_ThrowTypeError(ctx, "cannot create a worker inside a worker");
|
||||||
|
|
||||||
|
/* base name, assuming the calling function is a normal JS
|
||||||
|
function */
|
||||||
|
basename_atom = JS_GetScriptOrModuleName(ctx, 1);
|
||||||
|
if (basename_atom == JS_ATOM_NULL) {
|
||||||
|
return JS_ThrowTypeError(ctx, "could not determine calling script or module name");
|
||||||
|
}
|
||||||
|
basename = JS_AtomToCString(ctx, basename_atom);
|
||||||
|
JS_FreeAtom(ctx, basename_atom);
|
||||||
|
if (!basename)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
/* script source */
|
/* module name */
|
||||||
|
filename = JS_ToCString(ctx, argv[0]);
|
||||||
str = JS_ToCStringLen(ctx, &str_len, argv[0]);
|
if (!filename)
|
||||||
if (!str)
|
goto fail;
|
||||||
return JS_EXCEPTION;
|
|
||||||
|
|
||||||
args = malloc(sizeof(*args));
|
args = malloc(sizeof(*args));
|
||||||
if (!args) {
|
if (!args)
|
||||||
JS_ThrowOutOfMemory(ctx);
|
goto oom_fail;
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
memset(args, 0, sizeof(*args));
|
memset(args, 0, sizeof(*args));
|
||||||
args->eval_buf = malloc(str_len + 1);
|
args->filename = strdup(filename);
|
||||||
if (!args->eval_buf) {
|
args->basename = strdup(basename);
|
||||||
JS_ThrowOutOfMemory(ctx);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
memcpy(args->eval_buf, str, str_len + 1);
|
|
||||||
args->eval_buf_len = str_len;
|
|
||||||
JS_FreeCString(ctx, str);
|
|
||||||
str = NULL;
|
|
||||||
|
|
||||||
/* ports */
|
/* ports */
|
||||||
args->recv_pipe = js_new_message_pipe();
|
args->recv_pipe = js_new_message_pipe();
|
||||||
if (!args->recv_pipe)
|
if (!args->recv_pipe)
|
||||||
goto fail;
|
goto oom_fail;
|
||||||
args->send_pipe = js_new_message_pipe();
|
args->send_pipe = js_new_message_pipe();
|
||||||
if (!args->send_pipe)
|
if (!args->send_pipe)
|
||||||
goto fail;
|
goto oom_fail;
|
||||||
|
|
||||||
obj = js_worker_ctor_internal(ctx, new_target,
|
obj = js_worker_ctor_internal(ctx, new_target,
|
||||||
args->send_pipe, args->recv_pipe);
|
args->send_pipe, args->recv_pipe);
|
||||||
if (JS_IsUndefined(obj))
|
if (JS_IsException(obj))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
pthread_attr_init(&attr);
|
pthread_attr_init(&attr);
|
||||||
|
@ -3273,11 +3270,17 @@ static JSValue js_worker_ctor(JSContext *ctx, JSValueConst new_target,
|
||||||
JS_ThrowTypeError(ctx, "could not create worker");
|
JS_ThrowTypeError(ctx, "could not create worker");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
JS_FreeCString(ctx, basename);
|
||||||
|
JS_FreeCString(ctx, filename);
|
||||||
return obj;
|
return obj;
|
||||||
|
oom_fail:
|
||||||
|
JS_ThrowOutOfMemory(ctx);
|
||||||
fail:
|
fail:
|
||||||
JS_FreeCString(ctx, str);
|
JS_FreeCString(ctx, basename);
|
||||||
|
JS_FreeCString(ctx, filename);
|
||||||
if (args) {
|
if (args) {
|
||||||
free(args->eval_buf);
|
free(args->filename);
|
||||||
|
free(args->basename);
|
||||||
js_free_message_pipe(args->recv_pipe);
|
js_free_message_pipe(args->recv_pipe);
|
||||||
js_free_message_pipe(args->send_pipe);
|
js_free_message_pipe(args->send_pipe);
|
||||||
free(args);
|
free(args);
|
||||||
|
@ -3417,6 +3420,13 @@ static const JSCFunctionListEntry js_worker_proto_funcs[] = {
|
||||||
|
|
||||||
#endif /* USE_WORKER */
|
#endif /* USE_WORKER */
|
||||||
|
|
||||||
|
void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt))
|
||||||
|
{
|
||||||
|
#ifdef USE_WORKER
|
||||||
|
js_worker_new_context_func = func;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define OS_PLATFORM "win32"
|
#define OS_PLATFORM "win32"
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
|
@ -3668,6 +3678,12 @@ void js_std_free_handlers(JSRuntime *rt)
|
||||||
free_timer(rt, th);
|
free_timer(rt, th);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_WORKER
|
||||||
|
/* XXX: free port_list ? */
|
||||||
|
js_free_message_pipe(ts->recv_pipe);
|
||||||
|
js_free_message_pipe(ts->send_pipe);
|
||||||
|
#endif
|
||||||
|
|
||||||
free(ts);
|
free(ts);
|
||||||
JS_SetRuntimeOpaque(rt, NULL); /* fail safe */
|
JS_SetRuntimeOpaque(rt, NULL); /* fail safe */
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,8 @@ void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
|
||||||
void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
|
void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
|
||||||
JSValueConst reason,
|
JSValueConst reason,
|
||||||
JS_BOOL is_handled, void *opaque);
|
JS_BOOL is_handled, void *opaque);
|
||||||
|
void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt));
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* extern "C" { */
|
} /* extern "C" { */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -359,7 +359,8 @@ DEF( call3, 1, 1, 1, npopx)
|
||||||
|
|
||||||
DEF( is_undefined, 1, 1, 1, none)
|
DEF( is_undefined, 1, 1, 1, none)
|
||||||
DEF( is_null, 1, 1, 1, none)
|
DEF( is_null, 1, 1, 1, none)
|
||||||
DEF( is_function, 1, 1, 1, none)
|
DEF(typeof_is_undefined, 1, 1, 1, none)
|
||||||
|
DEF( typeof_is_function, 1, 1, 1, none)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef DEF
|
#undef DEF
|
||||||
|
|
10
quickjs.h
10
quickjs.h
|
@ -412,6 +412,8 @@ void JS_ComputeMemoryUsage(JSRuntime *rt, JSMemoryUsage *s);
|
||||||
void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
|
void JS_DumpMemoryUsage(FILE *fp, const JSMemoryUsage *s, JSRuntime *rt);
|
||||||
|
|
||||||
/* atom support */
|
/* atom support */
|
||||||
|
#define JS_ATOM_NULL 0
|
||||||
|
|
||||||
JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);
|
JSAtom JS_NewAtomLen(JSContext *ctx, const char *str, size_t len);
|
||||||
JSAtom JS_NewAtom(JSContext *ctx, const char *str);
|
JSAtom JS_NewAtom(JSContext *ctx, const char *str);
|
||||||
JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);
|
JSAtom JS_NewAtomUInt32(JSContext *ctx, uint32_t n);
|
||||||
|
@ -835,6 +837,8 @@ typedef int JSInterruptHandler(JSRuntime *rt, void *opaque);
|
||||||
void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
|
void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, void *opaque);
|
||||||
/* if can_block is TRUE, Atomics.wait() can be used */
|
/* if can_block is TRUE, Atomics.wait() can be used */
|
||||||
void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
|
void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
|
||||||
|
/* set the [IsHTMLDDA] internal slot */
|
||||||
|
void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj);
|
||||||
|
|
||||||
typedef struct JSModuleDef JSModuleDef;
|
typedef struct JSModuleDef JSModuleDef;
|
||||||
|
|
||||||
|
@ -886,6 +890,12 @@ JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len,
|
||||||
returns a module. */
|
returns a module. */
|
||||||
int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
|
int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
|
||||||
|
|
||||||
|
/* only exported for os.Worker() */
|
||||||
|
JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
|
||||||
|
/* only exported for os.Worker() */
|
||||||
|
JSModuleDef *JS_RunModule(JSContext *ctx, const char *basename,
|
||||||
|
const char *filename);
|
||||||
|
|
||||||
/* C function definition */
|
/* C function definition */
|
||||||
typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
|
typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
|
||||||
JS_CFUNC_generic,
|
JS_CFUNC_generic,
|
||||||
|
|
|
@ -743,10 +743,16 @@ static JSValue js_createRealm(JSContext *ctx, JSValue this_val,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static JSValue js_IsHTMLDDA(JSContext *ctx, JSValue this_val,
|
||||||
|
int argc, JSValue *argv)
|
||||||
|
{
|
||||||
|
return JS_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static JSValue add_helpers1(JSContext *ctx)
|
static JSValue add_helpers1(JSContext *ctx)
|
||||||
{
|
{
|
||||||
JSValue global_obj;
|
JSValue global_obj;
|
||||||
JSValue obj262;
|
JSValue obj262, obj;
|
||||||
|
|
||||||
global_obj = JS_GetGlobalObject(ctx);
|
global_obj = JS_GetGlobalObject(ctx);
|
||||||
|
|
||||||
|
@ -773,6 +779,9 @@ static JSValue add_helpers1(JSContext *ctx)
|
||||||
JS_SetPropertyStr(ctx, obj262, "createRealm",
|
JS_SetPropertyStr(ctx, obj262, "createRealm",
|
||||||
JS_NewCFunction(ctx, js_createRealm,
|
JS_NewCFunction(ctx, js_createRealm,
|
||||||
"createRealm", 0));
|
"createRealm", 0));
|
||||||
|
obj = JS_NewCFunction(ctx, js_IsHTMLDDA, "IsHTMLDDA", 0);
|
||||||
|
JS_SetIsHTMLDDA(ctx, obj);
|
||||||
|
JS_SetPropertyStr(ctx, obj262, "IsHTMLDDA", obj);
|
||||||
|
|
||||||
JS_SetPropertyStr(ctx, global_obj, "$262", JS_DupValue(ctx, obj262));
|
JS_SetPropertyStr(ctx, global_obj, "$262", JS_DupValue(ctx, obj262));
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,7 @@ class-methods-private
|
||||||
class-static-fields-public
|
class-static-fields-public
|
||||||
class-static-fields-private
|
class-static-fields-private
|
||||||
class-static-methods-private
|
class-static-methods-private
|
||||||
|
cleanupSome=skip
|
||||||
coalesce-expression
|
coalesce-expression
|
||||||
computed-property-names
|
computed-property-names
|
||||||
const
|
const
|
||||||
|
@ -100,10 +101,10 @@ host-gc-required=skip
|
||||||
import.meta
|
import.meta
|
||||||
Int32Array
|
Int32Array
|
||||||
Int8Array
|
Int8Array
|
||||||
IsHTMLDDA=skip
|
IsHTMLDDA
|
||||||
json-superset
|
json-superset
|
||||||
let
|
let
|
||||||
logical-assignment-operators=skip
|
logical-assignment-operators
|
||||||
Map
|
Map
|
||||||
new.target
|
new.target
|
||||||
numeric-separator-literal
|
numeric-separator-literal
|
||||||
|
|
|
@ -277,6 +277,8 @@ function test_string()
|
||||||
assert("aaaa".split("aaaaa", 1), [ "aaaa" ]);
|
assert("aaaa".split("aaaaa", 1), [ "aaaa" ]);
|
||||||
|
|
||||||
assert(eval('"\0"'), "\0");
|
assert(eval('"\0"'), "\0");
|
||||||
|
|
||||||
|
assert("abc".padStart(Infinity, ""), "abc");
|
||||||
}
|
}
|
||||||
|
|
||||||
function test_math()
|
function test_math()
|
||||||
|
|
|
@ -359,6 +359,23 @@ function test_labels()
|
||||||
while (0) x: { break x; };
|
while (0) x: { break x; };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function test_destructuring()
|
||||||
|
{
|
||||||
|
function * g () { return 0; };
|
||||||
|
var [x] = g();
|
||||||
|
assert(x, void 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_spread()
|
||||||
|
{
|
||||||
|
var x;
|
||||||
|
x = [1, 2, ...[3, 4]];
|
||||||
|
assert(x.toString(), "1,2,3,4");
|
||||||
|
|
||||||
|
x = [ ...[ , ] ];
|
||||||
|
assert(Object.getOwnPropertyNames(x).toString(), "0,length");
|
||||||
|
}
|
||||||
|
|
||||||
test_op1();
|
test_op1();
|
||||||
test_cvt();
|
test_cvt();
|
||||||
test_eq();
|
test_eq();
|
||||||
|
@ -373,3 +390,5 @@ test_template_skip();
|
||||||
test_object_literal();
|
test_object_literal();
|
||||||
test_regexp_skip();
|
test_regexp_skip();
|
||||||
test_labels();
|
test_labels();
|
||||||
|
test_destructuring();
|
||||||
|
test_spread();
|
||||||
|
|
|
@ -25,38 +25,7 @@ function test_worker()
|
||||||
{
|
{
|
||||||
var counter;
|
var counter;
|
||||||
|
|
||||||
/* Note: can use std.loadFile() to read from a file */
|
worker = new os.Worker("./test_worker_module.js");
|
||||||
worker = new os.Worker(`
|
|
||||||
import * as std from "std";
|
|
||||||
import * as os from "os";
|
|
||||||
|
|
||||||
var parent = os.Worker.parent;
|
|
||||||
|
|
||||||
function handle_msg(e) {
|
|
||||||
var ev = e.data;
|
|
||||||
// print("child_recv", JSON.stringify(ev));
|
|
||||||
switch(ev.type) {
|
|
||||||
case "abort":
|
|
||||||
parent.postMessage({ type: "done" });
|
|
||||||
break;
|
|
||||||
case "sab":
|
|
||||||
/* modify the SharedArrayBuffer */
|
|
||||||
ev.buf[2] = 10;
|
|
||||||
parent.postMessage({ type: "sab_done", buf: ev.buf });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function worker_main() {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
parent.onmessage = handle_msg;
|
|
||||||
for(i = 0; i < 10; i++) {
|
|
||||||
parent.postMessage({ type: "num", num: i });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
worker_main();
|
|
||||||
`);
|
|
||||||
|
|
||||||
counter = 0;
|
counter = 0;
|
||||||
worker.onmessage = function (e) {
|
worker.onmessage = function (e) {
|
||||||
|
|
31
tests/test_worker_module.js
Normal file
31
tests/test_worker_module.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* Worker code for test_worker.js */
|
||||||
|
import * as std from "std";
|
||||||
|
import * as os from "os";
|
||||||
|
|
||||||
|
var parent = os.Worker.parent;
|
||||||
|
|
||||||
|
function handle_msg(e) {
|
||||||
|
var ev = e.data;
|
||||||
|
// print("child_recv", JSON.stringify(ev));
|
||||||
|
switch(ev.type) {
|
||||||
|
case "abort":
|
||||||
|
parent.postMessage({ type: "done" });
|
||||||
|
break;
|
||||||
|
case "sab":
|
||||||
|
/* modify the SharedArrayBuffer */
|
||||||
|
ev.buf[2] = 10;
|
||||||
|
parent.postMessage({ type: "sab_done", buf: ev.buf });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function worker_main() {
|
||||||
|
var i;
|
||||||
|
|
||||||
|
parent.onmessage = handle_msg;
|
||||||
|
for(i = 0; i < 10; i++) {
|
||||||
|
parent.postMessage({ type: "num", num: i });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
worker_main();
|
Loading…
Reference in a new issue