[torque] Simplify handling of VisitResults

Only pass around the unadulterated value identifier in the VisitResult class
until the very last moment before code generation, at which point the
declaration that was used to originally define the value is used to generate the
correct final source code string in the context of a l-value or r-value.

Bug: v8:7793
Change-Id: Ifd0c0d245b2eb65c7f3ddb1ad4c87ee235c54a82
Reviewed-on: https://chromium-review.googlesource.com/1125063
Commit-Queue: Daniel Clifford <danno@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54229}
This commit is contained in:
Daniel Clifford 2018-07-05 07:52:12 +02:00 committed by Commit Bot
parent 887dbc8311
commit 1813e3d572
5 changed files with 74 additions and 65 deletions

View File

@ -84,11 +84,8 @@ class Value : public Declarable {
public: public:
const std::string& name() const { return name_; } const std::string& name() const { return name_; }
virtual bool IsConst() const { return true; } virtual bool IsConst() const { return true; }
virtual std::string GetValueForDeclaration() const = 0; virtual std::string value() const = 0;
virtual std::string GetValueForRead() const { virtual std::string RValue() const { return value(); }
return GetValueForDeclaration();
}
virtual std::string GetValueForWrite() const { UNREACHABLE(); }
DECLARE_DECLARABLE_BOILERPLATE(Value, value); DECLARE_DECLARABLE_BOILERPLATE(Value, value);
const Type* type() const { return type_; } const Type* type() const { return type_; }
@ -104,7 +101,7 @@ class Value : public Declarable {
class Parameter : public Value { class Parameter : public Value {
public: public:
DECLARE_DECLARABLE_BOILERPLATE(Parameter, parameter); DECLARE_DECLARABLE_BOILERPLATE(Parameter, parameter);
std::string GetValueForDeclaration() const override { return var_name_; } std::string value() const override { return var_name_; }
private: private:
friend class Declarations; friend class Declarations;
@ -119,19 +116,14 @@ class Variable : public Value {
public: public:
DECLARE_DECLARABLE_BOILERPLATE(Variable, variable); DECLARE_DECLARABLE_BOILERPLATE(Variable, variable);
bool IsConst() const override { return false; } bool IsConst() const override { return false; }
std::string GetValueForDeclaration() const override { return value_; } std::string value() const override { return value_; }
std::string GetValueForRead() const override { std::string RValue() const override {
if (!IsDefined()) { if (!IsDefined()) {
ReportError("Reading uninitialized variable."); ReportError("Reading uninitialized variable.");
} }
if (type()->IsConstexpr()) { std::string result = "(*" + value() + ")";
return std::string("*") + value_; if (!type()->IsConstexpr()) result += ".value()";
} else { return result;
return value_ + "->value()";
}
}
std::string GetValueForWrite() const override {
return std::string("*") + value_;
} }
void Define() { void Define() {
if (defined_ && type()->IsConstexpr()) { if (defined_ && type()->IsConstexpr()) {
@ -183,7 +175,7 @@ class Label : public Declarable {
class Constant : public Value { class Constant : public Value {
public: public:
DECLARE_DECLARABLE_BOILERPLATE(Constant, constant); DECLARE_DECLARABLE_BOILERPLATE(Constant, constant);
std::string GetValueForDeclaration() const override { return value_; } std::string value() const override { return value_; }
private: private:
friend class Declarations; friend class Declarations;

View File

@ -221,8 +221,9 @@ void ImplementationVisitor::Visit(TorqueMacroDeclaration* decl,
} }
if (result_var != nullptr) { if (result_var != nullptr) {
GenerateIndent(); GenerateIndent();
source_out() << "return " << result_var->GetValueForRead() << ";" source_out() << "return "
<< std::endl; << VisitResult(result_var->type(), result_var).RValue()
<< ";" << std::endl;
} }
source_out() << "}" << std::endl << std::endl; source_out() << "}" << std::endl << std::endl;
} }
@ -241,18 +242,18 @@ void ImplementationVisitor::Visit(TorqueBuiltinDeclaration* decl,
const Value* val = const Value* val =
declarations()->LookupValue(decl->signature->parameters.names[0]); declarations()->LookupValue(decl->signature->parameters.names[0]);
GenerateIndent(); GenerateIndent();
source_out() << "TNode<Context> " << val->GetValueForDeclaration() source_out() << "TNode<Context> " << val->value()
<< " = UncheckedCast<Context>(Parameter(" << " = UncheckedCast<Context>(Parameter("
<< "Descriptor::kContext));" << std::endl; << "Descriptor::kContext));" << std::endl;
GenerateIndent(); GenerateIndent();
source_out() << "USE(" << val->GetValueForDeclaration() << ");" << std::endl; source_out() << "USE(" << val->value() << ");" << std::endl;
size_t first = 1; size_t first = 1;
if (builtin->IsVarArgsJavaScript()) { if (builtin->IsVarArgsJavaScript()) {
assert(decl->signature->parameters.has_varargs); assert(decl->signature->parameters.has_varargs);
Constant* arguments = Constant::cast(declarations()->LookupValue( Constant* arguments = Constant::cast(declarations()->LookupValue(
decl->signature->parameters.arguments_variable)); decl->signature->parameters.arguments_variable));
std::string arguments_name = arguments->GetValueForDeclaration(); std::string arguments_name = arguments->value();
GenerateIndent(); GenerateIndent();
source_out() source_out()
<< "Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);" << "Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);"
@ -264,15 +265,14 @@ void ImplementationVisitor::Visit(TorqueBuiltinDeclaration* decl,
const Value* receiver = const Value* receiver =
declarations()->LookupValue(decl->signature->parameters.names[1]); declarations()->LookupValue(decl->signature->parameters.names[1]);
GenerateIndent(); GenerateIndent();
source_out() << "TNode<Object> " << receiver->GetValueForDeclaration() source_out() << "TNode<Object> " << receiver->value()
<< " = arguments_impl.GetReceiver();" << std::endl; << " = arguments_impl.GetReceiver();" << std::endl;
GenerateIndent(); GenerateIndent();
source_out() << "auto arguments = &arguments_impl;" << std::endl; source_out() << "auto arguments = &arguments_impl;" << std::endl;
GenerateIndent(); GenerateIndent();
source_out() << "USE(arguments);" << std::endl; source_out() << "USE(arguments);" << std::endl;
GenerateIndent(); GenerateIndent();
source_out() << "USE(" << receiver->GetValueForDeclaration() << ");" source_out() << "USE(" << receiver->value() << ");" << std::endl;
<< std::endl;
first = 2; first = 2;
} }
@ -310,7 +310,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
source_out() << "" << std::endl; source_out() << "" << std::endl;
left = Visit(expr->if_true); left = Visit(expr->if_true);
GenerateIndent(); GenerateIndent();
source_out() << "return " << left.variable() << ";" << std::endl; source_out() << "return " << left.RValue() << ";" << std::endl;
} }
source_out() << ";" << std::endl; source_out() << ";" << std::endl;
GenerateIndent(); GenerateIndent();
@ -320,7 +320,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
source_out() << "" << std::endl; source_out() << "" << std::endl;
right = Visit(expr->if_false); right = Visit(expr->if_false);
GenerateIndent(); GenerateIndent();
source_out() << "return " << right.variable() << ";" << std::endl; source_out() << "return " << right.RValue() << ";" << std::endl;
} }
source_out() << ";" << std::endl; source_out() << ";" << std::endl;
@ -359,7 +359,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
GenerateLabelBind(done_label); GenerateLabelBind(done_label);
} }
return VisitResult(common_type, result->GetValueForRead()); return VisitResult(common_type, result);
} }
VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) { VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
@ -372,7 +372,7 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
if (left_result.type()->IsBool()) { if (left_result.type()->IsBool()) {
Label* true_label = declarations()->LookupLabel(kTrueLabelName); Label* true_label = declarations()->LookupLabel(kTrueLabelName);
GenerateIndent(); GenerateIndent();
source_out() << "GotoIf(" << left_result.variable() << ", " source_out() << "GotoIf(" << left_result.RValue() << ", "
<< true_label->generated() << ");" << std::endl; << true_label->generated() << ");" << std::endl;
} else if (!left_result.type()->IsConstexprBool()) { } else if (!left_result.type()->IsConstexprBool()) {
GenerateLabelBind(false_label); GenerateLabelBind(false_label);
@ -388,8 +388,8 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
} }
if (left_result.type()->IsConstexprBool()) { if (left_result.type()->IsConstexprBool()) {
return VisitResult(left_result.type(), std::string("(") + return VisitResult(left_result.type(), std::string("(") +
left_result.variable() + " || " + left_result.RValue() + " || " +
right_result.variable() + ")"); right_result.RValue() + ")");
} else { } else {
return right_result; return right_result;
} }
@ -405,7 +405,7 @@ VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
if (left_result.type()->IsBool()) { if (left_result.type()->IsBool()) {
Label* false_label = declarations()->LookupLabel(kFalseLabelName); Label* false_label = declarations()->LookupLabel(kFalseLabelName);
GenerateIndent(); GenerateIndent();
source_out() << "GotoIfNot(" << left_result.variable() << ", " source_out() << "GotoIfNot(" << left_result.RValue() << ", "
<< false_label->generated() << ");" << std::endl; << false_label->generated() << ");" << std::endl;
} else if (!left_result.type()->IsConstexprBool()) { } else if (!left_result.type()->IsConstexprBool()) {
GenerateLabelBind(true_label); GenerateLabelBind(true_label);
@ -421,8 +421,8 @@ VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
} }
if (left_result.type()->IsConstexprBool()) { if (left_result.type()->IsConstexprBool()) {
return VisitResult(left_result.type(), std::string("(") + return VisitResult(left_result.type(), std::string("(") +
left_result.variable() + " && " + left_result.RValue() + " && " +
right_result.variable() + ")"); right_result.RValue() + ")");
} else { } else {
return right_result; return right_result;
} }
@ -566,7 +566,7 @@ const Type* ImplementationVisitor::Visit(IfStatement* stmt) {
const Type* right_result = TypeOracle::GetVoidType(); const Type* right_result = TypeOracle::GetVoidType();
{ {
GenerateIndent(); GenerateIndent();
source_out() << "if ((" << expression_result.variable() << ")) "; source_out() << "if ((" << expression_result.RValue() << ")) ";
ScopedIndent indent(this, false); ScopedIndent indent(this, false);
source_out() << std::endl; source_out() << std::endl;
left_result = Visit(stmt->if_true); left_result = Visit(stmt->if_true);
@ -782,11 +782,11 @@ const Type* ImplementationVisitor::Visit(ReturnStatement* stmt) {
} else if (current_callable->IsBuiltin()) { } else if (current_callable->IsBuiltin()) {
if (Builtin::cast(current_callable)->IsVarArgsJavaScript()) { if (Builtin::cast(current_callable)->IsVarArgsJavaScript()) {
GenerateIndent(); GenerateIndent();
source_out() << "arguments->PopAndReturn(" << return_result.variable() source_out() << "arguments->PopAndReturn(" << return_result.RValue()
<< ");" << std::endl; << ");" << std::endl;
} else { } else {
GenerateIndent(); GenerateIndent();
source_out() << "Return(" << return_result.variable() << ");" source_out() << "Return(" << return_result.RValue() << ");"
<< std::endl; << std::endl;
} }
} else { } else {
@ -829,8 +829,7 @@ const Type* ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
stmt, std::string(kForIndexValueVariable) + "_" + NewTempVariable(), stmt, std::string(kForIndexValueVariable) + "_" + NewTempVariable(),
common_type, begin); common_type, begin);
VisitResult index_for_read = {index_var->type(), VisitResult index_for_read = {index_var->type(), index_var};
index_var->GetValueForRead()};
Label* header_label = declarations()->DeclarePrivateLabel("header"); Label* header_label = declarations()->DeclarePrivateLabel("header");
GenerateLabelDefinition(header_label, stmt); GenerateLabelDefinition(header_label, stmt);
@ -1058,7 +1057,7 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
const Type* parameter_type = *type_iterator; const Type* parameter_type = *type_iterator;
const std::string& generated_type_name = const std::string& generated_type_name =
parameter_type->GetGeneratedTypeName(); parameter_type->GetGeneratedTypeName();
o << generated_type_name << " " << parameter->GetValueForDeclaration(); o << generated_type_name << " " << parameter->value();
type_iterator++; type_iterator++;
first = false; first = false;
} }
@ -1074,7 +1073,7 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
generated_type_name += var->type()->GetGeneratedTNodeTypeName(); generated_type_name += var->type()->GetGeneratedTNodeTypeName();
generated_type_name += ">*"; generated_type_name += ">*";
o << ", "; o << ", ";
o << generated_type_name << " " << var->GetValueForDeclaration(); o << generated_type_name << " " << var->value();
} }
} }
@ -1203,7 +1202,7 @@ void ImplementationVisitor::GenerateChangedVarsFromControlSplit(AstNode* node) {
} else { } else {
source_out() << ", "; source_out() << ", ";
} }
source_out() << v->GetValueForDeclaration(); source_out() << v->value();
} }
source_out() << "}"; source_out() << "}";
} }
@ -1224,7 +1223,7 @@ const Type* ImplementationVisitor::GetCommonType(const Type* left,
VisitResult ImplementationVisitor::GenerateCopy(const VisitResult& to_copy) { VisitResult ImplementationVisitor::GenerateCopy(const VisitResult& to_copy) {
std::string temp = GenerateNewTempVariable(to_copy.type()); std::string temp = GenerateNewTempVariable(to_copy.type());
source_out() << to_copy.variable() << ";" << std::endl; source_out() << to_copy.RValue() << ";" << std::endl;
GenerateIndent(); GenerateIndent();
source_out() << "USE(" << temp << ");" << std::endl; source_out() << "USE(" << temp << ");" << std::endl;
return VisitResult(to_copy.type(), temp); return VisitResult(to_copy.type(), temp);
@ -1267,7 +1266,8 @@ void ImplementationVisitor::GenerateAssignToVariable(Variable* var,
VisitResult value) { VisitResult value) {
VisitResult casted_value = GenerateImplicitConvert(var->type(), value); VisitResult casted_value = GenerateImplicitConvert(var->type(), value);
GenerateIndent(); GenerateIndent();
source_out() << var->GetValueForWrite() << " = " << casted_value.variable() VisitResult variable_result = {var->type(), var};
source_out() << variable_result.LValue() << " = " << casted_value.RValue()
<< ";\n"; << ";\n";
var->Define(); var->Define();
} }
@ -1317,20 +1317,17 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
GenerateIndent(); GenerateIndent();
if (variable->type()->IsConstexpr()) { if (variable->type()->IsConstexpr()) {
source_out() << variable->type()->GetGeneratedTypeName(); source_out() << variable->type()->GetGeneratedTypeName();
source_out() << " " << variable->GetValueForDeclaration() << "_impl;" source_out() << " " << variable->value() << "_impl;" << std::endl;
<< std::endl;
} else { } else {
source_out() << "TVARIABLE("; source_out() << "TVARIABLE(";
source_out() << variable->type()->GetGeneratedTNodeTypeName(); source_out() << variable->type()->GetGeneratedTNodeTypeName();
source_out() << ", " << variable->GetValueForDeclaration() << "_impl);" source_out() << ", " << variable->value() << "_impl);" << std::endl;
<< std::endl;
} }
GenerateIndent(); GenerateIndent();
source_out() << "auto " << variable->GetValueForDeclaration() << " = &" source_out() << "auto " << variable->value() << " = &" << variable->value()
<< variable->GetValueForDeclaration() << "_impl;" << std::endl; << "_impl;" << std::endl;
GenerateIndent(); GenerateIndent();
source_out() << "USE(" << variable->GetValueForDeclaration() << ");" source_out() << "USE(" << variable->value() << ");" << std::endl;
<< std::endl;
if (initialization) { if (initialization) {
GenerateAssignToVariable(variable, *initialization); GenerateAssignToVariable(variable, *initialization);
} }
@ -1340,7 +1337,7 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
void ImplementationVisitor::GenerateParameter( void ImplementationVisitor::GenerateParameter(
const std::string& parameter_name) { const std::string& parameter_name) {
const Value* val = declarations()->LookupValue(parameter_name); const Value* val = declarations()->LookupValue(parameter_name);
std::string var = val->GetValueForDeclaration(); std::string var = val->value();
GenerateIndent(); GenerateIndent();
source_out() << val->type()->GetGeneratedTypeName() << " " << var << " = "; source_out() << val->type()->GetGeneratedTypeName() << " " << var << " = ";
@ -1400,7 +1397,7 @@ VisitResult ImplementationVisitor::GeneratePointerCall(
const Type* to_type = type->parameter_types()[current]; const Type* to_type = type->parameter_types()[current];
VisitResult result = VisitResult result =
GenerateImplicitConvert(to_type, arguments.parameters[current]); GenerateImplicitConvert(to_type, arguments.parameters[current]);
variables.push_back(result.variable()); variables.push_back(result.RValue());
} }
std::string result_variable_name; std::string result_variable_name;
@ -1429,7 +1426,7 @@ VisitResult ImplementationVisitor::GeneratePointerCall(
} }
source_out() << "Builtins::CallableFor(isolate(), Builtins::k" source_out() << "Builtins::CallableFor(isolate(), Builtins::k"
<< example_builtin->name() << ").descriptor(), " << example_builtin->name() << ").descriptor(), "
<< callee_result.variable() << ", "; << callee_result.RValue() << ", ";
size_t total_parameters = 0; size_t total_parameters = 0;
for (size_t i = 0; i < arguments.parameters.size(); ++i) { for (size_t i = 0; i < arguments.parameters.size(); ++i) {
@ -1468,7 +1465,7 @@ VisitResult ImplementationVisitor::GenerateCall(
: callable->signature().types()[current]; : callable->signature().types()[current];
VisitResult result = VisitResult result =
GenerateImplicitConvert(to_type, arguments.parameters[current]); GenerateImplicitConvert(to_type, arguments.parameters[current]);
variables.push_back(result.variable()); variables.push_back(result.RValue());
} }
std::string result_variable_name; std::string result_variable_name;
@ -1552,7 +1549,7 @@ VisitResult ImplementationVisitor::GenerateCall(
ReportError(s.str()); ReportError(s.str());
} }
j++; j++;
source_out() << variable->GetValueForDeclaration(); source_out() << variable->value();
} }
label->MarkUsed(); label->MarkUsed();
} }
@ -1632,7 +1629,7 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
} }
if (!result.type()->IsVoidOrNever()) { if (!result.type()->IsVoidOrNever()) {
GenerateIndent(); GenerateIndent();
source_out() << "USE(" << result.variable() << ");" << std::endl; source_out() << "USE(" << result.RValue() << ");" << std::endl;
} }
if (is_tailcall) { if (is_tailcall) {
result = {TypeOracle::GetNeverType(), ""}; result = {TypeOracle::GetNeverType(), ""};
@ -1664,7 +1661,7 @@ void ImplementationVisitor::GenerateBranch(const VisitResult& condition,
Label* true_label, Label* true_label,
Label* false_label) { Label* false_label) {
GenerateIndent(); GenerateIndent();
source_out() << "Branch(" << condition.variable() << ", " source_out() << "Branch(" << condition.RValue() << ", "
<< true_label->generated() << ", " << false_label->generated() << true_label->generated() << ", " << false_label->generated()
<< ");" << std::endl; << ");" << std::endl;
} }
@ -1703,7 +1700,11 @@ VisitResult ImplementationVisitor::GenerateImplicitConvert(
GetGeneratedCallableName(kFromConstexprMacroName, {destination_type}); GetGeneratedCallableName(kFromConstexprMacroName, {destination_type});
return GenerateCall(name, {{source}, {}}, false); return GenerateCall(name, {{source}, {}}, false);
} else if (IsAssignableFrom(destination_type, source.type())) { } else if (IsAssignableFrom(destination_type, source.type())) {
return VisitResult(destination_type, source.variable()); if (source.declarable()) {
return VisitResult(destination_type, *source.declarable());
} else {
return VisitResult(destination_type, source.value());
}
} else { } else {
std::stringstream s; std::stringstream s;
s << "cannot use expression of type " << *source.type() s << "cannot use expression of type " << *source.type()

View File

@ -58,7 +58,7 @@ class ImplementationVisitor : public FileVisitor {
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 VisitResult({value->type(), value->GetValueForRead()}); return VisitResult(value->type(), value);
} }
VisitResult GenerateFetchFromLocation(FieldAccessExpression* expr, VisitResult GenerateFetchFromLocation(FieldAccessExpression* expr,
LocationReference reference) { LocationReference reference) {

View File

@ -248,6 +248,15 @@ bool operator<(const Type& a, const Type& b) {
return a.MangledName() < b.MangledName(); return a.MangledName() < b.MangledName();
} }
VisitResult::VisitResult(const Type* type, const Value* declarable)
: type_(type), value_(declarable->value()), declarable_(declarable) {}
std::string VisitResult::LValue() const { return std::string("*") + value_; }
std::string VisitResult::RValue() const {
return (declarable_) ? (*declarable_)->RValue() : value_;
}
} // namespace torque } // namespace torque
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8

View File

@ -33,6 +33,7 @@ static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64"; static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
class Label; class Label;
class Value;
class TypeBase { class TypeBase {
public: public:
@ -292,14 +293,20 @@ inline std::ostream& operator<<(std::ostream& os, const Type& t) {
class VisitResult { class VisitResult {
public: public:
VisitResult() {} VisitResult() {}
VisitResult(const Type* type, const std::string& variable) VisitResult(const Type* type, const std::string& value)
: type_(type), variable_(variable) {} : type_(type), value_(value), declarable_{} {}
VisitResult(const Type* type, const Value* declarable);
const Type* type() const { return type_; } const Type* type() const { return type_; }
const std::string& variable() const { return variable_; } // const std::string& variable() const { return variable_; }
base::Optional<const Value*> declarable() const { return declarable_; }
std::string value() const { return value_; }
std::string LValue() const;
std::string RValue() const;
private: private:
const Type* type_; const Type* type_;
std::string variable_; std::string value_;
base::Optional<const Value*> declarable_;
}; };
class VisitResultVector : public std::vector<VisitResult> { class VisitResultVector : public std::vector<VisitResult> {