@@ -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