| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 continue; | 85 continue; |
| 86 } | 86 } |
| 87 | 87 |
| 88 return current_statement; | 88 return current_statement; |
| 89 } | 89 } |
| 90 } | 90 } |
| 91 | 91 |
| 92 // ---------------------------------------------------------------------------- | 92 // ---------------------------------------------------------------------------- |
| 93 // Implementation of AsmTyper::VariableInfo | 93 // Implementation of AsmTyper::VariableInfo |
| 94 | 94 |
| 95 AsmTyper::VariableInfo* AsmTyper::VariableInfo::ForSpecialSymbol( |
| 96 Zone* zone, StandardMember standard_member) { |
| 97 DCHECK(standard_member == kStdlib || standard_member == kFFI || |
| 98 standard_member == kHeap || standard_member == kModule); |
| 99 auto* new_var_info = new (zone) VariableInfo(AsmType::None()); |
| 100 new_var_info->standard_member_ = standard_member; |
| 101 new_var_info->mutability_ = kImmutableGlobal; |
| 102 return new_var_info; |
| 103 } |
| 104 |
| 95 AsmTyper::VariableInfo* AsmTyper::VariableInfo::Clone(Zone* zone) const { | 105 AsmTyper::VariableInfo* AsmTyper::VariableInfo::Clone(Zone* zone) const { |
| 96 CHECK(standard_member_ != kNone); | 106 CHECK(standard_member_ != kNone); |
| 107 CHECK(!type_->IsA(AsmType::None())); |
| 97 auto* new_var_info = new (zone) VariableInfo(type_); | 108 auto* new_var_info = new (zone) VariableInfo(type_); |
| 98 new_var_info->standard_member_ = standard_member_; | 109 new_var_info->standard_member_ = standard_member_; |
| 99 new_var_info->mutability_ = mutability_; | 110 new_var_info->mutability_ = mutability_; |
| 100 return new_var_info; | 111 return new_var_info; |
| 101 } | 112 } |
| 102 | 113 |
| 103 void AsmTyper::VariableInfo::FirstForwardUseIs(VariableProxy* var) { | 114 void AsmTyper::VariableInfo::FirstForwardUseIs(VariableProxy* var) { |
| 104 DCHECK(first_forward_use_ == nullptr); | 115 DCHECK(first_forward_use_ == nullptr); |
| 105 missing_definition_ = true; | 116 missing_definition_ = true; |
| 106 first_forward_use_ = var; | 117 first_forward_use_ = var; |
| 107 } | 118 } |
| 108 | 119 |
| 109 // ---------------------------------------------------------------------------- | 120 // ---------------------------------------------------------------------------- |
| 110 // Implementation of AsmTyper | 121 // Implementation of AsmTyper |
| 111 | 122 |
| 112 AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script, | 123 AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Script* script, |
| 113 FunctionLiteral* root) | 124 FunctionLiteral* root) |
| 114 : isolate_(isolate), | 125 : isolate_(isolate), |
| 115 zone_(zone), | 126 zone_(zone), |
| 116 script_(script), | 127 script_(script), |
| 117 root_(root), | 128 root_(root), |
| 118 forward_definitions_(zone), | 129 forward_definitions_(zone), |
| 119 stdlib_types_(zone), | 130 stdlib_types_(zone), |
| 120 stdlib_math_types_(zone), | 131 stdlib_math_types_(zone), |
| 132 module_info_(VariableInfo::ForSpecialSymbol(zone_, kModule)), |
| 121 global_scope_(ZoneHashMap::PointersMatch, | 133 global_scope_(ZoneHashMap::PointersMatch, |
| 122 ZoneHashMap::kDefaultHashMapCapacity, | 134 ZoneHashMap::kDefaultHashMapCapacity, |
| 123 ZoneAllocationPolicy(zone)), | 135 ZoneAllocationPolicy(zone)), |
| 124 local_scope_(ZoneHashMap::PointersMatch, | 136 local_scope_(ZoneHashMap::PointersMatch, |
| 125 ZoneHashMap::kDefaultHashMapCapacity, | 137 ZoneHashMap::kDefaultHashMapCapacity, |
| 126 ZoneAllocationPolicy(zone)), | 138 ZoneAllocationPolicy(zone)), |
| 127 stack_limit_(isolate->stack_guard()->real_climit()), | 139 stack_limit_(isolate->stack_guard()->real_climit()), |
| 128 node_types_(zone_), | 140 node_types_(zone_), |
| 129 fround_type_(AsmType::FroundType(zone_)) { | 141 fround_type_(AsmType::FroundType(zone_)), |
| 142 ffi_type_(AsmType::FFIType(zone_)) { |
| 130 InitializeStdlib(); | 143 InitializeStdlib(); |
| 131 module_info_.set_standard_member(kModule); | |
| 132 } | 144 } |
| 133 | 145 |
| 134 namespace { | 146 namespace { |
| 135 bool ValidAsmIdentifier(Handle<String> name) { | 147 bool ValidAsmIdentifier(Handle<String> name) { |
| 136 static const char* kInvalidAsmNames[] = {"eval", "arguments"}; | 148 static const char* kInvalidAsmNames[] = {"eval", "arguments"}; |
| 137 | 149 |
| 138 for (size_t ii = 0; ii < arraysize(kInvalidAsmNames); ++ii) { | 150 for (size_t ii = 0; ii < arraysize(kInvalidAsmNames); ++ii) { |
| 139 if (strcmp(name->ToCString().get(), kInvalidAsmNames[ii]) == 0) { | 151 if (strcmp(name->ToCString().get(), kInvalidAsmNames[ii]) == 0) { |
| 140 return false; | 152 return false; |
| 141 } | 153 } |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 AsmTyper::VariableInfo* AsmTyper::Lookup(Variable* variable) { | 323 AsmTyper::VariableInfo* AsmTyper::Lookup(Variable* variable) { |
| 312 ZoneHashMap* scope = in_function_ ? &local_scope_ : &global_scope_; | 324 ZoneHashMap* scope = in_function_ ? &local_scope_ : &global_scope_; |
| 313 ZoneHashMap::Entry* entry = | 325 ZoneHashMap::Entry* entry = |
| 314 scope->Lookup(variable, ComputePointerHash(variable)); | 326 scope->Lookup(variable, ComputePointerHash(variable)); |
| 315 if (entry == nullptr && in_function_) { | 327 if (entry == nullptr && in_function_) { |
| 316 entry = global_scope_.Lookup(variable, ComputePointerHash(variable)); | 328 entry = global_scope_.Lookup(variable, ComputePointerHash(variable)); |
| 317 } | 329 } |
| 318 | 330 |
| 319 if (entry == nullptr && !module_name_.is_null() && | 331 if (entry == nullptr && !module_name_.is_null() && |
| 320 module_name_->Equals(*variable->name())) { | 332 module_name_->Equals(*variable->name())) { |
| 321 return &module_info_; | 333 return module_info_; |
| 322 } | 334 } |
| 323 | 335 |
| 324 return entry ? reinterpret_cast<VariableInfo*>(entry->value) : nullptr; | 336 return entry ? reinterpret_cast<VariableInfo*>(entry->value) : nullptr; |
| 325 } | 337 } |
| 326 | 338 |
| 327 void AsmTyper::AddForwardReference(VariableProxy* proxy, VariableInfo* info) { | 339 void AsmTyper::AddForwardReference(VariableProxy* proxy, VariableInfo* info) { |
| 328 info->FirstForwardUseIs(proxy); | 340 info->FirstForwardUseIs(proxy); |
| 329 forward_definitions_.push_back(info); | 341 forward_definitions_.push_back(info); |
| 330 } | 342 } |
| 331 | 343 |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 module_name_ = fun->name(); | 474 module_name_ = fun->name(); |
| 463 | 475 |
| 464 // Allowed parameters: Stdlib, FFI, Mem | 476 // Allowed parameters: Stdlib, FFI, Mem |
| 465 static const uint32_t MaxModuleParameters = 3; | 477 static const uint32_t MaxModuleParameters = 3; |
| 466 if (scope->num_parameters() > MaxModuleParameters) { | 478 if (scope->num_parameters() > MaxModuleParameters) { |
| 467 FAIL(fun, "asm.js modules may not have more than three parameters."); | 479 FAIL(fun, "asm.js modules may not have more than three parameters."); |
| 468 } | 480 } |
| 469 | 481 |
| 470 struct { | 482 struct { |
| 471 StandardMember standard_member; | 483 StandardMember standard_member; |
| 472 AsmType* type; | |
| 473 } kModuleParamInfo[3] = { | 484 } kModuleParamInfo[3] = { |
| 474 {kStdlib, AsmType::None()}, | 485 {kStdlib}, {kFFI}, {kHeap}, |
| 475 {kFFI, AsmType::FFIType(zone_)}, | |
| 476 {kHeap, AsmType::None()}, | |
| 477 }; | 486 }; |
| 478 | 487 |
| 479 for (int ii = 0; ii < scope->num_parameters(); ++ii) { | 488 for (int ii = 0; ii < scope->num_parameters(); ++ii) { |
| 480 Variable* param = scope->parameter(ii); | 489 Variable* param = scope->parameter(ii); |
| 481 DCHECK(param); | 490 DCHECK(param); |
| 482 | 491 |
| 483 if (!ValidAsmIdentifier(param->name())) { | 492 if (!ValidAsmIdentifier(param->name())) { |
| 484 FAIL(fun, "Invalid asm.js identifier in module parameter."); | 493 FAIL(fun, "Invalid asm.js identifier in module parameter."); |
| 485 } | 494 } |
| 486 | 495 |
| 487 auto* param_info = new (zone_) VariableInfo(); | 496 auto* param_info = VariableInfo::ForSpecialSymbol( |
| 488 param_info->set_mutability(VariableInfo::kImmutableGlobal); | 497 zone_, kModuleParamInfo[ii].standard_member); |
| 489 param_info->set_standard_member(kModuleParamInfo[ii].standard_member); | |
| 490 param_info->set_type(kModuleParamInfo[ii].type); | |
| 491 | 498 |
| 492 if (!AddGlobal(param, param_info)) { | 499 if (!AddGlobal(param, param_info)) { |
| 493 FAIL(fun, "Redeclared identifier in module parameter."); | 500 FAIL(fun, "Redeclared identifier in module parameter."); |
| 494 } | 501 } |
| 495 } | 502 } |
| 496 | 503 |
| 497 ZoneVector<Assignment*> function_pointer_tables(zone_); | 504 ZoneVector<Assignment*> function_pointer_tables(zone_); |
| 498 FlattenedStatements iter(zone_, fun->body()); | 505 FlattenedStatements iter(zone_, fun->body()); |
| 499 auto* use_asm_directive = iter.Next(); | 506 auto* use_asm_directive = iter.Next(); |
| 500 if (use_asm_directive == nullptr || !IsUseAsmDirective(use_asm_directive)) { | 507 if (use_asm_directive == nullptr || !IsUseAsmDirective(use_asm_directive)) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 644 } else if (value->IsProperty()) { | 651 } else if (value->IsProperty()) { |
| 645 target_info = ImportLookup(value->AsProperty()); | 652 target_info = ImportLookup(value->AsProperty()); |
| 646 if (target_info == nullptr) { | 653 if (target_info == nullptr) { |
| 647 FAIL(assign, "Invalid import."); | 654 FAIL(assign, "Invalid import."); |
| 648 } | 655 } |
| 649 CHECK(target_info->mutability() == VariableInfo::kImmutableGlobal); | 656 CHECK(target_info->mutability() == VariableInfo::kImmutableGlobal); |
| 650 if (!target_info->IsFFI()) { | 657 if (!target_info->IsFFI()) { |
| 651 target_info = target_info->Clone(zone_); | 658 target_info = target_info->Clone(zone_); |
| 652 } else { | 659 } else { |
| 653 // create a new target info that represents a foreign variable. | 660 // create a new target info that represents a foreign variable. |
| 654 DCHECK(target_info->type()->AsFFIType() != nullptr); | 661 target_info = new (zone_) VariableInfo(ffi_type_); |
| 655 target_info = new (zone_) VariableInfo(target_info->type()); | |
| 656 target_info->set_mutability(VariableInfo::kImmutableGlobal); | 662 target_info->set_mutability(VariableInfo::kImmutableGlobal); |
| 657 } | 663 } |
| 658 } else if (value->IsBinaryOperation()) { | 664 } else if (value->IsBinaryOperation()) { |
| 659 // This should either be: | 665 // This should either be: |
| 660 // | 666 // |
| 661 // var <> = ffi.<>|0 | 667 // var <> = ffi.<>|0 |
| 662 // | 668 // |
| 663 // or | 669 // or |
| 664 // | 670 // |
| 665 // var <> = +ffi.<> | 671 // var <> = +ffi.<> |
| (...skipping 22 matching lines...) Expand all Loading... |
| 688 FAIL(value, | 694 FAIL(value, |
| 689 "Invalid initializer for foreign import - object lookup failed."); | 695 "Invalid initializer for foreign import - object lookup failed."); |
| 690 } | 696 } |
| 691 CHECK(target_info->mutability() == VariableInfo::kImmutableGlobal); | 697 CHECK(target_info->mutability() == VariableInfo::kImmutableGlobal); |
| 692 if (!target_info->IsFFI()) { | 698 if (!target_info->IsFFI()) { |
| 693 FAIL(value, | 699 FAIL(value, |
| 694 "Invalid initializer for foreign import - object is not the ffi."); | 700 "Invalid initializer for foreign import - object is not the ffi."); |
| 695 } | 701 } |
| 696 | 702 |
| 697 // Create a new target info that represents the foreign import. | 703 // Create a new target info that represents the foreign import. |
| 698 DCHECK(target_info->type()->AsFFIType() != nullptr); | |
| 699 target_info = new (zone_) VariableInfo(import_type); | 704 target_info = new (zone_) VariableInfo(import_type); |
| 700 target_info->set_mutability(VariableInfo::kMutableGlobal); | 705 target_info->set_mutability(VariableInfo::kMutableGlobal); |
| 701 } else if (value->IsCallNew()) { | 706 } else if (value->IsCallNew()) { |
| 702 AsmType* type = nullptr; | 707 AsmType* type = nullptr; |
| 703 RECURSE(type = NewHeapView(value->AsCallNew())); | 708 RECURSE(type = NewHeapView(value->AsCallNew())); |
| 704 target_info = new (zone_) VariableInfo(type); | 709 target_info = new (zone_) VariableInfo(type); |
| 705 target_info->set_mutability(VariableInfo::kImmutableGlobal); | 710 target_info->set_mutability(VariableInfo::kImmutableGlobal); |
| 706 } | 711 } |
| 707 | 712 |
| 708 if (target_info == nullptr) { | 713 if (target_info == nullptr) { |
| (...skipping 835 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 | 1549 |
| 1545 return AsmType::Unsigned(); | 1550 return AsmType::Unsigned(); |
| 1546 } | 1551 } |
| 1547 | 1552 |
| 1548 // 6.8.3 Identifier | 1553 // 6.8.3 Identifier |
| 1549 AsmType* AsmTyper::ValidateIdentifier(VariableProxy* proxy) { | 1554 AsmType* AsmTyper::ValidateIdentifier(VariableProxy* proxy) { |
| 1550 auto* proxy_info = Lookup(proxy->var()); | 1555 auto* proxy_info = Lookup(proxy->var()); |
| 1551 if (proxy_info == nullptr) { | 1556 if (proxy_info == nullptr) { |
| 1552 FAIL(proxy, "Undeclared identifier."); | 1557 FAIL(proxy, "Undeclared identifier."); |
| 1553 } | 1558 } |
| 1554 if (proxy_info->type()->AsCallableType() != nullptr) { | 1559 auto* type = proxy_info->type(); |
| 1560 if (type->IsA(AsmType::None()) || type->AsCallableType() != nullptr) { |
| 1555 FAIL(proxy, "Identifier may not be accessed by ordinary expressions."); | 1561 FAIL(proxy, "Identifier may not be accessed by ordinary expressions."); |
| 1556 } | 1562 } |
| 1557 DCHECK(!proxy_info->type()->IsA(AsmType::None())); | 1563 return type; |
| 1558 return proxy_info->type(); | |
| 1559 } | 1564 } |
| 1560 | 1565 |
| 1561 // 6.8.4 CallExpression | 1566 // 6.8.4 CallExpression |
| 1562 AsmType* AsmTyper::ValidateCallExpression(Call* call) { | 1567 AsmType* AsmTyper::ValidateCallExpression(Call* call) { |
| 1563 AsmType* return_type; | 1568 AsmType* return_type; |
| 1564 RECURSE(return_type = ValidateFloatCoercion(call)); | 1569 RECURSE(return_type = ValidateFloatCoercion(call)); |
| 1565 if (return_type == nullptr) { | 1570 if (return_type == nullptr) { |
| 1566 FAIL(call, "Unanotated call to a function must be a call to fround."); | 1571 FAIL(call, "Unanotated call to a function must be a call to fround."); |
| 1567 } | 1572 } |
| 1568 return return_type; | 1573 return return_type; |
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2621 return true; | 2626 return true; |
| 2622 } | 2627 } |
| 2623 | 2628 |
| 2624 *error_message = typer.error_message(); | 2629 *error_message = typer.error_message(); |
| 2625 return false; | 2630 return false; |
| 2626 } | 2631 } |
| 2627 | 2632 |
| 2628 } // namespace wasm | 2633 } // namespace wasm |
| 2629 } // namespace internal | 2634 } // namespace internal |
| 2630 } // namespace v8 | 2635 } // namespace v8 |
| OLD | NEW |