diff --git a/quickjs-libc.c b/quickjs-libc.c index ca8e359..d116b93 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -484,8 +484,50 @@ typedef JSModuleDef *(JSInitModuleFunc)(JSContext *ctx, static JSModuleDef *js_module_loader_so(JSContext *ctx, const char *module_name) { - JS_ThrowReferenceError(ctx, "shared library modules are not supported yet"); - return NULL; + JSModuleDef *m; + HANDLE hd; + JSInitModuleFunc *init; + char *filename; + + if (!strchr(module_name, '/')) { + /* must add a '/' so that the DLL is not searched in the + system library paths */ + filename = js_malloc(ctx, strlen(module_name) + 2 + 1); + if (!filename) + return NULL; + strcpy(filename, "./"); + strcpy(filename + 2, module_name); + } else { + filename = (char *)module_name; + } + + /* C module */ + hd = LoadLibrary(filename); + if (filename != module_name) + js_free(ctx, filename); + if (!hd) { + JS_ThrowReferenceError(ctx, "could not load module filename '%s'('%s') as shared library", + module_name,filename); + goto fail; + } + + init = (JSInitModuleFunc*)GetProcAddress(hd,"js_init_module"); + if (!init) { + JS_ThrowReferenceError(ctx, "could not load module filename '%s': js_init_module not found", + module_name); + goto fail; + } + + m = init(ctx, module_name); + if (!m) { + JS_ThrowReferenceError(ctx, "could not load module filename '%s': initialization error", + module_name); + fail: + if (hd) + FreeLibrary(hd); + return NULL; + } + return m; } #else static JSModuleDef *js_module_loader_so(JSContext *ctx, @@ -513,15 +555,13 @@ static JSModuleDef *js_module_loader_so(JSContext *ctx, if (filename != module_name) js_free(ctx, filename); if (!hd) { - JS_ThrowReferenceError(ctx, "could not load module filename '%s' as shared library", - module_name); - goto fail; + goto dlerror; } init = dlsym(hd, "js_init_module"); if (!init) { - JS_ThrowReferenceError(ctx, "could not load module filename '%s': js_init_module not found", - module_name); + dlerror: + JS_ThrowReferenceError(ctx, "could not load module filename '%s': %s", module_name, dlerror()); goto fail; } @@ -660,7 +700,13 @@ JSModuleDef *js_module_loader(JSContext *ctx, { JSModuleDef *m; - if (has_suffix(module_name, ".so")) { + if ( + #if !defined(_WIN32) + has_suffix(module_name, ".so") + #else + has_suffix(module_name, ".dll") + #endif + ) { m = js_module_loader_so(ctx, module_name); } else { size_t buf_len; diff --git a/quickjs.c b/quickjs.c index 475232c..89269f2 100644 --- a/quickjs.c +++ b/quickjs.c @@ -3795,6 +3795,20 @@ static JSValue string_buffer_end(StringBuffer *s) return JS_MKPTR(JS_TAG_STRING, str); } +JSValue JS_NewStringWLen(JSContext *ctx, size_t buf_len) +{ + JSString *str; + if (buf_len <= 0) { + return JS_AtomToString(ctx, JS_ATOM_empty_string); + } + str = js_alloc_string_rt(ctx->rt, buf_len, 0); + if (unlikely(!str)){ + JS_ThrowOutOfMemory(ctx); + return JS_EXCEPTION; + } + memset(str->u.str8, 0, buf_len+1); + return JS_MKPTR(JS_TAG_STRING, str); +} /* create a string from a UTF-8 buffer */ JSValue JS_NewStringLen(JSContext *ctx, const char *buf, size_t buf_len) { @@ -3894,6 +3908,18 @@ JSValue JS_NewAtomString(JSContext *ctx, const char *str) return val; } +uint8_t *JS_ToCStringLenRaw(JSContext *ctx, size_t *plen, JSValueConst val) +{ + if (JS_VALUE_GET_TAG(val) != JS_TAG_STRING) + { + if(plen) *plen = 0; + return NULL; + } + JSString *str = JS_VALUE_GET_STRING(val); + if(plen) *plen = str->len; + return str->u.str8; +} + /* return (NULL, 0) if exception. */ /* return pointer into a JSString with a live ref_count */ /* cesu8 determines if non-BMP1 codepoints are encoded as 1 or 2 utf-8 sequences */ @@ -5214,7 +5240,7 @@ static int JS_SetObjectData(JSContext *ctx, JSValueConst obj, JSValue val) return -1; } -JSValue JS_NewObjectClass(JSContext *ctx, int class_id) +JSValue JS_NewObjectClass(JSContext *ctx, JSClassID class_id) { return JS_NewObjectProtoClass(ctx, ctx->class_proto[class_id], class_id); } @@ -44282,11 +44308,10 @@ static uint64_t xorshift64star(uint64_t *pstate) return x * 0x2545F4914F6CDD1D; } +static int64_t date_now(void); static void js_random_init(JSContext *ctx) { - struct timeval tv; - gettimeofday(&tv, NULL); - ctx->random_state = ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; + ctx->random_state = date_now(); /* the state must be non zero */ if (ctx->random_state == 0) ctx->random_state = 1; diff --git a/quickjs.h b/quickjs.h index c92afbc..64cb7d6 100644 --- a/quickjs.h +++ b/quickjs.h @@ -732,6 +732,7 @@ int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val); /* same as JS_ToInt64() but allow BigInt */ int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val); +JSValue JS_NewStringWLen(JSContext *ctx, size_t len); JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1); static inline JSValue JS_NewString(JSContext *ctx, const char *str) { @@ -740,6 +741,7 @@ static inline JSValue JS_NewString(JSContext *ctx, const char *str) JSValue JS_NewAtomString(JSContext *ctx, const char *str); JSValue JS_ToString(JSContext *ctx, JSValueConst val); JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val); +uint8_t *JS_ToCStringLenRaw(JSContext *ctx, size_t *plen, JSValueConst val1); const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8); static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1) {