-
Notifications
You must be signed in to change notification settings - Fork 1
/
asmloader.js
139 lines (137 loc) · 5.05 KB
/
asmloader.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
A simple ASM.js loader
*/
Module = {};
Module.noInitialRun = true;
Module.noExitRuntime = true;
Module.print = function(text) {
postMessage({'type': 'io', 'args': {'file': 'stdout', 'data': text}});
};
Module.printErr = function(text) {
postMessage({'type': 'io', 'args': {'file': 'stderr', 'data': text}});
};
Module.environment = 'WORKER';
function stringToArrayBuffer(string) {
var enc = new TextEncoder("utf-8");
return enc.encode(string);
}
onmessage = function(e) {
var type = e.data.type;
var args = e.data.args;
var id = e.data.id;
if (type == 'fs') {
// file system operations
if (args.operation == 'mkdir') {
try {
FS.mkdir(args.path);
postMessage({'type': 'ack', 'args': {'success': true, 'id': id}});
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
} else if (args.operation == 'write') {
try {
console.log(args);
FS.writeFile(args.path, new Uint8Array(args.data), args.opts);
postMessage({'type': 'ack', 'args': {'success': true, 'id': id}});
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
} else if (args.operation == 'read') {
try {
var buffer = FS.readFile(args.path, args.opts);
postMessage({'type': 'ack', 'args': {'success': true, 'id': id, 'msg': buffer}});
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
} else if (args.operation == 'rm') {
try {
FS.unlink(args.path);
postMessage({'type': 'ack', 'args': {'success': true, 'id': id}});
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
} else if (args.operation == 'rmdir') {
try {
FS.rmdir(args.path);
postMessage({'type': 'ack', 'args': {'success': true, 'id': id}});
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
} else if (args.operation == 'readdir') {
try {
var result = FS.readdir(args.path);
postMessage({'type': 'ack', 'args': {'success': true, 'id': id, 'msg': result}})
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
} else if (args.operation == 'cwd') {
try {
var result = FS.cwd();
postMessage({'type': 'ack', 'args': {'success': true, 'id': id, 'msg': result}})
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
} else if (args.operation == 'chdir') {
try {
var result = FS.chdir(args.path);
postMessage({'type': 'ack', 'args': {'success': true, 'id': id, 'msg': result}})
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
}
} else if (type == 'exec') {
try {
var argv = args.argv;
var argvBufs = [];
var total = 0;
var argvOffsets = [];
for (var i = 0; i < argv.length; i++) {
var arg = argv[i];
var buf = stringToArrayBuffer(arg);
argvBufs.push(buf);
argvOffsets.push(total);
total += buf.length + 1;
}
var argvStrPtr = Module._malloc(total);
for (var i = 0; i < argvBufs.length; i++) {
var buf = argvBufs[i];
var arr = new Uint8Array(Module.HEAPU8.buffer, argvStrPtr + argvOffsets[i], buf.buffer.byteLength + 1);
arr.set(buf);
arr[buf.buffer.byteLength] = 0;
}
// allocate buffer for pointer to pointers
var argvPtr = Module._malloc(argvOffsets.length * 4);
var argvBuf = new Uint32Array(argvOffsets.length * 4);
for (var i = 0; i < argvBuf.length; i++) {
argvBuf[i] = argvStrPtr + argvOffsets[i];
}
// copy ptrs to heap
var argvHeap = new Uint32Array(Module.HEAPU8.buffer, argvPtr, argvBuf.buffer.byteLength);
argvHeap.set(argvBuf);
var exitStatus = 0;
try {
exitStatus = Module._main(argv.length, argvPtr);
} catch (error) {
if (error.name == 'ExitStatus') {
exitStatus = error.status;
} else {
throw error;
}
}
Module._free(argvStrPtr);
Module._free(argvPtr);
postMessage({'type': 'ack', 'args': {'success': true, 'id': id, 'msg': exitStatus}});
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
} else if (type == 'load') {
try {
Module.onRuntimeInitialized = function(){
postMessage({'type': 'ack', 'args': {'success': true, 'id': id}});
}; // wait until everything is loaded...
importScripts(args.path);
} catch (error) {
postMessage({'type': 'ack', 'args': {'success': false, 'error': error.toString(), 'id': id}});
}
}
}