mirror of
https://github.com/DoneJS-Runtime/quickjs-done-nextgen.git
synced 2025-01-09 17:43:15 +00:00
Update qjs.c
This commit is contained in:
parent
78a733fdc3
commit
02c03f6a01
1 changed files with 250 additions and 402 deletions
638
qjs.c
638
qjs.c
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* QuickJS stand alone interpreter
|
* QuickJS stand alone interpreter
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2024 Sneed Group
|
||||||
* Copyright (c) 2017-2021 Fabrice Bellard
|
* Copyright (c) 2017-2021 Fabrice Bellard
|
||||||
* Copyright (c) 2017-2021 Charlie Gordon
|
* Copyright (c) 2017-2021 Charlie Gordon
|
||||||
*
|
*
|
||||||
|
@ -28,81 +29,26 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <malloc/malloc.h>
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#include <malloc.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cutils.h"
|
#include "cutils.h"
|
||||||
#include "quickjs.h"
|
|
||||||
#include "quickjs-libc.h"
|
#include "quickjs-libc.h"
|
||||||
|
|
||||||
#ifdef QJS_USE_MIMALLOC
|
|
||||||
#include <mimalloc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const uint8_t qjsc_repl[];
|
extern const uint8_t qjsc_repl[];
|
||||||
extern const uint32_t qjsc_repl_size;
|
extern const uint32_t qjsc_repl_size;
|
||||||
extern const uint8_t qjsc_standalone[];
|
#ifdef CONFIG_BIGNUM
|
||||||
extern const uint32_t qjsc_standalone_size;
|
extern const uint8_t qjsc_qjscalc[];
|
||||||
|
extern const uint32_t qjsc_qjscalc_size;
|
||||||
// Must match standalone.js
|
static int bignum_ext;
|
||||||
#define TRAILER_SIZE 12
|
#endif
|
||||||
static const char trailer_magic[] = "quickjs2";
|
|
||||||
static const int trailer_magic_size = sizeof(trailer_magic) - 1;
|
|
||||||
static const int trailer_size = TRAILER_SIZE;
|
|
||||||
|
|
||||||
static int qjs__argc;
|
|
||||||
static char **qjs__argv;
|
|
||||||
|
|
||||||
|
|
||||||
static BOOL is_standalone(const char *exe)
|
|
||||||
{
|
|
||||||
FILE *exe_f = fopen(exe, "rb");
|
|
||||||
if (!exe_f)
|
|
||||||
return FALSE;
|
|
||||||
if (fseek(exe_f, -trailer_size, SEEK_END) < 0)
|
|
||||||
goto fail;
|
|
||||||
uint8_t buf[TRAILER_SIZE];
|
|
||||||
if (fread(buf, 1, trailer_size, exe_f) != trailer_size)
|
|
||||||
goto fail;
|
|
||||||
fclose(exe_f);
|
|
||||||
return !memcmp(buf, trailer_magic, trailer_magic_size);
|
|
||||||
fail:
|
|
||||||
fclose(exe_f);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue load_standalone_module(JSContext *ctx)
|
|
||||||
{
|
|
||||||
JSModuleDef *m;
|
|
||||||
JSValue obj, val;
|
|
||||||
obj = JS_ReadObject(ctx, qjsc_standalone, qjsc_standalone_size, JS_READ_OBJ_BYTECODE);
|
|
||||||
if (JS_IsException(obj))
|
|
||||||
goto exception;
|
|
||||||
assert(JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE);
|
|
||||||
if (JS_ResolveModule(ctx, obj) < 0) {
|
|
||||||
JS_FreeValue(ctx, obj);
|
|
||||||
goto exception;
|
|
||||||
}
|
|
||||||
js_module_set_import_meta(ctx, obj, FALSE, TRUE);
|
|
||||||
val = JS_EvalFunction(ctx, JS_DupValue(ctx, obj));
|
|
||||||
val = js_std_await(ctx, val);
|
|
||||||
|
|
||||||
if (JS_IsException(val)) {
|
|
||||||
JS_FreeValue(ctx, obj);
|
|
||||||
exception:
|
|
||||||
js_std_dump_error(ctx);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
JS_FreeValue(ctx, val);
|
|
||||||
|
|
||||||
m = JS_VALUE_GET_PTR(obj);
|
|
||||||
JS_FreeValue(ctx, obj);
|
|
||||||
return JS_GetModuleNamespace(ctx, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
|
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
|
||||||
const char *filename, int eval_flags)
|
const char *filename, int eval_flags)
|
||||||
|
@ -119,7 +65,6 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
|
||||||
js_module_set_import_meta(ctx, val, TRUE, TRUE);
|
js_module_set_import_meta(ctx, val, TRUE, TRUE);
|
||||||
val = JS_EvalFunction(ctx, val);
|
val = JS_EvalFunction(ctx, val);
|
||||||
}
|
}
|
||||||
val = js_std_await(ctx, val);
|
|
||||||
} else {
|
} else {
|
||||||
val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
|
val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
|
||||||
}
|
}
|
||||||
|
@ -138,6 +83,7 @@ static int eval_file(JSContext *ctx, const char *filename, int module)
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
int ret, eval_flags;
|
int ret, eval_flags;
|
||||||
size_t buf_len;
|
size_t buf_len;
|
||||||
|
|
||||||
buf = js_load_file(ctx, &buf_len, filename);
|
buf = js_load_file(ctx, &buf_len, filename);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
perror(filename);
|
perror(filename);
|
||||||
|
@ -145,7 +91,7 @@ static int eval_file(JSContext *ctx, const char *filename, int module)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module < 0) {
|
if (module < 0) {
|
||||||
module = (js__has_suffix(filename, ".mjs") ||
|
module = (has_suffix(filename, ".mjs") ||
|
||||||
JS_DetectModule((const char *)buf, buf_len));
|
JS_DetectModule((const char *)buf, buf_len));
|
||||||
}
|
}
|
||||||
if (module)
|
if (module)
|
||||||
|
@ -153,64 +99,38 @@ static int eval_file(JSContext *ctx, const char *filename, int module)
|
||||||
else
|
else
|
||||||
eval_flags = JS_EVAL_TYPE_GLOBAL;
|
eval_flags = JS_EVAL_TYPE_GLOBAL;
|
||||||
|
|
||||||
|
//POLYFILLS FOR QJS FILES BEGIN
|
||||||
|
const char *pf = "globalThis.global = globalThis;\n"
|
||||||
|
"global.console.error = console.log\n"
|
||||||
|
"global.console.warn = console.log\n"
|
||||||
|
"globalThis.breakFunction = () => { throw new Error('Function Break'); };\n"
|
||||||
|
"\n"
|
||||||
|
"if (typeof os !== 'undefined') {\n"
|
||||||
|
" globalThis.sleep = os.sleep;\n"
|
||||||
|
" async function setTimeout2(func, ms) {globalThis.clearTimeout = false; await sleep(ms); if (!clearTimeout) { func(); } }\n"
|
||||||
|
" globalThis.setTimeout = setTimeout2\n"
|
||||||
|
"} else {\n"
|
||||||
|
" console.error('os is not defined.');\n"
|
||||||
|
"}\n"
|
||||||
|
"\n"
|
||||||
|
"if (typeof std !== 'undefined') {\n"
|
||||||
|
" globalThis.urlGet = std.urlGet;\n"
|
||||||
|
" globalThis.loadFile = std.loadFile;\n"
|
||||||
|
" globalThis.printf = console.log;\n"
|
||||||
|
" globalThis.evalFile = std.loadScript;\n"
|
||||||
|
" globalThis.require = std.loadScript;\n"
|
||||||
|
" globalThis.getURL = std.urlGet;\n"
|
||||||
|
"} else {\n"
|
||||||
|
" console.error('std is not defined.');\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
|
eval_buf(ctx, pf, strlen(pf), "<input>", JS_EVAL_TYPE_MODULE);
|
||||||
ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
|
ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
|
||||||
js_free(ctx, buf);
|
js_free(ctx, buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t parse_limit(const char *arg) {
|
|
||||||
char *p;
|
|
||||||
unsigned long unit = 1024; /* default to traditional KB */
|
|
||||||
double d = strtod(arg, &p);
|
|
||||||
|
|
||||||
if (p == arg) {
|
|
||||||
fprintf(stderr, "Invalid limit: %s\n", arg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p) {
|
|
||||||
switch (*p++) {
|
|
||||||
case 'b': case 'B': unit = 1UL << 0; break;
|
|
||||||
case 'k': case 'K': unit = 1UL << 10; break; /* IEC kibibytes */
|
|
||||||
case 'm': case 'M': unit = 1UL << 20; break; /* IEC mebibytes */
|
|
||||||
case 'g': case 'G': unit = 1UL << 30; break; /* IEC gigibytes */
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Invalid limit: %s, unrecognized suffix, only k,m,g are allowed\n", arg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (*p) {
|
|
||||||
fprintf(stderr, "Invalid limit: %s, only one suffix allowed\n", arg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int64_t)(d * unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_gc(JSContext *ctx, JSValue this_val,
|
|
||||||
int argc, JSValue *argv)
|
|
||||||
{
|
|
||||||
JS_RunGC(JS_GetRuntime(ctx));
|
|
||||||
return JS_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_navigator_get_userAgent(JSContext *ctx, JSValue this_val)
|
|
||||||
{
|
|
||||||
char version[32];
|
|
||||||
snprintf(version, sizeof(version), "quickjs-ng/%s", JS_GetVersion());
|
|
||||||
return JS_NewString(ctx, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry navigator_proto_funcs[] = {
|
|
||||||
JS_CGETSET_DEF2("userAgent", js_navigator_get_userAgent, NULL, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE),
|
|
||||||
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Navigator", JS_PROP_CONFIGURABLE),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry global_obj[] = {
|
|
||||||
JS_CFUNC_DEF("gc", 0, js_gc),
|
|
||||||
};
|
|
||||||
|
|
||||||
/* also used to initialize the worker context */
|
/* also used to initialize the worker context */
|
||||||
static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
||||||
{
|
{
|
||||||
|
@ -218,30 +138,26 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
||||||
ctx = JS_NewContext(rt);
|
ctx = JS_NewContext(rt);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return NULL;
|
return NULL;
|
||||||
/* system modules */
|
#ifdef CONFIG_BIGNUM
|
||||||
js_init_module_std(ctx, "qjs:std");
|
if (bignum_ext) {
|
||||||
js_init_module_os(ctx, "qjs:os");
|
JS_AddIntrinsicBigFloat(ctx);
|
||||||
js_init_module_bjson(ctx, "qjs:bjson");
|
JS_AddIntrinsicBigDecimal(ctx);
|
||||||
|
JS_AddIntrinsicOperators(ctx);
|
||||||
JSValue global = JS_GetGlobalObject(ctx);
|
JS_EnableBignumExt(ctx, TRUE);
|
||||||
JS_SetPropertyFunctionList(ctx, global, global_obj, countof(global_obj));
|
|
||||||
JSValue args = JS_NewArray(ctx);
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < qjs__argc; i++) {
|
|
||||||
JS_SetPropertyUint32(ctx, args, i, JS_NewString(ctx, qjs__argv[i]));
|
|
||||||
}
|
}
|
||||||
JS_SetPropertyStr(ctx, global, "execArgv", args);
|
#endif
|
||||||
JS_SetPropertyStr(ctx, global, "argv0", JS_NewString(ctx, qjs__argv[0]));
|
/* system modules */
|
||||||
JSValue navigator_proto = JS_NewObject(ctx);
|
js_init_module_std(ctx, "std");
|
||||||
JS_SetPropertyFunctionList(ctx, navigator_proto, navigator_proto_funcs, countof(navigator_proto_funcs));
|
js_init_module_os(ctx, "os");
|
||||||
JSValue navigator = JS_NewObjectProto(ctx, navigator_proto);
|
|
||||||
JS_DefinePropertyValueStr(ctx, global, "navigator", navigator, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE);
|
|
||||||
JS_FreeValue(ctx, global);
|
|
||||||
JS_FreeValue(ctx, navigator_proto);
|
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#define MALLOC_OVERHEAD 0
|
||||||
|
#else
|
||||||
|
#define MALLOC_OVERHEAD 8
|
||||||
|
#endif
|
||||||
|
|
||||||
struct trace_malloc_data {
|
struct trace_malloc_data {
|
||||||
uint8_t *base;
|
uint8_t *base;
|
||||||
};
|
};
|
||||||
|
@ -252,14 +168,31 @@ static inline unsigned long long js_trace_malloc_ptr_offset(uint8_t *ptr,
|
||||||
return ptr - dp->base;
|
return ptr - dp->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* default memory allocation functions with memory limitation */
|
||||||
|
static size_t js_trace_malloc_usable_size(const void *ptr)
|
||||||
|
{
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
return malloc_size(ptr);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
return _msize((void *)ptr);
|
||||||
|
#elif defined(EMSCRIPTEN)
|
||||||
|
return 0;
|
||||||
|
#elif defined(__linux__)
|
||||||
|
return malloc_usable_size((void *)ptr);
|
||||||
|
#else
|
||||||
|
/* change this to `return 0;` if compilation fails */
|
||||||
|
return malloc_usable_size((void *)ptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
#if defined(_WIN32) && !defined(__clang__)
|
#ifdef _WIN32
|
||||||
/* mingw printf is used */
|
/* mingw printf is used */
|
||||||
__attribute__((format(gnu_printf, 2, 3)))
|
__attribute__((format(gnu_printf, 2, 3)))
|
||||||
#else
|
#else
|
||||||
__attribute__((format(printf, 2, 3)))
|
__attribute__((format(printf, 2, 3)))
|
||||||
#endif
|
#endif
|
||||||
js_trace_malloc_printf(void *opaque, const char *fmt, ...)
|
js_trace_malloc_printf(JSMallocState *s, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int c;
|
int c;
|
||||||
|
@ -274,8 +207,8 @@ __attribute__((format(printf, 2, 3)))
|
||||||
printf("NULL");
|
printf("NULL");
|
||||||
} else {
|
} else {
|
||||||
printf("H%+06lld.%zd",
|
printf("H%+06lld.%zd",
|
||||||
js_trace_malloc_ptr_offset(ptr, opaque),
|
js_trace_malloc_ptr_offset(ptr, s->opaque),
|
||||||
js__malloc_usable_size(ptr));
|
js_trace_malloc_usable_size(ptr));
|
||||||
}
|
}
|
||||||
fmt++;
|
fmt++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -297,83 +230,77 @@ static void js_trace_malloc_init(struct trace_malloc_data *s)
|
||||||
free(s->base = malloc(8));
|
free(s->base = malloc(8));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *js_trace_calloc(void *opaque, size_t count, size_t size)
|
static void *js_trace_malloc(JSMallocState *s, size_t size)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
ptr = calloc(count, size);
|
|
||||||
js_trace_malloc_printf(opaque, "C %zd %zd -> %p\n", count, size, ptr);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *js_trace_malloc(void *opaque, size_t size)
|
/* Do not allocate zero bytes: behavior is platform dependent */
|
||||||
{
|
assert(size != 0);
|
||||||
void *ptr;
|
|
||||||
|
if (unlikely(s->malloc_size + size > s->malloc_limit))
|
||||||
|
return NULL;
|
||||||
ptr = malloc(size);
|
ptr = malloc(size);
|
||||||
js_trace_malloc_printf(opaque, "A %zd -> %p\n", size, ptr);
|
js_trace_malloc_printf(s, "A %zd -> %p\n", size, ptr);
|
||||||
|
if (ptr) {
|
||||||
|
s->malloc_count++;
|
||||||
|
s->malloc_size += js_trace_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
|
||||||
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_trace_free(void *opaque, void *ptr)
|
static void js_trace_free(JSMallocState *s, void *ptr)
|
||||||
{
|
{
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return;
|
return;
|
||||||
js_trace_malloc_printf(opaque, "F %p\n", ptr);
|
|
||||||
|
js_trace_malloc_printf(s, "F %p\n", ptr);
|
||||||
|
s->malloc_count--;
|
||||||
|
s->malloc_size -= js_trace_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *js_trace_realloc(void *opaque, void *ptr, size_t size)
|
static void *js_trace_realloc(JSMallocState *s, void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
js_trace_malloc_printf(opaque, "R %zd %p", size, ptr);
|
size_t old_size;
|
||||||
|
|
||||||
|
if (!ptr) {
|
||||||
|
if (size == 0)
|
||||||
|
return NULL;
|
||||||
|
return js_trace_malloc(s, size);
|
||||||
|
}
|
||||||
|
old_size = js_trace_malloc_usable_size(ptr);
|
||||||
|
if (size == 0) {
|
||||||
|
js_trace_malloc_printf(s, "R %zd %p\n", size, ptr);
|
||||||
|
s->malloc_count--;
|
||||||
|
s->malloc_size -= old_size + MALLOC_OVERHEAD;
|
||||||
|
free(ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (s->malloc_size + size - old_size > s->malloc_limit)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
js_trace_malloc_printf(s, "R %zd %p", size, ptr);
|
||||||
|
|
||||||
ptr = realloc(ptr, size);
|
ptr = realloc(ptr, size);
|
||||||
js_trace_malloc_printf(opaque, " -> %p\n", ptr);
|
js_trace_malloc_printf(s, " -> %p\n", ptr);
|
||||||
|
if (ptr) {
|
||||||
|
s->malloc_size += js_trace_malloc_usable_size(ptr) - old_size;
|
||||||
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const JSMallocFunctions trace_mf = {
|
static const JSMallocFunctions trace_mf = {
|
||||||
js_trace_calloc,
|
|
||||||
js_trace_malloc,
|
js_trace_malloc,
|
||||||
js_trace_free,
|
js_trace_free,
|
||||||
js_trace_realloc,
|
js_trace_realloc,
|
||||||
js__malloc_usable_size
|
js_trace_malloc_usable_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef QJS_USE_MIMALLOC
|
|
||||||
static void *js_mi_calloc(void *opaque, size_t count, size_t size)
|
|
||||||
{
|
|
||||||
return mi_calloc(count, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *js_mi_malloc(void *opaque, size_t size)
|
|
||||||
{
|
|
||||||
return mi_malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void js_mi_free(void *opaque, void *ptr)
|
|
||||||
{
|
|
||||||
if (!ptr)
|
|
||||||
return;
|
|
||||||
mi_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *js_mi_realloc(void *opaque, void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
return mi_realloc(ptr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const JSMallocFunctions mi_mf = {
|
|
||||||
js_mi_calloc,
|
|
||||||
js_mi_malloc,
|
|
||||||
js_mi_free,
|
|
||||||
js_mi_realloc,
|
|
||||||
mi_malloc_usable_size
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PROG_NAME "qjs"
|
#define PROG_NAME "qjs"
|
||||||
|
|
||||||
void help(void)
|
void help(void)
|
||||||
{
|
{
|
||||||
printf("QuickJS-ng DoneJS Edition version %s\n"
|
printf("QuickJS version " CONFIG_VERSION "\n"
|
||||||
"usage: " PROG_NAME " [options] [file [args]]\n"
|
"usage: " PROG_NAME " [options] [file [args]]\n"
|
||||||
"-h --help list options\n"
|
"-h --help list options\n"
|
||||||
"-e --eval EXPR evaluate EXPR\n"
|
"-e --eval EXPR evaluate EXPR\n"
|
||||||
|
@ -381,16 +308,17 @@ void help(void)
|
||||||
"-m --module load as ES6 module (default=autodetect)\n"
|
"-m --module load as ES6 module (default=autodetect)\n"
|
||||||
" --script load as ES6 script (default=autodetect)\n"
|
" --script load as ES6 script (default=autodetect)\n"
|
||||||
"-I --include file include an additional file\n"
|
"-I --include file include an additional file\n"
|
||||||
" --std make 'std', 'os' and 'bjson' available to script\n"
|
" --std make 'std' and 'os' available to the loaded script\n"
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
" --bignum enable the bignum extensions (BigFloat, BigDecimal)\n"
|
||||||
|
" --qjscalc load the QJSCalc runtime (default if invoked as qjscalc)\n"
|
||||||
|
#endif
|
||||||
"-T --trace trace memory allocation\n"
|
"-T --trace trace memory allocation\n"
|
||||||
"-d --dump dump the memory usage stats\n"
|
"-d --dump dump the memory usage stats\n"
|
||||||
"-D --dump-flags flags for dumping debug data (see DUMP_* defines)\n"
|
" --memory-limit n limit the memory usage to 'n' bytes\n"
|
||||||
"-c --compile FILE compile the given JS file as a standalone executable\n"
|
" --stack-size n limit the stack size to 'n' bytes\n"
|
||||||
"-o --out FILE output file for standalone executables\n"
|
" --unhandled-rejection dump unhandled promise rejections\n"
|
||||||
" --exe select the executable to use as the base, defaults to the current one\n"
|
"-q --quit just instantiate the interpreter and quit\n");
|
||||||
" --memory-limit n limit the memory usage to 'n' Kbytes\n"
|
|
||||||
" --stack-size n limit the stack size to 'n' Kbytes\n"
|
|
||||||
"-q --quit just instantiate the interpreter and quit\n", JS_GetVersion());
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,55 +326,48 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
JSContext *ctx;
|
JSContext *ctx;
|
||||||
JSValue ret = JS_UNDEFINED;
|
|
||||||
struct trace_malloc_data trace_data = { NULL };
|
struct trace_malloc_data trace_data = { NULL };
|
||||||
int r = 0;
|
int optind;
|
||||||
int optind = 1;
|
|
||||||
char *compile_file = NULL;
|
|
||||||
char *exe = NULL;
|
|
||||||
char *expr = NULL;
|
char *expr = NULL;
|
||||||
char *dump_flags_str = NULL;
|
|
||||||
char *out = NULL;
|
|
||||||
int standalone = 0;
|
|
||||||
int interactive = 0;
|
int interactive = 0;
|
||||||
int dump_memory = 0;
|
int dump_memory = 0;
|
||||||
int dump_flags = 0;
|
|
||||||
int trace_memory = 0;
|
int trace_memory = 0;
|
||||||
int empty_run = 0;
|
int empty_run = 0;
|
||||||
int module = -1;
|
int module = -1;
|
||||||
int load_std = 0;
|
//int load_std = 0; //we don't need this anymore, we ignore this and always load std libs
|
||||||
|
int dump_unhandled_promise_rejection = 0;
|
||||||
|
size_t memory_limit = 0;
|
||||||
char *include_list[32];
|
char *include_list[32];
|
||||||
int i, include_count = 0;
|
int i, include_count = 0;
|
||||||
int64_t memory_limit = -1;
|
#ifdef CONFIG_BIGNUM
|
||||||
int64_t stack_size = -1;
|
int load_jscalc;
|
||||||
|
#endif
|
||||||
|
size_t stack_size = 0;
|
||||||
|
|
||||||
/* save for later */
|
#ifdef CONFIG_BIGNUM
|
||||||
qjs__argc = argc;
|
/* load jscalc runtime if invoked as 'qjscalc' */
|
||||||
qjs__argv = argv;
|
{
|
||||||
|
const char *p, *exename;
|
||||||
if (is_standalone(argv[0])) {
|
exename = argv[0];
|
||||||
standalone = 1;
|
p = strrchr(exename, '/');
|
||||||
goto start;
|
if (p)
|
||||||
|
exename = p + 1;
|
||||||
|
load_jscalc = !strcmp(exename, "qjscalc");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
dump_flags_str = getenv("QJS_DUMP_FLAGS");
|
|
||||||
dump_flags = dump_flags_str ? strtol(dump_flags_str, NULL, 16) : 0;
|
|
||||||
|
|
||||||
/* cannot use getopt because we want to pass the command line to
|
/* cannot use getopt because we want to pass the command line to
|
||||||
the script */
|
the script */
|
||||||
|
optind = 1;
|
||||||
while (optind < argc && *argv[optind] == '-') {
|
while (optind < argc && *argv[optind] == '-') {
|
||||||
char *arg = argv[optind] + 1;
|
char *arg = argv[optind] + 1;
|
||||||
const char *longopt = "";
|
const char *longopt = "";
|
||||||
char *opt_arg = NULL;
|
|
||||||
/* a single - is not an option, it also stops argument scanning */
|
/* a single - is not an option, it also stops argument scanning */
|
||||||
if (!*arg)
|
if (!*arg)
|
||||||
break;
|
break;
|
||||||
optind++;
|
optind++;
|
||||||
if (*arg == '-') {
|
if (*arg == '-') {
|
||||||
longopt = arg + 1;
|
longopt = arg + 1;
|
||||||
opt_arg = strchr(longopt, '=');
|
|
||||||
if (opt_arg)
|
|
||||||
*opt_arg++ = '\0';
|
|
||||||
arg += strlen(arg);
|
arg += strlen(arg);
|
||||||
/* -- stops argument scanning */
|
/* -- stops argument scanning */
|
||||||
if (!*longopt)
|
if (!*longopt)
|
||||||
|
@ -454,25 +375,23 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
for (; *arg || *longopt; longopt = "") {
|
for (; *arg || *longopt; longopt = "") {
|
||||||
char opt = *arg;
|
char opt = *arg;
|
||||||
if (opt) {
|
if (opt)
|
||||||
arg++;
|
arg++;
|
||||||
if (!opt_arg && *arg)
|
|
||||||
opt_arg = arg;
|
|
||||||
}
|
|
||||||
if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
|
if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
|
||||||
help();
|
help();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (opt == 'e' || !strcmp(longopt, "eval")) {
|
if (opt == 'e' || !strcmp(longopt, "eval")) {
|
||||||
if (!opt_arg) {
|
if (*arg) {
|
||||||
if (optind >= argc) {
|
expr = arg;
|
||||||
fprintf(stderr, "qjs: missing expression for -e\n");
|
break;
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
}
|
||||||
expr = opt_arg;
|
if (optind < argc) {
|
||||||
break;
|
expr = argv[optind++];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "qjs: missing expression for -e\n");
|
||||||
|
exit(2);
|
||||||
}
|
}
|
||||||
if (opt == 'I' || !strcmp(longopt, "include")) {
|
if (opt == 'I' || !strcmp(longopt, "include")) {
|
||||||
if (optind >= argc) {
|
if (optind >= argc) {
|
||||||
|
@ -502,76 +421,47 @@ int main(int argc, char **argv)
|
||||||
dump_memory++;
|
dump_memory++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (opt == 'D' || !strcmp(longopt, "dump-flags")) {
|
|
||||||
dump_flags = opt_arg ? strtol(opt_arg, NULL, 16) : 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (opt == 'T' || !strcmp(longopt, "trace")) {
|
if (opt == 'T' || !strcmp(longopt, "trace")) {
|
||||||
trace_memory++;
|
trace_memory++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(longopt, "std")) {
|
//if (!strcmp(longopt, "std")) {
|
||||||
load_std = 1;
|
//load_std = 1;
|
||||||
|
//continue;
|
||||||
|
//}
|
||||||
|
if (!strcmp(longopt, "unhandled-rejection")) {
|
||||||
|
dump_unhandled_promise_rejection = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
if (!strcmp(longopt, "bignum")) {
|
||||||
|
bignum_ext = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(longopt, "qjscalc")) {
|
||||||
|
load_jscalc = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (opt == 'q' || !strcmp(longopt, "quit")) {
|
if (opt == 'q' || !strcmp(longopt, "quit")) {
|
||||||
empty_run++;
|
empty_run++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(longopt, "memory-limit")) {
|
if (!strcmp(longopt, "memory-limit")) {
|
||||||
if (!opt_arg) {
|
if (optind >= argc) {
|
||||||
if (optind >= argc) {
|
fprintf(stderr, "expecting memory limit");
|
||||||
fprintf(stderr, "expecting memory limit");
|
exit(1);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
}
|
||||||
memory_limit = parse_limit(opt_arg);
|
memory_limit = (size_t)strtod(argv[optind++], NULL);
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(longopt, "stack-size")) {
|
if (!strcmp(longopt, "stack-size")) {
|
||||||
if (!opt_arg) {
|
if (optind >= argc) {
|
||||||
if (optind >= argc) {
|
fprintf(stderr, "expecting stack size");
|
||||||
fprintf(stderr, "expecting stack size");
|
exit(1);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
}
|
||||||
stack_size = parse_limit(opt_arg);
|
stack_size = (size_t)strtod(argv[optind++], NULL);
|
||||||
break;
|
continue;
|
||||||
}
|
|
||||||
if (opt == 'c' || !strcmp(longopt, "compile")) {
|
|
||||||
if (!opt_arg) {
|
|
||||||
if (optind >= argc) {
|
|
||||||
fprintf(stderr, "qjs: missing file for -c\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
|
||||||
compile_file = opt_arg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (opt == 'o' || !strcmp(longopt, "out")) {
|
|
||||||
if (!opt_arg) {
|
|
||||||
if (optind >= argc) {
|
|
||||||
fprintf(stderr, "qjs: missing file for -o\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
|
||||||
out = opt_arg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strcmp(longopt, "exe")) {
|
|
||||||
if (!opt_arg) {
|
|
||||||
if (optind >= argc) {
|
|
||||||
fprintf(stderr, "qjs: missing file for --exe\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
|
||||||
exe = opt_arg;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (opt) {
|
if (opt) {
|
||||||
fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
|
fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
|
||||||
|
@ -582,31 +472,25 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compile_file && !out)
|
#ifdef CONFIG_BIGNUM
|
||||||
help();
|
if (load_jscalc)
|
||||||
|
bignum_ext = 1;
|
||||||
start:
|
#endif
|
||||||
|
|
||||||
if (trace_memory) {
|
if (trace_memory) {
|
||||||
js_trace_malloc_init(&trace_data);
|
js_trace_malloc_init(&trace_data);
|
||||||
rt = JS_NewRuntime2(&trace_mf, &trace_data);
|
rt = JS_NewRuntime2(&trace_mf, &trace_data);
|
||||||
} else {
|
} else {
|
||||||
#ifdef QJS_USE_MIMALLOC
|
|
||||||
rt = JS_NewRuntime2(&mi_mf, NULL);
|
|
||||||
#else
|
|
||||||
rt = JS_NewRuntime();
|
rt = JS_NewRuntime();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (!rt) {
|
if (!rt) {
|
||||||
fprintf(stderr, "qjs: cannot allocate JS runtime\n");
|
fprintf(stderr, "qjs: cannot allocate JS runtime\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
if (memory_limit >= 0)
|
if (memory_limit != 0)
|
||||||
JS_SetMemoryLimit(rt, (size_t)memory_limit);
|
JS_SetMemoryLimit(rt, memory_limit);
|
||||||
if (stack_size >= 0)
|
if (stack_size != 0)
|
||||||
JS_SetMaxStackSize(rt, (size_t)stack_size);
|
JS_SetMaxStackSize(rt, stack_size);
|
||||||
if (dump_flags != 0)
|
|
||||||
JS_SetDumpFlags(rt, dump_flags);
|
|
||||||
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
||||||
js_std_init_handlers(rt);
|
js_std_init_handlers(rt);
|
||||||
ctx = JS_NewCustomContext(rt);
|
ctx = JS_NewCustomContext(rt);
|
||||||
|
@ -618,93 +502,39 @@ start:
|
||||||
/* loader for ES6 modules */
|
/* loader for ES6 modules */
|
||||||
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
||||||
|
|
||||||
/* exit on unhandled promise rejections */
|
if (dump_unhandled_promise_rejection) {
|
||||||
JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker, NULL);
|
JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty_run) {
|
if (!empty_run) {
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
if (load_jscalc) {
|
||||||
|
js_std_eval_binary(ctx, qjsc_qjscalc, qjsc_qjscalc_size, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
js_std_add_helpers(ctx, argc - optind, argv + optind);
|
js_std_add_helpers(ctx, argc - optind, argv + optind);
|
||||||
|
|
||||||
/* make 'std' and 'os' visible to non module code */
|
/* make 'std' and 'os' visible to all code */
|
||||||
if (load_std) {
|
//if (load_std) {
|
||||||
const char *str =
|
const char *str = "import * as std from 'std';\n"
|
||||||
"import * as bjson from 'qjs:bjson';\n"
|
"import * as os from 'os';\n"
|
||||||
"import * as std from 'qjs:std';\n"
|
|
||||||
"import * as os from 'qjs:os';\n"
|
|
||||||
"globalThis.bjson = bjson;\n"
|
|
||||||
"globalThis.std = std;\n"
|
"globalThis.std = std;\n"
|
||||||
"globalThis.os = os;\n";
|
"globalThis.os = os;\n";
|
||||||
eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE);
|
eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE);
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
|
||||||
for(i = 0; i < include_count; i++) {
|
for(i = 0; i < include_count; i++) {
|
||||||
if (eval_file(ctx, include_list[i], 0))
|
if (eval_file(ctx, include_list[i], module))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
//POLYFILLS FOR QJS FILES BEGIN
|
if (expr) {
|
||||||
const char *pf = "globalThis.global = globalThis;\n"
|
|
||||||
"global.console.error = console.log\n"
|
|
||||||
"global.console.warn = console.log\n"
|
|
||||||
"globalThis.breakFunction = () => { throw new Error('Function Break'); };\n"
|
|
||||||
"\n"
|
|
||||||
"if (typeof os !== 'undefined') {\n"
|
|
||||||
" globalThis.sleep = os.sleep;\n"
|
|
||||||
" async function setTimeout2(func, ms) {globalThis.clearTimeout = false; await sleep(ms); if (!clearTimeout) { func(); } }\n"
|
|
||||||
" globalThis.setTimeout = setTimeout2\n"
|
|
||||||
"} else {\n"
|
|
||||||
" console.error('os is not defined.');\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
|
||||||
"if (typeof std !== 'undefined') {\n"
|
|
||||||
" globalThis.urlGet = std.urlGet;\n"
|
|
||||||
" globalThis.loadFile = std.loadFile;\n"
|
|
||||||
" globalThis.doneRequire = std.loadFile;\n"
|
|
||||||
" globalThis.printf = console.log;\n"
|
|
||||||
" globalThis.evalFile = std.loadScript;\n"
|
|
||||||
" globalThis.require = (moduleSpecifier) => import(moduleSpecifier).then(mod => mod.default || mod);\n"
|
|
||||||
" globalThis.stdRequire = globalThis.require;\n"
|
|
||||||
" globalThis.safeGlobals = {} \n"
|
|
||||||
" globalThis.getURL = std.urlGet;\n"
|
|
||||||
"} else {\n"
|
|
||||||
" console.error('std is not defined.');\n"
|
|
||||||
"}\n";
|
|
||||||
eval_buf(ctx, pf, strlen(pf), "<input>", JS_EVAL_TYPE_MODULE);
|
|
||||||
|
|
||||||
if (interactive) {
|
|
||||||
js_std_eval_binary(ctx, qjsc_repl, qjsc_repl_size, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (standalone) {
|
|
||||||
JSValue ns = load_standalone_module(ctx);
|
|
||||||
if (JS_IsException(ns))
|
|
||||||
goto fail;
|
|
||||||
JSValue func = JS_GetPropertyStr(ctx, ns, "runStandalone");
|
|
||||||
JS_FreeValue(ctx, ns);
|
|
||||||
if (JS_IsException(func))
|
|
||||||
goto fail;
|
|
||||||
ret = JS_Call(ctx, func, JS_UNDEFINED, 0, NULL);
|
|
||||||
JS_FreeValue(ctx, func);
|
|
||||||
} else if (compile_file) {
|
|
||||||
JSValue ns = load_standalone_module(ctx);
|
|
||||||
if (JS_IsException(ns))
|
|
||||||
goto fail;
|
|
||||||
JSValue func = JS_GetPropertyStr(ctx, ns, "compileStandalone");
|
|
||||||
JS_FreeValue(ctx, ns);
|
|
||||||
if (JS_IsException(func))
|
|
||||||
goto fail;
|
|
||||||
JSValue args[3];
|
|
||||||
args[0] = JS_NewString(ctx, compile_file);
|
|
||||||
args[1] = JS_NewString(ctx, out);
|
|
||||||
args[2] = JS_NewString(ctx, exe != NULL ? exe : argv[0]);
|
|
||||||
ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args);
|
|
||||||
JS_FreeValue(ctx, func);
|
|
||||||
JS_FreeValue(ctx, args[0]);
|
|
||||||
JS_FreeValue(ctx, args[1]);
|
|
||||||
JS_FreeValue(ctx, args[2]);
|
|
||||||
} else if (expr) {
|
|
||||||
if (eval_buf(ctx, expr, strlen(expr), "<cmdline>", 0))
|
if (eval_buf(ctx, expr, strlen(expr), "<cmdline>", 0))
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (optind >= argc) {
|
} else
|
||||||
|
if (optind >= argc) {
|
||||||
/* interactive mode */
|
/* interactive mode */
|
||||||
interactive = 1;
|
interactive = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -713,21 +543,39 @@ start:
|
||||||
if (eval_file(ctx, filename, module))
|
if (eval_file(ctx, filename, module))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
if (interactive) {
|
||||||
|
js_std_eval_binary(ctx, qjsc_repl, qjsc_repl_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if (standalone || compile_file) {
|
//POLYFILLS FOR QJS REPL BEGIN
|
||||||
if (JS_IsException(ret)) {
|
const char *pf = "globalThis.global = globalThis;\n"
|
||||||
r = 1;
|
"global.console.error = console.log\n"
|
||||||
} else {
|
"global.console.warn = console.log\n"
|
||||||
JS_FreeValue(ctx, ret);
|
"globalThis.breakFunction = () => { throw new Error('Function Break'); };\n"
|
||||||
r = js_std_loop(ctx);
|
"\n"
|
||||||
}
|
"if (typeof os !== 'undefined') {\n"
|
||||||
} else {
|
" globalThis.sleep = os.sleep;\n"
|
||||||
r = js_std_loop(ctx);
|
" async function setTimeout2(func, ms) {globalThis.clearTimeout = false; await sleep(ms); if (!clearTimeout) { func(); } }\n"
|
||||||
}
|
" globalThis.setTimeout = setTimeout2\n"
|
||||||
if (r) {
|
"} else {\n"
|
||||||
js_std_dump_error(ctx);
|
" console.error('os is not defined.');\n"
|
||||||
goto fail;
|
"}\n"
|
||||||
}
|
"\n"
|
||||||
|
"if (typeof std !== 'undefined') {\n"
|
||||||
|
" globalThis.urlGet = std.urlGet;\n"
|
||||||
|
" globalThis.loadFile = std.loadFile;\n"
|
||||||
|
" globalThis.printf = console.log;\n"
|
||||||
|
" globalThis.evalFile = std.loadScript;\n"
|
||||||
|
" globalThis.require = std.loadScript;\n"
|
||||||
|
" globalThis.getURL = std.urlGet;\n"
|
||||||
|
"} else {\n"
|
||||||
|
" console.error('std is not defined.');\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
|
||||||
|
eval_buf(ctx, pf, strlen(pf), "<input>", JS_EVAL_TYPE_MODULE);
|
||||||
|
|
||||||
|
js_std_loop(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_memory) {
|
if (dump_memory) {
|
||||||
|
@ -741,7 +589,7 @@ start:
|
||||||
|
|
||||||
if (empty_run && dump_memory) {
|
if (empty_run && dump_memory) {
|
||||||
clock_t t[5];
|
clock_t t[5];
|
||||||
double best[5] = {0};
|
double best[5];
|
||||||
int i, j;
|
int i, j;
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
t[0] = clock();
|
t[0] = clock();
|
||||||
|
|
Loading…
Reference in a new issue