porffor 0.30.7 → 0.30.9

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.
@@ -1895,6 +1895,77 @@ const createNewTarget = (scope, decl, idx = 0) => {
1895
1895
  ];
1896
1896
  };
1897
1897
 
1898
+ const makeObject = (scope, obj) => {
1899
+ const properties = [];
1900
+ for (const x in obj) {
1901
+ properties.push({
1902
+ type: 'Property',
1903
+ method: false,
1904
+ shorthand: false,
1905
+ computed: false,
1906
+ key: {
1907
+ type: 'Identifier',
1908
+ name: x
1909
+ },
1910
+ value: obj[x],
1911
+ kind: 'init'
1912
+ });
1913
+ }
1914
+
1915
+ return generateObject(scope, {
1916
+ type: 'ObjectExpression',
1917
+ properties
1918
+ });
1919
+ };
1920
+
1921
+ const getObjProp = (obj, prop) => {
1922
+ if (typeof obj === 'string') obj = {
1923
+ type: 'Identifier',
1924
+ name: obj
1925
+ };
1926
+
1927
+ if (typeof prop === 'string') prop = {
1928
+ type: 'Identifier',
1929
+ name: prop
1930
+ };
1931
+
1932
+ return objectHack({
1933
+ type: 'MemberExpression',
1934
+ object: obj,
1935
+ property: prop,
1936
+ computed: false,
1937
+ optional: false
1938
+ });
1939
+ };
1940
+
1941
+ const setObjProp = (obj, prop, value) => {
1942
+ if (typeof obj === 'string') obj = {
1943
+ type: 'Identifier',
1944
+ name: obj
1945
+ };
1946
+
1947
+ if (typeof prop === 'string') prop = {
1948
+ type: 'Identifier',
1949
+ name: prop
1950
+ };
1951
+
1952
+ return objectHack({
1953
+ type: 'ExpressionStatement',
1954
+ expression: {
1955
+ type: 'AssignmentExpression',
1956
+ operator: '=',
1957
+ left: {
1958
+ type: 'MemberExpression',
1959
+ object: obj,
1960
+ property: prop,
1961
+ computed: false,
1962
+ optional: false
1963
+ },
1964
+ right: value
1965
+ }
1966
+ });
1967
+ };
1968
+
1898
1969
  const createThisArg = (scope, decl, knownThis = undefined) => {
1899
1970
  if (knownThis) {
1900
1971
  // todo: check compliance
@@ -1902,11 +1973,8 @@ const createThisArg = (scope, decl, knownThis = undefined) => {
1902
1973
  }
1903
1974
 
1904
1975
  if (decl._new) {
1905
- // todo: created object should have .prototype = func.prototype
1906
- // todo: created object should have .constructor = func
1907
1976
  return [
1908
- // create an empty object
1909
- ...generateObject(scope, { properties: [] }),
1977
+ ...makeObject(scope, {}),
1910
1978
  ...number(TYPES.object, Valtype.i32)
1911
1979
  ];
1912
1980
  } else {
@@ -2656,7 +2724,7 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
2656
2724
  if (valtypeBinary === Valtype.i32 &&
2657
2725
  (func && func.params[paramOffset + i * (typedParams ? 2 : 1)] === Valtype.f64)
2658
2726
  ) {
2659
- out.push(Opcodes.i32_from);
2727
+ out.push([ Opcodes.f64_convert_i32_u ]);
2660
2728
  }
2661
2729
 
2662
2730
  if (typedParams) out = out.concat(arg._callType ?? getNodeType(scope, arg));
@@ -3011,7 +3079,7 @@ const extractTypeAnnotation = decl => {
3011
3079
  };
3012
3080
 
3013
3081
  const setLocalWithType = (scope, name, isGlobal, decl, tee = false, overrideType = undefined) => {
3014
- const local = isGlobal ? globals[name] : scope.locals[name];
3082
+ const local = isGlobal ? globals[name] : (scope.locals[name] ?? { idx: name });
3015
3083
  const out = Array.isArray(decl) ? decl : generate(scope, decl, isGlobal, name);
3016
3084
 
3017
3085
  // optimize away last type usage
@@ -3445,6 +3513,39 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
3445
3513
  // ...setLastType(scope, getNodeType(scope, decl)),
3446
3514
  ],
3447
3515
 
3516
+ [TYPES.function]: [
3517
+ ...objectWasm,
3518
+ Opcodes.i32_to_u,
3519
+ ...(op === '=' ? [] : [ [ Opcodes.local_tee, localTmp(scope, '#objset_object', Valtype.i32) ] ]),
3520
+ ...getNodeType(scope, object),
3521
+
3522
+ ...propertyWasm,
3523
+ ...getNodeType(scope, property),
3524
+ ...toPropertyKey(scope, op === '='),
3525
+ ...(op === '=' ? [] : [ [ Opcodes.local_set, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
3526
+ ...(op === '=' ? [] : [
3527
+ Opcodes.i32_to_u,
3528
+ [ Opcodes.local_tee, localTmp(scope, '#objset_property', Valtype.i32) ]
3529
+ ]),
3530
+ ...(op === '=' ? [] : [ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ] ]),
3531
+
3532
+ ...(op === '=' ? generate(scope, decl.right) : performOp(scope, op, [
3533
+ [ Opcodes.local_get, localTmp(scope, '#objset_object', Valtype.i32) ],
3534
+ ...getNodeType(scope, object),
3535
+
3536
+ [ Opcodes.local_get, localTmp(scope, '#objset_property', Valtype.i32) ],
3537
+ [ Opcodes.local_get, localTmp(scope, '#objset_property_type', Valtype.i32) ],
3538
+
3539
+ [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_get').index ],
3540
+ ...setLastType(scope)
3541
+ ], generate(scope, decl.right), getLastType(scope), getNodeType(scope, decl.right), false, name, true)),
3542
+ ...getNodeType(scope, decl),
3543
+
3544
+ [ Opcodes.call, includeBuiltin(scope, '__Porffor_object_set').index ],
3545
+ [ Opcodes.drop ],
3546
+ // ...setLastType(scope, getNodeType(scope, decl)),
3547
+ ],
3548
+
3448
3549
  ...wrapBC({
3449
3550
  [TYPES.uint8array]: [
3450
3551
  [ Opcodes.i32_add ],
@@ -3738,6 +3839,8 @@ const generateUnary = (scope, decl) => {
3738
3839
  const object = decl.argument.object;
3739
3840
  const property = getMemberProperty(decl.argument);
3740
3841
 
3842
+ if (property.value === 'length' || property.value === 'name') scope.noFastFuncMembers = true;
3843
+
3741
3844
  return [
3742
3845
  ...generate(scope, object),
3743
3846
  Opcodes.i32_to_u,
@@ -5249,7 +5352,7 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5249
5352
  const name = decl.object.name;
5250
5353
 
5251
5354
  // hack: .name
5252
- if (decl.property.name === 'name' && hasFuncWithName(name)) {
5355
+ if (decl.property.name === 'name' && hasFuncWithName(name) && !scope.noFastFuncMembers) {
5253
5356
  let nameProp = name;
5254
5357
 
5255
5358
  // eg: __String_prototype_toLowerCase -> toLowerCase
@@ -5262,12 +5365,14 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5262
5365
  if (decl.property.name === 'length') {
5263
5366
  // todo: support optional
5264
5367
 
5265
- const func = funcs.find(x => x.name === name);
5266
- if (func) return withType(scope, number(countLength(func, name)), TYPES.number);
5368
+ if (!scope.noFastFuncMembers) {
5369
+ const func = funcs.find(x => x.name === name);
5370
+ if (func) return withType(scope, number(countLength(func, name)), TYPES.number);
5267
5371
 
5268
- if (Object.hasOwn(builtinFuncs, name)) return withType(scope, number(countLength(builtinFuncs[name], name)), TYPES.number);
5269
- if (Object.hasOwn(importedFuncs, name)) return withType(scope, number(importedFuncs[name].params.length ?? importedFuncs[name].params), TYPES.number);
5270
- if (Object.hasOwn(internalConstrs, name)) return withType(scope, number(internalConstrs[name].length ?? 0), TYPES.number);
5372
+ if (Object.hasOwn(builtinFuncs, name)) return withType(scope, number(countLength(builtinFuncs[name], name)), TYPES.number);
5373
+ if (Object.hasOwn(importedFuncs, name)) return withType(scope, number(importedFuncs[name].params.length ?? importedFuncs[name].params), TYPES.number);
5374
+ if (Object.hasOwn(internalConstrs, name)) return withType(scope, number(internalConstrs[name].length ?? 0), TYPES.number);
5375
+ }
5271
5376
 
5272
5377
  const out = [
5273
5378
  ...generate(scope, decl.object),
@@ -5783,9 +5888,20 @@ const generateFunc = (scope, decl) => {
5783
5888
  // todo: wrap in try and reject thrown value once supported
5784
5889
  }
5785
5890
 
5891
+ if (!globalThis.precompile && func.constr) {
5892
+ wasm.unshift(
5893
+ // if being constructed
5894
+ [ Opcodes.local_get, '#newtarget' ],
5895
+ Opcodes.i32_to_u,
5896
+ [ Opcodes.if, Blocktype.void ],
5897
+ // set prototype of this ;)
5898
+ ...generate(func, setObjProp({ type: 'ThisExpression' }, '__proto__', getObjProp(func.name, 'prototype'))),
5899
+ [ Opcodes.end ]
5900
+ );
5901
+ }
5902
+
5786
5903
  if (name === 'main') {
5787
5904
  func.gotLastType = true;
5788
-
5789
5905
  func.export = true;
5790
5906
  func.returns = [ valtypeBinary, Valtype.i32 ];
5791
5907
 
@@ -5811,7 +5927,7 @@ const generateFunc = (scope, decl) => {
5811
5927
  else func.returns = [];
5812
5928
  }
5813
5929
 
5814
- // inject promise job runner func at the end of main if used
5930
+ // inject promise job runner func at the end of main if job queue is used
5815
5931
  if (Object.hasOwn(funcIndex, '__ecma262_HostEnqueuePromiseJob')) {
5816
5932
  wasm.push(
5817
5933
  [ Opcodes.call, includeBuiltin(scope, '__Porffor_promise_runJobs').index ],
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "porffor",
3
3
  "description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
4
- "version": "0.30.7+151147330",
4
+ "version": "0.30.9+3fa3e04ac",
5
5
  "author": "CanadaHonk",
6
6
  "license": "MIT",
7
7
  "scripts": {},
package/runner/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import fs from 'node:fs';
3
- globalThis.version = '0.30.7+151147330';
3
+ globalThis.version = '0.30.9+3fa3e04ac';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {