[torque]: Add the ability to test Torque functionality with cctest
In the process, add a few simple tests for "constexpr" expressions, which identified a few bugs that are also fixed in this CL. Change-Id: I97486c781572642d2b574b92133b1f9cda3db592 Reviewed-on: https://chromium-review.googlesource.com/1055493 Commit-Queue: Daniel Clifford <danno@chromium.org> Reviewed-by: Tobias Tebbi <tebbi@chromium.org> Cr-Commit-Position: refs/heads/master@{#53135}
This commit is contained in:
parent
3fc8937ed1
commit
5f920f770d
3
BUILD.gn
3
BUILD.gn
@ -846,18 +846,21 @@ torque_files = [
|
|||||||
"src/builtins/base.tq",
|
"src/builtins/base.tq",
|
||||||
"src/builtins/array.tq",
|
"src/builtins/array.tq",
|
||||||
"src/builtins/typed-array.tq",
|
"src/builtins/typed-array.tq",
|
||||||
|
"test/torque/test-torque.tq",
|
||||||
]
|
]
|
||||||
|
|
||||||
torque_modules = [
|
torque_modules = [
|
||||||
"base",
|
"base",
|
||||||
"array",
|
"array",
|
||||||
"typed-array",
|
"typed-array",
|
||||||
|
"test",
|
||||||
]
|
]
|
||||||
|
|
||||||
action("run_torque") {
|
action("run_torque") {
|
||||||
visibility = [
|
visibility = [
|
||||||
":*",
|
":*",
|
||||||
"tools/gcmole/:*",
|
"tools/gcmole/:*",
|
||||||
|
"test/cctest/:*",
|
||||||
]
|
]
|
||||||
|
|
||||||
# We reuse the snapshot toolchain for building torque to not build v8_libbase
|
# We reuse the snapshot toolchain for building torque to not build v8_libbase
|
||||||
|
@ -136,6 +136,10 @@ extern operator '<=' macro SmiLessThanOrEqual(Smi, Smi): bool;
|
|||||||
extern operator '>' macro SmiGreaterThan(Smi, Smi): bool;
|
extern operator '>' macro SmiGreaterThan(Smi, Smi): bool;
|
||||||
extern operator '>=' macro SmiGreaterThanOrEqual(Smi, Smi): bool;
|
extern operator '>=' macro SmiGreaterThanOrEqual(Smi, Smi): bool;
|
||||||
|
|
||||||
|
extern operator '==' macro ElementsKindEqual(
|
||||||
|
constexpr ElementsKind, constexpr ElementsKind): constexpr bool;
|
||||||
|
extern macro IsFastElementsKind(constexpr ElementsKind): constexpr bool;
|
||||||
|
|
||||||
extern macro SmiAbove(Smi, Smi): bool;
|
extern macro SmiAbove(Smi, Smi): bool;
|
||||||
|
|
||||||
extern operator '==' macro WordEqual(intptr, intptr): bool;
|
extern operator '==' macro WordEqual(intptr, intptr): bool;
|
||||||
@ -175,6 +179,7 @@ extern operator '-' macro NumberSub(Number, Number): Number;
|
|||||||
extern operator 'min' macro NumberMin(Number, Number): Number;
|
extern operator 'min' macro NumberMin(Number, Number): Number;
|
||||||
extern operator 'max' macro NumberMax(Number, Number): Number;
|
extern operator 'max' macro NumberMax(Number, Number): Number;
|
||||||
|
|
||||||
|
extern operator '!' macro ConstexprBoolNot(constexpr bool): constexpr bool;
|
||||||
extern operator '!' macro Word32BinaryNot(bool): bool;
|
extern operator '!' macro Word32BinaryNot(bool): bool;
|
||||||
|
|
||||||
extern operator '.map' macro LoadMap(HeapObject): Map;
|
extern operator '.map' macro LoadMap(HeapObject): Map;
|
||||||
|
22
src/builtins/builtins-test-gen.h
Normal file
22
src/builtins/builtins-test-gen.h
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#ifndef V8_BUILTINS_BUILTINS_TEST_GEN_H_
|
||||||
|
#define V8_BUILTINS_BUILTINS_TEST_GEN_H_
|
||||||
|
|
||||||
|
#include "torque-generated/builtins-base-from-dsl-gen.h"
|
||||||
|
|
||||||
|
namespace v8 {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
class TestBuiltinsAssembler : public BaseBuiltinsFromDSLAssembler {
|
||||||
|
public:
|
||||||
|
explicit TestBuiltinsAssembler(compiler::CodeAssemblerState* state)
|
||||||
|
: BaseBuiltinsFromDSLAssembler(state) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace v8
|
||||||
|
|
||||||
|
#endif // V8_BUILTINS_BUILTINS_TEST_GEN_H_
|
@ -1489,6 +1489,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
|
|
||||||
// ElementsKind helpers:
|
// ElementsKind helpers:
|
||||||
Node* IsFastElementsKind(Node* elements_kind);
|
Node* IsFastElementsKind(Node* elements_kind);
|
||||||
|
bool IsFastElementsKind(ElementsKind kind) {
|
||||||
|
return v8::internal::IsFastElementsKind(kind);
|
||||||
|
}
|
||||||
Node* IsFastSmiOrTaggedElementsKind(Node* elements_kind);
|
Node* IsFastSmiOrTaggedElementsKind(Node* elements_kind);
|
||||||
Node* IsFastSmiElementsKind(Node* elements_kind);
|
Node* IsFastSmiElementsKind(Node* elements_kind);
|
||||||
Node* IsHoleyFastElementsKind(Node* elements_kind);
|
Node* IsHoleyFastElementsKind(Node* elements_kind);
|
||||||
@ -2337,6 +2340,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
|
|||||||
Unreachable();
|
Unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConstexprBoolNot(bool value) { return !value; }
|
||||||
|
|
||||||
void PerformStackCheck(Node* context);
|
void PerformStackCheck(Node* context);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -264,6 +264,7 @@ inline bool IsTransitionableFastElementsKind(ElementsKind from_kind) {
|
|||||||
from_kind != TERMINAL_FAST_ELEMENTS_KIND;
|
from_kind != TERMINAL_FAST_ELEMENTS_KIND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool ElementsKindEqual(ElementsKind a, ElementsKind b) { return a == b; }
|
||||||
|
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -79,6 +79,7 @@ class Type : public Declarable {
|
|||||||
bool IsVoid() const { return name() == VOID_TYPE_STRING; }
|
bool IsVoid() const { return name() == VOID_TYPE_STRING; }
|
||||||
bool IsNever() const { return name() == NEVER_TYPE_STRING; }
|
bool IsNever() const { return name() == NEVER_TYPE_STRING; }
|
||||||
bool IsBool() const { return name() == BOOL_TYPE_STRING; }
|
bool IsBool() const { return name() == BOOL_TYPE_STRING; }
|
||||||
|
bool IsConstexprBool() const { return name() == CONSTEXPR_BOOL_TYPE_STRING; }
|
||||||
bool IsVoidOrNever() const { return IsVoid() || IsNever(); }
|
bool IsVoidOrNever() const { return IsVoid() || IsNever(); }
|
||||||
bool IsConstexpr() const {
|
bool IsConstexpr() const {
|
||||||
return name().substr(0, strlen(CONSTEXPR_TYPE_PREFIX)) ==
|
return name().substr(0, strlen(CONSTEXPR_TYPE_PREFIX)) ==
|
||||||
@ -136,7 +137,13 @@ class Variable : public Value {
|
|||||||
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 GetValueForDeclaration() const override { return value_; }
|
||||||
std::string GetValueForRead() const override { return value_ + "->value()"; }
|
std::string GetValueForRead() const override {
|
||||||
|
if (type()->IsConstexpr()) {
|
||||||
|
return std::string("*") + value_;
|
||||||
|
} else {
|
||||||
|
return value_ + "->value()";
|
||||||
|
}
|
||||||
|
}
|
||||||
std::string GetValueForWrite() const override {
|
std::string GetValueForWrite() const override {
|
||||||
return std::string("*") + value_;
|
return std::string("*") + value_;
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,9 @@ void DeclarationVisitor::Visit(ReturnStatement* stmt) {
|
|||||||
MarkVariableModified(Variable::cast(
|
MarkVariableModified(Variable::cast(
|
||||||
declarations()->LookupValue(stmt->pos, kReturnValueVariable)));
|
declarations()->LookupValue(stmt->pos, kReturnValueVariable)));
|
||||||
}
|
}
|
||||||
|
if (stmt->value) {
|
||||||
|
Visit(*stmt->value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclarationVisitor::Visit(ForOfLoopStatement* stmt) {
|
void DeclarationVisitor::Visit(ForOfLoopStatement* stmt) {
|
||||||
|
@ -208,6 +208,12 @@ class DeclarationVisitor : public FileVisitor {
|
|||||||
void Visit(VarDeclarationStatement* stmt) {
|
void Visit(VarDeclarationStatement* stmt) {
|
||||||
std::string variable_name = stmt->name;
|
std::string variable_name = stmt->name;
|
||||||
const Type* type = declarations()->LookupType(stmt->pos, stmt->type);
|
const Type* type = declarations()->LookupType(stmt->pos, stmt->type);
|
||||||
|
if (type->IsConstexpr()) {
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << "cannot declare variable with constexpr type at "
|
||||||
|
<< PositionAsString(stmt->pos);
|
||||||
|
ReportError(stream.str());
|
||||||
|
}
|
||||||
declarations()->DeclareVariable(stmt->pos, variable_name, type);
|
declarations()->DeclareVariable(stmt->pos, variable_name, type);
|
||||||
if (global_context_.verbose()) {
|
if (global_context_.verbose()) {
|
||||||
std::cout << "declared variable " << variable_name << " with type "
|
std::cout << "declared variable " << variable_name << " with type "
|
||||||
|
@ -78,6 +78,8 @@ class Declarations {
|
|||||||
return source_file_map_->PositionAsString(pos);
|
return source_file_map_->PositionAsString(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintScopeChain() { chain_.Print(); }
|
||||||
|
|
||||||
class NodeScopeActivator;
|
class NodeScopeActivator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -65,6 +65,7 @@ void ImplementationVisitor::Visit(ModuleDeclaration* decl) {
|
|||||||
source << "#include \"src/builtins/builtins-utils-gen.h\"" << std::endl;
|
source << "#include \"src/builtins/builtins-utils-gen.h\"" << std::endl;
|
||||||
source << "#include \"src/builtins/builtins.h\"" << std::endl;
|
source << "#include \"src/builtins/builtins.h\"" << std::endl;
|
||||||
source << "#include \"src/code-factory.h\"" << std::endl;
|
source << "#include \"src/code-factory.h\"" << std::endl;
|
||||||
|
source << "#include \"src/elements-kind.h\"" << std::endl;
|
||||||
source << "#include \"src/heap/factory-inl.h\"" << std::endl;
|
source << "#include \"src/heap/factory-inl.h\"" << std::endl;
|
||||||
source << "#include \"src/objects.h\"" << std::endl;
|
source << "#include \"src/objects.h\"" << std::endl;
|
||||||
|
|
||||||
@ -149,13 +150,17 @@ void ImplementationVisitor::Visit(MacroDeclaration* decl) {
|
|||||||
|
|
||||||
const Variable* result_var = nullptr;
|
const Variable* result_var = nullptr;
|
||||||
if (macro->HasReturnValue()) {
|
if (macro->HasReturnValue()) {
|
||||||
GenerateIndent();
|
|
||||||
source_out() << "Node* return_default = &*SmiConstant(0);" << std::endl;
|
|
||||||
const Type* return_type = macro->signature().return_type;
|
const Type* return_type = macro->signature().return_type;
|
||||||
VisitResult init = {return_type,
|
if (!return_type->IsConstexpr()) {
|
||||||
std::string("UncheckedCast<") +
|
GenerateIndent();
|
||||||
return_type->GetGeneratedTNodeTypeName() +
|
source_out() << "Node* return_default = &*SmiConstant(0);" << std::endl;
|
||||||
">(return_default)"};
|
}
|
||||||
|
VisitResult init = {
|
||||||
|
return_type,
|
||||||
|
return_type->IsConstexpr()
|
||||||
|
? (return_type->GetGeneratedTypeName() + "()")
|
||||||
|
: (std::string("UncheckedCast<") +
|
||||||
|
return_type->GetGeneratedTNodeTypeName() + ">(return_default)")};
|
||||||
result_var =
|
result_var =
|
||||||
GenerateVariableDeclaration(decl, kReturnValueVariable, {}, init);
|
GenerateVariableDeclaration(decl, kReturnValueVariable, {}, init);
|
||||||
}
|
}
|
||||||
@ -335,42 +340,73 @@ VisitResult ImplementationVisitor::Visit(ConditionalExpression* expr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
VisitResult ImplementationVisitor::Visit(LogicalOrExpression* expr) {
|
||||||
|
VisitResult left_result;
|
||||||
{
|
{
|
||||||
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
||||||
Label* false_label =
|
Label* false_label =
|
||||||
declarations()->LookupLabel(expr->pos, kFalseLabelName);
|
declarations()->LookupLabel(expr->pos, kFalseLabelName);
|
||||||
GenerateLabelDefinition(false_label);
|
GenerateLabelDefinition(false_label);
|
||||||
VisitResult left_result = Visit(expr->left);
|
left_result = Visit(expr->left);
|
||||||
if (left_result.type()->IsBool()) {
|
if (left_result.type()->IsBool()) {
|
||||||
Label* true_label =
|
Label* true_label =
|
||||||
declarations()->LookupLabel(expr->pos, kTrueLabelName);
|
declarations()->LookupLabel(expr->pos, kTrueLabelName);
|
||||||
GenerateIndent();
|
GenerateIndent();
|
||||||
source_out() << "GotoIf(" << left_result.variable() << ", "
|
source_out() << "GotoIf(" << left_result.variable() << ", "
|
||||||
<< true_label->generated() << ");" << std::endl;
|
<< true_label->generated() << ");" << std::endl;
|
||||||
} else {
|
} else if (!left_result.type()->IsConstexprBool()) {
|
||||||
GenerateLabelBind(false_label);
|
GenerateLabelBind(false_label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Visit(expr->right);
|
VisitResult right_result = Visit(expr->right);
|
||||||
|
if (right_result.type() != left_result.type()) {
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << "types of left and right expression of logical OR don't match (\""
|
||||||
|
<< left_result.type() << "\" vs. \"" << right_result.type()
|
||||||
|
<< "\") at " << PositionAsString(expr->pos);
|
||||||
|
ReportError(stream.str());
|
||||||
|
}
|
||||||
|
if (left_result.type()->IsConstexprBool()) {
|
||||||
|
return VisitResult(left_result.type(), std::string("(") +
|
||||||
|
left_result.variable() + " || " +
|
||||||
|
right_result.variable() + ")");
|
||||||
|
} else {
|
||||||
|
return right_result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
|
VisitResult ImplementationVisitor::Visit(LogicalAndExpression* expr) {
|
||||||
|
VisitResult left_result;
|
||||||
{
|
{
|
||||||
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
Declarations::NodeScopeActivator scope(declarations(), expr->left);
|
||||||
Label* true_label = declarations()->LookupLabel(expr->pos, kTrueLabelName);
|
Label* true_label = declarations()->LookupLabel(expr->pos, kTrueLabelName);
|
||||||
GenerateLabelDefinition(true_label);
|
GenerateLabelDefinition(true_label);
|
||||||
VisitResult left_result = Visit(expr->left);
|
left_result = Visit(expr->left);
|
||||||
if (left_result.type()->IsBool()) {
|
if (left_result.type()->IsBool()) {
|
||||||
Label* false_label =
|
Label* false_label =
|
||||||
declarations()->LookupLabel(expr->pos, kFalseLabelName);
|
declarations()->LookupLabel(expr->pos, kFalseLabelName);
|
||||||
GenerateIndent();
|
GenerateIndent();
|
||||||
source_out() << "GotoIfNot(" << left_result.variable() << ", "
|
source_out() << "GotoIfNot(" << left_result.variable() << ", "
|
||||||
<< false_label->generated() << ");" << std::endl;
|
<< false_label->generated() << ");" << std::endl;
|
||||||
} else {
|
} else if (!left_result.type()->IsConstexprBool()) {
|
||||||
GenerateLabelBind(true_label);
|
GenerateLabelBind(true_label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Visit(expr->right);
|
VisitResult right_result = Visit(expr->right);
|
||||||
|
if (right_result.type() != left_result.type()) {
|
||||||
|
std::stringstream stream;
|
||||||
|
stream
|
||||||
|
<< "types of left and right expression of logical AND don't match (\""
|
||||||
|
<< left_result.type() << "\" vs. \"" << right_result.type() << "\") at "
|
||||||
|
<< PositionAsString(expr->pos);
|
||||||
|
ReportError(stream.str());
|
||||||
|
}
|
||||||
|
if (left_result.type()->IsConstexprBool()) {
|
||||||
|
return VisitResult(left_result.type(), std::string("(") +
|
||||||
|
left_result.variable() + " && " +
|
||||||
|
right_result.variable() + ")");
|
||||||
|
} else {
|
||||||
|
return right_result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VisitResult ImplementationVisitor::Visit(IncrementDecrementExpression* expr) {
|
VisitResult ImplementationVisitor::Visit(IncrementDecrementExpression* expr) {
|
||||||
@ -494,24 +530,33 @@ const Type* ImplementationVisitor::Visit(IfStatement* stmt) {
|
|||||||
ReportError(stream.str());
|
ReportError(stream.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Type* left_result;
|
||||||
|
const Type* right_result = GetTypeOracle().GetVoidType();
|
||||||
{
|
{
|
||||||
GenerateIndent();
|
GenerateIndent();
|
||||||
source_out() << "if ((" << expression_result.variable() << ")) ";
|
source_out() << "if ((" << expression_result.variable() << ")) ";
|
||||||
ScopedIndent indent(this, false);
|
ScopedIndent indent(this, false);
|
||||||
source_out() << std::endl;
|
source_out() << std::endl;
|
||||||
Visit(stmt->if_true);
|
left_result = Visit(stmt->if_true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_else) {
|
if (has_else) {
|
||||||
source_out() << " else ";
|
source_out() << " else ";
|
||||||
ScopedIndent indent(this, false);
|
ScopedIndent indent(this, false);
|
||||||
source_out() << std::endl;
|
source_out() << std::endl;
|
||||||
Visit(*stmt->if_false);
|
right_result = Visit(*stmt->if_false);
|
||||||
|
}
|
||||||
|
if (left_result->IsNever() != right_result->IsNever()) {
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << "either both or neither branches in a constexpr if statement "
|
||||||
|
"must reach their end at"
|
||||||
|
<< PositionAsString(stmt->pos);
|
||||||
|
ReportError(stream.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
source_out() << std::endl;
|
source_out() << std::endl;
|
||||||
|
|
||||||
return GetTypeOracle().GetVoidType();
|
return left_result;
|
||||||
} else {
|
} else {
|
||||||
Label* true_label = nullptr;
|
Label* true_label = nullptr;
|
||||||
Label* false_label = nullptr;
|
Label* false_label = nullptr;
|
||||||
@ -1041,6 +1086,7 @@ void ImplementationVisitor::GenerateChangedVarsFromControlSplit(AstNode* node) {
|
|||||||
source_out() << "{";
|
source_out() << "{";
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto v : changed_vars) {
|
for (auto v : changed_vars) {
|
||||||
|
if (v->type()->IsConstexpr()) continue;
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
@ -1164,10 +1210,16 @@ Variable* ImplementationVisitor::GenerateVariableDeclaration(
|
|||||||
}
|
}
|
||||||
|
|
||||||
GenerateIndent();
|
GenerateIndent();
|
||||||
source_out() << "TVARIABLE(";
|
if (variable->type()->IsConstexpr()) {
|
||||||
source_out() << variable->type()->GetGeneratedTNodeTypeName();
|
source_out() << variable->type()->GetGeneratedTypeName();
|
||||||
source_out() << ", " << variable->GetValueForDeclaration() << "_impl);"
|
source_out() << " " << variable->GetValueForDeclaration() << "_impl;"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
} else {
|
||||||
|
source_out() << "TVARIABLE(";
|
||||||
|
source_out() << variable->type()->GetGeneratedTNodeTypeName();
|
||||||
|
source_out() << ", " << variable->GetValueForDeclaration() << "_impl);"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
GenerateIndent();
|
GenerateIndent();
|
||||||
source_out() << "auto " << variable->GetValueForDeclaration() << " = &"
|
source_out() << "auto " << variable->GetValueForDeclaration() << " = &"
|
||||||
<< variable->GetValueForDeclaration() << "_impl;" << std::endl;
|
<< variable->GetValueForDeclaration() << "_impl;" << std::endl;
|
||||||
@ -1228,9 +1280,11 @@ VisitResult ImplementationVisitor::GenerateCall(
|
|||||||
GenerateIndent();
|
GenerateIndent();
|
||||||
} else {
|
} else {
|
||||||
result_variable_name = GenerateNewTempVariable(result_type);
|
result_variable_name = GenerateNewTempVariable(result_type);
|
||||||
source_out() << "UncheckedCast<";
|
if (!result_type->IsConstexpr()) {
|
||||||
source_out() << result_type->GetGeneratedTNodeTypeName();
|
source_out() << "UncheckedCast<";
|
||||||
source_out() << ">(";
|
source_out() << result_type->GetGeneratedTNodeTypeName();
|
||||||
|
source_out() << ">(";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (callable->IsBuiltin()) {
|
if (callable->IsBuiltin()) {
|
||||||
if (is_tailcall) {
|
if (is_tailcall) {
|
||||||
@ -1313,7 +1367,8 @@ VisitResult ImplementationVisitor::GenerateCall(
|
|||||||
std::cout << "finished generating code for call to " << callable_name
|
std::cout << "finished generating code for call to " << callable_name
|
||||||
<< " at " << PositionAsString(pos) << "" << std::endl;
|
<< " at " << PositionAsString(pos) << "" << std::endl;
|
||||||
}
|
}
|
||||||
if (!result_type->IsVoidOrNever() && !is_tailcall) {
|
if (!result_type->IsVoidOrNever() && !is_tailcall &&
|
||||||
|
!result_type->IsConstexpr()) {
|
||||||
source_out() << ")";
|
source_out() << ")";
|
||||||
}
|
}
|
||||||
source_out() << ");" << std::endl;
|
source_out() << ");" << std::endl;
|
||||||
|
@ -229,6 +229,7 @@ v8_source_set("cctest_sources") {
|
|||||||
"test-version.cc",
|
"test-version.cc",
|
||||||
"test-weakmaps.cc",
|
"test-weakmaps.cc",
|
||||||
"test-weaksets.cc",
|
"test-weaksets.cc",
|
||||||
|
"torque/test-torque.cc",
|
||||||
"trace-extension.cc",
|
"trace-extension.cc",
|
||||||
"trace-extension.h",
|
"trace-extension.h",
|
||||||
"types-fuzz.h",
|
"types-fuzz.h",
|
||||||
@ -381,7 +382,9 @@ v8_source_set("cctest_sources") {
|
|||||||
]
|
]
|
||||||
|
|
||||||
defines = []
|
defines = []
|
||||||
deps = []
|
deps = [
|
||||||
|
"../..:run_torque",
|
||||||
|
]
|
||||||
|
|
||||||
if (is_component_build) {
|
if (is_component_build) {
|
||||||
# cctest can't be built against a shared library, so we
|
# cctest can't be built against a shared library, so we
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
include_rules = [
|
include_rules = [
|
||||||
"+src",
|
"+src",
|
||||||
|
"+torque-generated"
|
||||||
]
|
]
|
||||||
|
70
test/cctest/torque/test-torque.cc
Normal file
70
test/cctest/torque/test-torque.cc
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright 2015 the V8 project authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
#include "src/api.h"
|
||||||
|
#include "src/base/utils/random-number-generator.h"
|
||||||
|
#include "src/builtins/builtins-promise-gen.h"
|
||||||
|
#include "src/builtins/builtins-string-gen.h"
|
||||||
|
#include "src/char-predicates.h"
|
||||||
|
#include "src/code-factory.h"
|
||||||
|
#include "src/code-stub-assembler.h"
|
||||||
|
#include "src/compiler/node.h"
|
||||||
|
#include "src/debug/debug.h"
|
||||||
|
#include "src/elements-kind.h"
|
||||||
|
#include "src/isolate.h"
|
||||||
|
#include "src/objects-inl.h"
|
||||||
|
#include "src/objects/promise-inl.h"
|
||||||
|
#include "test/cctest/compiler/code-assembler-tester.h"
|
||||||
|
#include "test/cctest/compiler/function-tester.h"
|
||||||
|
#include "torque-generated/builtins-test-from-dsl-gen.h"
|
||||||
|
|
||||||
|
namespace v8 {
|
||||||
|
namespace internal {
|
||||||
|
namespace compiler {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
typedef CodeAssemblerLabel Label;
|
||||||
|
typedef CodeAssemblerVariable Variable;
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
TEST(TestConstexpr1) {
|
||||||
|
Isolate* isolate(CcTest::InitIsolateOnce());
|
||||||
|
CodeAssemblerTester asm_tester(isolate, 0);
|
||||||
|
TestBuiltinsFromDSLAssembler m(asm_tester.state());
|
||||||
|
{
|
||||||
|
m.TestConstexpr1();
|
||||||
|
m.Return(m.UndefinedConstant());
|
||||||
|
}
|
||||||
|
FunctionTester ft(asm_tester.GenerateCode(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestConstexprIf) {
|
||||||
|
Isolate* isolate(CcTest::InitIsolateOnce());
|
||||||
|
CodeAssemblerTester asm_tester(isolate, 0);
|
||||||
|
TestBuiltinsFromDSLAssembler m(asm_tester.state());
|
||||||
|
{
|
||||||
|
m.TestConstexprIf();
|
||||||
|
m.Return(m.UndefinedConstant());
|
||||||
|
}
|
||||||
|
FunctionTester ft(asm_tester.GenerateCode(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TestConstexprReturn) {
|
||||||
|
Isolate* isolate(CcTest::InitIsolateOnce());
|
||||||
|
CodeAssemblerTester asm_tester(isolate, 0);
|
||||||
|
TestBuiltinsFromDSLAssembler m(asm_tester.state());
|
||||||
|
{
|
||||||
|
m.TestConstexprReturn();
|
||||||
|
m.Return(m.UndefinedConstant());
|
||||||
|
}
|
||||||
|
FunctionTester ft(asm_tester.GenerateCode(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace compiler
|
||||||
|
} // namespace internal
|
||||||
|
} // namespace v8
|
40
test/torque/test-torque.tq
Normal file
40
test/torque/test-torque.tq
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2018 the V8 project authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
module test {
|
||||||
|
|
||||||
|
macro ElementsKindTestHelper1(kind: constexpr ElementsKind): bool {
|
||||||
|
if constexpr ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro ElementsKindTestHelper2(kind: constexpr ElementsKind): bool {
|
||||||
|
return ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
macro ElementsKindTestHelper3(kind: constexpr ElementsKind): constexpr bool {
|
||||||
|
return ((kind == UINT8_ELEMENTS) || (kind == UINT16_ELEMENTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
macro TestConstexpr1() {
|
||||||
|
assert(convert<bool>(IsFastElementsKind(PACKED_SMI_ELEMENTS)));
|
||||||
|
}
|
||||||
|
|
||||||
|
macro TestConstexprIf() {
|
||||||
|
assert(ElementsKindTestHelper1(UINT8_ELEMENTS));
|
||||||
|
assert(ElementsKindTestHelper1(UINT16_ELEMENTS));
|
||||||
|
assert(!ElementsKindTestHelper1(UINT32_ELEMENTS));
|
||||||
|
}
|
||||||
|
|
||||||
|
macro TestConstexprReturn() {
|
||||||
|
assert(convert<bool>(ElementsKindTestHelper3(UINT8_ELEMENTS)));
|
||||||
|
assert(convert<bool>(ElementsKindTestHelper3(UINT16_ELEMENTS)));
|
||||||
|
assert(!convert<bool>(ElementsKindTestHelper3(UINT32_ELEMENTS)));
|
||||||
|
assert(convert<bool>(!ElementsKindTestHelper3(UINT32_ELEMENTS)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user