mirror of
				https://github.com/bellard/quickjs.git
				synced 2025-05-29 01:49:18 +08:00 
			
		
		
		
	fixed exception handling in AsyncFromSyncIterator and async for of
This commit is contained in:
		
							parent
							
								
									67de495254
								
							
						
					
					
						commit
						56c47f7d2a
					
				| @ -207,8 +207,9 @@ DEF(   for_of_start, 1, 1, 3, none) | |||||||
| DEF(for_await_of_start, 1, 1, 3, none) | DEF(for_await_of_start, 1, 1, 3, none) | ||||||
| DEF(    for_in_next, 1, 1, 3, none) | DEF(    for_in_next, 1, 1, 3, none) | ||||||
| DEF(    for_of_next, 2, 3, 5, u8) | DEF(    for_of_next, 2, 3, 5, u8) | ||||||
|  | DEF(for_await_of_next, 1, 3, 4, none) /* iter next catch_offset -> iter next catch_offset obj */ | ||||||
| DEF(iterator_check_object, 1, 1, 1, none) | DEF(iterator_check_object, 1, 1, 1, none) | ||||||
| DEF(iterator_get_value_done, 1, 1, 2, none) | DEF(iterator_get_value_done, 1, 2, 3, none) /* catch_offset obj -> catch_offset value done */ | ||||||
| DEF( iterator_close, 1, 3, 0, none) | DEF( iterator_close, 1, 3, 0, none) | ||||||
| DEF(  iterator_next, 1, 4, 4, none) | DEF(  iterator_next, 1, 4, 4, none) | ||||||
| DEF(  iterator_call, 2, 4, 5, u8) | DEF(  iterator_call, 2, 4, 5, u8) | ||||||
|  | |||||||
							
								
								
									
										140
									
								
								quickjs.c
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								quickjs.c
									
									
									
									
									
								
							| @ -15227,6 +15227,21 @@ static __exception int js_for_of_next(JSContext *ctx, JSValue *sp, int offset) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static __exception int js_for_await_of_next(JSContext *ctx, JSValue *sp) | ||||||
|  | { | ||||||
|  |     JSValue obj, iter, next; | ||||||
|  | 
 | ||||||
|  |     sp[-1] = JS_UNDEFINED; /* disable the catch offset so that
 | ||||||
|  |                               exceptions do not close the iterator */ | ||||||
|  |     iter = sp[-3]; | ||||||
|  |     next = sp[-2]; | ||||||
|  |     obj = JS_Call(ctx, next, iter, 0, NULL); | ||||||
|  |     if (JS_IsException(obj)) | ||||||
|  |         return -1; | ||||||
|  |     sp[0] = obj; | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static JSValue JS_IteratorGetCompleteValue(JSContext *ctx, JSValueConst obj, | static JSValue JS_IteratorGetCompleteValue(JSContext *ctx, JSValueConst obj, | ||||||
|                                            BOOL *pdone) |                                            BOOL *pdone) | ||||||
| { | { | ||||||
| @ -15259,6 +15274,9 @@ static __exception int js_iterator_get_value_done(JSContext *ctx, JSValue *sp) | |||||||
|     if (JS_IsException(value)) |     if (JS_IsException(value)) | ||||||
|         return -1; |         return -1; | ||||||
|     JS_FreeValue(ctx, obj); |     JS_FreeValue(ctx, obj); | ||||||
|  |     /* put again the catch offset so that exceptions close the
 | ||||||
|  |        iterator */ | ||||||
|  |     sp[-2] = JS_NewCatchOffset(ctx, 0);  | ||||||
|     sp[-1] = value; |     sp[-1] = value; | ||||||
|     sp[0] = JS_NewBool(ctx, done); |     sp[0] = JS_NewBool(ctx, done); | ||||||
|     return 0; |     return 0; | ||||||
| @ -17214,6 +17232,11 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, | |||||||
|                 sp += 2; |                 sp += 2; | ||||||
|             } |             } | ||||||
|             BREAK; |             BREAK; | ||||||
|  |         CASE(OP_for_await_of_next): | ||||||
|  |             if (js_for_await_of_next(ctx, sp)) | ||||||
|  |                 goto exception; | ||||||
|  |             sp++; | ||||||
|  |             BREAK; | ||||||
|         CASE(OP_for_await_of_start): |         CASE(OP_for_await_of_start): | ||||||
|             if (js_for_of_start(ctx, sp, TRUE)) |             if (js_for_of_start(ctx, sp, TRUE)) | ||||||
|                 goto exception; |                 goto exception; | ||||||
| @ -26138,12 +26161,9 @@ static __exception int js_parse_for_in_of(JSParseState *s, int label_name, | |||||||
|     emit_label(s, label_cont); |     emit_label(s, label_cont); | ||||||
|     if (is_for_of) { |     if (is_for_of) { | ||||||
|         if (is_async) { |         if (is_async) { | ||||||
|             /* call the next method */ |  | ||||||
|             /* stack: iter_obj next catch_offset */ |             /* stack: iter_obj next catch_offset */ | ||||||
|             emit_op(s, OP_dup3); |             /* call the next method */ | ||||||
|             emit_op(s, OP_drop); |             emit_op(s, OP_for_await_of_next);  | ||||||
|             emit_op(s, OP_call_method); |  | ||||||
|             emit_u16(s, 0); |  | ||||||
|             /* get the result of the promise */ |             /* get the result of the promise */ | ||||||
|             emit_op(s, OP_await); |             emit_op(s, OP_await); | ||||||
|             /* unwrap the value and done values */ |             /* unwrap the value and done values */ | ||||||
| @ -48426,25 +48446,6 @@ static const JSCFunctionListEntry js_async_function_proto_funcs[] = { | |||||||
|     JS_PROP_STRING_DEF("[Symbol.toStringTag]", "AsyncFunction", JS_PROP_CONFIGURABLE ), |     JS_PROP_STRING_DEF("[Symbol.toStringTag]", "AsyncFunction", JS_PROP_CONFIGURABLE ), | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| static JSValue js_async_from_sync_iterator_unwrap(JSContext *ctx, |  | ||||||
|                                                   JSValueConst this_val, |  | ||||||
|                                                   int argc, JSValueConst *argv, |  | ||||||
|                                                   int magic, JSValue *func_data) |  | ||||||
| { |  | ||||||
|     return js_create_iterator_result(ctx, JS_DupValue(ctx, argv[0]), |  | ||||||
|                                      JS_ToBool(ctx, func_data[0])); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static JSValue js_async_from_sync_iterator_unwrap_func_create(JSContext *ctx, |  | ||||||
|                                                               BOOL done) |  | ||||||
| { |  | ||||||
|     JSValueConst func_data[1]; |  | ||||||
| 
 |  | ||||||
|     func_data[0] = (JSValueConst)JS_NewBool(ctx, done); |  | ||||||
|     return JS_NewCFunctionData(ctx, js_async_from_sync_iterator_unwrap, |  | ||||||
|                                1, 0, 1, func_data); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| /* AsyncIteratorPrototype */ | /* AsyncIteratorPrototype */ | ||||||
| 
 | 
 | ||||||
| static const JSCFunctionListEntry js_async_iterator_proto_funcs[] = { | static const JSCFunctionListEntry js_async_iterator_proto_funcs[] = { | ||||||
| @ -48506,6 +48507,41 @@ static JSValue JS_CreateAsyncFromSyncIterator(JSContext *ctx, | |||||||
|     return async_iter; |     return async_iter; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | static JSValue js_async_from_sync_iterator_unwrap(JSContext *ctx, | ||||||
|  |                                                   JSValueConst this_val, | ||||||
|  |                                                   int argc, JSValueConst *argv, | ||||||
|  |                                                   int magic, JSValue *func_data) | ||||||
|  | { | ||||||
|  |     return js_create_iterator_result(ctx, JS_DupValue(ctx, argv[0]), | ||||||
|  |                                      JS_ToBool(ctx, func_data[0])); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static JSValue js_async_from_sync_iterator_unwrap_func_create(JSContext *ctx, | ||||||
|  |                                                               BOOL done) | ||||||
|  | { | ||||||
|  |     JSValueConst func_data[1]; | ||||||
|  | 
 | ||||||
|  |     func_data[0] = (JSValueConst)JS_NewBool(ctx, done); | ||||||
|  |     return JS_NewCFunctionData(ctx, js_async_from_sync_iterator_unwrap, | ||||||
|  |                                1, 0, 1, func_data); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static JSValue js_async_from_sync_iterator_close_wrap(JSContext *ctx, | ||||||
|  |                                                       JSValueConst this_val, | ||||||
|  |                                                       int argc, JSValueConst *argv, | ||||||
|  |                                                       int magic, JSValue *func_data) | ||||||
|  | { | ||||||
|  |     JS_Throw(ctx, JS_DupValue(ctx, argv[0])); | ||||||
|  |     JS_IteratorClose(ctx, func_data[0], TRUE); | ||||||
|  |     return JS_EXCEPTION; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static JSValue js_async_from_sync_iterator_close_wrap_func_create(JSContext *ctx, JSValueConst sync_iter) | ||||||
|  | { | ||||||
|  |     return JS_NewCFunctionData(ctx, js_async_from_sync_iterator_close_wrap, | ||||||
|  |                                1, 0, 1, &sync_iter); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst this_val, | static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst this_val, | ||||||
|                                                 int argc, JSValueConst *argv, |                                                 int argc, JSValueConst *argv, | ||||||
|                                                 int magic) |                                                 int magic) | ||||||
| @ -48536,11 +48572,13 @@ static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst thi | |||||||
|             if (magic == GEN_MAGIC_RETURN) { |             if (magic == GEN_MAGIC_RETURN) { | ||||||
|                 err = js_create_iterator_result(ctx, JS_DupValue(ctx, argv[0]), TRUE); |                 err = js_create_iterator_result(ctx, JS_DupValue(ctx, argv[0]), TRUE); | ||||||
|                 is_reject = 0; |                 is_reject = 0; | ||||||
|  |                 goto done_resolve; | ||||||
|             } else { |             } else { | ||||||
|                 err = JS_DupValue(ctx, argv[0]); |                 if (JS_IteratorClose(ctx, s->sync_iter, FALSE)) | ||||||
|                 is_reject = 1; |                     goto reject; | ||||||
|  |                 JS_ThrowTypeError(ctx, "throw is not a method"); | ||||||
|  |                 goto reject; | ||||||
|             } |             } | ||||||
|             goto done_resolve; |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     value = JS_IteratorNext2(ctx, s->sync_iter, method, |     value = JS_IteratorNext2(ctx, s->sync_iter, method, | ||||||
| @ -48555,21 +48593,9 @@ static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst thi | |||||||
|         if (JS_IsException(value)) |         if (JS_IsException(value)) | ||||||
|             goto reject; |             goto reject; | ||||||
|     } |     } | ||||||
| 
 |      | ||||||
|     if (JS_IsException(value)) { |     if (JS_IsException(value)) | ||||||
|         JSValue res2; |         goto reject; | ||||||
|     reject: |  | ||||||
|         err = JS_GetException(ctx); |  | ||||||
|         is_reject = 1; |  | ||||||
|     done_resolve: |  | ||||||
|         res2 = JS_Call(ctx, resolving_funcs[is_reject], JS_UNDEFINED, |  | ||||||
|                        1, (JSValueConst *)&err); |  | ||||||
|         JS_FreeValue(ctx, err); |  | ||||||
|         JS_FreeValue(ctx, res2); |  | ||||||
|         JS_FreeValue(ctx, resolving_funcs[0]); |  | ||||||
|         JS_FreeValue(ctx, resolving_funcs[1]); |  | ||||||
|         return promise; |  | ||||||
|     } |  | ||||||
|     { |     { | ||||||
|         JSValue value_wrapper_promise, resolve_reject[2]; |         JSValue value_wrapper_promise, resolve_reject[2]; | ||||||
|         int res; |         int res; | ||||||
| @ -48577,8 +48603,22 @@ static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst thi | |||||||
|         value_wrapper_promise = js_promise_resolve(ctx, ctx->promise_ctor, |         value_wrapper_promise = js_promise_resolve(ctx, ctx->promise_ctor, | ||||||
|                                                    1, (JSValueConst *)&value, 0); |                                                    1, (JSValueConst *)&value, 0); | ||||||
|         if (JS_IsException(value_wrapper_promise)) { |         if (JS_IsException(value_wrapper_promise)) { | ||||||
|  |             JSValue res2; | ||||||
|             JS_FreeValue(ctx, value); |             JS_FreeValue(ctx, value); | ||||||
|             goto reject; |             if (magic != GEN_MAGIC_RETURN && !done) { | ||||||
|  |                 JS_IteratorClose(ctx, s->sync_iter, TRUE); | ||||||
|  |             } | ||||||
|  |         reject: | ||||||
|  |             err = JS_GetException(ctx); | ||||||
|  |             is_reject = 1; | ||||||
|  |         done_resolve: | ||||||
|  |             res2 = JS_Call(ctx, resolving_funcs[is_reject], JS_UNDEFINED, | ||||||
|  |                            1, (JSValueConst *)&err); | ||||||
|  |             JS_FreeValue(ctx, err); | ||||||
|  |             JS_FreeValue(ctx, res2); | ||||||
|  |             JS_FreeValue(ctx, resolving_funcs[0]); | ||||||
|  |             JS_FreeValue(ctx, resolving_funcs[1]); | ||||||
|  |             return promise; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         resolve_reject[0] = |         resolve_reject[0] = | ||||||
| @ -48587,13 +48627,23 @@ static JSValue js_async_from_sync_iterator_next(JSContext *ctx, JSValueConst thi | |||||||
|             JS_FreeValue(ctx, value_wrapper_promise); |             JS_FreeValue(ctx, value_wrapper_promise); | ||||||
|             goto fail; |             goto fail; | ||||||
|         } |         } | ||||||
|  |         if (done || magic == GEN_MAGIC_RETURN) { | ||||||
|  |             resolve_reject[1] = JS_UNDEFINED; | ||||||
|  |         } else { | ||||||
|  |             resolve_reject[1] = | ||||||
|  |                 js_async_from_sync_iterator_close_wrap_func_create(ctx, s->sync_iter); | ||||||
|  |             if (JS_IsException(resolve_reject[1])) { | ||||||
|  |                 JS_FreeValue(ctx, value_wrapper_promise); | ||||||
|  |                 JS_FreeValue(ctx, resolve_reject[0]); | ||||||
|  |                 goto fail; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|         JS_FreeValue(ctx, value); |         JS_FreeValue(ctx, value); | ||||||
|         resolve_reject[1] = JS_UNDEFINED; |  | ||||||
| 
 |  | ||||||
|         res = perform_promise_then(ctx, value_wrapper_promise, |         res = perform_promise_then(ctx, value_wrapper_promise, | ||||||
|                                    (JSValueConst *)resolve_reject, |                                    (JSValueConst *)resolve_reject, | ||||||
|                                    (JSValueConst *)resolving_funcs); |                                    (JSValueConst *)resolving_funcs); | ||||||
|         JS_FreeValue(ctx, resolve_reject[0]); |         JS_FreeValue(ctx, resolve_reject[0]); | ||||||
|  |         JS_FreeValue(ctx, resolve_reject[1]); | ||||||
|         JS_FreeValue(ctx, value_wrapper_promise); |         JS_FreeValue(ctx, value_wrapper_promise); | ||||||
|         JS_FreeValue(ctx, resolving_funcs[0]); |         JS_FreeValue(ctx, resolving_funcs[0]); | ||||||
|         JS_FreeValue(ctx, resolving_funcs[1]); |         JS_FreeValue(ctx, resolving_funcs[1]); | ||||||
|  | |||||||
| @ -1,30 +1,6 @@ | |||||||
| test262/test/annexB/language/comments/single-line-html-close-first-line-1.js:1: unexpected error type: SyntaxError: unexpected token in expression: '>' | test262/test/annexB/language/comments/single-line-html-close-first-line-1.js:1: unexpected error type: SyntaxError: unexpected token in expression: '>' | ||||||
| test262/test/annexB/language/comments/single-line-html-close-first-line-2.js:1: unexpected error type: SyntaxError: unexpected token in expression: '>' | test262/test/annexB/language/comments/single-line-html-close-first-line-2.js:1: unexpected error type: SyntaxError: unexpected token in expression: '>' | ||||||
| test262/test/annexB/language/comments/single-line-html-close-first-line-3.js:1: unexpected error type: SyntaxError: unexpected token in expression: '>' | test262/test/annexB/language/comments/single-line-html-close-first-line-3.js:1: unexpected error type: SyntaxError: unexpected token in expression: '>' | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/iterator-result-poisoned-wrapper.js:64: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/iterator-result-poisoned-wrapper.js:64: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/next-result-poisoned-wrapper.js:69: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/next-result-poisoned-wrapper.js:69: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-iterator-next-rejected-promise-close.js:59: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-iterator-next-rejected-promise-close.js:59: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-next-rejected-promise-close.js:64: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-next-rejected-promise-close.js:64: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/iterator-result-rejected-promise-close.js:74: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/iterator-result-rejected-promise-close.js:74: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-null.js:52: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-null.js:52: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-result-poisoned-wrapper.js:81: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-result-poisoned-wrapper.js:81: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-get-return-undefined.js:64: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-get-return-undefined.js:64: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-poisoned-return.js:68: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-poisoned-return.js:68: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-not-object.js:72: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-not-object.js:72: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-object.js:66: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-object.js:66: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined.js:41: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined.js:41: strict mode: TypeError: $DONE() not called |  | ||||||
| test262/test/built-ins/Function/prototype/arguments/prop-desc.js:31: Test262Error: Function.prototype.arguments property getter/setter are the same function Expected SameValue(«function () { | test262/test/built-ins/Function/prototype/arguments/prop-desc.js:31: Test262Error: Function.prototype.arguments property getter/setter are the same function Expected SameValue(«function () { | ||||||
|     [native code] |     [native code] | ||||||
| }», «function () { | }», «function () { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user