+26
-25
projects/mojo-wasm/index.html
+26
-25
projects/mojo-wasm/index.html
···
25
25
}
26
26
27
27
try {
28
-
if (ptr + Number(len) > memory.buffer.byteLength) {
28
+
if (ptr + len > memory.buffer.byteLength) {
29
29
console.error("Write would exceed memory bounds");
30
30
return -1;
31
31
}
32
32
33
33
// Read data from memory
34
-
const data = new Uint8Array(memory.buffer, ptr, Number(len));
34
+
const data = new Uint8Array(memory.buffer, Number(ptr), Number(len));
35
35
36
36
// Handle standard file descriptors
37
37
if (fd === 1n) {
···
60
60
};
61
61
62
62
const KGEN_CompilerRT_AlignedAlloc = (align, size) => {
63
-
const alignNum = Number(align);
64
-
const sizeNum = Number(size);
65
-
66
63
// Allocate the memory
67
64
const ptr = heapPointer;
68
-
heapPointer += sizeNum;
65
+
heapPointer += size;
69
66
70
-
console.log("Allocated", sizeNum, "bytes at", ptr, "aligned to", alignNum);
67
+
console.log("Allocated", size, "bytes at", ptr, "aligned to", align);
71
68
return ptr;
72
69
};
73
70
···
81
78
return 1;
82
79
}
83
80
84
-
return 1; // Success
81
+
return 1;
85
82
};
86
83
87
84
const env = {
···
119
116
120
117
const writeStringToMemory = (str) => {
121
118
const bytes = new TextEncoder().encode(str);
122
-
const len = bytes.length;
119
+
const len = BigInt(bytes.length + 1);
123
120
124
121
// Allocate memory for the string plus null terminator
125
-
const ptr = KGEN_CompilerRT_AlignedAlloc(1, len + 1);
122
+
const ptr = KGEN_CompilerRT_AlignedAlloc(1, len);
126
123
if (!ptr) throw new Error("Memory allocation failed");
127
124
128
125
// Write the string to memory
129
126
new Uint8Array(memory.buffer).set(bytes, Number(ptr));
130
127
131
128
// Add null terminator
132
-
new Uint8Array(memory.buffer)[Number(ptr) + len] = 0;
129
+
new Uint8Array(memory.buffer)[Number(ptr + len)] = 0;
133
130
134
-
return { ptr: Number(ptr), len };
131
+
return { ptr, len };
135
132
};
136
133
137
134
const readStringFromMemory = ({ ptr, len }) => {
138
135
// Bounds check
139
-
if (Number(ptr) + len > memory.buffer.byteLength) {
136
+
if (Number(ptr + len) > memory.buffer.byteLength) {
140
137
throw new Error("Read would exceed memory bounds");
141
138
}
142
139
143
140
// Read bytes from memory
144
-
const bytes = new Uint8Array(memory.buffer, Number(ptr), len);
141
+
const bytes = new Uint8Array(memory.buffer, Number(ptr), Number(len - 1n));
145
142
146
143
// Decode to string
147
144
return new TextDecoder().decode(bytes);
···
158
155
initializeEnv(instance);
159
156
160
157
// Test assertions
161
-
const assert = console.assert;
158
+
const assert = (exp1, exp2) =>
159
+
exp1 === exp2
160
+
? undefined
161
+
: console.log(
162
+
`assert: '${exp1}' [${String(exp1).length}] not equal '${exp2}' [${String(exp2).length}]`,
163
+
);
162
164
const fns = instance.exports;
163
165
const alloc = KGEN_CompilerRT_AlignedAlloc;
164
-
const strLen = (str) => new TextEncoder().encode(str).length + 1;
166
+
const strLen = (str) => BigInt(new TextEncoder().encode(str).length + 1);
165
167
166
168
// Add
167
169
() => {
···
192
194
() => {
193
195
const inputString = writeStringToMemory("print-input-string");
194
196
fns.print_input_string(inputString.ptr);
195
-
}
197
+
};
196
198
197
199
// Return
198
200
() => {
199
201
const expectedString = "return-static-string";
200
202
const len = strLen(expectedString);
201
203
const ptr = alloc(1, len);
202
-
fns.return_static_string(Number(ptr));
203
-
assert(readStringFromMemory({ ptr, len }) === expectedString);
204
+
fns.return_static_string(ptr);
205
+
assert(readStringFromMemory({ ptr, len }), expectedString);
204
206
};
205
-
() => {
207
+
{
206
208
const expectedString = "return-input-string";
207
209
const input = writeStringToMemory(expectedString);
208
210
const output = writeStringToMemory("AAAAAAAAAAAAAAAAAAA");
209
-
fns.return_input_string(Number(input.ptr), Number(output.ptr));
210
-
console.log(readStringFromMemory(input));
211
-
console.log(readStringFromMemory(output));
212
-
};
211
+
fns.return_input_string(input.ptr, output.ptr);
212
+
assert(readStringFromMemory(output), expectedString);
213
+
}
213
214
214
215
// Set
215
216
() => {
···
221
222
const newString = writeStringToMemory(expectedNewString);
222
223
fns.set_global_string();
223
224
console.log(fns.get_global_string(newString.ptr), expectedNewString);
224
-
}
225
+
};
225
226
}
226
227
try {
227
228
init();
+3
-3
projects/mojo-wasm/justfile
+3
-3
projects/mojo-wasm/justfile
···
1
1
build:
2
2
mkdir -p build
3
-
mojo build --emit-llvm --emit shared-lib src/main.mojo > build/out.ll
4
-
llc --mtriple=wasm32-wasi -filetype=obj build/out.ll
5
-
wasm-ld --no-entry --export-all --allow-undefined -o build/out.wasm build/out.o
3
+
mojo build --emit-llvm --target-features "none" --emit shared-lib src/main.mojo > build/out.ll
4
+
llc --mtriple=wasm64-wasi -filetype=obj build/out.ll
5
+
wasm-ld --no-entry --export-all --allow-undefined -mwasm64 -o build/out.wasm build/out.o
6
6
7
7
server:
8
8
python server.py