Chromium Code Reviews| 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 |
| 11 #include "src/ast/ast.h" | 11 #include "src/ast/ast.h" |
| 12 #include "src/ast/scopes.h" | 12 #include "src/ast/scopes.h" |
| 13 #include "src/codegen.h" | 13 #include "src/codegen.h" |
| 14 #include "src/type-cache.h" | 14 #include "src/type-cache.h" |
| 15 | 15 |
| 16 namespace v8 { | 16 namespace v8 { |
| 17 namespace internal { | 17 namespace internal { |
| 18 namespace wasm { | 18 namespace wasm { |
| 19 | 19 |
| 20 #define RECURSE(call) \ | 20 #define RECURSE(call) \ |
| 21 do { \ | 21 do { \ |
| 22 DCHECK(!HasStackOverflow()); \ | 22 DCHECK(!HasStackOverflow()); \ |
| 23 call; \ | 23 call; \ |
| 24 if (HasStackOverflow()) return; \ | 24 if (HasStackOverflow()) return; \ |
| 25 } while (false) | 25 } while (false) |
| 26 | 26 |
| 27 | 27 |
| 28 class AsmWasmBuilderImpl : public AstVisitor { | 28 class AsmWasmBuilderImpl : public AstVisitor { |
| 29 public: | 29 public: |
| 30 AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, FunctionLiteral* literal) | 30 AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, FunctionLiteral* literal, |
| 31 Handle<Object> foreign) | |
| 31 : local_variables_(HashMap::PointersMatch, | 32 : local_variables_(HashMap::PointersMatch, |
| 32 ZoneHashMap::kDefaultHashMapCapacity, | 33 ZoneHashMap::kDefaultHashMapCapacity, |
| 33 ZoneAllocationPolicy(zone)), | 34 ZoneAllocationPolicy(zone)), |
| 34 functions_(HashMap::PointersMatch, ZoneHashMap::kDefaultHashMapCapacity, | 35 functions_(HashMap::PointersMatch, ZoneHashMap::kDefaultHashMapCapacity, |
| 35 ZoneAllocationPolicy(zone)), | 36 ZoneAllocationPolicy(zone)), |
| 36 global_variables_(HashMap::PointersMatch, | 37 global_variables_(HashMap::PointersMatch, |
| 37 ZoneHashMap::kDefaultHashMapCapacity, | 38 ZoneHashMap::kDefaultHashMapCapacity, |
| 38 ZoneAllocationPolicy(zone)), | 39 ZoneAllocationPolicy(zone)), |
| 39 in_function_(false), | 40 in_function_(false), |
| 40 is_set_op_(false), | 41 is_set_op_(false), |
| 41 marking_exported(false), | 42 marking_exported(false), |
| 42 builder_(new (zone) WasmModuleBuilder(zone)), | 43 builder_(new (zone) WasmModuleBuilder(zone)), |
| 43 current_function_builder_(nullptr), | 44 current_function_builder_(nullptr), |
| 44 literal_(literal), | 45 literal_(literal), |
| 45 isolate_(isolate), | 46 isolate_(isolate), |
| 46 zone_(zone), | 47 zone_(zone), |
| 48 foreign_(foreign), | |
| 47 cache_(TypeCache::Get()), | 49 cache_(TypeCache::Get()), |
| 48 breakable_blocks_(zone), | 50 breakable_blocks_(zone), |
| 49 block_size_(0), | 51 block_size_(0), |
| 50 init_function_index_(0), | 52 init_function_index_(0), |
| 51 next_table_index_(0), | 53 next_table_index_(0), |
| 52 function_tables_(HashMap::PointersMatch, | 54 function_tables_(HashMap::PointersMatch, |
| 53 ZoneHashMap::kDefaultHashMapCapacity, | 55 ZoneHashMap::kDefaultHashMapCapacity, |
| 54 ZoneAllocationPolicy(zone)), | 56 ZoneAllocationPolicy(zone)), |
| 55 imported_function_table_(this) { | 57 imported_function_table_(this) { |
| 56 InitializeAstVisitor(isolate); | 58 InitializeAstVisitor(isolate); |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 552 function->AddParam(sig->GetParam(i)); | 554 function->AddParam(sig->GetParam(i)); |
| 553 } | 555 } |
| 554 return index; | 556 return index; |
| 555 } | 557 } |
| 556 } | 558 } |
| 557 }; | 559 }; |
| 558 | 560 |
| 559 void VisitAssignment(Assignment* expr) { | 561 void VisitAssignment(Assignment* expr) { |
| 560 bool in_init = false; | 562 bool in_init = false; |
| 561 if (!in_function_) { | 563 if (!in_function_) { |
| 564 BinaryOperation* binop = expr->value()->AsBinaryOperation(); | |
| 565 if (binop != nullptr) { | |
| 566 Property* prop = binop->left()->AsProperty(); | |
| 567 DCHECK(prop != nullptr); | |
| 568 LoadInitFunction(); | |
| 569 is_set_op_ = true; | |
| 570 RECURSE(Visit(expr->target())); | |
| 571 DCHECK(!is_set_op_); | |
| 572 if (binop->op() == Token::MUL) { | |
| 573 VisitForeignVariable(true, prop); | |
| 574 } else if (binop->op() == Token::BIT_OR) { | |
| 575 VisitForeignVariable(false, prop); | |
| 576 } else { | |
| 577 UNREACHABLE(); | |
| 578 } | |
| 579 UnLoadInitFunction(); | |
| 580 return; | |
| 581 } | |
| 562 // TODO(bradnelson): Get rid of this. | 582 // TODO(bradnelson): Get rid of this. |
| 563 if (TypeOf(expr->value()) == kAstStmt) { | 583 if (TypeOf(expr->value()) == kAstStmt) { |
| 564 Property* prop = expr->value()->AsProperty(); | 584 Property* prop = expr->value()->AsProperty(); |
| 565 if (prop != nullptr) { | 585 if (prop != nullptr) { |
| 566 VariableProxy* vp = prop->obj()->AsVariableProxy(); | 586 VariableProxy* vp = prop->obj()->AsVariableProxy(); |
| 567 if (vp != nullptr && vp->var()->IsParameter() && | 587 if (vp != nullptr && vp->var()->IsParameter() && |
| 568 vp->var()->index() == 1) { | 588 vp->var()->index() == 1) { |
| 569 VariableProxy* target = expr->target()->AsVariableProxy(); | 589 VariableProxy* target = expr->target()->AsVariableProxy(); |
| 570 if (target->bounds().lower->Is(Type::Function())) { | 590 if (target->bounds().lower->Is(Type::Function())) { |
| 571 const AstRawString* name = | 591 const AstRawString* name = |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 RECURSE(Visit(expr->value())); | 623 RECURSE(Visit(expr->value())); |
| 604 if (in_init) { | 624 if (in_init) { |
| 605 UnLoadInitFunction(); | 625 UnLoadInitFunction(); |
| 606 } | 626 } |
| 607 } | 627 } |
| 608 | 628 |
| 609 void VisitYield(Yield* expr) { UNREACHABLE(); } | 629 void VisitYield(Yield* expr) { UNREACHABLE(); } |
| 610 | 630 |
| 611 void VisitThrow(Throw* expr) { UNREACHABLE(); } | 631 void VisitThrow(Throw* expr) { UNREACHABLE(); } |
| 612 | 632 |
| 633 void VisitForeignVariable(bool is_float, Property* expr) { | |
| 634 VariableProxy* var_proxy = expr->obj()->AsVariableProxy(); | |
| 635 DCHECK(var_proxy != nullptr); | |
| 636 Variable* var = var_proxy->var(); | |
| 637 DCHECK(var->location() == VariableLocation::PARAMETER && var->index() == 1); | |
| 638 Literal* key_literal = expr->key()->AsLiteral(); | |
| 639 DCHECK(key_literal != nullptr); | |
| 640 double val = 0.0; | |
| 641 if (!key_literal->value().is_null() && !foreign_.is_null()) { | |
|
aseemgarg
2016/02/09 02:38:55
Not sure of these constructs. @Ben, can you review
bradnelson
2016/02/09 04:55:23
Yes please!
| |
| 642 Handle<Name> name = | |
| 643 i::Object::ToName(isolate_, key_literal->value()).ToHandleChecked(); | |
| 644 MaybeHandle<Object> maybe_value = i::Object::GetProperty(foreign_, name); | |
| 645 if (!maybe_value.is_null()) { | |
| 646 Handle<Object> value = maybe_value.ToHandleChecked(); | |
| 647 if (!value.is_null() && value->IsNumber()) { | |
| 648 val = static_cast<double>(value->Number()); | |
| 649 } | |
| 650 } | |
| 651 } | |
| 652 if (is_float) { | |
| 653 byte code[] = {WASM_F64(val)}; | |
| 654 current_function_builder_->EmitCode(code, sizeof(code)); | |
| 655 } else { | |
| 656 byte code[] = {WASM_I32(static_cast<int32_t>(val))}; | |
| 657 current_function_builder_->EmitCode(code, sizeof(code)); | |
| 658 } | |
| 659 } | |
| 660 | |
| 613 void VisitProperty(Property* expr) { | 661 void VisitProperty(Property* expr) { |
| 614 Expression* obj = expr->obj(); | 662 Expression* obj = expr->obj(); |
| 615 DCHECK(obj->bounds().lower == obj->bounds().upper); | 663 DCHECK(obj->bounds().lower == obj->bounds().upper); |
| 616 Type* type = obj->bounds().lower; | 664 Type* type = obj->bounds().lower; |
| 617 MachineType mtype; | 665 MachineType mtype; |
| 618 int size; | 666 int size; |
| 619 if (type->Is(cache_.kUint8Array)) { | 667 if (type->Is(cache_.kUint8Array)) { |
| 620 mtype = MachineType::Uint8(); | 668 mtype = MachineType::Uint8(); |
| 621 size = 1; | 669 size = 1; |
| 622 } else if (type->Is(cache_.kInt8Array)) { | 670 } else if (type->Is(cache_.kInt8Array)) { |
| (...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1166 ZoneHashMap functions_; | 1214 ZoneHashMap functions_; |
| 1167 ZoneHashMap global_variables_; | 1215 ZoneHashMap global_variables_; |
| 1168 bool in_function_; | 1216 bool in_function_; |
| 1169 bool is_set_op_; | 1217 bool is_set_op_; |
| 1170 bool marking_exported; | 1218 bool marking_exported; |
| 1171 WasmModuleBuilder* builder_; | 1219 WasmModuleBuilder* builder_; |
| 1172 WasmFunctionBuilder* current_function_builder_; | 1220 WasmFunctionBuilder* current_function_builder_; |
| 1173 FunctionLiteral* literal_; | 1221 FunctionLiteral* literal_; |
| 1174 Isolate* isolate_; | 1222 Isolate* isolate_; |
| 1175 Zone* zone_; | 1223 Zone* zone_; |
| 1224 Handle<Object> foreign_; | |
| 1176 TypeCache const& cache_; | 1225 TypeCache const& cache_; |
| 1177 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; | 1226 ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; |
| 1178 int block_size_; | 1227 int block_size_; |
| 1179 uint16_t init_function_index_; | 1228 uint16_t init_function_index_; |
| 1180 uint32_t next_table_index_; | 1229 uint32_t next_table_index_; |
| 1181 ZoneHashMap function_tables_; | 1230 ZoneHashMap function_tables_; |
| 1182 ImportedFunctionTable imported_function_table_; | 1231 ImportedFunctionTable imported_function_table_; |
| 1183 | 1232 |
| 1184 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | 1233 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
| 1185 | 1234 |
| 1186 private: | 1235 private: |
| 1187 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); | 1236 DISALLOW_COPY_AND_ASSIGN(AsmWasmBuilderImpl); |
| 1188 }; | 1237 }; |
| 1189 | 1238 |
| 1190 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, | 1239 AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, |
| 1191 FunctionLiteral* literal) | 1240 FunctionLiteral* literal, Handle<Object> foreign) |
| 1192 : isolate_(isolate), zone_(zone), literal_(literal) {} | 1241 : isolate_(isolate), zone_(zone), literal_(literal), foreign_(foreign) {} |
| 1193 | 1242 |
| 1194 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so | 1243 // TODO(aseemgarg): probably should take zone (to write wasm to) as input so |
| 1195 // that zone in constructor may be thrown away once wasm module is written. | 1244 // that zone in constructor may be thrown away once wasm module is written. |
| 1196 WasmModuleIndex* AsmWasmBuilder::Run() { | 1245 WasmModuleIndex* AsmWasmBuilder::Run() { |
| 1197 AsmWasmBuilderImpl impl(isolate_, zone_, literal_); | 1246 AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_); |
| 1198 impl.Compile(); | 1247 impl.Compile(); |
| 1199 WasmModuleWriter* writer = impl.builder_->Build(zone_); | 1248 WasmModuleWriter* writer = impl.builder_->Build(zone_); |
| 1200 return writer->WriteTo(zone_); | 1249 return writer->WriteTo(zone_); |
| 1201 } | 1250 } |
| 1202 } // namespace wasm | 1251 } // namespace wasm |
| 1203 } // namespace internal | 1252 } // namespace internal |
| 1204 } // namespace v8 | 1253 } // namespace v8 |
| OLD | NEW |