mirror of
https://github.com/DoneJS-Runtime/quickjs-done-nextgen.git
synced 2025-01-09 17:43:15 +00:00
Don't use _Thread_local in run-test262.c
Allows building with tcc and old gcc versions again.
This commit is contained in:
parent
f641d4ff18
commit
b29332697b
3 changed files with 47 additions and 43 deletions
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
|
@ -140,7 +140,7 @@ jobs:
|
||||||
make cxxtest
|
make cxxtest
|
||||||
|
|
||||||
- name: test
|
- name: test
|
||||||
if: ${{ matrix.config.configType != 'examples' && matrix.config.configType != 'tcc' }}
|
if: ${{ matrix.config.configType != 'examples' }}
|
||||||
run: |
|
run: |
|
||||||
make test
|
make test
|
||||||
|
|
||||||
|
|
|
@ -289,14 +289,7 @@ endif()
|
||||||
# Test262 runner
|
# Test262 runner
|
||||||
#
|
#
|
||||||
|
|
||||||
if(EMSCRIPTEN
|
if(NOT EMSCRIPTEN)
|
||||||
OR CMAKE_C_COMPILER_ID STREQUAL "TinyCC"
|
|
||||||
OR (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 5))
|
|
||||||
# Empty. run-test262 uses pthreads, sorry Windows users.
|
|
||||||
# tcc and gcc 4.8 don't understand _Thread_local, whereas I
|
|
||||||
# don't understand why people still use 4.8 in this day and age
|
|
||||||
# but hey, here we are.
|
|
||||||
else()
|
|
||||||
add_executable(run-test262
|
add_executable(run-test262
|
||||||
run-test262.c
|
run-test262.c
|
||||||
)
|
)
|
||||||
|
|
|
@ -50,6 +50,17 @@ typedef pthread_t js_thread_t;
|
||||||
|
|
||||||
#define CMD_NAME "run-test262"
|
#define CMD_NAME "run-test262"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
js_mutex_t agent_mutex;
|
||||||
|
js_cond_t agent_cond;
|
||||||
|
/* list of Test262Agent.link */
|
||||||
|
struct list_head agent_list;
|
||||||
|
js_mutex_t report_mutex;
|
||||||
|
/* list of AgentReport.link */
|
||||||
|
struct list_head report_list;
|
||||||
|
int async_done;
|
||||||
|
} ThreadLocalStorage;
|
||||||
|
|
||||||
typedef struct namelist_t {
|
typedef struct namelist_t {
|
||||||
char **array;
|
char **array;
|
||||||
int count;
|
int count;
|
||||||
|
@ -97,7 +108,6 @@ int start_index, stop_index;
|
||||||
int test_excluded;
|
int test_excluded;
|
||||||
_Atomic int test_count, test_failed, test_skipped;
|
_Atomic int test_count, test_failed, test_skipped;
|
||||||
_Atomic int new_errors, changed_errors, fixed_errors;
|
_Atomic int new_errors, changed_errors, fixed_errors;
|
||||||
_Thread_local int async_done;
|
|
||||||
|
|
||||||
void warning(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));
|
void warning(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));
|
||||||
void fatal(int, const char *, ...) __attribute__((__format__(__printf__, 2, 3)));
|
void fatal(int, const char *, ...) __attribute__((__format__(__printf__, 2, 3)));
|
||||||
|
@ -443,6 +453,7 @@ static void enumerate_tests(const char *path)
|
||||||
static JSValue js_print_262(JSContext *ctx, JSValue this_val,
|
static JSValue js_print_262(JSContext *ctx, JSValue this_val,
|
||||||
int argc, JSValue *argv)
|
int argc, JSValue *argv)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
|
||||||
int i;
|
int i;
|
||||||
const char *str;
|
const char *str;
|
||||||
|
|
||||||
|
@ -451,9 +462,9 @@ static JSValue js_print_262(JSContext *ctx, JSValue this_val,
|
||||||
if (!str)
|
if (!str)
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
if (!strcmp(str, "Test262:AsyncTestComplete")) {
|
if (!strcmp(str, "Test262:AsyncTestComplete")) {
|
||||||
async_done++;
|
tls->async_done++;
|
||||||
} else if (strstart(str, "Test262:AsyncTestFailure", NULL)) {
|
} else if (strstart(str, "Test262:AsyncTestFailure", NULL)) {
|
||||||
async_done = 2; /* force an error */
|
tls->async_done = 2; /* force an error */
|
||||||
}
|
}
|
||||||
if (outfile) {
|
if (outfile) {
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
|
@ -552,16 +563,6 @@ static long cpu_count(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
js_mutex_t agent_mutex;
|
|
||||||
js_cond_t agent_cond;
|
|
||||||
/* list of Test262Agent.link */
|
|
||||||
struct list_head agent_list;
|
|
||||||
js_mutex_t report_mutex;
|
|
||||||
/* list of AgentReport.link */
|
|
||||||
struct list_head report_list;
|
|
||||||
} ThreadLocalStorage;
|
|
||||||
|
|
||||||
static void init_thread_local_storage(ThreadLocalStorage *p)
|
static void init_thread_local_storage(ThreadLocalStorage *p)
|
||||||
{
|
{
|
||||||
js_mutex_init(&p->agent_mutex);
|
js_mutex_init(&p->agent_mutex);
|
||||||
|
@ -569,11 +570,9 @@ static void init_thread_local_storage(ThreadLocalStorage *p)
|
||||||
init_list_head(&p->agent_list);
|
init_list_head(&p->agent_list);
|
||||||
js_mutex_init(&p->report_mutex);
|
js_mutex_init(&p->report_mutex);
|
||||||
init_list_head(&p->report_list);
|
init_list_head(&p->report_list);
|
||||||
|
p->async_done = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// points to parent thread's TLS in agent threads
|
|
||||||
static _Thread_local ThreadLocalStorage *tls;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
js_thread_t tid;
|
js_thread_t tid;
|
||||||
|
@ -597,17 +596,20 @@ static void add_helpers(JSContext *ctx);
|
||||||
|
|
||||||
static void *agent_start(void *arg)
|
static void *agent_start(void *arg)
|
||||||
{
|
{
|
||||||
Test262Agent *agent = arg;
|
ThreadLocalStorage *tls;
|
||||||
|
Test262Agent *agent;
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
JSContext *ctx;
|
JSContext *ctx;
|
||||||
JSValue ret_val;
|
JSValue ret_val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
agent = arg;
|
||||||
tls = agent->tls; // shares thread-local storage with parent thread
|
tls = agent->tls; // shares thread-local storage with parent thread
|
||||||
rt = JS_NewRuntime();
|
rt = JS_NewRuntime();
|
||||||
if (rt == NULL) {
|
if (rt == NULL) {
|
||||||
fatal(1, "JS_NewRuntime failure");
|
fatal(1, "JS_NewRuntime failure");
|
||||||
}
|
}
|
||||||
|
JS_SetRuntimeOpaque(rt, tls);
|
||||||
ctx = JS_NewContext(rt);
|
ctx = JS_NewContext(rt);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
JS_FreeRuntime(rt);
|
JS_FreeRuntime(rt);
|
||||||
|
@ -674,6 +676,7 @@ static void *agent_start(void *arg)
|
||||||
static JSValue js_agent_start(JSContext *ctx, JSValue this_val,
|
static JSValue js_agent_start(JSContext *ctx, JSValue this_val,
|
||||||
int argc, JSValue *argv)
|
int argc, JSValue *argv)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
|
||||||
const char *script;
|
const char *script;
|
||||||
Test262Agent *agent;
|
Test262Agent *agent;
|
||||||
|
|
||||||
|
@ -697,6 +700,7 @@ static JSValue js_agent_start(JSContext *ctx, JSValue this_val,
|
||||||
|
|
||||||
static void js_agent_free(JSContext *ctx)
|
static void js_agent_free(JSContext *ctx)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
|
||||||
struct list_head *el, *el1;
|
struct list_head *el, *el1;
|
||||||
Test262Agent *agent;
|
Test262Agent *agent;
|
||||||
|
|
||||||
|
@ -719,7 +723,7 @@ static JSValue js_agent_leaving(JSContext *ctx, JSValue this_val,
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL is_broadcast_pending(void)
|
static BOOL is_broadcast_pending(ThreadLocalStorage *tls)
|
||||||
{
|
{
|
||||||
struct list_head *el;
|
struct list_head *el;
|
||||||
Test262Agent *agent;
|
Test262Agent *agent;
|
||||||
|
@ -734,6 +738,7 @@ static BOOL is_broadcast_pending(void)
|
||||||
static JSValue js_agent_broadcast(JSContext *ctx, JSValue this_val,
|
static JSValue js_agent_broadcast(JSContext *ctx, JSValue this_val,
|
||||||
int argc, JSValue *argv)
|
int argc, JSValue *argv)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
|
||||||
JSValue sab = argv[0];
|
JSValue sab = argv[0];
|
||||||
struct list_head *el;
|
struct list_head *el;
|
||||||
Test262Agent *agent;
|
Test262Agent *agent;
|
||||||
|
@ -765,7 +770,7 @@ static JSValue js_agent_broadcast(JSContext *ctx, JSValue this_val,
|
||||||
}
|
}
|
||||||
js_cond_broadcast(&tls->agent_cond);
|
js_cond_broadcast(&tls->agent_cond);
|
||||||
|
|
||||||
while (is_broadcast_pending()) {
|
while (is_broadcast_pending(tls)) {
|
||||||
js_cond_wait(&tls->agent_cond, &tls->agent_mutex);
|
js_cond_wait(&tls->agent_cond, &tls->agent_mutex);
|
||||||
}
|
}
|
||||||
js_mutex_unlock(&tls->agent_mutex);
|
js_mutex_unlock(&tls->agent_mutex);
|
||||||
|
@ -819,6 +824,7 @@ static JSValue js_agent_monotonicNow(JSContext *ctx, JSValue this_val,
|
||||||
static JSValue js_agent_getReport(JSContext *ctx, JSValue this_val,
|
static JSValue js_agent_getReport(JSContext *ctx, JSValue this_val,
|
||||||
int argc, JSValue *argv)
|
int argc, JSValue *argv)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
|
||||||
AgentReport *rep;
|
AgentReport *rep;
|
||||||
JSValue ret;
|
JSValue ret;
|
||||||
|
|
||||||
|
@ -843,6 +849,7 @@ static JSValue js_agent_getReport(JSContext *ctx, JSValue this_val,
|
||||||
static JSValue js_agent_report(JSContext *ctx, JSValue this_val,
|
static JSValue js_agent_report(JSContext *ctx, JSValue this_val,
|
||||||
int argc, JSValue *argv)
|
int argc, JSValue *argv)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
|
||||||
const char *str;
|
const char *str;
|
||||||
AgentReport *rep;
|
AgentReport *rep;
|
||||||
|
|
||||||
|
@ -1338,6 +1345,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
|
||||||
const char *error_type, int eval_flags, int is_async,
|
const char *error_type, int eval_flags, int is_async,
|
||||||
int *msec)
|
int *msec)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
|
||||||
JSValue res_val, exception_val;
|
JSValue res_val, exception_val;
|
||||||
int ret, error_line, pos, pos_line;
|
int ret, error_line, pos, pos_line;
|
||||||
BOOL is_error, has_error_line, ret_promise;
|
BOOL is_error, has_error_line, ret_promise;
|
||||||
|
@ -1352,7 +1360,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
|
||||||
|
|
||||||
/* a module evaluation returns a promise */
|
/* a module evaluation returns a promise */
|
||||||
ret_promise = ((eval_flags & JS_EVAL_TYPE_MODULE) != 0);
|
ret_promise = ((eval_flags & JS_EVAL_TYPE_MODULE) != 0);
|
||||||
async_done = 0; /* counter of "Test262:AsyncTestComplete" messages */
|
tls->async_done = 0; /* counter of "Test262:AsyncTestComplete" messages */
|
||||||
|
|
||||||
start = get_clock_ms();
|
start = get_clock_ms();
|
||||||
res_val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
|
res_val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
|
||||||
|
@ -1373,7 +1381,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
|
||||||
} else if (ret == 0) {
|
} else if (ret == 0) {
|
||||||
if (is_async) {
|
if (is_async) {
|
||||||
/* test if the test called $DONE() once */
|
/* test if the test called $DONE() once */
|
||||||
if (async_done != 1) {
|
if (tls->async_done != 1) {
|
||||||
res_val = JS_ThrowTypeError(ctx, "$DONE() not called");
|
res_val = JS_ThrowTypeError(ctx, "$DONE() not called");
|
||||||
} else {
|
} else {
|
||||||
res_val = JS_UNDEFINED;
|
res_val = JS_UNDEFINED;
|
||||||
|
@ -1721,10 +1729,10 @@ JSContext *JS_NewCustomContext(JSRuntime *rt)
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_test_buf(const char *filename, char *harness, namelist_t *ip,
|
int run_test_buf(ThreadLocalStorage *tls, const char *filename, char *harness,
|
||||||
char *buf, size_t buf_len, const char* error_type,
|
namelist_t *ip, char *buf, size_t buf_len,
|
||||||
int eval_flags, BOOL is_negative, BOOL is_async,
|
const char* error_type, int eval_flags, BOOL is_negative,
|
||||||
BOOL can_block, int *msec)
|
BOOL is_async, BOOL can_block, int *msec)
|
||||||
{
|
{
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
JSContext *ctx;
|
JSContext *ctx;
|
||||||
|
@ -1734,6 +1742,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
|
||||||
if (rt == NULL) {
|
if (rt == NULL) {
|
||||||
fatal(1, "JS_NewRuntime failure");
|
fatal(1, "JS_NewRuntime failure");
|
||||||
}
|
}
|
||||||
|
JS_SetRuntimeOpaque(rt, tls);
|
||||||
js_std_init_handlers(rt);
|
js_std_init_handlers(rt);
|
||||||
ctx = JS_NewCustomContext(rt);
|
ctx = JS_NewCustomContext(rt);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
|
@ -1782,7 +1791,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_test(const char *filename, int *msec)
|
int run_test(ThreadLocalStorage *tls, const char *filename, int *msec)
|
||||||
{
|
{
|
||||||
char harnessbuf[1024];
|
char harnessbuf[1024];
|
||||||
char *harness;
|
char *harness;
|
||||||
|
@ -1943,12 +1952,12 @@ int run_test(const char *filename, int *msec)
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
if (use_nostrict) {
|
if (use_nostrict) {
|
||||||
ret = run_test_buf(filename, harness, ip, buf, buf_len,
|
ret = run_test_buf(tls, filename, harness, ip, buf, buf_len,
|
||||||
error_type, eval_flags, is_negative, is_async,
|
error_type, eval_flags, is_negative, is_async,
|
||||||
can_block, msec);
|
can_block, msec);
|
||||||
}
|
}
|
||||||
if (use_strict) {
|
if (use_strict) {
|
||||||
ret |= run_test_buf(filename, harness, ip, buf, buf_len,
|
ret |= run_test_buf(tls, filename, harness, ip, buf, buf_len,
|
||||||
error_type, eval_flags | JS_EVAL_FLAG_STRICT,
|
error_type, eval_flags | JS_EVAL_FLAG_STRICT,
|
||||||
is_negative, is_async, can_block, msec);
|
is_negative, is_async, can_block, msec);
|
||||||
}
|
}
|
||||||
|
@ -1961,7 +1970,8 @@ int run_test(const char *filename, int *msec)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* run a test when called by test262-harness+eshost */
|
/* run a test when called by test262-harness+eshost */
|
||||||
int run_test262_harness_test(const char *filename, BOOL is_module)
|
int run_test262_harness_test(ThreadLocalStorage *tls, const char *filename,
|
||||||
|
BOOL is_module)
|
||||||
{
|
{
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
JSContext *ctx;
|
JSContext *ctx;
|
||||||
|
@ -1977,6 +1987,7 @@ int run_test262_harness_test(const char *filename, BOOL is_module)
|
||||||
if (rt == NULL) {
|
if (rt == NULL) {
|
||||||
fatal(1, "JS_NewRuntime failure");
|
fatal(1, "JS_NewRuntime failure");
|
||||||
}
|
}
|
||||||
|
JS_SetRuntimeOpaque(rt, tls);
|
||||||
ctx = JS_NewContext(rt);
|
ctx = JS_NewContext(rt);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
JS_FreeRuntime(rt);
|
JS_FreeRuntime(rt);
|
||||||
|
@ -2072,10 +2083,10 @@ int include_exclude_or_skip(int i) // naming is hard...
|
||||||
|
|
||||||
void *run_test_dir_list(void *arg)
|
void *run_test_dir_list(void *arg)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage tls_s, *tls = &tls_s;
|
||||||
const char *p;
|
const char *p;
|
||||||
int i, msec;
|
int i, msec;
|
||||||
|
|
||||||
tls = &(ThreadLocalStorage){};
|
|
||||||
init_thread_local_storage(tls);
|
init_thread_local_storage(tls);
|
||||||
|
|
||||||
for (i = (uintptr_t)arg; i < test_list.count; i += nthreads) {
|
for (i = (uintptr_t)arg; i < test_list.count; i += nthreads) {
|
||||||
|
@ -2083,7 +2094,7 @@ void *run_test_dir_list(void *arg)
|
||||||
continue;
|
continue;
|
||||||
p = test_list.array[i];
|
p = test_list.array[i];
|
||||||
msec = 0;
|
msec = 0;
|
||||||
run_test(p, &msec);
|
run_test(tls, p, &msec);
|
||||||
if (verbose > 1 || (slow_test_threshold && msec >= slow_test_threshold))
|
if (verbose > 1 || (slow_test_threshold && msec >= slow_test_threshold))
|
||||||
fprintf(stderr, "%s (%d ms)\n", p, msec);
|
fprintf(stderr, "%s (%d ms)\n", p, msec);
|
||||||
}
|
}
|
||||||
|
@ -2124,6 +2135,7 @@ char *get_opt_arg(const char *option, char *arg)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
ThreadLocalStorage tls_s, *tls = &tls_s;
|
||||||
int i, optind;
|
int i, optind;
|
||||||
BOOL is_dir_list;
|
BOOL is_dir_list;
|
||||||
BOOL only_check_errors = FALSE;
|
BOOL only_check_errors = FALSE;
|
||||||
|
@ -2134,7 +2146,6 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
||||||
|
|
||||||
tls = &(ThreadLocalStorage){};
|
|
||||||
init_thread_local_storage(tls);
|
init_thread_local_storage(tls);
|
||||||
js_mutex_init(&stats_mutex);
|
js_mutex_init(&stats_mutex);
|
||||||
|
|
||||||
|
@ -2209,7 +2220,7 @@ int main(int argc, char **argv)
|
||||||
help();
|
help();
|
||||||
|
|
||||||
if (is_test262_harness) {
|
if (is_test262_harness) {
|
||||||
return run_test262_harness_test(argv[optind], is_module);
|
return run_test262_harness_test(tls, argv[optind], is_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
nthreads = max_int(nthreads, 1);
|
nthreads = max_int(nthreads, 1);
|
||||||
|
@ -2276,7 +2287,7 @@ int main(int argc, char **argv)
|
||||||
} else {
|
} else {
|
||||||
while (optind < argc) {
|
while (optind < argc) {
|
||||||
int msec = 0;
|
int msec = 0;
|
||||||
run_test(argv[optind++], &msec);
|
run_test(tls, argv[optind++], &msec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue