Add performance.{now,timeOrigin}

Ref: https://github.com/quickjs-ng/quickjs/issues/16
This commit is contained in:
Saúl Ibarra Corretgé 2023-11-17 23:56:46 +01:00
parent f03ab48a85
commit ea068d9a70
2 changed files with 41 additions and 0 deletions

View file

@ -392,6 +392,8 @@ struct JSContext {
JSValue global_obj; /* global object */ JSValue global_obj; /* global object */
JSValue global_var_obj; /* contains the global let/const definitions */ JSValue global_var_obj; /* contains the global let/const definitions */
uint64_t time_origin;
uint64_t random_state; uint64_t random_state;
bf_context_t *bf_ctx; /* points to rt->bf_ctx, shared by all contexts */ bf_context_t *bf_ctx; /* points to rt->bf_ctx, shared by all contexts */
/* when the counter reaches zero, JSRutime.interrupt_handler is called */ /* when the counter reaches zero, JSRutime.interrupt_handler is called */
@ -1979,6 +1981,9 @@ JSContext *JS_NewContext(JSRuntime *rt)
JS_AddIntrinsicTypedArrays(ctx); JS_AddIntrinsicTypedArrays(ctx);
JS_AddIntrinsicPromise(ctx); JS_AddIntrinsicPromise(ctx);
JS_AddIntrinsicBigInt(ctx); JS_AddIntrinsicBigInt(ctx);
JS_AddPerformance(ctx);
return ctx; return ctx;
} }
@ -50219,3 +50224,37 @@ void JS_AddIntrinsicTypedArrays(JSContext *ctx)
JS_AddIntrinsicAtomics(ctx); JS_AddIntrinsicAtomics(ctx);
#endif #endif
} }
/* Performance */
static uint64_t js__now_ms(void)
{
// TODO(saghul) Windows support.
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return (((uint64_t) ts.tv_sec) * 1000 + ts.tv_nsec / 1e6);
}
static JSValue js_perf_now(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
{
return JS_NewFloat64(ctx, js__now_ms() - ctx->time_origin);
}
static const JSCFunctionListEntry js_perf_proto_funcs[] = {
JS_CFUNC_DEF2("now", 0, js_perf_now, JS_PROP_ENUMERABLE),
};
void JS_AddPerformance(JSContext *ctx)
{
ctx->time_origin = js__now_ms();
JSValue performance = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, performance, js_perf_proto_funcs, countof(js_perf_proto_funcs));
JS_DefinePropertyValueStr(ctx, performance, "timeOrigin",
JS_NewFloat64(ctx, ctx->time_origin),
JS_PROP_ENUMERABLE);
JS_DefinePropertyValueStr(ctx, ctx->global_obj, "performance",
JS_DupValue(ctx, performance),
JS_PROP_ENUMERABLE);
JS_FreeValue(ctx, performance);
}

View file

@ -365,6 +365,7 @@ void JS_AddIntrinsicMapSet(JSContext *ctx);
void JS_AddIntrinsicTypedArrays(JSContext *ctx); void JS_AddIntrinsicTypedArrays(JSContext *ctx);
void JS_AddIntrinsicPromise(JSContext *ctx); void JS_AddIntrinsicPromise(JSContext *ctx);
void JS_AddIntrinsicBigInt(JSContext *ctx); void JS_AddIntrinsicBigInt(JSContext *ctx);
void JS_AddPerformance(JSContext *ctx);
JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val, JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv); int argc, JSValueConst *argv);
@ -960,6 +961,7 @@ typedef struct JSCFunctionListEntry {
/* Note: c++ does not like nested designators */ /* Note: c++ does not like nested designators */
#define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } } #define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_DEF2(name, length, func1, prop_flags) { name, prop_flags, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } } #define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } } #define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } } #define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }