Skip to content

Commit 8b6a19d

Browse files
[0.82] E2Ex86 CI failure fix (#15549)
* forking GenerateModuleCpp * Change files * review changes
1 parent 041b11f commit 8b6a19d

6 files changed

Lines changed: 285 additions & 19 deletions

File tree

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "forking GenerateModuleCpp",
4+
"packageName": "@react-native-windows/codegen",
5+
"email": "66076509+vineethkuttan@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "prerelease",
3+
"comment": "forking GenerateModuleCpp",
4+
"packageName": "react-native-windows",
5+
"email": "66076509+vineethkuttan@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}
Lines changed: 245 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,245 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
*
8+
* @format
9+
*/
10+
11+
'use strict';
12+
13+
const path = require('path');
14+
15+
// Load dependencies from @react-native/codegen
16+
const rnPath = path.dirname(require.resolve('react-native/package.json'));
17+
const rncodegenPath = path.dirname(
18+
require.resolve('@react-native/codegen/package.json', {paths: [rnPath]}),
19+
);
20+
21+
const {unwrapNullable} = require(
22+
path.resolve(rncodegenPath, 'lib/parsers/parsers-commons'),
23+
);
24+
const {createAliasResolver, getModules} = require(
25+
path.resolve(rncodegenPath, 'lib/generators/modules/Utils'),
26+
);
27+
const HostFunctionTemplate = ({
28+
hasteModuleName,
29+
methodName,
30+
returnTypeAnnotation,
31+
args,
32+
}) => {
33+
const isNullable = returnTypeAnnotation.type === 'NullableTypeAnnotation';
34+
const isVoid = returnTypeAnnotation.type === 'VoidTypeAnnotation';
35+
const methodCallArgs = [' rt', ...args].join(',\n ');
36+
const methodCall = `static_cast<${hasteModuleName}CxxSpecJSI *>(&turboModule)->${methodName}(\n${methodCallArgs}\n )`;
37+
return `static jsi::Value __hostFunction_${hasteModuleName}CxxSpecJSI_${methodName}(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {${isVoid ? `\n ${methodCall};` : isNullable ? `\n auto result = ${methodCall};` : ''}
38+
return ${isVoid ? 'jsi::Value::undefined()' : isNullable ? 'result ? jsi::Value(std::move(*result)) : jsi::Value::null()' : methodCall};
39+
}`;
40+
};
41+
const ModuleTemplate = ({
42+
hasteModuleName,
43+
hostFunctions,
44+
moduleName,
45+
methods,
46+
}) => {
47+
return `${hostFunctions.join('\n')}
48+
49+
${hasteModuleName}CxxSpecJSI::${hasteModuleName}CxxSpecJSI(std::shared_ptr<CallInvoker> jsInvoker)
50+
: TurboModule("${moduleName}", jsInvoker) {
51+
${methods
52+
.map(({methodName, paramCount}) => {
53+
return ` methodMap_["${methodName}"] = MethodMetadata {${paramCount}, __hostFunction_${hasteModuleName}CxxSpecJSI_${methodName}};`;
54+
})
55+
.join('\n')}
56+
}`;
57+
};
58+
const FileTemplate = ({libraryName, modules}) => {
59+
return `/**
60+
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
61+
*
62+
* Do not edit this file as changes may cause incorrect behavior and will be lost
63+
* once the code is regenerated.
64+
*
65+
* ${'@'}generated by codegen project: GenerateModuleCpp.js
66+
*/
67+
68+
#include "${libraryName}JSI.h"
69+
70+
namespace facebook::react {
71+
72+
${modules}
73+
74+
75+
} // namespace facebook::react
76+
`;
77+
};
78+
function serializeArg(moduleName, arg, index, resolveAlias, enumMap) {
79+
const {typeAnnotation: nullableTypeAnnotation, optional} = arg;
80+
const [typeAnnotation, nullable] = unwrapNullable(nullableTypeAnnotation);
81+
let realTypeAnnotation = typeAnnotation;
82+
if (realTypeAnnotation.type === 'TypeAliasTypeAnnotation') {
83+
realTypeAnnotation = resolveAlias(realTypeAnnotation.name);
84+
}
85+
function wrap(callback) {
86+
const val = `args[${index}]`;
87+
const expression = callback(val);
88+
89+
// param?: T
90+
if (optional && !nullable) {
91+
// throw new Error('are we hitting this case? ' + moduleName);
92+
return `count <= ${index} || ${val}.isUndefined() ? std::nullopt : std::make_optional(${expression})`;
93+
}
94+
95+
// param: ?T
96+
// param?: ?T
97+
if (nullable || optional) {
98+
return `count <= ${index} || ${val}.isNull() || ${val}.isUndefined() ? std::nullopt : std::make_optional(${expression})`;
99+
}
100+
101+
// param: T
102+
//return `count <= ${index} ? throw jsi::JSError(rt, "Expected argument in position ${index} to be passed") : ${expression}`;
103+
//Windows #15545
104+
return `(count > ${index} || (throw jsi::JSError(rt, "Expected argument in position ${index} to be passed"), false), ${expression})`;
105+
//Windows
106+
}
107+
switch (realTypeAnnotation.type) {
108+
case 'ReservedTypeAnnotation':
109+
switch (realTypeAnnotation.name) {
110+
case 'RootTag':
111+
return wrap(val => `${val}.asNumber()`);
112+
default:
113+
realTypeAnnotation.name;
114+
throw new Error(
115+
`Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.name}"`,
116+
);
117+
}
118+
case 'StringTypeAnnotation':
119+
return wrap(val => `${val}.asString(rt)`);
120+
case 'StringLiteralTypeAnnotation':
121+
return wrap(val => `${val}.asString(rt)`);
122+
case 'StringLiteralUnionTypeAnnotation':
123+
return wrap(val => `${val}.asString(rt)`);
124+
case 'BooleanTypeAnnotation':
125+
return wrap(val => `${val}.asBool()`);
126+
case 'EnumDeclaration':
127+
switch (realTypeAnnotation.memberType) {
128+
case 'NumberTypeAnnotation':
129+
return wrap(val => `${val}.asNumber()`);
130+
case 'StringTypeAnnotation':
131+
return wrap(val => `${val}.asString(rt)`);
132+
default:
133+
throw new Error(
134+
`Unknown enum type for "${arg.name}, found: ${realTypeAnnotation.type}"`,
135+
);
136+
}
137+
case 'NumberTypeAnnotation':
138+
return wrap(val => `${val}.asNumber()`);
139+
case 'FloatTypeAnnotation':
140+
return wrap(val => `${val}.asNumber()`);
141+
case 'DoubleTypeAnnotation':
142+
return wrap(val => `${val}.asNumber()`);
143+
case 'Int32TypeAnnotation':
144+
return wrap(val => `${val}.asNumber()`);
145+
case 'NumberLiteralTypeAnnotation':
146+
return wrap(val => `${val}.asNumber()`);
147+
case 'ArrayTypeAnnotation':
148+
return wrap(val => `${val}.asObject(rt).asArray(rt)`);
149+
case 'FunctionTypeAnnotation':
150+
return wrap(val => `${val}.asObject(rt).asFunction(rt)`);
151+
case 'GenericObjectTypeAnnotation':
152+
return wrap(val => `${val}.asObject(rt)`);
153+
case 'UnionTypeAnnotation':
154+
switch (typeAnnotation.memberType) {
155+
case 'NumberTypeAnnotation':
156+
return wrap(val => `${val}.asNumber()`);
157+
case 'ObjectTypeAnnotation':
158+
return wrap(val => `${val}.asObject(rt)`);
159+
case 'StringTypeAnnotation':
160+
return wrap(val => `${val}.asString(rt)`);
161+
default:
162+
throw new Error(
163+
`Unsupported union member type for param "${arg.name}, found: ${realTypeAnnotation.memberType}"`,
164+
);
165+
}
166+
case 'ObjectTypeAnnotation':
167+
return wrap(val => `${val}.asObject(rt)`);
168+
case 'MixedTypeAnnotation':
169+
return wrap(val => `jsi::Value(rt, ${val})`);
170+
default:
171+
realTypeAnnotation.type;
172+
throw new Error(
173+
`Unknown prop type for "${arg.name}, found: ${realTypeAnnotation.type}"`,
174+
);
175+
}
176+
}
177+
function serializePropertyIntoHostFunction(
178+
moduleName,
179+
hasteModuleName,
180+
property,
181+
resolveAlias,
182+
enumMap,
183+
) {
184+
const [propertyTypeAnnotation] = unwrapNullable(property.typeAnnotation);
185+
return HostFunctionTemplate({
186+
hasteModuleName,
187+
methodName: property.name,
188+
returnTypeAnnotation: propertyTypeAnnotation.returnTypeAnnotation,
189+
args: propertyTypeAnnotation.params.map((p, i) =>
190+
serializeArg(moduleName, p, i, resolveAlias, enumMap),
191+
),
192+
});
193+
}
194+
module.exports = {
195+
generate(
196+
libraryName,
197+
schema,
198+
packageName,
199+
assumeNonnull = false,
200+
headerPrefix,
201+
) {
202+
const nativeModules = getModules(schema);
203+
const modules = Object.keys(nativeModules)
204+
.map(hasteModuleName => {
205+
const nativeModule = nativeModules[hasteModuleName];
206+
const {
207+
aliasMap,
208+
enumMap,
209+
spec: {methods},
210+
moduleName,
211+
} = nativeModule;
212+
const resolveAlias = createAliasResolver(aliasMap);
213+
const hostFunctions = methods.map(property =>
214+
serializePropertyIntoHostFunction(
215+
moduleName,
216+
hasteModuleName,
217+
property,
218+
resolveAlias,
219+
enumMap,
220+
),
221+
);
222+
return ModuleTemplate({
223+
hasteModuleName,
224+
hostFunctions,
225+
moduleName,
226+
methods: methods.map(
227+
({name: propertyName, typeAnnotation: nullableTypeAnnotation}) => {
228+
const [{params}] = unwrapNullable(nullableTypeAnnotation);
229+
return {
230+
methodName: propertyName,
231+
paramCount: params.length,
232+
};
233+
},
234+
),
235+
});
236+
})
237+
.join('\n');
238+
const fileName = `${libraryName}JSI-generated.cpp`;
239+
const replacedTemplate = FileTemplate({
240+
modules,
241+
libraryName,
242+
});
243+
return new Map([[fileName, replacedTemplate]]);
244+
},
245+
};

packages/@react-native-windows/codegen/src/index.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,10 @@ export function generate(
254254
rncodegenPath,
255255
'lib/generators/modules/GenerateModuleH',
256256
)).generate;
257-
const generateJsiModuleCpp = require(path.resolve(
258-
rncodegenPath,
259-
'lib/generators/modules/GenerateModuleCpp',
260-
)).generate;
257+
// Use local fixed version instead of upstream to fix x86 union padding issue
258+
// with MixedTypeAnnotation. See GenerateModuleCpp.js for details.
259+
const generateJsiModuleCpp =
260+
require('./generators/GenerateModuleCpp').generate;
261261
const generatorPropsH = require(path.resolve(
262262
rncodegenPath,
263263
'lib/generators/components/GeneratePropsH',
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
{
22
"extends": "@rnw-scripts/ts-config",
3-
"include": ["src"],
4-
"exclude": ["node_modules"]
5-
}
3+
"compilerOptions": {
4+
"allowJs": true
5+
},
6+
"include": [
7+
"src"
8+
],
9+
"exclude": [
10+
"node_modules"
11+
]
12+
}

vnext/Microsoft.ReactNative.IntegrationTests/codegen/msrnIntegrationTestsJSI-generated.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getConst
1919
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_logAction(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
2020
static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->logAction(
2121
rt,
22-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt),
23-
count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : jsi::Value(rt, args[1])
22+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asString(rt)),
23+
(count > 1 || (throw jsi::JSError(rt, "Expected argument in position 1 to be passed"), false), jsi::Value(rt, args[1]))
2424
);
2525
return jsi::Value::undefined();
2626
}
@@ -33,52 +33,52 @@ static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_voidFunc
3333
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getBool(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
3434
return static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->getBool(
3535
rt,
36-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool()
36+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asBool())
3737
);
3838
}
3939
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getNumber(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
4040
return static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->getNumber(
4141
rt,
42-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber()
42+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asNumber())
4343
);
4444
}
4545
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getString(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
4646
return static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->getString(
4747
rt,
48-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asString(rt)
48+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asString(rt))
4949
);
5050
}
5151
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getArray(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
5252
return static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->getArray(
5353
rt,
54-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt).asArray(rt)
54+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asObject(rt).asArray(rt))
5555
);
5656
}
5757
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getObject(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
5858
return static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->getObject(
5959
rt,
60-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt)
60+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asObject(rt))
6161
);
6262
}
6363
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getValue(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
6464
return static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->getValue(
6565
rt,
66-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asNumber(),
67-
count <= 1 ? throw jsi::JSError(rt, "Expected argument in position 1 to be passed") : args[1].asString(rt),
68-
count <= 2 ? throw jsi::JSError(rt, "Expected argument in position 2 to be passed") : args[2].asObject(rt)
66+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asNumber()),
67+
(count > 1 || (throw jsi::JSError(rt, "Expected argument in position 1 to be passed"), false), args[1].asString(rt)),
68+
(count > 2 || (throw jsi::JSError(rt, "Expected argument in position 2 to be passed"), false), args[2].asObject(rt))
6969
);
7070
}
7171
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getValueWithCallback(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
7272
static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->getValueWithCallback(
7373
rt,
74-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asObject(rt).asFunction(rt)
74+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asObject(rt).asFunction(rt))
7575
);
7676
return jsi::Value::undefined();
7777
}
7878
static jsi::Value __hostFunction_NativeMySimpleTurboModuleCxxCxxSpecJSI_getValueWithPromise(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {
7979
return static_cast<NativeMySimpleTurboModuleCxxCxxSpecJSI *>(&turboModule)->getValueWithPromise(
8080
rt,
81-
count <= 0 ? throw jsi::JSError(rt, "Expected argument in position 0 to be passed") : args[0].asBool()
81+
(count > 0 || (throw jsi::JSError(rt, "Expected argument in position 0 to be passed"), false), args[0].asBool())
8282
);
8383
}
8484

0 commit comments

Comments
 (0)