| 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 |