Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,38 @@ commands:
node_version:
description: "version of node to install"
type: string
canary:
description: "install a canary version of node"
type: boolean
default: false
steps:
- run:
name: setup node v<< parameters.node_version >>
command: |
cd $HOME
version=<< parameters.node_version >>
wget https://nodejs.org/dist/v${version}/node-v${version}-linux-x64.tar.xz
if [[ << parameters.canary >> == "true" ]]; then
wget https://nodejs.org/download/v8-canary/v${version}/node-v${version}-linux-x64.tar.xz
else
wget https://nodejs.org/dist/v${version}/node-v${version}-linux-x64.tar.xz
fi
tar xf node-v${version}-linux-x64.tar.xz
echo "NODE_JS = [os.path.expanduser('~/node-v${version}-linux-x64/bin/node')]" >> ~/emsdk/.emscripten
echo "JS_ENGINES = [NODE_JS]" >> ~/emsdk/.emscripten
echo "if os.path.exists(V8_ENGINE[0]): JS_ENGINES.append(V8_ENGINE)" >> ~/emsdk/.emscripten
cat ~/emsdk/.emscripten
echo "export PATH=\"$HOME/node-v${version}-linux-x64/bin:\$PATH\"" >> $BASH_ENV
install-latest-node:
install-node-latest:
description: "install latest version of node"
steps:
- install-node-version:
node_version: "19.0.0"
install-node-canary:
description: "install canary version of node"
steps:
- install-node-version:
node_version: "20.0.0-v8-canary202302081604228b65"
canary: true
install-v8:
description: "install v8 using jsvu"
steps:
Expand Down Expand Up @@ -532,7 +546,7 @@ jobs:
- run-tests:
title: "wasm64l"
test_targets: "wasm64l"
- install-latest-node
- install-node-canary
- run-tests:
title: "wasm64"
test_targets: "wasm64"
Expand All @@ -548,6 +562,14 @@ jobs:
command: git submodule update --init
- pip-install
- build
- install-node-canary
- run-tests:
title: "selected subset"
test_targets: "
other.test_gen_struct_info
other.test_native_call_before_init
other.test_node_unhandled_rejection
core2.test_hello_world"
# Run some basic tests with the minimum version of node that we currently
# support.
- install-node-version:
Expand All @@ -562,7 +584,7 @@ jobs:
# Run a few test with the most recent version of node
# In particular we have some tests that require node flags on older
# versions of node but not with the most recent version.
- install-latest-node
- install-node-latest
- run-tests:
# Run tests that on older versions of node would require flags, but
# those flags should not be injected on newer versions.
Expand Down
7 changes: 7 additions & 0 deletions emscripten.py
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,13 @@ def create_wasm64_wrappers(metadata):
'__cxa_can_catch': '_ppp',
'_wasmfs_write_file': '_ppp',
'__dl_seterr': '_pp',
'_emscripten_run_in_main_runtime_thread_js': '___p_',
'_emscripten_proxy_execute_task_queue': '_p',
'_emscripten_thread_exit': '_p',
'_emscripten_thread_init': '_p____',
'_emscripten_thread_free_data': '_p',
'_emscripten_dlsync_self_async': '_p',
'_emscripten_proxy_dlsync_async': '_pp',
}

wasm64_wrappers = '''
Expand Down
6 changes: 3 additions & 3 deletions src/library_dylink.js
Original file line number Diff line number Diff line change
Expand Up @@ -1081,11 +1081,11 @@ var LibraryDylink = {
var filename = UTF8ToString({{{ makeGetValue('handle', C_STRUCTS.dso.name, '*') }}});
dlSetError('Could not load dynamic lib: ' + filename + '\n' + e);
{{{ runtimeKeepalivePop() }}}
callUserCallback(function () { {{{ makeDynCall('vii', 'onerror') }}}(handle, user_data); });
callUserCallback(function () { {{{ makeDynCall('vpp', 'onerror') }}}(handle, user_data); });
}
function successCallback() {
{{{ runtimeKeepalivePop() }}}
callUserCallback(function () { {{{ makeDynCall('vii', 'onsuccess') }}}(handle, user_data); });
callUserCallback(function () { {{{ makeDynCall('vpp', 'onsuccess') }}}(handle, user_data); });
}

{{{ runtimeKeepalivePush() }}}
Expand Down Expand Up @@ -1115,7 +1115,7 @@ var LibraryDylink = {

// void* dlsym(void* handle, const char* symbol);
_dlsym_js__deps: ['$dlSetError', '$getFunctionAddress', '$addFunction'],
_dlsym_js__sig: 'ppp',
_dlsym_js__sig: 'pppp',
_dlsym_js: function(handle, symbol, symbolIndex) {
// void *dlsym(void *restrict handle, const char *restrict name);
// http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html
Expand Down
8 changes: 6 additions & 2 deletions src/library_pthread.js
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,7 @@ var LibraryPThread = {
worker.pthread_ptr = 0;
},

__emscripten_thread_cleanup__sig: 'vp',
__emscripten_thread_cleanup: function(thread) {
// Called when a thread needs to be cleaned up so it can be reused.
// A thread is considered reusable when it either returns from its
Expand Down Expand Up @@ -708,7 +709,7 @@ var LibraryPThread = {
// allocations from __pthread_create_js we could also remove this.
__pthread_create_js__noleakcheck: true,
#endif
__pthread_create_js__sig: 'iiiii',
__pthread_create_js__sig: 'ipppp',
__pthread_create_js__deps: ['$spawnThread', 'pthread_self', '$pthreadCreateProxied',
#if OFFSCREENCANVAS_SUPPORT
'malloc',
Expand Down Expand Up @@ -975,6 +976,7 @@ var LibraryPThread = {

emscripten_receive_on_main_thread_js_callArgs: '=[]',

emscripten_receive_on_main_thread_js__sig: 'diip',
emscripten_receive_on_main_thread_js__deps: [
'emscripten_proxy_to_main_thread_js',
'emscripten_receive_on_main_thread_js_callArgs'],
Expand Down Expand Up @@ -1078,7 +1080,7 @@ var LibraryPThread = {
// *ThreadMain(void *arg) form, or try linking with the Emscripten linker
// flag -sEMULATE_FUNCTION_POINTER_CASTS to add in emulation for this x86
// ABI extension.
var result = {{{ makeDynCall('ii', 'ptr') }}}(arg);
var result = {{{ makeDynCall('pp', 'ptr') }}}(arg);
#if STACK_OVERFLOW_CHECK
checkStackCookie();
#endif
Expand All @@ -1097,6 +1099,7 @@ var LibraryPThread = {
},

#if MAIN_MODULE
_emscripten_thread_exit_joinable__sig: 'vp',
_emscripten_thread_exit_joinable: function(thread) {
// Called when a thread exits and is joinable. We mark these threads
// as finished, which means that are in state where are no longer actually
Expand Down Expand Up @@ -1207,6 +1210,7 @@ var LibraryPThread = {
},

_emscripten_notify_task_queue__deps: ['$executeNotifiedProxyingQueue'],
_emscripten_notify_task_queue__sig: 'vpppp',
_emscripten_notify_task_queue: function(targetThreadId, currThreadId, mainThreadId, queue) {
if (targetThreadId == currThreadId) {
setTimeout(() => executeNotifiedProxyingQueue(queue));
Expand Down
3 changes: 0 additions & 3 deletions system/lib/compiler-rt/stack_limits.S
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,6 @@ emscripten_wasm_worker_initialize:
local.get 0
.globaltype __tls_size, PTR, immutable
global.get __tls_size
#ifdef __wasm64__
i64.extend_i32_u
#endif
PTR.add
PTR.const 0xf
PTR.add
Expand Down
2 changes: 1 addition & 1 deletion system/lib/libc/musl/arch/emscripten/bits/alltypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ typedef struct {
union {
int __i[10];
volatile int __vi[10];
unsigned __s[10];
unsigned long __s[10];
} __u;
#ifdef __EMSCRIPTEN__
// For canvas transfer implementation in Emscripten, use an extra control field
Expand Down
4 changes: 2 additions & 2 deletions system/lib/pthread/library_pthread.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ static void _do_call(void* arg) {
break;
case EM_PROXIED_JS_FUNCTION:
q->returnValue.d =
emscripten_receive_on_main_thread_js((int)(size_t)q->functionPtr, q->args[0].i, &q->args[1].d);
emscripten_receive_on_main_thread_js((intptr_t)q->functionPtr, q->args[0].i, &q->args[1].d);
break;
case EM_FUNC_SIG_V:
((em_func_v)q->functionPtr)();
Expand Down Expand Up @@ -435,7 +435,7 @@ double _emscripten_run_in_main_runtime_thread_js(int index, int num_args, int64_
c->calleeDelete = 1-sync;
c->functionEnum = EM_PROXIED_JS_FUNCTION;
// Index not needed to ever be more than 32-bit.
c->functionPtr = (void*)(size_t)index;
c->functionPtr = (void*)(intptr_t)index;
assert(num_args+1 <= EM_QUEUED_JS_CALL_MAX_ARGS);
// The types are only known at runtime in these calls, so we store values that
// must be able to contain any valid JS value, including a 64-bit BigInt if
Expand Down
2 changes: 0 additions & 2 deletions test/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,6 @@ def setup_node_pthreads(self):
self.require_node()
self.set_setting('USE_PTHREADS')
self.emcc_args += ['-Wno-pthreads-mem-growth']
if self.get_setting('MEMORY64'):
self.skipTest('node pthreads not yet supported with MEMORY64')
if self.get_setting('MINIMAL_RUNTIME'):
self.skipTest('node pthreads not yet supported with MINIMAL_RUNTIME')
self.js_engines = [config.NODE_JS]
Expand Down
2 changes: 1 addition & 1 deletion test/core/pthread/exceptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ pthread_t thread[NUM_THREADS];

void CreateThread(int i)
{
int rc = pthread_create(&thread[i], nullptr, ThreadMain, (void*)i);
int rc = pthread_create(&thread[i], nullptr, ThreadMain, (void*)(intptr_t)i);
assert(rc == 0);
}

Expand Down
2 changes: 1 addition & 1 deletion test/core/pthread/test_pthread_dlopen_many.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ int main() {
// start a bunch of threads while holding the lock
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
pthread_create(&threads[i], NULL, thread_main, (void*)i);
pthread_create(&threads[i], NULL, thread_main, (void*)(intptr_t)i);
}

// busy wait until all threads are running
Expand Down
21 changes: 9 additions & 12 deletions test/pthread/test_pthread_cleanup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,22 @@
#include <assert.h>
#include <unistd.h>
#include <errno.h>
#include <emscripten/em_asm.h>

// Stores/encodes the results of calling to cleanup handlers.
long cleanupState = 1;
int32_t cleanup_state = 1;

static void cleanup_handler1(void *arg) {
cleanupState <<= 2;
cleanup_state <<= 2;
// Perform non-commutative arithmetic to a global var that encodes the cleanup stack order ops.
cleanupState *= (long)arg;
EM_ASM(console.log('Called clean-up handler 1 with arg ' + $0), arg);
//printf("Called clean-up handler 1 with arg %d\n", (long)arg);
cleanup_state *= (intptr_t)arg;
printf("Called clean-up handler 1 with arg %p (state=%d)\n", arg, cleanup_state);
}

static void cleanup_handler2(void *arg) {
cleanupState <<= 3;
cleanup_state <<= 3;
// Perform non-commutative arithmetic to a global var that encodes the cleanup stack order ops.
cleanupState *= (long)arg;
EM_ASM(console.log('Called clean-up handler 2 with arg ' + $0), arg);
//printf("Called clean-up handler 2 with arg %d\n", (long)arg);
cleanup_state *= (intptr_t)arg;
printf("Called clean-up handler 2 with arg %p (state=%d)\n", arg, cleanup_state);
}

static void *thread_start1(void *arg) {
Expand Down Expand Up @@ -83,8 +80,8 @@ int main() {
// s = pthread_cancel(thr[3]);
// assert(s == 0);
pthread_cleanup_pop(1);
printf("Cleanup state variable: %ld\n", cleanupState);
assert(cleanupState == 907640832);
printf("Cleanup state variable: %d\n", cleanup_state);
assert(cleanup_state == 907640832);

pthread_cleanup_pop(1);
exit(EXIT_SUCCESS);
Expand Down
8 changes: 4 additions & 4 deletions test/pthread/test_pthread_thread_local_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ int main()
{
if (thread[i])
{
int status;
intptr_t status;
int rc = pthread_join(thread[i], (void**)&status);
assert(rc == 0);
printf("Main: Joined thread idx %ld with status %d\n", i, status);
printf("Main: Joined thread idx %ld with status %lu\n", i, status);
assert(status == 0);
thread[i] = 0;
if (numThreadsToCreate > 0)
Expand All @@ -102,10 +102,10 @@ int main()
{
if (thread[i])
{
int status = 1;
intptr_t status = 1;
int rc = pthread_join(thread[i], (void**)&status);
assert(rc == 0);
printf("Main: Joined thread idx %d with status %d\n", i, status);
printf("Main: Joined thread idx %d with status %lu\n", i, status);
assert(status == 0);
}
}
Expand Down
2 changes: 2 additions & 0 deletions test/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -9284,6 +9284,7 @@ def test_pthread_create_embind_stack_check(self):
self.do_run_in_out_file_test('core/pthread/create.cpp')

@node_pthreads
@no_wasm64('MEMORY64 does not yet support exceptions')
def test_pthread_exceptions(self):
self.set_setting('PTHREAD_POOL_SIZE', 2)
self.set_setting('EXIT_RUNTIME')
Expand Down Expand Up @@ -9395,6 +9396,7 @@ def test_pthread_dylink_entry_point(self, args):

@needs_dylink
@node_pthreads
@no_wasm64('MEMORY64 does not yet support exceptions')
def test_pthread_dylink_exceptions(self):
self.emcc_args.append('-Wno-experimental')
self.set_setting('USE_PTHREADS')
Expand Down
2 changes: 1 addition & 1 deletion tools/extract_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def parse_function_for_memory_inits(module, func_index, offset_map):
call_targets = []
while module.tell() != end:
opcode = OpCode(module.read_byte())
if opcode in (OpCode.END, OpCode.NOP, OpCode.DROP, OpCode.I32_ADD):
if opcode in (OpCode.END, OpCode.NOP, OpCode.DROP, OpCode.I32_ADD, OpCode.I64_ADD):
pass
elif opcode in (OpCode.BLOCK,):
module.read_type()
Expand Down
2 changes: 1 addition & 1 deletion tools/webassembly.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class OpCode(IntEnum):
F32_CONST = 0x43
F64_CONST = 0x44
I32_ADD = 0x6a
I64_ADD = 0x6b
I64_ADD = 0x7c
REF_NULL = 0xd0
ATOMIC_PREFIX = 0xfe
MEMORY_PREFIX = 0xfc
Expand Down