Skip to content

Commit

Permalink
feat(jsruntime): global env (#384)
Browse files Browse the repository at this point in the history
* feat(jsruntime): global object

* fix(jsruntime): compute locators in compiler

global variables should not be captured.

* feat(jsruntime): built-in global value properties

* fix(jsruntime): perform dereference explicitly

* refactor(jsparser): rename

* _THEN_BLOCK_ -> _THEN_
* _ELSE_BLOCK_ -> _ELSE_

* refactor(jsruntime): refactoring

* refactor(jsruntime): rename

* refactor(jsruntime): refactoring

* fix(jsruntime): check flags

* refactor(jsruntime): rename

* refactor(jsruntime): refactoring
  • Loading branch information
masnagam authored Dec 13, 2024
1 parent f0235ef commit 95c40a1
Show file tree
Hide file tree
Showing 28 changed files with 1,143 additions and 885 deletions.
186 changes: 96 additions & 90 deletions bins/estree/src/builder/actions.yaml

Large diffs are not rendered by default.

179 changes: 93 additions & 86 deletions libs/jsparser/src/syntax/actions.yaml

Large diffs are not rendered by default.

23 changes: 15 additions & 8 deletions libs/jsparser/src/syntax/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,8 @@ pub enum Node<'s> {
ArrowFunction,
AsyncArrowFunction,
AwaitExpression,
ThenBlock,
ElseBlock,
Then,
Else,
FalsyShortCircuit,
TruthyShortCircuit,
NullishShortCircuit,
Expand All @@ -235,6 +235,7 @@ pub enum Node<'s> {
LoopBody,
StartBlockScope,
EndBlockScope,
Dereference,
}

#[derive(Clone, Copy)]
Expand Down Expand Up @@ -531,15 +532,21 @@ where
Err(Error::SyntaxError)
}

// _THEN_BLOCK_
fn process_then_block(&mut self) -> Result<(), Error> {
self.enqueue(Node::ThenBlock);
// _DEREFERENCE_
fn process_dereference(&mut self) -> Result<(), Error> {
self.enqueue(Node::Dereference);
Ok(())
}

// _ELSE_BLOCK_
fn process_else_block(&mut self) -> Result<(), Error> {
self.enqueue(Node::ElseBlock);
// _THEN_
fn process_then(&mut self) -> Result<(), Error> {
self.enqueue(Node::Then);
Ok(())
}

// _ELSE_
fn process_else(&mut self) -> Result<(), Error> {
self.enqueue(Node::Else);
Ok(())
}

Expand Down
120 changes: 93 additions & 27 deletions libs/jsparser/src/transpile.js
Original file line number Diff line number Diff line change
Expand Up @@ -598,8 +598,8 @@ function addActions(rules) {
'_ASYNC_FUNCTION_CONTEXT_',
'_FUNCTION_SIGNATURE_',
'_ANONYMOUS_FUNCTION_SIGNATURE_',
'_ELSE_BLOCK_',
'_THEN_BLOCK_',
'_ELSE_',
'_THEN_',
'_BLOCK_SCOPE_',
'_FALSY_SHORT_CIRCUIT_',
'_TRUTHY_SHORT_CIRCUIT_',
Expand All @@ -621,6 +621,7 @@ function addActions(rules) {
'_TRY_BLOCK_',
'_CATCH_BLOCK_',
'_FINALLY_BLOCK_',
'_DEREFERENCE_',
];

for (const action of ACTIONS) {
Expand Down Expand Up @@ -686,12 +687,12 @@ function modifyIfStatement(rules) {

rule.values[0] = rule
.values[0]
.replace('`)` Statement[', '`)` _THEN_BLOCK_ Statement[')
.replace('`else` Statement[', '`else` _ELSE_BLOCK_ Statement[');
.replace('`)` Statement[', '`)` _THEN_ Statement[')
.replace('`else` Statement[', '`else` _ELSE_ Statement[');

rule.values[1] = rule
.values[1]
.replace('`)` Statement[', '`)` _THEN_BLOCK_ Statement[');
.replace('`)` Statement[', '`)` _THEN_ Statement[');

return rules;
}
Expand All @@ -704,18 +705,27 @@ function modifyConditionalExpression(rules) {
rule = rules.find((rule) => rule.name === 'ConditionalExpression[In, Yield, Await]');
assert(rule !== undefined);
assert(rule.values.length === 2);
const [cond, thenBlock, elseBlock] = rule
const [cond, thenExpr, elseExpr] = rule
.values[1]
.split(/`\?`|`\:`/)
.map((term) => term.trim());
rule.values[1] = [
cond,
'`?`',
'_THEN_BLOCK_',
thenBlock,
'_THEN_',
thenExpr,
// Insert the _DEREFERENCE_ actions just after the expression in order to perform dereference
// on the expression before processing the _ELSE_ action. The _ELSE_ action
// creates a basic block and switches the current basic block to it. So, the dereference has
// to be perform before that.
//
// For similar reasons, the _DEREFERENCE_ actions are inserted into other production rules as
// well.
'_DEREFERENCE_',
'`:`',
'_ELSE_BLOCK_',
elseBlock,
'_ELSE_',
elseExpr,
'_DEREFERENCE_',
].join(' ');

return rules;
Expand All @@ -725,45 +735,101 @@ function modifyShortCircuitExpressions(rules) {
const TARGETS = [
{
rule: 'LogicalANDExpression[In, Yield, Await]',
op: '`&&`',
action: '_FALSY_SHORT_CIRCUIT_',
targets: [
{
term: '`&&` BitwiseORExpression[?In, ?Yield, ?Await]',
action: '_DEREFERENCE_',
insertBefore: false,
},
{
term: '`&&`',
action: '_FALSY_SHORT_CIRCUIT_',
insertBefore: false,
},
],
},
{
rule: 'LogicalORExpression[In, Yield, Await]',
op: '`||`',
action: '_TRUTHY_SHORT_CIRCUIT_',
targets: [
{
term: '`||` LogicalANDExpression[?In, ?Yield, ?Await]',
action: '_DEREFERENCE_',
insertBefore: false,
},
{
term: '`||`',
action: '_TRUTHY_SHORT_CIRCUIT_',
insertBefore: false,
},
],
},
{
rule: 'CoalesceExpression[In, Yield, Await]',
op: '`??`',
action: '_NULLISH_SHORT_CIRCUIT_',
targets: [
{
term: '`??` BitwiseORExpression[?In, ?Yield, ?Await]',
action: '_DEREFERENCE_',
insertBefore: false,
},
{
term: '`??`',
action: '_NULLISH_SHORT_CIRCUIT_',
insertBefore: false,
},
],
},
{
rule: 'AssignmentExpression[In, Yield, Await]',
op: '`&&=`',
action: '_FALSY_SHORT_CIRCUIT_ASSIGNMENT_',
targets: [
{
term: '`&&=` AssignmentExpression[?In, ?Yield, ?Await]',
action: '_DEREFERENCE_',
insertBefore: false,
},
{
term: '`&&=`',
action: '_FALSY_SHORT_CIRCUIT_ASSIGNMENT_',
insertBefore: false,
},
],
},
{
rule: 'AssignmentExpression[In, Yield, Await]',
op: '`||=`',
action: '_TRUTHY_SHORT_CIRCUIT_ASSIGNMENT_',
targets: [
{
term: '`||=` AssignmentExpression[?In, ?Yield, ?Await]',
action: '_DEREFERENCE_',
insertBefore: false,
},
{
term: '`||=`',
action: '_TRUTHY_SHORT_CIRCUIT_ASSIGNMENT_',
insertBefore: false,
},
],
},
{
rule: 'AssignmentExpression[In, Yield, Await]',
op: '`??=`',
action: '_NULLISH_SHORT_CIRCUIT_ASSIGNMENT_',
targets: [
{
term: '`??=` AssignmentExpression[?In, ?Yield, ?Await]',
action: '_DEREFERENCE_',
insertBefore: false,
},
{
term: '`??=`',
action: '_NULLISH_SHORT_CIRCUIT_ASSIGNMENT_',
insertBefore: false,
},
],
},
];

for (const target of TARGETS) {
log.debug(`Modifying ${target.rule}...`);
const rule = rules.find((rule) => rule.name === target.rule);
assert(rule !== undefined);
const index = rule.values.findIndex((production) => production.includes(target.op));
assert(index !== -1);
const [lhs, rhs] = rule.values[index].split(target.op).map((term) => term.trim());
// Insert target.action for the short-circuit evaluation of the LHS.
rule.values[index] = [lhs, target.op, target.action, rhs].join(' ');
modifyTargetsInRule(rule, target.targets);
}

return rules;
Expand Down
155 changes: 0 additions & 155 deletions libs/jsruntime/src/function.rs

This file was deleted.

Loading

0 comments on commit 95c40a1

Please sign in to comment.