Skip to content

Commit b6d110e

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm,dyn_modules] Fix handling of int and double parameters in FFI calls
TEST=ci Change-Id: Ie44ceb491122be85d9a5731be2c7571b0126dcd7 Cq-Include-Trybots: luci.dart.try:vm-dyn-linux-debug-x64-try,vm-dyn-mac-debug-arm64-try,vm-ffi-dyn-mac-debug-simarm64_arm64-try,vm-ffi-dyn-mac-release-simarm64_arm64-try,vm-aot-dyn-linux-debug-x64-try,vm-aot-dyn-linux-product-x64-try Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/447840 Reviewed-by: Ryan Macnak <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent db352c0 commit b6d110e

File tree

1 file changed

+54
-7
lines changed

1 file changed

+54
-7
lines changed

runtime/vm/runtime_entry.cc

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,36 @@ extern "C" void FfiCallTrampoline(FfiCallArguments* args);
12081208
extern "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+
12111241
static 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

Comments
 (0)