diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 28d54dc3c..499685e38 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -165,9 +165,9 @@ jobs: ./build/qjs -c examples/hello.js -o hello ./hello - - name: test interrupt + - name: test api run: | - ./build/interrupt-test + ./build/api-test windows-msvc: runs-on: windows-latest @@ -197,9 +197,9 @@ jobs: run: | build\${{matrix.buildType}}\qjs.exe -c examples\hello.js -o hello.exe .\hello.exe - - name: test interrupt + - name: test api run: | - build\${{matrix.buildType}}\interrupt-test.exe + build\${{matrix.buildType}}\api-test.exe - name: Set up Visual Studio shell uses: egor-tensin/vs-shell@v2 with: @@ -262,9 +262,9 @@ jobs: build\${{matrix.buildType}}\qjs.exe examples\test_point.js build\${{matrix.buildType}}\run-test262.exe -c tests.conf build\${{matrix.buildType}}\function_source.exe - - name: test interrupt + - name: test api run: | - build\${{matrix.buildType}}\interrupt-test.exe + build\${{matrix.buildType}}\api-test.exe windows-ninja: runs-on: windows-latest @@ -294,9 +294,9 @@ jobs: build\qjs.exe examples\test_point.js build\run-test262.exe -c tests.conf build\function_source.exe - - name: test interrupt + - name: test api run: | - build\interrupt-test.exe + build\api-test.exe windows-sdk: runs-on: windows-latest @@ -327,9 +327,9 @@ jobs: build\${{matrix.buildType}}\qjs.exe examples\test_point.js build\${{matrix.buildType}}\run-test262.exe -c tests.conf build\${{matrix.buildType}}\function_source.exe - - name: test interrupt + - name: test api run: | - build\${{matrix.buildType}}\interrupt-test.exe + build\${{matrix.buildType}}\api-test.exe windows-mingw: runs-on: windows-latest @@ -380,9 +380,9 @@ jobs: run: | ./build/qjs -c examples/hello.js -o hello.exe ./hello - - name: test interrupt + - name: test api run: | - ./build/interrupt-test + ./build/api-test windows-mingw-shared: runs-on: windows-latest defaults: @@ -467,9 +467,9 @@ jobs: - name: test run: make test - - name: test interrupt + - name: test api run: | - ./build/interrupt-test + ./build/api-test openbsd: runs-on: ubuntu-latest diff --git a/CMakeLists.txt b/CMakeLists.txt index 06b54dd07..8ca49d0b8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -308,11 +308,11 @@ endif() # Interrupt test # -add_executable(interrupt-test - interrupt-test.c +add_executable(api-test + api-test.c ) -target_compile_definitions(interrupt-test PRIVATE ${qjs_defines}) -target_link_libraries(interrupt-test qjs) +target_compile_definitions(api-test PRIVATE ${qjs_defines}) +target_link_libraries(api-test qjs) # Unicode generator # diff --git a/interrupt-test.c b/api-test.c similarity index 63% rename from interrupt-test.c rename to api-test.c index c216a942c..0fb33beb8 100644 --- a/interrupt-test.c +++ b/api-test.c @@ -1,17 +1,12 @@ +#ifdef NDEBUG +#undef NDEBUG +#endif +#include #include #include "quickjs.h" #define MAX_TIME 10 -#define expect(condition) \ - do { \ - if (!(condition)) { \ - fprintf(stderr, "Failed: %s, file %s, line %d\n", \ - #condition, __FILE__, __LINE__); \ - exit(EXIT_FAILURE); \ - } \ - } while (0) - static int timeout_interrupt_handler(JSRuntime *rt, void *opaque) { int *time = (int *)opaque; @@ -34,12 +29,12 @@ static void sync_call(void) int time = 0; JS_SetInterruptHandler(rt, timeout_interrupt_handler, &time); JSValue ret = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_GLOBAL); - expect(time > MAX_TIME); - expect(JS_IsException(ret)); + assert(time > MAX_TIME); + assert(JS_IsException(ret)); JS_FreeValue(ctx, ret); - expect(JS_HasException(ctx)); + assert(JS_HasException(ctx)); JSValue e = JS_GetException(ctx); - expect(JS_IsUncatchableError(ctx, e)); + assert(JS_IsUncatchableError(ctx, e)); JS_FreeValue(ctx, e); JS_FreeContext(ctx); JS_FreeRuntime(rt); @@ -61,18 +56,18 @@ static void async_call(void) int time = 0; JS_SetInterruptHandler(rt, timeout_interrupt_handler, &time); JSValue ret = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_GLOBAL); - expect(!JS_IsException(ret)); + assert(!JS_IsException(ret)); JS_FreeValue(ctx, ret); - expect(JS_IsJobPending(rt)); + assert(JS_IsJobPending(rt)); int r = 0; while (JS_IsJobPending(rt)) { r = JS_ExecutePendingJob(rt, &ctx); } - expect(time > MAX_TIME); - expect(r == -1); - expect(JS_HasException(ctx)); + assert(time > MAX_TIME); + assert(r == -1); + assert(JS_HasException(ctx)); JSValue e = JS_GetException(ctx); - expect(JS_IsUncatchableError(ctx, e)); + assert(JS_IsUncatchableError(ctx, e)); JS_FreeValue(ctx, e); JS_FreeContext(ctx); JS_FreeRuntime(rt); @@ -80,7 +75,7 @@ static void async_call(void) static JSValue save_value(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { - expect(argc == 1); + assert(argc == 1); JSValue *p = (JSValue *)JS_GetContextOpaque(ctx); *p = JS_DupValue(ctx, argv[0]); return JS_UNDEFINED; @@ -109,26 +104,54 @@ static void async_call_stack_overflow(void) JS_SetPropertyStr(ctx, global, "save_value", JS_NewCFunction(ctx, save_value, "save_value", 1)); JS_FreeValue(ctx, global); JSValue ret = JS_Eval(ctx, code, strlen(code), "", JS_EVAL_TYPE_GLOBAL); - expect(!JS_IsException(ret)); + assert(!JS_IsException(ret)); JS_FreeValue(ctx, ret); - expect(JS_IsJobPending(rt)); + assert(JS_IsJobPending(rt)); int r = 0; while (JS_IsJobPending(rt)) { r = JS_ExecutePendingJob(rt, &ctx); } - expect(r == 1); - expect(!JS_HasException(ctx)); - expect(JS_IsError(ctx, value)); /* StackOverflow should be caught */ + assert(r == 1); + assert(!JS_HasException(ctx)); + assert(JS_IsError(ctx, value)); // stack overflow should be caught JS_FreeValue(ctx, value); JS_FreeContext(ctx); JS_FreeRuntime(rt); } -int main() +// https://github.com/quickjs-ng/quickjs/issues/914 +static void raw_context_global_var(void) +{ + JSRuntime *rt = JS_NewRuntime(); + JSContext *ctx = JS_NewContextRaw(rt); + JS_AddIntrinsicEval(ctx); + { + static const char code[] = "globalThis"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "*", JS_EVAL_TYPE_GLOBAL); + assert(JS_IsException(ret)); + JS_FreeValue(ctx, ret); + } + { + static const char code[] = "var x = 42"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "*", JS_EVAL_TYPE_GLOBAL); + assert(JS_IsUndefined(ret)); + JS_FreeValue(ctx, ret); + } + { + static const char code[] = "function f() {}"; + JSValue ret = JS_Eval(ctx, code, strlen(code), "*", JS_EVAL_TYPE_GLOBAL); + assert(JS_IsUndefined(ret)); + JS_FreeValue(ctx, ret); + } + JS_FreeContext(ctx); + JS_FreeRuntime(rt); +} + +int main(void) { sync_call(); async_call(); async_call_stack_overflow(); - printf("interrupt-test passed\n"); + raw_context_global_var(); return 0; -} \ No newline at end of file +} diff --git a/quickjs.c b/quickjs.c index 386b7bb93..9d39e9008 100644 --- a/quickjs.c +++ b/quickjs.c @@ -51399,6 +51399,8 @@ static void JS_AddIntrinsicBasicObjects(JSContext *ctx) int i; ctx->class_proto[JS_CLASS_OBJECT] = JS_NewObjectProto(ctx, JS_NULL); + ctx->global_obj = JS_NewObject(ctx); + ctx->global_var_obj = JS_NewObjectProto(ctx, JS_NULL); ctx->function_proto = JS_NewCFunction3(ctx, js_function_proto, "", 0, JS_CFUNC_generic, 0, ctx->class_proto[JS_CLASS_OBJECT]); @@ -51458,9 +51460,6 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) JS_FreeValue(ctx, obj1); JS_FreeValue(ctx, js_object_seal(ctx, JS_UNDEFINED, 1, &ctx->throw_type_error, 1)); - ctx->global_obj = JS_NewObject(ctx); - ctx->global_var_obj = JS_NewObjectProto(ctx, JS_NULL); - /* Object */ obj = JS_NewGlobalCConstructor(ctx, "Object", js_object_constructor, 1, ctx->class_proto[JS_CLASS_OBJECT]);