@grain/stdlib 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/array.gr +76 -57
- package/buffer.gr +7 -4
- package/bytes.gr +10 -10
- package/char.gr +112 -56
- package/char.md +200 -0
- package/hash.gr +17 -13
- package/list.gr +78 -61
- package/map.gr +106 -110
- package/number.gr +25 -7
- package/number.md +34 -0
- package/option.gr +25 -25
- package/package.json +1 -1
- package/pervasives.gr +32 -20
- package/queue.gr +4 -1
- package/range.gr +26 -26
- package/runtime/dataStructures.gr +28 -29
- package/runtime/debug.gr +0 -1
- package/runtime/equal.gr +37 -16
- package/runtime/exception.gr +28 -15
- package/runtime/gc.gr +31 -18
- package/runtime/malloc.gr +19 -11
- package/runtime/numberUtils.gr +208 -105
- package/runtime/numbers.gr +217 -118
- package/runtime/string.gr +98 -39
- package/runtime/stringUtils.gr +6 -2
- package/runtime/unsafe/conv.gr +10 -10
- package/runtime/unsafe/memory.gr +14 -3
- package/runtime/unsafe/printWasm.gr +4 -4
- package/runtime/unsafe/tags.gr +2 -2
- package/runtime/unsafe/wasmf32.gr +9 -2
- package/runtime/unsafe/wasmf64.gr +9 -2
- package/runtime/unsafe/wasmi32.gr +65 -47
- package/runtime/unsafe/wasmi64.gr +78 -50
- package/runtime/wasi.gr +199 -45
- package/set.gr +111 -116
- package/stack.gr +26 -26
- package/string.gr +273 -119
- package/sys/file.gr +356 -177
- package/sys/process.gr +10 -6
- package/sys/random.gr +3 -6
- package/sys/time.gr +3 -3
package/runtime/equal.gr
CHANGED
|
@@ -10,15 +10,15 @@ import WasmI32, {
|
|
|
10
10
|
mul as (*),
|
|
11
11
|
ltS as (<),
|
|
12
12
|
remS as (%),
|
|
13
|
-
shl as (<<)
|
|
13
|
+
shl as (<<),
|
|
14
14
|
} from "runtime/unsafe/wasmi32"
|
|
15
15
|
import WasmI64 from "runtime/unsafe/wasmi64"
|
|
16
16
|
import Tags from "runtime/unsafe/tags"
|
|
17
17
|
import Memory from "runtime/unsafe/memory"
|
|
18
18
|
|
|
19
|
-
primitive (!)
|
|
20
|
-
primitive (||)
|
|
21
|
-
primitive (&&)
|
|
19
|
+
primitive (!): Bool -> Bool = "@not"
|
|
20
|
+
primitive (||): (Bool, Bool) -> Bool = "@or"
|
|
21
|
+
primitive (&&): (Bool, Bool) -> Bool = "@and"
|
|
22
22
|
|
|
23
23
|
import { isNumber, numberEqual } from "runtime/numbers"
|
|
24
24
|
|
|
@@ -45,7 +45,12 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
45
45
|
|
|
46
46
|
let bytes = xarity * 4n
|
|
47
47
|
for (let mut i = 0n; i < bytes; i += 4n) {
|
|
48
|
-
if (
|
|
48
|
+
if (
|
|
49
|
+
!equalHelp(
|
|
50
|
+
WasmI32.load(xptr + i, 20n),
|
|
51
|
+
WasmI32.load(yptr + i, 20n)
|
|
52
|
+
)
|
|
53
|
+
) {
|
|
49
54
|
result = false
|
|
50
55
|
break
|
|
51
56
|
}
|
|
@@ -72,7 +77,9 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
72
77
|
|
|
73
78
|
let bytes = xlength * 4n
|
|
74
79
|
for (let mut i = 0n; i < bytes; i += 4n) {
|
|
75
|
-
if (
|
|
80
|
+
if (
|
|
81
|
+
!equalHelp(WasmI32.load(xptr + i, 16n), WasmI32.load(yptr + i, 16n))
|
|
82
|
+
) {
|
|
76
83
|
result = false
|
|
77
84
|
break
|
|
78
85
|
}
|
|
@@ -91,7 +98,7 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
91
98
|
if (xlength != ylength) {
|
|
92
99
|
false
|
|
93
100
|
} else if ((xlength & cycleMarker) == cycleMarker) {
|
|
94
|
-
|
|
101
|
+
// Cycle check
|
|
95
102
|
true
|
|
96
103
|
} else {
|
|
97
104
|
WasmI32.store(xptr, xlength ^ cycleMarker, 4n)
|
|
@@ -100,7 +107,9 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
100
107
|
let mut result = true
|
|
101
108
|
let bytes = xlength * 4n
|
|
102
109
|
for (let mut i = 0n; i < bytes; i += 4n) {
|
|
103
|
-
if (
|
|
110
|
+
if (
|
|
111
|
+
!equalHelp(WasmI32.load(xptr + i, 8n), WasmI32.load(yptr + i, 8n))
|
|
112
|
+
) {
|
|
104
113
|
result = false
|
|
105
114
|
break
|
|
106
115
|
}
|
|
@@ -112,7 +121,9 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
112
121
|
result
|
|
113
122
|
}
|
|
114
123
|
},
|
|
115
|
-
t when
|
|
124
|
+
t when (
|
|
125
|
+
t == Tags._GRAIN_STRING_HEAP_TAG || t == Tags._GRAIN_BYTES_HEAP_TAG
|
|
126
|
+
) => {
|
|
116
127
|
let xlength = WasmI32.load(xptr, 4n)
|
|
117
128
|
let ylength = WasmI32.load(yptr, 4n)
|
|
118
129
|
|
|
@@ -124,14 +135,19 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
124
135
|
let first = xlength - extra
|
|
125
136
|
let mut result = true
|
|
126
137
|
for (let mut i = 0n; i < first; i += 8n) {
|
|
127
|
-
if (
|
|
138
|
+
if (
|
|
139
|
+
WasmI64.ne(WasmI64.load(xptr + i, 8n), WasmI64.load(yptr + i, 8n))
|
|
140
|
+
) {
|
|
128
141
|
result = false
|
|
129
142
|
break
|
|
130
143
|
}
|
|
131
144
|
}
|
|
132
145
|
if (result) {
|
|
133
146
|
for (let mut i = 0n; i < extra; i += 1n) {
|
|
134
|
-
if (
|
|
147
|
+
if (
|
|
148
|
+
WasmI32.load8U(xptr + first + i, 8n) !=
|
|
149
|
+
WasmI32.load8U(yptr + first + i, 8n)
|
|
150
|
+
) {
|
|
135
151
|
result = false
|
|
136
152
|
break
|
|
137
153
|
}
|
|
@@ -153,8 +169,8 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
153
169
|
2n
|
|
154
170
|
}
|
|
155
171
|
// WebAssembly is little-endian, so bytes are in reverse order
|
|
156
|
-
let x = WasmI32.load(xptr, 4n) << (
|
|
157
|
-
let y = WasmI32.load(yptr, 4n) << (
|
|
172
|
+
let x = WasmI32.load(xptr, 4n) << (4n - n) * 8n
|
|
173
|
+
let y = WasmI32.load(yptr, 4n) << (4n - n) * 8n
|
|
158
174
|
x == y
|
|
159
175
|
},
|
|
160
176
|
t when t == Tags._GRAIN_TUPLE_HEAP_TAG => {
|
|
@@ -170,7 +186,9 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
170
186
|
let mut result = true
|
|
171
187
|
let bytes = xsize * 4n
|
|
172
188
|
for (let mut i = 0n; i < bytes; i += 4n) {
|
|
173
|
-
if (
|
|
189
|
+
if (
|
|
190
|
+
!equalHelp(WasmI32.load(xptr + i, 8n), WasmI32.load(yptr + i, 8n))
|
|
191
|
+
) {
|
|
174
192
|
result = false
|
|
175
193
|
break
|
|
176
194
|
}
|
|
@@ -185,10 +203,13 @@ let rec heapEqualHelp = (heapTag, xptr, yptr) => {
|
|
|
185
203
|
_ => {
|
|
186
204
|
// No other implementation
|
|
187
205
|
xptr == yptr
|
|
188
|
-
}
|
|
206
|
+
},
|
|
189
207
|
}
|
|
190
208
|
}, equalHelp = (x, y) => {
|
|
191
|
-
if (
|
|
209
|
+
if (
|
|
210
|
+
(x & Tags._GRAIN_GENERIC_TAG_MASK) != 0n &&
|
|
211
|
+
(y & Tags._GRAIN_GENERIC_TAG_MASK) != 0n
|
|
212
|
+
) {
|
|
192
213
|
// Short circuit for non-pointer values
|
|
193
214
|
x == y
|
|
194
215
|
} else if (isNumber(x)) {
|
package/runtime/exception.gr
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
/* grainc-flags --compilation-mode=runtime */
|
|
2
2
|
|
|
3
|
-
import WasmI32, {
|
|
4
|
-
eq as (==),
|
|
5
|
-
add as (+)
|
|
6
|
-
} from "runtime/unsafe/wasmi32"
|
|
3
|
+
import WasmI32, { eq as (==), add as (+) } from "runtime/unsafe/wasmi32"
|
|
7
4
|
|
|
8
|
-
import foreign wasm fd_write: (
|
|
5
|
+
import foreign wasm fd_write: (
|
|
6
|
+
WasmI32,
|
|
7
|
+
WasmI32,
|
|
8
|
+
WasmI32,
|
|
9
|
+
WasmI32,
|
|
10
|
+
) -> WasmI32 from "wasi_snapshot_preview1"
|
|
9
11
|
|
|
10
|
-
enum Option<a> {
|
|
12
|
+
enum Option<a> {
|
|
13
|
+
Some(a),
|
|
14
|
+
None,
|
|
15
|
+
}
|
|
11
16
|
|
|
12
17
|
export let mut printers = 0n
|
|
13
18
|
|
|
@@ -15,11 +20,14 @@ export let mut printers = 0n
|
|
|
15
20
|
// no GC operations. As such, they should only be called by this module and/or
|
|
16
21
|
// modules that understand these restrictions, namely Pervasives.
|
|
17
22
|
|
|
18
|
-
export let dangerouslyRegisterBasePrinter =
|
|
23
|
+
export let dangerouslyRegisterBasePrinter = f => {
|
|
19
24
|
let mut current = printers
|
|
20
25
|
while (true) {
|
|
21
26
|
// There will be at least one printer registered by the time this is called
|
|
22
|
-
let (_, next) = WasmI32.toGrain(current)
|
|
27
|
+
let (_, next) = WasmI32.toGrain(current): (
|
|
28
|
+
Exception -> Option<String>,
|
|
29
|
+
WasmI32
|
|
30
|
+
)
|
|
23
31
|
if (next == 0n) {
|
|
24
32
|
// Using a tuple in runtime mode is typically disallowed as there is no way
|
|
25
33
|
// to reclaim the memory, but this function is only called once
|
|
@@ -34,7 +42,7 @@ export let dangerouslyRegisterBasePrinter = (f) => {
|
|
|
34
42
|
void
|
|
35
43
|
}
|
|
36
44
|
|
|
37
|
-
export let dangerouslyRegisterPrinter =
|
|
45
|
+
export let dangerouslyRegisterPrinter = f => {
|
|
38
46
|
printers = WasmI32.fromGrain((f, printers))
|
|
39
47
|
// We don't decRef the closure or arguments here to avoid a cyclic dep. on Memory.
|
|
40
48
|
// This is fine, as this function is only called seldomly.
|
|
@@ -50,13 +58,16 @@ let exceptionToString = (e: Exception) => {
|
|
|
50
58
|
if (current == 0n) {
|
|
51
59
|
break
|
|
52
60
|
}
|
|
53
|
-
let (printer, next) = WasmI32.toGrain(current)
|
|
61
|
+
let (printer, next) = WasmI32.toGrain(current): (
|
|
62
|
+
Exception -> Option<String>,
|
|
63
|
+
WasmI32
|
|
64
|
+
)
|
|
54
65
|
match (printer(e)) {
|
|
55
66
|
Some(str) => {
|
|
56
67
|
result = str
|
|
57
68
|
break
|
|
58
69
|
},
|
|
59
|
-
None => void
|
|
70
|
+
None => void,
|
|
60
71
|
}
|
|
61
72
|
current = next
|
|
62
73
|
}
|
|
@@ -100,19 +111,21 @@ export exception AssertionError(String)
|
|
|
100
111
|
export exception InvalidArgument(String)
|
|
101
112
|
export exception OutOfMemory
|
|
102
113
|
|
|
103
|
-
let runtimeErrorPrinter =
|
|
114
|
+
let runtimeErrorPrinter = e => {
|
|
104
115
|
match (e) {
|
|
105
116
|
IndexOutOfBounds => Some("IndexOutOfBounds: Index out of bounds"),
|
|
106
117
|
DivisionByZero => Some("DivisionByZero: Division by zero"),
|
|
107
118
|
ModuloByZero => Some("ModuloByZero: Modulo by zero"),
|
|
108
119
|
Overflow => Some("Overflow: Number overflow"),
|
|
109
|
-
NumberNotIntlike =>
|
|
110
|
-
|
|
120
|
+
NumberNotIntlike =>
|
|
121
|
+
Some("NumberNotIntlike: Can't coerce number to integer"),
|
|
122
|
+
NumberNotRational =>
|
|
123
|
+
Some("NumberNotRational: Can't coerce number to rational"),
|
|
111
124
|
MatchFailure => Some("MatchFailure: No matching pattern"),
|
|
112
125
|
AssertionError(s) => Some(s),
|
|
113
126
|
OutOfMemory => Some("OutOfMemory: Maximum memory size exceeded"),
|
|
114
127
|
InvalidArgument(msg) => Some(msg),
|
|
115
|
-
_ => None
|
|
128
|
+
_ => None,
|
|
116
129
|
}
|
|
117
130
|
}
|
|
118
131
|
|
package/runtime/gc.gr
CHANGED
|
@@ -25,18 +25,23 @@ import WasmI32, {
|
|
|
25
25
|
sub as (-),
|
|
26
26
|
mul as (*),
|
|
27
27
|
and as (&),
|
|
28
|
-
eq as (==)
|
|
28
|
+
eq as (==),
|
|
29
29
|
} from "runtime/unsafe/wasmi32"
|
|
30
30
|
|
|
31
31
|
// Using foreigns directly here to avoid cyclic dependency
|
|
32
|
-
import foreign wasm fd_write
|
|
32
|
+
import foreign wasm fd_write: (
|
|
33
|
+
WasmI32,
|
|
34
|
+
WasmI32,
|
|
35
|
+
WasmI32,
|
|
36
|
+
WasmI32,
|
|
37
|
+
) -> WasmI32 from "wasi_snapshot_preview1"
|
|
33
38
|
|
|
34
|
-
primitive (&&)
|
|
35
|
-
primitive (||)
|
|
36
|
-
primitive throw
|
|
37
|
-
primitive ignore
|
|
38
|
-
primitive box
|
|
39
|
-
primitive unbox
|
|
39
|
+
primitive (&&): (Bool, Bool) -> Bool = "@and"
|
|
40
|
+
primitive (||): (Bool, Bool) -> Bool = "@or"
|
|
41
|
+
primitive throw: Exception -> a = "@throw"
|
|
42
|
+
primitive ignore: a -> Void = "@ignore"
|
|
43
|
+
primitive box: a -> Box<a> = "@box"
|
|
44
|
+
primitive unbox: Box<a> -> a = "@unbox"
|
|
40
45
|
|
|
41
46
|
exception DecRefError
|
|
42
47
|
|
|
@@ -154,7 +159,10 @@ export let free = (userPtr: WasmI32) => {
|
|
|
154
159
|
}
|
|
155
160
|
|
|
156
161
|
export let incRef = (userPtr: WasmI32) => {
|
|
157
|
-
if (
|
|
162
|
+
if (
|
|
163
|
+
WasmI32.eqz(userPtr & Tags._GRAIN_GENERIC_TAG_MASK) &&
|
|
164
|
+
WasmI32.ne(userPtr, 0n)
|
|
165
|
+
) {
|
|
158
166
|
// if (_DEBUG) {
|
|
159
167
|
// logIncRef(userPtr, getRefCount(userPtr))
|
|
160
168
|
// void;
|
|
@@ -165,7 +173,10 @@ export let incRef = (userPtr: WasmI32) => {
|
|
|
165
173
|
}
|
|
166
174
|
|
|
167
175
|
let rec decRef = (userPtr: WasmI32, ignoreZeros: Bool) => {
|
|
168
|
-
if (
|
|
176
|
+
if (
|
|
177
|
+
WasmI32.eqz(userPtr & Tags._GRAIN_GENERIC_TAG_MASK) &&
|
|
178
|
+
WasmI32.ne(userPtr, 0n)
|
|
179
|
+
) {
|
|
169
180
|
let refCount = getRefCount(userPtr)
|
|
170
181
|
// if (_DEBUG) {
|
|
171
182
|
// logDecRef(userPtr, refCount, ignoreZeros)
|
|
@@ -197,40 +208,42 @@ let rec decRef = (userPtr: WasmI32, ignoreZeros: Bool) => {
|
|
|
197
208
|
t when t == Tags._GRAIN_ADT_HEAP_TAG => {
|
|
198
209
|
let arity = WasmI32.load(userPtr, 16n)
|
|
199
210
|
let maxOffset = arity * 4n
|
|
200
|
-
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i
|
|
211
|
+
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
201
212
|
ignore(decRef(WasmI32.load(userPtr + i, 20n), false))
|
|
202
213
|
}
|
|
203
214
|
},
|
|
204
215
|
t when t == Tags._GRAIN_RECORD_HEAP_TAG => {
|
|
205
216
|
let arity = WasmI32.load(userPtr, 12n)
|
|
206
217
|
let maxOffset = arity * 4n
|
|
207
|
-
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i
|
|
218
|
+
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
208
219
|
ignore(decRef(WasmI32.load(userPtr + i, 16n), false))
|
|
209
220
|
}
|
|
210
221
|
},
|
|
211
|
-
t when
|
|
222
|
+
t when (
|
|
223
|
+
t == Tags._GRAIN_ARRAY_HEAP_TAG || t == Tags._GRAIN_TUPLE_HEAP_TAG
|
|
224
|
+
) => {
|
|
212
225
|
let arity = WasmI32.load(userPtr, 4n)
|
|
213
226
|
let maxOffset = arity * 4n
|
|
214
|
-
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i
|
|
227
|
+
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
215
228
|
ignore(decRef(WasmI32.load(userPtr + i, 8n), false))
|
|
216
229
|
}
|
|
217
230
|
},
|
|
218
231
|
t when t == Tags._GRAIN_LAMBDA_HEAP_TAG => {
|
|
219
232
|
let arity = WasmI32.load(userPtr, 12n)
|
|
220
233
|
let maxOffset = arity * 4n
|
|
221
|
-
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i
|
|
234
|
+
for (let mut i = 0n; WasmI32.ltU(i, maxOffset); i += 4n) {
|
|
222
235
|
ignore(decRef(WasmI32.load(userPtr + i, 16n), false))
|
|
223
236
|
}
|
|
224
237
|
},
|
|
225
238
|
_ => {
|
|
226
239
|
// No travelsal necessary for other tags
|
|
227
240
|
void
|
|
228
|
-
}
|
|
241
|
+
},
|
|
229
242
|
}
|
|
230
243
|
}
|
|
231
244
|
|
|
232
|
-
export let decRefIgnoreZeros =
|
|
233
|
-
export let decRef =
|
|
245
|
+
export let decRefIgnoreZeros = userPtr => decRef(userPtr, true)
|
|
246
|
+
export let decRef = userPtr => decRef(userPtr, false)
|
|
234
247
|
|
|
235
248
|
// For debugging:
|
|
236
249
|
|
package/runtime/malloc.gr
CHANGED
|
@@ -17,18 +17,18 @@ import WasmI32, {
|
|
|
17
17
|
shl as (<<),
|
|
18
18
|
shrU as (>>),
|
|
19
19
|
eq as (==),
|
|
20
|
-
ne as (!=)
|
|
20
|
+
ne as (!=),
|
|
21
21
|
} from "runtime/unsafe/wasmi32"
|
|
22
22
|
import Exception from "runtime/exception"
|
|
23
23
|
|
|
24
24
|
primitive memorySize: () -> WasmI32 = "@wasm.memory_size"
|
|
25
|
-
primitive memoryGrow:
|
|
25
|
+
primitive memoryGrow: WasmI32 -> WasmI32 = "@wasm.memory_grow"
|
|
26
26
|
|
|
27
|
-
primitive (!)
|
|
28
|
-
primitive (&&)
|
|
29
|
-
primitive (||)
|
|
27
|
+
primitive (!): Bool -> Bool = "@not"
|
|
28
|
+
primitive (&&): (Bool, Bool) -> Bool = "@and"
|
|
29
|
+
primitive (||): (Bool, Bool) -> Bool = "@or"
|
|
30
30
|
|
|
31
|
-
primitive throw
|
|
31
|
+
primitive throw: Exception -> a = "@throw"
|
|
32
32
|
|
|
33
33
|
/* UNDERSTANDING THE STRUCTURE OF THE FREE LIST
|
|
34
34
|
* The original K&R definition for the free list entry type was the following:
|
|
@@ -130,7 +130,7 @@ let growHeap = (nbytes: WasmI32) => {
|
|
|
130
130
|
// so we need to request more anyway.
|
|
131
131
|
reqSize = nbytes - heapSize
|
|
132
132
|
reqSize = reqSize >> 16n
|
|
133
|
-
reqSize
|
|
133
|
+
reqSize += 1n
|
|
134
134
|
reqResult = memoryGrow(reqSize)
|
|
135
135
|
if (reqResult == -1n) {
|
|
136
136
|
-1n
|
|
@@ -147,7 +147,7 @@ let growHeap = (nbytes: WasmI32) => {
|
|
|
147
147
|
|
|
148
148
|
reqSize = nbytes
|
|
149
149
|
reqSize = reqSize >> 16n
|
|
150
|
-
reqSize
|
|
150
|
+
reqSize += 1n
|
|
151
151
|
|
|
152
152
|
reqResult = memoryGrow(reqSize)
|
|
153
153
|
if (reqResult == -1n) {
|
|
@@ -174,7 +174,10 @@ export let free = (ap: WasmI32) => {
|
|
|
174
174
|
// Find the location to insert this block into the free list
|
|
175
175
|
while (true) {
|
|
176
176
|
let nextp = getNext(p)
|
|
177
|
-
if (
|
|
177
|
+
if (
|
|
178
|
+
blockPtr > p && blockPtr < nextp ||
|
|
179
|
+
p >= nextp && (blockPtr > p || blockPtr < nextp)
|
|
180
|
+
) {
|
|
178
181
|
break
|
|
179
182
|
}
|
|
180
183
|
p = nextp
|
|
@@ -255,7 +258,12 @@ export let malloc = (nb: WasmI32) => {
|
|
|
255
258
|
let mut ret = -1n
|
|
256
259
|
|
|
257
260
|
// Search the freelist for any blocks large enough.
|
|
258
|
-
for (
|
|
261
|
+
for (
|
|
262
|
+
let mut p = getNext(prevp); ; {
|
|
263
|
+
prevp = p
|
|
264
|
+
p = getNext(p)
|
|
265
|
+
}
|
|
266
|
+
) {
|
|
259
267
|
let size = getSize(p)
|
|
260
268
|
if (size >= nbytes) {
|
|
261
269
|
// If this block is big enough, allocate from it.
|
|
@@ -266,7 +274,7 @@ export let malloc = (nb: WasmI32) => {
|
|
|
266
274
|
// Shrink it as needed
|
|
267
275
|
let newSize = size - nbytes
|
|
268
276
|
setSize(p, newSize)
|
|
269
|
-
p
|
|
277
|
+
p += newSize
|
|
270
278
|
setSize(p, nbytes)
|
|
271
279
|
}
|
|
272
280
|
// Update the pointer to the free list.
|