Index: test/unittests/asmjs/asm-scanner-unittest.cc |
diff --git a/test/unittests/asmjs/asm-scanner-unittest.cc b/test/unittests/asmjs/asm-scanner-unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9924244ec754ab7f73390b011cfc3c4c72eebac1 |
--- /dev/null |
+++ b/test/unittests/asmjs/asm-scanner-unittest.cc |
@@ -0,0 +1,290 @@ |
+// Copyright 2017 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 "src/asmjs/asm-scanner.h" |
+#include "src/objects.h" |
+#include "src/parsing/scanner-character-streams.h" |
+#include "src/parsing/scanner.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace v8 { |
+namespace internal { |
+ |
+#define TOK(t) AsmJsScanner::kToken_##t |
+ |
+class AsmJsScannerTest : public ::testing::Test { |
+ protected: |
+ void SetupSource(const char* source) { |
+ scanner.SetStream(ScannerStream::ForTesting(source)); |
+ } |
+ |
+ void Skip(AsmJsScanner::token_t t) { |
+ CHECK_EQ(t, scanner.Token()); |
+ scanner.Next(); |
+ } |
+ |
+ void SkipGlobal() { |
+ CHECK(scanner.IsGlobal()); |
+ scanner.Next(); |
+ } |
+ |
+ void SkipLocal() { |
+ CHECK(scanner.IsLocal()); |
+ scanner.Next(); |
+ } |
+ |
+ void CheckForEnd() { CHECK(scanner.Token() == AsmJsScanner::kEndOfInput); } |
+ |
+ void CheckForParseError() { |
+ CHECK(scanner.Token() == AsmJsScanner::kParseError); |
+ } |
+ |
+ AsmJsScanner scanner; |
+}; |
+ |
+TEST_F(AsmJsScannerTest, SimpleFunction) { |
+ SetupSource("function foo() { return; }"); |
+ Skip(TOK(function)); |
+ DCHECK_EQ("foo", scanner.GetIdentifierString()); |
+ SkipGlobal(); |
+ Skip('('); |
+ Skip(')'); |
+ Skip('{'); |
+ // clang-format off |
+ Skip(TOK(return)); |
+ // clang-format on |
+ Skip(';'); |
+ Skip('}'); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, JSKeywords) { |
+ SetupSource( |
+ "arguments break case const continue\n" |
+ "default do else eval for function\n" |
+ "if new return switch var while\n"); |
+ Skip(TOK(arguments)); |
+ Skip(TOK(break)); |
+ Skip(TOK(case)); |
+ Skip(TOK(const)); |
+ Skip(TOK(continue)); |
+ Skip(TOK(default)); |
+ Skip(TOK(do)); |
+ Skip(TOK(else)); |
+ Skip(TOK(eval)); |
+ Skip(TOK(for)); |
+ Skip(TOK(function)); |
+ Skip(TOK(if)); |
+ Skip(TOK(new)); |
+ // clang-format off |
+ Skip(TOK(return)); |
+ // clang-format on |
+ Skip(TOK(switch)); |
+ Skip(TOK(var)); |
+ Skip(TOK(while)); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, JSOperatorsSpread) { |
+ SetupSource( |
+ "+ - * / % & | ^ ~ << >> >>>\n" |
+ "< > <= >= == !=\n"); |
+ Skip('+'); |
+ Skip('-'); |
+ Skip('*'); |
+ Skip('/'); |
+ Skip('%'); |
+ Skip('&'); |
+ Skip('|'); |
+ Skip('^'); |
+ Skip('~'); |
+ Skip(TOK(SHL)); |
+ Skip(TOK(SAR)); |
+ Skip(TOK(SHR)); |
+ Skip('<'); |
+ Skip('>'); |
+ Skip(TOK(LE)); |
+ Skip(TOK(GE)); |
+ Skip(TOK(EQ)); |
+ Skip(TOK(NE)); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, JSOperatorsTight) { |
+ SetupSource( |
+ "+-*/%&|^~<<>> >>>\n" |
+ "<><=>= ==!=\n"); |
+ Skip('+'); |
+ Skip('-'); |
+ Skip('*'); |
+ Skip('/'); |
+ Skip('%'); |
+ Skip('&'); |
+ Skip('|'); |
+ Skip('^'); |
+ Skip('~'); |
+ Skip(TOK(SHL)); |
+ Skip(TOK(SAR)); |
+ Skip(TOK(SHR)); |
+ Skip('<'); |
+ Skip('>'); |
+ Skip(TOK(LE)); |
+ Skip(TOK(GE)); |
+ Skip(TOK(EQ)); |
+ Skip(TOK(NE)); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, UsesOfAsm) { |
+ SetupSource("'use asm' \"use asm\"\n"); |
+ Skip(TOK(UseAsm)); |
+ Skip(TOK(UseAsm)); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, DefaultGlobalScope) { |
+ SetupSource("var x = x + x;"); |
+ Skip(TOK(var)); |
+ CHECK_EQ("x", scanner.GetIdentifierString()); |
+ AsmJsScanner::token_t x = scanner.Token(); |
+ SkipGlobal(); |
+ Skip('='); |
+ Skip(x); |
+ Skip('+'); |
+ Skip(x); |
+ Skip(';'); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, GlobalScope) { |
+ SetupSource("var x = x + x;"); |
+ scanner.EnterGlobalScope(); |
+ Skip(TOK(var)); |
+ CHECK_EQ("x", scanner.GetIdentifierString()); |
+ AsmJsScanner::token_t x = scanner.Token(); |
+ SkipGlobal(); |
+ Skip('='); |
+ Skip(x); |
+ Skip('+'); |
+ Skip(x); |
+ Skip(';'); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, LocalScope) { |
+ SetupSource("var x = x + x;"); |
+ scanner.EnterLocalScope(); |
+ Skip(TOK(var)); |
+ CHECK_EQ("x", scanner.GetIdentifierString()); |
+ AsmJsScanner::token_t x = scanner.Token(); |
+ SkipLocal(); |
+ Skip('='); |
+ Skip(x); |
+ Skip('+'); |
+ Skip(x); |
+ Skip(';'); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, Numbers) { |
+ SetupSource("1 1.2 0x1f 1.e3"); |
+ |
+ CHECK(scanner.IsUnsigned()); |
+ CHECK_EQ(1, scanner.AsUnsigned()); |
+ scanner.Next(); |
+ |
+ CHECK(scanner.IsDouble()); |
+ CHECK_EQ(1.2, scanner.AsDouble()); |
+ scanner.Next(); |
+ |
+ CHECK(scanner.IsUnsigned()); |
+ CHECK_EQ(31, scanner.AsUnsigned()); |
+ scanner.Next(); |
+ |
+ CHECK(scanner.IsDouble()); |
+ CHECK_EQ(1.0e3, scanner.AsDouble()); |
+ scanner.Next(); |
+ |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, BadNumber) { |
+ SetupSource(".123fe"); |
+ Skip('.'); |
+ CheckForParseError(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, Rewind1) { |
+ SetupSource("+ - * /"); |
+ Skip('+'); |
+ scanner.Rewind(); |
+ Skip('+'); |
+ Skip('-'); |
+ scanner.Rewind(); |
+ Skip('-'); |
+ Skip('*'); |
+ scanner.Rewind(); |
+ Skip('*'); |
+ Skip('/'); |
+ scanner.Rewind(); |
+ Skip('/'); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, Comments) { |
+ SetupSource( |
+ "var // This is a test /* */ eval\n" |
+ "var /* test *** test */ eval\n" |
+ "function /* this */ ^"); |
+ Skip(TOK(var)); |
+ Skip(TOK(var)); |
+ Skip(TOK(eval)); |
+ Skip(TOK(function)); |
+ Skip('^'); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, TrailingCComment) { |
+ SetupSource("var /* test\n"); |
+ Skip(TOK(var)); |
+ CheckForParseError(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, Seeking) { |
+ SetupSource("var eval do arguments function break\n"); |
+ Skip(TOK(var)); |
+ int old_pos = scanner.GetPosition(); |
+ Skip(TOK(eval)); |
+ Skip(TOK(do)); |
+ Skip(TOK(arguments)); |
+ scanner.Rewind(); |
+ Skip(TOK(arguments)); |
+ scanner.Rewind(); |
+ scanner.Seek(old_pos); |
+ Skip(TOK(do)); |
+ Skip(TOK(arguments)); |
+ Skip(TOK(function)); |
+ Skip(TOK(break)); |
+ CheckForEnd(); |
+} |
+ |
+TEST_F(AsmJsScannerTest, Newlines) { |
+ SetupSource( |
+ "var x = 1\n" |
+ "var y = 2\n"); |
+ Skip(TOK(var)); |
+ scanner.Next(); |
+ Skip('='); |
+ scanner.Next(); |
+ CHECK(scanner.IsPrecededByNewline()); |
+ Skip(TOK(var)); |
+ scanner.Next(); |
+ Skip('='); |
+ scanner.Next(); |
+ CHECK(scanner.IsPrecededByNewline()); |
+ CheckForEnd(); |
+} |
+ |
+} // namespace internal |
+} // namespace v8 |