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 |