OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
| 5 #include "src/typing-asm.h" |
| 6 |
| 7 #include <limits> |
| 8 |
5 #include "src/v8.h" | 9 #include "src/v8.h" |
6 | 10 |
7 #include "src/typing-asm.h" | |
8 | |
9 #include "src/ast/ast.h" | 11 #include "src/ast/ast.h" |
10 #include "src/ast/scopes.h" | 12 #include "src/ast/scopes.h" |
11 #include "src/codegen.h" | 13 #include "src/codegen.h" |
12 #include "src/type-cache.h" | 14 #include "src/type-cache.h" |
13 | 15 |
14 namespace v8 { | 16 namespace v8 { |
15 namespace internal { | 17 namespace internal { |
16 | 18 |
17 #define FAIL(node, msg) \ | 19 #define FAIL(node, msg) \ |
18 do { \ | 20 do { \ |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 } | 381 } |
380 | 382 |
381 | 383 |
382 void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) { | 384 void AsmTyper::VisitSwitchStatement(SwitchStatement* stmt) { |
383 if (!in_function_) { | 385 if (!in_function_) { |
384 FAIL(stmt, "switch statement inside module body"); | 386 FAIL(stmt, "switch statement inside module body"); |
385 } | 387 } |
386 RECURSE(VisitWithExpectation(stmt->tag(), cache_.kAsmSigned, | 388 RECURSE(VisitWithExpectation(stmt->tag(), cache_.kAsmSigned, |
387 "switch expression non-integer")); | 389 "switch expression non-integer")); |
388 ZoneList<CaseClause*>* clauses = stmt->cases(); | 390 ZoneList<CaseClause*>* clauses = stmt->cases(); |
| 391 ZoneSet<int32_t> cases(zone()); |
389 for (int i = 0; i < clauses->length(); ++i) { | 392 for (int i = 0; i < clauses->length(); ++i) { |
390 CaseClause* clause = clauses->at(i); | 393 CaseClause* clause = clauses->at(i); |
391 if (!clause->is_default()) { | 394 if (clause->is_default()) { |
| 395 if (i != clauses->length() - 1) { |
| 396 FAIL(clause, "default case out of order"); |
| 397 } |
| 398 } else { |
392 Expression* label = clause->label(); | 399 Expression* label = clause->label(); |
393 RECURSE(VisitWithExpectation(label, cache_.kAsmSigned, | 400 RECURSE(VisitWithExpectation(label, cache_.kAsmSigned, |
394 "case label non-integer")); | 401 "case label non-integer")); |
395 if (!label->IsLiteral()) FAIL(label, "non-literal case label"); | 402 if (!label->IsLiteral()) FAIL(label, "non-literal case label"); |
396 Handle<Object> value = label->AsLiteral()->value(); | 403 Handle<Object> value = label->AsLiteral()->value(); |
397 int32_t value32; | 404 int32_t value32; |
398 if (!value->ToInt32(&value32)) FAIL(label, "illegal case label value"); | 405 if (!value->ToInt32(&value32)) FAIL(label, "illegal case label value"); |
| 406 if (cases.find(value32) != cases.end()) { |
| 407 FAIL(label, "duplicate case value"); |
| 408 } |
| 409 cases.insert(value32); |
399 } | 410 } |
400 // TODO(bradnelson): Detect duplicates. | 411 // TODO(bradnelson): Detect duplicates. |
401 ZoneList<Statement*>* stmts = clause->statements(); | 412 ZoneList<Statement*>* stmts = clause->statements(); |
402 RECURSE(VisitStatements(stmts)); | 413 RECURSE(VisitStatements(stmts)); |
403 } | 414 } |
| 415 if (cases.size() > 0) { |
| 416 int64_t min_case = *cases.begin(); |
| 417 int64_t max_case = *cases.rbegin(); |
| 418 if (max_case - min_case > std::numeric_limits<int32_t>::max()) { |
| 419 FAIL(stmt, "case range too large"); |
| 420 } |
| 421 } |
404 } | 422 } |
405 | 423 |
406 | 424 |
407 void AsmTyper::VisitCaseClause(CaseClause* clause) { UNREACHABLE(); } | 425 void AsmTyper::VisitCaseClause(CaseClause* clause) { UNREACHABLE(); } |
408 | 426 |
409 | 427 |
410 void AsmTyper::VisitDoWhileStatement(DoWhileStatement* stmt) { | 428 void AsmTyper::VisitDoWhileStatement(DoWhileStatement* stmt) { |
411 if (!in_function_) { | 429 if (!in_function_) { |
412 FAIL(stmt, "do statement inside module body"); | 430 FAIL(stmt, "do statement inside module body"); |
413 } | 431 } |
(...skipping 1051 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1465 | 1483 |
1466 | 1484 |
1467 void AsmTyper::VisitRewritableAssignmentExpression( | 1485 void AsmTyper::VisitRewritableAssignmentExpression( |
1468 RewritableAssignmentExpression* expr) { | 1486 RewritableAssignmentExpression* expr) { |
1469 RECURSE(Visit(expr->expression())); | 1487 RECURSE(Visit(expr->expression())); |
1470 } | 1488 } |
1471 | 1489 |
1472 | 1490 |
1473 } // namespace internal | 1491 } // namespace internal |
1474 } // namespace v8 | 1492 } // namespace v8 |
OLD | NEW |