Commit 610c964a authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[torque] add support for release-build checks

Change-Id: Ie8bdbcdea8006d3105c419113f9adb2c1d6f162c
Reviewed-on: https://chromium-review.googlesource.com/1070203
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53341}
parent 8ac37bc3
...@@ -36,7 +36,8 @@ ISNT: 'isnt'; ...@@ -36,7 +36,8 @@ ISNT: 'isnt';
IS: 'is'; IS: 'is';
LET: 'let'; LET: 'let';
EXTERN: 'extern'; EXTERN: 'extern';
ASSERT: 'assert'; ASSERT_TOKEN: 'assert';
CHECK_TOKEN: 'check';
UNREACHABLE_TOKEN: 'unreachable'; UNREACHABLE_TOKEN: 'unreachable';
DEBUG_TOKEN: 'debug'; DEBUG_TOKEN: 'debug';
...@@ -241,7 +242,7 @@ gotoStatement: GOTO labelReference argumentList?; ...@@ -241,7 +242,7 @@ gotoStatement: GOTO labelReference argumentList?;
handlerWithStatement: (CATCH IDENTIFIER | LABEL labelDeclaration) statementBlock; handlerWithStatement: (CATCH IDENTIFIER | LABEL labelDeclaration) statementBlock;
tryCatch: TRY statementBlock handlerWithStatement+; tryCatch: TRY statementBlock handlerWithStatement+;
diagnosticStatement: (ASSERT '(' expression ')') | UNREACHABLE_TOKEN | DEBUG_TOKEN; diagnosticStatement: ((ASSERT_TOKEN | CHECK_TOKEN) '(' expression ')') | UNREACHABLE_TOKEN | DEBUG_TOKEN;
statement : variableDeclarationWithInitialization ';' statement : variableDeclarationWithInitialization ';'
| helperCallStatement ';' | helperCallStatement ';'
......
This diff is collapsed.
...@@ -61,41 +61,42 @@ class TorqueLexer : public antlr4::Lexer { ...@@ -61,41 +61,42 @@ class TorqueLexer : public antlr4::Lexer {
IS = 46, IS = 46,
LET = 47, LET = 47,
EXTERN = 48, EXTERN = 48,
ASSERT = 49, ASSERT_TOKEN = 49,
UNREACHABLE_TOKEN = 50, CHECK_TOKEN = 50,
DEBUG_TOKEN = 51, UNREACHABLE_TOKEN = 51,
ASSIGNMENT = 52, DEBUG_TOKEN = 52,
ASSIGNMENT_OPERATOR = 53, ASSIGNMENT = 53,
EQUAL = 54, ASSIGNMENT_OPERATOR = 54,
PLUS = 55, EQUAL = 55,
MINUS = 56, PLUS = 56,
MULTIPLY = 57, MINUS = 57,
DIVIDE = 58, MULTIPLY = 58,
MODULO = 59, DIVIDE = 59,
BIT_OR = 60, MODULO = 60,
BIT_AND = 61, BIT_OR = 61,
BIT_NOT = 62, BIT_AND = 62,
MAX = 63, BIT_NOT = 63,
MIN = 64, MAX = 64,
NOT_EQUAL = 65, MIN = 65,
LESS_THAN = 66, NOT_EQUAL = 66,
LESS_THAN_EQUAL = 67, LESS_THAN = 67,
GREATER_THAN = 68, LESS_THAN_EQUAL = 68,
GREATER_THAN_EQUAL = 69, GREATER_THAN = 69,
SHIFT_LEFT = 70, GREATER_THAN_EQUAL = 70,
SHIFT_RIGHT = 71, SHIFT_LEFT = 71,
SHIFT_RIGHT_ARITHMETIC = 72, SHIFT_RIGHT = 72,
VARARGS = 73, SHIFT_RIGHT_ARITHMETIC = 73,
EQUALITY_OPERATOR = 74, VARARGS = 74,
INCREMENT = 75, EQUALITY_OPERATOR = 75,
DECREMENT = 76, INCREMENT = 76,
NOT = 77, DECREMENT = 77,
STRING_LITERAL = 78, NOT = 78,
IDENTIFIER = 79, STRING_LITERAL = 79,
WS = 80, IDENTIFIER = 80,
BLOCK_COMMENT = 81, WS = 81,
LINE_COMMENT = 82, BLOCK_COMMENT = 82,
DECIMAL_LITERAL = 83 LINE_COMMENT = 83,
DECIMAL_LITERAL = 84
}; };
explicit TorqueLexer(antlr4::CharStream* input); explicit TorqueLexer(antlr4::CharStream* input);
......
This diff is collapsed.
...@@ -61,41 +61,42 @@ class TorqueParser : public antlr4::Parser { ...@@ -61,41 +61,42 @@ class TorqueParser : public antlr4::Parser {
IS = 46, IS = 46,
LET = 47, LET = 47,
EXTERN = 48, EXTERN = 48,
ASSERT = 49, ASSERT_TOKEN = 49,
UNREACHABLE_TOKEN = 50, CHECK_TOKEN = 50,
DEBUG_TOKEN = 51, UNREACHABLE_TOKEN = 51,
ASSIGNMENT = 52, DEBUG_TOKEN = 52,
ASSIGNMENT_OPERATOR = 53, ASSIGNMENT = 53,
EQUAL = 54, ASSIGNMENT_OPERATOR = 54,
PLUS = 55, EQUAL = 55,
MINUS = 56, PLUS = 56,
MULTIPLY = 57, MINUS = 57,
DIVIDE = 58, MULTIPLY = 58,
MODULO = 59, DIVIDE = 59,
BIT_OR = 60, MODULO = 60,
BIT_AND = 61, BIT_OR = 61,
BIT_NOT = 62, BIT_AND = 62,
MAX = 63, BIT_NOT = 63,
MIN = 64, MAX = 64,
NOT_EQUAL = 65, MIN = 65,
LESS_THAN = 66, NOT_EQUAL = 66,
LESS_THAN_EQUAL = 67, LESS_THAN = 67,
GREATER_THAN = 68, LESS_THAN_EQUAL = 68,
GREATER_THAN_EQUAL = 69, GREATER_THAN = 69,
SHIFT_LEFT = 70, GREATER_THAN_EQUAL = 70,
SHIFT_RIGHT = 71, SHIFT_LEFT = 71,
SHIFT_RIGHT_ARITHMETIC = 72, SHIFT_RIGHT = 72,
VARARGS = 73, SHIFT_RIGHT_ARITHMETIC = 73,
EQUALITY_OPERATOR = 74, VARARGS = 74,
INCREMENT = 75, EQUALITY_OPERATOR = 75,
DECREMENT = 76, INCREMENT = 76,
NOT = 77, DECREMENT = 77,
STRING_LITERAL = 78, NOT = 78,
IDENTIFIER = 79, STRING_LITERAL = 79,
WS = 80, IDENTIFIER = 80,
BLOCK_COMMENT = 81, WS = 81,
LINE_COMMENT = 82, BLOCK_COMMENT = 82,
DECIMAL_LITERAL = 83 LINE_COMMENT = 83,
DECIMAL_LITERAL = 84
}; };
enum { enum {
...@@ -1097,8 +1098,9 @@ class TorqueParser : public antlr4::Parser { ...@@ -1097,8 +1098,9 @@ class TorqueParser : public antlr4::Parser {
DiagnosticStatementContext(antlr4::ParserRuleContext* parent, DiagnosticStatementContext(antlr4::ParserRuleContext* parent,
size_t invokingState); size_t invokingState);
size_t getRuleIndex() const override; size_t getRuleIndex() const override;
antlr4::tree::TerminalNode* ASSERT();
ExpressionContext* expression(); ExpressionContext* expression();
antlr4::tree::TerminalNode* ASSERT_TOKEN();
antlr4::tree::TerminalNode* CHECK_TOKEN();
antlr4::tree::TerminalNode* UNREACHABLE_TOKEN(); antlr4::tree::TerminalNode* UNREACHABLE_TOKEN();
antlr4::tree::TerminalNode* DEBUG_TOKEN(); antlr4::tree::TerminalNode* DEBUG_TOKEN();
......
...@@ -748,14 +748,14 @@ antlrcpp::Any AstGenerator::visitConditionalExpression( ...@@ -748,14 +748,14 @@ antlrcpp::Any AstGenerator::visitConditionalExpression(
antlrcpp::Any AstGenerator::visitDiagnosticStatement( antlrcpp::Any AstGenerator::visitDiagnosticStatement(
TorqueParser::DiagnosticStatementContext* context) { TorqueParser::DiagnosticStatementContext* context) {
if (context->ASSERT()) { if (context->ASSERT_TOKEN() || context->CHECK_TOKEN()) {
size_t a = context->expression()->start->getStartIndex(); size_t a = context->expression()->start->getStartIndex();
size_t b = context->expression()->stop->getStopIndex(); size_t b = context->expression()->stop->getStopIndex();
antlr4::misc::Interval interval(a, b); antlr4::misc::Interval interval(a, b);
std::string source = source_file_context_->stream->getText(interval); std::string source = source_file_context_->stream->getText(interval);
return implicit_cast<Statement*>(RegisterNode(new AssertStatement{ return implicit_cast<Statement*>(RegisterNode(new AssertStatement{
Pos(context), context->expression()->accept(this).as<Expression*>(), Pos(context), context->ASSERT_TOKEN() != nullptr,
source})); context->expression()->accept(this).as<Expression*>(), source}));
} else if (context->UNREACHABLE_TOKEN()) { } else if (context->UNREACHABLE_TOKEN()) {
return implicit_cast<Statement*>( return implicit_cast<Statement*>(
RegisterNode(new DebugStatement{Pos(context), "unreachable", true})); RegisterNode(new DebugStatement{Pos(context), "unreachable", true}));
......
...@@ -427,8 +427,13 @@ struct DebugStatement : Statement { ...@@ -427,8 +427,13 @@ struct DebugStatement : Statement {
struct AssertStatement : Statement { struct AssertStatement : Statement {
DEFINE_AST_NODE_LEAF_BOILERPLATE(AssertStatement) DEFINE_AST_NODE_LEAF_BOILERPLATE(AssertStatement)
AssertStatement(SourcePosition p, Expression* e, const std::string& s) AssertStatement(SourcePosition pos, bool debug_only, Expression* expression,
: Statement(kKind, p), expression(e), source(s) {} std::string source)
: Statement(kKind, pos),
debug_only(debug_only),
expression(expression),
source(std::move(source)) {}
bool debug_only;
Expression* expression; Expression* expression;
std::string source; std::string source;
}; };
......
...@@ -115,9 +115,11 @@ class DeclarationVisitor : public FileVisitor { ...@@ -115,9 +115,11 @@ class DeclarationVisitor : public FileVisitor {
void Visit(DebugStatement* stmt) {} void Visit(DebugStatement* stmt) {}
void Visit(AssertStatement* stmt) { void Visit(AssertStatement* stmt) {
bool do_check = !stmt->debug_only;
#if defined(DEBUG) #if defined(DEBUG)
DeclareExpressionForBranch(stmt->expression); do_check = true;
#endif #endif
if (do_check) DeclareExpressionForBranch(stmt->expression);
} }
void Visit(VarDeclarationStatement* stmt) { void Visit(VarDeclarationStatement* stmt) {
......
...@@ -692,46 +692,50 @@ const Type* ImplementationVisitor::Visit(DebugStatement* stmt) { ...@@ -692,46 +692,50 @@ const Type* ImplementationVisitor::Visit(DebugStatement* stmt) {
} }
const Type* ImplementationVisitor::Visit(AssertStatement* stmt) { const Type* ImplementationVisitor::Visit(AssertStatement* stmt) {
bool do_check = !stmt->debug_only;
#if defined(DEBUG) #if defined(DEBUG)
// CSA_ASSERT & co. are not used here on purpose for two reasons. First, do_check = true;
// Torque allows and handles two types of expressions in the if protocol #endif
// automagically, ones that return TNode<BoolT> and those that use the if (do_check) {
// BranchIf(..., Label* true, Label* false) idiom. Because the machinery to // CSA_ASSERT & co. are not used here on purpose for two reasons. First,
// handle this is embedded in the expression handling and to it's not possible // Torque allows and handles two types of expressions in the if protocol
// to make the decision to use CSA_ASSERT or CSA_ASSERT_BRANCH isn't trivial // automagically, ones that return TNode<BoolT> and those that use the
// up-front. Secondly, on failure, the assert text should be the corresponding // BranchIf(..., Label* true, Label* false) idiom. Because the machinery to
// Torque code, not the -gen.cc code, which would be the case when using // handle this is embedded in the expression handling and to it's not
// CSA_ASSERT_XXX. // possible to make the decision to use CSA_ASSERT or CSA_ASSERT_BRANCH
Label* true_label = nullptr; // isn't trivial up-front. Secondly, on failure, the assert text should be
Label* false_label = nullptr; // the corresponding Torque code, not the -gen.cc code, which would be the
Declarations::NodeScopeActivator scope(declarations(), stmt->expression); // case when using CSA_ASSERT_XXX.
true_label = declarations()->LookupLabel(kTrueLabelName); Label* true_label = nullptr;
GenerateLabelDefinition(true_label); Label* false_label = nullptr;
false_label = declarations()->LookupLabel(kFalseLabelName); Declarations::NodeScopeActivator scope(declarations(), stmt->expression);
GenerateLabelDefinition(false_label); true_label = declarations()->LookupLabel(kTrueLabelName);
GenerateLabelDefinition(true_label);
VisitResult expression_result = Visit(stmt->expression); false_label = declarations()->LookupLabel(kFalseLabelName);
if (expression_result.type() == GetTypeOracle().GetBoolType()) { GenerateLabelDefinition(false_label);
GenerateBranch(expression_result, true_label, false_label);
} else { VisitResult expression_result = Visit(stmt->expression);
if (expression_result.type() != GetTypeOracle().GetNeverType()) { if (expression_result.type() == GetTypeOracle().GetBoolType()) {
std::stringstream s; GenerateBranch(expression_result, true_label, false_label);
s << "unexpected return type " << expression_result.type() } else {
<< " for branch expression"; if (expression_result.type() != GetTypeOracle().GetNeverType()) {
ReportError(s.str()); std::stringstream s;
s << "unexpected return type " << expression_result.type()
<< " for branch expression";
ReportError(s.str());
}
} }
}
GenerateLabelBind(false_label); GenerateLabelBind(false_label);
GenerateIndent(); GenerateIndent();
source_out() << "Print(\"" source_out() << "Print(\""
<< "assert '" << stmt->source << "' failed at " << "assert '" << stmt->source << "' failed at "
<< PositionAsString(stmt->pos) << "\");" << std::endl; << PositionAsString(stmt->pos) << "\");" << std::endl;
GenerateIndent(); GenerateIndent();
source_out() << "Unreachable();" << std::endl; source_out() << "Unreachable();" << std::endl;
GenerateLabelBind(true_label); GenerateLabelBind(true_label);
#endif }
return GetTypeOracle().GetVoidType(); return GetTypeOracle().GetVoidType();
} }
......
...@@ -36,20 +36,20 @@ module test { ...@@ -36,20 +36,20 @@ module test {
} }
macro TestConstexpr1() { macro TestConstexpr1() {
assert(convert<bool>(IsFastElementsKind(PACKED_SMI_ELEMENTS))); check(convert<bool>(IsFastElementsKind(PACKED_SMI_ELEMENTS)));
} }
macro TestConstexprIf() { macro TestConstexprIf() {
assert(ElementsKindTestHelper1(UINT8_ELEMENTS)); check(ElementsKindTestHelper1(UINT8_ELEMENTS));
assert(ElementsKindTestHelper1(UINT16_ELEMENTS)); check(ElementsKindTestHelper1(UINT16_ELEMENTS));
assert(!ElementsKindTestHelper1(UINT32_ELEMENTS)); check(!ElementsKindTestHelper1(UINT32_ELEMENTS));
} }
macro TestConstexprReturn() { macro TestConstexprReturn() {
assert(convert<bool>(ElementsKindTestHelper3(UINT8_ELEMENTS))); check(convert<bool>(ElementsKindTestHelper3(UINT8_ELEMENTS)));
assert(convert<bool>(ElementsKindTestHelper3(UINT16_ELEMENTS))); check(convert<bool>(ElementsKindTestHelper3(UINT16_ELEMENTS)));
assert(!convert<bool>(ElementsKindTestHelper3(UINT32_ELEMENTS))); check(!convert<bool>(ElementsKindTestHelper3(UINT32_ELEMENTS)));
assert(convert<bool>(!ElementsKindTestHelper3(UINT32_ELEMENTS))); check(convert<bool>(!ElementsKindTestHelper3(UINT32_ELEMENTS)));
} }
macro TestGotoLabel(): Boolean { macro TestGotoLabel(): Boolean {
...@@ -66,7 +66,7 @@ module test { ...@@ -66,7 +66,7 @@ module test {
LabelTestHelper2() otherwise Label2; LabelTestHelper2() otherwise Label2;
} }
label Label2(smi: Smi) { label Label2(smi: Smi) {
assert(smi == 42); check(smi == 42);
return True; return True;
} }
} }
...@@ -76,8 +76,8 @@ module test { ...@@ -76,8 +76,8 @@ module test {
LabelTestHelper3() otherwise Label3; LabelTestHelper3() otherwise Label3;
} }
label Label3(str: String, smi: Smi) { label Label3(str: String, smi: Smi) {
assert(str == 'foo'); check(str == 'foo');
assert(smi == 7); check(smi == 7);
return True; return True;
} }
} }
...@@ -91,10 +91,10 @@ module test { ...@@ -91,10 +91,10 @@ module test {
} }
macro TestBuiltinSpecialization(c: Context) { macro TestBuiltinSpecialization(c: Context) {
assert(GenericBuiltinTest<Smi>(c, 0) == Null); check(GenericBuiltinTest<Smi>(c, 0) == Null);
assert(GenericBuiltinTest<Smi>(c, 1) == Null); check(GenericBuiltinTest<Smi>(c, 1) == Null);
assert(GenericBuiltinTest<Object>(c, Undefined) == Undefined); check(GenericBuiltinTest<Object>(c, Undefined) == Undefined);
assert(GenericBuiltinTest<Object>(c, Undefined) == Undefined); check(GenericBuiltinTest<Object>(c, Undefined) == Undefined);
} }
macro LabelTestHelper4(flag: constexpr bool): never labels Label4, Label5 { macro LabelTestHelper4(flag: constexpr bool): never labels Label4, Label5 {
...@@ -143,16 +143,15 @@ module test { ...@@ -143,16 +143,15 @@ module test {
macro TestMacroSpecialization() { macro TestMacroSpecialization() {
try { try {
if (True == False) goto Fail; // Silence warnings in release build check(GenericMacroTest<Smi>(0) == Undefined);
assert(GenericMacroTest<Smi>(0) == Undefined); check(GenericMacroTest<Smi>(1) == Undefined);
assert(GenericMacroTest<Smi>(1) == Undefined); check(GenericMacroTest<Object>(Null) == Null);
assert(GenericMacroTest<Object>(Null) == Null); check(GenericMacroTest<Object>(False) == False);
assert(GenericMacroTest<Object>(False) == False); check(GenericMacroTest<Object>(True) == True);
assert(GenericMacroTest<Object>(True) == True); check(GenericMacroTestWithLabels<Smi>(0) otherwise Fail == Undefined);
assert(GenericMacroTestWithLabels<Smi>(0) otherwise Fail == Undefined); check(GenericMacroTestWithLabels<Smi>(0) otherwise Fail == Undefined);
assert(GenericMacroTestWithLabels<Smi>(0) otherwise Fail == Undefined); check(GenericMacroTestWithLabels<Object>(Null) otherwise Fail == Null);
assert(GenericMacroTestWithLabels<Object>(Null) otherwise Fail == Null); check(GenericMacroTestWithLabels<Object>(False) otherwise Fail == False);
assert(GenericMacroTestWithLabels<Object>(False) otherwise Fail == False);
} }
label Fail { label Fail {
unreachable; unreachable;
...@@ -168,9 +167,9 @@ module test { ...@@ -168,9 +167,9 @@ module test {
macro TestFunctionPointers(context : Context) : Boolean { macro TestFunctionPointers(context : Context) : Boolean {
let fptr : builtin(Context, Smi) => Smi = TestHelperPlus1; let fptr : builtin(Context, Smi) => Smi = TestHelperPlus1;
assert(fptr(context, 42) == 43); check(fptr(context, 42) == 43);
fptr = TestHelperPlus2; fptr = TestHelperPlus2;
assert(fptr(context, 42) == 44); check(fptr(context, 42) == 44);
return True; return True;
} }
...@@ -184,10 +183,10 @@ module test { ...@@ -184,10 +183,10 @@ module test {
let fptr1: builtin(Context, Smi) => Object = GenericBuiltinTest<Smi>; let fptr1: builtin(Context, Smi) => Object = GenericBuiltinTest<Smi>;
let fptr2: builtin(Context, Object) => Object = GenericBuiltinTest<Object>; let fptr2: builtin(Context, Object) => Object = GenericBuiltinTest<Object>;
assert(fptr1(c, 0) == Null); check(fptr1(c, 0) == Null);
assert(fptr1(c, 1) == Null); check(fptr1(c, 1) == Null);
assert(fptr2(c, Undefined) == Undefined); check(fptr2(c, Undefined) == Undefined);
assert(fptr2(c, Undefined) == Undefined); check(fptr2(c, Undefined) == Undefined);
} }
type SmiToSmi = builtin(Smi) => Smi; type SmiToSmi = builtin(Smi) => Smi;
......
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