Skip to content

Commit e574e6c

Browse files
committed
Don't use _Thread_local in run-test262.c
Allows building with tcc and old gcc versions again.
1 parent 163b1d4 commit e574e6c

File tree

3 files changed

+50
-43
lines changed

3 files changed

+50
-43
lines changed

.github/workflows/ci.yml

+4-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ jobs:
140140
make cxxtest
141141
142142
- name: test
143-
if: ${{ matrix.config.configType != 'examples' && matrix.config.configType != 'tcc' }}
143+
if: ${{ matrix.config.configType != 'examples' }}
144144
run: |
145145
make test
146146
@@ -191,6 +191,9 @@ jobs:
191191
- name: stats
192192
run: |
193193
./build/qjs -qd
194+
- name: test
195+
run: |
196+
make test
194197
195198
windows-msvc:
196199
runs-on: windows-latest

CMakeLists.txt

+1-8
Original file line numberDiff line numberDiff line change
@@ -289,14 +289,7 @@ endif()
289289
# Test262 runner
290290
#
291291

292-
if(EMSCRIPTEN
293-
OR CMAKE_C_COMPILER_ID STREQUAL "TinyCC"
294-
OR (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 5))
295-
# Empty. run-test262 uses pthreads, sorry Windows users.
296-
# tcc and gcc 4.8 don't understand _Thread_local, whereas I
297-
# don't understand why people still use 4.8 in this day and age
298-
# but hey, here we are.
299-
else()
292+
if(NOT EMSCRIPTEN)
300293
add_executable(run-test262
301294
run-test262.c
302295
)

run-test262.c

+45-34
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ typedef pthread_t js_thread_t;
5050

5151
#define CMD_NAME "run-test262"
5252

53+
typedef struct {
54+
js_mutex_t agent_mutex;
55+
js_cond_t agent_cond;
56+
/* list of Test262Agent.link */
57+
struct list_head agent_list;
58+
js_mutex_t report_mutex;
59+
/* list of AgentReport.link */
60+
struct list_head report_list;
61+
int async_done;
62+
} ThreadLocalStorage;
63+
5364
typedef struct namelist_t {
5465
char **array;
5566
int count;
@@ -97,7 +108,6 @@ int start_index, stop_index;
97108
int test_excluded;
98109
_Atomic int test_count, test_failed, test_skipped;
99110
_Atomic int new_errors, changed_errors, fixed_errors;
100-
_Thread_local int async_done;
101111

102112
void warning(const char *, ...) __attribute__((__format__(__printf__, 1, 2)));
103113
void fatal(int, const char *, ...) __attribute__((__format__(__printf__, 2, 3)));
@@ -443,6 +453,7 @@ static void enumerate_tests(const char *path)
443453
static JSValue js_print_262(JSContext *ctx, JSValue this_val,
444454
int argc, JSValue *argv)
445455
{
456+
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
446457
int i;
447458
const char *str;
448459

@@ -451,9 +462,9 @@ static JSValue js_print_262(JSContext *ctx, JSValue this_val,
451462
if (!str)
452463
return JS_EXCEPTION;
453464
if (!strcmp(str, "Test262:AsyncTestComplete")) {
454-
async_done++;
465+
tls->async_done++;
455466
} else if (strstart(str, "Test262:AsyncTestFailure", NULL)) {
456-
async_done = 2; /* force an error */
467+
tls->async_done = 2; /* force an error */
457468
}
458469
if (outfile) {
459470
if (i != 0)
@@ -552,28 +563,16 @@ static long cpu_count(void)
552563
#endif
553564
}
554565

555-
typedef struct {
556-
js_mutex_t agent_mutex;
557-
js_cond_t agent_cond;
558-
/* list of Test262Agent.link */
559-
struct list_head agent_list;
560-
js_mutex_t report_mutex;
561-
/* list of AgentReport.link */
562-
struct list_head report_list;
563-
} ThreadLocalStorage;
564-
565566
static void init_thread_local_storage(ThreadLocalStorage *p)
566567
{
567568
js_mutex_init(&p->agent_mutex);
568569
js_cond_init(&p->agent_cond);
569570
init_list_head(&p->agent_list);
570571
js_mutex_init(&p->report_mutex);
571572
init_list_head(&p->report_list);
573+
p->async_done = 0;
572574
}
573575

574-
// points to parent thread's TLS in agent threads
575-
static _Thread_local ThreadLocalStorage *tls;
576-
577576
typedef struct {
578577
struct list_head link;
579578
js_thread_t tid;
@@ -597,17 +596,20 @@ static void add_helpers(JSContext *ctx);
597596

598597
static void *agent_start(void *arg)
599598
{
600-
Test262Agent *agent = arg;
599+
ThreadLocalStorage *tls;
600+
Test262Agent *agent;
601601
JSRuntime *rt;
602602
JSContext *ctx;
603603
JSValue ret_val;
604604
int ret;
605605

606+
agent = arg;
606607
tls = agent->tls; // shares thread-local storage with parent thread
607608
rt = JS_NewRuntime();
608609
if (rt == NULL) {
609610
fatal(1, "JS_NewRuntime failure");
610611
}
612+
JS_SetRuntimeOpaque(rt, tls);
611613
ctx = JS_NewContext(rt);
612614
if (ctx == NULL) {
613615
JS_FreeRuntime(rt);
@@ -674,6 +676,7 @@ static void *agent_start(void *arg)
674676
static JSValue js_agent_start(JSContext *ctx, JSValue this_val,
675677
int argc, JSValue *argv)
676678
{
679+
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
677680
const char *script;
678681
Test262Agent *agent;
679682

@@ -697,6 +700,7 @@ static JSValue js_agent_start(JSContext *ctx, JSValue this_val,
697700

698701
static void js_agent_free(JSContext *ctx)
699702
{
703+
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
700704
struct list_head *el, *el1;
701705
Test262Agent *agent;
702706

@@ -719,7 +723,7 @@ static JSValue js_agent_leaving(JSContext *ctx, JSValue this_val,
719723
return JS_UNDEFINED;
720724
}
721725

722-
static BOOL is_broadcast_pending(void)
726+
static BOOL is_broadcast_pending(ThreadLocalStorage *tls)
723727
{
724728
struct list_head *el;
725729
Test262Agent *agent;
@@ -734,6 +738,7 @@ static BOOL is_broadcast_pending(void)
734738
static JSValue js_agent_broadcast(JSContext *ctx, JSValue this_val,
735739
int argc, JSValue *argv)
736740
{
741+
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
737742
JSValue sab = argv[0];
738743
struct list_head *el;
739744
Test262Agent *agent;
@@ -765,7 +770,7 @@ static JSValue js_agent_broadcast(JSContext *ctx, JSValue this_val,
765770
}
766771
js_cond_broadcast(&tls->agent_cond);
767772

768-
while (is_broadcast_pending()) {
773+
while (is_broadcast_pending(tls)) {
769774
js_cond_wait(&tls->agent_cond, &tls->agent_mutex);
770775
}
771776
js_mutex_unlock(&tls->agent_mutex);
@@ -819,6 +824,7 @@ static JSValue js_agent_monotonicNow(JSContext *ctx, JSValue this_val,
819824
static JSValue js_agent_getReport(JSContext *ctx, JSValue this_val,
820825
int argc, JSValue *argv)
821826
{
827+
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
822828
AgentReport *rep;
823829
JSValue ret;
824830

@@ -843,6 +849,7 @@ static JSValue js_agent_getReport(JSContext *ctx, JSValue this_val,
843849
static JSValue js_agent_report(JSContext *ctx, JSValue this_val,
844850
int argc, JSValue *argv)
845851
{
852+
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
846853
const char *str;
847854
AgentReport *rep;
848855

@@ -1338,6 +1345,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
13381345
const char *error_type, int eval_flags, int is_async,
13391346
int *msec)
13401347
{
1348+
ThreadLocalStorage *tls = JS_GetRuntimeOpaque(JS_GetRuntime(ctx));
13411349
JSValue res_val, exception_val;
13421350
int ret, error_line, pos, pos_line;
13431351
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,
13521360

13531361
/* a module evaluation returns a promise */
13541362
ret_promise = ((eval_flags & JS_EVAL_TYPE_MODULE) != 0);
1355-
async_done = 0; /* counter of "Test262:AsyncTestComplete" messages */
1363+
tls->async_done = 0; /* counter of "Test262:AsyncTestComplete" messages */
13561364

13571365
start = get_clock_ms();
13581366
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,
13731381
} else if (ret == 0) {
13741382
if (is_async) {
13751383
/* test if the test called $DONE() once */
1376-
if (async_done != 1) {
1384+
if (tls->async_done != 1) {
13771385
res_val = JS_ThrowTypeError(ctx, "$DONE() not called");
13781386
} else {
13791387
res_val = JS_UNDEFINED;
@@ -1721,10 +1729,10 @@ JSContext *JS_NewCustomContext(JSRuntime *rt)
17211729
return ctx;
17221730
}
17231731

1724-
int run_test_buf(const char *filename, char *harness, namelist_t *ip,
1725-
char *buf, size_t buf_len, const char* error_type,
1726-
int eval_flags, BOOL is_negative, BOOL is_async,
1727-
BOOL can_block, int *msec)
1732+
int run_test_buf(ThreadLocalStorage *tls, const char *filename, char *harness,
1733+
namelist_t *ip, char *buf, size_t buf_len,
1734+
const char* error_type, int eval_flags, BOOL is_negative,
1735+
BOOL is_async, BOOL can_block, int *msec)
17281736
{
17291737
JSRuntime *rt;
17301738
JSContext *ctx;
@@ -1734,6 +1742,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
17341742
if (rt == NULL) {
17351743
fatal(1, "JS_NewRuntime failure");
17361744
}
1745+
JS_SetRuntimeOpaque(rt, tls);
17371746
js_std_init_handlers(rt);
17381747
ctx = JS_NewCustomContext(rt);
17391748
if (ctx == NULL) {
@@ -1782,7 +1791,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
17821791
return ret;
17831792
}
17841793

1785-
int run_test(const char *filename, int *msec)
1794+
int run_test(ThreadLocalStorage *tls, const char *filename, int *msec)
17861795
{
17871796
char harnessbuf[1024];
17881797
char *harness;
@@ -1943,12 +1952,12 @@ int run_test(const char *filename, int *msec)
19431952
}
19441953
ret = 0;
19451954
if (use_nostrict) {
1946-
ret = run_test_buf(filename, harness, ip, buf, buf_len,
1955+
ret = run_test_buf(tls, filename, harness, ip, buf, buf_len,
19471956
error_type, eval_flags, is_negative, is_async,
19481957
can_block, msec);
19491958
}
19501959
if (use_strict) {
1951-
ret |= run_test_buf(filename, harness, ip, buf, buf_len,
1960+
ret |= run_test_buf(tls, filename, harness, ip, buf, buf_len,
19521961
error_type, eval_flags | JS_EVAL_FLAG_STRICT,
19531962
is_negative, is_async, can_block, msec);
19541963
}
@@ -1961,7 +1970,8 @@ int run_test(const char *filename, int *msec)
19611970
}
19621971

19631972
/* run a test when called by test262-harness+eshost */
1964-
int run_test262_harness_test(const char *filename, BOOL is_module)
1973+
int run_test262_harness_test(ThreadLocalStorage *tls, const char *filename,
1974+
BOOL is_module)
19651975
{
19661976
JSRuntime *rt;
19671977
JSContext *ctx;
@@ -1977,6 +1987,7 @@ int run_test262_harness_test(const char *filename, BOOL is_module)
19771987
if (rt == NULL) {
19781988
fatal(1, "JS_NewRuntime failure");
19791989
}
1990+
JS_SetRuntimeOpaque(rt, tls);
19801991
ctx = JS_NewContext(rt);
19811992
if (ctx == NULL) {
19821993
JS_FreeRuntime(rt);
@@ -2072,18 +2083,18 @@ int include_exclude_or_skip(int i) // naming is hard...
20722083

20732084
void *run_test_dir_list(void *arg)
20742085
{
2086+
ThreadLocalStorage tls_s, *tls = &tls_s;
20752087
const char *p;
20762088
int i, msec;
20772089

2078-
tls = &(ThreadLocalStorage){};
20792090
init_thread_local_storage(tls);
20802091

20812092
for (i = (uintptr_t)arg; i < test_list.count; i += nthreads) {
20822093
if (INCLUDE != include_exclude_or_skip(i))
20832094
continue;
20842095
p = test_list.array[i];
20852096
msec = 0;
2086-
run_test(p, &msec);
2097+
run_test(tls, p, &msec);
20872098
if (verbose > 1 || (slow_test_threshold && msec >= slow_test_threshold))
20882099
fprintf(stderr, "%s (%d ms)\n", p, msec);
20892100
}
@@ -2124,6 +2135,7 @@ char *get_opt_arg(const char *option, char *arg)
21242135

21252136
int main(int argc, char **argv)
21262137
{
2138+
ThreadLocalStorage tls_s, *tls = &tls_s;
21272139
int i, optind;
21282140
BOOL is_dir_list;
21292141
BOOL only_check_errors = FALSE;
@@ -2134,7 +2146,6 @@ int main(int argc, char **argv)
21342146

21352147
js_std_set_worker_new_context_func(JS_NewCustomContext);
21362148

2137-
tls = &(ThreadLocalStorage){};
21382149
init_thread_local_storage(tls);
21392150
js_mutex_init(&stats_mutex);
21402151

@@ -2209,7 +2220,7 @@ int main(int argc, char **argv)
22092220
help();
22102221

22112222
if (is_test262_harness) {
2212-
return run_test262_harness_test(argv[optind], is_module);
2223+
return run_test262_harness_test(tls, argv[optind], is_module);
22132224
}
22142225

22152226
nthreads = max_int(nthreads, 1);
@@ -2276,7 +2287,7 @@ int main(int argc, char **argv)
22762287
} else {
22772288
while (optind < argc) {
22782289
int msec = 0;
2279-
run_test(argv[optind++], &msec);
2290+
run_test(tls, argv[optind++], &msec);
22802291
}
22812292
}
22822293

0 commit comments

Comments
 (0)