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()), | |
49 isolate_(CcTest::i_isolate()), | 48 isolate_(CcTest::i_isolate()), |
50 ast_value_factory_(zone_, isolate_->ast_string_constants(), | |
51 isolate_->heap()->HashSeed()), | |
52 factory_(isolate_->factory()), | 49 factory_(isolate_->factory()), |
53 source_code_( | 50 source_code_( |
54 factory_->NewStringFromUtf8(CStrVector(source)).ToHandleChecked()), | 51 factory_->NewStringFromUtf8(CStrVector(source)).ToHandleChecked()), |
55 script_(factory_->NewScript(source_code_)) { | 52 script_(factory_->NewScript(source_code_)), |
56 ParseInfo info(zone_, script_); | 53 info_(script_), |
57 info.set_allow_lazy_parsing(false); | 54 ast_value_factory_(info_.zone(), isolate_->ast_string_constants(), |
58 info.set_toplevel(true); | 55 isolate_->heap()->HashSeed()) { |
59 info.set_ast_value_factory(&ast_value_factory_); | 56 info_.set_allow_lazy_parsing(false); |
60 info.set_ast_value_factory_owned(false); | 57 info_.set_toplevel(true); |
61 Parser parser(&info); | 58 info_.set_ast_value_factory(&ast_value_factory_); |
| 59 info_.set_ast_value_factory_owned(false); |
| 60 Parser parser(&info_); |
62 | 61 |
63 if (!Compiler::ParseAndAnalyze(&info)) { | 62 if (!Compiler::ParseAndAnalyze(&info_)) { |
64 std::cerr << "Failed to parse:\n" << source_ << "\n"; | 63 std::cerr << "Failed to parse:\n" << source_ << "\n"; |
65 CHECK(false); | 64 CHECK(false); |
66 } | 65 } |
67 | 66 |
68 outer_scope_ = info.script_scope(); | 67 outer_scope_ = info_.script_scope(); |
69 module_ = info.scope() | 68 module_ = info_.scope() |
70 ->declarations() | 69 ->declarations() |
71 ->AtForTest(0) | 70 ->AtForTest(0) |
72 ->AsFunctionDeclaration() | 71 ->AsFunctionDeclaration() |
73 ->fun(); | 72 ->fun(); |
74 typer_.reset(new AsmTyper(isolate_, zone_, script_, module_)); | 73 typer_.reset(new AsmTyper(isolate_, zone(), script_, module_)); |
75 | 74 |
76 if (validation_type_ == ValidateStatement || | 75 if (validation_type_ == ValidateStatement || |
77 validation_type_ == ValidateExpression) { | 76 validation_type_ == ValidateExpression) { |
78 fun_scope_.reset(new AsmTyper::FunctionScope(typer_.get())); | 77 fun_scope_.reset(new AsmTyper::FunctionScope(typer_.get())); |
79 | 78 |
80 for (Declaration* decl : *module_->scope()->declarations()) { | 79 for (Declaration* decl : *module_->scope()->declarations()) { |
81 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) { | 80 if (FunctionDeclaration* fun_decl = decl->AsFunctionDeclaration()) { |
82 fun_decl_ = fun_decl; | 81 fun_decl_ = fun_decl; |
83 break; | 82 break; |
84 } | 83 } |
(...skipping 12 matching lines...) Expand all Loading... |
97 const VariableMode mode_; | 96 const VariableMode mode_; |
98 }; | 97 }; |
99 | 98 |
100 AsmTyperHarnessBuilder* WithLocal(VariableName var_name, AsmType* type) { | 99 AsmTyperHarnessBuilder* WithLocal(VariableName var_name, AsmType* type) { |
101 CHECK(validation_type_ == ValidateStatement || | 100 CHECK(validation_type_ == ValidateStatement || |
102 validation_type_ == ValidateExpression); | 101 validation_type_ == ValidateExpression); |
103 auto* var = DeclareVariable(var_name); | 102 auto* var = DeclareVariable(var_name); |
104 if (var->IsUnallocated()) { | 103 if (var->IsUnallocated()) { |
105 var->AllocateTo(VariableLocation::LOCAL, -1); | 104 var->AllocateTo(VariableLocation::LOCAL, -1); |
106 } | 105 } |
107 auto* var_info = new (zone_) AsmTyper::VariableInfo(type); | 106 auto* var_info = new (zone()) AsmTyper::VariableInfo(type); |
108 var_info->set_mutability(AsmTyper::VariableInfo::kLocal); | 107 var_info->set_mutability(AsmTyper::VariableInfo::kLocal); |
109 CHECK(typer_->AddLocal(var, var_info)); | 108 CHECK(typer_->AddLocal(var, var_info)); |
110 return this; | 109 return this; |
111 } | 110 } |
112 | 111 |
113 AsmTyperHarnessBuilder* WithGlobal(VariableName var_name, AsmType* type) { | 112 AsmTyperHarnessBuilder* WithGlobal(VariableName var_name, AsmType* type) { |
114 auto* var = DeclareVariable(var_name); | 113 auto* var = DeclareVariable(var_name); |
115 if (var->IsUnallocated()) { | 114 if (var->IsUnallocated()) { |
116 var->AllocateTo(VariableLocation::MODULE, -1); | 115 var->AllocateTo(VariableLocation::MODULE, -1); |
117 } | 116 } |
118 if (type != nullptr) { | 117 if (type != nullptr) { |
119 auto* var_info = new (zone_) AsmTyper::VariableInfo(type); | 118 auto* var_info = new (zone()) AsmTyper::VariableInfo(type); |
120 var_info->set_mutability(AsmTyper::VariableInfo::kMutableGlobal); | 119 var_info->set_mutability(AsmTyper::VariableInfo::kMutableGlobal); |
121 CHECK(typer_->AddGlobal(var, var_info)); | 120 CHECK(typer_->AddGlobal(var, var_info)); |
122 } | 121 } |
123 return this; | 122 return this; |
124 } | 123 } |
125 | 124 |
126 AsmTyperHarnessBuilder* WithGlobal( | 125 AsmTyperHarnessBuilder* WithGlobal( |
127 VariableName var_name, std::function<AsmType*(Zone*)> type_creator) { | 126 VariableName var_name, std::function<AsmType*(Zone*)> type_creator) { |
128 return WithGlobal(var_name, type_creator(zone_)); | 127 return WithGlobal(var_name, type_creator(zone())); |
129 } | 128 } |
130 | 129 |
131 AsmTyperHarnessBuilder* WithUndefinedGlobal( | 130 AsmTyperHarnessBuilder* WithUndefinedGlobal( |
132 VariableName var_name, std::function<AsmType*(Zone*)> type_creator) { | 131 VariableName var_name, std::function<AsmType*(Zone*)> type_creator) { |
133 auto* type = type_creator(zone_); | 132 auto* type = type_creator(zone()); |
134 CHECK(type->AsFunctionType() != nullptr || | 133 CHECK(type->AsFunctionType() != nullptr || |
135 type->AsFunctionTableType() != nullptr); | 134 type->AsFunctionTableType() != nullptr); |
136 WithGlobal(var_name, type); | 135 WithGlobal(var_name, type); |
137 auto* var_info = typer_->Lookup(DeclareVariable(var_name)); | 136 auto* var_info = typer_->Lookup(DeclareVariable(var_name)); |
138 CHECK(var_info); | 137 CHECK(var_info); |
139 MessageLocation location; | 138 MessageLocation location; |
140 var_info->SetFirstForwardUse(location); | 139 var_info->SetFirstForwardUse(location); |
141 return this; | 140 return this; |
142 } | 141 } |
143 | 142 |
144 AsmTyperHarnessBuilder* WithImport(VariableName var_name, | 143 AsmTyperHarnessBuilder* WithImport(VariableName var_name, |
145 AsmTyper::StandardMember standard_member) { | 144 AsmTyper::StandardMember standard_member) { |
146 auto* var = DeclareVariable(var_name); | 145 auto* var = DeclareVariable(var_name); |
147 if (var->IsUnallocated()) { | 146 if (var->IsUnallocated()) { |
148 var->AllocateTo(VariableLocation::LOCAL, -1); | 147 var->AllocateTo(VariableLocation::LOCAL, -1); |
149 } | 148 } |
150 AsmTyper::VariableInfo* var_info = nullptr; | 149 AsmTyper::VariableInfo* var_info = nullptr; |
151 auto* stdlib_map = &typer_->stdlib_math_types_; | 150 auto* stdlib_map = &typer_->stdlib_math_types_; |
152 switch (standard_member) { | 151 switch (standard_member) { |
153 case AsmTyper::kHeap: | 152 case AsmTyper::kHeap: |
154 case AsmTyper::kStdlib: | 153 case AsmTyper::kStdlib: |
155 case AsmTyper::kModule: | 154 case AsmTyper::kModule: |
156 case AsmTyper::kNone: | 155 case AsmTyper::kNone: |
157 CHECK(false); | 156 CHECK(false); |
158 case AsmTyper::kFFI: | 157 case AsmTyper::kFFI: |
159 stdlib_map = nullptr; | 158 stdlib_map = nullptr; |
160 var_info = new (zone_) AsmTyper::VariableInfo(AsmType::FFIType(zone_)); | 159 var_info = |
| 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 |
340 std::string source_; | 342 std::string source_; |
341 ValidationType validation_type_; | 343 ValidationType validation_type_; |
342 HandleAndZoneScope handles_; | 344 HandleAndZoneScope handles_; |
343 Zone* zone_; | |
344 Isolate* isolate_; | 345 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_; |
349 | 351 |
350 DeclarationScope* outer_scope_; | 352 DeclarationScope* outer_scope_; |
351 FunctionLiteral* module_; | 353 FunctionLiteral* module_; |
352 FunctionDeclaration* fun_decl_; | 354 FunctionDeclaration* fun_decl_; |
353 std::unique_ptr<AsmTyper> typer_; | 355 std::unique_ptr<AsmTyper> typer_; |
354 std::unique_ptr<AsmTyper::FunctionScope> fun_scope_; | 356 std::unique_ptr<AsmTyper::FunctionScope> fun_scope_; |
355 }; | 357 }; |
356 | 358 |
357 } // namespace wasm | 359 } // namespace wasm |
358 } // namespace internal | 360 } // namespace internal |
(...skipping 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2078 if (!ValidationOf(Module(kTests[ii])) | 2080 if (!ValidationOf(Module(kTests[ii])) |
2079 ->FailsWithMessage( | 2081 ->FailsWithMessage( |
2080 "Constant in return must be signed, float, or double.")) { | 2082 "Constant in return must be signed, float, or double.")) { |
2081 std::cerr << "Test:\n" << kTests[ii]; | 2083 std::cerr << "Test:\n" << kTests[ii]; |
2082 CHECK(false); | 2084 CHECK(false); |
2083 } | 2085 } |
2084 } | 2086 } |
2085 } | 2087 } |
2086 | 2088 |
2087 } // namespace | 2089 } // namespace |
OLD | NEW |