json-as 0.5.54 → 0.5.57

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.
@@ -20,8 +20,11 @@ import {
20
20
  trueWord,
21
21
  uCode,
22
22
  emptyArrayWord,
23
+ falseWord,
24
+ newLineCode,
23
25
  } from "./chars";
24
26
  import { snip_fast, unsafeCharCodeAt } from "./util";
27
+ import { Virtual } from "as-virtual/assembly";
25
28
 
26
29
  /**
27
30
  * JSON Encoder/Decoder for AssemblyScript
@@ -138,208 +141,174 @@ export namespace JSON {
138
141
  );
139
142
  }
140
143
  }
141
- // @ts-ignore: Decorator
142
- @inline function parseObjectValue<T>(data: string): T {
143
- let type: T;
144
- if (isString<T>()) {
145
- // @ts-ignore
146
- let result = "";
147
- let last = 0;
148
- for (let i = 0; i < data.length; i++) {
149
- // \\"
150
- if (unsafeCharCodeAt(data, i) === backSlashCode) {
151
- const char = unsafeCharCodeAt(data, ++i);
152
- result += data.slice(last, i - 1);
153
- if (char === 34) {
154
- result += '"';
144
+ }
145
+
146
+ // @ts-ignore: Decorator
147
+ @global @inline function __parseObjectValue<T>(data: string): T {
148
+ let type: T;
149
+ if (isString<T>()) {
150
+ // @ts-ignore
151
+ let result = "";
152
+ let last = 0;
153
+ for (let i = 0; i < data.length; i++) {
154
+ // \\"
155
+ if (unsafeCharCodeAt(data, i) === backSlashCode) {
156
+ const char = unsafeCharCodeAt(data, ++i);
157
+ result += data.slice(last, i - 1);
158
+ if (char === 34) {
159
+ result += '"';
160
+ last = ++i;
161
+ } else if (char === 110) {
162
+ result += "\n";
163
+ last = ++i;
164
+ // 92 98 114 116 102 117
165
+ } else if (char >= 92 && char <= 117) {
166
+ if (char === 92) {
167
+ result += "\\";
155
168
  last = ++i;
156
- } else if (char === 110) {
157
- result += "\n";
169
+ } else if (char === 98) {
170
+ result += "\b";
171
+ last = ++i;
172
+ } else if (char === 102) {
173
+ result += "\f";
174
+ last = ++i;
175
+ } else if (char === 114) {
176
+ result += "\r";
177
+ last = ++i;
178
+ } else if (char === 116) {
179
+ result += "\t";
180
+ last = ++i;
181
+ } else if (
182
+ char === 117 &&
183
+ load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
184
+ 27584753879220272
185
+ ) {
186
+ result += "\u000b";
187
+ i += 4;
158
188
  last = ++i;
159
- // 92 98 114 116 102 117
160
- } else if (char >= 92 && char <= 117) {
161
- if (char === 92) {
162
- result += "\\";
163
- last = ++i;
164
- } else if (char === 98) {
165
- result += "\b";
166
- last = ++i;
167
- } else if (char === 102) {
168
- result += "\f";
169
- last = ++i;
170
- } else if (char === 114) {
171
- result += "\r";
172
- last = ++i;
173
- } else if (char === 116) {
174
- result += "\t";
175
- last = ++i;
176
- } else if (
177
- char === 117 &&
178
- load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
179
- 27584753879220272
180
- ) {
181
- result += "\u000b";
182
- i += 4;
183
- last = ++i;
184
- }
185
189
  }
186
190
  }
187
191
  }
188
- result += data.slice(last);
189
- // @ts-ignore
190
- return result;
191
- } else if (isBoolean<T>()) {
192
- // @ts-ignore
193
- return parseBoolean<T>(data);
194
- } else if (isFloat<T>() || isInteger<T>()) {
195
- return parseNumber<T>(data);
196
- } else if (isArrayLike<T>()) {
197
- // @ts-ignore
198
- return parseArray<T>(data);
199
- // @ts-ignore
200
- } else if (isNullable<T>() && data == "null") {
201
- // @ts-ignore
202
- return null;
203
- // @ts-ignore
204
- } else if (isDefined(type.__JSON_Set_Key)) {
205
- return parseObject<T>(data.trimStart());
206
- } else if (idof<nonnull<T>>() == idof<Date>()) {
207
- // @ts-ignore
208
- return Date.fromString(data);
209
- } else {
210
- // @ts-ignore
211
- throw new Error(
212
- `Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
213
- );
214
192
  }
193
+ result += data.slice(last);
194
+ // @ts-ignore
195
+ return result;
196
+ } else if (isBoolean<T>()) {
197
+ // @ts-ignore
198
+ return parseBoolean<T>(data);
199
+ } else if (isFloat<T>() || isInteger<T>()) {
200
+ return parseNumber<T>(data);
201
+ } else if (isArrayLike<T>()) {
202
+ // @ts-ignore
203
+ return parseArray<T>(data);
204
+ // @ts-ignore
205
+ } else if (isNullable<T>() && data == "null") {
206
+ // @ts-ignore
207
+ return null;
208
+ // @ts-ignore
209
+ } else if (isDefined(type.__JSON_Set_Key)) {
210
+ return parseObject<T>(data.trimStart());
211
+ } else if (idof<nonnull<T>>() == idof<Date>()) {
212
+ // @ts-ignore
213
+ return Date.fromString(data);
214
+ } else {
215
+ // @ts-ignore
216
+ throw new Error(
217
+ `Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
218
+ );
215
219
  }
216
220
  }
217
221
 
218
222
  // @ts-ignore: Decorator
219
223
  @inline function serializeString(data: string): string {
220
- // @ts-ignore
221
- //if (data.length === 0) return "\"\"";
222
- /*
223
- let char: i32 = 0;
224
- if (data.length === 1) {
225
- char = unsafeCharCodeAt(data, 0);
226
- if (char === 34) {
227
- return "\\\"";
228
- } else if (char === 92) {
229
- return "\\n";
230
- } else if (char <= 13 && char >= 8) {
231
- switch (char) {
232
- case 0x5C: {
233
- return "\\\\";
234
- }
235
- case 0x08: {
236
- return "\\b";
237
- }
238
- case 0x0D: {
239
- return "\\r";
240
- }
241
- case 0x09: {
242
- return "\\t";
243
- }
244
- case 0x0C: {
245
- return "\\f";
246
- }
247
- case 0x0B: {
248
- return "\\u000b";
249
- }
250
- }
251
- } else {
252
- return data;
253
- }
254
- }*/
255
-
256
- let result = '"';
224
+ let result = new StringSink('"');
257
225
 
258
226
  let last: i32 = 0;
259
227
  // @ts-ignore
260
228
  for (let i = 0; i < data.length; i++) {
261
229
  const char = unsafeCharCodeAt(<string>data, i);
262
230
  if (char === 34 || char === 92) {
263
- result += (<string>data).slice(last, i) + "\\";
231
+ result.write(<string>data, last, i);
232
+ result.writeCodePoint(backSlashCode);
264
233
  last = i;
265
- //i++;
266
234
  } else if (char <= 13 && char >= 8) {
267
- result += (<string>data).slice(last, i);
235
+ result.write(<string>data, last, i);
268
236
  last = i + 1;
269
237
  switch (char) {
270
238
  case 8: {
271
- result += "\\b";
239
+ result.write("\\b");
272
240
  break;
273
241
  }
274
242
  case 9: {
275
- result += "\\t";
243
+ result.write("\\t");
276
244
  break;
277
245
  }
278
246
  case 10: {
279
- result += "\\n";
247
+ result.write("\\n");
280
248
  break;
281
249
  }
282
250
  case 11: {
283
- result += "\\x0B"; // \\u000b
251
+ result.write("\\x0B"); // \\u000b
284
252
  break;
285
253
  }
286
254
  case 12: {
287
- result += "\\f";
255
+ result.write("\\f");
288
256
  break;
289
257
  }
290
258
  case 13: {
291
- result += "\\r";
259
+ result.write("\\r");
292
260
  break;
293
261
  }
294
262
  }
295
263
  }
296
264
  }
297
265
  if (result.length === 1) return '"' + data + '"';
298
- else result += (<string>data).slice(last);
299
- return result + '"';
266
+ else result.write(<string>data, last);
267
+ result.write("\"");
268
+ return result.toString();
300
269
  }
301
270
 
302
271
  // @ts-ignore: Decorator
303
272
  @inline function parseString(data: string): string {
304
- let result = "";
273
+ let result = new StringSink();
305
274
  let last = 1;
306
275
  for (let i = 1; i < data.length - 1; i++) {
307
276
  // \\"
308
277
  if (unsafeCharCodeAt(data, i) === backSlashCode) {
309
278
  const char = unsafeCharCodeAt(data, ++i);
310
- result += data.slice(last, i - 1);
279
+ result.write(data, last, i - 1);
311
280
  if (char === 34) {
312
- result += '"';
281
+ result.writeCodePoint(quoteCode);
313
282
  last = i + 1;
314
283
  } else if (char >= 92 && char <= 117) {
315
284
  switch (char) {
316
285
  case 92: {
317
- result += "\\";
286
+ result.writeCodePoint(backSlashCode);
318
287
  last = i + 1;
319
288
  break;
320
289
  }
321
290
  case 98: {
322
- result += "\b";
291
+ result.write("\b");
323
292
  last = i + 1;
324
293
  break;
325
294
  }
326
295
  case 102: {
327
- result += "\f";
296
+ result.write("\f");
328
297
  last = i + 1;
329
298
  break;
330
299
  }
331
300
  case 110: {
332
- result += "\n";
301
+ result.writeCodePoint(newLineCode);
333
302
  last = i + 1;
334
303
  break;
335
304
  }
336
305
  case 114: {
337
- result += "\r";
306
+ result.write("\r");
338
307
  last = i + 1;
339
308
  break;
340
309
  }
341
310
  case 116: {
342
- result += "\t";
311
+ result.write("\t");
343
312
  last = i + 1;
344
313
  break;
345
314
  }
@@ -349,7 +318,7 @@ export namespace JSON {
349
318
  load<u64>(changetype<usize>(data) + <usize>((i + 1) << 1)) ===
350
319
  27584753879220272
351
320
  ) {
352
- result += "\u000b";
321
+ result.write("\u000b");
353
322
  i += 4;
354
323
  last = i + 1;
355
324
  }
@@ -359,8 +328,8 @@ export namespace JSON {
359
328
  }
360
329
  }
361
330
  }
362
- result += data.slice(last, data.length - 1);
363
- return result;
331
+ if ((data.length - 1) > last) result.write(data, last, data.length - 1);
332
+ return result.toString();
364
333
  }
365
334
 
366
335
  // @ts-ignore: Decorator
@@ -371,7 +340,7 @@ export namespace JSON {
371
340
  }
372
341
 
373
342
  // @ts-ignore: Decorator
374
- @inline export function parseNumber<T>(data: string): T {
343
+ @inline function parseNumber<T>(data: string): T {
375
344
  if (isInteger<T>()) {
376
345
  // @ts-ignore
377
346
  return snip_fast<T>(data);
@@ -389,7 +358,7 @@ export namespace JSON {
389
358
  let schema: nonnull<T> = changetype<nonnull<T>>(
390
359
  __new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
391
360
  );
392
- let key = "";
361
+ let key = Virtual.createEmpty<string>();
393
362
  let isKey = false;
394
363
  let depth = 0;
395
364
  let outerLoopIndex = 1;
@@ -409,10 +378,7 @@ export namespace JSON {
409
378
  if (depth === 0) {
410
379
  ++arrayValueIndex;
411
380
  // @ts-ignore
412
- schema.__JSON_Set_Key(
413
- key,
414
- data.slice(outerLoopIndex, arrayValueIndex)
415
- );
381
+ schema.__JSON_Set_Key<Virtual<string>>(key, data, outerLoopIndex, arrayValueIndex);
416
382
  outerLoopIndex = arrayValueIndex;
417
383
  isKey = false;
418
384
  break;
@@ -433,10 +399,7 @@ export namespace JSON {
433
399
  if (depth === 0) {
434
400
  ++objectValueIndex;
435
401
  // @ts-ignore
436
- schema.__JSON_Set_Key(
437
- key,
438
- data.slice(outerLoopIndex, objectValueIndex)
439
- );
402
+ schema.__JSON_Set_Key<Virtual<string>>(key, data, outerLoopIndex, objectValueIndex);
440
403
  outerLoopIndex = objectValueIndex;
441
404
  isKey = false;
442
405
  break;
@@ -455,14 +418,11 @@ export namespace JSON {
455
418
  unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
456
419
  ) {
457
420
  if (isKey === false) {
458
- key = data.slice(outerLoopIndex, stringValueIndex);
421
+ key.reinst(data, outerLoopIndex, stringValueIndex);
459
422
  isKey = true;
460
423
  } else {
461
424
  // @ts-ignore
462
- schema.__JSON_Set_Key(
463
- key,
464
- data.slice(outerLoopIndex, stringValueIndex)
465
- );
425
+ schema.__JSON_Set_Key<Virtual<string>>(key, data, outerLoopIndex, stringValueIndex);
466
426
  isKey = false;
467
427
  }
468
428
  outerLoopIndex = ++stringValueIndex;
@@ -471,7 +431,7 @@ export namespace JSON {
471
431
  }
472
432
  } else if (char == nCode) {
473
433
  // @ts-ignore
474
- schema.__JSON_Set_Key(key, nullWord);
434
+ schema.__JSON_Set_Key<Virtual<string>>(key, nullWord, 0, 4);
475
435
  isKey = false;
476
436
  } else if (
477
437
  char === tCode &&
@@ -480,7 +440,7 @@ export namespace JSON {
480
440
  unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
481
441
  ) {
482
442
  // @ts-ignore
483
- schema.__JSON_Set_Key(key, trueWord);
443
+ schema.__JSON_Set_Key<Virtual<string>>(key, trueWord, 0, 4);
484
444
  isKey = false;
485
445
  } else if (
486
446
  char === fCode &&
@@ -490,7 +450,7 @@ export namespace JSON {
490
450
  unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
491
451
  ) {
492
452
  // @ts-ignore
493
- schema.__JSON_Set_Key(key, "false");
453
+ schema.__JSON_Set_Key<Virtual<string>>(key, falseWord, 0, 5);
494
454
  isKey = false;
495
455
  } else if ((char >= 48 && char <= 57) || char === 45) {
496
456
  let numberValueIndex = ++outerLoopIndex;
@@ -498,10 +458,7 @@ export namespace JSON {
498
458
  const char = unsafeCharCodeAt(data, numberValueIndex);
499
459
  if (char === commaCode || char === rightBraceCode || isSpace(char)) {
500
460
  // @ts-ignore
501
- schema.__JSON_Set_Key(
502
- key,
503
- data.slice(outerLoopIndex - 1, numberValueIndex)
504
- );
461
+ schema.__JSON_Set_Key<Virtual<string>>(key, data, outerLoopIndex - 1, numberValueIndex);
505
462
  outerLoopIndex = numberValueIndex;
506
463
  isKey = false;
507
464
  break;
@@ -639,7 +596,7 @@ export namespace JSON {
639
596
  }
640
597
 
641
598
  // @ts-ignore: Decorator
642
- @inline export function parseObjectArray<T extends unknown[]>(data: string): T {
599
+ @inline function parseObjectArray<T extends unknown[]>(data: string): T {
643
600
  const result = instantiate<T>();
644
601
  let lastPos: u32 = 1;
645
602
  let depth: u32 = 0;
@@ -107,19 +107,19 @@ import { backSlashCode, quoteCode } from "./chars";
107
107
  // The first char (f) is E or e
108
108
  // We push the offset up by two and apply the notation.
109
109
  if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
110
- return -(val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
110
+ return -(val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
111
111
  } else {
112
112
  // Inlined this operation instead of using a loop
113
- return -(val * (10 ** (atoi_fast<u32>(str, offset + 2) + 1))) as T;
113
+ return -(val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
114
114
  }
115
115
  } else if (high > 57) {
116
116
  // The first char (f) is E or e
117
117
  // We push the offset up by two and apply the notation.
118
118
  if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
119
- return -(val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
119
+ return -(val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
120
120
  } else {
121
121
  // Inlined this operation instead of using a loop
122
- return -(val * (10 ** (atoi_fast<u32>(str, offset + 4) + 1))) as T;
122
+ return -(val * (10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1))) as T;
123
123
  }
124
124
  } else {
125
125
  val = (val * 100 + ((low - 48) * 10) + (high - 48)) as T;
@@ -134,10 +134,10 @@ import { backSlashCode, quoteCode } from "./chars";
134
134
  // The first char (f) is E or e
135
135
  // We push the offset up by two and apply the notation.
136
136
  if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
137
- return -(val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
137
+ return -(val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
138
138
  } else {
139
139
  // Inlined this operation instead of using a loop
140
- return -(val * (10 ** (atoi_fast<u32>(str, offset + 2) + 1))) as T;
140
+ return -(val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
141
141
  }
142
142
  } else {
143
143
  val = (val * 10) + (ch - 48) as T;
@@ -156,17 +156,17 @@ import { backSlashCode, quoteCode } from "./chars";
156
156
  // The first char (f) is E or e
157
157
  // We push the offset up by two and apply the notation.
158
158
  if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
159
- return (val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
159
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
160
160
  } else {
161
161
  // Inlined this operation instead of using a loop
162
- return (val * (10 ** (atoi_fast<u32>(str, offset + 2) + 1))) as T;
162
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
163
163
  }
164
164
  } else if (high > 57) {
165
165
  if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
166
- return (val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
166
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
167
167
  } else {
168
168
  // Inlined this operation instead of using a loop
169
- return (val * (10 ** (atoi_fast<u32>(str, offset + 4) + 1))) as T;
169
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1))) as T;
170
170
  }
171
171
  } else {
172
172
  // Optimized with multiplications and shifts.
@@ -181,10 +181,10 @@ import { backSlashCode, quoteCode } from "./chars";
181
181
  // e is 101 and E is 69.
182
182
  if (ch > 57) {
183
183
  if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
184
- val = (val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
184
+ val = (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
185
185
  } else {
186
186
  // Inlined this operation instead of using a loop
187
- val = (val * (10 ** (atoi_fast<u32>(str, offset + 2) + 1))) as T;
187
+ val = (val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
188
188
  }
189
189
  return val as T;
190
190
  } else {
@@ -209,17 +209,17 @@ import { backSlashCode, quoteCode } from "./chars";
209
209
  // The first char (f) is E or e
210
210
  // We push the offset up by two and apply the notation.
211
211
  if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
212
- return (val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
212
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
213
213
  } else {
214
214
  // Inlined this operation instead of using a loop
215
- return (val * (10 ** (atoi_fast<u32>(str, offset + 2) + 1))) as T;
215
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
216
216
  }
217
217
  } else if (high > 57) {
218
218
  if (load<u16>(changetype<usize>(str) + <usize>offset + 4) == 45) {
219
- return (val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
219
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
220
220
  } else {
221
221
  // Inlined this operation instead of using a loop
222
- return (val * (10 ** (atoi_fast<u32>(str, offset + 4) + 1))) as T;
222
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 4, offset + 6) + 1))) as T;
223
223
  }
224
224
  } else {
225
225
  // Optimized with multiplications and shifts.
@@ -234,10 +234,10 @@ import { backSlashCode, quoteCode } from "./chars";
234
234
  // e is 101 and E is 69.
235
235
  if (ch > 57) {
236
236
  if (load<u16>(changetype<usize>(str) + <usize>offset + 2) == 45) {
237
- return (val / (10 ** (atoi_fast<u32>(str, offset + 6) - 1))) as T;
237
+ return (val / (10 ** (__atoi_fast<u32>(str, offset + 6, offset + 8) - 1))) as T;
238
238
  } else {
239
239
  // Inlined this operation instead of using a loop
240
- return (val * (10 ** (atoi_fast<u32>(str, offset + 2) + 1))) as T;
240
+ return (val * (10 ** (__atoi_fast<u32>(str, offset + 2, offset + 4) + 1))) as T;
241
241
  }
242
242
  } else {
243
243
  val = (val * 10) + (ch - 48) as T;
@@ -252,34 +252,34 @@ import { backSlashCode, quoteCode } from "./chars";
252
252
  */
253
253
 
254
254
  // @ts-ignore
255
- @inline export function atoi_fast<T extends number>(str: string, offset: u32 = 0): T {
255
+ @global @inline export function __atoi_fast<T extends number>(str: string, start: u32 = 0, end: u32 = 0): T {
256
256
  // @ts-ignore
257
257
  let val: T = 0;
258
- const len = u32(str.length << 1);
258
+ if (!end) end = start + u32(str.length << 1);
259
259
  if (isSigned<T>()) {
260
260
  // Negative path
261
- if (load<u16>(changetype<usize>(str) + <usize>offset) === 45) {
262
- offset += 2;
263
- for (; offset < len; offset += 2) {
264
- val = (val * 10) + (load<u16>(changetype<usize>(str) + <usize>offset) - 48) as T;
261
+ if (load<u16>(changetype<usize>(str) + <usize>start) === 45) {
262
+ start += 2;
263
+ for (; start < end; start += 2) {
264
+ val = (val * 10) + (load<u16>(changetype<usize>(str) + <usize>start) - 48) as T;
265
265
  }
266
266
  return -val as T;
267
267
  } else {
268
- for (; offset < len; offset += 2) {
269
- val = ((val * 10) + (load<u16>(changetype<usize>(str) + <usize>offset) - 48)) as T;
268
+ for (; start < end; start += 2) {
269
+ val = ((val * 10) + (load<u16>(changetype<usize>(str) + <usize>start) - 48)) as T;
270
270
  }
271
271
  return val as T;
272
272
  }
273
273
  } else {
274
- for (; offset < len; offset += 2) {
275
- val = ((val * 10) + (load<u16>(changetype<usize>(str) + <usize>offset) - 48)) as T;
274
+ for (; start < end; start += 2) {
275
+ val = ((val * 10) + (load<u16>(changetype<usize>(str) + <usize>start) - 48)) as T;
276
276
  }
277
277
  return val as T;
278
278
  }
279
279
  }
280
280
 
281
281
  /**
282
- * Parses an integer using atoi_fast and applies the appended exponential number to it as scientific notation.
282
+ * Parses an integer using __atoi_fast and applies the appended exponential number to it as scientific notation.
283
283
  * Benchmark: Hovers around 30m ops/s
284
284
  * Only safe if the string is valid.
285
285
  * @param str integer to parse. example: 123e1, 123e-1, 123E100
@@ -301,12 +301,12 @@ import { backSlashCode, quoteCode } from "./chars";
301
301
  const char = load<u16>(changetype<usize>(str) + <usize>(offset += 2));
302
302
  if (char === 45) {
303
303
  // @ts-ignore
304
- val /= sciNote<T>(atoi_fast<T>(str, (offset += 2)));
304
+ val /= sciNote<T>(__atoi_fast<T>(str, (offset += 2)));
305
305
  // @ts-ignore
306
306
  return val;
307
307
  } else {
308
308
  // @ts-ignore
309
- val *= sciNote<T>(atoi_fast<T>(str, offset));
309
+ val *= sciNote<T>(__atoi_fast<T>(str, offset));
310
310
  // @ts-ignore
311
311
  return val;
312
312
  }
@@ -336,4 +336,15 @@ import { backSlashCode, quoteCode } from "./chars";
336
336
  }
337
337
  // @ts-ignore
338
338
  return res;
339
+ }
340
+
341
+ // @ts-ignore
342
+ @inline function equalsSlice(p1_data: string, p1_start: i32, p1_end: i32, p2_data: string, p2_start: i32, p2_end: i32): boolean {
343
+ const p1_len = p1_end - p1_start;
344
+ const p2_len = p2_end - p2_start;
345
+ if (p1_len != p2_len) return false;
346
+ if (p1_len == 2) {
347
+ return load<u16>(changetype<usize>(p1_data) + p1_start) == load<u16>(changetype<usize>(p2_data) + p2_start)
348
+ }
349
+ return memory.compare(changetype<usize>(p1_data) + p1_start, changetype<usize>(p2_data) + p2_start, p1_len) === 0;
339
350
  }