[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:
parent
887dbc8311
commit
1813e3d572
@ -84,11 +84,8 @@ class Value : public Declarable {
|
||||
public:
|
||||
const std::string& name() const { return name_; }
|
||||
virtual bool IsConst() const { return true; }
|
||||
virtual std::string GetValueForDeclaration() const = 0;
|
||||
virtual std::string GetValueForRead() const {
|
||||
return GetValueForDeclaration();
|
||||
}
|
||||
virtual std::string GetValueForWrite() const { UNREACHABLE(); }
|
||||
virtual std::string value() const = 0;
|
||||
virtual std::string RValue() const { return value(); }
|
||||
DECLARE_DECLARABLE_BOILERPLATE(Value, value);
|
||||
const Type* type() const { return type_; }
|
||||
|
||||
@ -104,7 +101,7 @@ class Value : public Declarable {
|
||||
class Parameter : public Value {
|
||||
public:
|
||||
DECLARE_DECLARABLE_BOILERPLATE(Parameter, parameter);
|
||||
std::string GetValueForDeclaration() const override { return var_name_; }
|
||||
std::string value() const override { return var_name_; }
|
||||
|
||||
private:
|
||||
friend class Declarations;
|
||||
@ -119,19 +116,14 @@ class Variable : public Value {
|
||||
public:
|
||||
DECLARE_DECLARABLE_BOILERPLATE(Variable, variable);
|
||||
bool IsConst() const override { return false; }
|
||||
std::string GetValueForDeclaration() const override { return value_; }
|
||||
std::string GetValueForRead() const override {
|
||||
std::string value() const override { return value_; }
|
||||
std::string RValue() const override {
|
||||
if (!IsDefined()) {
|
||||
ReportError("Reading uninitialized variable.");
|
||||
}
|
||||
if (type()->IsConstexpr()) {
|
||||
return std::string("*") + value_;
|
||||
} else {
|
||||
return value_ + "->value()";
|
||||
}
|
||||
}
|
||||
std::string GetValueForWrite() const override {
|
||||
return std::string("*") + value_;
|
||||
std::string result = "(*" + value() + ")";
|
||||
if (!type()->IsConstexpr()) result += ".value()";
|
||||
return result;
|
||||
}
|
||||
void Define() {
|
||||
if (defined_ && type()->IsConstexpr()) {
|
||||
@ -183,7 +175,7 @@ class Label : public Declarable {
|
||||
class Constant : public Value {
|
||||
public:
|
||||
DECLARE_DECLARABLE_BOILERPLATE(Constant, constant);
|
||||
std::string GetValueForDeclaration() const override { return value_; }
|
||||
std::string value() const override { return value_; }
|
||||
|
||||
private:
|
||||
friend class Declarations;
|
||||
|
@ -221,8 +221,9 @@ void ImplementationVisitor::Visit(TorqueMacroDeclaration* decl,
|
||||
}
|
||||
if (result_var != nullptr) {
|
||||
GenerateIndent();
|
||||
source_out() << "return " << result_var->GetValueForRead() << ";"
|
||||
<< std::endl;
|
||||
source_out() << "return "
|
||||
<< VisitResult(result_var->type(), result_var).RValue()
|
||||
<< ";" << std::endl;
|
||||
}
|
||||
source_out() << "}" << std::endl << std::endl;
|
||||
}
|
||||
@ -241,18 +242,18 @@ void ImplementationVisitor::Visit(TorqueBuiltinDeclaration* decl,
|
||||
const Value* val =
|
||||
declarations()->LookupValue(decl->signature->parameters.names[0]);
|
||||
GenerateIndent();
|
||||
source_out() << "TNode<Context> " << val->GetValueForDeclaration()
|
||||
source_out() << "TNode<Context> " << val->value()
|
||||
<< " = UncheckedCast<Context>(Parameter("
|
||||
<< "Descriptor::kContext));" << std::endl;
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << val->GetValueForDeclaration() << ");" << std::endl;
|
||||
source_out() << "USE(" << val->value() << ");" << std::endl;
|
||||
|
||||
size_t first = 1;
|
||||
if (builtin->IsVarArgsJavaScript()) {
|
||||
assert(decl->signature->parameters.has_varargs);
|
||||
Constant* arguments = Constant::cast(declarations()->LookupValue(
|
||||
decl->signature->parameters.arguments_variable));
|
||||
std::string arguments_name = arguments->GetValueForDeclaration();
|
||||
std::string arguments_name = arguments->value();
|
||||
GenerateIndent();
|
||||
source_out()
|
||||
<< "Node* argc = Parameter(Descriptor::kJSActualArgumentsCount);"
|
||||
@ -264,15 +265,14 @@ void ImplementationVisitor::Visit(TorqueBuiltinDeclaration* decl,
|
||||
const Value* receiver =
|
||||
declarations()->LookupValue(decl->signature->parameters.names[1]);
|
||||
GenerateIndent();
|
||||
source_out() << "TNode<Object> " << receiver->GetValueForDeclaration()
|
||||
source_out() << "TNode<Object> " << receiver->value()
|
||||
<< " = arguments_impl.GetReceiver();" << std::endl;
|
||||
GenerateIndent();
|
||||
source_out() << "auto arguments = &arguments_impl;" << std::endl;
|
||||
GenerateIndent();
|
||||
source_out() << "USE(arguments);" << std::endl;
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << receiver->GetValueForDeclaration() << ");"
|
||||
<< std::endl;
|
||||
source_out() << "USE(" << receiver->value() << ");" << std::endl;
|
||||
first = 2;
|
||||
}
|
||||
|
||||
@ -310,7 +310,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
|
||||
source_out() << "" << std::endl;
|
||||
left = Visit(expr->if_true);
|
||||
GenerateIndent();
|
||||
source_out() << "return " << left.variable() << ";" << std::endl;
|
||||
source_out() << "return " << left.RValue() << ";" << std::endl;
|
||||
}
|
||||
source_out() << ";" << std::endl;
|
||||
GenerateIndent();
|
||||
@ -320,7 +320,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
|
||||
source_out() << "" << std::endl;
|
||||
right = Visit(expr->if_false);
|
||||
GenerateIndent();
|
||||
source_out() << "return " << right.variable() << ";" << std::endl;
|
||||
source_out() << "return " << right.RValue() << ";" << std::endl;
|
||||
}
|
||||
source_out() << ";" << std::endl;
|
||||
|
||||
@ -359,7 +359,7 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
|
||||
|
||||
GenerateLabelBind(done_label);
|
||||
}
|
||||
return VisitResult(common_type, result->GetValueForRead());
|
||||
return VisitResult(common_type, result);
|
||||
}
|
||||
|
||||
VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
||||
@ -372,7 +372,7 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
||||
if (left_result.type()->IsBool()) {
|
||||
Label* true_label = declarations()->LookupLabel(kTrueLabelName);
|
||||
GenerateIndent();
|
||||
source_out() << "GotoIf(" << left_result.variable() << ", "
|
||||
source_out() << "GotoIf(" << left_result.RValue() << ", "
|
||||
<< true_label->generated() << ");" << std::endl;
|
||||
} else if (!left_result.type()->IsConstexprBool()) {
|
||||
GenerateLabelBind(false_label);
|
||||
@ -388,8 +388,8 @@ VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
||||
}
|
||||
if (left_result.type()->IsConstexprBool()) {
|
||||
return VisitResult(left_result.type(), std::string("(") +
|
||||
left_result.variable() + " || " +
|
||||
right_result.variable() + ")");
|
||||
left_result.RValue() + " || " +
|
||||
right_result.RValue() + ")");
|
||||
} else {
|
||||
return right_result;
|
||||
}
|
||||
@ -405,7 +405,7 @@ VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
|
||||
if (left_result.type()->IsBool()) {
|
||||
Label* false_label = declarations()->LookupLabel(kFalseLabelName);
|
||||
GenerateIndent();
|
||||
source_out() << "GotoIfNot(" << left_result.variable() << ", "
|
||||
source_out() << "GotoIfNot(" << left_result.RValue() << ", "
|
||||
<< false_label->generated() << ");" << std::endl;
|
||||
} else if (!left_result.type()->IsConstexprBool()) {
|
||||
GenerateLabelBind(true_label);
|
||||
@ -421,8 +421,8 @@ VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
|
||||
}
|
||||
if (left_result.type()->IsConstexprBool()) {
|
||||
return VisitResult(left_result.type(), std::string("(") +
|
||||
left_result.variable() + " && " +
|
||||
right_result.variable() + ")");
|
||||
left_result.RValue() + " && " +
|
||||
right_result.RValue() + ")");
|
||||
} else {
|
||||
return right_result;
|
||||
}
|
||||
@ -566,7 +566,7 @@ const Type* ImplementationVisitor::Visit(IfStatement* stmt) {
|
||||
const Type* right_result = TypeOracle::GetVoidType();
|
||||
{
|
||||
GenerateIndent();
|
||||
source_out() << "if ((" << expression_result.variable() << ")) ";
|
||||
source_out() << "if ((" << expression_result.RValue() << ")) ";
|
||||
ScopedIndent indent(this, false);
|
||||
source_out() << std::endl;
|
||||
left_result = Visit(stmt->if_true);
|
||||
@ -782,11 +782,11 @@ const Type* ImplementationVisitor::Visit(ReturnStatement* stmt) {
|
||||
} else if (current_callable->IsBuiltin()) {
|
||||
if (Builtin::cast(current_callable)->IsVarArgsJavaScript()) {
|
||||
GenerateIndent();
|
||||
source_out() << "arguments->PopAndReturn(" << return_result.variable()
|
||||
source_out() << "arguments->PopAndReturn(" << return_result.RValue()
|
||||
<< ");" << std::endl;
|
||||
} else {
|
||||
GenerateIndent();
|
||||
source_out() << "Return(" << return_result.variable() << ");"
|
||||
source_out() << "Return(" << return_result.RValue() << ");"
|
||||
<< std::endl;
|
||||
}
|
||||
} else {
|
||||
@ -829,8 +829,7 @@ const Type* ImplementationVisitor::Visit(ForOfLoopStatement* stmt) {
|
||||
stmt, std::string(kForIndexValueVariable) + "_" + NewTempVariable(),
|
||||
common_type, begin);
|
||||
|
||||
VisitResult index_for_read = {index_var->type(),
|
||||
index_var->GetValueForRead()};
|
||||
VisitResult index_for_read = {index_var->type(), index_var};
|
||||
|
||||
Label* header_label = declarations()->DeclarePrivateLabel("header");
|
||||
GenerateLabelDefinition(header_label, stmt);
|
||||
@ -1058,7 +1057,7 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
|
||||
const Type* parameter_type = *type_iterator;
|
||||
const std::string& generated_type_name =
|
||||
parameter_type->GetGeneratedTypeName();
|
||||
o << generated_type_name << " " << parameter->GetValueForDeclaration();
|
||||
o << generated_type_name << " " << parameter->value();
|
||||
type_iterator++;
|
||||
first = false;
|
||||
}
|
||||
@ -1074,7 +1073,7 @@ void ImplementationVisitor::GenerateMacroFunctionDeclaration(
|
||||
generated_type_name += var->type()->GetGeneratedTNodeTypeName();
|
||||
generated_type_name += ">*";
|
||||
o << ", ";
|
||||
o << generated_type_name << " " << var->GetValueForDeclaration();
|
||||
o << generated_type_name << " " << var->value();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1203,7 +1202,7 @@ void ImplementationVisitor::GenerateChangedVarsFromControlSplit(AstNode* node) {
|
||||
} else {
|
||||
source_out() << ", ";
|
||||
}
|
||||
source_out() << v->GetValueForDeclaration();
|
||||
source_out() << v->value();
|
||||
}
|
||||
source_out() << "}";
|
||||
}
|
||||
@ -1224,7 +1223,7 @@ const Type* ImplementationVisitor::GetCommonType(const Type* left,
|
||||
|
||||
VisitResult ImplementationVisitor::GenerateCopy(const VisitResult& to_copy) {
|
||||
std::string temp = GenerateNewTempVariable(to_copy.type());
|
||||
source_out() << to_copy.variable() << ";" << std::endl;
|
||||
source_out() << to_copy.RValue() << ";" << std::endl;
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << temp << ");" << std::endl;
|
||||
return VisitResult(to_copy.type(), temp);
|
||||
@ -1267,7 +1266,8 @@ void ImplementationVisitor::GenerateAssignToVariable(Variable* var,
|
||||
VisitResult value) {
|
||||
VisitResult casted_value = GenerateImplicitConvert(var->type(), value);
|
||||
GenerateIndent();
|
||||
source_out() << var->GetValueForWrite() << " = " << casted_value.variable()
|
||||
VisitResult variable_result = {var->type(), var};
|
||||
source_out() << variable_result.LValue() << " = " << casted_value.RValue()
|
||||
<< ";\n";
|
||||
var->Define();
|
||||
}
|
||||
@ -1317,20 +1317,17 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
|
||||
GenerateIndent();
|
||||
if (variable->type()->IsConstexpr()) {
|
||||
source_out() << variable->type()->GetGeneratedTypeName();
|
||||
source_out() << " " << variable->GetValueForDeclaration() << "_impl;"
|
||||
<< std::endl;
|
||||
source_out() << " " << variable->value() << "_impl;" << std::endl;
|
||||
} else {
|
||||
source_out() << "TVARIABLE(";
|
||||
source_out() << variable->type()->GetGeneratedTNodeTypeName();
|
||||
source_out() << ", " << variable->GetValueForDeclaration() << "_impl);"
|
||||
<< std::endl;
|
||||
source_out() << ", " << variable->value() << "_impl);" << std::endl;
|
||||
}
|
||||
GenerateIndent();
|
||||
source_out() << "auto " << variable->GetValueForDeclaration() << " = &"
|
||||
<< variable->GetValueForDeclaration() << "_impl;" << std::endl;
|
||||
source_out() << "auto " << variable->value() << " = &" << variable->value()
|
||||
<< "_impl;" << std::endl;
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << variable->GetValueForDeclaration() << ");"
|
||||
<< std::endl;
|
||||
source_out() << "USE(" << variable->value() << ");" << std::endl;
|
||||
if (initialization) {
|
||||
GenerateAssignToVariable(variable, *initialization);
|
||||
}
|
||||
@ -1340,7 +1337,7 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
|
||||
void ImplementationVisitor::GenerateParameter(
|
||||
const std::string& parameter_name) {
|
||||
const Value* val = declarations()->LookupValue(parameter_name);
|
||||
std::string var = val->GetValueForDeclaration();
|
||||
std::string var = val->value();
|
||||
GenerateIndent();
|
||||
source_out() << val->type()->GetGeneratedTypeName() << " " << var << " = ";
|
||||
|
||||
@ -1400,7 +1397,7 @@ VisitResult ImplementationVisitor::GeneratePointerCall(
|
||||
const Type* to_type = type->parameter_types()[current];
|
||||
VisitResult result =
|
||||
GenerateImplicitConvert(to_type, arguments.parameters[current]);
|
||||
variables.push_back(result.variable());
|
||||
variables.push_back(result.RValue());
|
||||
}
|
||||
|
||||
std::string result_variable_name;
|
||||
@ -1429,7 +1426,7 @@ VisitResult ImplementationVisitor::GeneratePointerCall(
|
||||
}
|
||||
source_out() << "Builtins::CallableFor(isolate(), Builtins::k"
|
||||
<< example_builtin->name() << ").descriptor(), "
|
||||
<< callee_result.variable() << ", ";
|
||||
<< callee_result.RValue() << ", ";
|
||||
|
||||
size_t total_parameters = 0;
|
||||
for (size_t i = 0; i < arguments.parameters.size(); ++i) {
|
||||
@ -1468,7 +1465,7 @@ VisitResult ImplementationVisitor::GenerateCall(
|
||||
: callable->signature().types()[current];
|
||||
VisitResult result =
|
||||
GenerateImplicitConvert(to_type, arguments.parameters[current]);
|
||||
variables.push_back(result.variable());
|
||||
variables.push_back(result.RValue());
|
||||
}
|
||||
|
||||
std::string result_variable_name;
|
||||
@ -1552,7 +1549,7 @@ VisitResult ImplementationVisitor::GenerateCall(
|
||||
ReportError(s.str());
|
||||
}
|
||||
j++;
|
||||
source_out() << variable->GetValueForDeclaration();
|
||||
source_out() << variable->value();
|
||||
}
|
||||
label->MarkUsed();
|
||||
}
|
||||
@ -1632,7 +1629,7 @@ VisitResult ImplementationVisitor::Visit(CallExpression* expr,
|
||||
}
|
||||
if (!result.type()->IsVoidOrNever()) {
|
||||
GenerateIndent();
|
||||
source_out() << "USE(" << result.variable() << ");" << std::endl;
|
||||
source_out() << "USE(" << result.RValue() << ");" << std::endl;
|
||||
}
|
||||
if (is_tailcall) {
|
||||
result = {TypeOracle::GetNeverType(), ""};
|
||||
@ -1664,7 +1661,7 @@ void ImplementationVisitor::GenerateBranch(const VisitResult& condition,
|
||||
Label* true_label,
|
||||
Label* false_label) {
|
||||
GenerateIndent();
|
||||
source_out() << "Branch(" << condition.variable() << ", "
|
||||
source_out() << "Branch(" << condition.RValue() << ", "
|
||||
<< true_label->generated() << ", " << false_label->generated()
|
||||
<< ");" << std::endl;
|
||||
}
|
||||
@ -1703,7 +1700,11 @@ VisitResult ImplementationVisitor::GenerateImplicitConvert(
|
||||
GetGeneratedCallableName(kFromConstexprMacroName, {destination_type});
|
||||
return GenerateCall(name, {{source}, {}}, false);
|
||||
} 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 {
|
||||
std::stringstream s;
|
||||
s << "cannot use expression of type " << *source.type()
|
||||
|
@ -58,7 +58,7 @@ class ImplementationVisitor : public FileVisitor {
|
||||
s << "\"" << value->name() << "\" is used before it is defined";
|
||||
ReportError(s.str());
|
||||
}
|
||||
return VisitResult({value->type(), value->GetValueForRead()});
|
||||
return VisitResult(value->type(), value);
|
||||
}
|
||||
VisitResult GenerateFetchFromLocation(FieldAccessExpression* expr,
|
||||
LocationReference reference) {
|
||||
|
@ -248,6 +248,15 @@ bool operator<(const Type& a, const Type& b) {
|
||||
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 internal
|
||||
} // namespace v8
|
||||
|
@ -33,6 +33,7 @@ static const char* const CONST_INT32_TYPE_STRING = "constexpr int32";
|
||||
static const char* const CONST_FLOAT64_TYPE_STRING = "constexpr float64";
|
||||
|
||||
class Label;
|
||||
class Value;
|
||||
|
||||
class TypeBase {
|
||||
public:
|
||||
@ -292,14 +293,20 @@ inline std::ostream& operator<<(std::ostream& os, const Type& t) {
|
||||
class VisitResult {
|
||||
public:
|
||||
VisitResult() {}
|
||||
VisitResult(const Type* type, const std::string& variable)
|
||||
: type_(type), variable_(variable) {}
|
||||
VisitResult(const Type* type, const std::string& value)
|
||||
: type_(type), value_(value), declarable_{} {}
|
||||
VisitResult(const Type* type, const Value* declarable);
|
||||
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:
|
||||
const Type* type_;
|
||||
std::string variable_;
|
||||
std::string value_;
|
||||
base::Optional<const Value*> declarable_;
|
||||
};
|
||||
|
||||
class VisitResultVector : public std::vector<VisitResult> {
|
||||
|
Loading…
Reference in New Issue
Block a user