Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c207ff5
[compiler] First example of an aliasing signature (array push)
josephsavona May 29, 2025
0d6822a
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona May 29, 2025
4f5f2ec
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona May 30, 2025
0553eb7
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona May 30, 2025
f61920b
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona May 30, 2025
bd3c784
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona May 30, 2025
4fcb9cb
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 2, 2025
85354fc
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 3, 2025
c30a39b
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 3, 2025
aab4298
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 4, 2025
51d4826
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 4, 2025
0547f2c
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 5, 2025
d5ae4d6
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 5, 2025
13a1e9b
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 5, 2025
f1f3f71
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 6, 2025
8ef6ced
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 6, 2025
27d4cd5
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 6, 2025
33676ac
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 6, 2025
b191183
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 7, 2025
f65c32b
Update on "[compiler] First example of an aliasing signature (array p…
josephsavona Jun 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,20 @@

import {CompilerError} from '../CompilerError';
import {AliasingSignature} from '../Inference/InferMutationAliasingEffects';
import {Effect, ValueKind, ValueReason} from './HIR';
import {
Effect,
GeneratedSource,
makeDeclarationId,
makeIdentifierId,
makeInstructionId,
Place,
ValueKind,
ValueReason,
} from './HIR';
import {
BuiltInType,
FunctionType,
makeType,
ObjectType,
PolyType,
PrimitiveType,
Expand Down Expand Up @@ -305,6 +315,28 @@ addObject(BUILTIN_SHAPES, BuiltInArrayId, [
returnType: PRIMITIVE_TYPE,
calleeEffect: Effect.Store,
returnValueKind: ValueKind.Primitive,
aliasing: {
receiver: makeIdentifierId(0),
params: [],
rest: makeIdentifierId(1),
returns: makeIdentifierId(2),
effects: [
// Push directly mutates the array itself
{kind: 'Mutate', value: signatureArgument(0)},
// The arguments are captured into the array
{
kind: 'Capture',
from: signatureArgument(1),
into: signatureArgument(0),
},
// Returns the new length, a primitive
{
kind: 'Create',
into: signatureArgument(2),
value: ValueKind.Primitive,
},
],
},
}),
],
[
Expand Down Expand Up @@ -1173,3 +1205,22 @@ export const DefaultNonmutatingHook = addHook(
},
'DefaultNonmutatingHook',
);

export function signatureArgument(id: number): Place {
const place: Place = {
kind: 'Identifier',
effect: Effect.Unknown,
loc: GeneratedSource,
reactive: false,
identifier: {
declarationId: makeDeclarationId(id),
id: makeIdentifierId(id),
loc: GeneratedSource,
mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
name: null,
scope: null,
type: makeType(),
},
};
return place;
}
19 changes: 19 additions & 0 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {GotoVariant, InstructionKind} from './HIR';
import {
AliasedPlace,
AliasingEffect,
AliasingSignature,
} from '../Inference/InferMutationAliasingEffects';

export type Options = {
Expand Down Expand Up @@ -991,3 +992,21 @@ function printPlaceForAliasEffect(place: Place): string {
function printAliasedPlace(place: AliasedPlace): string {
return place.kind + ' ' + printPlaceForAliasEffect(place.place);
}

export function printAliasingSignature(signature: AliasingSignature): string {
const tokens: Array<string> = ['function '];
tokens.push('(');
tokens.push('this=$' + String(signature.receiver));
for (const param of signature.params) {
tokens.push(', $' + String(param));
}
if (signature.rest != null) {
tokens.push(`, ...$${String(signature.rest)}`);
}
tokens.push('): ');
tokens.push('$' + String(signature.returns) + ':');
for (const effect of signature.effects) {
tokens.push('\n ' + printAliasingEffect(effect));
}
return tokens.join('');
}
Original file line number Diff line number Diff line change
Expand Up @@ -920,15 +920,19 @@ function computeSignatureForInstruction(
case 'CallExpression':
case 'MethodCall': {
let callee;
let receiver;
let mutatesCallee = false;
if (value.kind === 'NewExpression') {
callee = value.callee;
receiver = value.callee;
mutatesCallee = false;
} else if (value.kind === 'CallExpression') {
callee = value.callee;
receiver = value.callee;
mutatesCallee = true;
} else if (value.kind === 'MethodCall') {
callee = value.property;
receiver = value.receiver;
mutatesCallee = false;
} else {
assertExhaustive(
Expand All @@ -942,11 +946,11 @@ function computeSignatureForInstruction(
? computeEffectsForSignature(
signature.aliasing,
lvalue,
callee,
receiver,
value.args,
)
: null;
if (signatureEffects != null) {
if (signatureEffects != null && signature?.aliasing != null) {
effects.push(...signatureEffects);
} else {
effects.push({kind: 'Create', into: lvalue, value: ValueKind.Mutable});
Expand Down Expand Up @@ -1292,34 +1296,30 @@ function computeEffectsForSignature(
const effects: Array<AliasingEffect> = [];
for (const effect of signature.effects) {
switch (effect.kind) {
case 'Alias': {
const from = substitutions.get(effect.from.identifier.id) ?? [];
const to = substitutions.get(effect.into.identifier.id) ?? [];
for (const fromId of from) {
for (const toId of to) {
effects.push({kind: 'Alias', from: fromId, into: toId});
}
}
break;
}
case 'ImmutableCapture':
case 'Alias':
case 'CreateFrom':
case 'Capture': {
const from = substitutions.get(effect.from.identifier.id) ?? [];
const to = substitutions.get(effect.into.identifier.id) ?? [];
for (const fromId of from) {
for (const toId of to) {
effects.push({
kind: 'Capture',
kind: effect.kind,
from: fromId,
into: toId,
});
}
}
break;
}
case 'Mutate':
case 'MutateTransitive':
case 'MutateTransitiveConditionally':
case 'MutateConditionally': {
const values = substitutions.get(effect.value.identifier.id) ?? [];
for (const id of values) {
effects.push({kind: 'MutateConditionally', value: id});
effects.push({kind: effect.kind, value: id});
}
break;
}
Expand All @@ -1337,14 +1337,9 @@ function computeEffectsForSignature(
}
break;
}
case 'ImmutableCapture':
case 'CreateFrom':
case 'Apply':
case 'Mutate':
case 'MutateTransitive':
case 'MutateTransitiveConditionally': {
case 'Apply': {
CompilerError.throwTodo({
reason: 'Handle other types for function declarations',
reason: `Handle ${effect.kind} effects for function declarations`,
loc: lvalue.loc,
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

## Input

```javascript
// @enableNewMutationAliasingModel
function Component({a, b, c}) {
const x = [];
x.push(a);
const merged = {b}; // could be mutated by mutate(x) below
x.push(merged);
mutate(x);
const independent = {c}; // can't be later mutated
x.push(independent);
return <Foo value={x} />;
}

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime"; // @enableNewMutationAliasingModel
function Component(t0) {
const $ = _c(6);
const { a, b, c } = t0;
let t1;
if ($[0] !== a || $[1] !== b || $[2] !== c) {
const x = [];
x.push(a);
const merged = { b };
x.push(merged);
mutate(x);
let t2;
if ($[4] !== c) {
t2 = { c };
$[4] = c;
$[5] = t2;
} else {
t2 = $[5];
}
const independent = t2;
x.push(independent);
t1 = <Foo value={x} />;
$[0] = a;
$[1] = b;
$[2] = c;
$[3] = t1;
} else {
t1 = $[3];
}
return t1;
}

```

### Eval output
(kind: exception) Fixture not implemented
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// @enableNewMutationAliasingModel
function Component({a, b, c}) {
const x = [];
x.push(a);
const merged = {b}; // could be mutated by mutate(x) below
x.push(merged);
mutate(x);
const independent = {c}; // can't be later mutated
x.push(independent);
return <Foo value={x} />;
}
Loading