diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25404cb..f2e7d92 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -139,7 +139,6 @@ jobs: run: | cp build/fib.so examples/ cp build/point.so examples/ - cp build/bjson.so tests/ ./build/qjs examples/test_fib.js ./build/qjs examples/test_point.js ./build/qjs tests/test_bjson.js @@ -207,6 +206,7 @@ jobs: - name: test run: | build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js + build\${{matrix.buildType}}\qjs.exe tests\test_bjson.js build\${{matrix.buildType}}\qjs.exe tests\test_closure.js build\${{matrix.buildType}}\qjs.exe tests\test_language.js build\${{matrix.buildType}}\qjs.exe tests\test_builtin.js @@ -235,6 +235,7 @@ jobs: - name: test run: | build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js + build\${{matrix.buildType}}\qjs.exe tests\test_bjson.js build\${{matrix.buildType}}\qjs.exe tests\test_closure.js build\${{matrix.buildType}}\qjs.exe tests\test_language.js build\${{matrix.buildType}}\qjs.exe tests\test_builtin.js @@ -267,6 +268,7 @@ jobs: - name: test run: | build\qjs.exe tests\test_bigint.js + build\qjs.exe tests\test_bjson.js build\qjs.exe tests\test_closure.js build\qjs.exe tests\test_language.js build\qjs.exe tests\test_builtin.js diff --git a/CMakeLists.txt b/CMakeLists.txt index 373bb1f..d4de876 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -312,16 +312,6 @@ if(BUILD_EXAMPLES AND NOT WIN32) if(APPLE) target_link_options(point PRIVATE -undefined dynamic_lookup) endif() - - add_library(bjson MODULE tests/bjson.c) - set_target_properties(bjson PROPERTIES - PREFIX "" - C_VISIBILITY_PRESET default - ) - target_compile_definitions(bjson PRIVATE JS_SHARED_LIBRARY) - if(APPLE) - target_link_options(bjson PRIVATE -undefined dynamic_lookup) - endif() endif() add_executable(test_fib diff --git a/doc/quickjs.texi b/doc/quickjs.texi index dab92bf..c335eeb 100644 --- a/doc/quickjs.texi +++ b/doc/quickjs.texi @@ -872,8 +872,7 @@ Examples are available in @file{quickjs-libc.c}. @subsection C Modules Native ES6 modules are supported and can be dynamically or statically -linked. Look at the @file{test_bjson} and @file{bjson.so} -examples. The standard library @file{quickjs-libc.c} is also a good example +linked. The standard library @file{quickjs-libc.c} is a good example of a native module. @subsection Memory handling diff --git a/gen/repl.c b/gen/repl.c index 2757a66..8e33106 100644 Binary files a/gen/repl.c and b/gen/repl.c differ diff --git a/qjs.c b/qjs.c index a293a17..1090117 100644 --- a/qjs.c +++ b/qjs.c @@ -152,6 +152,7 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt) /* system modules */ js_init_module_std(ctx, "std"); js_init_module_os(ctx, "os"); + js_init_module_bjson(ctx, "bjson"); JSValue global = JS_GetGlobalObject(ctx); JS_SetPropertyFunctionList(ctx, global, global_obj, countof(global_obj)); diff --git a/qjsc.c b/qjsc.c index 33dccce..1ef26ee 100644 --- a/qjsc.c +++ b/qjsc.c @@ -378,6 +378,7 @@ int main(int argc, char **argv) /* add system modules */ namelist_add(&cmodule_list, "std", "std", 0); namelist_add(&cmodule_list, "os", "os", 0); + namelist_add(&cmodule_list, "bjson", "bjson", 0); for(;;) { c = getopt(argc, argv, "ho:N:mn:bxesvM:p:S:D:"); diff --git a/quickjs-libc.c b/quickjs-libc.c index f66f872..3416eb2 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -4089,3 +4089,69 @@ void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, JS_FreeValue(ctx, val); } } + +static JSValue js_bjson_read(JSContext *ctx, JSValue this_val, + int argc, JSValue *argv) +{ + uint8_t *buf; + uint64_t pos, len; + JSValue obj; + size_t size; + int flags; + + if (JS_ToIndex(ctx, &pos, argv[1])) + return JS_EXCEPTION; + if (JS_ToIndex(ctx, &len, argv[2])) + return JS_EXCEPTION; + buf = JS_GetArrayBuffer(ctx, &size, argv[0]); + if (!buf) + return JS_EXCEPTION; + if (pos + len > size) + return JS_ThrowRangeError(ctx, "array buffer overflow"); + flags = 0; + if (JS_ToBool(ctx, argv[3])) + flags |= JS_READ_OBJ_REFERENCE; + obj = JS_ReadObject(ctx, buf + pos, len, flags); + return obj; +} + +static JSValue js_bjson_write(JSContext *ctx, JSValue this_val, + int argc, JSValue *argv) +{ + size_t len; + uint8_t *buf; + JSValue array; + int flags; + + flags = 0; + if (JS_ToBool(ctx, argv[1])) + flags |= JS_WRITE_OBJ_REFERENCE; + buf = JS_WriteObject(ctx, &len, argv[0], flags); + if (!buf) + return JS_EXCEPTION; + array = JS_NewArrayBufferCopy(ctx, buf, len); + js_free(ctx, buf); + return array; +} + + +static const JSCFunctionListEntry js_bjson_funcs[] = { + JS_CFUNC_DEF("read", 4, js_bjson_read ), + JS_CFUNC_DEF("write", 2, js_bjson_write ), +}; + +static int js_bjson_init(JSContext *ctx, JSModuleDef *m) +{ + return JS_SetModuleExportList(ctx, m, js_bjson_funcs, + countof(js_bjson_funcs)); +} + +JSModuleDef *js_init_module_bjson(JSContext *ctx, const char *module_name) +{ + JSModuleDef *m; + m = JS_NewCModule(ctx, module_name, js_bjson_init); + if (!m) + return NULL; + JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs)); + return m; +} diff --git a/quickjs-libc.h b/quickjs-libc.h index ad850a3..8917191 100644 --- a/quickjs-libc.h +++ b/quickjs-libc.h @@ -35,6 +35,7 @@ extern "C" { JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); +JSModuleDef *js_init_module_bjson(JSContext *ctx, const char *module_name); void js_std_add_helpers(JSContext *ctx, int argc, char **argv); void js_std_loop(JSContext *ctx); JSValue js_std_await(JSContext *ctx, JSValue obj); diff --git a/repl.js b/repl.js index 3074819..7274654 100644 --- a/repl.js +++ b/repl.js @@ -24,9 +24,11 @@ */ import * as std from "std"; import * as os from "os"; +import * as bjson from "bjson"; (function(g) { - /* add 'os' and 'std' bindings */ + /* add 'bjson', 'os' and 'std' bindings */ + g.bjson = bjson; g.os = os; g.std = std; diff --git a/tests/bjson.c b/tests/bjson.c deleted file mode 100644 index efa10b3..0000000 --- a/tests/bjson.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * QuickJS: binary JSON module (test only) - * - * Copyright (c) 2017-2019 Fabrice Bellard - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -#include "../quickjs-libc.h" -#include "../cutils.h" - -static JSValue js_bjson_read(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - uint8_t *buf; - uint64_t pos, len; - JSValue obj; - size_t size; - int flags; - - if (JS_ToIndex(ctx, &pos, argv[1])) - return JS_EXCEPTION; - if (JS_ToIndex(ctx, &len, argv[2])) - return JS_EXCEPTION; - buf = JS_GetArrayBuffer(ctx, &size, argv[0]); - if (!buf) - return JS_EXCEPTION; - if (pos + len > size) - return JS_ThrowRangeError(ctx, "array buffer overflow"); - flags = 0; - if (JS_ToBool(ctx, argv[3])) - flags |= JS_READ_OBJ_REFERENCE; - obj = JS_ReadObject(ctx, buf + pos, len, flags); - return obj; -} - -static JSValue js_bjson_write(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - size_t len; - uint8_t *buf; - JSValue array; - int flags; - - flags = 0; - if (JS_ToBool(ctx, argv[1])) - flags |= JS_WRITE_OBJ_REFERENCE; - buf = JS_WriteObject(ctx, &len, argv[0], flags); - if (!buf) - return JS_EXCEPTION; - array = JS_NewArrayBufferCopy(ctx, buf, len); - js_free(ctx, buf); - return array; -} - -static const JSCFunctionListEntry js_bjson_funcs[] = { - JS_CFUNC_DEF("read", 4, js_bjson_read ), - JS_CFUNC_DEF("write", 2, js_bjson_write ), -}; - -static int js_bjson_init(JSContext *ctx, JSModuleDef *m) -{ - return JS_SetModuleExportList(ctx, m, js_bjson_funcs, - countof(js_bjson_funcs)); -} - -#ifdef JS_SHARED_LIBRARY -#define JS_INIT_MODULE js_init_module -#else -#define JS_INIT_MODULE js_init_module_bjson -#endif - -JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name) -{ - JSModuleDef *m; - m = JS_NewCModule(ctx, module_name, js_bjson_init); - if (!m) - return NULL; - JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs)); - return m; -} diff --git a/tests/test_bjson.js b/tests/test_bjson.js index 25e1090..000d1b8 100644 --- a/tests/test_bjson.js +++ b/tests/test_bjson.js @@ -1,4 +1,4 @@ -import * as bjson from "./bjson.so"; +import * as bjson from "bjson"; function assert(actual, expected, message) { if (arguments.length == 1)