OLD | NEW |
(Empty) | |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/asmjs/asm-scanner.h" |
| 6 #include "src/objects.h" |
| 7 #include "src/parsing/scanner-character-streams.h" |
| 8 #include "src/parsing/scanner.h" |
| 9 #include "testing/gtest/include/gtest/gtest.h" |
| 10 |
| 11 namespace v8 { |
| 12 namespace internal { |
| 13 |
| 14 #define TOK(t) AsmJsScanner::kToken_##t |
| 15 |
| 16 class AsmJsScannerTest : public ::testing::Test { |
| 17 protected: |
| 18 void SetupSource(const char* source) { |
| 19 scanner.SetStream(ScannerStream::ForTesting(source)); |
| 20 } |
| 21 |
| 22 void Skip(AsmJsScanner::token_t t) { |
| 23 CHECK_EQ(t, scanner.Token()); |
| 24 scanner.Next(); |
| 25 } |
| 26 |
| 27 void SkipGlobal() { |
| 28 CHECK(scanner.IsGlobal()); |
| 29 scanner.Next(); |
| 30 } |
| 31 |
| 32 void SkipLocal() { |
| 33 CHECK(scanner.IsLocal()); |
| 34 scanner.Next(); |
| 35 } |
| 36 |
| 37 void CheckForEnd() { CHECK(scanner.Token() == AsmJsScanner::kEndOfInput); } |
| 38 |
| 39 void CheckForParseError() { |
| 40 CHECK(scanner.Token() == AsmJsScanner::kParseError); |
| 41 } |
| 42 |
| 43 AsmJsScanner scanner; |
| 44 }; |
| 45 |
| 46 TEST_F(AsmJsScannerTest, SimpleFunction) { |
| 47 SetupSource("function foo() { return; }"); |
| 48 Skip(TOK(function)); |
| 49 DCHECK_EQ("foo", scanner.GetIdentifierString()); |
| 50 SkipGlobal(); |
| 51 Skip('('); |
| 52 Skip(')'); |
| 53 Skip('{'); |
| 54 // clang-format off |
| 55 Skip(TOK(return)); |
| 56 // clang-format on |
| 57 Skip(';'); |
| 58 Skip('}'); |
| 59 CheckForEnd(); |
| 60 } |
| 61 |
| 62 TEST_F(AsmJsScannerTest, JSKeywords) { |
| 63 SetupSource( |
| 64 "arguments break case const continue\n" |
| 65 "default do else eval for function\n" |
| 66 "if new return switch var while\n"); |
| 67 Skip(TOK(arguments)); |
| 68 Skip(TOK(break)); |
| 69 Skip(TOK(case)); |
| 70 Skip(TOK(const)); |
| 71 Skip(TOK(continue)); |
| 72 Skip(TOK(default)); |
| 73 Skip(TOK(do)); |
| 74 Skip(TOK(else)); |
| 75 Skip(TOK(eval)); |
| 76 Skip(TOK(for)); |
| 77 Skip(TOK(function)); |
| 78 Skip(TOK(if)); |
| 79 Skip(TOK(new)); |
| 80 // clang-format off |
| 81 Skip(TOK(return)); |
| 82 // clang-format on |
| 83 Skip(TOK(switch)); |
| 84 Skip(TOK(var)); |
| 85 Skip(TOK(while)); |
| 86 CheckForEnd(); |
| 87 } |
| 88 |
| 89 TEST_F(AsmJsScannerTest, JSOperatorsSpread) { |
| 90 SetupSource( |
| 91 "+ - * / % & | ^ ~ << >> >>>\n" |
| 92 "< > <= >= == !=\n"); |
| 93 Skip('+'); |
| 94 Skip('-'); |
| 95 Skip('*'); |
| 96 Skip('/'); |
| 97 Skip('%'); |
| 98 Skip('&'); |
| 99 Skip('|'); |
| 100 Skip('^'); |
| 101 Skip('~'); |
| 102 Skip(TOK(SHL)); |
| 103 Skip(TOK(SAR)); |
| 104 Skip(TOK(SHR)); |
| 105 Skip('<'); |
| 106 Skip('>'); |
| 107 Skip(TOK(LE)); |
| 108 Skip(TOK(GE)); |
| 109 Skip(TOK(EQ)); |
| 110 Skip(TOK(NE)); |
| 111 CheckForEnd(); |
| 112 } |
| 113 |
| 114 TEST_F(AsmJsScannerTest, JSOperatorsTight) { |
| 115 SetupSource( |
| 116 "+-*/%&|^~<<>> >>>\n" |
| 117 "<><=>= ==!=\n"); |
| 118 Skip('+'); |
| 119 Skip('-'); |
| 120 Skip('*'); |
| 121 Skip('/'); |
| 122 Skip('%'); |
| 123 Skip('&'); |
| 124 Skip('|'); |
| 125 Skip('^'); |
| 126 Skip('~'); |
| 127 Skip(TOK(SHL)); |
| 128 Skip(TOK(SAR)); |
| 129 Skip(TOK(SHR)); |
| 130 Skip('<'); |
| 131 Skip('>'); |
| 132 Skip(TOK(LE)); |
| 133 Skip(TOK(GE)); |
| 134 Skip(TOK(EQ)); |
| 135 Skip(TOK(NE)); |
| 136 CheckForEnd(); |
| 137 } |
| 138 |
| 139 TEST_F(AsmJsScannerTest, UsesOfAsm) { |
| 140 SetupSource("'use asm' \"use asm\"\n"); |
| 141 Skip(TOK(UseAsm)); |
| 142 Skip(TOK(UseAsm)); |
| 143 CheckForEnd(); |
| 144 } |
| 145 |
| 146 TEST_F(AsmJsScannerTest, DefaultGlobalScope) { |
| 147 SetupSource("var x = x + x;"); |
| 148 Skip(TOK(var)); |
| 149 CHECK_EQ("x", scanner.GetIdentifierString()); |
| 150 AsmJsScanner::token_t x = scanner.Token(); |
| 151 SkipGlobal(); |
| 152 Skip('='); |
| 153 Skip(x); |
| 154 Skip('+'); |
| 155 Skip(x); |
| 156 Skip(';'); |
| 157 CheckForEnd(); |
| 158 } |
| 159 |
| 160 TEST_F(AsmJsScannerTest, GlobalScope) { |
| 161 SetupSource("var x = x + x;"); |
| 162 scanner.EnterGlobalScope(); |
| 163 Skip(TOK(var)); |
| 164 CHECK_EQ("x", scanner.GetIdentifierString()); |
| 165 AsmJsScanner::token_t x = scanner.Token(); |
| 166 SkipGlobal(); |
| 167 Skip('='); |
| 168 Skip(x); |
| 169 Skip('+'); |
| 170 Skip(x); |
| 171 Skip(';'); |
| 172 CheckForEnd(); |
| 173 } |
| 174 |
| 175 TEST_F(AsmJsScannerTest, LocalScope) { |
| 176 SetupSource("var x = x + x;"); |
| 177 scanner.EnterLocalScope(); |
| 178 Skip(TOK(var)); |
| 179 CHECK_EQ("x", scanner.GetIdentifierString()); |
| 180 AsmJsScanner::token_t x = scanner.Token(); |
| 181 SkipLocal(); |
| 182 Skip('='); |
| 183 Skip(x); |
| 184 Skip('+'); |
| 185 Skip(x); |
| 186 Skip(';'); |
| 187 CheckForEnd(); |
| 188 } |
| 189 |
| 190 TEST_F(AsmJsScannerTest, Numbers) { |
| 191 SetupSource("1 1.2 0x1f 1.e3"); |
| 192 |
| 193 CHECK(scanner.IsUnsigned()); |
| 194 CHECK_EQ(1, scanner.AsUnsigned()); |
| 195 scanner.Next(); |
| 196 |
| 197 CHECK(scanner.IsDouble()); |
| 198 CHECK_EQ(1.2, scanner.AsDouble()); |
| 199 scanner.Next(); |
| 200 |
| 201 CHECK(scanner.IsUnsigned()); |
| 202 CHECK_EQ(31, scanner.AsUnsigned()); |
| 203 scanner.Next(); |
| 204 |
| 205 CHECK(scanner.IsDouble()); |
| 206 CHECK_EQ(1.0e3, scanner.AsDouble()); |
| 207 scanner.Next(); |
| 208 |
| 209 CheckForEnd(); |
| 210 } |
| 211 |
| 212 TEST_F(AsmJsScannerTest, BadNumber) { |
| 213 SetupSource(".123fe"); |
| 214 Skip('.'); |
| 215 CheckForParseError(); |
| 216 } |
| 217 |
| 218 TEST_F(AsmJsScannerTest, Rewind1) { |
| 219 SetupSource("+ - * /"); |
| 220 Skip('+'); |
| 221 scanner.Rewind(); |
| 222 Skip('+'); |
| 223 Skip('-'); |
| 224 scanner.Rewind(); |
| 225 Skip('-'); |
| 226 Skip('*'); |
| 227 scanner.Rewind(); |
| 228 Skip('*'); |
| 229 Skip('/'); |
| 230 scanner.Rewind(); |
| 231 Skip('/'); |
| 232 CheckForEnd(); |
| 233 } |
| 234 |
| 235 TEST_F(AsmJsScannerTest, Comments) { |
| 236 SetupSource( |
| 237 "var // This is a test /* */ eval\n" |
| 238 "var /* test *** test */ eval\n" |
| 239 "function /* this */ ^"); |
| 240 Skip(TOK(var)); |
| 241 Skip(TOK(var)); |
| 242 Skip(TOK(eval)); |
| 243 Skip(TOK(function)); |
| 244 Skip('^'); |
| 245 CheckForEnd(); |
| 246 } |
| 247 |
| 248 TEST_F(AsmJsScannerTest, TrailingCComment) { |
| 249 SetupSource("var /* test\n"); |
| 250 Skip(TOK(var)); |
| 251 CheckForParseError(); |
| 252 } |
| 253 |
| 254 TEST_F(AsmJsScannerTest, Seeking) { |
| 255 SetupSource("var eval do arguments function break\n"); |
| 256 Skip(TOK(var)); |
| 257 int old_pos = scanner.GetPosition(); |
| 258 Skip(TOK(eval)); |
| 259 Skip(TOK(do)); |
| 260 Skip(TOK(arguments)); |
| 261 scanner.Rewind(); |
| 262 Skip(TOK(arguments)); |
| 263 scanner.Rewind(); |
| 264 scanner.Seek(old_pos); |
| 265 Skip(TOK(do)); |
| 266 Skip(TOK(arguments)); |
| 267 Skip(TOK(function)); |
| 268 Skip(TOK(break)); |
| 269 CheckForEnd(); |
| 270 } |
| 271 |
| 272 TEST_F(AsmJsScannerTest, Newlines) { |
| 273 SetupSource( |
| 274 "var x = 1\n" |
| 275 "var y = 2\n"); |
| 276 Skip(TOK(var)); |
| 277 scanner.Next(); |
| 278 Skip('='); |
| 279 scanner.Next(); |
| 280 CHECK(scanner.IsPrecededByNewline()); |
| 281 Skip(TOK(var)); |
| 282 scanner.Next(); |
| 283 Skip('='); |
| 284 scanner.Next(); |
| 285 CHECK(scanner.IsPrecededByNewline()); |
| 286 CheckForEnd(); |
| 287 } |
| 288 |
| 289 } // namespace internal |
| 290 } // namespace v8 |
OLD | NEW |