-
Notifications
You must be signed in to change notification settings - Fork 51k
[compiler] Delete LoweredFunction.dependencies and hoisted instructions #31204
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7ac7b52
e288dea
13752bf
de4b0a8
00a53cc
2b51f3b
640a785
98b0d00
cdf5e83
cd06aee
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,7 +7,6 @@ | |
|
|
||
| import {NodePath, Scope} from '@babel/traverse'; | ||
| import * as t from '@babel/types'; | ||
| import {Expression} from '@babel/types'; | ||
| import invariant from 'invariant'; | ||
| import { | ||
| CompilerError, | ||
|
|
@@ -3186,7 +3185,13 @@ function lowerJsxMemberExpression( | |
| loc: object.node.loc ?? null, | ||
| suggestions: null, | ||
| }); | ||
| objectPlace = lowerIdentifier(builder, object); | ||
|
|
||
| const kind = getLoadKind(builder, object); | ||
| objectPlace = lowerValueToTemporary(builder, { | ||
| kind: kind, | ||
| place: lowerIdentifier(builder, object), | ||
| loc: exprPath.node.loc ?? GeneratedSource, | ||
| }); | ||
| } | ||
| const property = exprPath.get('property').node.name; | ||
| return lowerValueToTemporary(builder, { | ||
|
|
@@ -3359,7 +3364,7 @@ function lowerFunction( | |
| >, | ||
| ): LoweredFunction | null { | ||
| const componentScope: Scope = builder.parentFunction.scope; | ||
| const captured = gatherCapturedDeps(builder, expr, componentScope); | ||
| const capturedContext = gatherCapturedContext(expr, componentScope); | ||
|
|
||
| /* | ||
| * TODO(gsn): In the future, we could only pass in the context identifiers | ||
|
|
@@ -3373,7 +3378,7 @@ function lowerFunction( | |
| expr, | ||
| builder.environment, | ||
| builder.bindings, | ||
| [...builder.context, ...captured.identifiers], | ||
| [...builder.context, ...capturedContext], | ||
| builder.parentFunction, | ||
| ); | ||
| let loweredFunc: HIRFunction; | ||
|
|
@@ -3386,7 +3391,6 @@ function lowerFunction( | |
| loweredFunc = lowering.unwrap(); | ||
| return { | ||
| func: loweredFunc, | ||
| dependencies: captured.refs, | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -4060,14 +4064,6 @@ function lowerAssignment( | |
| } | ||
| } | ||
|
|
||
| function isValidDependency(path: NodePath<t.MemberExpression>): boolean { | ||
| const parent: NodePath<t.Node> = path.parentPath; | ||
| return ( | ||
| !path.node.computed && | ||
| !(parent.isCallExpression() && parent.get('callee') === path) | ||
| ); | ||
| } | ||
|
|
||
| function captureScopes({from, to}: {from: Scope; to: Scope}): Set<Scope> { | ||
| let scopes: Set<Scope> = new Set(); | ||
| while (from) { | ||
|
|
@@ -4082,19 +4078,16 @@ function captureScopes({from, to}: {from: Scope; to: Scope}): Set<Scope> { | |
| return scopes; | ||
| } | ||
|
|
||
| function gatherCapturedDeps( | ||
| builder: HIRBuilder, | ||
| function gatherCapturedContext( | ||
| fn: NodePath< | ||
| | t.FunctionExpression | ||
| | t.ArrowFunctionExpression | ||
| | t.FunctionDeclaration | ||
| | t.ObjectMethod | ||
| >, | ||
| componentScope: Scope, | ||
| ): {identifiers: Array<t.Identifier>; refs: Array<Place>} { | ||
| const capturedIds: Map<t.Identifier, number> = new Map(); | ||
| const capturedRefs: Set<Place> = new Set(); | ||
| const seenPaths: Set<string> = new Set(); | ||
| ): Array<t.Identifier> { | ||
| const capturedIds = new Set<t.Identifier>(); | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We now only need a set of seen context variables. Previously |
||
|
|
||
| /* | ||
| * Capture all the scopes from the parent of this function up to and including | ||
|
|
@@ -4105,33 +4098,11 @@ function gatherCapturedDeps( | |
| to: componentScope, | ||
| }); | ||
|
|
||
| function addCapturedId(bindingIdentifier: t.Identifier): number { | ||
| if (!capturedIds.has(bindingIdentifier)) { | ||
| const index = capturedIds.size; | ||
| capturedIds.set(bindingIdentifier, index); | ||
| return index; | ||
| } else { | ||
| return capturedIds.get(bindingIdentifier)!; | ||
| } | ||
| } | ||
|
|
||
| function handleMaybeDependency( | ||
| path: | ||
| | NodePath<t.MemberExpression> | ||
| | NodePath<t.Identifier> | ||
| | NodePath<t.JSXOpeningElement>, | ||
| path: NodePath<t.Identifier> | NodePath<t.JSXOpeningElement>, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This becomes much simpler as we just need to extract potential context variables (i.e. ones defined in an outer scope of the current function) |
||
| ): void { | ||
| // Base context variable to depend on | ||
| let baseIdentifier: NodePath<t.Identifier> | NodePath<t.JSXIdentifier>; | ||
| /* | ||
| * Base expression to depend on, which (for now) may contain non side-effectful | ||
| * member expressions | ||
| */ | ||
| let dependency: | ||
| | NodePath<t.MemberExpression> | ||
| | NodePath<t.JSXMemberExpression> | ||
| | NodePath<t.Identifier> | ||
| | NodePath<t.JSXIdentifier>; | ||
| if (path.isJSXOpeningElement()) { | ||
| const name = path.get('name'); | ||
| if (!(name.isJSXMemberExpression() || name.isJSXIdentifier())) { | ||
|
|
@@ -4147,115 +4118,20 @@ function gatherCapturedDeps( | |
| 'Invalid logic in gatherCapturedDeps', | ||
| ); | ||
| baseIdentifier = current; | ||
|
|
||
| /* | ||
| * Get the expression to depend on, which may involve PropertyLoads | ||
| * for member expressions | ||
| */ | ||
| let currentDep: | ||
| | NodePath<t.JSXMemberExpression> | ||
| | NodePath<t.Identifier> | ||
| | NodePath<t.JSXIdentifier> = baseIdentifier; | ||
|
|
||
| while (true) { | ||
| const nextDep: null | NodePath<t.Node> = currentDep.parentPath; | ||
| if (nextDep && nextDep.isJSXMemberExpression()) { | ||
| currentDep = nextDep; | ||
| } else { | ||
| break; | ||
| } | ||
| } | ||
| dependency = currentDep; | ||
| } else if (path.isMemberExpression()) { | ||
| // Calculate baseIdentifier | ||
| let currentId: NodePath<Expression> = path; | ||
| while (currentId.isMemberExpression()) { | ||
| currentId = currentId.get('object'); | ||
| } | ||
| if (!currentId.isIdentifier()) { | ||
| return; | ||
| } | ||
| baseIdentifier = currentId; | ||
|
|
||
| /* | ||
| * Get the expression to depend on, which may involve PropertyLoads | ||
| * for member expressions | ||
| */ | ||
| let currentDep: | ||
| | NodePath<t.MemberExpression> | ||
| | NodePath<t.Identifier> | ||
| | NodePath<t.JSXIdentifier> = baseIdentifier; | ||
|
|
||
| while (true) { | ||
| const nextDep: null | NodePath<t.Node> = currentDep.parentPath; | ||
| if ( | ||
| nextDep && | ||
| nextDep.isMemberExpression() && | ||
| isValidDependency(nextDep) | ||
| ) { | ||
| currentDep = nextDep; | ||
| } else { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| dependency = currentDep; | ||
| } else { | ||
| baseIdentifier = path; | ||
| dependency = path; | ||
| } | ||
|
|
||
| /* | ||
| * Skip dependency path, as we already tried to recursively add it (+ all subexpressions) | ||
| * as a dependency. | ||
| */ | ||
| dependency.skip(); | ||
| path.skip(); | ||
|
|
||
| // Add the base identifier binding as a dependency. | ||
| const binding = baseIdentifier.scope.getBinding(baseIdentifier.node.name); | ||
| if (binding === undefined || !pureScopes.has(binding.scope)) { | ||
| return; | ||
| } | ||
| const idKey = String(addCapturedId(binding.identifier)); | ||
|
|
||
| // Add the expression (potentially a memberexpr path) as a dependency. | ||
| let exprKey = idKey; | ||
| if (dependency.isMemberExpression()) { | ||
| let pathTokens = []; | ||
| let current: NodePath<Expression> = dependency; | ||
| while (current.isMemberExpression()) { | ||
| const property = current.get('property') as NodePath<t.Identifier>; | ||
| pathTokens.push(property.node.name); | ||
| current = current.get('object'); | ||
| } | ||
|
|
||
| exprKey += '.' + pathTokens.reverse().join('.'); | ||
| } else if (dependency.isJSXMemberExpression()) { | ||
| let pathTokens = []; | ||
| let current: NodePath<t.JSXMemberExpression | t.JSXIdentifier> = | ||
| dependency; | ||
| while (current.isJSXMemberExpression()) { | ||
| const property = current.get('property'); | ||
| pathTokens.push(property.node.name); | ||
| current = current.get('object'); | ||
| } | ||
| } | ||
|
|
||
| if (!seenPaths.has(exprKey)) { | ||
| let loweredDep: Place; | ||
| if (dependency.isJSXIdentifier()) { | ||
| loweredDep = lowerValueToTemporary(builder, { | ||
| kind: 'LoadLocal', | ||
| place: lowerIdentifier(builder, dependency), | ||
| loc: path.node.loc ?? GeneratedSource, | ||
| }); | ||
| } else if (dependency.isJSXMemberExpression()) { | ||
| loweredDep = lowerJsxMemberExpression(builder, dependency); | ||
| } else { | ||
| loweredDep = lowerExpressionToTemporary(builder, dependency); | ||
| } | ||
| capturedRefs.add(loweredDep); | ||
| seenPaths.add(exprKey); | ||
| if (binding !== undefined && pureScopes.has(binding.scope)) { | ||
| capturedIds.add(binding.identifier); | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -4286,13 +4162,13 @@ function gatherCapturedDeps( | |
| return; | ||
| } else if (path.isJSXElement()) { | ||
| handleMaybeDependency(path.get('openingElement')); | ||
| } else if (path.isMemberExpression() || path.isIdentifier()) { | ||
| } else if (path.isIdentifier()) { | ||
| handleMaybeDependency(path); | ||
| } | ||
| }, | ||
| }); | ||
|
|
||
| return {identifiers: [...capturedIds.keys()], refs: [...capturedRefs]}; | ||
| return [...capturedIds.keys()]; | ||
| } | ||
|
|
||
| function notNull<T>(value: T | null): value is T { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed as we don't calculate
LoweredFunction.dependenciesanymore