Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -1488,6 +1488,7 @@ function lowerExpression(
loc: exprLoc,
};
}
case 'BigIntLiteral':
case 'BooleanLiteral':
case 'NumericLiteral':
case 'StringLiteral': {
Expand All @@ -1497,7 +1498,7 @@ function lowerExpression(
const value = expr.node.value;
return {
kind: 'Primitive',
value,
value: exprNode.type === 'BigIntLiteral' ? BigInt(value) : value,
loc: exprLoc,
};
}
Expand Down Expand Up @@ -4345,6 +4346,7 @@ export function lowerType(node: t.FlowType | t.TSType): Type {
case 'NumberTypeAnnotation':
case 'StringLiteralTypeAnnotation':
case 'StringTypeAnnotation':
case 'TSBigIntKeyword':
case 'TSBooleanKeyword':
case 'TSNullKeyword':
case 'TSNumberKeyword':
Expand Down
11 changes: 11 additions & 0 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/Globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const UNTYPED_GLOBALS: Set<string> = new Set([
'Object',
'Function',
'Number',
'BigInt',
'RegExp',
'Date',
'Error',
Expand Down Expand Up @@ -328,6 +329,16 @@ const TYPED_GLOBALS: Array<[string, BuiltInType]> = [
],
]),
],
[
'BigInt',
addFunction(DEFAULT_SHAPES, [], {
positionalParams: [],
restParam: Effect.Read,
returnType: {kind: 'Primitive'},
calleeEffect: Effect.Read,
returnValueKind: ValueKind.Primitive,
}),
],
[
'Boolean',
addFunction(DEFAULT_SHAPES, [], {
Expand Down
8 changes: 2 additions & 6 deletions compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -887,11 +887,7 @@ export type InstructionValue =
loc: SourceLocation;
}
| Destructure
| {
kind: 'Primitive';
value: number | boolean | string | null | undefined;
loc: SourceLocation;
}
| Primitive
| JSXText
| {
kind: 'BinaryExpression';
Expand Down Expand Up @@ -1115,7 +1111,7 @@ export type Place = {
// A primitive value with a specific (constant) value.
export type Primitive = {
kind: 'Primitive';
value: number | boolean | string | null | undefined;
value: number | boolean | string | bigint | null | undefined;
loc: SourceLocation;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ export function printInstructionValue(instrValue: ReactiveValue): string {
case 'Primitive': {
if (instrValue.value === undefined) {
value = '<undefined>';
} else if (typeof instrValue.value === 'bigint') {
value = instrValue.value + 'n';
} else {
value = JSON.stringify(instrValue.value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,12 +346,16 @@ function evaluateInstruction(
result = {kind: 'Primitive', value: lhs + rhs, loc: value.loc};
} else if (typeof lhs === 'string' && typeof rhs === 'string') {
result = {kind: 'Primitive', value: lhs + rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs + rhs, loc: value.loc};
Comment on lines 346 to +350
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code appears to be somewhat redundant. For example, multiple if/else-if conditions could be combined, and the condition typeof lhs === 'number' && typeof rhs === 'number' could be moved to an outer layer. However, I'm not sure why this wasn't done before—perhaps it was intentional—so I've chosen to keep the original implementation.

}
break;
}
case '-': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs - rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs - rhs, loc: value.loc};
Comment on lines 354 to +358
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not apply this code to every operation. Specifically, I excluded operators such as *, **, and << because they might compute extremely large values, which could significantly increase the size of the compiled code.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++

}
break;
}
Expand All @@ -364,24 +368,32 @@ function evaluateInstruction(
case '/': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs / rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs / rhs, loc: value.loc};
}
break;
}
case '|': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs | rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs | rhs, loc: value.loc};
}
break;
}
case '&': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs & rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs & rhs, loc: value.loc};
}
break;
}
case '^': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs ^ rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs ^ rhs, loc: value.loc};
}
break;
}
Expand All @@ -394,6 +406,8 @@ function evaluateInstruction(
case '>>': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs >> rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs >> rhs, loc: value.loc};
}
break;
}
Expand All @@ -410,6 +424,8 @@ function evaluateInstruction(
case '%': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs % rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs % rhs, loc: value.loc};
}
break;
}
Expand All @@ -422,24 +438,32 @@ function evaluateInstruction(
case '<': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs < rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs < rhs, loc: value.loc};
}
break;
}
case '<=': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs <= rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs <= rhs, loc: value.loc};
}
break;
}
case '>': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs > rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs > rhs, loc: value.loc};
}
break;
}
case '>=': {
if (typeof lhs === 'number' && typeof rhs === 'number') {
result = {kind: 'Primitive', value: lhs >= rhs, loc: value.loc};
} else if (typeof lhs === 'bigint' && typeof rhs === 'bigint') {
result = {kind: 'Primitive', value: lhs >= rhs, loc: value.loc};
}
break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
ObjectPropertyKey,
Pattern,
Place,
Primitive,
PrunedReactiveScopeBlock,
ReactiveBlock,
ReactiveFunction,
Expand Down Expand Up @@ -2513,14 +2514,16 @@ function codegenLValue(
function codegenValue(
cx: Context,
loc: SourceLocation,
value: boolean | number | string | null | undefined,
value: Primitive['value'],
): t.Expression {
if (typeof value === 'number') {
return t.numericLiteral(value);
} else if (typeof value === 'boolean') {
return t.booleanLiteral(value);
} else if (typeof value === 'string') {
return createStringLiteral(loc, value);
} else if (typeof value === 'bigint') {
return t.bigIntLiteral(value + '');
} else if (value === null) {
return t.nullLiteral();
} else if (value === undefined) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

## Input

```javascript
function Test(props) {
if (props.num % 2n === 0n) {
return <>even</>;
}

return <>odd</>;
}

export const FIXTURE_ENTRYPOINT = {
fn: Test,
params: [{num: 1n}],
};

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime";
function Test(props) {
const $ = _c(2);
if (props.num % 2n === 0n) {
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <>even</>;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
}
let t0;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <>odd</>;
$[1] = t0;
} else {
t0 = $[1];
}
return t0;
}

export const FIXTURE_ENTRYPOINT = {
fn: Test,
params: [{ num: 1n }],
};

```

### Eval output
(kind: ok) odd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
function Test(props) {
if (props.num % 2n === 0n) {
return <>even</>;
}

return <>odd</>;
}

export const FIXTURE_ENTRYPOINT = {
fn: Test,
params: [{num: 1n}],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

## Input

```javascript
import {Stringify} from 'shared-runtime';

function foo() {
return (
<Stringify
value={[
12n | 0n,
12n & 0n,
12n ^ 0n,
12n | 3n,
12n & 5n,
12n ^ 7n,
12n >> 0n,
12n >> 1n,
4n % 2n,
]}
/>
);
}

export const FIXTURE_ENTRYPOINT = {
fn: foo,
params: [],
isComponent: false,
};

```

## Code

```javascript
import { c as _c } from "react/compiler-runtime";
import { Stringify } from "shared-runtime";

function foo() {
const $ = _c(1);
let t0;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t0 = <Stringify value={[12n, 0n, 12n, 15n, 4n, 11n, 12n, 6n, 0n]} />;
$[0] = t0;
} else {
t0 = $[0];
}
return t0;
}

export const FIXTURE_ENTRYPOINT = {
fn: foo,
params: [],
isComponent: false,
};

```

### Eval output
(kind: exception) Do not know how to serialize a BigInt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Stringify} from 'shared-runtime';

function foo() {
return (
<Stringify
value={[
12n | 0n,
12n & 0n,
12n ^ 0n,
12n | 3n,
12n & 5n,
12n ^ 7n,
12n >> 0n,
12n >> 1n,
4n % 2n,
]}
/>
);
}

export const FIXTURE_ENTRYPOINT = {
fn: foo,
params: [],
isComponent: false,
};
Loading
Loading