mirror of
https://github.com/DoneJS-Runtime/quickjs-done-nextgen.git
synced 2025-01-09 17:43:15 +00:00
Add native module support on Windows
This commit is contained in:
parent
ada24f33f3
commit
902cc2cf0e
8 changed files with 127 additions and 30 deletions
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
|
@ -195,14 +195,20 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: build
|
- name: build
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -G "Visual Studio 17 2022" -A ${{matrix.arch}}
|
cmake -B build -DBUILD_EXAMPLES=ON -G "Visual Studio 17 2022" -A ${{matrix.arch}}
|
||||||
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
|
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
|
||||||
cmake --build build --config ${{matrix.buildType}} --target function_source
|
cmake --build build --config ${{matrix.buildType}} --target function_source
|
||||||
|
cmake --build build --config ${{matrix.buildType}} --target fib
|
||||||
|
cmake --build build --config ${{matrix.buildType}} --target point
|
||||||
- name: stats
|
- name: stats
|
||||||
run: |
|
run: |
|
||||||
build\${{matrix.buildType}}\qjs.exe -qd
|
build\${{matrix.buildType}}\qjs.exe -qd
|
||||||
- name: test
|
- name: test
|
||||||
run: |
|
run: |
|
||||||
|
cp build\${{matrix.buildType}}\fib.dll examples\
|
||||||
|
cp build\${{matrix.buildType}}\point.dll examples\
|
||||||
|
build\${{matrix.buildType}}\qjs.exe examples\test_fib.js
|
||||||
|
build\${{matrix.buildType}}\qjs.exe examples\test_point.js
|
||||||
build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js
|
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_bjson.js
|
||||||
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
|
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
|
||||||
|
@ -224,14 +230,20 @@ jobs:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: build
|
- name: build
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -G "Visual Studio 17 2022" -T ClangCL
|
cmake -B build -DBUILD_EXAMPLES=ON -G "Visual Studio 17 2022" -T ClangCL
|
||||||
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
|
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
|
||||||
cmake --build build --config ${{matrix.buildType}} --target function_source
|
cmake --build build --config ${{matrix.buildType}} --target function_source
|
||||||
|
cmake --build build --config ${{matrix.buildType}} --target fib
|
||||||
|
cmake --build build --config ${{matrix.buildType}} --target point
|
||||||
- name: stats
|
- name: stats
|
||||||
run: |
|
run: |
|
||||||
build\${{matrix.buildType}}\qjs.exe -qd
|
build\${{matrix.buildType}}\qjs.exe -qd
|
||||||
- name: test
|
- name: test
|
||||||
run: |
|
run: |
|
||||||
|
cp build\${{matrix.buildType}}\fib.dll examples\
|
||||||
|
cp build\${{matrix.buildType}}\point.dll examples\
|
||||||
|
build\${{matrix.buildType}}\qjs.exe examples\test_fib.js
|
||||||
|
build\${{matrix.buildType}}\qjs.exe examples\test_point.js
|
||||||
build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js
|
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_bjson.js
|
||||||
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
|
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
|
||||||
|
@ -257,14 +269,20 @@ jobs:
|
||||||
ninja.exe --version
|
ninja.exe --version
|
||||||
- name: build
|
- name: build
|
||||||
run: |
|
run: |
|
||||||
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Ninja"
|
cmake -B build -DBUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Ninja"
|
||||||
cmake --build build --target qjs_exe
|
cmake --build build --target qjs_exe
|
||||||
cmake --build build --target function_source
|
cmake --build build --target function_source
|
||||||
|
cmake --build build --target fib
|
||||||
|
cmake --build build --target point
|
||||||
- name: stats
|
- name: stats
|
||||||
run: |
|
run: |
|
||||||
build\qjs.exe -qd
|
build\qjs.exe -qd
|
||||||
- name: test
|
- name: test
|
||||||
run: |
|
run: |
|
||||||
|
cp build\fib.dll examples\
|
||||||
|
cp build\point.dll examples\
|
||||||
|
build\qjs.exe examples\test_fib.js
|
||||||
|
build\qjs.exe examples\test_point.js
|
||||||
build\qjs.exe tests\test_bigint.js
|
build\qjs.exe tests\test_bigint.js
|
||||||
build\qjs.exe tests\test_bjson.js
|
build\qjs.exe tests\test_bjson.js
|
||||||
build\qjs.exe tests\test_closure.js
|
build\qjs.exe tests\test_closure.js
|
||||||
|
|
|
@ -273,7 +273,7 @@ target_link_libraries(function_source ${qjs_libs})
|
||||||
# Examples
|
# Examples
|
||||||
#
|
#
|
||||||
|
|
||||||
if(BUILD_EXAMPLES AND NOT WIN32)
|
if(BUILD_EXAMPLES)
|
||||||
add_executable(hello
|
add_executable(hello
|
||||||
gen/hello.c
|
gen/hello.c
|
||||||
)
|
)
|
||||||
|
@ -290,27 +290,31 @@ if(BUILD_EXAMPLES AND NOT WIN32)
|
||||||
target_compile_definitions(hello_module PRIVATE ${qjs_defines})
|
target_compile_definitions(hello_module PRIVATE ${qjs_defines})
|
||||||
target_link_libraries(hello_module ${qjs_libs})
|
target_link_libraries(hello_module ${qjs_libs})
|
||||||
|
|
||||||
if(NOT WIN32)
|
add_library(fib MODULE examples/fib.c)
|
||||||
add_library(fib MODULE examples/fib.c)
|
set_target_properties(fib PROPERTIES
|
||||||
set_target_properties(fib PROPERTIES
|
PREFIX ""
|
||||||
PREFIX ""
|
C_VISIBILITY_PRESET default
|
||||||
C_VISIBILITY_PRESET default
|
)
|
||||||
)
|
target_compile_definitions(fib PRIVATE JS_SHARED_LIBRARY)
|
||||||
target_compile_definitions(fib PRIVATE JS_SHARED_LIBRARY)
|
if(WIN32)
|
||||||
if(APPLE)
|
target_link_libraries(fib ${qjs_libs})
|
||||||
target_link_options(fib PRIVATE -undefined dynamic_lookup)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(point MODULE examples/point.c)
|
|
||||||
set_target_properties(point PROPERTIES
|
|
||||||
PREFIX ""
|
|
||||||
C_VISIBILITY_PRESET default
|
|
||||||
)
|
|
||||||
target_compile_definitions(point PRIVATE JS_SHARED_LIBRARY)
|
|
||||||
if(APPLE)
|
|
||||||
target_link_options(point PRIVATE -undefined dynamic_lookup)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
if(APPLE)
|
||||||
|
target_link_options(fib PRIVATE -undefined dynamic_lookup)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(point MODULE examples/point.c)
|
||||||
|
set_target_properties(point PROPERTIES
|
||||||
|
PREFIX ""
|
||||||
|
C_VISIBILITY_PRESET default
|
||||||
|
)
|
||||||
|
target_compile_definitions(point PRIVATE JS_SHARED_LIBRARY)
|
||||||
|
if(WIN32)
|
||||||
|
target_link_libraries(point ${qjs_libs})
|
||||||
|
endif()
|
||||||
|
if(APPLE)
|
||||||
|
target_link_options(point PRIVATE -undefined dynamic_lookup)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_executable(test_fib
|
add_executable(test_fib
|
||||||
examples/fib.c
|
examples/fib.c
|
||||||
|
|
|
@ -61,7 +61,15 @@ static int js_fib_init(JSContext *ctx, JSModuleDef *m)
|
||||||
#define JS_INIT_MODULE js_init_module_fib
|
#define JS_INIT_MODULE js_init_module_fib
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
|
#ifndef JS_EXTERN
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define JS_EXTERN __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define JS_EXTERN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JS_EXTERN JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
|
||||||
{
|
{
|
||||||
JSModuleDef *m;
|
JSModuleDef *m;
|
||||||
m = JS_NewCModule(ctx, module_name, js_fib_init);
|
m = JS_NewCModule(ctx, module_name, js_fib_init);
|
||||||
|
|
|
@ -141,7 +141,15 @@ static int js_point_init(JSContext *ctx, JSModuleDef *m)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
|
#ifndef JS_EXTERN
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define JS_EXTERN __declspec(dllexport)
|
||||||
|
#else
|
||||||
|
#define JS_EXTERN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JS_EXTERN JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
|
||||||
{
|
{
|
||||||
JSModuleDef *m;
|
JSModuleDef *m;
|
||||||
m = JS_NewCModule(ctx, module_name, js_point_init);
|
m = JS_NewCModule(ctx, module_name, js_point_init);
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
/* example of JS module importing a C module */
|
/* example of JS module importing a C module */
|
||||||
|
import * as os from "os";
|
||||||
|
|
||||||
import { fib } from "./fib.so";
|
const isWin = os.platform === 'win32';
|
||||||
|
const { fib } = await import(`./fib.${isWin ? 'dll' : 'so'}`);
|
||||||
|
|
||||||
console.log("Hello World");
|
console.log("Hello World");
|
||||||
console.log("fib(10)=", fib(10));
|
console.log("fib(10)=", fib(10));
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
/* example of JS module importing a C module */
|
/* example of JS module importing a C module */
|
||||||
import { Point } from "./point.so";
|
import * as os from "os";
|
||||||
|
|
||||||
|
const isWin = os.platform === 'win32';
|
||||||
|
const { Point } = await import(`./point.${isWin ? 'dll' : 'so'}`);
|
||||||
|
|
||||||
function assert(b, str)
|
function assert(b, str)
|
||||||
{
|
{
|
||||||
|
|
BIN
gen/test_fib.c
BIN
gen/test_fib.c
Binary file not shown.
|
@ -96,6 +96,14 @@ extern char **environ;
|
||||||
|
|
||||||
#define MAX_SAFE_INTEGER (((int64_t) 1 << 53) - 1)
|
#define MAX_SAFE_INTEGER (((int64_t) 1 << 53) - 1)
|
||||||
|
|
||||||
|
#ifndef QJS_NATIVE_MODULE_SUFFIX
|
||||||
|
#ifdef _WIN32
|
||||||
|
#define QJS_NATIVE_MODULE_SUFFIX ".dll"
|
||||||
|
#else
|
||||||
|
#define QJS_NATIVE_MODULE_SUFFIX ".so"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
- add socket calls
|
- add socket calls
|
||||||
*/
|
*/
|
||||||
|
@ -483,7 +491,53 @@ typedef JSModuleDef *(JSInitModuleFunc)(JSContext *ctx,
|
||||||
const char *module_name);
|
const char *module_name);
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(__wasi__)
|
#if defined(_WIN32)
|
||||||
|
static JSModuleDef *js_module_loader_so(JSContext *ctx,
|
||||||
|
const char *module_name)
|
||||||
|
{
|
||||||
|
JSModuleDef *m;
|
||||||
|
HINSTANCE hd;
|
||||||
|
JSInitModuleFunc *init;
|
||||||
|
char *filename = NULL;
|
||||||
|
size_t len = strlen(module_name);
|
||||||
|
JS_BOOL is_absolute = len > 2 && ((module_name[0] >= 'A' && module_name[0] <= 'Z') ||
|
||||||
|
(module_name[0] >= 'a' && module_name[0] <= 'z')) && module_name[1] == ':';
|
||||||
|
JS_BOOL is_relative = len > 2 && module_name[0] == '.' && (module_name[1] == '/' || module_name[1] == '\\');
|
||||||
|
if (is_absolute || is_relative) {
|
||||||
|
filename = (char *)module_name;
|
||||||
|
} else {
|
||||||
|
filename = js_malloc(ctx, len + 2 + 1);
|
||||||
|
if (!filename)
|
||||||
|
return NULL;
|
||||||
|
strcpy(filename, "./");
|
||||||
|
strcpy(filename + 2, module_name);
|
||||||
|
}
|
||||||
|
hd = LoadLibraryA(filename);
|
||||||
|
if (filename != module_name)
|
||||||
|
js_free(ctx, filename);
|
||||||
|
if (hd == NULL) {
|
||||||
|
JS_ThrowReferenceError(ctx, "js_load_module '%s' error: %lu",
|
||||||
|
module_name, GetLastError());
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
init = (JSInitModuleFunc *)(uintptr_t)GetProcAddress(hd, "js_init_module");
|
||||||
|
if (!init) {
|
||||||
|
JS_ThrowReferenceError(ctx, "js_init_module '%s' not found: %lu",
|
||||||
|
module_name, GetLastError());
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
m = init(ctx, module_name);
|
||||||
|
if (!m) {
|
||||||
|
JS_ThrowReferenceError(ctx, "js_call_module '%s' initialization error",
|
||||||
|
module_name);
|
||||||
|
fail:
|
||||||
|
if (hd != NULL)
|
||||||
|
FreeLibrary(hd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
#elif defined(__wasi__)
|
||||||
static JSModuleDef *js_module_loader_so(JSContext *ctx,
|
static JSModuleDef *js_module_loader_so(JSContext *ctx,
|
||||||
const char *module_name)
|
const char *module_name)
|
||||||
{
|
{
|
||||||
|
@ -599,7 +653,7 @@ JSModuleDef *js_module_loader(JSContext *ctx,
|
||||||
{
|
{
|
||||||
JSModuleDef *m;
|
JSModuleDef *m;
|
||||||
|
|
||||||
if (has_suffix(module_name, ".so")) {
|
if (has_suffix(module_name, QJS_NATIVE_MODULE_SUFFIX)) {
|
||||||
m = js_module_loader_so(ctx, module_name);
|
m = js_module_loader_so(ctx, module_name);
|
||||||
} else {
|
} else {
|
||||||
size_t buf_len;
|
size_t buf_len;
|
||||||
|
|
Loading…
Reference in a new issue