Skip to content
Open
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
5 changes: 5 additions & 0 deletions packages/react-native-codegen/src/CodegenSchema.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ export type Int32TypeAnnotation = Readonly<{
type: 'Int32TypeAnnotation',
}>;

export type BigIntTypeAnnotation = Readonly<{
type: 'BigIntTypeAnnotation',
}>;

export type NumberLiteralTypeAnnotation = Readonly<{
type: 'NumberLiteralTypeAnnotation',
value: number,
Expand Down Expand Up @@ -418,6 +422,7 @@ export type NativeModuleBaseTypeAnnotation =
| NumberLiteralTypeAnnotation
| BooleanLiteralTypeAnnotation
| Int32TypeAnnotation
| BigIntTypeAnnotation
| DoubleTypeAnnotation
| FloatTypeAnnotation
| BooleanTypeAnnotation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ function serializeArg(
return wrap(val => `${val}.asNumber()`);
case 'Int32TypeAnnotation':
return wrap(val => `${val}.asNumber()`);
case 'BigIntTypeAnnotation':
return wrap(val => `jsi::Value(rt, ${val})`);
case 'NumberLiteralTypeAnnotation':
return wrap(val => `${val}.asNumber()`);
case 'ArrayTypeAnnotation':
Expand Down Expand Up @@ -268,6 +270,8 @@ function translatePrimitiveJSTypeToCpp(
return wrapOptional('double', isRequired);
case 'Int32TypeAnnotation':
return wrapOptional('int', isRequired);
case 'BigIntTypeAnnotation':
return wrapOptional('BigInt', isRequired);
case 'BooleanTypeAnnotation':
return wrapOptional('bool', isRequired);
case 'BooleanLiteralTypeAnnotation':
Expand Down Expand Up @@ -602,6 +606,12 @@ function translateFunctionToCpp(
enumMap,
);

// BigInt methods return BigInt from C++, but the callFromJs template
// parameter must be jsi::BigInt so the bridging layer converts via
// Bridging<BigInt>::toJs -> jsi::BigInt -> jsi::Value.
const callFromJsReturnType =
returnType === 'BigInt' ? 'jsi::BigInt' : returnType;

let methodCallArgs = [...args].join(',\n ');
if (methodCallArgs.length > 0) {
methodCallArgs = `,\n ${methodCallArgs}`;
Expand All @@ -611,7 +621,7 @@ function translateFunctionToCpp(
static_assert(
bridging::getParameterCount(&T::${prop.name}) == ${paramTypes.length},
"Expected ${prop.name}(...) to have ${paramTypes.length} parameters");
${!isVoid ? (!isNullable ? 'return ' : 'auto result = ') : ''}bridging::callFromJs<${returnType}>(rt, &T::${prop.name}, static_cast<${hasteModuleName}CxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule)${methodCallArgs});${!isVoid ? (!isNullable ? '' : 'return result ? jsi::Value(std::move(*result)) : jsi::Value::null();') : 'return jsi::Value::undefined();'}\n }`;
${!isVoid ? (!isNullable ? 'return ' : 'auto result = ') : ''}bridging::callFromJs<${callFromJsReturnType}>(rt, &T::${prop.name}, static_cast<${hasteModuleName}CxxSpec*>(&turboModule)->jsInvoker_, static_cast<T*>(&turboModule)${methodCallArgs});${!isVoid ? (!isNullable ? '' : 'return result ? jsi::Value(std::move(*result)) : jsi::Value::null();') : 'return jsi::Value::undefined();'}\n }`;
}

type EventEmitterCpp = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,9 @@ function translateEventEmitterTypeToJavaType(
case 'DoubleTypeAnnotation':
case 'Int32TypeAnnotation':
return 'double';
case 'BigIntTypeAnnotation':
imports.add('java.math.BigInteger');
return 'BigInteger';
case 'BooleanTypeAnnotation':
case 'BooleanLiteralTypeAnnotation':
return 'boolean';
Expand Down Expand Up @@ -267,6 +270,12 @@ function translateFunctionParamToJavaType(
case 'FunctionTypeAnnotation':
imports.add('com.facebook.react.bridge.Callback');
return wrapOptional('Callback', isRequired);
case 'BigIntTypeAnnotation':
throw new Error(
createErrorMessage(
`${realTypeAnnotation.type} is not supported in Java TurboModules yet`,
),
);
default:
(realTypeAnnotation.type: 'MixedTypeAnnotation');
throw new Error(createErrorMessage(realTypeAnnotation.type));
Expand Down Expand Up @@ -361,6 +370,12 @@ function translateFunctionReturnTypeToJavaType(
case 'ArrayTypeAnnotation':
imports.add('com.facebook.react.bridge.WritableArray');
return wrapOptional('WritableArray', isRequired);
case 'BigIntTypeAnnotation':
throw new Error(
createErrorMessage(
`${realTypeAnnotation.type} is not supported in Java TurboModules yet`,
),
);
default:
(realTypeAnnotation.type: 'MixedTypeAnnotation');
throw new Error(createErrorMessage(realTypeAnnotation.type));
Expand Down Expand Up @@ -443,6 +458,8 @@ function getFalsyReturnStatementFromReturnType(
return 'return null;';
case 'ArrayTypeAnnotation':
return 'return null;';
case 'BigIntTypeAnnotation':
throw new Error(createErrorMessage(realTypeAnnotation.type));
default:
(realTypeAnnotation.type: 'MixedTypeAnnotation');
throw new Error(createErrorMessage(realTypeAnnotation.type));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type JSReturnType =
| 'StringKind'
| 'BooleanKind'
| 'NumberKind'
| 'BigIntKind'
| 'PromiseKind'
| 'ObjectKind'
| 'ArrayKind';
Expand Down Expand Up @@ -208,6 +209,8 @@ function translateReturnTypeToKind(
return 'NumberKind';
case 'Int32TypeAnnotation':
return 'NumberKind';
case 'BigIntTypeAnnotation':
return 'BigIntKind';
case 'PromiseTypeAnnotation':
return 'PromiseKind';
case 'GenericObjectTypeAnnotation':
Expand Down Expand Up @@ -295,6 +298,10 @@ function translateParamTypeToJniType(
return !isRequired ? 'Ljava/lang/Double;' : 'D';
case 'Int32TypeAnnotation':
return !isRequired ? 'Ljava/lang/Double;' : 'D';
case 'BigIntTypeAnnotation':
throw new Error(
`${realTypeAnnotation.type} is not supported in Java TurboModules yet`,
);
case 'GenericObjectTypeAnnotation':
return 'Lcom/facebook/react/bridge/ReadableMap;';
case 'ObjectTypeAnnotation':
Expand Down Expand Up @@ -379,6 +386,10 @@ function translateReturnTypeToJniType(
return nullable ? 'Ljava/lang/Double;' : 'D';
case 'Int32TypeAnnotation':
return nullable ? 'Ljava/lang/Double;' : 'D';
case 'BigIntTypeAnnotation':
throw new Error(
`${realTypeAnnotation.type} is not supported in Java TurboModules yet`,
);
case 'PromiseTypeAnnotation':
return 'Lcom/facebook/react/bridge/Promise;';
case 'GenericObjectTypeAnnotation':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
'use strict';

import type {
BigIntTypeAnnotation,
BooleanLiteralTypeAnnotation,
BooleanTypeAnnotation,
DoubleTypeAnnotation,
Expand Down Expand Up @@ -72,6 +73,7 @@ export type StructTypeAnnotation =
| NumberLiteralTypeAnnotation
| BooleanLiteralTypeAnnotation
| Int32TypeAnnotation
| BigIntTypeAnnotation
| DoubleTypeAnnotation
| FloatTypeAnnotation
| BooleanTypeAnnotation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ function toObjCValue(
return wrapPrimitive('double');
case 'Int32TypeAnnotation':
return wrapPrimitive('double');
case 'BigIntTypeAnnotation':
return value;
case 'DoubleTypeAnnotation':
return wrapPrimitive('double');
case 'BooleanTypeAnnotation':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ function toObjCValue(
return RCTBridgingTo('Double');
case 'Int32TypeAnnotation':
return RCTBridgingTo('Double');
case 'BigIntTypeAnnotation':
return RCTBridgingTo('NSNumber');
case 'DoubleTypeAnnotation':
return RCTBridgingTo('Double');
case 'BooleanTypeAnnotation':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ type ReturnJSType =
| 'ObjectKind'
| 'ArrayKind'
| 'NumberKind'
| 'BigIntKind'
| 'StringKind';

export type MethodSerializationOutput = Readonly<{
Expand Down Expand Up @@ -272,6 +273,8 @@ function getParamObjCType(
return notStruct(isRequired ? 'double' : 'NSNumber *');
case 'Int32TypeAnnotation':
return notStruct(isRequired ? 'NSInteger' : 'NSNumber *');
case 'BigIntTypeAnnotation':
return notStruct(wrapOptional('NSNumber *', !nullable));
case 'BooleanTypeAnnotation':
return notStruct(isRequired ? 'BOOL' : 'NSNumber *');
case 'BooleanLiteralTypeAnnotation':
Expand Down Expand Up @@ -353,6 +356,8 @@ function getReturnObjCType(
return wrapOptional('NSNumber *', isRequired);
case 'Int32TypeAnnotation':
return wrapOptional('NSNumber *', isRequired);
case 'BigIntTypeAnnotation':
return wrapOptional('NSNumber *', isRequired);
case 'BooleanTypeAnnotation':
return wrapOptional('NSNumber *', isRequired);
case 'BooleanLiteralTypeAnnotation':
Expand Down Expand Up @@ -427,6 +432,8 @@ function getReturnJSType(
return 'NumberKind';
case 'Int32TypeAnnotation':
return 'NumberKind';
case 'BigIntTypeAnnotation':
return 'BigIntKind';
case 'BooleanTypeAnnotation':
return 'BooleanKind';
case 'BooleanLiteralTypeAnnotation':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
'use strict';

import type {
BigIntTypeAnnotation,
BooleanLiteralTypeAnnotation,
BooleanTypeAnnotation,
DoubleTypeAnnotation,
Expand Down Expand Up @@ -87,6 +88,12 @@ function emitInt32Prop(
};
}

function emitBigInt(nullable: boolean): Nullable<BigIntTypeAnnotation> {
return wrapNullable(nullable, {
type: 'BigIntTypeAnnotation',
});
}

function emitNumber(
nullable: boolean,
): Nullable<NativeModuleNumberTypeAnnotation> {
Expand Down Expand Up @@ -652,6 +659,8 @@ function emitCommonTypes(
const typeMap = {
Stringish: emitStringish,
Int32: emitInt32,
BigInt: emitBigInt,
BigIntTypeAnnotation: emitBigInt,
Double: emitDouble,
Float: emitFloat,
UnsafeObject: emitGenericObject,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ class TypeScriptParser implements Parser {
return 'ArrayTypeAnnotation';
case 'TSBooleanKeyword':
return 'BooleanTypeAnnotation';
case 'TSBigIntKeyword':
return 'BigIntTypeAnnotation';
case 'TSNumberKeyword':
return 'NumberTypeAnnotation';
case 'TSVoidKeyword':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ function formatTypeAnnotation(annotation: CompleteTypeAnnotation): string {
return 'float';
case 'Int32TypeAnnotation':
return 'int';
case 'BigIntTypeAnnotation':
return 'bigint';
case 'NumberLiteralTypeAnnotation':
return annotation.value.toString();
case 'BooleanLiteralTypeAnnotation':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ export function compareTypeAnnotationForSorting(
);
case 'NumberTypeAnnotation':
case 'Int32TypeAnnotation':
case 'BigIntTypeAnnotation':
case 'FloatTypeAnnotation':
case 'DoubleTypeAnnotation':
return 0;
Expand Down Expand Up @@ -281,6 +282,8 @@ function typeAnnotationArbitraryOrder(annotation: CompleteTypeAnnotation) {
return 28;
case 'UnionTypeAnnotation':
return 30;
case 'BigIntTypeAnnotation':
return 31;
default:
(annotation.type: empty);
return -1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export function compareTypeAnnotation(
case 'DoubleTypeAnnotation':
case 'FloatTypeAnnotation':
case 'Int32TypeAnnotation':
case 'BigIntTypeAnnotation':
case 'BooleanTypeAnnotation':
case 'NumberTypeAnnotation':
case 'StringTypeAnnotation':
Expand Down
81 changes: 81 additions & 0 deletions packages/react-native/ReactCommon/react/bridging/BigInt.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <react/bridging/Base.h>

#include <cstdint>
#include <variant>

namespace facebook::react {

class BigInt {
public:
BigInt(jsi::Runtime &rt, const jsi::BigInt &bigint)
{
if (bigint.isInt64(rt)) {
value_ = bigint.asInt64(rt);
} else if (bigint.isUint64(rt)) {
value_ = bigint.asUint64(rt);
} else {
throw jsi::JSError(rt, "BigInt value cannot be losslessly represented as int64_t or uint64_t");
}
}

/* implicit */ BigInt(int64_t value) : value_(value) {}
/* implicit */ BigInt(uint64_t value) : value_(value) {}

bool isInt64() const
{
return std::holds_alternative<int64_t>(value_);
}

bool isUint64() const
{
return std::holds_alternative<uint64_t>(value_);
}

int64_t asInt64() const
{
return std::get<int64_t>(value_);
}

uint64_t asUint64() const
{
return std::get<uint64_t>(value_);
}

jsi::BigInt toJSBigInt(jsi::Runtime &rt) const
{
if (isInt64()) {
return jsi::BigInt::fromInt64(rt, asInt64());
} else {
return jsi::BigInt::fromUint64(rt, asUint64());
}
}

bool operator==(const BigInt &other) const = default;

private:
std::variant<int64_t, uint64_t> value_;
};

template <>
struct Bridging<BigInt> {
static BigInt fromJs(jsi::Runtime &rt, const jsi::Value &value)
{
return {rt, value.getBigInt(rt)};
}

static jsi::BigInt toJs(jsi::Runtime &rt, const BigInt &value)
{
return value.toJSBigInt(rt);
}
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <react/bridging/AString.h>
#include <react/bridging/Array.h>
#include <react/bridging/BigInt.h>
#include <react/bridging/Bool.h>
#include <react/bridging/Class.h>
#include <react/bridging/Dynamic.h>
Expand Down
Loading
Loading