[fuzzer] Add the numeric conversion logic in ConsumeAndGenerate

Add the numeric conversion logic in ConsumeAndGenerate function.

Bug: v8:11954
Change-Id: I24a97dade0485315d21f280a6b99a4d5377f09f7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3260509
Commit-Queue: Maria Tîmbur <mtimbur@google.com>
Reviewed-by: Thibaud Michaud <thibaudm@chromium.org>
Reviewed-by: Manos Koukoutos <manoskouk@chromium.org>
Cr-Commit-Position: refs/heads/main@{#77942}
This commit is contained in:
Maria Tîmbur 2021-11-17 10:51:24 +00:00 committed by V8 LUCI CQ
parent f6edda0987
commit a533662e79

View File

@ -2267,14 +2267,59 @@ void WasmGenerator::Generate(base::Vector<const ValueType> types,
}
// Emit code to match an arbitrary signature.
// TODO(manoskouk): Do something which uses inputs instead of dropping them.
// Possibly generate function a function with the correct sig on the fly? Or
// generalize the {Convert} function.
// TODO(11954): Add the missing reference type conversion/upcasting.
void WasmGenerator::ConsumeAndGenerate(
base::Vector<const ValueType> param_types,
base::Vector<const ValueType> return_types, DataRange* data) {
for (unsigned i = 0; i < param_types.size(); i++) builder_->Emit(kExprDrop);
Generate(return_types, data);
// This numeric conversion logic consists of picking exactly one
// index in the return values and dropping all the values that come
// before that index. Then we convert the value from that index to the
// wanted type. If we don't find any value we generate it.
auto primitive = [](ValueType t) -> bool {
switch (t.kind()) {
case kI32:
case kI64:
case kF32:
case kF64:
return true;
default:
return false;
}
};
if (return_types.size() == 0 || param_types.size() == 0 ||
!primitive(return_types[0])) {
for (unsigned i = 0; i < param_types.size(); i++) {
builder_->Emit(kExprDrop);
}
Generate(return_types, data);
return;
}
int bottom_primitives = 0;
while (static_cast<int>(param_types.size()) > bottom_primitives &&
primitive(param_types[bottom_primitives])) {
bottom_primitives++;
}
int return_index =
bottom_primitives > 0 ? (data->get<uint8_t>() % bottom_primitives) : -1;
for (int i = static_cast<int>(param_types.size() - 1); i > return_index;
--i) {
builder_->Emit(kExprDrop);
}
for (int i = return_index; i > 0; --i) {
Convert(param_types[i], param_types[i - 1]);
builder_->EmitI32Const(0);
builder_->Emit(kExprSelect);
}
DCHECK(!return_types.empty());
if (return_index >= 0) {
Convert(param_types[0], return_types[0]);
Generate(return_types + 1, data);
} else {
Generate(return_types, data);
}
}
enum SigKind { kFunctionSig, kExceptionSig };