| 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 <cstring> | 5 #include <cstring> |
| 6 #include <functional> | 6 #include <functional> |
| 7 #include <iostream> | 7 #include <iostream> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/asmjs/asm-typer.h" | 10 #include "src/asmjs/asm-typer.h" |
| (...skipping 27 matching lines...) Expand all Loading... |
| 38 ValidateExpression, | 38 ValidateExpression, |
| 39 }; | 39 }; |
| 40 } // namespace | 40 } // namespace |
| 41 | 41 |
| 42 class AsmTyperHarnessBuilder { | 42 class AsmTyperHarnessBuilder { |
| 43 public: | 43 public: |
| 44 AsmTyperHarnessBuilder(const char* source, ValidationType type) | 44 AsmTyperHarnessBuilder(const char* source, ValidationType type) |
| 45 : source_(source), | 45 : source_(source), |
| 46 validation_type_(type), | 46 validation_type_(type), |
| 47 handles_(), | 47 handles_(), |
| 48 zone_(handles_.main_zone()), |
| 48 isolate_(CcTest::i_isolate()), | 49 isolate_(CcTest::i_isolate()), |
| 50 ast_value_factory_(zone_, isolate_->ast_string_constants(), |
| 51 isolate_->heap()->HashSeed()), |
| 49 factory_(isolate_->factory()), | 52 factory_(isolate_->factory()), |
| 50 source_code_( | 53 source_code_( |
| 51 factory_->NewStringFromUtf8(CStrVector(source)).ToHandleChecked()), | 54 factory_->NewStringFromUtf8(CStrVector(source)).ToHandleChecked()), |
| 52 script_(factory_->NewScript(source_code_)), | 55 script_(factory_->NewScript(source_code_)) { |
| 53 info_(script_), | 56 ParseInfo info(zone_, script_); |
| 54 ast_value_factory_(info_.zone(), isolate_->ast_string_constants(), | 57 info.set_allow_lazy_parsing(false); |
| 55 isolate_->heap()->HashSeed()) { | 58 info.set_toplevel(true); |
| 56 info_.set_allow_lazy_parsing(false); | 59 info.set_ast_value_factory(&ast_value_factory_); |
| 57 info_.set_toplevel(true); | 60 info.set_ast_value_factory_owned(false); |
| 58 info_.set_ast_value_factory(&ast_value_factory_); | 61 Parser parser(&info); |
| 59 info_.set_ast_value_factory_owned(false); | |
| 60 Parser parser(&info_); | |
| 61 | 62 |
| 62 if (!Compiler::ParseAndAnalyze(&info_)) { | 63 if (!Compiler::ParseAndAnalyze(&info)) { |
| 63 std::cerr << "Failed to parse:\n" << source_ << "\n"; | 64 std::cerr << "Failed to parse:\n" << source_ << "\n"; |
| 64 CHECK(false); | 65 CHECK(false); |
| 65 } | 66 } |
| 66 | 67 |
| 67 outer_scope_ = info_.script_scope(); | 68 outer_scope_ = info.script_scope(); |
| 68 module_ = info_.scope() | 69 module_ = info.scope() |
| 69 ->declarations() | 70 ->declarations() |
| 70 ->AtForTest(0) | 71 ->AtForTest(0) |
| 71 ->AsFunctionDeclaration() | 72 ->AsFunctionDeclaration() |
| 72 ->fun(); | 73 ->fun(); |
| 73 typer_.reset(new AsmTyper(isolate_, zone(), script_, module_)); | 74 typer_.reset(new AsmTyper(isolate_, zone_, script_, module_)); |
| 74 | 75 |
| 75 if (validation_type_ == ValidateStatement || | 76 if (validation_type_ == ValidateStatement || |
| 76 validation_type_ == ValidateExpression) { | 77 validation_type_ == ValidateExpression) { |
| 77 fun_scope_.reset(new AsmTyper::FunctionScope(typer_.get())); | 78 fun_scope_.reset(new AsmTyper::FunctionScope(typer_.get())); |
| 78 | 79 |
| 79 for (Declaration* decl : *module_->scope()->declarations()) { | 80 for (Declaration* decl : *module_->scope()->declarations()) { |
| 80 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) { | 81 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) { |
| 81 fun_decl_ = fun_decl; | 82 fun_decl_ = fun_decl; |
| 82 break; | 83 break; |
| 83 } | 84 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 96 const VariableMode mode_; | 97 const VariableMode mode_; |
| 97 }; | 98 }; |
| 98 | 99 |
| 99 AsmTyperHarnessBuilder* WithLocal(VariableName var_name, AsmType* type) { | 100 AsmTyperHarnessBuilder* WithLocal(VariableName var_name, AsmType* type) { |
| 100 CHECK(validation_type_ == ValidateStatement || | 101 CHECK(validation_type_ == ValidateStatement || |
| 101 validation_type_ == ValidateExpression); | 102 validation_type_ == ValidateExpression); |
| 102 auto* var = DeclareVariable(var_name); | 103 auto* var = DeclareVariable(var_name); |
| 103 if (var->IsUnallocated()) { | 104 if (var->IsUnallocated()) { |
| 104 var->AllocateTo(VariableLocation::LOCAL, -1); | 105 var->AllocateTo(VariableLocation::LOCAL, -1); |
| 105 } | 106 } |
| 106 auto* var_info = new (zone()) AsmTyper::VariableInfo(type); | 107 auto* var_info = new (zone_) AsmTyper::VariableInfo(type); |
| 107 var_info->set_mutability(AsmTyper::VariableInfo::kLocal); | 108 var_info->set_mutability(AsmTyper::VariableInfo::kLocal); |
| 108 CHECK(typer_->AddLocal(var, var_info)); | 109 CHECK(typer_->AddLocal(var, var_info)); |
| 109 return this; | 110 return this; |
| 110 } | 111 } |
| 111 | 112 |
| 112 AsmTyperHarnessBuilder* WithGlobal(VariableName var_name, AsmType* type) { | 113 AsmTyperHarnessBuilder* WithGlobal(VariableName var_name, AsmType* type) { |
| 113 auto* var = DeclareVariable(var_name); | 114 auto* var = DeclareVariable(var_name); |
| 114 if (var->IsUnallocated()) { | 115 if (var->IsUnallocated()) { |
| 115 var->AllocateTo(VariableLocation::MODULE, -1); | 116 var->AllocateTo(VariableLocation::MODULE, -1); |
| 116 } | 117 } |
| 117 if (type != nullptr) { | 118 if (type != nullptr) { |
| 118 auto* var_info = new (zone()) AsmTyper::VariableInfo(type); | 119 auto* var_info = new (zone_) AsmTyper::VariableInfo(type); |
| 119 var_info->set_mutability(AsmTyper::VariableInfo::kMutableGlobal); | 120 var_info->set_mutability(AsmTyper::VariableInfo::kMutableGlobal); |
| 120 CHECK(typer_->AddGlobal(var, var_info)); | 121 CHECK(typer_->AddGlobal(var, var_info)); |
| 121 } | 122 } |
| 122 return this; | 123 return this; |
| 123 } | 124 } |
| 124 | 125 |
| 125 AsmTyperHarnessBuilder* WithGlobal( | 126 AsmTyperHarnessBuilder* WithGlobal( |
| 126 VariableName var_name, std::function<AsmType*(Zone*)> type_creator) { | 127 VariableName var_name, std::function<AsmType*(Zone*)> type_creator) { |
| 127 return WithGlobal(var_name, type_creator(zone())); | 128 return WithGlobal(var_name, type_creator(zone_)); |
| 128 } | 129 } |
| 129 | 130 |
| 130 AsmTyperHarnessBuilder* WithUndefinedGlobal( | 131 AsmTyperHarnessBuilder* WithUndefinedGlobal( |
| 131 VariableName var_name, std::function<AsmType*(Zone*)> type_creator) { | 132 VariableName var_name, std::function<AsmType*(Zone*)> type_creator) { |
| 132 auto* type = type_creator(zone()); | 133 auto* type = type_creator(zone_); |
| 133 CHECK(type->AsFunctionType() != nullptr || | 134 CHECK(type->AsFunctionType() != nullptr || |
| 134 type->AsFunctionTableType() != nullptr); | 135 type->AsFunctionTableType() != nullptr); |
| 135 WithGlobal(var_name, type); | 136 WithGlobal(var_name, type); |
| 136 auto* var_info = typer_->Lookup(DeclareVariable(var_name)); | 137 auto* var_info = typer_->Lookup(DeclareVariable(var_name)); |
| 137 CHECK(var_info); | 138 CHECK(var_info); |
| 138 MessageLocation location; | 139 MessageLocation location; |
| 139 var_info->SetFirstForwardUse(location); | 140 var_info->SetFirstForwardUse(location); |
| 140 return this; | 141 return this; |
| 141 } | 142 } |
| 142 | 143 |
| 143 AsmTyperHarnessBuilder* WithImport(VariableName var_name, | 144 AsmTyperHarnessBuilder* WithImport(VariableName var_name, |
| 144 AsmTyper::StandardMember standard_member) { | 145 AsmTyper::StandardMember standard_member) { |
| 145 auto* var = DeclareVariable(var_name); | 146 auto* var = DeclareVariable(var_name); |
| 146 if (var->IsUnallocated()) { | 147 if (var->IsUnallocated()) { |
| 147 var->AllocateTo(VariableLocation::LOCAL, -1); | 148 var->AllocateTo(VariableLocation::LOCAL, -1); |
| 148 } | 149 } |
| 149 AsmTyper::VariableInfo* var_info = nullptr; | 150 AsmTyper::VariableInfo* var_info = nullptr; |
| 150 auto* stdlib_map = &typer_->stdlib_math_types_; | 151 auto* stdlib_map = &typer_->stdlib_math_types_; |
| 151 switch (standard_member) { | 152 switch (standard_member) { |
| 152 case AsmTyper::kHeap: | 153 case AsmTyper::kHeap: |
| 153 case AsmTyper::kStdlib: | 154 case AsmTyper::kStdlib: |
| 154 case AsmTyper::kModule: | 155 case AsmTyper::kModule: |
| 155 case AsmTyper::kNone: | 156 case AsmTyper::kNone: |
| 156 CHECK(false); | 157 CHECK(false); |
| 157 case AsmTyper::kFFI: | 158 case AsmTyper::kFFI: |
| 158 stdlib_map = nullptr; | 159 stdlib_map = nullptr; |
| 159 var_info = | 160 var_info = new (zone_) AsmTyper::VariableInfo(AsmType::FFIType(zone_)); |
| 160 new (zone()) AsmTyper::VariableInfo(AsmType::FFIType(zone())); | |
| 161 var_info->set_mutability(AsmTyper::VariableInfo::kImmutableGlobal); | 161 var_info->set_mutability(AsmTyper::VariableInfo::kImmutableGlobal); |
| 162 break; | 162 break; |
| 163 case AsmTyper::kInfinity: | 163 case AsmTyper::kInfinity: |
| 164 case AsmTyper::kNaN: | 164 case AsmTyper::kNaN: |
| 165 stdlib_map = &typer_->stdlib_types_; | 165 stdlib_map = &typer_->stdlib_types_; |
| 166 default: | 166 default: |
| 167 break; | 167 break; |
| 168 } | 168 } |
| 169 | 169 |
| 170 if (var_info == nullptr) { | 170 if (var_info == nullptr) { |
| 171 for (auto iter : *stdlib_map) { | 171 for (auto iter : *stdlib_map) { |
| 172 if (iter.second->standard_member() == standard_member) { | 172 if (iter.second->standard_member() == standard_member) { |
| 173 var_info = iter.second; | 173 var_info = iter.second; |
| 174 break; | 174 break; |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 | 177 |
| 178 CHECK(var_info != nullptr); | 178 CHECK(var_info != nullptr); |
| 179 var_info = var_info->Clone(zone()); | 179 var_info = var_info->Clone(zone_); |
| 180 } | 180 } |
| 181 | 181 |
| 182 CHECK(typer_->AddGlobal(var, var_info)); | 182 CHECK(typer_->AddGlobal(var, var_info)); |
| 183 return this; | 183 return this; |
| 184 } | 184 } |
| 185 | 185 |
| 186 AsmTyperHarnessBuilder* WithReturnType(AsmType* type) { | 186 AsmTyperHarnessBuilder* WithReturnType(AsmType* type) { |
| 187 CHECK(type->IsReturnType()); | 187 CHECK(type->IsReturnType()); |
| 188 CHECK(typer_->return_type_ == AsmType::None()); | 188 CHECK(typer_->return_type_ == AsmType::None()); |
| 189 typer_->return_type_ = type; | 189 typer_->return_type_ = type; |
| 190 return this; | 190 return this; |
| 191 } | 191 } |
| 192 | 192 |
| 193 AsmTyperHarnessBuilder* WithStdlib(VariableName var_name) { | 193 AsmTyperHarnessBuilder* WithStdlib(VariableName var_name) { |
| 194 auto* var = DeclareVariable(var_name); | 194 auto* var = DeclareVariable(var_name); |
| 195 auto* var_info = | 195 auto* var_info = |
| 196 AsmTyper::VariableInfo::ForSpecialSymbol(zone(), AsmTyper::kStdlib); | 196 AsmTyper::VariableInfo::ForSpecialSymbol(zone_, AsmTyper::kStdlib); |
| 197 CHECK(typer_->AddGlobal(var, var_info)); | 197 CHECK(typer_->AddGlobal(var, var_info)); |
| 198 return this; | 198 return this; |
| 199 } | 199 } |
| 200 | 200 |
| 201 AsmTyperHarnessBuilder* WithHeap(VariableName var_name) { | 201 AsmTyperHarnessBuilder* WithHeap(VariableName var_name) { |
| 202 auto* var = DeclareVariable(var_name); | 202 auto* var = DeclareVariable(var_name); |
| 203 auto* var_info = | 203 auto* var_info = |
| 204 AsmTyper::VariableInfo::ForSpecialSymbol(zone(), AsmTyper::kHeap); | 204 AsmTyper::VariableInfo::ForSpecialSymbol(zone_, AsmTyper::kHeap); |
| 205 CHECK(typer_->AddGlobal(var, var_info)); | 205 CHECK(typer_->AddGlobal(var, var_info)); |
| 206 return this; | 206 return this; |
| 207 } | 207 } |
| 208 | 208 |
| 209 AsmTyperHarnessBuilder* WithFFI(VariableName var_name) { | 209 AsmTyperHarnessBuilder* WithFFI(VariableName var_name) { |
| 210 auto* var = DeclareVariable(var_name); | 210 auto* var = DeclareVariable(var_name); |
| 211 auto* var_info = | 211 auto* var_info = |
| 212 AsmTyper::VariableInfo::ForSpecialSymbol(zone(), AsmTyper::kFFI); | 212 AsmTyper::VariableInfo::ForSpecialSymbol(zone_, AsmTyper::kFFI); |
| 213 CHECK(typer_->AddGlobal(var, var_info)); | 213 CHECK(typer_->AddGlobal(var, var_info)); |
| 214 return this; | 214 return this; |
| 215 } | 215 } |
| 216 | 216 |
| 217 bool Succeeds() { | 217 bool Succeeds() { |
| 218 CHECK(validation_type_ == ValidateModule || | 218 CHECK(validation_type_ == ValidateModule || |
| 219 validation_type_ == ValidateGlobals || | 219 validation_type_ == ValidateGlobals || |
| 220 validation_type_ == ValidateFunctionTables || | 220 validation_type_ == ValidateFunctionTables || |
| 221 validation_type_ == ValidateExport || | 221 validation_type_ == ValidateExport || |
| 222 validation_type_ == ValidateFunction || | 222 validation_type_ == ValidateFunction || |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 ast_value_factory_.Internalize(isolate_); | 298 ast_value_factory_.Internalize(isolate_); |
| 299 return var_name.mode_ == DYNAMIC_GLOBAL | 299 return var_name.mode_ == DYNAMIC_GLOBAL |
| 300 ? outer_scope_->DeclareDynamicGlobal(name_ast_string, | 300 ? outer_scope_->DeclareDynamicGlobal(name_ast_string, |
| 301 NORMAL_VARIABLE) | 301 NORMAL_VARIABLE) |
| 302 : module_->scope()->DeclareLocal(name_ast_string, VAR, | 302 : module_->scope()->DeclareLocal(name_ast_string, VAR, |
| 303 kCreatedInitialized, | 303 kCreatedInitialized, |
| 304 NORMAL_VARIABLE); | 304 NORMAL_VARIABLE); |
| 305 } | 305 } |
| 306 | 306 |
| 307 bool ValidateAllStatements(FunctionDeclaration* fun_decl) { | 307 bool ValidateAllStatements(FunctionDeclaration* fun_decl) { |
| 308 AsmTyper::FlattenedStatements iter(zone(), fun_decl->fun()->body()); | 308 AsmTyper::FlattenedStatements iter(zone_, fun_decl->fun()->body()); |
| 309 while (auto* curr = iter.Next()) { | 309 while (auto* curr = iter.Next()) { |
| 310 if (typer_->ValidateStatement(curr) == AsmType::None()) { | 310 if (typer_->ValidateStatement(curr) == AsmType::None()) { |
| 311 return false; | 311 return false; |
| 312 } | 312 } |
| 313 } | 313 } |
| 314 return true; | 314 return true; |
| 315 } | 315 } |
| 316 | 316 |
| 317 AsmType* ValidateExpressionStatment(FunctionDeclaration* fun_decl) { | 317 AsmType* ValidateExpressionStatment(FunctionDeclaration* fun_decl) { |
| 318 AsmTyper::FlattenedStatements iter(zone(), fun_decl->fun()->body()); | 318 AsmTyper::FlattenedStatements iter(zone_, fun_decl->fun()->body()); |
| 319 AsmType* ret = AsmType::None(); | 319 AsmType* ret = AsmType::None(); |
| 320 bool last_was_expression_statement = false; | 320 bool last_was_expression_statement = false; |
| 321 while (auto* curr = iter.Next()) { | 321 while (auto* curr = iter.Next()) { |
| 322 if (auto* expr_stmt = curr->AsExpressionStatement()) { | 322 if (auto* expr_stmt = curr->AsExpressionStatement()) { |
| 323 last_was_expression_statement = true; | 323 last_was_expression_statement = true; |
| 324 if ((ret = typer_->ValidateExpression(expr_stmt->expression())) == | 324 if ((ret = typer_->ValidateExpression(expr_stmt->expression())) == |
| 325 AsmType::None()) { | 325 AsmType::None()) { |
| 326 break; | 326 break; |
| 327 } | 327 } |
| 328 } else { | 328 } else { |
| 329 ret = AsmType::None(); | 329 ret = AsmType::None(); |
| 330 last_was_expression_statement = true; | 330 last_was_expression_statement = true; |
| 331 if (typer_->ValidateStatement(curr) == AsmType::None()) { | 331 if (typer_->ValidateStatement(curr) == AsmType::None()) { |
| 332 break; | 332 break; |
| 333 } | 333 } |
| 334 } | 334 } |
| 335 } | 335 } |
| 336 CHECK(last_was_expression_statement || ret == AsmType::None()); | 336 CHECK(last_was_expression_statement || ret == AsmType::None()); |
| 337 return ret; | 337 return ret; |
| 338 } | 338 } |
| 339 | 339 |
| 340 Zone* zone() { return info_.zone(); } | |
| 341 | |
| 342 std::string source_; | 340 std::string source_; |
| 343 ValidationType validation_type_; | 341 ValidationType validation_type_; |
| 344 HandleAndZoneScope handles_; | 342 HandleAndZoneScope handles_; |
| 343 Zone* zone_; |
| 345 Isolate* isolate_; | 344 Isolate* isolate_; |
| 345 AstValueFactory ast_value_factory_; |
| 346 Factory* factory_; | 346 Factory* factory_; |
| 347 Handle<String> source_code_; | 347 Handle<String> source_code_; |
| 348 Handle<Script> script_; | 348 Handle<Script> script_; |
| 349 ParseInfo info_; | |
| 350 AstValueFactory ast_value_factory_; | |
| 351 | 349 |
| 352 DeclarationScope* outer_scope_; | 350 DeclarationScope* outer_scope_; |
| 353 FunctionLiteral* module_; | 351 FunctionLiteral* module_; |
| 354 FunctionDeclaration* fun_decl_; | 352 FunctionDeclaration* fun_decl_; |
| 355 std::unique_ptr<AsmTyper> typer_; | 353 std::unique_ptr<AsmTyper> typer_; |
| 356 std::unique_ptr<AsmTyper::FunctionScope> fun_scope_; | 354 std::unique_ptr<AsmTyper::FunctionScope> fun_scope_; |
| 357 }; | 355 }; |
| 358 | 356 |
| 359 } // namespace wasm | 357 } // namespace wasm |
| 360 } // namespace internal | 358 } // namespace internal |
| (...skipping 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2080 if (!ValidationOf(Module(kTests[ii])) | 2078 if (!ValidationOf(Module(kTests[ii])) |
| 2081 ->FailsWithMessage( | 2079 ->FailsWithMessage( |
| 2082 "Constant in return must be signed, float, or double.")) { | 2080 "Constant in return must be signed, float, or double.")) { |
| 2083 std::cerr << "Test:\n" << kTests[ii]; | 2081 std::cerr << "Test:\n" << kTests[ii]; |
| 2084 CHECK(false); | 2082 CHECK(false); |
| 2085 } | 2083 } |
| 2086 } | 2084 } |
| 2087 } | 2085 } |
| 2088 | 2086 |
| 2089 } // namespace | 2087 } // namespace |
| OLD | NEW |