OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/asmjs/asm-typer.h" | 5 #include "src/asmjs/asm-typer.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 #include <string> | 8 #include <string> |
9 | 9 |
10 #include "src/v8.h" | 10 #include "src/v8.h" |
(...skipping 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1248 // No need to handle these here -- see the AsmTyper's definition. | 1248 // No need to handle these here -- see the AsmTyper's definition. |
1249 | 1249 |
1250 // 6.5.10 SwitchStatement | 1250 // 6.5.10 SwitchStatement |
1251 AsmType* AsmTyper::ValidateSwitchStatement(SwitchStatement* stmt) { | 1251 AsmType* AsmTyper::ValidateSwitchStatement(SwitchStatement* stmt) { |
1252 AsmType* cond_type; | 1252 AsmType* cond_type; |
1253 RECURSE(cond_type = ValidateExpression(stmt->tag())); | 1253 RECURSE(cond_type = ValidateExpression(stmt->tag())); |
1254 if (!cond_type->IsA(AsmType::Signed())) { | 1254 if (!cond_type->IsA(AsmType::Signed())) { |
1255 FAIL(stmt, "Switch tag must be signed."); | 1255 FAIL(stmt, "Switch tag must be signed."); |
1256 } | 1256 } |
1257 | 1257 |
1258 bool has_default = false; | 1258 int default_pos = kNoSourcePosition; |
1259 | 1259 int last_case_pos = kNoSourcePosition; |
1260 ZoneSet<int32_t> cases_seen(zone_); | 1260 ZoneSet<int32_t> cases_seen(zone_); |
1261 for (auto* a_case : *stmt->cases()) { | 1261 for (auto* a_case : *stmt->cases()) { |
1262 if (a_case->is_default()) { | 1262 if (a_case->is_default()) { |
1263 CHECK(!has_default); | 1263 CHECK(default_pos == kNoSourcePosition); |
1264 RECURSE(ValidateDefault(a_case)); | 1264 RECURSE(ValidateDefault(a_case)); |
1265 has_default = true; | 1265 default_pos = a_case->position(); |
1266 continue; | 1266 continue; |
1267 } | 1267 } |
1268 | 1268 |
| 1269 if (last_case_pos == kNoSourcePosition) { |
| 1270 last_case_pos = a_case->position(); |
| 1271 } else { |
| 1272 last_case_pos = std::max(last_case_pos, a_case->position()); |
| 1273 } |
| 1274 |
1269 int32_t case_lbl; | 1275 int32_t case_lbl; |
1270 RECURSE(ValidateCase(a_case, &case_lbl)); | 1276 RECURSE(ValidateCase(a_case, &case_lbl)); |
1271 auto case_lbl_pos = cases_seen.find(case_lbl); | 1277 auto case_lbl_pos = cases_seen.find(case_lbl); |
1272 if (case_lbl_pos != cases_seen.end() && *case_lbl_pos == case_lbl) { | 1278 if (case_lbl_pos != cases_seen.end() && *case_lbl_pos == case_lbl) { |
1273 FAIL(a_case, "Duplicated case label."); | 1279 FAIL(a_case, "Duplicated case label."); |
1274 } | 1280 } |
1275 cases_seen.insert(case_lbl); | 1281 cases_seen.insert(case_lbl); |
1276 } | 1282 } |
1277 | 1283 |
1278 if (!cases_seen.empty()) { | 1284 if (!cases_seen.empty()) { |
1279 const int64_t max_lbl = *cases_seen.rbegin(); | 1285 const int64_t max_lbl = *cases_seen.rbegin(); |
1280 const int64_t min_lbl = *cases_seen.begin(); | 1286 const int64_t min_lbl = *cases_seen.begin(); |
1281 if (max_lbl - min_lbl > std::numeric_limits<int32_t>::max()) { | 1287 if (max_lbl - min_lbl > std::numeric_limits<int32_t>::max()) { |
1282 FAIL(stmt, "Out-of-bounds case label range."); | 1288 FAIL(stmt, "Out-of-bounds case label range."); |
1283 } | 1289 } |
1284 } | 1290 } |
1285 | 1291 |
| 1292 if (last_case_pos != kNoSourcePosition && default_pos != kNoSourcePosition && |
| 1293 default_pos < last_case_pos) { |
| 1294 FAIL(stmt, "Switch default must appear last."); |
| 1295 } |
| 1296 |
1286 return AsmType::Void(); | 1297 return AsmType::Void(); |
1287 } | 1298 } |
1288 | 1299 |
1289 // 6.6 ValidateCase | 1300 // 6.6 ValidateCase |
1290 namespace { | 1301 namespace { |
1291 bool ExtractInt32CaseLabel(CaseClause* clause, int32_t* lbl) { | 1302 bool ExtractInt32CaseLabel(CaseClause* clause, int32_t* lbl) { |
1292 auto* lbl_expr = clause->label()->AsLiteral(); | 1303 auto* lbl_expr = clause->label()->AsLiteral(); |
1293 | 1304 |
1294 if (lbl_expr == nullptr) { | 1305 if (lbl_expr == nullptr) { |
1295 return false; | 1306 return false; |
(...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2635 return true; | 2646 return true; |
2636 } | 2647 } |
2637 | 2648 |
2638 *error_message = typer.error_message(); | 2649 *error_message = typer.error_message(); |
2639 return false; | 2650 return false; |
2640 } | 2651 } |
2641 | 2652 |
2642 } // namespace wasm | 2653 } // namespace wasm |
2643 } // namespace internal | 2654 } // namespace internal |
2644 } // namespace v8 | 2655 } // namespace v8 |
OLD | NEW |