Commit 46952216 authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[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: 's avatarTobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54948}
parent 78c20334
...@@ -63,7 +63,7 @@ type ExtractFixedArrayFlags generates ...@@ -63,7 +63,7 @@ type ExtractFixedArrayFlags generates
type ParameterMode generates 'TNode<Int32T>' constexpr 'ParameterMode'; type ParameterMode generates 'TNode<Int32T>' constexpr 'ParameterMode';
type RootListIndex generates 'TNode<Int32T>' constexpr 'Heap::RootListIndex'; type RootListIndex generates 'TNode<Int32T>' constexpr 'Heap::RootListIndex';
type MessageTemplate constexpr 'MessageTemplate'; type MessageTemplate constexpr 'MessageTemplate::Template';
type HasPropertyLookupMode constexpr 'HasPropertyLookupMode'; type HasPropertyLookupMode constexpr 'HasPropertyLookupMode';
type ToIntegerTruncationMode constexpr 'ToIntegerTruncationMode'; type ToIntegerTruncationMode constexpr 'ToIntegerTruncationMode';
......
...@@ -10,7 +10,7 @@ module typed_array { ...@@ -10,7 +10,7 @@ module typed_array {
extern macro LoadFixedTypedArrayElementAsTagged( extern macro LoadFixedTypedArrayElementAsTagged(
RawPtr, Smi, constexpr ElementsKind, constexpr ParameterMode): Object; RawPtr, Smi, constexpr ElementsKind, constexpr ParameterMode): Object;
extern macro StoreFixedTypedArrayElementFromTagged( extern macro StoreFixedTypedArrayElementFromTagged(
Context, FixedArrayBase, Smi, Object, constexpr ElementsKind, Context, FixedTypedArrayBase, Smi, Object, constexpr ElementsKind,
constexpr ParameterMode); constexpr ParameterMode);
type LoadFn = builtin(Context, JSTypedArray, Smi) => Object; type LoadFn = builtin(Context, JSTypedArray, Smi) => Object;
......
...@@ -1367,11 +1367,6 @@ LocationReference ImplementationVisitor::GetLocationReference( ...@@ -1367,11 +1367,6 @@ LocationReference ImplementationVisitor::GetLocationReference(
declarations()->LookupValue((*result.declarable())->name() + "." + declarations()->LookupValue((*result.declarable())->name() + "." +
expr->field), expr->field),
{}, {}); {}, {});
} else {
return LocationReference(
nullptr,
VisitResult(result.type(), result.RValue() + "." + expr->field), {});
} }
} }
return LocationReference(nullptr, result, {}); return LocationReference(nullptr, result, {});
...@@ -1422,17 +1417,8 @@ VisitResult ImplementationVisitor::GenerateFetchFromLocation( ...@@ -1422,17 +1417,8 @@ VisitResult ImplementationVisitor::GenerateFetchFromLocation(
if (reference.value != nullptr) { if (reference.value != nullptr) {
return GenerateFetchFromLocation(reference); return GenerateFetchFromLocation(reference);
} else if (const StructType* struct_type = StructType::DynamicCast(type)) { } else if (const StructType* struct_type = StructType::DynamicCast(type)) {
auto& fields = struct_type->fields(); return VisitResult(struct_type->GetFieldType(expr->field),
auto i = std::find_if( reference.base.RValue() + "." + expr->field);
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());
} else { } else {
Arguments arguments; Arguments arguments;
arguments.parameters = {reference.base}; arguments.parameters = {reference.base};
...@@ -1488,7 +1474,7 @@ void ImplementationVisitor::GenerateAssignToLocation( ...@@ -1488,7 +1474,7 @@ void ImplementationVisitor::GenerateAssignToLocation(
ReportError(s.str()); ReportError(s.str());
} }
GenerateAssignToVariable(var, assignment_value); GenerateAssignToVariable(var, assignment_value);
} else if (auto access = FieldAccessExpression::cast(location)) { } else if (auto access = FieldAccessExpression::DynamicCast(location)) {
GenerateCall(std::string(".") + access->field + "=", GenerateCall(std::string(".") + access->field + "=",
{{reference.base, assignment_value}, {}}); {{reference.base, assignment_value}, {}});
} else { } else {
......
...@@ -19,8 +19,8 @@ namespace internal { ...@@ -19,8 +19,8 @@ namespace internal {
namespace torque { namespace torque {
struct LocationReference { struct LocationReference {
LocationReference(Value* v, VisitResult b, VisitResult i) LocationReference(Value* value, VisitResult base, VisitResult index)
: value(v), base(b), index(i) {} : value(value), base(base), index(index) {}
Value* value; Value* value;
VisitResult base; VisitResult base;
VisitResult index; VisitResult index;
......
...@@ -270,6 +270,7 @@ std::string VisitResult::LValue() const { ...@@ -270,6 +270,7 @@ std::string VisitResult::LValue() const {
} }
std::string VisitResult::RValue() const { std::string VisitResult::RValue() const {
std::string result;
if (declarable()) { if (declarable()) {
auto value = *declarable(); auto value = *declarable();
if (value->IsVariable() && !Variable::cast(value)->IsDefined()) { if (value->IsVariable() && !Variable::cast(value)->IsDefined()) {
...@@ -277,10 +278,12 @@ std::string VisitResult::RValue() const { ...@@ -277,10 +278,12 @@ std::string VisitResult::RValue() const {
s << "\"" << value->name() << "\" is used before it is defined"; s << "\"" << value->name() << "\" is used before it is defined";
ReportError(s.str()); ReportError(s.str());
} }
return value->RValue(); result = value->RValue();
} else { } else {
return value_; result = value_;
} }
return "implicit_cast<" + type()->GetGeneratedTypeName() + ">(" + result +
")";
} }
} // namespace torque } // namespace torque
......
...@@ -311,6 +311,15 @@ class StructType final : public Type { ...@@ -311,6 +311,15 @@ class StructType final : public Type {
bool IsConstexpr() const override { return false; } bool IsConstexpr() const override { return false; }
const std::vector<NameAndType>& fields() const { return fields_; } 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_; } const std::string& name() const { return name_; }
Module* module() const { return module_; } Module* module() const { return module_; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment