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