porffor 0.37.16 → 0.37.18

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/compiler/2c.js CHANGED
@@ -15,7 +15,10 @@ const CValtype = {
15
15
  f32: 'f32',
16
16
  f64: 'f64',
17
17
 
18
- undefined: 'void'
18
+ undefined: 'void',
19
+
20
+ pointer: 'void*',
21
+ buffer: 'void*'
19
22
  };
20
23
 
21
24
  const alwaysPreface = `typedef uint8_t u8;
@@ -168,7 +171,7 @@ const removeBrackets = str => {
168
171
  if (str.startsWith(p)) return p + removeBrackets(str.slice(p.length));
169
172
  }
170
173
 
171
- return str.startsWith('(') && str.endsWith(')') ? str.slice(1, -1) : str;
174
+ return str.startsWith('(') && str.endsWith(')') && !str.startsWith('(*') ? str.slice(1, -1) : str;
172
175
  };
173
176
 
174
177
  export default ({ funcs, globals, tags, data, exceptions, pages }) => {
@@ -212,7 +215,8 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
212
215
  }
213
216
 
214
217
  if (pages.size > 0) {
215
- prepend.set('_memory', `static char _memory[${pages.size * pageSize}];\n`);
218
+ prepend.set('_memory', `char* _memory; u32 _memoryPages = ${pages.size};\n`);
219
+ prependMain.set('_initMemory', `_memory = malloc(_memoryPages * ${pageSize});\n`);
216
220
  if (Prefs['2cMemcpy']) includes.set('string.h', true);
217
221
  }
218
222
 
@@ -267,6 +271,7 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
267
271
 
268
272
  let brId = 0;
269
273
 
274
+ let ffiFuncs = {};
270
275
  const cified = new Set();
271
276
  const cify = f => {
272
277
  let out = '';
@@ -387,6 +392,23 @@ export default ({ funcs, globals, tags, data, exceptions, pages }) => {
387
392
 
388
393
  for (let _ = 0; _ < f.wasm.length; _++) {
389
394
  const i = f.wasm[_];
395
+
396
+ if (i[0] === null && i[1] === 'dlopen') {
397
+ // special ffi time
398
+ const path = i[2];
399
+ const symbols = i[3];
400
+
401
+ includes.set('dlfcn.h', true);
402
+ line(`void* _dl = dlopen("${path}", RTLD_LAZY)`);
403
+
404
+ for (const name in symbols) {
405
+ line(`*(void**)(&${name}) = dlsym(_dl, "${name}")`);
406
+ ffiFuncs[name] = symbols[name];
407
+ }
408
+
409
+ continue;
410
+ }
411
+
390
412
  if (!i || !i[0]) continue;
391
413
 
392
414
  if (invOperatorOpcode[i[0]]) {
@@ -653,22 +675,46 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
653
675
 
654
676
  if (!cified.has(func.name) && func.name !== f.name) {
655
677
  cified.add(func.name);
656
- cify(func);
678
+ if (!ffiFuncs[func.name]) {
679
+ cify(func);
680
+ }
657
681
  }
658
682
 
659
683
  let args = [];
660
684
  for (let j = 0; j < func.params.length; j++) args.unshift(removeBrackets(vals.pop()));
661
685
 
686
+ let name = sanitize(func.name);
687
+ if (ffiFuncs[func.name]) {
688
+ name = `(*` + name + ')';
689
+
690
+ // handle ffi pointer and buffer args
691
+ const { parameters } = ffiFuncs[func.name];
692
+ for (let j = 0; j < parameters.length; j++) {
693
+ if (parameters[j] === 'buffer') {
694
+ let x = args[j];
695
+ if (x.startsWith('(i32)')) x = x.slice(5);
696
+ args[j] = `(void*)((u64)_memory + (u64)(${x}) + 4)`;
697
+ }
698
+
699
+ if (parameters[j] === 'pointer') {
700
+ let x = args[j];
701
+ if (x.startsWith('(i32)')) x = '(u64)' + x.slice(5);
702
+
703
+ args[j] = `(void*)${x}`;
704
+ }
705
+ }
706
+ }
707
+
662
708
  if (func.returns.length > 0) {
663
709
  if (func.returnType != null) {
664
- vals.push(`${sanitize(func.name)}(${args.join(', ')})`);
710
+ vals.push(`${name}(${args.join(', ')})`);
665
711
  } else {
666
712
  const id = retTmpId++;
667
- line(`const struct ReturnValue _${id} = ${sanitize(func.name)}(${args.join(', ')})`);
713
+ line(`const struct ReturnValue _${id} = ${name}(${args.join(', ')})`);
668
714
  vals.push(`_${id}.value`);
669
715
  vals.push(`_${id}.type`);
670
716
  }
671
- } else line(`${sanitize(func.name)}(${args.join(', ')})`);
717
+ } else line(`${name}(${args.join(', ')})`);
672
718
 
673
719
  break;
674
720
 
@@ -796,6 +842,15 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
796
842
  // break;
797
843
  // }
798
844
 
845
+ case Opcodes.memory_grow: {
846
+ const id = localTmpId++;
847
+ line(`const u32 _oldPages${id} = _memoryPages`);
848
+ line(`_memoryPages += ${vals.pop()}`);
849
+ line(`_memory = realloc(_memory, _memoryPages * ${pageSize})`);
850
+ vals.push(`_oldPages${id}`);
851
+ break;
852
+ }
853
+
799
854
  default:
800
855
  if (CMemFuncs[i[0]]) {
801
856
  const name = invOpcodes[i[0]];
@@ -837,6 +892,11 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
837
892
 
838
893
  cify(funcs.find(x => x.name === 'main'));
839
894
 
895
+ const rawParams = f => {
896
+ if (ffiFuncs[f.name]) return ffiFuncs[f.name].parameters;
897
+ return f.params;
898
+ };
899
+
840
900
  prepend.set('func decls', funcs.filter(x => x.name !== 'main' && cified.has(x.name)).map(f => {
841
901
  const returns = f.returns.length > 0;
842
902
  const typedReturns = f.returnType == null;
@@ -848,7 +908,7 @@ _time_out = _time.tv_nsec / 1000000. + _time.tv_sec * 1000.;`);
848
908
 
849
909
  const shouldInline = false;
850
910
 
851
- return `${!typedReturns ? (returns ? CValtype[f.returns[0]] : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${sanitize(f.name)}(${f.params.map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')});`;
911
+ return `${!typedReturns ? (returns ? CValtype[f.returns[0]] : 'void') : 'struct ReturnValue'} ${shouldInline ? 'inline ' : ''}${ffiFuncs[f.name] ? '(*' : ''}${sanitize(f.name)}${ffiFuncs[f.name] ? ')' : ''}(${rawParams(f).map((x, i) => `${CValtype[x]} ${invLocals[i]}`).join(', ')});`;
852
912
  }).join('\n'));
853
913
 
854
914
  const makeIncludes = includes => [...includes.keys()].map(x => `#include <${x}>\n`).join('');