This repository has been archived by the owner on Sep 11, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 47
对 QuickJS 的修改
huliangjie edited this page Apr 15, 2021
·
1 revision
// quickjs.h
#ifndef JS_PTR64
// #define JS_NAN_BOXING
#endif
因为部分平台的行为不正确
// quickjs.c
// 添加 || defined(CONFIG_DISABLE_STACK_CHECK)
#if !defined(CONFIG_STACK_CHECK) || defined(CONFIG_DISABLE_STACK_CHECK)
/* no stack limitation */
static inline uint8_t *js_get_stack_pointer(void)
{
return NULL;
}
用于在 module_require 中得到自身信息.
// quickjs.c
// make JS_GetActiveFunction extern
JSValueConst JS_GetActiveFunction(JSContext *ctx) { }
预留, 用于直接比较JSString, 以避免不必要的类型转换.
// quickjs.c
// make js_string_compare extern
/* return < 0, 0 or > 0 */
int js_string_compare(JSContext *ctx,
const JSString *p1, const JSString *p2)
// quickjs.c
// add #elif defined(__ANDROID__)
// change to 'return 0;'
/* default memory allocation functions with memory limitation */
static inline size_t js_def_malloc_usable_size(void *ptr)
{
#if defined(__APPLE__)
return malloc_size(ptr);
#elif defined(_WIN32)
return _msize(ptr);
#elif defined(EMSCRIPTEN)
return 0;
#elif defined(__ANDROID__)
return 0;
#elif defined(__linux__)
return malloc_usable_size(ptr);
#else
/* change this to `return 0;` if compilation fails */
return 0;
#endif
}
static const JSMallocFunctions def_malloc_funcs = {
js_def_malloc,
js_def_free,
js_def_realloc,
#if defined(__APPLE__)
malloc_size,
#elif defined(_WIN32)
(size_t (*)(const void *))_msize,
#elif defined(EMSCRIPTEN)
NULL,
#elif defined(__ANDROID__)
NULL,
#elif defined(__linux__)
(size_t (*)(const void *))malloc_usable_size,
#else
/* change this to `NULL,` if compilation fails */
malloc_usable_size,
#endif
};
See stackoverflow
// quickjs.c
// insert before static int JS_InitAtoms(JSRuntime *rt)
#if defined(__APPLE__)
// not best solution
#include <mach/mach_time.h>
#ifndef CLOCK_REALTIME
#define CLOCK_REALTIME 0
int clock_gettime(int clk_id, struct timespec *t){
mach_timebase_info_data_t timebase;
mach_timebase_info(&timebase);
uint64_t time;
time = mach_absolute_time();
double nseconds = ((double)time * (double)timebase.numer)/((double)timebase.denom);
double seconds = ((double)time * (double)timebase.numer)/((double)timebase.denom * 1e9);
t->tv_sec = seconds;
t->tv_nsec = nseconds;
return 0;
}
#endif
#endif
此修改用于忽略TypedArray越界赋值异常.
let x = new Uint8Array(4);
x[20] = 1;
上述代码在 nodejs 等环境中默认不会抛越界异常. 部分 js 库 (如 xlsx) 依赖于此特性.
// quickjs.c
// in JS_SetPropertyInternal()
// ...
typed_array_oob:
val = JS_ToNumberFree(ctx, val);
JS_FreeValue(ctx, val);
if (JS_IsException(val))
return -1;
if (typed_array_is_detached(ctx, p1)) {
JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
return -1;
}
#ifdef JSB_TYPED_ARRAY_NO_THROW
return TRUE;
#else
return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index");
#endif
// ...
// in JS_SetPropertyValue()
// ...
ta_out_of_bound:
if (typed_array_is_detached(ctx, p)) {
JS_ThrowTypeErrorDetachedArrayBuffer(ctx);
return -1;
} else {
#ifdef JSB_TYPED_ARRAY_NO_THROW
break;
#else
return JS_ThrowTypeErrorOrFalse(ctx, flags, "out-of-bound numeric index");
#endif
// ...
用于部分情况下数学库中没有 log2 时提供替代.
// quickjs.c
// 在不存在log2的情况下提供替代的 log2
#if defined(JSB_DEF_LOG2)
static double log2(double v) { return log(v) / log(2.0); }
#endif
用于在 C# 中产生字符串, 绕过 vsprintf
// quickjs.c
static JSValue JSB_ThrowError2(JSContext *ctx, JSErrorEnum error_num,
const char *buf, size_t buf_len, BOOL add_backtrace)
{
JSValue obj, ret;
obj = JS_NewObjectProtoClass(ctx, ctx->native_error_proto[error_num],
JS_CLASS_ERROR);
if (unlikely(JS_IsException(obj))) {
/* out of memory: throw JS_NULL to avoid recursing */
obj = JS_NULL;
} else {
JS_DefinePropertyValue(ctx, obj, JS_ATOM_message,
JS_NewStringLen(ctx, buf, buf_len),
JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
}
if (add_backtrace) {
build_backtrace(ctx, obj, NULL, 0, 0);
}
ret = JS_Throw(ctx, obj);
return ret;
}
JSValue JSB_ThrowError(JSContext *ctx, const char *buf, size_t buf_len)
{
JSRuntime *rt = ctx->rt;
JSStackFrame *sf;
BOOL add_backtrace;
/* the backtrace is added later if called from a bytecode function */
sf = rt->current_stack_frame;
add_backtrace = !rt->in_out_of_memory &&
(!sf || (JS_GetFunctionBytecode(sf->cur_func) == NULL));
return JSB_ThrowError2(ctx, JS_INTERNAL_ERROR, buf, buf_len, add_backtrace);
}