| Index: src/wasm/ast-decoder.cc
|
| diff --git a/src/wasm/ast-decoder.cc b/src/wasm/ast-decoder.cc
|
| index 390a67300a34a22640952dc5bc92339d341217f7..9b99ec01fc139da0dfc110c1bf701d46daef2021 100644
|
| --- a/src/wasm/ast-decoder.cc
|
| +++ b/src/wasm/ast-decoder.cc
|
| @@ -157,10 +157,17 @@ class WasmDecoder : public Decoder {
|
| return false;
|
| }
|
|
|
| - inline bool Validate(const byte* pc, CallFunctionOperand& operand) {
|
| + inline bool Complete(const byte* pc, CallFunctionOperand& operand) {
|
| ModuleEnv* m = module_;
|
| if (m && m->module && operand.index < m->module->functions.size()) {
|
| operand.sig = m->module->functions[operand.index].sig;
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + inline bool Validate(const byte* pc, CallFunctionOperand& operand) {
|
| + if (Complete(pc, operand)) {
|
| uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
|
| if (operand.arity != expected) {
|
| error(pc, pc + 1,
|
| @@ -174,10 +181,17 @@ class WasmDecoder : public Decoder {
|
| return false;
|
| }
|
|
|
| - inline bool Validate(const byte* pc, CallIndirectOperand& operand) {
|
| + inline bool Complete(const byte* pc, CallIndirectOperand& operand) {
|
| ModuleEnv* m = module_;
|
| if (m && m->module && operand.index < m->module->signatures.size()) {
|
| operand.sig = m->module->signatures[operand.index];
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + inline bool Validate(const byte* pc, CallIndirectOperand& operand) {
|
| + if (Complete(pc, operand)) {
|
| uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
|
| if (operand.arity != expected) {
|
| error(pc, pc + 1,
|
| @@ -191,10 +205,17 @@ class WasmDecoder : public Decoder {
|
| return false;
|
| }
|
|
|
| - inline bool Validate(const byte* pc, CallImportOperand& operand) {
|
| + inline bool Complete(const byte* pc, CallImportOperand& operand) {
|
| ModuleEnv* m = module_;
|
| if (m && m->module && operand.index < m->module->import_table.size()) {
|
| operand.sig = m->module->import_table[operand.index].sig;
|
| + return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + inline bool Validate(const byte* pc, CallImportOperand& operand) {
|
| + if (Complete(pc, operand)) {
|
| uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
|
| if (operand.arity != expected) {
|
| error(pc, pc + 1, "arity mismatch in import call (expected %u, got %u)",
|
| @@ -391,7 +412,7 @@ class WasmDecoder : public Decoder {
|
| // shift-reduce strategy with multiple internal stacks.
|
| class SR_WasmDecoder : public WasmDecoder {
|
| public:
|
| - SR_WasmDecoder(Zone* zone, TFBuilder* builder, FunctionBody& body)
|
| + SR_WasmDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body)
|
| : WasmDecoder(body.module, body.sig, body.start, body.end),
|
| zone_(zone),
|
| builder_(builder),
|
| @@ -1526,20 +1547,22 @@ int OpcodeArity(const byte* pc, const byte* end) {
|
| }
|
|
|
| void PrintAstForDebugging(const byte* start, const byte* end) {
|
| - FunctionBody body = {nullptr, nullptr, start, start, end};
|
| base::AccountingAllocator allocator;
|
| - PrintAst(&allocator, body);
|
| + OFStream os(stdout);
|
| + PrintAst(&allocator, FunctionBodyForTesting(start, end), os, nullptr);
|
| }
|
|
|
| -void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
|
| +bool PrintAst(base::AccountingAllocator* allocator, const FunctionBody& body,
|
| + std::ostream& os,
|
| + std::vector<std::tuple<uint32_t, int, int>>* offset_table) {
|
| Zone zone(allocator);
|
| SR_WasmDecoder decoder(&zone, nullptr, body);
|
| -
|
| - OFStream os(stdout);
|
| + int line_nr = 0;
|
|
|
| // Print the function signature.
|
| if (body.sig) {
|
| os << "// signature: " << *body.sig << std::endl;
|
| + ++line_nr;
|
| }
|
|
|
| // Print the local declarations.
|
| @@ -1556,24 +1579,35 @@ void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
|
| os << std::endl;
|
|
|
| for (const byte* locals = body.start; locals < pc; locals++) {
|
| - printf(" 0x%02x,", *locals);
|
| + os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ",";
|
| }
|
| os << std::endl;
|
| + ++line_nr;
|
| }
|
|
|
| - os << "// body: \n";
|
| - int control_depth = 0;
|
| + os << "// body: " << std::endl;
|
| + ++line_nr;
|
| + unsigned control_depth = 0;
|
| while (pc < body.end) {
|
| size_t length = decoder.OpcodeLength(pc);
|
|
|
| WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
|
| if (opcode == kExprElse) control_depth--;
|
|
|
| - for (int i = 0; i < control_depth && i < 32; i++) printf(" ");
|
| - printf("k%s,", WasmOpcodes::OpcodeName(opcode));
|
| + int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64;
|
| + if (offset_table) {
|
| + offset_table->push_back(
|
| + std::make_tuple(pc - body.start, line_nr, num_whitespaces));
|
| + }
|
| +
|
| + // 64 whitespaces
|
| + const char* padding =
|
| + " ";
|
| + os.write(padding, num_whitespaces);
|
| + os << "k" << WasmOpcodes::OpcodeName(opcode) << ",";
|
|
|
| for (size_t i = 1; i < length; i++) {
|
| - printf(" 0x%02x,", pc[i]);
|
| + os << " " << AsHex(pc[i], 2) << ",";
|
| }
|
|
|
| switch (opcode) {
|
| @@ -1606,7 +1640,7 @@ void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
|
| }
|
| case kExprCallIndirect: {
|
| CallIndirectOperand operand(&decoder, pc);
|
| - if (decoder.Validate(pc, operand)) {
|
| + if (decoder.Complete(pc, operand)) {
|
| os << " // sig #" << operand.index << ": " << *operand.sig;
|
| } else {
|
| os << " // arity=" << operand.arity << " sig #" << operand.index;
|
| @@ -1615,7 +1649,7 @@ void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
|
| }
|
| case kExprCallImport: {
|
| CallImportOperand operand(&decoder, pc);
|
| - if (decoder.Validate(pc, operand)) {
|
| + if (decoder.Complete(pc, operand)) {
|
| os << " // import #" << operand.index << ": " << *operand.sig;
|
| } else {
|
| os << " // arity=" << operand.arity << " import #" << operand.index;
|
| @@ -1624,7 +1658,7 @@ void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
|
| }
|
| case kExprCallFunction: {
|
| CallFunctionOperand operand(&decoder, pc);
|
| - if (decoder.Validate(pc, operand)) {
|
| + if (decoder.Complete(pc, operand)) {
|
| os << " // function #" << operand.index << ": " << *operand.sig;
|
| } else {
|
| os << " // arity=" << operand.arity << " function #" << operand.index;
|
| @@ -1642,7 +1676,10 @@ void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
|
|
|
| pc += length;
|
| os << std::endl;
|
| + ++line_nr;
|
| }
|
| +
|
| + return decoder.ok();
|
| }
|
|
|
| BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
|
|
|