| 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <limits> | 8 #include <limits> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <string> | 10 #include <string> |
| 11 | 11 |
| 12 #include "include/v8.h" |
| 12 #include "src/v8.h" | 13 #include "src/v8.h" |
| 13 | 14 |
| 14 #include "src/asmjs/asm-types.h" | 15 #include "src/asmjs/asm-types.h" |
| 15 #include "src/ast/ast.h" | 16 #include "src/ast/ast.h" |
| 16 #include "src/ast/scopes.h" | 17 #include "src/ast/scopes.h" |
| 17 #include "src/base/bits.h" | 18 #include "src/base/bits.h" |
| 18 #include "src/codegen.h" | 19 #include "src/codegen.h" |
| 19 #include "src/globals.h" | 20 #include "src/globals.h" |
| 21 #include "src/messages.h" |
| 20 #include "src/utils.h" | 22 #include "src/utils.h" |
| 21 | 23 |
| 22 #define FAIL_LINE(line, msg) \ | 24 #define FAIL_LOCATION(location, msg) \ |
| 23 do { \ | 25 do { \ |
| 24 base::OS::SNPrintF(error_message_, sizeof(error_message_), \ | 26 Handle<String> message(isolate_->factory()->InternalizeOneByteString( \ |
| 25 "asm: line %d: %s", (line) + 1, msg); \ | 27 STATIC_CHAR_VECTOR(msg))); \ |
| 26 return AsmType::None(); \ | 28 error_message_ = MessageHandler::MakeMessageObject( \ |
| 29 isolate_, MessageTemplate::kAsmJsInvalid, (location), message, \ |
| 30 Handle<JSArray>::null()); \ |
| 31 error_message_->set_error_level(v8::Isolate::kMessageWarning); \ |
| 32 message_location_ = *(location); \ |
| 33 return AsmType::None(); \ |
| 27 } while (false) | 34 } while (false) |
| 28 | 35 |
| 29 #define FAIL(node, msg) \ | 36 #define FAIL(node, msg) \ |
| 30 do { \ | 37 do { \ |
| 31 int line = node->position() == kNoSourcePosition \ | 38 MessageLocation location(script_, node->position(), node->position()); \ |
| 32 ? -1 \ | 39 FAIL_LOCATION(&location, msg); \ |
| 33 : script_->GetLineNumber(node->position()); \ | |
| 34 FAIL_LINE(line, msg); \ | |
| 35 } while (false) | 40 } while (false) |
| 36 | 41 |
| 37 #define RECURSE(call) \ | 42 #define RECURSE(call) \ |
| 38 do { \ | 43 do { \ |
| 39 if (GetCurrentStackPosition() < stack_limit_) { \ | 44 if (GetCurrentStackPosition() < stack_limit_) { \ |
| 40 stack_overflow_ = true; \ | 45 stack_overflow_ = true; \ |
| 41 FAIL(root_, "Stack overflow while parsing asm.js module."); \ | 46 FAIL(root_, "Stack overflow while parsing asm.js module."); \ |
| 42 } \ | 47 } \ |
| 43 \ | 48 \ |
| 44 AsmType* result = (call); \ | 49 AsmType* result = (call); \ |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 157 | 162 |
| 158 AsmTyper::VariableInfo* AsmTyper::VariableInfo::Clone(Zone* zone) const { | 163 AsmTyper::VariableInfo* AsmTyper::VariableInfo::Clone(Zone* zone) const { |
| 159 CHECK(standard_member_ != kNone); | 164 CHECK(standard_member_ != kNone); |
| 160 CHECK(!type_->IsA(AsmType::None())); | 165 CHECK(!type_->IsA(AsmType::None())); |
| 161 auto* new_var_info = new (zone) VariableInfo(type_); | 166 auto* new_var_info = new (zone) VariableInfo(type_); |
| 162 new_var_info->standard_member_ = standard_member_; | 167 new_var_info->standard_member_ = standard_member_; |
| 163 new_var_info->mutability_ = mutability_; | 168 new_var_info->mutability_ = mutability_; |
| 164 return new_var_info; | 169 return new_var_info; |
| 165 } | 170 } |
| 166 | 171 |
| 167 void AsmTyper::VariableInfo::SetFirstForwardUse(int source_location) { | 172 void AsmTyper::VariableInfo::SetFirstForwardUse( |
| 168 DCHECK(source_location_ == -1); | 173 const MessageLocation& source_location) { |
| 169 missing_definition_ = true; | 174 missing_definition_ = true; |
| 170 source_location_ = source_location; | 175 source_location_ = source_location; |
| 171 } | 176 } |
| 172 | 177 |
| 173 // ---------------------------------------------------------------------------- | 178 // ---------------------------------------------------------------------------- |
| 174 // Implementation of AsmTyper | 179 // Implementation of AsmTyper |
| 175 | 180 |
| 176 AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Handle<Script> script, | 181 AsmTyper::AsmTyper(Isolate* isolate, Zone* zone, Handle<Script> script, |
| 177 FunctionLiteral* root) | 182 FunctionLiteral* root) |
| 178 : isolate_(isolate), | 183 : isolate_(isolate), |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 | 398 |
| 394 if (entry == nullptr && !module_name_.is_null() && | 399 if (entry == nullptr && !module_name_.is_null() && |
| 395 module_name_->Equals(*variable->name())) { | 400 module_name_->Equals(*variable->name())) { |
| 396 return module_info_; | 401 return module_info_; |
| 397 } | 402 } |
| 398 | 403 |
| 399 return entry ? reinterpret_cast<VariableInfo*>(entry->value) : nullptr; | 404 return entry ? reinterpret_cast<VariableInfo*>(entry->value) : nullptr; |
| 400 } | 405 } |
| 401 | 406 |
| 402 void AsmTyper::AddForwardReference(VariableProxy* proxy, VariableInfo* info) { | 407 void AsmTyper::AddForwardReference(VariableProxy* proxy, VariableInfo* info) { |
| 403 info->SetFirstForwardUse(proxy->position()); | 408 MessageLocation location(script_, proxy->position(), proxy->position()); |
| 409 info->SetFirstForwardUse(location); |
| 404 forward_definitions_.push_back(info); | 410 forward_definitions_.push_back(info); |
| 405 } | 411 } |
| 406 | 412 |
| 407 bool AsmTyper::AddGlobal(Variable* variable, VariableInfo* info) { | 413 bool AsmTyper::AddGlobal(Variable* variable, VariableInfo* info) { |
| 408 // We can't DCHECK(!in_function_) because function may actually install global | 414 // We can't DCHECK(!in_function_) because function may actually install global |
| 409 // names (forward defined functions and function tables.) | 415 // names (forward defined functions and function tables.) |
| 410 DCHECK(info->mutability() != VariableInfo::kInvalidMutability); | 416 DCHECK(info->mutability() != VariableInfo::kInvalidMutability); |
| 411 DCHECK(info->IsGlobal()); | 417 DCHECK(info->IsGlobal()); |
| 412 DCHECK(ValidAsmIdentifier(variable->name())); | 418 DCHECK(ValidAsmIdentifier(variable->name())); |
| 413 | 419 |
| (...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 } | 737 } |
| 732 } | 738 } |
| 733 | 739 |
| 734 // 6.2 ValidateExport | 740 // 6.2 ValidateExport |
| 735 if (module_return_ == nullptr) { | 741 if (module_return_ == nullptr) { |
| 736 FAIL(fun, "Missing asm.js module export."); | 742 FAIL(fun, "Missing asm.js module export."); |
| 737 } | 743 } |
| 738 | 744 |
| 739 for (auto* forward_def : forward_definitions_) { | 745 for (auto* forward_def : forward_definitions_) { |
| 740 if (forward_def->missing_definition()) { | 746 if (forward_def->missing_definition()) { |
| 741 int position = forward_def->source_location(); | 747 FAIL_LOCATION(forward_def->source_location(), |
| 742 int line = | 748 "Missing definition for forward declared identifier."); |
| 743 position == kNoSourcePosition ? -1 : script_->GetLineNumber(position); | |
| 744 | |
| 745 FAIL_LINE(line, "Missing definition for forward declared identifier."); | |
| 746 } | 749 } |
| 747 } | 750 } |
| 748 | 751 |
| 749 RECURSE(ValidateExport(module_return_)); | 752 RECURSE(ValidateExport(module_return_)); |
| 750 | 753 |
| 751 if (!source_layout_.IsValid()) { | 754 if (!source_layout_.IsValid()) { |
| 752 FAIL(fun, "Invalid asm.js source code layout."); | 755 FAIL(fun, "Invalid asm.js source code layout."); |
| 753 } | 756 } |
| 754 | 757 |
| 755 return AsmType::Int(); // Any type that is not AsmType::None(); | 758 return AsmType::Int(); // Any type that is not AsmType::None(); |
| (...skipping 2142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2898 | 2901 |
| 2899 if (!heap_var_info->IsHeap()) { | 2902 if (!heap_var_info->IsHeap()) { |
| 2900 FAIL(heap, | 2903 FAIL(heap, |
| 2901 "Heap view creation parameter should be the module's heap parameter."); | 2904 "Heap view creation parameter should be the module's heap parameter."); |
| 2902 } | 2905 } |
| 2903 | 2906 |
| 2904 DCHECK(heap_view_info->type()->IsA(AsmType::Heap())); | 2907 DCHECK(heap_view_info->type()->IsA(AsmType::Heap())); |
| 2905 return heap_view_info->type(); | 2908 return heap_view_info->type(); |
| 2906 } | 2909 } |
| 2907 | 2910 |
| 2908 bool IsValidAsm(Isolate* isolate, Zone* zone, Handle<Script> script, | |
| 2909 FunctionLiteral* root, std::string* error_message) { | |
| 2910 error_message->clear(); | |
| 2911 | |
| 2912 AsmTyper typer(isolate, zone, script, root); | |
| 2913 if (typer.Validate()) { | |
| 2914 return true; | |
| 2915 } | |
| 2916 | |
| 2917 *error_message = typer.error_message(); | |
| 2918 return false; | |
| 2919 } | |
| 2920 | |
| 2921 } // namespace wasm | 2911 } // namespace wasm |
| 2922 } // namespace internal | 2912 } // namespace internal |
| 2923 } // namespace v8 | 2913 } // namespace v8 |
| OLD | NEW |