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 |