[torque] generate implicit_cast according to VisitResult types
In the generated CSA, we called overloaded macros while relying on CSA subtyping of TNodes. This doesn't work well with overloads, because for C++ any TNode subtyping is treated as an implicit conversion, which makes these calls ambiguous for C++. As a solution, we insert implicit_cast conversions for arguments according to the type predicted by Torque. This way, a CSA overload is always called with exactly the signature declared in base.tq. This has the additional benefit that it validates the signatures declared in base.tq, which could previously be too permissive. Also, this triggered a bug in structs, where VisitResult's were carrying the wrong type. Bug: v8:7793 TBR: danno@chromium.org Change-Id: I8ed4bfd04793c8a8805a4a3dd5cf2a85c20ce786 Reviewed-on: https://chromium-review.googlesource.com/1165237 Commit-Queue: Tobias Tebbi <tebbi@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#54948}
This commit is contained in:
parent
78c20334a4
commit
469522160b
@ -63,7 +63,7 @@ type ExtractFixedArrayFlags generates
|
||||
type ParameterMode generates 'TNode<Int32T>' constexpr 'ParameterMode';
|
||||
type RootListIndex generates 'TNode<Int32T>' constexpr 'Heap::RootListIndex';
|
||||
|
||||
type MessageTemplate constexpr 'MessageTemplate';
|
||||
type MessageTemplate constexpr 'MessageTemplate::Template';
|
||||
type HasPropertyLookupMode constexpr 'HasPropertyLookupMode';
|
||||
|
||||
type ToIntegerTruncationMode constexpr 'ToIntegerTruncationMode';
|
||||
|
@ -10,7 +10,7 @@ module typed_array {
|
||||
extern macro LoadFixedTypedArrayElementAsTagged(
|
||||
RawPtr, Smi, constexpr ElementsKind, constexpr ParameterMode): Object;
|
||||
extern macro StoreFixedTypedArrayElementFromTagged(
|
||||
Context, FixedArrayBase, Smi, Object, constexpr ElementsKind,
|
||||
Context, FixedTypedArrayBase, Smi, Object, constexpr ElementsKind,
|
||||
constexpr ParameterMode);
|
||||
|
||||
type LoadFn = builtin(Context, JSTypedArray, Smi) => Object;
|
||||
|
@ -1367,11 +1367,6 @@ LocationReference ImplementationVisitor::GetLocationReference(
|
||||
declarations()->LookupValue((*result.declarable())->name() + "." +
|
||||
expr->field),
|
||||
{}, {});
|
||||
|
||||
} else {
|
||||
return LocationReference(
|
||||
nullptr,
|
||||
VisitResult(result.type(), result.RValue() + "." + expr->field), {});
|
||||
}
|
||||
}
|
||||
return LocationReference(nullptr, result, {});
|
||||
@ -1422,17 +1417,8 @@ VisitResult ImplementationVisitor::GenerateFetchFromLocation(
|
||||
if (reference.value != nullptr) {
|
||||
return GenerateFetchFromLocation(reference);
|
||||
} else if (const StructType* struct_type = StructType::DynamicCast(type)) {
|
||||
auto& fields = struct_type->fields();
|
||||
auto i = std::find_if(
|
||||
fields.begin(), fields.end(),
|
||||
[&](const NameAndType& f) { return f.name == expr->field; });
|
||||
if (i == fields.end()) {
|
||||
std::stringstream s;
|
||||
s << "\"" << expr->field << "\" is not a field of struct type \""
|
||||
<< struct_type->name() << "\"";
|
||||
ReportError(s.str());
|
||||
}
|
||||
return VisitResult(i->type, reference.base.RValue());
|
||||
return VisitResult(struct_type->GetFieldType(expr->field),
|
||||
reference.base.RValue() + "." + expr->field);
|
||||
} else {
|
||||
Arguments arguments;
|
||||
arguments.parameters = {reference.base};
|
||||
@ -1488,7 +1474,7 @@ void ImplementationVisitor::GenerateAssignToLocation(
|
||||
ReportError(s.str());
|
||||
}
|
||||
GenerateAssignToVariable(var, assignment_value);
|
||||
} else if (auto access = FieldAccessExpression::cast(location)) {
|
||||
} else if (auto access = FieldAccessExpression::DynamicCast(location)) {
|
||||
GenerateCall(std::string(".") + access->field + "=",
|
||||
{{reference.base, assignment_value}, {}});
|
||||
} else {
|
||||
|
@ -19,8 +19,8 @@ namespace internal {
|
||||
namespace torque {
|
||||
|
||||
struct LocationReference {
|
||||
LocationReference(Value* v, VisitResult b, VisitResult i)
|
||||
: value(v), base(b), index(i) {}
|
||||
LocationReference(Value* value, VisitResult base, VisitResult index)
|
||||
: value(value), base(base), index(index) {}
|
||||
Value* value;
|
||||
VisitResult base;
|
||||
VisitResult index;
|
||||
|
@ -270,6 +270,7 @@ std::string VisitResult::LValue() const {
|
||||
}
|
||||
|
||||
std::string VisitResult::RValue() const {
|
||||
std::string result;
|
||||
if (declarable()) {
|
||||
auto value = *declarable();
|
||||
if (value->IsVariable() && !Variable::cast(value)->IsDefined()) {
|
||||
@ -277,10 +278,12 @@ std::string VisitResult::RValue() const {
|
||||
s << "\"" << value->name() << "\" is used before it is defined";
|
||||
ReportError(s.str());
|
||||
}
|
||||
return value->RValue();
|
||||
result = value->RValue();
|
||||
} else {
|
||||
return value_;
|
||||
result = value_;
|
||||
}
|
||||
return "implicit_cast<" + type()->GetGeneratedTypeName() + ">(" + result +
|
||||
")";
|
||||
}
|
||||
|
||||
} // namespace torque
|
||||
|
@ -311,6 +311,15 @@ class StructType final : public Type {
|
||||
bool IsConstexpr() const override { return false; }
|
||||
|
||||
const std::vector<NameAndType>& fields() const { return fields_; }
|
||||
const Type* GetFieldType(const std::string& fieldname) const {
|
||||
for (const NameAndType& field : fields()) {
|
||||
if (field.name == fieldname) return field.type;
|
||||
}
|
||||
std::stringstream s;
|
||||
s << "\"" << fieldname << "\" is not a field of struct type \"" << name()
|
||||
<< "\"";
|
||||
ReportError(s.str());
|
||||
}
|
||||
const std::string& name() const { return name_; }
|
||||
Module* module() const { return module_; }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user