porffor 0.41.5 → 0.41.6

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.
@@ -893,7 +893,7 @@ const generateBinaryExp = (scope, decl, _global, _name) => {
893
893
 
894
894
  const asmFuncToAsm = (scope, func) => {
895
895
  return func(scope, {
896
- TYPES, TYPE_NAMES, typeSwitch, makeArray, makeString, allocPage, internalThrow,
896
+ Valtype, Opcodes, TYPES, TYPE_NAMES, typeSwitch, makeArray, makeString, allocPage, internalThrow,
897
897
  getNodeType, generate, generateIdent,
898
898
  builtin: (n, offset = false) => {
899
899
  let idx = funcIndex[n] ?? importedFuncs[n];
@@ -910,6 +910,7 @@ const asmFuncToAsm = (scope, func) => {
910
910
 
911
911
  return idx;
912
912
  },
913
+ hasFunc: x => funcIndex[x] != null,
913
914
  funcRef: name => {
914
915
  if (funcIndex[name] == null && builtinFuncs[name]) {
915
916
  includeBuiltin(scope, name);
@@ -3854,8 +3855,12 @@ const generateUpdate = (scope, decl, _global, _name, valueUnused = false) => {
3854
3855
  };
3855
3856
 
3856
3857
  const generateIf = (scope, decl) => {
3857
- const out = truthy(scope, generate(scope, decl.test), getNodeType(scope, decl.test), false, true);
3858
+ if (globalThis.precompile && decl.test?.tag?.name === '__Porffor_comptime_flag') {
3859
+ const flag = decl.test.quasi.quasis[0].value.raw;
3860
+ return [ [ null, 'comptime_flag', flag, decl.consequent, '#', Prefs ] ];
3861
+ }
3858
3862
 
3863
+ const out = truthy(scope, generate(scope, decl.test), getNodeType(scope, decl.test), false, true);
3859
3864
 
3860
3865
  out.push([ Opcodes.if, Blocktype.void ]);
3861
3866
  depth.push('if');
@@ -5414,17 +5419,40 @@ const generateMember = (scope, decl, _global, _name, _objectWasm = undefined) =>
5414
5419
 
5415
5420
  const known = knownType(scope, getNodeType(scope, decl.object));
5416
5421
  for (const x of prototypes) {
5417
- const type = TYPES[x.split('_prototype')[0].slice(2).toLowerCase()];
5422
+ let type = TYPES[x.split('_prototype')[0].slice(2).toLowerCase()];
5418
5423
  if (type == null) continue;
5419
5424
 
5420
5425
  // do not __proto__ primitive hack for objects or functions
5421
5426
  if (type === TYPES.object || type === TYPES.function) continue;
5422
5427
 
5428
+ // hack: do not support primitives for Object.prototype.isPrototypeOf
5429
+ if (scope.name === '__Object_prototype_isPrototypeOf') {
5430
+ switch (type) {
5431
+ case TYPES.boolean:
5432
+ type = TYPES.booleanobject;
5433
+ break;
5434
+
5435
+ case TYPES.number:
5436
+ type = TYPES.numberobject;
5437
+ break;
5438
+
5439
+ case TYPES.string:
5440
+ type = TYPES.stringobject;
5441
+ break;
5442
+
5443
+ case TYPES.bytestring:
5444
+ continue;
5445
+ }
5446
+ }
5447
+
5423
5448
  const ident = {
5424
5449
  type: 'Identifier',
5425
5450
  name: x
5426
5451
  };
5427
5452
 
5453
+ // hack: bytestrings should return string prototype
5454
+ if (type === TYPES.bytestring) ident.name = '__String_prototype';
5455
+
5428
5456
  bc[type] = () => [
5429
5457
  ...generate(scope, ident),
5430
5458
  ...setLastType(scope, getNodeType(scope, ident))
@@ -5926,6 +5954,10 @@ let objectHackers = [];
5926
5954
  const objectHack = node => {
5927
5955
  if (!node) return node;
5928
5956
 
5957
+ // delete .end, .loc while here
5958
+ delete node.end;
5959
+ delete node.loc;
5960
+
5929
5961
  if (node.type === 'MemberExpression') {
5930
5962
  const out = (() => {
5931
5963
  const abortOut = { ...node, object: objectHack(node.object) };
@@ -5950,7 +5982,7 @@ const objectHack = node => {
5950
5982
  if (objectName !== 'Object_prototype' && (node.property.name === 'propertyIsEnumerable' || node.property.name === 'hasOwnProperty' || node.property.name === 'isPrototypeOf')) return abortOut;
5951
5983
 
5952
5984
  const name = '__' + objectName + '_' + node.property.name;
5953
- if ((!hasFuncWithName(name) && !Object.hasOwn(builtinVars, name)) && (hasFuncWithName(objectName) || Object.hasOwn(builtinVars, objectName))) return abortOut;
5985
+ if ((!hasFuncWithName(name) && !Object.hasOwn(builtinVars, name) && !isExistingProtoFunc(name) && !hasFuncWithName(name + '$get')) && (hasFuncWithName(objectName) || Object.hasOwn(builtinVars, objectName) || hasFuncWithName('__' + objectName) || Object.hasOwn(builtinVars, '__' + objectName))) return abortOut;
5954
5986
 
5955
5987
  if (Prefs.codeLog) log('codegen', `object hack! ${node.object.name}.${node.property.name} -> ${name}`);
5956
5988
 
@@ -52,6 +52,8 @@ const compile = async (file, _funcs) => {
52
52
 
53
53
  const returnOverrides = {
54
54
  __Porffor_object_get: [ Valtype.f64, Valtype.i32 ],
55
+ __Porffor_object_getExplicit: [ Valtype.f64, Valtype.i32 ],
56
+ __Porffor_object_readValue: [ Valtype.f64, Valtype.i32 ],
55
57
  __Porffor_object_set: [ Valtype.f64, Valtype.i32 ],
56
58
  __Porffor_object_setStrict: [ Valtype.f64, Valtype.i32 ],
57
59
  __Porffor_object_packAccessor: [ Valtype.f64, Valtype.i32 ]
@@ -201,6 +203,10 @@ const precompile = async () => {
201
203
  const total = performance.now() - t;
202
204
  console.log(`\r${' '.repeat(100)}\r\u001b[90m${`[${total.toFixed(2)}ms]`.padEnd(12, ' ')}\u001b[0m\u001b[92mcompiled ${fileCount} files (${funcs.length} funcs)\u001b[0m \u001b[90m(${['parse', 'codegen', 'opt'].map(x => `${x}: ${((timing[x] / total) * 100).toFixed(0)}%`).join(', ')})\u001b[0m`);
203
205
 
206
+ const comptimeFlagChecks = {
207
+ hasFunc: x => `hasFunc('${x}')`
208
+ };
209
+
204
210
  return `// autogenerated by compiler/precompile.js
205
211
  import { number } from './embedding.js';
206
212
 
@@ -219,9 +225,19 @@ ${funcs.map(x => {
219
225
  .replace(/\["throw","(.*?)","(.*?)"\]/g, (_, constructor, message) => `...internalThrow(_,'${constructor}',\`${message}\`)`)
220
226
  .replace(/\["get object","(.*?)"\]/g, (_, objName) => `...generateIdent(_,{name:'${objName}'})`)
221
227
  .replace(/\[null,"typeswitch case start",\[(.*?)\]\],/g, (_, types) => `...t([${types}],()=>[`)
222
- .replaceAll(',[null,"typeswitch case end"]', '])');
223
-
224
- return `(_,{${str.includes('...t(') ? 't,' : ''}${`${str.includes('allocPage(') ? 'allocPage,' : ''}${str.includes('glbl(') ? 'glbl,' : ''}${str.includes('loc(') ? 'loc,' : ''}${str.includes('builtin(') ? 'builtin,' : ''}${str.includes('funcRef(') ? 'funcRef,' : ''}${str.includes('internalThrow(') ? 'internalThrow,' : ''}${str.includes('generateIdent(') ? 'generateIdent,' : ''}`.slice(0, -1)}})=>`.replace('_,{}', '') + str;
228
+ .replaceAll(',[null,"typeswitch case end"]', '])')
229
+ .replace(/\[null,"comptime_flag","(.*?)",(\{.*?\}),"#",(\{.*?\})\]/g, (_, flag, ast, prefs) => {
230
+ ast = JSON.parse(ast.replaceAll('\n', '\\n'));
231
+ ast = JSON.stringify(ast, (k, v) => {
232
+ if (k === 'loc' || k === 'start' || k === 'end') return undefined;
233
+ return v;
234
+ });
235
+
236
+ const [ id, extra ] = flag.split('.');
237
+ return `[null,()=>{if(${comptimeFlagChecks[id](extra)}){const r=()=>{valtype=Prefs.valtype??'f64';valtypeBinary=Valtype[valtype];const valtypeInd=['i32','i64','f64'].indexOf(valtype);Opcodes.i32_to=[[],[Opcodes.i32_wrap_i64],Opcodes.i32_trunc_sat_f64_s][valtypeInd];Opcodes.i32_to_u=[[],[Opcodes.i32_wrap_i64],Opcodes.i32_trunc_sat_f64_u][valtypeInd];Opcodes.i32_from=[[],[Opcodes.i64_extend_i32_s],[Opcodes.f64_convert_i32_s]][valtypeInd];Opcodes.i32_from_u=[[],[Opcodes.i64_extend_i32_u],[ Opcodes.f64_convert_i32_u]][valtypeInd]};const a=Prefs;Prefs=${prefs};r();const b=generate(_,${ast});Prefs=a;r();return b;}return []}]`;
238
+ });
239
+
240
+ return `(_,{${str.includes('hasFunc(') ? 'hasFunc,' : ''}${str.includes('Valtype[') ? 'Valtype,' : ''}${str.includes('Opcodes.') ? 'Opcodes,' : ''}${str.includes('...t(') ? 't,' : ''}${`${str.includes('allocPage(') ? 'allocPage,' : ''}${str.includes('glbl(') ? 'glbl,' : ''}${str.includes('loc(') ? 'loc,' : ''}${str.includes('builtin(') ? 'builtin,' : ''}${str.includes('funcRef(') ? 'funcRef,' : ''}${str.includes('internalThrow(') ? 'internalThrow,' : ''}${str.includes('generateIdent(') ? 'generateIdent,' : ''}${str.includes('generate(') ? 'generate,' : ''}`.slice(0, -1)}})=>`.replace('_,{}', '') + str;
225
241
  };
226
242
 
227
243
  const locals = Object.entries(x.locals).sort((a,b) => a[1].idx - b[1].idx)
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.41.5+1e2625ec1",
4
+ "version": "0.41.6+eb38ba00c",
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.41.5+1e2625ec1';
3
+ globalThis.version = '0.41.6+eb38ba00c';
4
4
 
5
5
  // deno compat
6
6
  if (typeof process === 'undefined' && typeof Deno !== 'undefined') {