porffor 0.18.20 → 0.18.21

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.
@@ -36,7 +36,7 @@ export const __Array_prototype_slice = (_this: any[], start: number, end: number
36
36
 
37
37
  while (thisPtr < thisPtrEnd) {
38
38
  Porffor.wasm.f64.store(outPtr, Porffor.wasm.f64.load(thisPtr, 0, 4), 0, 4);
39
- Porffor.wasm.i32.store8(outPtr + 8, Porffor.wasm.i32.load8_u(thisPtr + 8, 0, 4), 0, 4);
39
+ Porffor.wasm.i32.store8(outPtr, Porffor.wasm.i32.load8_u(thisPtr, 0, 12), 0, 12);
40
40
 
41
41
  thisPtr += 9;
42
42
  outPtr += 9;
@@ -72,7 +72,7 @@ export const __Array_prototype_splice = (_this: any[], start: number, deleteCoun
72
72
 
73
73
  while (thisPtr < thisPtrEnd) {
74
74
  Porffor.wasm.f64.store(outPtr, Porffor.wasm.f64.load(thisPtr, 0, 4), 0, 4);
75
- Porffor.wasm.i32.store8(outPtr + 8, Porffor.wasm.i32.load8_u(thisPtr + 8, 0, 4), 0, 4);
75
+ Porffor.wasm.i32.store8(outPtr, Porffor.wasm.i32.load8_u(thisPtr, 0, 12), 0, 12);
76
76
 
77
77
  thisPtr += 9;
78
78
  outPtr += 9;
@@ -133,7 +133,7 @@ memory.copy 0 0`;
133
133
 
134
134
  while (thisPtr < thisPtrEnd) {
135
135
  Porffor.wasm.f64.store(thisPtr, Porffor.wasm.f64.load(itemsPtr, 0, 4), 0, 4);
136
- Porffor.wasm.i32.store8(thisPtr + 8, Porffor.wasm.i32.load8_u(itemsPtr + 8, 0, 4), 0, 4);
136
+ Porffor.wasm.i32.store8(thisPtr, Porffor.wasm.i32.load8_u(itemsPtr, 0, 12), 0, 12);
137
137
 
138
138
  thisPtr += 9;
139
139
  itemsPtr += 9;
@@ -4,28 +4,64 @@ export default async () => {
4
4
  const arrayCode = (await import('node:fs')).readFileSync(globalThis.precompileCompilerPath + '/builtins/array.ts', 'utf8');
5
5
  const typedArrayFuncs = [...arrayCode.matchAll(/\/\/ @porf-typed-array[\s\S]+?^};$/gm)].map(x => x[0]);
6
6
 
7
- const constr = name => out += `export const ${name} = function (arg: any): ${name} {
7
+ // TypedArrays are stored like this in memory:
8
+ // length (i32)
9
+ // bufferPtr (i32)
10
+
11
+ const constr = name => out += `export const ${name} = function (arg: any, byteOffset: any, length: any): ${name} {
8
12
  if (!new.target) throw new TypeError("Constructor ${name} requires 'new'");
9
13
 
10
- const out: ${name} = Porffor.allocate();
14
+ const out: ${name} = Porffor.allocateBytes(8);
15
+ const outPtr: i32 = Porffor.wasm\`local.get \${out}\`;
16
+
11
17
  let len: i32 = 0;
18
+ let bufferPtr: i32;
12
19
 
13
20
  const type: i32 = Porffor.rawType(arg);
14
- if (Porffor.fastOr(
15
- type == Porffor.TYPES.array,
16
- type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
17
- type == Porffor.TYPES.set
18
- )) {
19
- let i: i32 = 0;
20
- for (const x of arg) {
21
- out[i++] = x;
21
+ if (type == Porffor.TYPES.arraybuffer) {
22
+ bufferPtr = Porffor.wasm\`local.get \${arg}\`;
23
+
24
+ let offset: i32 = 0;
25
+ if (Porffor.rawType(byteOffset) != Porffor.TYPES.undefined) offset = Math.trunc(byteOffset);
26
+
27
+ Porffor.wasm.i32.store(outPtr, bufferPtr + offset, 0, 4);
28
+
29
+ if (Porffor.rawType(length) == Porffor.TYPES.undefined) {
30
+ const bufferLen: i32 = Porffor.wasm.i32.load(bufferPtr, 0, 0);
31
+ len = (bufferLen - byteOffset) / ${name}.BYTES_PER_ELEMENT;
32
+
33
+ if (!Number.isInteger(len)) throw new RangeError('byte length of ${name} should be divisible by BYTES_PER_ELEMENT');
34
+ } else len = Math.trunc(length);
35
+ } else {
36
+ bufferPtr = Porffor.allocate();
37
+ Porffor.wasm.i32.store(outPtr, bufferPtr, 0, 4);
38
+
39
+ if (Porffor.fastOr(
40
+ type == Porffor.TYPES.array,
41
+ type == Porffor.TYPES.string, type == Porffor.TYPES.bytestring,
42
+ type == Porffor.TYPES.set
43
+ )) {
44
+ let i: i32 = 0;
45
+ for (const x of arg) {
46
+ out[i++] = x;
47
+ }
48
+ len = i;
49
+ } else if (type == Porffor.TYPES.number) {
50
+ len = Math.trunc(arg);
22
51
  }
23
- len = i;
24
- } else if (type == Porffor.TYPES.number) {
25
- len = arg;
52
+
53
+ Porffor.wasm.i32.store(bufferPtr, len * ${name}.BYTES_PER_ELEMENT, 0, 0);
26
54
  }
27
55
 
28
- out.length = len;
56
+ if (len < 0) throw new RangeError('Invalid TypedArray length (negative)');
57
+ if (len > 34359738368) throw new RangeError('Invalid TypedArray length (>32GiB)');
58
+
59
+ Porffor.wasm.i32.store(outPtr, len, 0, 0);
60
+ return out;
61
+ };
62
+
63
+ export const __${name}_prototype_buffer$get = (_this: ${name}) => {
64
+ const out: ArrayBuffer = Porffor.wasm.i32.load(_this, 0, 4);
29
65
  return out;
30
66
  };
31
67
 
@@ -0,0 +1,19 @@
1
+ import type {} from './porffor.d.ts';
2
+
3
+ export const ArrayBuffer = function (length: number): ArrayBuffer {
4
+ if (!new.target) throw new TypeError("Constructor ArrayBuffer requires 'new'");
5
+
6
+ if (length < 0) throw new RangeError('Invalid ArrayBuffer length (negative)');
7
+ if (length > 34359738368) throw new RangeError('Invalid ArrayBuffer length (>32GiB)');
8
+
9
+ length |= 0;
10
+
11
+ const out: ArrayBuffer = Porffor.allocateBytes(length + 4);
12
+ Porffor.wasm.i32.store(out, length, 0, 0);
13
+
14
+ return out;
15
+ };
16
+
17
+ export const __ArrayBuffer_prototype_byteLength$get = (_this: ArrayBuffer) => {
18
+ return Porffor.wasm.i32.load(_this, 0, 0);
19
+ };
@@ -1159,7 +1159,7 @@ export const BuiltinFuncs = function() {
1159
1159
  [ Opcodes.global_get, 1 ],
1160
1160
  ...number(pageSize, Valtype.i32),
1161
1161
  [ Opcodes.i32_ge_s ],
1162
- [ Opcodes.if, Blocktype.void ],
1162
+ [ Opcodes.if, Valtype.i32 ],
1163
1163
  // bytesWritten = bytesToAllocate
1164
1164
  [ Opcodes.local_get, 0 ],
1165
1165
  [ Opcodes.global_set, 1 ],
@@ -1168,20 +1168,27 @@ export const BuiltinFuncs = function() {
1168
1168
  ...number(1, Valtype.i32),
1169
1169
  [ Opcodes.memory_grow, 0x00 ],
1170
1170
 
1171
- // currentPtr = old page count * pageSize
1171
+ // currentPtr = old page count * pageSize + bytesToAllocate
1172
1172
  ...number(pageSize, Valtype.i32),
1173
1173
  [ Opcodes.i32_mul ],
1174
+ [ Opcodes.local_get, 0 ],
1175
+ [ Opcodes.i32_add ],
1174
1176
  [ Opcodes.global_set, 0 ],
1177
+
1178
+ // return currentPtr - bytesToAllocate
1179
+ [ Opcodes.global_get, 0 ],
1180
+ [ Opcodes.local_get, 0 ],
1181
+ [ Opcodes.i32_sub ],
1175
1182
  [ Opcodes.else ],
1176
1183
  // else, currentPtr += bytesToAllocate
1177
1184
  [ Opcodes.global_get, 0 ],
1178
1185
  [ Opcodes.local_get, 0 ],
1179
1186
  [ Opcodes.i32_add ],
1180
1187
  [ Opcodes.global_set, 0 ],
1181
- [ Opcodes.end ],
1182
1188
 
1183
- // return currentPtr
1184
- [ Opcodes.global_get, 0 ]
1189
+ // return currentPtr
1190
+ [ Opcodes.global_get, 0 ],
1191
+ [ Opcodes.end ]
1185
1192
  ]
1186
1193
  };
1187
1194
 
@@ -2916,6 +2916,8 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
2916
2916
  prelude: [
2917
2917
  ...generate(scope, decl.left.object),
2918
2918
  Opcodes.i32_to_u,
2919
+ [ Opcodes.i32_load, 0, 4 ],
2920
+
2919
2921
  ...generate(scope, decl.left.property),
2920
2922
  Opcodes.i32_to_u,
2921
2923
  ],
@@ -3577,6 +3579,7 @@ const generateForOf = (scope, decl) => {
3577
3579
  [ Opcodes.loop, Blocktype.void ],
3578
3580
 
3579
3581
  [ Opcodes.local_get, pointer ],
3582
+ [ Opcodes.i32_load, 0, 4 ],
3580
3583
  [ Opcodes.local_get, counter ]
3581
3584
  ],
3582
3585
  postlude: [
@@ -4230,7 +4233,7 @@ const generateMember = (scope, decl, _global, _name) => {
4230
4233
  }
4231
4234
 
4232
4235
  // todo: generate this array procedurally during builtinFuncs creation
4233
- if (['size', 'description', 'byteLength'].includes(decl.property.name)) {
4236
+ if (['size', 'description', 'byteLength', 'buffer'].includes(decl.property.name)) {
4234
4237
  const bc = {};
4235
4238
  const cands = Object.keys(builtinFuncs).filter(x => x.startsWith('__') && x.endsWith('_prototype_' + decl.property.name + '$get'));
4236
4239
 
@@ -4408,6 +4411,8 @@ const generateMember = (scope, decl, _global, _name) => {
4408
4411
  prelude: [
4409
4412
  ...object,
4410
4413
  Opcodes.i32_to_u,
4414
+ [ Opcodes.i32_load, 0, 4 ],
4415
+
4411
4416
  ...property,
4412
4417
  Opcodes.i32_to_u
4413
4418
  ],
@@ -4436,7 +4441,7 @@ const objectHack = node => {
4436
4441
  if (!objectName) objectName = objectHack(node.object)?.name?.slice?.(2);
4437
4442
 
4438
4443
  // if .name or .length, give up (hack within a hack!)
4439
- if (['name', 'length', 'size', 'description', 'byteLength'].includes(node.property.name)) {
4444
+ if (['name', 'length', 'size', 'description', 'byteLength', 'buffer'].includes(node.property.name)) {
4440
4445
  node.object = objectHack(node.object);
4441
4446
  return;
4442
4447
  }