| 1906 | } |
| 1907 | |
| 1908 | static JSValue tsn_generator_next( |
| 1909 | JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* func_data) { |
| 1910 | auto* closure = tsn_get_closure_from_func(func_data[0]); |
| 1911 | |
| 1912 | if (closure->resume_point >= 0) { // generating |
| 1913 | switch (static_cast<tsn_generator_op>(magic)) { |
| 1914 | case tsn_generator_op::gen_throw: |
| 1915 | // throw the error in the current js context and fallthrough |
| 1916 | tsn_throw(ctx, argv[0]); |
| 1917 | [[fallthrough]]; |
| 1918 | case tsn_generator_op::gen_next: { |
| 1919 | auto res = call_closure_callable(ctx, func_data[0], this_val, argc, argv, closure); |
| 1920 | if (JS_IsException(res) != 0) { |
| 1921 | return res; |
| 1922 | } |
| 1923 | auto iterator_result = tsn_iterator_result(ctx, closure->resume_point < 0, res); |
| 1924 | tsn_release_inline(ctx, res); |
| 1925 | return iterator_result; |
| 1926 | } |
| 1927 | case tsn_generator_op::gen_return: |
| 1928 | closure->resume_point = -1; |
| 1929 | return tsn_iterator_result(ctx, true, argv[0]); |
| 1930 | } |
| 1931 | } else { // completed |
| 1932 | switch (static_cast<tsn_generator_op>(magic)) { |
| 1933 | case tsn_generator_op::gen_next: |
| 1934 | return tsn_iterator_result(ctx, true, JS_UNDEFINED); |
| 1935 | case tsn_generator_op::gen_return: |
| 1936 | return tsn_iterator_result(ctx, true, argv[0]); |
| 1937 | case tsn_generator_op::gen_throw: |
| 1938 | tsn_throw(ctx, JS_DupValue(ctx, argv[0])); |
| 1939 | } |
| 1940 | } |
| 1941 | // should never get here |
| 1942 | return JS_UNDEFINED; |
| 1943 | } |
| 1944 | |
| 1945 | tsn_value tsn_new_generator(tsn_vm* ctx, tsn_value closure) { |
| 1946 | auto gen = JS_NewObject(ctx); |
nothing calls this directly
no test coverage detected