@grain/stdlib 0.6.6 → 0.7.1
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 +67 -0
- package/LICENSE +1 -1
- package/README.md +2 -2
- package/array.gr +55 -7
- package/array.md +606 -560
- package/bigint.md +228 -228
- package/buffer.gr +85 -53
- package/buffer.md +442 -319
- package/bytes.gr +112 -35
- package/bytes.md +299 -219
- package/char.gr +201 -99
- package/char.md +447 -120
- package/exception.gr +11 -11
- package/exception.md +29 -4
- package/float32.gr +327 -3
- package/float32.md +698 -111
- package/float64.gr +320 -3
- package/float64.md +698 -111
- package/fs.gr +1082 -0
- package/fs.md +630 -0
- package/hash.gr +142 -88
- package/hash.md +105 -17
- package/int16.md +178 -178
- package/int32.gr +26 -5
- package/int32.md +266 -231
- package/int64.gr +27 -2
- package/int64.md +266 -231
- package/int8.md +178 -178
- package/json.gr +366 -51
- package/json.md +431 -15
- package/list.gr +328 -31
- package/list.md +759 -336
- package/map.gr +20 -12
- package/map.md +266 -260
- package/marshal.gr +41 -40
- package/marshal.md +14 -14
- package/number.gr +278 -35
- package/number.md +688 -269
- package/option.md +162 -162
- package/package.json +5 -3
- package/path.gr +48 -0
- package/path.md +180 -89
- package/pervasives.gr +2 -2
- package/pervasives.md +275 -275
- package/priorityqueue.gr +7 -7
- package/priorityqueue.md +131 -131
- package/queue.gr +183 -29
- package/queue.md +404 -148
- package/random.md +43 -43
- package/range.gr +4 -4
- package/range.md +42 -42
- package/rational.md +123 -123
- package/regex.gr +52 -51
- package/regex.md +102 -102
- package/result.md +118 -118
- package/runtime/atof/common.md +39 -39
- package/runtime/atof/decimal.gr +6 -6
- package/runtime/atof/decimal.md +14 -14
- package/runtime/atof/lemire.gr +5 -5
- package/runtime/atof/lemire.md +1 -1
- package/runtime/atof/parse.gr +16 -16
- package/runtime/atof/parse.md +2 -2
- package/runtime/atof/slow.md +1 -1
- package/runtime/atof/table.md +2 -2
- package/runtime/atoi/parse.gr +3 -3
- package/runtime/atoi/parse.md +1 -1
- package/runtime/bigint.gr +15 -47
- package/runtime/bigint.md +54 -60
- package/runtime/compare.gr +2 -2
- package/runtime/compare.md +8 -8
- package/runtime/dataStructures.md +211 -211
- package/runtime/debugPrint.gr +4 -1
- package/runtime/debugPrint.md +9 -9
- package/runtime/equal.gr +99 -77
- package/runtime/equal.md +8 -8
- package/runtime/exception.gr +62 -82
- package/runtime/exception.md +62 -11
- package/runtime/gc.gr +39 -45
- package/runtime/gc.md +4 -4
- package/runtime/malloc.gr +7 -7
- package/runtime/malloc.md +13 -13
- package/runtime/math/kernel/cos.gr +70 -0
- package/runtime/math/kernel/cos.md +14 -0
- package/runtime/math/kernel/sin.gr +65 -0
- package/runtime/math/kernel/sin.md +14 -0
- package/runtime/math/kernel/tan.gr +136 -0
- package/runtime/math/kernel/tan.md +14 -0
- package/runtime/math/rempio2.gr +244 -0
- package/runtime/math/rempio2.md +14 -0
- package/runtime/math/trig.gr +130 -0
- package/runtime/math/trig.md +28 -0
- package/runtime/math/umuldi.gr +26 -0
- package/runtime/math/umuldi.md +14 -0
- package/runtime/numberUtils.gr +29 -29
- package/runtime/numberUtils.md +12 -12
- package/runtime/numbers.gr +373 -381
- package/runtime/numbers.md +348 -342
- package/runtime/string.gr +37 -105
- package/runtime/string.md +20 -26
- package/runtime/unsafe/constants.md +24 -24
- package/runtime/unsafe/conv.md +19 -19
- package/runtime/unsafe/memory.gr +24 -20
- package/runtime/unsafe/memory.md +27 -7
- package/runtime/unsafe/offsets.gr +36 -0
- package/runtime/unsafe/offsets.md +88 -0
- package/runtime/unsafe/panic.gr +28 -0
- package/runtime/unsafe/panic.md +14 -0
- package/runtime/unsafe/tags.md +32 -32
- package/runtime/unsafe/wasmf32.md +28 -28
- package/runtime/unsafe/wasmf64.md +28 -28
- package/runtime/unsafe/wasmi32.md +47 -47
- package/runtime/unsafe/wasmi64.md +50 -50
- package/runtime/utf8.gr +189 -0
- package/runtime/utf8.md +117 -0
- package/runtime/wasi.gr +4 -2
- package/runtime/wasi.md +147 -147
- package/set.gr +18 -11
- package/set.md +253 -247
- package/stack.gr +171 -2
- package/stack.md +371 -89
- package/string.gr +352 -557
- package/string.md +298 -255
- package/uint16.md +170 -170
- package/uint32.gr +25 -4
- package/uint32.md +249 -214
- package/uint64.gr +25 -5
- package/uint64.md +249 -214
- package/uint8.md +170 -170
- package/uri.gr +57 -53
- package/uri.md +88 -89
- package/wasi/file.gr +67 -59
- package/wasi/file.md +308 -308
- package/wasi/process.md +26 -26
- package/wasi/random.md +12 -12
- package/wasi/time.md +16 -16
- package/runtime/utils/printing.gr +0 -60
- package/runtime/utils/printing.md +0 -26
package/string.gr
CHANGED
|
@@ -24,7 +24,38 @@ use DataStructures.{
|
|
|
24
24
|
allocateString,
|
|
25
25
|
allocateBytes,
|
|
26
26
|
}
|
|
27
|
+
from "runtime/utf8" include Utf8
|
|
28
|
+
use Utf8.{
|
|
29
|
+
isLeadingByte,
|
|
30
|
+
utf8ByteCount,
|
|
31
|
+
usvEncodeLength,
|
|
32
|
+
getCodePoint,
|
|
33
|
+
writeUtf8CodePoint,
|
|
34
|
+
}
|
|
35
|
+
from "runtime/unsafe/offsets" include Offsets
|
|
36
|
+
use Offsets.{
|
|
37
|
+
_STR_LEN_OFFSET,
|
|
38
|
+
_STR_DATA_OFFSET,
|
|
39
|
+
_ARRAY_LEN_OFFSET,
|
|
40
|
+
_ARRAY_DATA_OFFSET,
|
|
41
|
+
_ARRAY_ITEM_SIZE,
|
|
42
|
+
_BYTES_LEN_OFFSET,
|
|
43
|
+
_BYTES_DATA_OFFSET,
|
|
44
|
+
}
|
|
45
|
+
from "runtime/unsafe/tags" include Tags
|
|
27
46
|
|
|
47
|
+
// Helpers
|
|
48
|
+
@unsafe
|
|
49
|
+
let convSimpleNumber = (x: Number, err: String) => {
|
|
50
|
+
use WasmI32.{ (&), (!=) }
|
|
51
|
+
let rawX = WasmI32.fromGrain(x)
|
|
52
|
+
if ((rawX & Tags._GRAIN_NUMBER_TAG_MASK) != Tags._GRAIN_NUMBER_TAG_TYPE) {
|
|
53
|
+
throw InvalidArgument(err)
|
|
54
|
+
}
|
|
55
|
+
untagSimpleNumber(x)
|
|
56
|
+
}
|
|
57
|
+
@unsafe
|
|
58
|
+
let rawByteLength = (ptr: WasmI32) => WasmI32.load(ptr, _STR_LEN_OFFSET)
|
|
28
59
|
/**
|
|
29
60
|
* Byte encodings
|
|
30
61
|
*/
|
|
@@ -63,20 +94,18 @@ provide let concat = (++)
|
|
|
63
94
|
*/
|
|
64
95
|
@unsafe
|
|
65
96
|
provide let length = (string: String) => {
|
|
66
|
-
use WasmI32.{ (+), (&), (!=) }
|
|
67
|
-
let stringPtr = WasmI32.fromGrain(string)
|
|
68
|
-
let size =
|
|
97
|
+
use WasmI32.{ (+), (&), (!=), ltU as (<) }
|
|
98
|
+
let mut stringPtr = WasmI32.fromGrain(string)
|
|
99
|
+
let size = rawByteLength(stringPtr)
|
|
69
100
|
|
|
70
101
|
let mut len = 0n
|
|
71
|
-
|
|
72
|
-
let end =
|
|
102
|
+
stringPtr += _STR_DATA_OFFSET
|
|
103
|
+
let end = stringPtr + size
|
|
73
104
|
|
|
74
|
-
while (
|
|
75
|
-
let byte = WasmI32.load8U(
|
|
76
|
-
if ((byte
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
ptr += 1n
|
|
105
|
+
while (stringPtr < end) {
|
|
106
|
+
let byte = WasmI32.load8U(stringPtr, 0n)
|
|
107
|
+
if (isLeadingByte(byte)) len += 1n
|
|
108
|
+
stringPtr += 1n
|
|
80
109
|
}
|
|
81
110
|
|
|
82
111
|
ignore(string)
|
|
@@ -97,7 +126,7 @@ provide let length = (string: String) => {
|
|
|
97
126
|
@unsafe
|
|
98
127
|
provide let byteLength = (string: String) => {
|
|
99
128
|
let stringPtr = WasmI32.fromGrain(string)
|
|
100
|
-
let result = Conv.wasmI32ToNumber(
|
|
129
|
+
let result = Conv.wasmI32ToNumber(rawByteLength(stringPtr))
|
|
101
130
|
ignore(string)
|
|
102
131
|
result
|
|
103
132
|
}
|
|
@@ -114,7 +143,7 @@ provide let byteLength = (string: String) => {
|
|
|
114
143
|
provide let isEmpty = (string: String) => {
|
|
115
144
|
use WasmI32.{ (==) }
|
|
116
145
|
let strPtr = WasmI32.fromGrain(string)
|
|
117
|
-
let result =
|
|
146
|
+
let result = rawByteLength(strPtr) == 0n
|
|
118
147
|
ignore(string)
|
|
119
148
|
result
|
|
120
149
|
}
|
|
@@ -132,36 +161,26 @@ provide let isEmpty = (string: String) => {
|
|
|
132
161
|
*/
|
|
133
162
|
@unsafe
|
|
134
163
|
provide let indexOf = (search: String, string: String) => {
|
|
164
|
+
use WasmI32.{ (+), (-), ltU as (<), gtU as (>), (==) }
|
|
135
165
|
let searchPtr = WasmI32.fromGrain(search)
|
|
136
166
|
let stringPtr = WasmI32.fromGrain(string)
|
|
137
167
|
|
|
138
|
-
let size =
|
|
139
|
-
let psize =
|
|
140
|
-
use WasmI32.{ (+), (-), (&), ltU as (<), gtU as (>), (==) }
|
|
168
|
+
let size = rawByteLength(stringPtr)
|
|
169
|
+
let psize = rawByteLength(searchPtr)
|
|
141
170
|
|
|
142
171
|
if (psize > size) {
|
|
143
172
|
return None
|
|
144
173
|
}
|
|
145
|
-
let mut
|
|
146
|
-
let
|
|
147
|
-
let pptr = searchPtr + 8n
|
|
174
|
+
let mut ptr = stringPtr + _STR_DATA_OFFSET
|
|
175
|
+
let pptr = searchPtr + _STR_DATA_OFFSET
|
|
148
176
|
let end = ptr + size - psize + 1n
|
|
149
177
|
|
|
150
|
-
|
|
178
|
+
for (let mut i = 0n; ptr < end; i += 1n) {
|
|
151
179
|
if (Memory.compare(ptr, pptr, psize) == 0n) {
|
|
152
|
-
return Some(tagSimpleNumber(
|
|
180
|
+
return Some(tagSimpleNumber(i))
|
|
153
181
|
}
|
|
154
|
-
idx += 1n
|
|
155
182
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
156
|
-
|
|
157
|
-
ptr += 1n
|
|
158
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
159
|
-
ptr += 4n
|
|
160
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
161
|
-
ptr += 3n
|
|
162
|
-
} else {
|
|
163
|
-
ptr += 2n
|
|
164
|
-
}
|
|
183
|
+
ptr += utf8ByteCount(byte)
|
|
165
184
|
}
|
|
166
185
|
|
|
167
186
|
ignore(search)
|
|
@@ -186,28 +205,26 @@ provide let lastIndexOf = (search: String, string: String) => {
|
|
|
186
205
|
// The last possible index in the string given the length of the search
|
|
187
206
|
let lastIndex = length(string) - length(search)
|
|
188
207
|
|
|
189
|
-
use WasmI32.{ (+), (-),
|
|
208
|
+
use WasmI32.{ (+), (-), gtU as (>), geU as (>=), (==), (!=) }
|
|
190
209
|
|
|
191
210
|
let searchPtr = WasmI32.fromGrain(search)
|
|
192
211
|
let stringPtr = WasmI32.fromGrain(string)
|
|
193
|
-
let searchSize =
|
|
194
|
-
let stringSize =
|
|
212
|
+
let searchSize = rawByteLength(searchPtr)
|
|
213
|
+
let stringSize = rawByteLength(stringPtr)
|
|
195
214
|
if (searchSize > stringSize) {
|
|
196
215
|
return None
|
|
197
216
|
}
|
|
198
217
|
let mut stringIndex = untagSimpleNumber(lastIndex)
|
|
199
|
-
let searchPtr = searchPtr +
|
|
200
|
-
let stringStartPtr = stringPtr +
|
|
218
|
+
let searchPtr = searchPtr + _STR_DATA_OFFSET
|
|
219
|
+
let stringStartPtr = stringPtr + _STR_DATA_OFFSET
|
|
201
220
|
for (
|
|
202
221
|
let mut stringPtr = stringStartPtr + stringSize - searchSize;
|
|
203
222
|
stringPtr >= stringStartPtr;
|
|
204
223
|
stringPtr -= 1n
|
|
205
224
|
) {
|
|
206
225
|
let byte = WasmI32.load8U(stringPtr, 0n)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
continue
|
|
210
|
-
}
|
|
226
|
+
// We're not at the start of a codepoint, so move on
|
|
227
|
+
if (!isLeadingByte(byte)) continue
|
|
211
228
|
if (Memory.compare(stringPtr, searchPtr, searchSize) == 0n) {
|
|
212
229
|
return Some(tagSimpleNumber(stringIndex))
|
|
213
230
|
}
|
|
@@ -220,68 +237,17 @@ provide let lastIndexOf = (search: String, string: String) => {
|
|
|
220
237
|
return None
|
|
221
238
|
}
|
|
222
239
|
|
|
223
|
-
@unsafe
|
|
224
|
-
let getCodePoint = (ptr: WasmI32) => {
|
|
225
|
-
// Algorithm from https://encoding.spec.whatwg.org/#utf-8-decoder
|
|
226
|
-
use WasmI32.{ (+), (&), (|), (<<), leU as (<=), geU as (>=), (==) }
|
|
227
|
-
|
|
228
|
-
let mut codePoint = 0n
|
|
229
|
-
let mut bytesSeen = 0n
|
|
230
|
-
let mut bytesNeeded = 0n
|
|
231
|
-
let mut lowerBoundary = 0x80n
|
|
232
|
-
let mut upperBoundary = 0xBFn
|
|
233
|
-
|
|
234
|
-
let mut offset = 0n
|
|
235
|
-
|
|
236
|
-
while (true) {
|
|
237
|
-
let byte = WasmI32.load8U(ptr + offset, 0n)
|
|
238
|
-
offset += 1n
|
|
239
|
-
if (bytesNeeded == 0n) {
|
|
240
|
-
if (byte >= 0x00n && byte <= 0x7Fn) {
|
|
241
|
-
return byte
|
|
242
|
-
} else if (byte >= 0xC2n && byte <= 0xDFn) {
|
|
243
|
-
bytesNeeded = 1n
|
|
244
|
-
codePoint = byte & 0x1Fn
|
|
245
|
-
} else if (byte >= 0xE0n && byte <= 0xEFn) {
|
|
246
|
-
if (byte == 0xE0n) lowerBoundary = 0xA0n
|
|
247
|
-
if (byte == 0xEDn) upperBoundary = 0x9Fn
|
|
248
|
-
bytesNeeded = 2n
|
|
249
|
-
codePoint = byte & 0xFn
|
|
250
|
-
} else if (byte >= 0xF0n && byte <= 0xF4n) {
|
|
251
|
-
if (byte == 0xF0n) lowerBoundary = 0x90n
|
|
252
|
-
if (byte == 0xF4n) upperBoundary = 0x8Fn
|
|
253
|
-
bytesNeeded = 3n
|
|
254
|
-
codePoint = byte & 0x7n
|
|
255
|
-
} else {
|
|
256
|
-
throw MalformedUnicode
|
|
257
|
-
}
|
|
258
|
-
continue
|
|
259
|
-
}
|
|
260
|
-
if (!(lowerBoundary <= byte && byte <= upperBoundary)) {
|
|
261
|
-
throw MalformedUnicode
|
|
262
|
-
}
|
|
263
|
-
lowerBoundary = 0x80n
|
|
264
|
-
upperBoundary = 0xBFn
|
|
265
|
-
codePoint = codePoint << 6n | byte & 0x3Fn
|
|
266
|
-
bytesSeen += 1n
|
|
267
|
-
if (bytesSeen == bytesNeeded) {
|
|
268
|
-
return codePoint
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
return 0n
|
|
272
|
-
}
|
|
273
|
-
|
|
274
240
|
@unsafe
|
|
275
241
|
let charAtHelp = (position, string: String) => {
|
|
276
242
|
if (length(string) <= position || position < 0) {
|
|
277
243
|
fail "Invalid offset: " ++ toString(position)
|
|
278
244
|
}
|
|
279
245
|
// Implementation is similar to explodeHelp, but doesn't perform unneeded memory allocations
|
|
280
|
-
use WasmI32.{ (+),
|
|
281
|
-
let
|
|
282
|
-
let
|
|
283
|
-
let
|
|
284
|
-
let mut ptr =
|
|
246
|
+
use WasmI32.{ (+), ltU as (<), (==) }
|
|
247
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
248
|
+
let size = rawByteLength(stringPtr)
|
|
249
|
+
let position = untagSimpleNumber(position)
|
|
250
|
+
let mut ptr = stringPtr + _STR_DATA_OFFSET
|
|
285
251
|
let end = ptr + size
|
|
286
252
|
let mut counter = 0n
|
|
287
253
|
while (ptr < end) {
|
|
@@ -289,17 +255,8 @@ let charAtHelp = (position, string: String) => {
|
|
|
289
255
|
return getCodePoint(ptr)
|
|
290
256
|
}
|
|
291
257
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
292
|
-
|
|
293
|
-
1n
|
|
294
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
295
|
-
4n
|
|
296
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
297
|
-
3n
|
|
298
|
-
} else {
|
|
299
|
-
2n
|
|
300
|
-
}
|
|
258
|
+
ptr += utf8ByteCount(byte)
|
|
301
259
|
counter += 1n
|
|
302
|
-
ptr += n
|
|
303
260
|
}
|
|
304
261
|
|
|
305
262
|
ignore(string)
|
|
@@ -347,14 +304,13 @@ provide let charAt = (position, string: String) => {
|
|
|
347
304
|
|
|
348
305
|
@unsafe
|
|
349
306
|
let explodeHelp = (s: String, chars) => {
|
|
350
|
-
use WasmI32.{ (+),
|
|
351
|
-
|
|
352
|
-
let size = WasmI32.fromGrain(byteLength(s)) >>> 1n
|
|
353
|
-
let len = WasmI32.fromGrain(length(s)) >>> 1n
|
|
307
|
+
use WasmI32.{ (+), ltU as (<), (==) }
|
|
354
308
|
|
|
355
309
|
let sPtr = WasmI32.fromGrain(s)
|
|
310
|
+
let size = rawByteLength(sPtr)
|
|
311
|
+
let len = untagSimpleNumber(length(s))
|
|
356
312
|
|
|
357
|
-
let mut ptr = sPtr +
|
|
313
|
+
let mut ptr = sPtr + _STR_DATA_OFFSET
|
|
358
314
|
let end = ptr + size
|
|
359
315
|
|
|
360
316
|
let arr = allocateArray(len)
|
|
@@ -362,26 +318,18 @@ let explodeHelp = (s: String, chars) => {
|
|
|
362
318
|
|
|
363
319
|
while (ptr < end) {
|
|
364
320
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
365
|
-
let n =
|
|
366
|
-
1n
|
|
367
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
368
|
-
4n
|
|
369
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
370
|
-
3n
|
|
371
|
-
} else {
|
|
372
|
-
2n
|
|
373
|
-
}
|
|
321
|
+
let n = utf8ByteCount(byte)
|
|
374
322
|
|
|
375
323
|
let c = if (chars) {
|
|
376
324
|
WasmI32.fromGrain(tagChar(getCodePoint(ptr)))
|
|
377
325
|
} else {
|
|
378
326
|
let sPtr = allocateString(n)
|
|
379
|
-
Memory.copy(sPtr +
|
|
327
|
+
Memory.copy(sPtr + _STR_DATA_OFFSET, ptr, n)
|
|
380
328
|
sPtr
|
|
381
329
|
}
|
|
382
330
|
|
|
383
|
-
WasmI32.store(arr + arrIdx, c,
|
|
384
|
-
arrIdx +=
|
|
331
|
+
WasmI32.store(arr + arrIdx, c, _ARRAY_DATA_OFFSET)
|
|
332
|
+
arrIdx += _ARRAY_ITEM_SIZE
|
|
385
333
|
ptr += n
|
|
386
334
|
}
|
|
387
335
|
|
|
@@ -432,58 +380,21 @@ provide let implode = (arr: Array<Char>) => {
|
|
|
432
380
|
leU as (<=),
|
|
433
381
|
}
|
|
434
382
|
|
|
435
|
-
let arrLength = WasmI32.load(WasmI32.fromGrain(arr),
|
|
383
|
+
let arrLength = WasmI32.load(WasmI32.fromGrain(arr), _ARRAY_LEN_OFFSET)
|
|
436
384
|
|
|
437
385
|
let mut stringByteLength = 0n
|
|
438
386
|
|
|
439
387
|
for (let mut i = 0n; i < arrLength; i += 1n) {
|
|
440
388
|
let usv = untagChar(arr[tagSimpleNumber(i)])
|
|
441
|
-
|
|
442
|
-
let n = if (usv <= 0x7Fn) {
|
|
443
|
-
1n
|
|
444
|
-
} else if (usv <= 0x07FFn) {
|
|
445
|
-
2n
|
|
446
|
-
} else if (usv <= 0xFFFFn) {
|
|
447
|
-
3n
|
|
448
|
-
} else {
|
|
449
|
-
4n
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
stringByteLength += n
|
|
389
|
+
stringByteLength += usvEncodeLength(usv)
|
|
453
390
|
}
|
|
454
391
|
|
|
455
392
|
let str = allocateString(stringByteLength)
|
|
456
|
-
let mut offset =
|
|
393
|
+
let mut offset = _STR_DATA_OFFSET
|
|
457
394
|
|
|
458
395
|
for (let mut i = 0n; i < arrLength; i += 1n) {
|
|
459
396
|
let usv = untagChar(arr[tagSimpleNumber(i)])
|
|
460
|
-
|
|
461
|
-
if (usv < 0x7Fn) {
|
|
462
|
-
WasmI32.store8(str + offset, usv, 0n)
|
|
463
|
-
offset += 1n
|
|
464
|
-
} else {
|
|
465
|
-
let mut count = 0n
|
|
466
|
-
let mut marker = 0n
|
|
467
|
-
if (usv <= 0x07FFn) {
|
|
468
|
-
count = 1n
|
|
469
|
-
marker = 0xC0n
|
|
470
|
-
} else if (usv <= 0xFFFFn) {
|
|
471
|
-
count = 2n
|
|
472
|
-
marker = 0xE0n
|
|
473
|
-
} else {
|
|
474
|
-
count = 3n
|
|
475
|
-
marker = 0xF0n
|
|
476
|
-
}
|
|
477
|
-
WasmI32.store8(str + offset, (usv >>> (6n * count)) + marker, 0n)
|
|
478
|
-
offset += 1n
|
|
479
|
-
|
|
480
|
-
while (count > 0n) {
|
|
481
|
-
let temp = usv >>> (6n * (count - 1n))
|
|
482
|
-
WasmI32.store8(str + offset, 0x80n | temp & 0x3Fn, 0n)
|
|
483
|
-
count -= 1n
|
|
484
|
-
offset += 1n
|
|
485
|
-
}
|
|
486
|
-
}
|
|
397
|
+
offset += writeUtf8CodePoint(str + offset, usv)
|
|
487
398
|
}
|
|
488
399
|
|
|
489
400
|
WasmI32.toGrain(str): String
|
|
@@ -529,21 +440,21 @@ provide let reverse = string => {
|
|
|
529
440
|
*/
|
|
530
441
|
@unsafe
|
|
531
442
|
provide let split = (separator: String, string: String) => {
|
|
532
|
-
use WasmI32.{ (+), (-), (&), (<<),
|
|
443
|
+
use WasmI32.{ (+), (-), (&), (<<), ltU as (<), gtU as (>), (==) }
|
|
533
444
|
|
|
534
|
-
let
|
|
535
|
-
let
|
|
445
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
446
|
+
let separatorPtr = WasmI32.fromGrain(separator)
|
|
447
|
+
let size = rawByteLength(stringPtr)
|
|
448
|
+
let psize = rawByteLength(separatorPtr)
|
|
536
449
|
|
|
537
450
|
if (psize == 0n) {
|
|
538
451
|
WasmI32.toGrain(explodeHelp(string, false)): Array<String>
|
|
539
452
|
} else if (psize > size) {
|
|
540
453
|
[> string]
|
|
541
454
|
} else {
|
|
542
|
-
let stringPtr =
|
|
543
|
-
let
|
|
544
|
-
|
|
545
|
-
let mut ptr = stringPtr + 8n
|
|
546
|
-
let mut pptr = separatorPtr + 8n
|
|
455
|
+
let stringPtr = stringPtr + _STR_DATA_OFFSET
|
|
456
|
+
let mut ptr = stringPtr
|
|
457
|
+
let mut pptr = separatorPtr + _STR_DATA_OFFSET
|
|
547
458
|
let end = ptr + size - psize + 1n
|
|
548
459
|
|
|
549
460
|
let mut numStrings = 1n
|
|
@@ -553,18 +464,10 @@ provide let split = (separator: String, string: String) => {
|
|
|
553
464
|
numStrings += 1n
|
|
554
465
|
}
|
|
555
466
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
556
|
-
|
|
557
|
-
ptr += 1n
|
|
558
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
559
|
-
ptr += 4n
|
|
560
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
561
|
-
ptr += 3n
|
|
562
|
-
} else {
|
|
563
|
-
ptr += 2n
|
|
564
|
-
}
|
|
467
|
+
ptr += utf8ByteCount(byte)
|
|
565
468
|
}
|
|
566
469
|
|
|
567
|
-
ptr = stringPtr
|
|
470
|
+
ptr = stringPtr
|
|
568
471
|
let mut last = ptr
|
|
569
472
|
let arr = allocateArray(numStrings)
|
|
570
473
|
let mut arrIdx = 0n
|
|
@@ -573,30 +476,22 @@ provide let split = (separator: String, string: String) => {
|
|
|
573
476
|
if (Memory.compare(ptr, pptr, psize) == 0n) {
|
|
574
477
|
let strSize = ptr - last
|
|
575
478
|
let str = allocateString(strSize)
|
|
576
|
-
Memory.copy(str +
|
|
577
|
-
WasmI32.store(arr +
|
|
578
|
-
arrIdx +=
|
|
479
|
+
Memory.copy(str + _STR_DATA_OFFSET, last, strSize)
|
|
480
|
+
WasmI32.store(arr + _ARRAY_DATA_OFFSET, str, arrIdx)
|
|
481
|
+
arrIdx += _ARRAY_ITEM_SIZE
|
|
579
482
|
ptr += psize
|
|
580
483
|
last = ptr
|
|
581
484
|
continue
|
|
582
485
|
}
|
|
583
486
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
584
|
-
|
|
585
|
-
ptr += 1n
|
|
586
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
587
|
-
ptr += 4n
|
|
588
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
589
|
-
ptr += 3n
|
|
590
|
-
} else {
|
|
591
|
-
ptr += 2n
|
|
592
|
-
}
|
|
487
|
+
ptr += utf8ByteCount(byte)
|
|
593
488
|
}
|
|
594
489
|
|
|
595
490
|
// Grab last string
|
|
596
|
-
let strSize = stringPtr +
|
|
491
|
+
let strSize = stringPtr + size - last
|
|
597
492
|
let lastStr = allocateString(strSize)
|
|
598
|
-
Memory.copy(lastStr +
|
|
599
|
-
WasmI32.store(arr + arrIdx, lastStr,
|
|
493
|
+
Memory.copy(lastStr + _STR_DATA_OFFSET, last, strSize)
|
|
494
|
+
WasmI32.store(arr + arrIdx, lastStr, _ARRAY_DATA_OFFSET)
|
|
600
495
|
|
|
601
496
|
ignore(separator)
|
|
602
497
|
ignore(string)
|
|
@@ -627,24 +522,14 @@ provide let split = (separator: String, string: String) => {
|
|
|
627
522
|
*/
|
|
628
523
|
@unsafe
|
|
629
524
|
provide let slice = (start: Number, end=length(string), string: String) => {
|
|
630
|
-
use WasmI32.{ (+), (-), (
|
|
631
|
-
|
|
632
|
-
let len = WasmI32.fromGrain(length(string)) >> 1n
|
|
633
|
-
let size = WasmI32.fromGrain(byteLength(string)) >> 1n
|
|
525
|
+
use WasmI32.{ (+), (-), (<), (>), (==) }
|
|
634
526
|
|
|
635
527
|
let stringPtr = WasmI32.fromGrain(string)
|
|
528
|
+
let len = untagSimpleNumber(length(string))
|
|
529
|
+
let size = rawByteLength(stringPtr)
|
|
636
530
|
|
|
637
|
-
let mut start =
|
|
638
|
-
|
|
639
|
-
throw InvalidArgument("Invalid start index")
|
|
640
|
-
}
|
|
641
|
-
start = start >> 1n
|
|
642
|
-
|
|
643
|
-
let mut to = WasmI32.fromGrain(end)
|
|
644
|
-
if ((to & 1n) != 1n) {
|
|
645
|
-
throw InvalidArgument("Invalid end index")
|
|
646
|
-
}
|
|
647
|
-
to = to >> 1n
|
|
531
|
+
let mut start = convSimpleNumber(start, "Invalid start index")
|
|
532
|
+
let mut to = convSimpleNumber(end, "Invalid end index")
|
|
648
533
|
|
|
649
534
|
if (start < 0n) {
|
|
650
535
|
start += len
|
|
@@ -661,7 +546,7 @@ provide let slice = (start: Number, end=length(string), string: String) => {
|
|
|
661
546
|
throw InvalidArgument("Start index exceeds end index")
|
|
662
547
|
}
|
|
663
548
|
|
|
664
|
-
let mut ptr = stringPtr +
|
|
549
|
+
let mut ptr = stringPtr + _STR_DATA_OFFSET
|
|
665
550
|
let mut begin = ptr
|
|
666
551
|
let mut end = ptr
|
|
667
552
|
let stop = ptr + size
|
|
@@ -669,7 +554,7 @@ provide let slice = (start: Number, end=length(string), string: String) => {
|
|
|
669
554
|
let mut idx = 0n
|
|
670
555
|
while (ptr < stop) {
|
|
671
556
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
672
|
-
if ((byte
|
|
557
|
+
if (isLeadingByte(byte)) {
|
|
673
558
|
if (idx == start) {
|
|
674
559
|
begin = ptr
|
|
675
560
|
}
|
|
@@ -682,7 +567,7 @@ provide let slice = (start: Number, end=length(string), string: String) => {
|
|
|
682
567
|
ptr += 1n
|
|
683
568
|
}
|
|
684
569
|
if (to == len) {
|
|
685
|
-
end = stringPtr +
|
|
570
|
+
end = stringPtr + _STR_DATA_OFFSET + size
|
|
686
571
|
}
|
|
687
572
|
if (start == to) {
|
|
688
573
|
begin = end
|
|
@@ -691,7 +576,7 @@ provide let slice = (start: Number, end=length(string), string: String) => {
|
|
|
691
576
|
let newSize = end - begin
|
|
692
577
|
let newString = allocateString(newSize)
|
|
693
578
|
|
|
694
|
-
Memory.copy(newString +
|
|
579
|
+
Memory.copy(newString + _STR_DATA_OFFSET, begin, newSize)
|
|
695
580
|
|
|
696
581
|
ignore(string)
|
|
697
582
|
|
|
@@ -715,27 +600,18 @@ provide let contains = (search: String, string: String) => {
|
|
|
715
600
|
// searching phase in O(nm) time complexity
|
|
716
601
|
// slightly (by coefficient) sub-linear in the average case
|
|
717
602
|
// http://igm.univ-mlv.fr/~lecroq/string/node13.html#SECTION00130
|
|
718
|
-
use WasmI32.{
|
|
719
|
-
(+),
|
|
720
|
-
(-),
|
|
721
|
-
(>>),
|
|
722
|
-
ltU as (<),
|
|
723
|
-
gtU as (>),
|
|
724
|
-
leU as (<=),
|
|
725
|
-
(==),
|
|
726
|
-
(!=),
|
|
727
|
-
}
|
|
603
|
+
use WasmI32.{ (+), (-), ltU as (<), gtU as (>), leU as (<=), (==), (!=) }
|
|
728
604
|
let pOrig = search
|
|
729
605
|
let sOrig = string
|
|
730
606
|
|
|
731
|
-
let n = WasmI32.fromGrain(byteLength(string)) >> 1n
|
|
732
|
-
let m = WasmI32.fromGrain(byteLength(search)) >> 1n
|
|
733
|
-
|
|
734
607
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
735
608
|
let mut searchPtr = WasmI32.fromGrain(search)
|
|
736
609
|
|
|
737
|
-
|
|
738
|
-
|
|
610
|
+
let n = rawByteLength(stringPtr)
|
|
611
|
+
let m = rawByteLength(searchPtr)
|
|
612
|
+
|
|
613
|
+
stringPtr += _STR_DATA_OFFSET
|
|
614
|
+
searchPtr += _STR_DATA_OFFSET
|
|
739
615
|
|
|
740
616
|
let mut j = 0n
|
|
741
617
|
and k = 0n
|
|
@@ -779,8 +655,8 @@ provide let contains = (search: String, string: String) => {
|
|
|
779
655
|
j += k
|
|
780
656
|
} else {
|
|
781
657
|
if (
|
|
782
|
-
Memory.compare(searchPtr + 2n, stringPtr + j + 2n, m - 2n) == 0n
|
|
783
|
-
WasmI32.load8U(searchPtr, 0n) == WasmI32.load8U(stringPtr + j, 0n)
|
|
658
|
+
Memory.compare(searchPtr + 2n, stringPtr + j + 2n, m - 2n) == 0n
|
|
659
|
+
&& WasmI32.load8U(searchPtr, 0n) == WasmI32.load8U(stringPtr + j, 0n)
|
|
784
660
|
) {
|
|
785
661
|
return true
|
|
786
662
|
}
|
|
@@ -814,11 +690,11 @@ provide let startsWith = (search: String, string: String) => {
|
|
|
814
690
|
let mut searchPtr = WasmI32.fromGrain(search)
|
|
815
691
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
816
692
|
|
|
817
|
-
let n =
|
|
818
|
-
let m =
|
|
693
|
+
let n = rawByteLength(stringPtr)
|
|
694
|
+
let m = rawByteLength(searchPtr)
|
|
819
695
|
|
|
820
|
-
stringPtr +=
|
|
821
|
-
searchPtr +=
|
|
696
|
+
stringPtr += _STR_DATA_OFFSET
|
|
697
|
+
searchPtr += _STR_DATA_OFFSET
|
|
822
698
|
|
|
823
699
|
// Bail if pattern length is longer than input length
|
|
824
700
|
let result = if (m > n) {
|
|
@@ -853,11 +729,11 @@ provide let endsWith = (search: String, string: String) => {
|
|
|
853
729
|
let mut searchPtr = WasmI32.fromGrain(search)
|
|
854
730
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
855
731
|
|
|
856
|
-
let n =
|
|
857
|
-
let m =
|
|
732
|
+
let n = rawByteLength(stringPtr)
|
|
733
|
+
let m = rawByteLength(searchPtr)
|
|
858
734
|
|
|
859
|
-
stringPtr +=
|
|
860
|
-
searchPtr +=
|
|
735
|
+
stringPtr += _STR_DATA_OFFSET
|
|
736
|
+
searchPtr += _STR_DATA_OFFSET
|
|
861
737
|
|
|
862
738
|
// Bail if pattern length is longer than input length
|
|
863
739
|
let result = if (m > n) {
|
|
@@ -896,16 +772,16 @@ provide let replaceFirst = (
|
|
|
896
772
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
897
773
|
let mut replacementPtr = WasmI32.fromGrain(replacement)
|
|
898
774
|
|
|
899
|
-
let patternLen =
|
|
900
|
-
let stringLen =
|
|
901
|
-
let replacementLen =
|
|
775
|
+
let patternLen = rawByteLength(patternPtr)
|
|
776
|
+
let stringLen = rawByteLength(stringPtr)
|
|
777
|
+
let replacementLen = rawByteLength(replacementPtr)
|
|
902
778
|
// Bail if search str is longer than the string
|
|
903
779
|
if (stringLen < patternLen) {
|
|
904
780
|
return string
|
|
905
781
|
}
|
|
906
|
-
patternPtr +=
|
|
907
|
-
stringPtr +=
|
|
908
|
-
replacementPtr +=
|
|
782
|
+
patternPtr += _STR_DATA_OFFSET
|
|
783
|
+
stringPtr += _STR_DATA_OFFSET
|
|
784
|
+
replacementPtr += _STR_DATA_OFFSET
|
|
909
785
|
|
|
910
786
|
// Search for an instance of the string
|
|
911
787
|
let mut foundIndex = -1n
|
|
@@ -916,7 +792,7 @@ provide let replaceFirst = (
|
|
|
916
792
|
if (Memory.compare(i, patternPtr, patternLen) == 0n) {
|
|
917
793
|
// Create the new string
|
|
918
794
|
let str = allocateString(stringLen - patternLen + replacementLen)
|
|
919
|
-
let strPtr = str +
|
|
795
|
+
let strPtr = str + _STR_DATA_OFFSET
|
|
920
796
|
Memory.copy(strPtr, stringPtr, foundIndex)
|
|
921
797
|
Memory.copy(strPtr + foundIndex, replacementPtr, replacementLen)
|
|
922
798
|
Memory.copy(
|
|
@@ -960,17 +836,17 @@ provide let replaceLast = (
|
|
|
960
836
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
961
837
|
let mut replacementPtr = WasmI32.fromGrain(replacement)
|
|
962
838
|
|
|
963
|
-
let patternLen =
|
|
964
|
-
let stringLen =
|
|
965
|
-
let replacementLen =
|
|
839
|
+
let patternLen = rawByteLength(patternPtr)
|
|
840
|
+
let stringLen = rawByteLength(stringPtr)
|
|
841
|
+
let replacementLen = rawByteLength(replacementPtr)
|
|
966
842
|
|
|
967
843
|
// Bail if search str is longer than the string
|
|
968
844
|
if (stringLen < patternLen) {
|
|
969
845
|
return string
|
|
970
846
|
}
|
|
971
|
-
patternPtr +=
|
|
972
|
-
stringPtr +=
|
|
973
|
-
replacementPtr +=
|
|
847
|
+
patternPtr += _STR_DATA_OFFSET
|
|
848
|
+
stringPtr += _STR_DATA_OFFSET
|
|
849
|
+
replacementPtr += _STR_DATA_OFFSET
|
|
974
850
|
|
|
975
851
|
let mut found = false
|
|
976
852
|
// Search for an instance of the string
|
|
@@ -982,7 +858,7 @@ provide let replaceLast = (
|
|
|
982
858
|
if (Memory.compare(i, patternPtr, patternLen) == 0n) {
|
|
983
859
|
// Create the new string
|
|
984
860
|
let str = allocateString(stringLen - patternLen + replacementLen)
|
|
985
|
-
let strPtr = str +
|
|
861
|
+
let strPtr = str + _STR_DATA_OFFSET
|
|
986
862
|
Memory.copy(strPtr, stringPtr, foundIndex)
|
|
987
863
|
Memory.copy(strPtr + foundIndex, replacementPtr, replacementLen)
|
|
988
864
|
Memory.copy(
|
|
@@ -1020,23 +896,23 @@ provide let replaceAll = (
|
|
|
1020
896
|
replacement: String,
|
|
1021
897
|
string: String,
|
|
1022
898
|
) => {
|
|
1023
|
-
use WasmI32.{ (+), (-), (*),
|
|
899
|
+
use WasmI32.{ (+), (-), (*), gtU as (>), ltU as (<), (==) }
|
|
1024
900
|
|
|
1025
901
|
let mut patternPtr = WasmI32.fromGrain(searchPattern)
|
|
1026
902
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
1027
903
|
let mut replacementPtr = WasmI32.fromGrain(replacement)
|
|
1028
904
|
|
|
1029
|
-
let patternLen =
|
|
1030
|
-
let stringLen =
|
|
1031
|
-
let replacementLen =
|
|
905
|
+
let patternLen = rawByteLength(patternPtr)
|
|
906
|
+
let stringLen = rawByteLength(stringPtr)
|
|
907
|
+
let replacementLen = rawByteLength(replacementPtr)
|
|
1032
908
|
|
|
1033
909
|
// Bail if search str is longer than the string
|
|
1034
910
|
let result = if (stringLen < patternLen) {
|
|
1035
911
|
string
|
|
1036
912
|
} else {
|
|
1037
|
-
patternPtr +=
|
|
1038
|
-
stringPtr +=
|
|
1039
|
-
replacementPtr +=
|
|
913
|
+
patternPtr += _STR_DATA_OFFSET
|
|
914
|
+
stringPtr += _STR_DATA_OFFSET
|
|
915
|
+
replacementPtr += _STR_DATA_OFFSET
|
|
1040
916
|
|
|
1041
917
|
let mut found = false
|
|
1042
918
|
// Search for an instance of the string
|
|
@@ -1060,7 +936,7 @@ provide let replaceAll = (
|
|
|
1060
936
|
let str = allocateString(
|
|
1061
937
|
stringLen - (patternLen - replacementLen) * foundCount
|
|
1062
938
|
)
|
|
1063
|
-
let mut strPtr = str +
|
|
939
|
+
let mut strPtr = str + _STR_DATA_OFFSET
|
|
1064
940
|
let mut lastIndex = 0n
|
|
1065
941
|
while (true) {
|
|
1066
942
|
match (foundIndexes) {
|
|
@@ -1102,44 +978,30 @@ let _OFFSET_NAME = "offset"
|
|
|
1102
978
|
|
|
1103
979
|
@unsafe
|
|
1104
980
|
let grainToWasmNumber = (num, name) => {
|
|
1105
|
-
use WasmI32.{ (
|
|
1106
|
-
let
|
|
1107
|
-
if (
|
|
1108
|
-
|
|
1109
|
-
throw Exception.InvalidArgument(name ++ str)
|
|
981
|
+
use WasmI32.{ (<) }
|
|
982
|
+
let _num = convSimpleNumber(num, name ++ " argument must be an integer")
|
|
983
|
+
if (_num < 0n) {
|
|
984
|
+
throw InvalidArgument(name ++ " argument must be non-negative")
|
|
1110
985
|
}
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
let str = " argument must be non-negative"
|
|
1114
|
-
throw Exception.InvalidArgument(name ++ str)
|
|
1115
|
-
}
|
|
1116
|
-
num
|
|
986
|
+
ignore(num)
|
|
987
|
+
_num
|
|
1117
988
|
}
|
|
1118
989
|
|
|
1119
990
|
@unsafe
|
|
1120
991
|
let utf16Length = (s: String) => {
|
|
1121
|
-
use WasmI32.{ (+), (
|
|
1122
|
-
|
|
1123
|
-
let size = WasmI32.fromGrain(byteLength(s)) >>> 1n
|
|
1124
|
-
let len = WasmI32.fromGrain(length(s)) >>> 1n
|
|
992
|
+
use WasmI32.{ (+), (<<), ltU as (<), (==) }
|
|
1125
993
|
|
|
1126
994
|
let sPtr = WasmI32.fromGrain(s)
|
|
995
|
+
let size = rawByteLength(sPtr)
|
|
996
|
+
let len = untagSimpleNumber(length(s))
|
|
1127
997
|
|
|
1128
|
-
let mut ptr = sPtr +
|
|
998
|
+
let mut ptr = sPtr + _STR_DATA_OFFSET
|
|
1129
999
|
let end = ptr + size
|
|
1130
1000
|
let mut size = 0n // <- number of UTF-16 code words
|
|
1131
1001
|
|
|
1132
1002
|
while (ptr < end) {
|
|
1133
1003
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
1134
|
-
let n =
|
|
1135
|
-
1n
|
|
1136
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
1137
|
-
4n
|
|
1138
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
1139
|
-
3n
|
|
1140
|
-
} else {
|
|
1141
|
-
2n
|
|
1142
|
-
}
|
|
1004
|
+
let n = utf8ByteCount(byte)
|
|
1143
1005
|
if (n == 4n) {
|
|
1144
1006
|
size += 2n
|
|
1145
1007
|
} else {
|
|
@@ -1164,11 +1026,6 @@ let encodedLength = (s: String, encoding) => {
|
|
|
1164
1026
|
}
|
|
1165
1027
|
}
|
|
1166
1028
|
|
|
1167
|
-
@unsafe
|
|
1168
|
-
let mut _BYTES_SIZE_OFFSET = 4n
|
|
1169
|
-
@unsafe
|
|
1170
|
-
let mut _BYTES_OFFSET = 8n
|
|
1171
|
-
|
|
1172
1029
|
@unsafe
|
|
1173
1030
|
let encodeAtHelp = (
|
|
1174
1031
|
string: String,
|
|
@@ -1178,18 +1035,17 @@ let encodeAtHelp = (
|
|
|
1178
1035
|
destPos: Number,
|
|
1179
1036
|
) => {
|
|
1180
1037
|
use WasmI32.{ (+), (-), (&), (>>>), ltU as (<), (>), leU as (<=), (==) }
|
|
1181
|
-
let byteSize = WasmI32.fromGrain(byteLength(string)) >>> 1n
|
|
1182
|
-
let len = WasmI32.fromGrain(length(string)) >>> 1n
|
|
1183
|
-
|
|
1184
1038
|
let stringPtr = WasmI32.fromGrain(string)
|
|
1039
|
+
let byteSize = rawByteLength(stringPtr)
|
|
1040
|
+
let len = untagSimpleNumber(length(string))
|
|
1185
1041
|
|
|
1186
|
-
let mut ptr = stringPtr +
|
|
1042
|
+
let mut ptr = stringPtr + _STR_DATA_OFFSET
|
|
1187
1043
|
let end = ptr + byteSize
|
|
1188
1044
|
|
|
1189
1045
|
let bytes = WasmI32.fromGrain(dest)
|
|
1190
1046
|
let mut bytesIdx = grainToWasmNumber(destPos, _OFFSET_NAME)
|
|
1191
1047
|
|
|
1192
|
-
let destSize = WasmI32.load(bytes,
|
|
1048
|
+
let destSize = WasmI32.load(bytes, _BYTES_LEN_OFFSET)
|
|
1193
1049
|
|
|
1194
1050
|
if (includeBom) {
|
|
1195
1051
|
match (encoding) {
|
|
@@ -1197,45 +1053,45 @@ let encodeAtHelp = (
|
|
|
1197
1053
|
if (bytesIdx + 3n > destSize) {
|
|
1198
1054
|
throw IndexOutOfBounds
|
|
1199
1055
|
}
|
|
1200
|
-
WasmI32.store8(bytes + bytesIdx, 0xEFn,
|
|
1201
|
-
WasmI32.store8(bytes + bytesIdx + 1n, 0xBBn,
|
|
1202
|
-
WasmI32.store8(bytes + bytesIdx + 2n, 0xBFn,
|
|
1056
|
+
WasmI32.store8(bytes + bytesIdx, 0xEFn, _BYTES_DATA_OFFSET)
|
|
1057
|
+
WasmI32.store8(bytes + bytesIdx + 1n, 0xBBn, _BYTES_DATA_OFFSET)
|
|
1058
|
+
WasmI32.store8(bytes + bytesIdx + 2n, 0xBFn, _BYTES_DATA_OFFSET)
|
|
1203
1059
|
bytesIdx += 3n
|
|
1204
1060
|
},
|
|
1205
1061
|
UTF16_BE => {
|
|
1206
1062
|
if (bytesIdx + 2n > destSize) {
|
|
1207
1063
|
throw IndexOutOfBounds
|
|
1208
1064
|
}
|
|
1209
|
-
WasmI32.store8(bytes + bytesIdx, 0xFEn,
|
|
1210
|
-
WasmI32.store8(bytes + bytesIdx + 1n, 0xFFn,
|
|
1065
|
+
WasmI32.store8(bytes + bytesIdx, 0xFEn, _BYTES_DATA_OFFSET)
|
|
1066
|
+
WasmI32.store8(bytes + bytesIdx + 1n, 0xFFn, _BYTES_DATA_OFFSET)
|
|
1211
1067
|
bytesIdx += 2n
|
|
1212
1068
|
},
|
|
1213
1069
|
UTF16_LE => {
|
|
1214
1070
|
if (bytesIdx + 2n > destSize) {
|
|
1215
1071
|
throw IndexOutOfBounds
|
|
1216
1072
|
}
|
|
1217
|
-
WasmI32.store8(bytes + bytesIdx, 0xFFn,
|
|
1218
|
-
WasmI32.store8(bytes + bytesIdx + 1n, 0xFEn,
|
|
1073
|
+
WasmI32.store8(bytes + bytesIdx, 0xFFn, _BYTES_DATA_OFFSET)
|
|
1074
|
+
WasmI32.store8(bytes + bytesIdx + 1n, 0xFEn, _BYTES_DATA_OFFSET)
|
|
1219
1075
|
bytesIdx += 2n
|
|
1220
1076
|
},
|
|
1221
1077
|
UTF32_BE => {
|
|
1222
1078
|
if (bytesIdx + 4n > destSize) {
|
|
1223
1079
|
throw IndexOutOfBounds
|
|
1224
1080
|
}
|
|
1225
|
-
WasmI32.store8(bytes + bytesIdx, 0n,
|
|
1226
|
-
WasmI32.store8(bytes + bytesIdx + 1n, 0n,
|
|
1227
|
-
WasmI32.store8(bytes + bytesIdx + 2n, 0xFEn,
|
|
1228
|
-
WasmI32.store8(bytes + bytesIdx + 3n, 0xFFn,
|
|
1081
|
+
WasmI32.store8(bytes + bytesIdx, 0n, _BYTES_DATA_OFFSET)
|
|
1082
|
+
WasmI32.store8(bytes + bytesIdx + 1n, 0n, _BYTES_DATA_OFFSET)
|
|
1083
|
+
WasmI32.store8(bytes + bytesIdx + 2n, 0xFEn, _BYTES_DATA_OFFSET)
|
|
1084
|
+
WasmI32.store8(bytes + bytesIdx + 3n, 0xFFn, _BYTES_DATA_OFFSET)
|
|
1229
1085
|
bytesIdx += 4n
|
|
1230
1086
|
},
|
|
1231
1087
|
UTF32_LE => {
|
|
1232
1088
|
if (bytesIdx + 4n > destSize) {
|
|
1233
1089
|
throw IndexOutOfBounds
|
|
1234
1090
|
}
|
|
1235
|
-
WasmI32.store8(bytes + bytesIdx, 0xFFn,
|
|
1236
|
-
WasmI32.store8(bytes + bytesIdx + 1n, 0xFEn,
|
|
1237
|
-
WasmI32.store8(bytes + bytesIdx + 2n, 0n,
|
|
1238
|
-
WasmI32.store8(bytes + bytesIdx + 3n, 0n,
|
|
1091
|
+
WasmI32.store8(bytes + bytesIdx, 0xFFn, _BYTES_DATA_OFFSET)
|
|
1092
|
+
WasmI32.store8(bytes + bytesIdx + 1n, 0xFEn, _BYTES_DATA_OFFSET)
|
|
1093
|
+
WasmI32.store8(bytes + bytesIdx + 2n, 0n, _BYTES_DATA_OFFSET)
|
|
1094
|
+
WasmI32.store8(bytes + bytesIdx + 3n, 0n, _BYTES_DATA_OFFSET)
|
|
1239
1095
|
bytesIdx += 4n
|
|
1240
1096
|
},
|
|
1241
1097
|
}
|
|
@@ -1249,21 +1105,13 @@ let encodeAtHelp = (
|
|
|
1249
1105
|
if (bytesIdx + byteSize > destSize) {
|
|
1250
1106
|
throw IndexOutOfBounds
|
|
1251
1107
|
}
|
|
1252
|
-
Memory.copy(bytes + bytesIdx +
|
|
1108
|
+
Memory.copy(bytes + bytesIdx + _BYTES_DATA_OFFSET, ptr, byteSize)
|
|
1253
1109
|
},
|
|
1254
1110
|
_ => {
|
|
1255
1111
|
while (ptr < end) {
|
|
1256
1112
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
1257
1113
|
// number of bytes spanning this UTF-8-encoded scalar value
|
|
1258
|
-
let n =
|
|
1259
|
-
1n
|
|
1260
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
1261
|
-
4n
|
|
1262
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
1263
|
-
3n
|
|
1264
|
-
} else {
|
|
1265
|
-
2n
|
|
1266
|
-
}
|
|
1114
|
+
let n = utf8ByteCount(byte)
|
|
1267
1115
|
match (encoding) {
|
|
1268
1116
|
UTF8 => {
|
|
1269
1117
|
// With the optimization above for bulk memory copy, this match
|
|
@@ -1271,7 +1119,7 @@ let encodeAtHelp = (
|
|
|
1271
1119
|
if (bytesIdx + n > destSize) {
|
|
1272
1120
|
throw IndexOutOfBounds
|
|
1273
1121
|
}
|
|
1274
|
-
Memory.copy(bytes + bytesIdx +
|
|
1122
|
+
Memory.copy(bytes + bytesIdx + _BYTES_DATA_OFFSET, ptr, n)
|
|
1275
1123
|
bytesIdx += n
|
|
1276
1124
|
},
|
|
1277
1125
|
UTF16_BE => {
|
|
@@ -1284,12 +1132,12 @@ let encodeAtHelp = (
|
|
|
1284
1132
|
WasmI32.store8(
|
|
1285
1133
|
bytes + bytesIdx,
|
|
1286
1134
|
(codePoint & 0xff00n) >>> 8n,
|
|
1287
|
-
|
|
1135
|
+
_BYTES_DATA_OFFSET
|
|
1288
1136
|
)
|
|
1289
1137
|
WasmI32.store8(
|
|
1290
1138
|
bytes + bytesIdx + 1n,
|
|
1291
1139
|
codePoint & 0xffn,
|
|
1292
|
-
|
|
1140
|
+
_BYTES_DATA_OFFSET
|
|
1293
1141
|
)
|
|
1294
1142
|
bytesIdx += 2n
|
|
1295
1143
|
} else {
|
|
@@ -1303,15 +1151,23 @@ let encodeAtHelp = (
|
|
|
1303
1151
|
WasmI32.store8(
|
|
1304
1152
|
bytes + bytesIdx,
|
|
1305
1153
|
(w1 & 0xff00n) >>> 8n,
|
|
1306
|
-
|
|
1154
|
+
_BYTES_DATA_OFFSET
|
|
1155
|
+
)
|
|
1156
|
+
WasmI32.store8(
|
|
1157
|
+
bytes + bytesIdx + 1n,
|
|
1158
|
+
w1 & 0xffn,
|
|
1159
|
+
_BYTES_DATA_OFFSET
|
|
1307
1160
|
)
|
|
1308
|
-
WasmI32.store8(bytes + bytesIdx + 1n, w1 & 0xffn, _BYTES_OFFSET)
|
|
1309
1161
|
WasmI32.store8(
|
|
1310
1162
|
bytes + bytesIdx + 2n,
|
|
1311
1163
|
(w2 & 0xff00n) >>> 8n,
|
|
1312
|
-
|
|
1164
|
+
_BYTES_DATA_OFFSET
|
|
1165
|
+
)
|
|
1166
|
+
WasmI32.store8(
|
|
1167
|
+
bytes + bytesIdx + 3n,
|
|
1168
|
+
w2 & 0xffn,
|
|
1169
|
+
_BYTES_DATA_OFFSET
|
|
1313
1170
|
)
|
|
1314
|
-
WasmI32.store8(bytes + bytesIdx + 3n, w2 & 0xffn, _BYTES_OFFSET)
|
|
1315
1171
|
bytesIdx += 4n
|
|
1316
1172
|
}
|
|
1317
1173
|
},
|
|
@@ -1322,11 +1178,15 @@ let encodeAtHelp = (
|
|
|
1322
1178
|
throw IndexOutOfBounds
|
|
1323
1179
|
}
|
|
1324
1180
|
// <lo><hi>
|
|
1325
|
-
WasmI32.store8(
|
|
1181
|
+
WasmI32.store8(
|
|
1182
|
+
bytes + bytesIdx,
|
|
1183
|
+
codePoint & 0xffn,
|
|
1184
|
+
_BYTES_DATA_OFFSET
|
|
1185
|
+
)
|
|
1326
1186
|
WasmI32.store8(
|
|
1327
1187
|
bytes + bytesIdx + 1n,
|
|
1328
1188
|
(codePoint & 0xff00n) >>> 8n,
|
|
1329
|
-
|
|
1189
|
+
_BYTES_DATA_OFFSET
|
|
1330
1190
|
)
|
|
1331
1191
|
bytesIdx += 2n
|
|
1332
1192
|
} else {
|
|
@@ -1337,17 +1197,21 @@ let encodeAtHelp = (
|
|
|
1337
1197
|
let uPrime = codePoint - 0x10000n
|
|
1338
1198
|
let w1 = ((uPrime & 0b11111111110000000000n) >>> 10n) + 0xD800n // High surrogate
|
|
1339
1199
|
let w2 = (uPrime & 0b00000000001111111111n) + 0xDC00n // Low surrogate
|
|
1340
|
-
WasmI32.store8(bytes + bytesIdx, w1 & 0xffn,
|
|
1200
|
+
WasmI32.store8(bytes + bytesIdx, w1 & 0xffn, _BYTES_DATA_OFFSET)
|
|
1341
1201
|
WasmI32.store8(
|
|
1342
1202
|
bytes + bytesIdx + 1n,
|
|
1343
1203
|
(w1 & 0xff00n) >>> 8n,
|
|
1344
|
-
|
|
1204
|
+
_BYTES_DATA_OFFSET
|
|
1205
|
+
)
|
|
1206
|
+
WasmI32.store8(
|
|
1207
|
+
bytes + bytesIdx + 2n,
|
|
1208
|
+
w2 & 0xffn,
|
|
1209
|
+
_BYTES_DATA_OFFSET
|
|
1345
1210
|
)
|
|
1346
|
-
WasmI32.store8(bytes + bytesIdx + 2n, w2 & 0xffn, _BYTES_OFFSET)
|
|
1347
1211
|
WasmI32.store8(
|
|
1348
1212
|
bytes + bytesIdx + 3n,
|
|
1349
1213
|
(w2 & 0xff00n) >>> 8n,
|
|
1350
|
-
|
|
1214
|
+
_BYTES_DATA_OFFSET
|
|
1351
1215
|
)
|
|
1352
1216
|
bytesIdx += 4n
|
|
1353
1217
|
}
|
|
@@ -1360,22 +1224,22 @@ let encodeAtHelp = (
|
|
|
1360
1224
|
WasmI32.store8(
|
|
1361
1225
|
bytes + bytesIdx,
|
|
1362
1226
|
(codePoint & 0xff000000n) >>> 24n,
|
|
1363
|
-
|
|
1227
|
+
_BYTES_DATA_OFFSET
|
|
1364
1228
|
)
|
|
1365
1229
|
WasmI32.store8(
|
|
1366
1230
|
bytes + bytesIdx + 1n,
|
|
1367
1231
|
(codePoint & 0xff0000n) >>> 16n,
|
|
1368
|
-
|
|
1232
|
+
_BYTES_DATA_OFFSET
|
|
1369
1233
|
)
|
|
1370
1234
|
WasmI32.store8(
|
|
1371
1235
|
bytes + bytesIdx + 2n,
|
|
1372
1236
|
(codePoint & 0xff00n) >>> 8n,
|
|
1373
|
-
|
|
1237
|
+
_BYTES_DATA_OFFSET
|
|
1374
1238
|
)
|
|
1375
1239
|
WasmI32.store8(
|
|
1376
1240
|
bytes + bytesIdx + 3n,
|
|
1377
1241
|
codePoint & 0xffn,
|
|
1378
|
-
|
|
1242
|
+
_BYTES_DATA_OFFSET
|
|
1379
1243
|
)
|
|
1380
1244
|
bytesIdx += 4n
|
|
1381
1245
|
},
|
|
@@ -1384,21 +1248,25 @@ let encodeAtHelp = (
|
|
|
1384
1248
|
throw IndexOutOfBounds
|
|
1385
1249
|
}
|
|
1386
1250
|
let codePoint = getCodePoint(ptr)
|
|
1387
|
-
WasmI32.store8(
|
|
1251
|
+
WasmI32.store8(
|
|
1252
|
+
bytes + bytesIdx,
|
|
1253
|
+
codePoint & 0xffn,
|
|
1254
|
+
_BYTES_DATA_OFFSET
|
|
1255
|
+
)
|
|
1388
1256
|
WasmI32.store8(
|
|
1389
1257
|
bytes + bytesIdx + 1n,
|
|
1390
1258
|
(codePoint & 0xff00n) >>> 8n,
|
|
1391
|
-
|
|
1259
|
+
_BYTES_DATA_OFFSET
|
|
1392
1260
|
)
|
|
1393
1261
|
WasmI32.store8(
|
|
1394
1262
|
bytes + bytesIdx + 2n,
|
|
1395
1263
|
(codePoint & 0xff0000n) >>> 16n,
|
|
1396
|
-
|
|
1264
|
+
_BYTES_DATA_OFFSET
|
|
1397
1265
|
)
|
|
1398
1266
|
WasmI32.store8(
|
|
1399
1267
|
bytes + bytesIdx + 3n,
|
|
1400
1268
|
(codePoint & 0xff000000n) >>> 24n,
|
|
1401
|
-
|
|
1269
|
+
_BYTES_DATA_OFFSET
|
|
1402
1270
|
)
|
|
1403
1271
|
bytesIdx += 4n
|
|
1404
1272
|
},
|
|
@@ -1446,8 +1314,7 @@ let encodeHelp = (string: String, encoding: Encoding, includeBom: Bool) => {
|
|
|
1446
1314
|
} else {
|
|
1447
1315
|
0
|
|
1448
1316
|
})
|
|
1449
|
-
|
|
1450
|
-
let bytes = WasmI32.toGrain(allocateBytes(WasmI32.fromGrain(size) >>> 1n))
|
|
1317
|
+
let bytes = WasmI32.toGrain(allocateBytes(untagSimpleNumber(size)))
|
|
1451
1318
|
encodeAtHelp(string, encoding, includeBom, bytes, 0)
|
|
1452
1319
|
}
|
|
1453
1320
|
|
|
@@ -1468,92 +1335,42 @@ provide let encode = (string: String, encoding: Encoding, includeBom=false) => {
|
|
|
1468
1335
|
|
|
1469
1336
|
// Byte->String decoding and helper functions:
|
|
1470
1337
|
|
|
1471
|
-
@unsafe
|
|
1472
|
-
let writeUtf8CodePoint = (ptr, codePoint) => {
|
|
1473
|
-
use WasmI32.{ (+), (-), (&), (|), (>>>), ltU as (<), leU as (<=), (==) }
|
|
1474
|
-
if (codePoint <= 0x007Fn) {
|
|
1475
|
-
// Code points in the ASCII range are written as just one byte with the
|
|
1476
|
-
// leading bit equal to zero (0xxxxxxx). Just store the value as one byte
|
|
1477
|
-
// directly. Note that the value is already guaranteed to start with most
|
|
1478
|
-
// significant bit equal to zero because of the check in the if statement
|
|
1479
|
-
// above, so there's no need to bit-mask it.
|
|
1480
|
-
WasmI32.store8(ptr, codePoint, 0n)
|
|
1481
|
-
1n
|
|
1482
|
-
} else if (codePoint <= 0x07FFn) {
|
|
1483
|
-
// Code points in the range 0x0080..0x07FF are written as two bytes.
|
|
1484
|
-
// The first byte has a three bit prefix of 110, followed by 5 bits of the
|
|
1485
|
-
// codepoint. The second byte has a two bit prefix of 10, followed by 6 bits
|
|
1486
|
-
// of the codepoint.
|
|
1487
|
-
let high = codePoint >>> 6n & 0b000_11111n | 0b110_00000n
|
|
1488
|
-
let low = codePoint & 0b00_111111n | 0b10_000000n
|
|
1489
|
-
WasmI32.store8(ptr, high, 0n)
|
|
1490
|
-
WasmI32.store8(ptr + 1n, low, 0n)
|
|
1491
|
-
2n
|
|
1492
|
-
} else if (codePoint <= 0xFFFFn) {
|
|
1493
|
-
// Code points in the range 0x0800..0xFFFF are written as three bytes.
|
|
1494
|
-
// The first byte has a four bit prefix of 1110, followed by 4 bits of the
|
|
1495
|
-
// codepoint. Remaining bytes each have a two bit prefix of 10, followed by
|
|
1496
|
-
// 6 bits of the codepoint.
|
|
1497
|
-
let high = codePoint >>> 12n & 0b0000_1111n | 0b1110_0000n
|
|
1498
|
-
let mid = codePoint >>> 6n & 0b00_111111n | 0b10_000000n
|
|
1499
|
-
let low = codePoint & 0b00_111111n | 0b10_000000n
|
|
1500
|
-
WasmI32.store8(ptr, high, 0n)
|
|
1501
|
-
WasmI32.store8(ptr + 1n, mid, 0n)
|
|
1502
|
-
WasmI32.store8(ptr + 2n, low, 0n)
|
|
1503
|
-
3n
|
|
1504
|
-
} else {
|
|
1505
|
-
// Code points in the range 0x10000..0x10FFFF are written as four bytes.
|
|
1506
|
-
// The first byte has a five bit prefix of 11110, followed by 3 bits of the
|
|
1507
|
-
// codepoint. Remaining bytes each have a two bit prefix of 10, followed by
|
|
1508
|
-
// 6 bits of the codepoint.
|
|
1509
|
-
let high = codePoint >>> 18n & 0b00000_111n | 0b11110_000n
|
|
1510
|
-
let mid1 = codePoint >>> 12n & 0b00_111111n | 0b10_000000n
|
|
1511
|
-
let mid2 = codePoint >>> 6n & 0b00_111111n | 0b10_000000n
|
|
1512
|
-
let low = codePoint & 0b00_111111n | 0b10_000000n
|
|
1513
|
-
WasmI32.store8(ptr, high, 0n)
|
|
1514
|
-
WasmI32.store8(ptr + 1n, mid1, 0n)
|
|
1515
|
-
WasmI32.store8(ptr + 2n, mid2, 0n)
|
|
1516
|
-
WasmI32.store8(ptr + 3n, low, 0n)
|
|
1517
|
-
4n
|
|
1518
|
-
}
|
|
1519
|
-
}
|
|
1520
|
-
|
|
1521
1338
|
@unsafe
|
|
1522
1339
|
let bytesHaveBom = (bytes: Bytes, encoding: Encoding, start: WasmI32) => {
|
|
1523
1340
|
use WasmI32.{ (+), geU as (>=), (==) }
|
|
1524
1341
|
let ptr = WasmI32.fromGrain(bytes)
|
|
1525
|
-
let bytesSize = WasmI32.load(ptr,
|
|
1342
|
+
let bytesSize = WasmI32.load(ptr, _BYTES_LEN_OFFSET)
|
|
1526
1343
|
let ptr = ptr + start
|
|
1527
1344
|
let result = match (encoding) {
|
|
1528
1345
|
UTF8 => {
|
|
1529
|
-
bytesSize >= 3n
|
|
1530
|
-
WasmI32.load8U(ptr,
|
|
1531
|
-
WasmI32.load8U(ptr + 1n,
|
|
1532
|
-
WasmI32.load8U(ptr + 2n,
|
|
1346
|
+
bytesSize >= 3n
|
|
1347
|
+
&& WasmI32.load8U(ptr, _BYTES_DATA_OFFSET) == 0xEFn
|
|
1348
|
+
&& WasmI32.load8U(ptr + 1n, _BYTES_DATA_OFFSET) == 0xBBn
|
|
1349
|
+
&& WasmI32.load8U(ptr + 2n, _BYTES_DATA_OFFSET) == 0xBFn
|
|
1533
1350
|
},
|
|
1534
1351
|
UTF16_BE => {
|
|
1535
|
-
bytesSize >= 2n
|
|
1536
|
-
WasmI32.load8U(ptr,
|
|
1537
|
-
WasmI32.load8U(ptr + 1n,
|
|
1352
|
+
bytesSize >= 2n
|
|
1353
|
+
&& WasmI32.load8U(ptr, _BYTES_DATA_OFFSET) == 0xFEn
|
|
1354
|
+
&& WasmI32.load8U(ptr + 1n, _BYTES_DATA_OFFSET) == 0xFFn
|
|
1538
1355
|
},
|
|
1539
1356
|
UTF16_LE => {
|
|
1540
|
-
bytesSize >= 2n
|
|
1541
|
-
WasmI32.load8U(ptr,
|
|
1542
|
-
WasmI32.load8U(ptr + 1n,
|
|
1357
|
+
bytesSize >= 2n
|
|
1358
|
+
&& WasmI32.load8U(ptr, _BYTES_DATA_OFFSET) == 0xFFn
|
|
1359
|
+
&& WasmI32.load8U(ptr + 1n, _BYTES_DATA_OFFSET) == 0xFEn
|
|
1543
1360
|
},
|
|
1544
1361
|
UTF32_BE => {
|
|
1545
|
-
bytesSize >= 4n
|
|
1546
|
-
WasmI32.load8U(ptr,
|
|
1547
|
-
WasmI32.load8U(ptr + 1n,
|
|
1548
|
-
WasmI32.load8U(ptr + 2n,
|
|
1549
|
-
WasmI32.load8U(ptr + 3n,
|
|
1362
|
+
bytesSize >= 4n
|
|
1363
|
+
&& WasmI32.load8U(ptr, _BYTES_DATA_OFFSET) == 0x00n
|
|
1364
|
+
&& WasmI32.load8U(ptr + 1n, _BYTES_DATA_OFFSET) == 0x00n
|
|
1365
|
+
&& WasmI32.load8U(ptr + 2n, _BYTES_DATA_OFFSET) == 0xFEn
|
|
1366
|
+
&& WasmI32.load8U(ptr + 3n, _BYTES_DATA_OFFSET) == 0xFFn
|
|
1550
1367
|
},
|
|
1551
1368
|
UTF32_LE => {
|
|
1552
|
-
bytesSize >= 4n
|
|
1553
|
-
WasmI32.load8U(ptr,
|
|
1554
|
-
WasmI32.load8U(ptr + 1n,
|
|
1555
|
-
WasmI32.load8U(ptr + 2n,
|
|
1556
|
-
WasmI32.load8U(ptr + 3n,
|
|
1369
|
+
bytesSize >= 4n
|
|
1370
|
+
&& WasmI32.load8U(ptr, _BYTES_DATA_OFFSET) == 0xFFn
|
|
1371
|
+
&& WasmI32.load8U(ptr + 1n, _BYTES_DATA_OFFSET) == 0xFEn
|
|
1372
|
+
&& WasmI32.load8U(ptr + 2n, _BYTES_DATA_OFFSET) == 0x00n
|
|
1373
|
+
&& WasmI32.load8U(ptr + 3n, _BYTES_DATA_OFFSET) == 0x00n
|
|
1557
1374
|
},
|
|
1558
1375
|
}
|
|
1559
1376
|
|
|
@@ -1585,14 +1402,14 @@ let decodedLength = (
|
|
|
1585
1402
|
}
|
|
1586
1403
|
let ptr = WasmI32.fromGrain(bytes)
|
|
1587
1404
|
let bytesSize = {
|
|
1588
|
-
let tmp = WasmI32.load(ptr,
|
|
1405
|
+
let tmp = WasmI32.load(ptr, _BYTES_LEN_OFFSET) - start
|
|
1589
1406
|
if (size < tmp) {
|
|
1590
1407
|
size
|
|
1591
1408
|
} else {
|
|
1592
1409
|
tmp
|
|
1593
1410
|
}
|
|
1594
1411
|
}
|
|
1595
|
-
let start = ptr +
|
|
1412
|
+
let start = ptr + _BYTES_DATA_OFFSET + start
|
|
1596
1413
|
let result = match (encoding) {
|
|
1597
1414
|
UTF8 => bytesSize,
|
|
1598
1415
|
UTF16_BE => {
|
|
@@ -1606,8 +1423,8 @@ let decodedLength = (
|
|
|
1606
1423
|
let ret = if (ptr + 2n >= end) {
|
|
1607
1424
|
throw MalformedUnicode
|
|
1608
1425
|
} else {
|
|
1609
|
-
let nextCodeWord = WasmI32.load8U(ptr, 2n) << 8n
|
|
1610
|
-
WasmI32.load8U(ptr, 3n)
|
|
1426
|
+
let nextCodeWord = WasmI32.load8U(ptr, 2n) << 8n
|
|
1427
|
+
| WasmI32.load8U(ptr, 3n)
|
|
1611
1428
|
if (nextCodeWord < 0xDC00n || nextCodeWord > 0xDFFFn) {
|
|
1612
1429
|
// high surrogate without low surrogate
|
|
1613
1430
|
throw MalformedUnicode
|
|
@@ -1624,15 +1441,7 @@ let decodedLength = (
|
|
|
1624
1441
|
ptr += 2n
|
|
1625
1442
|
codeWord
|
|
1626
1443
|
}
|
|
1627
|
-
|
|
1628
|
-
count += 1n
|
|
1629
|
-
} else if (codeWord <= 0x07FFn) {
|
|
1630
|
-
count += 2n
|
|
1631
|
-
} else if (codeWord <= 0xFFFFn) {
|
|
1632
|
-
count += 3n
|
|
1633
|
-
} else {
|
|
1634
|
-
count += 4n
|
|
1635
|
-
}
|
|
1444
|
+
count += usvEncodeLength(codeWord)
|
|
1636
1445
|
}
|
|
1637
1446
|
count
|
|
1638
1447
|
},
|
|
@@ -1647,8 +1456,8 @@ let decodedLength = (
|
|
|
1647
1456
|
let ret = if (ptr + 2n >= end) {
|
|
1648
1457
|
throw MalformedUnicode
|
|
1649
1458
|
} else {
|
|
1650
|
-
let nextCodeWord = WasmI32.load8U(ptr, 3n) << 8n
|
|
1651
|
-
WasmI32.load8U(ptr, 2n)
|
|
1459
|
+
let nextCodeWord = WasmI32.load8U(ptr, 3n) << 8n
|
|
1460
|
+
| WasmI32.load8U(ptr, 2n)
|
|
1652
1461
|
if (nextCodeWord < 0xDC00n || nextCodeWord > 0xDFFFn) {
|
|
1653
1462
|
// high surrogate without low surrogate
|
|
1654
1463
|
throw MalformedUnicode
|
|
@@ -1665,15 +1474,7 @@ let decodedLength = (
|
|
|
1665
1474
|
ptr += 2n
|
|
1666
1475
|
codeWord
|
|
1667
1476
|
}
|
|
1668
|
-
|
|
1669
|
-
count += 1n
|
|
1670
|
-
} else if (codeWord <= 0x07FFn) {
|
|
1671
|
-
count += 2n
|
|
1672
|
-
} else if (codeWord <= 0xFFFFn) {
|
|
1673
|
-
count += 3n
|
|
1674
|
-
} else {
|
|
1675
|
-
count += 4n
|
|
1676
|
-
}
|
|
1477
|
+
count += usvEncodeLength(codeWord)
|
|
1677
1478
|
}
|
|
1678
1479
|
count
|
|
1679
1480
|
},
|
|
@@ -1686,20 +1487,12 @@ let decodedLength = (
|
|
|
1686
1487
|
let mut ptr = start
|
|
1687
1488
|
let mut count = 0n
|
|
1688
1489
|
while (ptr < end) {
|
|
1689
|
-
let codeWord = WasmI32.load8U(ptr, 0n) << 24n
|
|
1690
|
-
WasmI32.load8U(ptr, 1n) << 16n
|
|
1691
|
-
WasmI32.load8U(ptr, 2n) << 8n
|
|
1692
|
-
WasmI32.load8U(ptr, 3n)
|
|
1490
|
+
let codeWord = WasmI32.load8U(ptr, 0n) << 24n
|
|
1491
|
+
| WasmI32.load8U(ptr, 1n) << 16n
|
|
1492
|
+
| WasmI32.load8U(ptr, 2n) << 8n
|
|
1493
|
+
| WasmI32.load8U(ptr, 3n)
|
|
1693
1494
|
ptr += 4n
|
|
1694
|
-
|
|
1695
|
-
count += 1n
|
|
1696
|
-
} else if (codeWord <= 0x07FFn) {
|
|
1697
|
-
count += 2n
|
|
1698
|
-
} else if (codeWord <= 0xFFFFn) {
|
|
1699
|
-
count += 3n
|
|
1700
|
-
} else {
|
|
1701
|
-
count += 4n
|
|
1702
|
-
}
|
|
1495
|
+
count += usvEncodeLength(codeWord)
|
|
1703
1496
|
}
|
|
1704
1497
|
count
|
|
1705
1498
|
},
|
|
@@ -1712,20 +1505,12 @@ let decodedLength = (
|
|
|
1712
1505
|
let mut ptr = start
|
|
1713
1506
|
let mut count = 0n
|
|
1714
1507
|
while (ptr < end) {
|
|
1715
|
-
let codeWord = WasmI32.load8U(ptr, 3n) << 24n
|
|
1716
|
-
WasmI32.load8U(ptr, 2n) << 16n
|
|
1717
|
-
WasmI32.load8U(ptr, 1n) << 8n
|
|
1718
|
-
WasmI32.load8U(ptr, 0n)
|
|
1508
|
+
let codeWord = WasmI32.load8U(ptr, 3n) << 24n
|
|
1509
|
+
| WasmI32.load8U(ptr, 2n) << 16n
|
|
1510
|
+
| WasmI32.load8U(ptr, 1n) << 8n
|
|
1511
|
+
| WasmI32.load8U(ptr, 0n)
|
|
1719
1512
|
ptr += 4n
|
|
1720
|
-
|
|
1721
|
-
count += 1n
|
|
1722
|
-
} else if (codeWord <= 0x07FFn) {
|
|
1723
|
-
count += 2n
|
|
1724
|
-
} else if (codeWord <= 0xFFFFn) {
|
|
1725
|
-
count += 3n
|
|
1726
|
-
} else {
|
|
1727
|
-
count += 4n
|
|
1728
|
-
}
|
|
1513
|
+
count += usvEncodeLength(codeWord)
|
|
1729
1514
|
}
|
|
1730
1515
|
count
|
|
1731
1516
|
},
|
|
@@ -1764,15 +1549,15 @@ let decodeRangeHelp = (
|
|
|
1764
1549
|
let str = allocateString(stringSize)
|
|
1765
1550
|
let mut bytesPtr = WasmI32.fromGrain(bytes)
|
|
1766
1551
|
let bytesSize = {
|
|
1767
|
-
let tmp = WasmI32.load(bytesPtr,
|
|
1552
|
+
let tmp = WasmI32.load(bytesPtr, _BYTES_LEN_OFFSET) - start
|
|
1768
1553
|
if (size < tmp) {
|
|
1769
1554
|
size
|
|
1770
1555
|
} else {
|
|
1771
1556
|
tmp
|
|
1772
1557
|
}
|
|
1773
1558
|
}
|
|
1774
|
-
bytesPtr +=
|
|
1775
|
-
let mut strPtr = str +
|
|
1559
|
+
bytesPtr += _BYTES_DATA_OFFSET + start
|
|
1560
|
+
let mut strPtr = str + _STR_DATA_OFFSET
|
|
1776
1561
|
let mut bomRead = false
|
|
1777
1562
|
if (skipBom && hasBom) {
|
|
1778
1563
|
bytesPtr += match (encoding) {
|
|
@@ -1794,16 +1579,16 @@ let decodeRangeHelp = (
|
|
|
1794
1579
|
// NOTE: Because the size check passed, we know the string is well-formed
|
|
1795
1580
|
let end = bytesPtr + bytesSize
|
|
1796
1581
|
while (bytesPtr < end) {
|
|
1797
|
-
let w1 = WasmI32.load8U(bytesPtr, 0n) << 8n
|
|
1798
|
-
WasmI32.load8U(bytesPtr, 1n)
|
|
1582
|
+
let w1 = WasmI32.load8U(bytesPtr, 0n) << 8n
|
|
1583
|
+
| WasmI32.load8U(bytesPtr, 1n)
|
|
1799
1584
|
let codeWord = if (w1 >= 0xD800n && w1 <= 0xDBFFn) {
|
|
1800
1585
|
// high surrogate. next character is low srurrogate
|
|
1801
1586
|
let w1 = (w1 & 0x03FFn) << 10n
|
|
1802
1587
|
let w2 = (
|
|
1803
|
-
WasmI32.load8U(bytesPtr, 2n) << 8n
|
|
1804
|
-
WasmI32.load8U(bytesPtr, 3n)
|
|
1805
|
-
)
|
|
1806
|
-
0x03FFn
|
|
1588
|
+
WasmI32.load8U(bytesPtr, 2n) << 8n
|
|
1589
|
+
| WasmI32.load8U(bytesPtr, 3n)
|
|
1590
|
+
)
|
|
1591
|
+
& 0x03FFn
|
|
1807
1592
|
let codeWord = w1 + w2 + 0x10000n
|
|
1808
1593
|
// no problems, so go past both code words
|
|
1809
1594
|
bytesPtr += 4n
|
|
@@ -1819,16 +1604,16 @@ let decodeRangeHelp = (
|
|
|
1819
1604
|
// NOTE: Because the size check passed, we know the string is well-formed
|
|
1820
1605
|
let end = bytesPtr + bytesSize
|
|
1821
1606
|
while (bytesPtr < end) {
|
|
1822
|
-
let w1 = WasmI32.load8U(bytesPtr, 1n) << 8n
|
|
1823
|
-
WasmI32.load8U(bytesPtr, 0n)
|
|
1607
|
+
let w1 = WasmI32.load8U(bytesPtr, 1n) << 8n
|
|
1608
|
+
| WasmI32.load8U(bytesPtr, 0n)
|
|
1824
1609
|
let codeWord = if (w1 >= 0xD800n && w1 <= 0xDBFFn) {
|
|
1825
1610
|
// high surrogate. next character is low srurrogate
|
|
1826
1611
|
let w1 = (w1 & 0x03FFn) << 10n
|
|
1827
1612
|
let w2 = (
|
|
1828
|
-
WasmI32.load8U(bytesPtr, 3n) << 8n
|
|
1829
|
-
WasmI32.load8U(bytesPtr, 2n)
|
|
1830
|
-
)
|
|
1831
|
-
0x03FFn
|
|
1613
|
+
WasmI32.load8U(bytesPtr, 3n) << 8n
|
|
1614
|
+
| WasmI32.load8U(bytesPtr, 2n)
|
|
1615
|
+
)
|
|
1616
|
+
& 0x03FFn
|
|
1832
1617
|
//let uPrime = codePoint - 0x10000n
|
|
1833
1618
|
//let w1 = ((uPrime & 0b11111111110000000000n) >>> 10n) + 0xD800n // High surrogate
|
|
1834
1619
|
//let w2 = (uPrime & 0b00000000001111111111n) + 0xDC00n // Low surrogate
|
|
@@ -1846,10 +1631,10 @@ let decodeRangeHelp = (
|
|
|
1846
1631
|
UTF32_BE => {
|
|
1847
1632
|
let end = bytesPtr + bytesSize
|
|
1848
1633
|
while (bytesPtr < end) {
|
|
1849
|
-
let codeWord = WasmI32.load8U(bytesPtr, 0n) << 24n
|
|
1850
|
-
WasmI32.load8U(bytesPtr, 1n) << 16n
|
|
1851
|
-
WasmI32.load8U(bytesPtr, 2n) << 8n
|
|
1852
|
-
WasmI32.load8U(bytesPtr, 3n)
|
|
1634
|
+
let codeWord = WasmI32.load8U(bytesPtr, 0n) << 24n
|
|
1635
|
+
| WasmI32.load8U(bytesPtr, 1n) << 16n
|
|
1636
|
+
| WasmI32.load8U(bytesPtr, 2n) << 8n
|
|
1637
|
+
| WasmI32.load8U(bytesPtr, 3n)
|
|
1853
1638
|
bytesPtr += 4n
|
|
1854
1639
|
strPtr += writeUtf8CodePoint(strPtr, codeWord)
|
|
1855
1640
|
}
|
|
@@ -1857,10 +1642,10 @@ let decodeRangeHelp = (
|
|
|
1857
1642
|
UTF32_LE => {
|
|
1858
1643
|
let end = bytesPtr + bytesSize
|
|
1859
1644
|
while (bytesPtr < end) {
|
|
1860
|
-
let codeWord = WasmI32.load8U(bytesPtr, 3n) << 24n
|
|
1861
|
-
WasmI32.load8U(bytesPtr, 2n) << 16n
|
|
1862
|
-
WasmI32.load8U(bytesPtr, 1n) << 8n
|
|
1863
|
-
WasmI32.load8U(bytesPtr, 0n)
|
|
1645
|
+
let codeWord = WasmI32.load8U(bytesPtr, 3n) << 24n
|
|
1646
|
+
| WasmI32.load8U(bytesPtr, 2n) << 16n
|
|
1647
|
+
| WasmI32.load8U(bytesPtr, 1n) << 8n
|
|
1648
|
+
| WasmI32.load8U(bytesPtr, 0n)
|
|
1864
1649
|
bytesPtr += 4n
|
|
1865
1650
|
strPtr += writeUtf8CodePoint(strPtr, codeWord)
|
|
1866
1651
|
}
|
|
@@ -1944,26 +1729,18 @@ provide let decode = (bytes: Bytes, encoding: Encoding, keepBom=false) => {
|
|
|
1944
1729
|
*/
|
|
1945
1730
|
@unsafe
|
|
1946
1731
|
provide let forEachCodePoint = (fn: Number => Void, str: String) => {
|
|
1947
|
-
use WasmI32.{ (+),
|
|
1732
|
+
use WasmI32.{ (+), ltU as (<) }
|
|
1948
1733
|
|
|
1949
1734
|
let strPtr = WasmI32.fromGrain(str)
|
|
1950
1735
|
|
|
1951
|
-
let byteSize =
|
|
1736
|
+
let byteSize = rawByteLength(strPtr)
|
|
1952
1737
|
|
|
1953
|
-
let mut ptr = strPtr +
|
|
1738
|
+
let mut ptr = strPtr + _STR_DATA_OFFSET
|
|
1954
1739
|
let end = ptr + byteSize
|
|
1955
1740
|
|
|
1956
1741
|
while (ptr < end) {
|
|
1957
1742
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
1958
|
-
let codePointByteCount =
|
|
1959
|
-
1n
|
|
1960
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
1961
|
-
4n
|
|
1962
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
1963
|
-
3n
|
|
1964
|
-
} else {
|
|
1965
|
-
2n
|
|
1966
|
-
}
|
|
1743
|
+
let codePointByteCount = utf8ByteCount(byte)
|
|
1967
1744
|
|
|
1968
1745
|
// Note that even if up to 4 bytes are needed to represent Unicode
|
|
1969
1746
|
// codepoints, this doesn't mean 32 bits. The highest allowed code point is
|
|
@@ -1997,27 +1774,19 @@ provide let forEachCodePoint = (fn: Number => Void, str: String) => {
|
|
|
1997
1774
|
*/
|
|
1998
1775
|
@unsafe
|
|
1999
1776
|
provide let forEachCodePointi = (fn: (Number, Number) => Void, str: String) => {
|
|
2000
|
-
use WasmI32.{ (+),
|
|
1777
|
+
use WasmI32.{ (+), ltU as (<), (==) }
|
|
2001
1778
|
|
|
2002
1779
|
let strPtr = WasmI32.fromGrain(str)
|
|
2003
1780
|
|
|
2004
|
-
let byteSize =
|
|
1781
|
+
let byteSize = rawByteLength(strPtr)
|
|
2005
1782
|
|
|
2006
|
-
let mut ptr = strPtr +
|
|
1783
|
+
let mut ptr = strPtr + _STR_DATA_OFFSET
|
|
2007
1784
|
let end = ptr + byteSize
|
|
2008
1785
|
|
|
2009
1786
|
let mut idx = 0n
|
|
2010
1787
|
while (ptr < end) {
|
|
2011
1788
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
2012
|
-
let codePointByteCount =
|
|
2013
|
-
1n
|
|
2014
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
2015
|
-
4n
|
|
2016
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
2017
|
-
3n
|
|
2018
|
-
} else {
|
|
2019
|
-
2n
|
|
2020
|
-
}
|
|
1789
|
+
let codePointByteCount = utf8ByteCount(byte)
|
|
2021
1790
|
|
|
2022
1791
|
// Note that even if up to 4 bytes are needed to represent Unicode
|
|
2023
1792
|
// codepoints, this doesn't mean 32 bits. The highest allowed code point is
|
|
@@ -2050,26 +1819,18 @@ provide let forEachCodePointi = (fn: (Number, Number) => Void, str: String) => {
|
|
|
2050
1819
|
*/
|
|
2051
1820
|
@unsafe
|
|
2052
1821
|
provide let forEachChar = (fn: Char => Void, str: String) => {
|
|
2053
|
-
use WasmI32.{ (+),
|
|
1822
|
+
use WasmI32.{ (+), ltU as (<), (==) }
|
|
2054
1823
|
|
|
2055
1824
|
let strPtr = WasmI32.fromGrain(str)
|
|
2056
1825
|
|
|
2057
|
-
let byteSize =
|
|
1826
|
+
let byteSize = rawByteLength(strPtr)
|
|
2058
1827
|
|
|
2059
|
-
let mut ptr = strPtr +
|
|
1828
|
+
let mut ptr = strPtr + _STR_DATA_OFFSET
|
|
2060
1829
|
let end = ptr + byteSize
|
|
2061
1830
|
|
|
2062
1831
|
while (ptr < end) {
|
|
2063
1832
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
2064
|
-
let codePointByteCount =
|
|
2065
|
-
1n
|
|
2066
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
2067
|
-
4n
|
|
2068
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
2069
|
-
3n
|
|
2070
|
-
} else {
|
|
2071
|
-
2n
|
|
2072
|
-
}
|
|
1833
|
+
let codePointByteCount = utf8ByteCount(byte)
|
|
2073
1834
|
|
|
2074
1835
|
// Note that even if up to 4 bytes are needed to represent Unicode
|
|
2075
1836
|
// codepoints, this doesn't mean 32 bits. The highest allowed code point is
|
|
@@ -2100,27 +1861,19 @@ provide let forEachChar = (fn: Char => Void, str: String) => {
|
|
|
2100
1861
|
*/
|
|
2101
1862
|
@unsafe
|
|
2102
1863
|
provide let forEachChari = (fn: (Char, Number) => Void, str: String) => {
|
|
2103
|
-
use WasmI32.{ (+),
|
|
1864
|
+
use WasmI32.{ (+), ltU as (<), (==) }
|
|
2104
1865
|
|
|
2105
1866
|
let strPtr = WasmI32.fromGrain(str)
|
|
2106
1867
|
|
|
2107
|
-
let byteSize =
|
|
1868
|
+
let byteSize = rawByteLength(strPtr)
|
|
2108
1869
|
|
|
2109
|
-
let mut ptr = strPtr +
|
|
1870
|
+
let mut ptr = strPtr + _STR_DATA_OFFSET
|
|
2110
1871
|
let end = ptr + byteSize
|
|
2111
1872
|
|
|
2112
1873
|
let mut idx = 0n
|
|
2113
1874
|
while (ptr < end) {
|
|
2114
1875
|
let byte = WasmI32.load8U(ptr, 0n)
|
|
2115
|
-
let codePointByteCount =
|
|
2116
|
-
1n
|
|
2117
|
-
} else if ((byte & 0xF0n) == 0xF0n) {
|
|
2118
|
-
4n
|
|
2119
|
-
} else if ((byte & 0xE0n) == 0xE0n) {
|
|
2120
|
-
3n
|
|
2121
|
-
} else {
|
|
2122
|
-
2n
|
|
2123
|
-
}
|
|
1876
|
+
let codePointByteCount = utf8ByteCount(byte)
|
|
2124
1877
|
|
|
2125
1878
|
// Note that even if up to 4 bytes are needed to represent Unicode
|
|
2126
1879
|
// codepoints, this doesn't mean 32 bits. The highest allowed code point is
|
|
@@ -2194,7 +1947,8 @@ let trimString = (stringPtr: WasmI32, byteLength: WasmI32, fromEnd: Bool) => {
|
|
|
2194
1947
|
// TODO(#661): Use unicode whitespace property and unicode line terminator
|
|
2195
1948
|
if (!fromEnd) {
|
|
2196
1949
|
if (
|
|
2197
|
-
byte == 0xEFn
|
|
1950
|
+
byte == 0xEFn
|
|
1951
|
+
&& // Check for the first BOM byte
|
|
2198
1952
|
// Check for the full BOM codepoint, 0xEFBBBF. Bytes are reversed because wasm is little-endian
|
|
2199
1953
|
WasmI32.load(stringPtr, i - 1n) >>> 8n == 0xBFBBEFn
|
|
2200
1954
|
) {
|
|
@@ -2204,7 +1958,8 @@ let trimString = (stringPtr: WasmI32, byteLength: WasmI32, fromEnd: Bool) => {
|
|
|
2204
1958
|
}
|
|
2205
1959
|
} else {
|
|
2206
1960
|
if (
|
|
2207
|
-
byte == 0xBFn
|
|
1961
|
+
byte == 0xBFn
|
|
1962
|
+
&& // Check for the last BOM byte
|
|
2208
1963
|
// Check for the full BOM codepoint, 0xEFBBBF. Bytes are reversed because wasm is little-endian
|
|
2209
1964
|
WasmI32.load(stringPtr, i - 3n) >>> 8n == 0xBFBBEFn
|
|
2210
1965
|
) {
|
|
@@ -2214,12 +1969,18 @@ let trimString = (stringPtr: WasmI32, byteLength: WasmI32, fromEnd: Bool) => {
|
|
|
2214
1969
|
}
|
|
2215
1970
|
}
|
|
2216
1971
|
if (
|
|
2217
|
-
byte != 0x20n
|
|
2218
|
-
|
|
2219
|
-
byte !=
|
|
2220
|
-
|
|
2221
|
-
byte !=
|
|
2222
|
-
|
|
1972
|
+
byte != 0x20n
|
|
1973
|
+
&& // Space
|
|
1974
|
+
byte != 0x0Dn
|
|
1975
|
+
&& // LF
|
|
1976
|
+
byte != 0x0An
|
|
1977
|
+
&& // CR
|
|
1978
|
+
byte != 0x09n
|
|
1979
|
+
&& // Tab
|
|
1980
|
+
byte != 0x0Bn
|
|
1981
|
+
&& // LINE TABULATION
|
|
1982
|
+
byte != 0x0Cn
|
|
1983
|
+
&& // FORM FEED (FF)
|
|
2223
1984
|
byte != 0xA0n // No Break Space
|
|
2224
1985
|
) {
|
|
2225
1986
|
break
|
|
@@ -2242,11 +2003,11 @@ let trimString = (stringPtr: WasmI32, byteLength: WasmI32, fromEnd: Bool) => {
|
|
|
2242
2003
|
provide let trimStart = (string: String) => {
|
|
2243
2004
|
use WasmI32.{ (-), (+) }
|
|
2244
2005
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
2245
|
-
let byteLength =
|
|
2246
|
-
stringPtr +=
|
|
2006
|
+
let byteLength = rawByteLength(stringPtr)
|
|
2007
|
+
stringPtr += _STR_DATA_OFFSET
|
|
2247
2008
|
let count = trimString(stringPtr, byteLength, false)
|
|
2248
2009
|
let str = allocateString(byteLength - count)
|
|
2249
|
-
Memory.copy(str +
|
|
2010
|
+
Memory.copy(str + _STR_DATA_OFFSET, stringPtr + count, byteLength - count)
|
|
2250
2011
|
ignore(string)
|
|
2251
2012
|
WasmI32.toGrain(str): String
|
|
2252
2013
|
}
|
|
@@ -2264,11 +2025,11 @@ provide let trimStart = (string: String) => {
|
|
|
2264
2025
|
provide let trimEnd = (string: String) => {
|
|
2265
2026
|
use WasmI32.{ (-), (+) }
|
|
2266
2027
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
2267
|
-
let byteLength =
|
|
2268
|
-
stringPtr +=
|
|
2028
|
+
let byteLength = rawByteLength(stringPtr)
|
|
2029
|
+
stringPtr += _STR_DATA_OFFSET
|
|
2269
2030
|
let count = trimString(stringPtr, byteLength, true)
|
|
2270
2031
|
let str = allocateString(byteLength - count)
|
|
2271
|
-
Memory.copy(str +
|
|
2032
|
+
Memory.copy(str + _STR_DATA_OFFSET, stringPtr, byteLength - count)
|
|
2272
2033
|
ignore(string)
|
|
2273
2034
|
WasmI32.toGrain(str): String
|
|
2274
2035
|
}
|
|
@@ -2286,14 +2047,14 @@ provide let trimEnd = (string: String) => {
|
|
|
2286
2047
|
provide let trim = (string: String) => {
|
|
2287
2048
|
use WasmI32.{ (-), (+), (==) }
|
|
2288
2049
|
let mut stringPtr = WasmI32.fromGrain(string)
|
|
2289
|
-
let byteLength =
|
|
2290
|
-
stringPtr +=
|
|
2050
|
+
let byteLength = rawByteLength(stringPtr)
|
|
2051
|
+
stringPtr += _STR_DATA_OFFSET
|
|
2291
2052
|
let startCount = trimString(stringPtr, byteLength, false)
|
|
2292
2053
|
if (startCount == byteLength) return ""
|
|
2293
2054
|
let endCount = trimString(stringPtr, byteLength, true)
|
|
2294
2055
|
let str = allocateString(byteLength - startCount - endCount)
|
|
2295
2056
|
Memory.copy(
|
|
2296
|
-
str +
|
|
2057
|
+
str + _STR_DATA_OFFSET,
|
|
2297
2058
|
stringPtr + startCount,
|
|
2298
2059
|
byteLength - startCount - endCount
|
|
2299
2060
|
)
|
|
@@ -2315,7 +2076,7 @@ provide let toAsciiLowercase = string => {
|
|
|
2315
2076
|
let chars = explode(string)
|
|
2316
2077
|
let len = arrayLength(chars)
|
|
2317
2078
|
for (let mut i = 0; i < len; i += 1) {
|
|
2318
|
-
chars[i] = Char.
|
|
2079
|
+
chars[i] = Char.Ascii.toLowercase(chars[i])
|
|
2319
2080
|
}
|
|
2320
2081
|
implode(chars)
|
|
2321
2082
|
}
|
|
@@ -2334,7 +2095,41 @@ provide let toAsciiUppercase = string => {
|
|
|
2334
2095
|
let chars = explode(string)
|
|
2335
2096
|
let len = arrayLength(chars)
|
|
2336
2097
|
for (let mut i = 0; i < len; i += 1) {
|
|
2337
|
-
chars[i] = Char.
|
|
2098
|
+
chars[i] = Char.Ascii.toUppercase(chars[i])
|
|
2338
2099
|
}
|
|
2339
2100
|
implode(chars)
|
|
2340
2101
|
}
|
|
2102
|
+
|
|
2103
|
+
/**
|
|
2104
|
+
* Produces a new string by repeating a substring a given number of times.
|
|
2105
|
+
*
|
|
2106
|
+
* @param count: The number of times to repeat the string
|
|
2107
|
+
* @param string: The string to repeat
|
|
2108
|
+
* @returns A string containing the repeated input string
|
|
2109
|
+
*
|
|
2110
|
+
* @throws InvalidArgument(String): When the `count` is not an integer
|
|
2111
|
+
* @throws InvalidArgument(String): When the `count` is negative
|
|
2112
|
+
*
|
|
2113
|
+
* @example assert String.repeat(5, "=") == "====="
|
|
2114
|
+
* @example assert String.repeat(0, ".") == ""
|
|
2115
|
+
*
|
|
2116
|
+
* @since v0.6.7
|
|
2117
|
+
*/
|
|
2118
|
+
@unsafe
|
|
2119
|
+
provide let repeat = (count, string: String) => {
|
|
2120
|
+
use WasmI32.{ (+), (*), (<), (&), (!=) }
|
|
2121
|
+
let rawCount = convSimpleNumber(count, "Invalid count value")
|
|
2122
|
+
if (rawCount < 0n) {
|
|
2123
|
+
throw InvalidArgument("Invalid count must be a positive integer or zero")
|
|
2124
|
+
}
|
|
2125
|
+
let stringPtr = WasmI32.fromGrain(string)
|
|
2126
|
+
let byteLength = rawByteLength(stringPtr)
|
|
2127
|
+
let stringPtr = stringPtr + _STR_DATA_OFFSET
|
|
2128
|
+
let newStringPtr = allocateString(byteLength * rawCount)
|
|
2129
|
+
let strContentPtr = newStringPtr + _STR_DATA_OFFSET
|
|
2130
|
+
for (let mut i = 0n; i < rawCount; i += 1n) {
|
|
2131
|
+
Memory.copy(strContentPtr + byteLength * i, stringPtr, byteLength)
|
|
2132
|
+
}
|
|
2133
|
+
ignore(string)
|
|
2134
|
+
return WasmI32.toGrain(newStringPtr): String
|
|
2135
|
+
}
|