Index: src/wasm/asm-wasm-builder.cc |
diff --git a/src/wasm/asm-wasm-builder.cc b/src/wasm/asm-wasm-builder.cc |
index fae07e98e56d969b9712515a0934135b7fedf76e..1d5e674e1c8b59e8c23e0ab8dcbccc847da92c51 100644 |
--- a/src/wasm/asm-wasm-builder.cc |
+++ b/src/wasm/asm-wasm-builder.cc |
@@ -51,7 +51,8 @@ class AsmWasmBuilderImpl : public AstVisitor { |
next_table_index_(0), |
function_tables_(HashMap::PointersMatch, |
ZoneHashMap::kDefaultHashMapCapacity, |
- ZoneAllocationPolicy(zone)) { |
+ ZoneAllocationPolicy(zone)), |
+ imported_function_table_(this) { |
InitializeAstVisitor(isolate); |
} |
@@ -367,35 +368,27 @@ class AsmWasmBuilderImpl : public AstVisitor { |
void VisitVariableProxy(VariableProxy* expr) { |
if (in_function_) { |
Variable* var = expr->var(); |
- if (var->is_function()) { |
- DCHECK(!is_set_op_); |
- std::vector<uint8_t> index = |
- UnsignedLEB128From(LookupOrInsertFunction(var)); |
- current_function_builder_->EmitCode( |
- &index[0], static_cast<uint32_t>(index.size())); |
- } else { |
- if (is_set_op_) { |
- if (var->IsContextSlot()) { |
- current_function_builder_->Emit(kExprStoreGlobal); |
- } else { |
- current_function_builder_->Emit(kExprSetLocal); |
- } |
- is_set_op_ = false; |
+ if (is_set_op_) { |
+ if (var->IsContextSlot()) { |
+ current_function_builder_->Emit(kExprStoreGlobal); |
} else { |
- if (var->IsContextSlot()) { |
- current_function_builder_->Emit(kExprLoadGlobal); |
- } else { |
- current_function_builder_->Emit(kExprGetLocal); |
- } |
+ current_function_builder_->Emit(kExprSetLocal); |
} |
- LocalType var_type = TypeOf(expr); |
- DCHECK(var_type != kAstStmt); |
+ is_set_op_ = false; |
+ } else { |
if (var->IsContextSlot()) { |
- AddLeb128(LookupOrInsertGlobal(var, var_type), false); |
+ current_function_builder_->Emit(kExprLoadGlobal); |
} else { |
- AddLeb128(LookupOrInsertLocal(var, var_type), true); |
+ current_function_builder_->Emit(kExprGetLocal); |
} |
} |
+ LocalType var_type = TypeOf(expr); |
+ DCHECK(var_type != kAstStmt); |
+ if (var->IsContextSlot()) { |
+ AddLeb128(LookupOrInsertGlobal(var, var_type), false); |
+ } else { |
+ AddLeb128(LookupOrInsertLocal(var, var_type), true); |
+ } |
} |
} |
@@ -508,11 +501,80 @@ class AsmWasmBuilderImpl : public AstVisitor { |
return reinterpret_cast<FunctionTableIndices*>(entry->value); |
} |
+ class ImportedFunctionTable { |
+ private: |
+ class ImportedFunctionIndices : public ZoneObject { |
+ public: |
+ const unsigned char* name_; |
+ int name_length_; |
+ WasmModuleBuilder::SignatureMap signature_to_index_; |
+ |
+ ImportedFunctionIndices(const unsigned char* name, int name_length, |
+ Zone* zone) |
+ : name_(name), name_length_(name_length), signature_to_index_(zone) {} |
+ }; |
+ ZoneHashMap table_; |
+ AsmWasmBuilderImpl* builder_; |
+ |
+ public: |
+ explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder) |
+ : table_(HashMap::PointersMatch, ZoneHashMap::kDefaultHashMapCapacity, |
+ ZoneAllocationPolicy(builder->zone())), |
+ builder_(builder) {} |
+ |
+ void AddImport(Variable* v, const unsigned char* name, int name_length) { |
+ ImportedFunctionIndices* indices = new (builder_->zone()) |
+ ImportedFunctionIndices(name, name_length, builder_->zone()); |
+ ZoneHashMap::Entry* entry = table_.LookupOrInsert( |
+ v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone())); |
+ entry->value = indices; |
+ } |
+ |
+ uint16_t GetFunctionIndex(Variable* v, FunctionSig* sig) { |
+ ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v)); |
+ DCHECK(entry != nullptr); |
+ ImportedFunctionIndices* indices = |
+ reinterpret_cast<ImportedFunctionIndices*>(entry->value); |
+ WasmModuleBuilder::SignatureMap::iterator pos = |
+ indices->signature_to_index_.find(sig); |
+ if (pos != indices->signature_to_index_.end()) { |
+ return pos->second; |
+ } else { |
+ uint16_t index = builder_->builder_->AddFunction(); |
+ indices->signature_to_index_[sig] = index; |
+ WasmFunctionBuilder* function = builder_->builder_->FunctionAt(index); |
+ function->External(1); |
+ function->SetName(indices->name_, indices->name_length_); |
+ if (sig->return_count() > 0) { |
+ function->ReturnType(sig->GetReturn()); |
+ } |
+ for (size_t i = 0; i < sig->parameter_count(); i++) { |
+ function->AddParam(sig->GetParam(i)); |
+ } |
+ return index; |
+ } |
+ } |
+ }; |
+ |
void VisitAssignment(Assignment* expr) { |
bool in_init = false; |
if (!in_function_) { |
// TODO(bradnelson): Get rid of this. |
if (TypeOf(expr->value()) == kAstStmt) { |
+ Property* prop = expr->value()->AsProperty(); |
+ if (prop != nullptr) { |
+ VariableProxy* vp = prop->obj()->AsVariableProxy(); |
+ if (vp != nullptr && vp->var()->IsParameter() && |
+ vp->var()->index() == 1) { |
+ VariableProxy* target = expr->target()->AsVariableProxy(); |
+ if (target->bounds().lower->Is(Type::Function())) { |
+ const AstRawString* name = |
+ prop->key()->AsLiteral()->AsRawPropertyName(); |
+ imported_function_table_.AddImport( |
+ target->var(), name->raw_data(), name->length()); |
+ } |
+ } |
+ } |
ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); |
if (funcs != nullptr && |
funcs->bounds().lower->AsArray()->Element()->IsFunction()) { |
@@ -620,8 +682,29 @@ class AsmWasmBuilderImpl : public AstVisitor { |
switch (call_type) { |
case Call::OTHER_CALL: { |
DCHECK(in_function_); |
+ uint16_t index; |
+ VariableProxy* vp = expr->expression()->AsVariableProxy(); |
+ if (vp != nullptr && |
+ Type::Any()->Is(vp->bounds().lower->AsFunction()->Result())) { |
+ LocalType return_type = TypeOf(expr); |
+ ZoneList<Expression*>* args = expr->arguments(); |
+ FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, |
+ args->length()); |
+ if (return_type != kAstStmt) { |
+ sig.AddReturn(return_type); |
+ } |
+ for (int i = 0; i < args->length(); i++) { |
+ sig.AddParam(TypeOf(args->at(i))); |
+ } |
+ index = |
+ imported_function_table_.GetFunctionIndex(vp->var(), sig.Build()); |
+ } else { |
+ index = LookupOrInsertFunction(vp->var()); |
+ } |
current_function_builder_->Emit(kExprCallFunction); |
- RECURSE(Visit(expr->expression())); |
+ std::vector<uint8_t> index_arr = UnsignedLEB128From(index); |
+ current_function_builder_->EmitCode( |
+ &index_arr[0], static_cast<uint32_t>(index_arr.size())); |
break; |
} |
case Call::KEYED_PROPERTY_CALL: { |
@@ -1094,6 +1177,7 @@ class AsmWasmBuilderImpl : public AstVisitor { |
uint16_t init_function_index_; |
uint32_t next_table_index_; |
ZoneHashMap function_tables_; |
+ ImportedFunctionTable imported_function_table_; |
DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |