Skip to content

Commit

Permalink
codegen: fix call this with chain expressions
Browse files Browse the repository at this point in the history
test262: 55.11% (+0.01) | πŸ§ͺ 50254 | 🀠 27693 (+1) | ❌ 7207 | πŸ’€ 14007 (-1) | πŸ—οΈ 32 | πŸ’₯ 176 | ⏰ 140 | πŸ“ 999
  • Loading branch information
CanadaHonk committed Dec 19, 2024
1 parent 6e1a42c commit 6b0b00d
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 34 deletions.
67 changes: 36 additions & 31 deletions compiler/codegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -2119,15 +2119,17 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
}

// literal.func()
if (!decl._new && !name && decl.callee.type === 'MemberExpression') {
if (!decl._new && !name && (decl.callee.type === 'MemberExpression' || decl.callee.type === 'ChainExpression')) {
const prop = (decl.callee.expression ?? decl.callee).property;
const object = (decl.callee.expression ?? decl.callee).object;

// megahack for /regex/.func()
const funcName = decl.callee.property.name;
if (decl.callee.object.regex && ['test'].includes(funcName)) {
const regex = decl.callee.object.regex.pattern;
const rhemynName = `regex_${funcName}_${sanitize(regex)}`;
if (object?.regex && ['test'].includes(prop.name)) {
const regex = object.regex.pattern;
const rhemynName = `regex_${prop.name}_${sanitize(regex)}`;

if (!funcIndex[rhemynName]) {
const func = Rhemyn[funcName](regex, currentFuncIndex++, rhemynName);
const func = Rhemyn[prop.name](regex, currentFuncIndex++, rhemynName);
func.internal = true;

funcIndex[func.name] = func.index;
Expand All @@ -2146,15 +2148,15 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
[ Opcodes.call, idx ],
Opcodes.i32_from_u,

...setLastType(scope, Rhemyn.types[funcName])
...setLastType(scope, Rhemyn.types[prop.name])
];
}

protoName = decl.callee.property.name;
target = decl.callee.object;
protoName = prop?.name;
target = object;
}

if (protoName) {
if (protoName && target) {
if (protoName === 'call') {
const valTmp = localTmp(scope, '#call_val');
const typeTmp = localTmp(scope, '#call_type', Valtype.i32);
Expand Down Expand Up @@ -2528,28 +2530,31 @@ const generateCall = (scope, decl, _global, _name, unusedValue = false) => {
const calleeLocal = localTmp(scope, tmpName + 'callee');

// hack: this should be more thorough, Function.bind, etc
if (decl.callee.type === 'MemberExpression' && !decl._new) {
const thisLocal = localTmp(scope, tmpName + 'caller');
const thisLocalType = localTmp(scope, tmpName + 'caller#type', Valtype.i32);

knownThis = [
[ Opcodes.local_get, thisLocal ],
[ Opcodes.local_get, thisLocalType ]
];
getCallee = [
...generate(scope, decl.callee.object),
[ Opcodes.local_set, thisLocal ],
...getNodeType(scope, decl.callee.object),
[ Opcodes.local_set, thisLocalType ],
if (!decl._new && (decl.callee.type === 'MemberExpression' || decl.callee.type === 'ChainExpression')) {
const { property, object, computed, optional } = decl.callee.expression ?? decl.callee;
if (object && property) {
const thisLocal = localTmp(scope, tmpName + 'caller');
const thisLocalType = localTmp(scope, tmpName + 'caller#type', Valtype.i32);

knownThis = [
[ Opcodes.local_get, thisLocal ],
[ Opcodes.local_get, thisLocalType ]
];
getCallee = [
...generate(scope, object),
[ Opcodes.local_set, thisLocal ],
...getNodeType(scope, object),
[ Opcodes.local_set, thisLocalType ],

...generate(scope, {
type: 'MemberExpression',
object: { type: 'Identifier', name: tmpName + 'caller' },
property: decl.callee.property,
computed: decl.callee.computed,
optional: decl.callee.optional
})
];
...generate(scope, {
type: 'MemberExpression',
object: { type: 'Identifier', name: tmpName + 'caller' },
property,
computed,
optional
})
];
}
}

let callee = decl.callee, callAsNew = decl._new;
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "porffor",
"description": "a basic experimental wip aot optimizing js -> wasm engine/compiler/runtime in js",
"version": "0.55.7",
"version": "0.55.8",
"author": "CanadaHonk",
"license": "MIT",
"scripts": {},
Expand Down
2 changes: 1 addition & 1 deletion runner/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env node
import fs from 'node:fs';
globalThis.version = '0.55.7';
globalThis.version = '0.55.8';

// deno compat
if (typeof process === 'undefined' && typeof Deno !== 'undefined') {
Expand Down
2 changes: 1 addition & 1 deletion test262/history.json

Large diffs are not rendered by default.

0 comments on commit 6b0b00d

Please sign in to comment.