OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/wasm/asm-wasm-builder.h" | 7 #include "src/wasm/asm-wasm-builder.h" |
8 #include "src/wasm/wasm-macro-gen.h" | 8 #include "src/wasm/wasm-macro-gen.h" |
9 #include "src/wasm/wasm-opcodes.h" | 9 #include "src/wasm/wasm-opcodes.h" |
10 | 10 |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 current_function_builder_->Emit(kExprReturn); | 178 current_function_builder_->Emit(kExprReturn); |
179 } else { | 179 } else { |
180 marking_exported = true; | 180 marking_exported = true; |
181 } | 181 } |
182 RECURSE(Visit(stmt->expression())); | 182 RECURSE(Visit(stmt->expression())); |
183 if (!in_function_) { | 183 if (!in_function_) { |
184 marking_exported = false; | 184 marking_exported = false; |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 void VisitWithStatement(WithStatement* stmt) { | 188 void VisitWithStatement(WithStatement* stmt) { UNREACHABLE(); } |
189 RECURSE(stmt->expression()); | |
190 RECURSE(stmt->statement()); | |
191 } | |
192 | 189 |
193 void VisitSwitchStatement(SwitchStatement* stmt) { | 190 void VisitSwitchStatement(SwitchStatement* stmt) { |
194 RECURSE(Visit(stmt->tag())); | 191 RECURSE(Visit(stmt->tag())); |
195 | 192 |
196 ZoneList<CaseClause*>* clauses = stmt->cases(); | 193 ZoneList<CaseClause*>* clauses = stmt->cases(); |
197 | 194 |
198 for (int i = 0; i < clauses->length(); ++i) { | 195 for (int i = 0; i < clauses->length(); ++i) { |
199 CaseClause* clause = clauses->at(i); | 196 CaseClause* clause = clauses->at(i); |
200 if (!clause->is_default()) { | 197 if (!clause->is_default()) { |
201 Expression* label = clause->label(); | 198 Expression* label = clause->label(); |
202 RECURSE(Visit(label)); | 199 RECURSE(Visit(label)); |
203 } | 200 } |
204 ZoneList<Statement*>* stmts = clause->statements(); | 201 ZoneList<Statement*>* stmts = clause->statements(); |
205 RECURSE(VisitStatements(stmts)); | 202 RECURSE(VisitStatements(stmts)); |
206 } | 203 } |
207 } | 204 } |
208 | 205 |
209 void VisitCaseClause(CaseClause* clause) { UNREACHABLE(); } | 206 void VisitCaseClause(CaseClause* clause) { UNREACHABLE(); } |
210 | 207 |
211 void VisitDoWhileStatement(DoWhileStatement* stmt) { | 208 void VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 209 DCHECK(in_function_); |
| 210 current_function_builder_->Emit(kExprLoop); |
| 211 uint32_t index = current_function_builder_->EmitEditableImmediate(0); |
| 212 int prev_block_size = block_size_; |
| 213 block_size_ = 0; |
| 214 breakable_blocks_.push_back( |
| 215 std::make_pair(stmt->AsBreakableStatement(), true)); |
| 216 block_size_++; |
212 RECURSE(Visit(stmt->body())); | 217 RECURSE(Visit(stmt->body())); |
| 218 block_size_++; |
| 219 current_function_builder_->Emit(kExprIf); |
213 RECURSE(Visit(stmt->cond())); | 220 RECURSE(Visit(stmt->cond())); |
| 221 current_function_builder_->EmitWithU8(kExprBr, 0); |
| 222 current_function_builder_->Emit(kExprNop); |
| 223 current_function_builder_->EditImmediate(index, block_size_); |
| 224 block_size_ = prev_block_size; |
| 225 breakable_blocks_.pop_back(); |
214 } | 226 } |
215 | 227 |
216 void VisitWhileStatement(WhileStatement* stmt) { | 228 void VisitWhileStatement(WhileStatement* stmt) { |
217 DCHECK(in_function_); | 229 DCHECK(in_function_); |
218 current_function_builder_->EmitWithU8(kExprLoop, 1); | 230 current_function_builder_->EmitWithU8(kExprLoop, 1); |
219 breakable_blocks_.push_back( | 231 breakable_blocks_.push_back( |
220 std::make_pair(stmt->AsBreakableStatement(), true)); | 232 std::make_pair(stmt->AsBreakableStatement(), true)); |
221 current_function_builder_->Emit(kExprIf); | 233 current_function_builder_->Emit(kExprIf); |
222 RECURSE(Visit(stmt->cond())); | 234 RECURSE(Visit(stmt->cond())); |
223 current_function_builder_->EmitWithU8(kExprBr, 0); | 235 current_function_builder_->EmitWithU8(kExprBr, 0); |
(...skipping 30 matching lines...) Expand all Loading... |
254 RECURSE(Visit(stmt->next())); | 266 RECURSE(Visit(stmt->next())); |
255 } | 267 } |
256 block_size_++; | 268 block_size_++; |
257 current_function_builder_->EmitWithU8(kExprBr, 0); | 269 current_function_builder_->EmitWithU8(kExprBr, 0); |
258 current_function_builder_->Emit(kExprNop); | 270 current_function_builder_->Emit(kExprNop); |
259 current_function_builder_->EditImmediate(index, block_size_); | 271 current_function_builder_->EditImmediate(index, block_size_); |
260 block_size_ = prev_block_size; | 272 block_size_ = prev_block_size; |
261 breakable_blocks_.pop_back(); | 273 breakable_blocks_.pop_back(); |
262 } | 274 } |
263 | 275 |
264 void VisitForInStatement(ForInStatement* stmt) { | 276 void VisitForInStatement(ForInStatement* stmt) { UNREACHABLE(); } |
265 RECURSE(Visit(stmt->enumerable())); | |
266 RECURSE(Visit(stmt->body())); | |
267 } | |
268 | 277 |
269 void VisitForOfStatement(ForOfStatement* stmt) { | 278 void VisitForOfStatement(ForOfStatement* stmt) { UNREACHABLE(); } |
270 RECURSE(Visit(stmt->iterable())); | |
271 RECURSE(Visit(stmt->body())); | |
272 } | |
273 | 279 |
274 void VisitTryCatchStatement(TryCatchStatement* stmt) { | 280 void VisitTryCatchStatement(TryCatchStatement* stmt) { UNREACHABLE(); } |
275 RECURSE(Visit(stmt->try_block())); | |
276 RECURSE(Visit(stmt->catch_block())); | |
277 } | |
278 | 281 |
279 void VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 282 void VisitTryFinallyStatement(TryFinallyStatement* stmt) { UNREACHABLE(); } |
280 RECURSE(Visit(stmt->try_block())); | |
281 RECURSE(Visit(stmt->finally_block())); | |
282 } | |
283 | 283 |
284 void VisitDebuggerStatement(DebuggerStatement* stmt) {} | 284 void VisitDebuggerStatement(DebuggerStatement* stmt) { UNREACHABLE(); } |
285 | 285 |
286 void VisitFunctionLiteral(FunctionLiteral* expr) { | 286 void VisitFunctionLiteral(FunctionLiteral* expr) { |
287 Scope* scope = expr->scope(); | 287 Scope* scope = expr->scope(); |
288 if (in_function_) { | 288 if (in_function_) { |
289 if (expr->bounds().lower->IsFunction()) { | 289 if (expr->bounds().lower->IsFunction()) { |
290 Type::FunctionType* func_type = expr->bounds().lower->AsFunction(); | 290 Type::FunctionType* func_type = expr->bounds().lower->AsFunction(); |
291 LocalType return_type = TypeFrom(func_type->Result()); | 291 LocalType return_type = TypeFrom(func_type->Result()); |
292 current_function_builder_->ReturnType(return_type); | 292 current_function_builder_->ReturnType(return_type); |
293 for (int i = 0; i < expr->parameter_count(); i++) { | 293 for (int i = 0; i < expr->parameter_count(); i++) { |
294 LocalType type = TypeFrom(func_type->Parameter(i)); | 294 LocalType type = TypeFrom(func_type->Parameter(i)); |
295 DCHECK(type != kAstStmt); | 295 DCHECK(type != kAstStmt); |
296 LookupOrInsertLocal(scope->parameter(i), type); | 296 LookupOrInsertLocal(scope->parameter(i), type); |
297 } | 297 } |
298 } else { | 298 } else { |
299 UNREACHABLE(); | 299 UNREACHABLE(); |
300 } | 300 } |
301 } | 301 } |
302 RECURSE(VisitDeclarations(scope->declarations())); | 302 RECURSE(VisitDeclarations(scope->declarations())); |
303 RECURSE(VisitStatements(expr->body())); | 303 RECURSE(VisitStatements(expr->body())); |
304 } | 304 } |
305 | 305 |
306 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {} | 306 void VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) { |
| 307 UNREACHABLE(); |
| 308 } |
307 | 309 |
308 void VisitConditional(Conditional* expr) { | 310 void VisitConditional(Conditional* expr) { |
| 311 DCHECK(in_function_); |
| 312 current_function_builder_->Emit(kExprIfElse); |
309 RECURSE(Visit(expr->condition())); | 313 RECURSE(Visit(expr->condition())); |
310 RECURSE(Visit(expr->then_expression())); | 314 RECURSE(Visit(expr->then_expression())); |
311 RECURSE(Visit(expr->else_expression())); | 315 RECURSE(Visit(expr->else_expression())); |
312 } | 316 } |
313 | 317 |
314 void VisitVariableProxy(VariableProxy* expr) { | 318 void VisitVariableProxy(VariableProxy* expr) { |
315 if (in_function_) { | 319 if (in_function_) { |
316 Variable* var = expr->var(); | 320 Variable* var = expr->var(); |
317 if (var->is_function()) { | 321 if (var->is_function()) { |
318 DCHECK(!is_set_op_); | 322 DCHECK(!is_set_op_); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
375 current_function_builder_->EmitCode(code, sizeof(code)); | 379 current_function_builder_->EmitCode(code, sizeof(code)); |
376 break; | 380 break; |
377 } | 381 } |
378 default: | 382 default: |
379 UNREACHABLE(); | 383 UNREACHABLE(); |
380 } | 384 } |
381 } | 385 } |
382 } | 386 } |
383 } | 387 } |
384 | 388 |
385 void VisitRegExpLiteral(RegExpLiteral* expr) {} | 389 void VisitRegExpLiteral(RegExpLiteral* expr) { UNREACHABLE(); } |
386 | 390 |
387 void VisitObjectLiteral(ObjectLiteral* expr) { | 391 void VisitObjectLiteral(ObjectLiteral* expr) { |
388 ZoneList<ObjectLiteralProperty*>* props = expr->properties(); | 392 ZoneList<ObjectLiteralProperty*>* props = expr->properties(); |
389 for (int i = 0; i < props->length(); ++i) { | 393 for (int i = 0; i < props->length(); ++i) { |
390 ObjectLiteralProperty* prop = props->at(i); | 394 ObjectLiteralProperty* prop = props->at(i); |
391 RECURSE(Visit(prop->value())); | 395 RECURSE(Visit(prop->value())); |
392 } | 396 } |
393 } | 397 } |
394 | 398 |
395 void VisitArrayLiteral(ArrayLiteral* expr) { | 399 void VisitArrayLiteral(ArrayLiteral* expr) { UNREACHABLE(); } |
396 ZoneList<Expression*>* values = expr->values(); | |
397 for (int i = 0; i < values->length(); ++i) { | |
398 Expression* value = values->at(i); | |
399 RECURSE(Visit(value)); | |
400 } | |
401 } | |
402 | 400 |
403 void LoadInitFunction() { | 401 void LoadInitFunction() { |
404 if (!init_function_initialized) { | 402 if (!init_function_initialized) { |
405 init_function_initialized = true; | 403 init_function_initialized = true; |
406 unsigned char init[] = "__init__"; | 404 unsigned char init[] = "__init__"; |
407 init_function_index = builder_->AddFunction(init, 8); | 405 init_function_index = builder_->AddFunction(init, 8); |
408 current_function_builder_ = builder_->FunctionAt(init_function_index); | 406 current_function_builder_ = builder_->FunctionAt(init_function_index); |
409 current_function_builder_->ReturnType(kAstStmt); | 407 current_function_builder_->ReturnType(kAstStmt); |
410 current_function_builder_->Exported(1); | 408 current_function_builder_->Exported(1); |
411 in_function_ = true; | 409 in_function_ = true; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 } | 441 } |
444 is_set_op_ = true; | 442 is_set_op_ = true; |
445 RECURSE(Visit(expr->target())); | 443 RECURSE(Visit(expr->target())); |
446 DCHECK(!is_set_op_); | 444 DCHECK(!is_set_op_); |
447 RECURSE(Visit(expr->value())); | 445 RECURSE(Visit(expr->value())); |
448 if (in_init) { | 446 if (in_init) { |
449 UnLoadInitFunction(); | 447 UnLoadInitFunction(); |
450 } | 448 } |
451 } | 449 } |
452 | 450 |
453 void VisitYield(Yield* expr) { | 451 void VisitYield(Yield* expr) { UNREACHABLE(); } |
454 RECURSE(Visit(expr->generator_object())); | |
455 RECURSE(Visit(expr->expression())); | |
456 } | |
457 | 452 |
458 void VisitThrow(Throw* expr) { RECURSE(Visit(expr->exception())); } | 453 void VisitThrow(Throw* expr) { UNREACHABLE(); } |
459 | 454 |
460 void VisitProperty(Property* expr) { | 455 void VisitProperty(Property* expr) { |
461 Expression* obj = expr->obj(); | 456 Expression* obj = expr->obj(); |
462 DCHECK(obj->bounds().lower == obj->bounds().upper); | 457 DCHECK(obj->bounds().lower == obj->bounds().upper); |
463 TypeImpl<ZoneTypeConfig>* type = obj->bounds().lower; | 458 TypeImpl<ZoneTypeConfig>* type = obj->bounds().lower; |
464 MachineType mtype; | 459 MachineType mtype; |
465 int size; | 460 int size; |
466 if (type->Is(cache_.kUint8Array)) { | 461 if (type->Is(cache_.kUint8Array)) { |
467 mtype = MachineType::Uint8(); | 462 mtype = MachineType::Uint8(); |
468 size = 1; | 463 size = 1; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
553 DCHECK(TypeOf(expr->expression()) == kAstI32); | 548 DCHECK(TypeOf(expr->expression()) == kAstI32); |
554 current_function_builder_->Emit(kExprBoolNot); | 549 current_function_builder_->Emit(kExprBoolNot); |
555 break; | 550 break; |
556 } | 551 } |
557 default: | 552 default: |
558 UNREACHABLE(); | 553 UNREACHABLE(); |
559 } | 554 } |
560 RECURSE(Visit(expr->expression())); | 555 RECURSE(Visit(expr->expression())); |
561 } | 556 } |
562 | 557 |
563 void VisitCountOperation(CountOperation* expr) { | 558 void VisitCountOperation(CountOperation* expr) { UNREACHABLE(); } |
564 RECURSE(Visit(expr->expression())); | |
565 } | |
566 | 559 |
567 bool MatchIntBinaryOperation(BinaryOperation* expr, Token::Value op, | 560 bool MatchIntBinaryOperation(BinaryOperation* expr, Token::Value op, |
568 int32_t val) { | 561 int32_t val) { |
569 DCHECK(expr->right() != NULL); | 562 DCHECK(expr->right() != NULL); |
570 if (expr->op() == op && expr->right()->IsLiteral() && | 563 if (expr->op() == op && expr->right()->IsLiteral() && |
571 TypeOf(expr) == kAstI32) { | 564 TypeOf(expr) == kAstI32) { |
572 Literal* right = expr->right()->AsLiteral(); | 565 Literal* right = expr->right()->AsLiteral(); |
573 DCHECK(right->raw_value()->IsNumber()); | 566 DCHECK(right->raw_value()->IsNumber()); |
574 if (static_cast<int32_t>(right->raw_value()->AsNumber()) == val) { | 567 if (static_cast<int32_t>(right->raw_value()->AsNumber()) == val) { |
575 return true; | 568 return true; |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
858 UNREACHABLE(); | 851 UNREACHABLE(); |
859 return kInt32; | 852 return kInt32; |
860 } | 853 } |
861 } | 854 } |
862 | 855 |
863 #undef CASE | 856 #undef CASE |
864 #undef NON_SIGNED_INT | 857 #undef NON_SIGNED_INT |
865 #undef SIGNED | 858 #undef SIGNED |
866 #undef NON_SIGNED | 859 #undef NON_SIGNED |
867 | 860 |
868 void VisitThisFunction(ThisFunction* expr) {} | 861 void VisitThisFunction(ThisFunction* expr) { UNREACHABLE(); } |
869 | 862 |
870 void VisitDeclarations(ZoneList<Declaration*>* decls) { | 863 void VisitDeclarations(ZoneList<Declaration*>* decls) { |
871 for (int i = 0; i < decls->length(); ++i) { | 864 for (int i = 0; i < decls->length(); ++i) { |
872 Declaration* decl = decls->at(i); | 865 Declaration* decl = decls->at(i); |
873 RECURSE(Visit(decl)); | 866 RECURSE(Visit(decl)); |
874 } | 867 } |
875 } | 868 } |
876 | 869 |
877 void VisitClassLiteral(ClassLiteral* expr) {} | 870 void VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); } |
878 | 871 |
879 void VisitSpread(Spread* expr) {} | 872 void VisitSpread(Spread* expr) { UNREACHABLE(); } |
880 | 873 |
881 void VisitSuperPropertyReference(SuperPropertyReference* expr) {} | 874 void VisitSuperPropertyReference(SuperPropertyReference* expr) { |
| 875 UNREACHABLE(); |
| 876 } |
882 | 877 |
883 void VisitSuperCallReference(SuperCallReference* expr) {} | 878 void VisitSuperCallReference(SuperCallReference* expr) { UNREACHABLE(); } |
884 | 879 |
885 void VisitSloppyBlockFunctionStatement(SloppyBlockFunctionStatement* expr) {} | 880 void VisitSloppyBlockFunctionStatement(SloppyBlockFunctionStatement* expr) { |
| 881 UNREACHABLE(); |
| 882 } |
886 | 883 |
887 void VisitDoExpression(DoExpression* expr) {} | 884 void VisitDoExpression(DoExpression* expr) { UNREACHABLE(); } |
888 | 885 |
889 void VisitRewritableAssignmentExpression( | 886 void VisitRewritableAssignmentExpression( |
890 RewritableAssignmentExpression* expr) {} | 887 RewritableAssignmentExpression* expr) { |
| 888 UNREACHABLE(); |
| 889 } |
891 | 890 |
892 struct IndexContainer : public ZoneObject { | 891 struct IndexContainer : public ZoneObject { |
893 uint16_t index; | 892 uint16_t index; |
894 }; | 893 }; |
895 | 894 |
896 uint16_t LookupOrInsertLocal(Variable* v, LocalType type) { | 895 uint16_t LookupOrInsertLocal(Variable* v, LocalType type) { |
897 DCHECK(current_function_builder_ != NULL); | 896 DCHECK(current_function_builder_ != NULL); |
898 ZoneHashMap::Entry* entry = | 897 ZoneHashMap::Entry* entry = |
899 local_variables_.Lookup(v, ComputePointerHash(v)); | 898 local_variables_.Lookup(v, ComputePointerHash(v)); |
900 if (entry == NULL) { | 899 if (entry == NULL) { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
993 // that zone in constructor may be thrown away once wasm module is written. | 992 // that zone in constructor may be thrown away once wasm module is written. |
994 WasmModuleIndex* AsmWasmBuilder::Run() { | 993 WasmModuleIndex* AsmWasmBuilder::Run() { |
995 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); | 994 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); |
996 impl.Compile(); | 995 impl.Compile(); |
997 WasmModuleWriter* writer = impl.builder_->Build(zone_); | 996 WasmModuleWriter* writer = impl.builder_->Build(zone_); |
998 return writer->WriteTo(zone_); | 997 return writer->WriteTo(zone_); |
999 } | 998 } |
1000 } // namespace wasm | 999 } // namespace wasm |
1001 } // namespace internal | 1000 } // namespace internal |
1002 } // namespace v8 | 1001 } // namespace v8 |
OLD | NEW |