| 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..5e7765adfdcdd8905762892e75cbbee07325649c 100644
|
| --- a/src/wasm/asm-wasm-builder.cc
|
| +++ b/src/wasm/asm-wasm-builder.cc
|
| @@ -33,10 +33,16 @@ namespace wasm {
|
|
|
| enum AsmScope { kModuleScope, kInitScope, kFuncScope, kExportScope };
|
|
|
| +struct ForeignVariable {
|
| + Handle<Name> name;
|
| + Variable* var;
|
| + LocalType type;
|
| +};
|
| +
|
| 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 +57,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 +81,43 @@ 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) {
|
| + b.AddParam(i->type);
|
| + }
|
| + 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];
|
| + uint32_t index = LookupOrInsertGlobal(fv->var, fv->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 +747,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 +880,18 @@ 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));
|
| + LocalType type = is_float ? kAstF64 : kAstI32;
|
| + foreign_variables_.push_back({name, var, type});
|
| }
|
| }
|
|
|
| @@ -1724,11 +1736,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 +1754,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_);
|
| }
|
|
|