@@ -1208,6 +1208,36 @@ extern "C" void FfiCallTrampoline(FfiCallArguments* args);
12081208extern " C" typedef void (*ffiCallTrampoline)(FfiCallArguments* args);
12091209#endif
12101210
1211+ static int64_t TruncateFfiInt (int64_t value,
1212+ compiler::ffi::PrimitiveType type,
1213+ bool is_return) {
1214+ #if defined(HOST_ARCH_RISCV64)
1215+ // 64-bit RISC-V represents C uint32 as sign-extended to 64 bits.
1216+ if (!is_return && (type == compiler::ffi::kUint32 )) {
1217+ return static_cast <int32_t >(static_cast <uint32_t >(value));
1218+ }
1219+ #endif
1220+ switch (type) {
1221+ case compiler::ffi::kInt8 :
1222+ return static_cast <int8_t >(value);
1223+ case compiler::ffi::kUint8 :
1224+ return static_cast <uint8_t >(value);
1225+ case compiler::ffi::kInt16 :
1226+ return static_cast <int16_t >(value);
1227+ case compiler::ffi::kUint16 :
1228+ return static_cast <uint16_t >(value);
1229+ case compiler::ffi::kInt32 :
1230+ return static_cast <int32_t >(value);
1231+ case compiler::ffi::kUint32 :
1232+ return static_cast <uint32_t >(value);
1233+ case compiler::ffi::kInt64 :
1234+ case compiler::ffi::kUint64 :
1235+ return value;
1236+ default :
1237+ UNREACHABLE ();
1238+ }
1239+ }
1240+ 12111241static void PassFfiCallArguments (
12121242 Thread* thread,
12131243 const compiler::ffi::CallMarshaller& marshaller,
@@ -1238,7 +1268,12 @@ static void PassFfiCallArguments(
12381268 ASSERT (!marshaller.IsVoid (i));
12391269 const auto rep = marshaller.RepInDart (i);
12401270 if (RepresentationUtils::IsUnboxedInteger (rep)) {
1241- value = Integer::Cast (arg).Value ();
1271+ value = TruncateFfiInt (Integer::Cast (arg).Value (),
1272+ marshaller.Location (i)
1273+ .payload_type ()
1274+ .AsPrimitive ()
1275+ .representation (),
1276+ /* is_return=*/ false );
12421277 } else if (rep == kUnboxedDouble ) {
12431278 value = bit_cast<uint64_t , double >(Double::Cast (arg).value ());
12441279 } else if (rep == kUnboxedFloat ) {
@@ -1294,20 +1329,32 @@ static ObjectPtr ReceiveFfiCallResult(
12941329 } else if (marshaller.IsVoid (arg_index)) {
12951330 return Object::null ();
12961331 } else if (marshaller.IsBool (arg_index)) {
1297- uword value = args->cpu_registers [CallingConventions::kReturnReg ];
1332+ int64_t value =
1333+ TruncateFfiInt (args->cpu_registers [CallingConventions::kReturnReg ],
1334+ marshaller.Location (arg_index)
1335+ .payload_type ()
1336+ .AsPrimitive ()
1337+ .representation (),
1338+ /* is_return=*/ true );
12981339 return Bool::Get (value != 0 ).ptr ();
12991340 } else {
13001341 const auto rep = marshaller.RepInDart (arg_index);
13011342 if (RepresentationUtils::IsUnboxedInteger (rep)) {
1302- uword value = args->cpu_registers [CallingConventions::kReturnReg ];
1343+ const int64_t value =
1344+ TruncateFfiInt (args->cpu_registers [CallingConventions::kReturnReg ],
1345+ marshaller.Location (arg_index)
1346+ .payload_type ()
1347+ .AsPrimitive ()
1348+ .representation (),
1349+ /* is_return=*/ true );
13031350 return Integer::New (value);
13041351 } else if (rep == kUnboxedDouble ) {
1305- double value = args->fpu_registers [CallingConventions::kReturnFpuReg ];
1352+ double value = bit_cast<double , uint64_t >(
1353+ args->fpu_registers [CallingConventions::kReturnFpuReg ]);
13061354 return Double::New (value);
13071355 } else if (rep == kUnboxedFloat ) {
1308- float value = bit_cast<float , uint32_t >(
1309- static_cast <uint32_t >(bit_cast<uint64_t , double >(
1310- args->fpu_registers [CallingConventions::kReturnFpuReg ])));
1356+ float value = bit_cast<float , uint32_t >(static_cast <uint32_t >(
1357+ args->fpu_registers [CallingConventions::kReturnFpuReg ]));
13111358 return Double::New (static_cast <double >(value));
13121359 } else {
13131360 UNREACHABLE ();
0 commit comments