mirror of
				https://github.com/bellard/quickjs.git
				synced 2025-05-29 01:49:18 +08:00 
			
		
		
		
	2020-09-06 release
This commit is contained in:
		
							parent
							
								
									8900766099
								
							
						
					
					
						commit
						7c312df422
					
				| @ -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 | ||||||
|  | |||||||
							
								
								
									
										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]); | ||||||
|  | |||||||
| @ -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"); | ||||||
| 
 | 
 | ||||||
|     /* script source */ |     /* 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; | ||||||
|      |      | ||||||
|     str = JS_ToCStringLen(ctx, &str_len, argv[0]); |     /* module name */ | ||||||
|     if (!str) |     filename = JS_ToCString(ctx, argv[0]); | ||||||
|         return JS_EXCEPTION; |     if (!filename) | ||||||
|  |         goto fail; | ||||||
| 
 | 
 | ||||||
|     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,6 +50,7 @@ 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" { */ | ||||||
|  | |||||||
| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user