Chromium Code Reviews| Index: src/wasm/asm-wasm-builder.cc |
| diff --git a/src/wasm/asm-wasm-builder.cc b/src/wasm/asm-wasm-builder.cc |
| index 325058c6db116d509108839fcf704e9900b03062..495fc64496af5fb5344b766d73051e533a11a7ce 100644 |
| --- a/src/wasm/asm-wasm-builder.cc |
| +++ b/src/wasm/asm-wasm-builder.cc |
| @@ -36,7 +36,7 @@ enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope }; |
| class AsmWasmBuilderImpl : public AstVisitor { |
| public: |
| AsmWasmBuilderImpl(Isolate* isolate, Zone* zone, FunctionLiteral* literal, |
| - Handle<Object> foreign, AsmTyper* typer) |
| + AsmTyper* typer) |
| : local_variables_(HashMap::PointersMatch, |
| ZoneHashMap::kDefaultHashMapCapacity, |
| ZoneAllocationPolicy(zone)), |
| @@ -51,11 +51,12 @@ class AsmWasmBuilderImpl : public AstVisitor { |
| literal_(literal), |
| isolate_(isolate), |
| zone_(zone), |
| - foreign_(foreign), |
| typer_(typer), |
| cache_(TypeCache::Get()), |
| breakable_blocks_(zone), |
| + foreign_variables_(zone), |
| init_function_index_(0), |
| + foreign_init_function_index_(0), |
| next_table_index_(0), |
| function_tables_(HashMap::PointersMatch, |
| ZoneHashMap::kDefaultHashMapCapacity, |
| @@ -74,9 +75,48 @@ class AsmWasmBuilderImpl : public AstVisitor { |
| current_function_builder_ = nullptr; |
| } |
| + void BuildForeignInitFunction() { |
| + foreign_init_function_index_ = builder_->AddFunction(); |
| + FunctionSig::Builder b(zone(), 0, foreign_variables_.size()); |
| + for (auto i = foreign_variables_.begin(); i != foreign_variables_.end(); |
| + ++i) { |
| + if (i->is_float) { |
| + b.AddParam(kAstF64); |
| + } else { |
| + b.AddParam(kAstI32); |
| + } |
| + } |
| + current_function_builder_ = |
| + builder_->FunctionAt(foreign_init_function_index_); |
| + current_function_builder_->Exported(1); |
| + std::string raw_name = "__foreign_init__"; |
| + current_function_builder_->SetName(raw_name.data(), |
| + static_cast<int>(raw_name.size())); |
| + current_function_builder_->SetSignature(b.Build()); |
| + for (size_t pos = 0; pos < foreign_variables_.size(); ++pos) { |
| + current_function_builder_->EmitGetLocal(static_cast<uint32_t>(pos)); |
| + ForeignVariable* fv = &foreign_variables_[pos]; |
| + LocalType var_type = fv->is_float ? kAstF64 : kAstI32; |
| + uint32_t index = LookupOrInsertGlobal(fv->var, var_type); |
| + current_function_builder_->EmitWithVarInt(kExprStoreGlobal, index); |
| + } |
| + current_function_builder_ = nullptr; |
| + } |
| + |
| + i::Handle<i::FixedArray> GetForeignArgs() { |
| + i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray( |
| + static_cast<int>(foreign_variables_.size())); |
| + for (size_t i = 0; i < foreign_variables_.size(); ++i) { |
| + ForeignVariable* fv = &foreign_variables_[i]; |
| + ret->set(static_cast<int>(i), *fv->name); |
| + } |
| + return ret; |
| + } |
| + |
| void Compile() { |
| InitializeInitFunction(); |
| RECURSE(VisitFunctionLiteral(literal_)); |
| + BuildForeignInitFunction(); |
| } |
| void VisitVariableDeclaration(VariableDeclaration* decl) {} |
| @@ -706,13 +746,17 @@ class AsmWasmBuilderImpl : public AstVisitor { |
| DCHECK(binop->right()->IsLiteral()); |
| DCHECK_EQ(1.0, binop->right()->AsLiteral()->raw_value()->AsNumber()); |
| DCHECK(binop->right()->AsLiteral()->raw_value()->ContainsDot()); |
| - VisitForeignVariable(true, prop); |
| + DCHECK(target->IsVariableProxy()); |
| + VisitForeignVariable(true, target->AsVariableProxy()->var(), prop); |
| + *is_nop = true; |
| return; |
| } else if (binop->op() == Token::BIT_OR) { |
| DCHECK(binop->right()->IsLiteral()); |
| DCHECK_EQ(0.0, binop->right()->AsLiteral()->raw_value()->AsNumber()); |
| DCHECK(!binop->right()->AsLiteral()->raw_value()->ContainsDot()); |
| - VisitForeignVariable(false, prop); |
| + DCHECK(target->IsVariableProxy()); |
| + VisitForeignVariable(false, target->AsVariableProxy()->var(), prop); |
| + *is_nop = true; |
| return; |
| } else { |
| UNREACHABLE(); |
| @@ -835,51 +879,21 @@ class AsmWasmBuilderImpl : public AstVisitor { |
| void VisitThrow(Throw* expr) { UNREACHABLE(); } |
| - void VisitForeignVariable(bool is_float, Property* expr) { |
| + void VisitForeignVariable(bool is_float, Variable* var, Property* expr) { |
| DCHECK(expr->obj()->AsVariableProxy()); |
| DCHECK(VariableLocation::PARAMETER == |
| expr->obj()->AsVariableProxy()->var()->location()); |
| DCHECK_EQ(1, expr->obj()->AsVariableProxy()->var()->index()); |
| Literal* key_literal = expr->key()->AsLiteral(); |
| DCHECK_NOT_NULL(key_literal); |
| - if (!key_literal->value().is_null() && !foreign_.is_null() && |
| - foreign_->IsObject()) { |
| + if (!key_literal->value().is_null()) { |
| Handle<Name> name = |
| i::Object::ToName(isolate_, key_literal->value()).ToHandleChecked(); |
| - MaybeHandle<Object> maybe_value = i::Object::GetProperty(foreign_, name); |
| - if (!maybe_value.is_null()) { |
| - Handle<Object> value = maybe_value.ToHandleChecked(); |
| - if (is_float) { |
| - MaybeHandle<Object> maybe_nvalue = i::Object::ToNumber(value); |
| - if (!maybe_nvalue.is_null()) { |
| - Handle<Object> nvalue = maybe_nvalue.ToHandleChecked(); |
| - if (nvalue->IsNumber()) { |
| - double val = nvalue->Number(); |
| - byte code[] = {WASM_F64(val)}; |
| - current_function_builder_->EmitCode(code, sizeof(code)); |
| - return; |
| - } |
| - } |
| - } else { |
| - MaybeHandle<Object> maybe_nvalue = |
| - i::Object::ToInt32(isolate_, value); |
| - if (!maybe_nvalue.is_null()) { |
| - Handle<Object> nvalue = maybe_nvalue.ToHandleChecked(); |
| - if (nvalue->IsNumber()) { |
| - int32_t val = static_cast<int32_t>(nvalue->Number()); |
| - current_function_builder_->EmitI32Const(val); |
| - return; |
| - } |
| - } |
| - } |
| - } |
| - } |
| - if (is_float) { |
| - byte code[] = {WASM_F64(std::numeric_limits<double>::quiet_NaN())}; |
| - current_function_builder_->EmitCode(code, sizeof(code)); |
| - } else { |
| - byte code[] = {WASM_I32V_1(0)}; |
| - current_function_builder_->EmitCode(code, sizeof(code)); |
| + ForeignVariable foreign; |
| + foreign.name = name; |
| + foreign.var = var; |
| + foreign.is_float = is_float; |
| + foreign_variables_.push_back(foreign); |
|
titzer
2016/05/20 11:39:59
Could you just do push_back({...})?
bradn
2016/05/20 14:37:32
Done.
|
| } |
| } |
| @@ -1713,6 +1727,12 @@ class AsmWasmBuilderImpl : public AstVisitor { |
| } |
| } |
| + struct ForeignVariable { |
|
titzer
2016/05/20 11:39:59
Can you move this to the top?
bradn
2016/05/20 14:37:32
Done.
|
| + Variable* var; |
| + Handle<Name> name; |
| + bool is_float; |
|
titzer
2016/05/20 11:39:59
Should we store the AST type here instead of a boo
bradn
2016/05/20 14:37:32
Done.
|
| + }; |
| + |
| Zone* zone() { return zone_; } |
| ZoneHashMap local_variables_; |
| @@ -1724,11 +1744,12 @@ class AsmWasmBuilderImpl : public AstVisitor { |
| FunctionLiteral* literal_; |
| Isolate* isolate_; |
| Zone* zone_; |
| - Handle<Object> foreign_; |
| AsmTyper* typer_; |
| TypeCache const& cache_; |
| ZoneVector<std::pair<BreakableStatement*, bool>> breakable_blocks_; |
| + ZoneVector<ForeignVariable> foreign_variables_; |
| uint32_t init_function_index_; |
| + uint32_t foreign_init_function_index_; |
| uint32_t next_table_index_; |
| ZoneHashMap function_tables_; |
| ImportedFunctionTable imported_function_table_; |
| @@ -1741,19 +1762,15 @@ class AsmWasmBuilderImpl : public AstVisitor { |
| }; |
| AsmWasmBuilder::AsmWasmBuilder(Isolate* isolate, Zone* zone, |
| - FunctionLiteral* literal, Handle<Object> foreign, |
| - AsmTyper* typer) |
| - : isolate_(isolate), |
| - zone_(zone), |
| - literal_(literal), |
| - foreign_(foreign), |
| - typer_(typer) {} |
| + FunctionLiteral* literal, AsmTyper* typer) |
| + : isolate_(isolate), zone_(zone), literal_(literal), typer_(typer) {} |
| // TODO(aseemgarg): probably should take zone (to write wasm to) as input so |
| // that zone in constructor may be thrown away once wasm module is written. |
| -WasmModuleIndex* AsmWasmBuilder::Run() { |
| - AsmWasmBuilderImpl impl(isolate_, zone_, literal_, foreign_, typer_); |
| +WasmModuleIndex* AsmWasmBuilder::Run(i::Handle<i::FixedArray>* foreign_args) { |
| + AsmWasmBuilderImpl impl(isolate_, zone_, literal_, typer_); |
| impl.Compile(); |
| + *foreign_args = impl.GetForeignArgs(); |
| WasmModuleWriter* writer = impl.builder_->Build(zone_); |
| return writer->WriteTo(zone_); |
| } |