Index: src/wasm/ast-decoder.cc |
diff --git a/src/wasm/ast-decoder.cc b/src/wasm/ast-decoder.cc |
index 5b23babd6ef7feaeabd6d22a8e66676e4b2e2205..c97c781c12eeab411b68b2fbc242dcf91c15adda 100644 |
--- a/src/wasm/ast-decoder.cc |
+++ b/src/wasm/ast-decoder.cc |
@@ -175,6 +175,16 @@ class WasmDecoder : public Decoder { |
return false; |
} |
+ inline bool Validate(const byte* pc, ImportIndexOperand& operand) { |
+ ModuleEnv* m = function_env_->module; |
+ if (m && m->module && operand.index < m->module->import_table->size()) { |
+ operand.sig = m->module->import_table->at(operand.index).sig; |
+ return true; |
+ } |
+ error(pc, pc + 1, "invalid signature index"); |
+ return false; |
+ } |
+ |
inline bool Validate(const byte* pc, BreakDepthOperand& operand, |
ZoneVector<Block>& blocks) { |
if (operand.depth < blocks.size()) { |
@@ -261,6 +271,12 @@ class WasmDecoder : public Decoder { |
function_env_->module->GetSignature(operand.index) |
->parameter_count()); |
} |
+ case kExprCallImport: { |
+ ImportIndexOperand operand(this, pc); |
+ return static_cast<int>( |
+ function_env_->module->GetImportSignature(operand.index) |
+ ->parameter_count()); |
+ } |
case kExprReturn: { |
return static_cast<int>(function_env_->sig->return_count()); |
} |
@@ -317,6 +333,10 @@ class WasmDecoder : public Decoder { |
SignatureIndexOperand operand(this, pc); |
return 1 + operand.length; |
} |
+ case kExprCallImport: { |
+ ImportIndexOperand operand(this, pc); |
+ return 1 + operand.length; |
+ } |
case kExprSetLocal: |
case kExprGetLocal: { |
@@ -790,6 +810,17 @@ class LR_WasmDecoder : public WasmDecoder { |
len = 1 + operand.length; |
break; |
} |
+ case kExprCallImport: { |
+ ImportIndexOperand operand(this, pc_); |
+ if (Validate(pc_, operand)) { |
+ LocalType type = operand.sig->return_count() == 0 |
+ ? kAstStmt |
+ : operand.sig->GetReturn(); |
+ Shift(type, static_cast<int>(operand.sig->parameter_count())); |
+ } |
+ len = 1 + operand.length; |
+ break; |
+ } |
default: |
error("Invalid opcode"); |
return; |
@@ -1212,6 +1243,23 @@ class LR_WasmDecoder : public WasmDecoder { |
} |
break; |
} |
+ case kExprCallImport: { |
+ ImportIndexOperand operand(this, p->pc()); |
+ CHECK(Validate(p->pc(), operand)); |
+ if (p->index > 0) { |
+ TypeCheckLast(p, operand.sig->GetParam(p->index - 1)); |
+ } |
+ if (p->done() && build()) { |
+ uint32_t count = p->tree->count + 1; |
+ TFNode** buffer = builder_->Buffer(count); |
+ buffer[0] = nullptr; // reserved for code object. |
+ for (uint32_t i = 1; i < count; i++) { |
+ buffer[i] = p->tree->children[i - 1]->node; |
+ } |
+ p->tree->node = builder_->CallImport(operand.index, buffer); |
+ } |
+ break; |
+ } |
default: |
break; |
} |