Skip to content

Commit cb45fd0

Browse files
jgonetmat-hek
authored andcommitted
Add popcorn WASM
1 parent 2b19c00 commit cb45fd0

File tree

7 files changed

+411
-25
lines changed

7 files changed

+411
-25
lines changed

src/platforms/emscripten/src/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ add_subdirectory(../../../libAtomVM libAtomVM)
2828
target_link_libraries(AtomVM PUBLIC libAtomVM)
2929
target_compile_options(libAtomVM PUBLIC -O3 -fno-exceptions -fno-rtti -pthread -sINLINING_LIMIT -sUSE_ZLIB=1)
3030
target_compile_definitions(libAtomVM PRIVATE WITH_ZLIB)
31-
target_link_options(AtomVM PRIVATE -sEXPORTED_RUNTIME_METHODS=ccall -sUSE_ZLIB=1 -O3 -pthread -sFETCH -lwebsocket.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/atomvm.pre.js)
32-
31+
target_link_options(AtomVM PRIVATE -sEXPORTED_RUNTIME_METHODS=ccall,cwrap,stringToNewUTF8,FS -sEMULATE_FUNCTION_POINTER_CASTS=1 -sEXPORTED_FUNCTIONS=_malloc,_cast,_call,_next_tracked_object_key,_main -sEXPORT_ES6=1 -sUSE_ZLIB=1 -O3 -pthread -sFETCH -lwebsocket.js --pre-js ${CMAKE_CURRENT_SOURCE_DIR}/atomvm.pre.js)
32+
set(CMAKE_EXECUTABLE_SUFFIX ".mjs")
3333
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
3434
target_link_options(AtomVM PRIVATE -sASSERTIONS=2 -sSAFE_HEAP -sSTACK_OVERFLOW_CHECK)
3535
endif()

src/platforms/emscripten/src/atomvm.pre.js

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,58 @@
1717
*
1818
* SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
1919
*/
20-
Module['cast'] = function(name, message) {
21-
ccall("cast", 'void', ['string', 'string'], [name, message]);
20+
Module["cast"] = function (name, message) {
21+
ccall("cast", "void", ["string", "string"], [name, message]);
2222
};
23-
Module['call'] = async function(name, message) {
24-
const promiseId = ccall("call", 'integer', ['string', 'string'], [name, message]);
25-
return promiseMap.get(promiseId).promise;
23+
Module["call"] = async function (name, message) {
24+
const promiseId = ccall(
25+
"call",
26+
"integer",
27+
["string", "string"],
28+
[name, message],
29+
);
30+
return promiseMap.get(promiseId).promise;
2631
};
32+
Module["nextTrackedObjectKey"] = function () {
33+
return ccall("next_tracked_object_key", "integer", [], []);
34+
};
35+
Module["trackedObjectsMap"] = new Map();
36+
Module["onTrackedObjectDelete"] = (key) => {
37+
Module["trackedObjectsMap"].delete(key);
38+
};
39+
Module["onGetTrackedObjects"] = (keys) => {
40+
const getTrackedObject = (key) => Module["trackedObjectsMap"].get(key);
41+
return keys.map(getTrackedObject);
42+
};
43+
Module["onRunTrackedJs"] = (scriptString, isDebug) => {
44+
const trackValue = (value) => {
45+
const key = Module["nextTrackedObjectKey"]();
46+
Module["trackedObjectsMap"].set(key, value);
47+
return key;
48+
};
49+
50+
let result;
51+
try {
52+
const indirectEval = eval;
53+
result = indirectEval(scriptString);
54+
} catch (_e) {
55+
return null;
56+
}
57+
isDebug && ensureValidResult(result);
58+
return result?.map(trackValue) ?? [];
59+
};
60+
61+
function ensureValidResult(result) {
62+
const isIndex = (k) => typeof k === "number";
63+
64+
if (result === null) {
65+
return;
66+
}
67+
if (Array.isArray(result) && keys.every(isIndex)) {
68+
return;
69+
}
70+
71+
const message =
72+
"Evaluated script returned invalid value. Expected number array or null";
73+
throw new Error(message);
74+
}

src/platforms/emscripten/src/lib/emscripten_sys.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,21 @@ struct EmscriptenMessageUnregisterHTMLEvent
108108
struct HTMLEventUserDataResource *rsrc;
109109
};
110110

111+
struct TrackedObjectResource
112+
{
113+
int32_t key;
114+
};
115+
111116
struct EmscriptenPlatformData
112117
{
113118
pthread_mutex_t poll_mutex;
114119
pthread_cond_t poll_cond;
115120
struct ListHead messages;
121+
atomic_size_t next_tracked_object_key;
116122
ErlNifResourceType *promise_resource_type;
117123
ErlNifResourceType *htmlevent_user_data_resource_type;
118124
ErlNifResourceType *websocket_resource_type;
125+
ErlNifResourceType *tracked_object_resource_type;
119126

120127
#ifndef AVM_NO_SMP
121128
Mutex *entropy_mutex;
@@ -134,6 +141,7 @@ void sys_enqueue_emscripten_cast_message(GlobalContext *glb, const char *target,
134141
em_promise_t sys_enqueue_emscripten_call_message(GlobalContext *glb, const char *target, const char *message);
135142
void sys_enqueue_emscripten_htmlevent_message(GlobalContext *glb, int32_t target_pid, term message, term user_data, HeapFragment *heap);
136143
void sys_enqueue_emscripten_unregister_htmlevent_message(GlobalContext *glb, struct HTMLEventUserDataResource *rsrc);
144+
size_t sys_get_next_tracked_object_key(GlobalContext *glb);
137145
void sys_promise_resolve_int_and_destroy(em_promise_t promise, em_promise_result_t result, int value);
138146
void sys_promise_resolve_str_and_destroy(em_promise_t promise, em_promise_result_t result, int value);
139147

src/platforms/emscripten/src/lib/platform_defaultatoms.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ X(WEBSOCKET_ATOM, "\x9", "websocket")
2424
X(WEBSOCKET_OPEN_ATOM, "\xE", "websocket_open")
2525
X(WEBSOCKET_CLOSE_ATOM, "\xF", "websocket_close")
2626
X(WEBSOCKET_ERROR_ATOM, "\xF", "websocket_error")
27+
X(BADVALUE_ATOM, "\x8", "badvalue")

0 commit comments

Comments
 (0)