Skip to content

Commit

Permalink
builtins: rewrite handling function name/length deletion
Browse files Browse the repository at this point in the history
much simpler and less specialized/hacky now

test262: 42.26% (+0.01) | πŸ§ͺ 48414 | 🀠 20460 (+3) | ❌ 6448 (+2) | πŸ’€ 15297 (-5) | πŸ—οΈ 65 | πŸ’₯ 301 | ⏰ 28 | πŸ“ 5815
  • Loading branch information
CanadaHonk committed Sep 4, 2024
1 parent 547538b commit bacc57e
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 153 deletions.
60 changes: 0 additions & 60 deletions compiler/builtins.js
Original file line number Diff line number Diff line change
Expand Up @@ -1048,65 +1048,5 @@ export const BuiltinFuncs = function() {
table: true
};

this.__Porffor_funcLut_deleteLength = {
params: [ Valtype.i32 ],
returns: [],
wasm: (scope, { allocPage }) => [
[ Opcodes.local_get, 0 ],
...number(64, Valtype.i32),
[ Opcodes.i32_mul ],
...number(2, Valtype.i32),
[ Opcodes.i32_add ],
...number(0, Valtype.i32),
[ Opcodes.i32_store16, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ],

[ Opcodes.local_get, 0 ],
...number(1, Valtype.i32),
[ Opcodes.i32_store8, 0, ...unsignedLEB128(allocPage(scope, 'func length deletion table')) ]
],
table: true
};

this.__Porffor_funcLut_deleteName = {
params: [ Valtype.i32 ],
returns: [],
wasm: (scope, { allocPage }) => [
[ Opcodes.local_get, 0 ],
...number(64, Valtype.i32),
[ Opcodes.i32_mul ],
...number(5, Valtype.i32),
[ Opcodes.i32_add ],
...number(0, Valtype.i32),
[ Opcodes.i32_store, 0, ...unsignedLEB128(allocPage(scope, 'func lut')) ],

[ Opcodes.local_get, 0 ],
...number(1, Valtype.i32),
[ Opcodes.i32_store8, 0, ...unsignedLEB128(allocPage(scope, 'func name deletion table')) ],
],
table: true
};

this.__Porffor_funcLut_isLengthDeleted = {
params: [ Valtype.i32 ],
returns: [ Valtype.i32 ],
returnType: TYPES.boolean,
wasm: (scope, { allocPage }) => [
[ Opcodes.local_get, 0 ],
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func length deletion table')) ]
],
table: true
};

this.__Porffor_funcLut_isNameDeleted = {
params: [ Valtype.i32 ],
returns: [ Valtype.i32 ],
returnType: TYPES.boolean,
wasm: (scope, { allocPage }) => [
[ Opcodes.local_get, 0 ],
[ Opcodes.i32_load8_u, 0, ...unsignedLEB128(allocPage(scope, 'func name deletion table')) ]
],
table: true
};

PrecompiledBuiltins.BuiltinFuncs.call(this);
};
18 changes: 12 additions & 6 deletions compiler/builtins/__internal_object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,20 @@ export const __Porffor_object_underlying = (obj: any): any => {
const key2: bytestring = 'constructor';
__Porffor_object_expr_initWithFlags(proto, key2, obj, 0b1010);
}

const key3: bytestring = 'name';
__Porffor_object_expr_initWithFlags(underlying, key3, __Porffor_funcLut_name(obj), 0b0010);

const key4: bytestring = 'length';
__Porffor_object_expr_initWithFlags(underlying, key4, __Porffor_funcLut_length(obj), 0b0010);
}

if (t == Porffor.TYPES.array) {
const arr: any[] = obj;
const len: i32 = arr.length;

const key3: bytestring = 'length';
__Porffor_object_expr_initWithFlags(underlying, key3, len, 0b1000);
const key5: bytestring = 'length';
__Porffor_object_expr_initWithFlags(underlying, key5, len, 0b1000);

// todo: this should somehow be kept in sync?
for (let i: i32 = 0; i < len; i++) {
Expand All @@ -50,8 +56,8 @@ export const __Porffor_object_underlying = (obj: any): any => {
const str: string = obj;
const len: i32 = str.length;

const key4: bytestring = 'length';
__Porffor_object_expr_initWithFlags(underlying, key4, len, 0b0000);
const key6: bytestring = 'length';
__Porffor_object_expr_initWithFlags(underlying, key6, len, 0b0000);

for (let i: i32 = 0; i < len; i++) {
__Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), str[i], 0b0100);
Expand All @@ -64,8 +70,8 @@ export const __Porffor_object_underlying = (obj: any): any => {
const str: bytestring = obj;
const len: i32 = str.length;

const key5: bytestring = 'length';
__Porffor_object_expr_initWithFlags(underlying, key5, len, 0b0000);
const key7: bytestring = 'length';
__Porffor_object_expr_initWithFlags(underlying, key7, len, 0b0000);

for (let i: i32 = 0; i < len; i++) {
__Porffor_object_expr_initWithFlags(underlying, __Number_prototype_toString(i), str[i], 0b0100);
Expand Down
51 changes: 0 additions & 51 deletions compiler/builtins/_internal_object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,29 +177,6 @@ return`;

export const __Porffor_object_get = (obj: any, key: any): any => {
const trueType: i32 = Porffor.wasm`local.get ${obj+1}`;
if (trueType == Porffor.TYPES.function) {
const tmp1: bytestring = 'name';
if (key == tmp1) {
const o: bytestring = __Porffor_funcLut_name(obj);
const t: i32 = Porffor.TYPES.bytestring;
Porffor.wasm`
local.get ${o}
f64.convert_i32_u
local.get ${t}
return`;
}

const tmp2: bytestring = 'length';
if (key == tmp2) {
const o: i32 = __Porffor_funcLut_length(obj);
Porffor.wasm`
local.get ${o}
f64.convert_i32_u
i32.const 1
return`;
}
}

if (trueType != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);

if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot get property of null');
Expand Down Expand Up @@ -592,20 +569,6 @@ local.set ${err}`;
export const __Porffor_object_delete = (obj: any, key: any): boolean => {
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');

if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.function) {
const tmp1: bytestring = 'name';
if (key == tmp1) {
__Porffor_funcLut_deleteName(obj);
return true;
}

const tmp2: bytestring = 'length';
if (key == tmp2) {
__Porffor_funcLut_deleteLength(obj);
return true;
}
}

if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
// todo: support non-pure objects
Expand Down Expand Up @@ -657,20 +620,6 @@ memory.copy 0 0`;
export const __Porffor_object_deleteStrict = (obj: any, key: any): boolean => {
if (Porffor.wasm`local.get ${obj}` == 0) throw new TypeError('Cannot delete property of null');

if (Porffor.wasm`local.get ${obj+1}` == Porffor.TYPES.function) {
const tmp1: bytestring = 'name';
if (key == tmp1) {
__Porffor_funcLut_deleteName(obj);
return true;
}

const tmp2: bytestring = 'length';
if (key == tmp2) {
__Porffor_funcLut_deleteLength(obj);
return true;
}
}

if (Porffor.wasm`local.get ${obj+1}` != Porffor.TYPES.object) obj = __Porffor_object_underlying(obj);
if (Porffor.rawType(obj) != Porffor.TYPES.object) {
// todo: support non-pure objects
Expand Down
10 changes: 0 additions & 10 deletions compiler/builtins/object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,16 +150,6 @@ export const __Object_prototype_hasOwnProperty = (_this: any, prop: any) => {
return Porffor.object.lookup(_this, p) != -1;
}

if (t == Porffor.TYPES.function) {
const tmp1: bytestring = 'name';
if (p == tmp1) return !__Porffor_funcLut_isNameDeleted(_this);

const tmp2: bytestring = 'length';
if (p == tmp2) return !__Porffor_funcLut_isLengthDeleted(_this);

return Porffor.object.lookup(_this, p) != -1;
}

const obj: any = __Porffor_object_underlying(_this);
if (Porffor.rawType(obj) == Porffor.TYPES.object) {
if (Porffor.object.lookup(obj, p) != -1) return true;
Expand Down
11 changes: 10 additions & 1 deletion compiler/builtins_objects.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,16 @@ export default function({ builtinFuncs }, Prefs) {
const props = autoFuncs(x);

// special case: Object.prototype.__proto__ = null
if (x === '__Object_prototype') Object.defineProperty(props, '__proto__', { value: { value: null }, enumerable: true });
if (x === '__Object_prototype') {
Object.defineProperty(props, '__proto__', { value: { value: null, configurable: true }, enumerable: true });
}

// special case: Function.prototype.length = 0
// special case: Function.prototype.name = ''
if (x === '__Function_prototype') {
props.length = { value: 0, configurable: true };
props.name = { value: '', configurable: true };
}

// add constructor for constructors
const name = x.slice(2, x.indexOf('_', 2));
Expand Down
Loading

0 comments on commit bacc57e

Please sign in to comment.