porffor 0.30.1 → 0.30.3
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/builtins/object.ts +21 -1
- package/compiler/builtins_precompiled.js +8 -1
- package/compiler/codegen.js +21 -10
- package/package.json +1 -1
- package/runner/index.js +8 -3
@@ -669,7 +669,7 @@ export const __Object_prototype_valueOf = (_this: any) => {
|
|
669
669
|
|
670
670
|
|
671
671
|
export const __Porffor_object_spread = (dst: object, src: any): object => {
|
672
|
-
if (src == null) return;
|
672
|
+
if (src == null) return dst;
|
673
673
|
|
674
674
|
// todo/perf: optimize this (and assign) for object instead of reading over object 2x
|
675
675
|
const keys: any[] = __Object_keys(src);
|
@@ -681,5 +681,25 @@ export const __Porffor_object_spread = (dst: object, src: any): object => {
|
|
681
681
|
Porffor.object.expr.init(dst, keys[i], vals[i]);
|
682
682
|
}
|
683
683
|
|
684
|
+
return dst;
|
685
|
+
};
|
686
|
+
|
687
|
+
export const __Porffor_object_rest = (dst: object, src: any, ...blocklist: any[]): object => {
|
688
|
+
if (src == null) return dst;
|
689
|
+
|
690
|
+
// todo: use ToPropertyKey on blocklist?
|
691
|
+
|
692
|
+
// todo/perf: optimize this (and assign) for object instead of reading over object 2x
|
693
|
+
const keys: any[] = __Object_keys(src);
|
694
|
+
const vals: any[] = __Object_values(src);
|
695
|
+
|
696
|
+
const len: i32 = keys.length;
|
697
|
+
for (let i: i32 = 0; i < len; i++) {
|
698
|
+
const k: any = keys[i];
|
699
|
+
if (blocklist.includes(k)) continue;
|
700
|
+
|
701
|
+
Porffor.object.expr.init(dst, k, vals[i]);
|
702
|
+
}
|
703
|
+
|
684
704
|
return dst;
|
685
705
|
};
|
@@ -1915,11 +1915,18 @@ export const BuiltinFuncs = function() {
|
|
1915
1915
|
locals: [], localNames: ["_this","_this#type"],
|
1916
1916
|
};
|
1917
1917
|
this.__Porffor_object_spread = {
|
1918
|
-
wasm: (scope, {builtin}) => [[32,2],[33,4],[32,3],[33,5],[2,127],[32,5],[65,0],[70],[4,64,"TYPESWITCH|empty"],[65,1],[12,1],[11],[32,5],[65,7],[70],[4,64,"TYPESWITCH|Object"],[32,4],[68,0,0,0,0,0,0,0,0],[97],[12,1],[11],[32,5],[65,128,1],[70],[4,64,"TYPESWITCH|undefined"],[65,1],[12,1],[11],[65,0],[11,"TYPESWITCH_end"],[4,64],[
|
1918
|
+
wasm: (scope, {builtin}) => [[32,2],[33,4],[32,3],[33,5],[2,127],[32,5],[65,0],[70],[4,64,"TYPESWITCH|empty"],[65,1],[12,1],[11],[32,5],[65,7],[70],[4,64,"TYPESWITCH|Object"],[32,4],[68,0,0,0,0,0,0,0,0],[97],[12,1],[11],[32,5],[65,128,1],[70],[4,64,"TYPESWITCH|undefined"],[65,1],[12,1],[11],[65,0],[11,"TYPESWITCH_end"],[4,64],[32,0],[65,7],[15],[11],[32,2],[32,3],[16, builtin('__Object_keys')],[26],[33,6],[32,2],[32,3],[16, builtin('__Object_values')],[26],[33,8],[32,6],[252,3],[40,1,0],[184],[33,9],[68,0,0,0,0,0,0,0,0],[33,10],[3,64],[32,10],[32,9],[99],[4,64],[32,0],[252,2],[65,7],[32,6],[33,11],[32,10],[34,12],[252,3],[65,9],[108],[32,11],[252,3],[106],[34,13],[43,0,4],[32,13],[45,0,12],[33,7],[252,2],[32,7],[32,8],[33,11],[32,10],[34,12],[252,3],[65,9],[108],[32,11],[252,3],[106],[34,13],[43,0,4],[32,13],[45,0,12],[34,7],[16, builtin('__Porffor_object_expr_init')],[33,7],[183],[26],[32,10],[68,0,0,0,0,0,0,240,63],[160],[33,10],[12,1],[11],[11],[32,0],[65,7],[15]],
|
1919
1919
|
params: [124,127,124,127], typedParams: 1,
|
1920
1920
|
returns: [124,127], typedReturns: 1,
|
1921
1921
|
locals: [124,127,124,127,124,124,124,124,124,127,127,127], localNames: ["dst","dst#type","src","src#type","#logicinner_tmp","#typeswitch_tmp1","keys","#last_type","vals","len","i","#member_obj","#member_prop","#loadArray_offset","#member_allocd","#swap"],
|
1922
1922
|
};
|
1923
|
+
this.__Porffor_object_rest = {
|
1924
|
+
wasm: (scope, {builtin}) => [[32,2],[33,6],[32,3],[33,7],[2,127],[32,7],[65,0],[70],[4,64,"TYPESWITCH|empty"],[65,1],[12,1],[11],[32,7],[65,7],[70],[4,64,"TYPESWITCH|Object"],[32,6],[68,0,0,0,0,0,0,0,0],[97],[12,1],[11],[32,7],[65,128,1],[70],[4,64,"TYPESWITCH|undefined"],[65,1],[12,1],[11],[65,0],[11,"TYPESWITCH_end"],[4,64],[32,0],[65,7],[15],[11],[32,2],[32,3],[16, builtin('__Object_keys')],[26],[33,8],[32,2],[32,3],[16, builtin('__Object_values')],[26],[33,10],[32,8],[252,3],[40,1,0],[184],[33,11],[68,0,0,0,0,0,0,0,0],[33,12],[3,64],[32,12],[32,11],[99],[4,64],[2,64],[32,8],[33,15],[32,12],[34,16],[252,3],[65,9],[108],[32,15],[252,3],[106],[34,17],[43,0,4],[32,17],[45,0,12],[33,14],[33,13],[32,4],[33,20],[65,208,0],[33,21],[32,20],[32,21],[32,13],[32,14],[68,0,0,0,0,0,0,0,0],[65,128,1],[16, builtin('__Array_prototype_includes')],[33,9],[33,6],[32,9],[33,7],[2,127],[32,7],[65,195,0],[70],[4,64,"TYPESWITCH|String"],[32,6],[252,3],[40,1,0],[12,1],[11],[32,7],[65,195,1],[70],[4,64,"TYPESWITCH|ByteString"],[32,6],[252,3],[40,1,0],[12,1],[11],[32,6],[252,3],[11,"TYPESWITCH_end"],[4,64],[12,1],[11],[32,0],[252,2],[65,7],[32,13],[252,2],[32,14],[32,10],[33,15],[32,12],[34,16],[252,3],[65,9],[108],[32,15],[252,3],[106],[34,17],[43,0,4],[32,17],[45,0,12],[34,9],[16, builtin('__Porffor_object_expr_init')],[33,9],[183],[26],[11],[32,12],[68,0,0,0,0,0,0,240,63],[160],[33,12],[12,1],[11],[11],[32,0],[65,7],[15]],
|
1925
|
+
params: [124,127,124,127,124,127], typedParams: 1,
|
1926
|
+
returns: [124,127], typedReturns: 1,
|
1927
|
+
locals: [124,127,124,127,124,124,124,124,127,124,124,127,127,127,124,127], localNames: ["dst","dst#type","src","src#type","blocklist","blocklist#type","#logicinner_tmp","#typeswitch_tmp1","keys","#last_type","vals","len","i","k","k#type","#member_obj","#member_prop","#loadArray_offset","#member_allocd","#swap","#proto_target","#proto_target#type"],
|
1928
|
+
hasRestArgument: 1,
|
1929
|
+
};
|
1923
1930
|
this.__ecma262_NewPromiseReactionJob = {
|
1924
1931
|
wasm: (scope, {builtin}) => [[65,22],[16, builtin('__Porffor_allocateBytes')],[183],[34,4],[33,7],[68,0,0,0,0,0,0,0,0],[33,8],[32,7],[252,3],[32,8],[252,3],[65,9],[108],[106],[34,6],[32,0],[34,5],[57,0,4],[32,6],[65,208,0],[58,0,12],[32,4],[33,7],[68,0,0,0,0,0,0,240,63],[33,8],[32,7],[252,3],[32,8],[252,3],[65,9],[108],[106],[34,6],[32,2],[34,5],[57,0,4],[32,6],[32,3],[58,0,12],[32,4],[65,208,0],[15]],
|
1925
1932
|
params: [124,127,124,127], typedParams: 1,
|
package/compiler/codegen.js
CHANGED
@@ -1800,6 +1800,13 @@ const disposeLeftover = wasm => {
|
|
1800
1800
|
const generateExp = (scope, decl) => {
|
1801
1801
|
const expression = decl.expression;
|
1802
1802
|
|
1803
|
+
if (expression.type === 'Literal' && typeof expression.value === 'string') {
|
1804
|
+
if (expression.value === 'use strict') {
|
1805
|
+
scope.strict = true;
|
1806
|
+
}
|
1807
|
+
return [];
|
1808
|
+
}
|
1809
|
+
|
1803
1810
|
const out = generate(scope, expression, undefined, undefined, Prefs.optUnused);
|
1804
1811
|
disposeLeftover(out);
|
1805
1812
|
|
@@ -3209,8 +3216,11 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3209
3216
|
let out = generateVarDstr(scope, 'const', tmpName, init, defaultValue, false);
|
3210
3217
|
|
3211
3218
|
const properties = [...pattern.properties];
|
3219
|
+
const usedProps = [];
|
3212
3220
|
for (const prop of properties) {
|
3213
3221
|
if (prop.type == 'Property') { // let { foo } = {}
|
3222
|
+
usedProps.push(!prop.computed && prop.key.type !== 'Literal' ? { type: 'Literal', value: prop.key.name } : prop.key);
|
3223
|
+
|
3214
3224
|
if (prop.value.type === 'AssignmentPattern') { // let { foo = defaultValue } = {}
|
3215
3225
|
decls.push(
|
3216
3226
|
...generateVarDstr(scope, kind, prop.value.left, {
|
@@ -3236,11 +3246,12 @@ const generateVarDstr = (scope, kind, pattern, init, defaultValue, global) => {
|
|
3236
3246
|
type: 'CallExpression',
|
3237
3247
|
callee: {
|
3238
3248
|
type: 'Identifier',
|
3239
|
-
name: '
|
3249
|
+
name: '__Porffor_object_rest'
|
3240
3250
|
},
|
3241
3251
|
arguments: [
|
3242
3252
|
{ type: 'ObjectExpression', properties: [] },
|
3243
|
-
{ type: 'Identifier', name: tmpName }
|
3253
|
+
{ type: 'Identifier', name: tmpName },
|
3254
|
+
...usedProps
|
3244
3255
|
]
|
3245
3256
|
}, undefined, global)
|
3246
3257
|
);
|
@@ -3607,10 +3618,8 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3607
3618
|
}
|
3608
3619
|
|
3609
3620
|
if (local === undefined) {
|
3610
|
-
//
|
3611
|
-
|
3612
|
-
// only allow = for this
|
3613
|
-
if (op !== '=') return internalThrow(scope, 'ReferenceError', `${unhackName(name)} is not defined`);
|
3621
|
+
// only allow = for this, or if in strict mode always throw
|
3622
|
+
if (op !== '=' || scope.strict) return internalThrow(scope, 'ReferenceError', `${unhackName(name)} is not defined`, true);
|
3614
3623
|
|
3615
3624
|
if (type != 'Identifier') {
|
3616
3625
|
const tmpName = '#rhs' + uniqId();
|
@@ -3623,6 +3632,8 @@ const generateAssign = (scope, decl, _global, _name, valueUnused = false) => {
|
|
3623
3632
|
}
|
3624
3633
|
|
3625
3634
|
if (Object.hasOwn(builtinVars, name)) {
|
3635
|
+
if (scope.strict) return internalThrow(scope, 'TypeError', `Cannot assign to non-writable global ${name}`, true);
|
3636
|
+
|
3626
3637
|
// just return rhs (eg `NaN = 2`)
|
3627
3638
|
return generate(scope, decl.right);
|
3628
3639
|
}
|
@@ -3749,7 +3760,6 @@ const generateUnary = (scope, decl) => {
|
|
3749
3760
|
|
3750
3761
|
// if ReferenceError (undeclared var), ignore and return true. otherwise false
|
3751
3762
|
if (!out[1]) {
|
3752
|
-
// todo: throw in strict mode
|
3753
3763
|
// exists
|
3754
3764
|
toReturn = false;
|
3755
3765
|
} else {
|
@@ -4022,7 +4032,7 @@ const generateForOf = (scope, decl) => {
|
|
4022
4032
|
// setup local for left
|
4023
4033
|
let setVar;
|
4024
4034
|
if (decl.left.type === 'Identifier') {
|
4025
|
-
|
4035
|
+
if (scope.strict) return internalThrow(scope, 'ReferenceError', `${decl.left.name} is not defined`);
|
4026
4036
|
setVar = generateVarDstr(scope, 'var', decl.left, { type: 'Identifier', name: tmpName }, undefined, true);
|
4027
4037
|
} else {
|
4028
4038
|
// todo: verify this is correct
|
@@ -4389,7 +4399,7 @@ const generateForIn = (scope, decl) => {
|
|
4389
4399
|
|
4390
4400
|
let setVar;
|
4391
4401
|
if (decl.left.type === 'Identifier') {
|
4392
|
-
|
4402
|
+
if (scope.strict) return internalThrow(scope, 'ReferenceError', `${decl.left.name} is not defined`);
|
4393
4403
|
setVar = generateVarDstr(scope, 'var', decl.left, { type: 'Identifier', name: tmpName }, undefined, true);
|
4394
4404
|
} else {
|
4395
4405
|
// todo: verify this is correct
|
@@ -5638,7 +5648,8 @@ const generateFunc = (scope, decl) => {
|
|
5638
5648
|
// not arrow function or main
|
5639
5649
|
(decl.type && decl.type !== 'ArrowFunctionExpression' && decl.type !== 'Program') &&
|
5640
5650
|
// not async or generator
|
5641
|
-
!decl.async && !decl.generator
|
5651
|
+
!decl.async && !decl.generator,
|
5652
|
+
strict: scope.strict
|
5642
5653
|
};
|
5643
5654
|
|
5644
5655
|
funcIndex[name] = func.index;
|
package/package.json
CHANGED
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.
|
3
|
+
globalThis.version = '0.30.3+8ee696663';
|
4
4
|
|
5
5
|
// deno compat
|
6
6
|
if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
|
@@ -115,7 +115,10 @@ if (process.argv.length >= 4) {
|
|
115
115
|
if (evalIndex !== -1) {
|
116
116
|
source = process.argv[evalIndex + 1];
|
117
117
|
if (source) {
|
118
|
-
|
118
|
+
// todo: this isn't entirely right, because shells should do the quoting for us but works well enough, see below as well
|
119
|
+
if ((source.startsWith('"') || source.startsWith("'")) && (source.endsWith('"') || source.endsWith("'"))) {
|
120
|
+
source = source.slice(1, -1);
|
121
|
+
}
|
119
122
|
process.argv.splice(evalIndex, 2); // remove flag and value
|
120
123
|
}
|
121
124
|
}
|
@@ -126,7 +129,9 @@ if (process.argv.length >= 4) {
|
|
126
129
|
process.argv.push('--no-opt-unused');
|
127
130
|
source = process.argv[printIndex + 1];
|
128
131
|
if (source) {
|
129
|
-
if (source.startsWith('"') || source.startsWith("'")) source
|
132
|
+
if ((source.startsWith('"') || source.startsWith("'")) && (source.endsWith('"') || source.endsWith("'"))) {
|
133
|
+
source = source.slice(1, -1);
|
134
|
+
}
|
130
135
|
process.argv.splice(printIndex, 2); // remove flag and value
|
131
136
|
}
|
132
137
|
|