-
Notifications
You must be signed in to change notification settings - Fork 171
feat(libc): windows native module support #490
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
29a2588
94f3753
7685526
c0ef55e
f87ab72
efa5ef6
c703ffb
76a0588
64ae115
096ada0
c2391b0
fedc1bc
306704c
8e465ca
75837c2
e3b79ba
a923934
b5183ae
4727d01
6094d3d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,8 @@ | ||
/* 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("fib(10)=", fib(10)); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -96,6 +96,14 @@ extern char **environ; | |
|
||
#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" | ||
zeromake marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#endif | ||
#endif | ||
|
||
/* TODO: | ||
- add socket calls | ||
*/ | ||
|
@@ -482,7 +490,53 @@ typedef JSModuleDef *(JSInitModuleFunc)(JSContext *ctx, | |
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) { | ||
zeromake marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be nicer to use FormatMessageA() to get a human-readable error message (example) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bnoordhuis struct JSContext {
char* errmsg;
}
static int js_error(JSContext *ctx) {
if (ctx->errmsg) {
LocalFree(ctx->errmsg);
ctx->errmsg = NULL;
}
// FormatMessageA ……
} There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bnoordhuis Doing it The Right Way (TM) seems a bit involved: https://github.com/libuv/libuv/blob/0a00e80c3686b93eccb9a801954e86bd7d7fe6ab/src/win/dl.c#L92 perhaps we can simplify here? |
||
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, | ||
const char *module_name) | ||
{ | ||
|
@@ -598,7 +652,7 @@ JSModuleDef *js_module_loader(JSContext *ctx, | |
{ | ||
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); | ||
} else { | ||
size_t buf_len; | ||
|
Uh oh!
There was an error while loading. Please reload this page.