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