summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-reader-ast.cc945
-rw-r--r--src/binary-reader-interpreter.cc1763
-rw-r--r--src/binary-reader-linker.cc305
-rw-r--r--src/binary-reader-logging.cc592
-rw-r--r--src/binary-reader-logging.h242
-rw-r--r--src/binary-reader-nop.h329
-rw-r--r--src/binary-reader-objdump.cc936
-rw-r--r--src/binary-reader-opcnt.cc115
-rw-r--r--src/binary-reader.cc1284
-rw-r--r--src/binary-reader.h523
-rw-r--r--src/tools/wasm-link.cc12
-rw-r--r--src/wasm-link.h4
12 files changed, 3644 insertions, 3406 deletions
diff --git a/src/binary-reader-ast.cc b/src/binary-reader-ast.cc
index 39c9e8fa..de0a2a93 100644
--- a/src/binary-reader-ast.cc
+++ b/src/binary-reader-ast.cc
@@ -25,7 +25,7 @@
#include <vector>
#include "ast.h"
-#include "binary-reader.h"
+#include "binary-reader-nop.h"
#include "common.h"
#define CHECK_RESULT(expr) \
@@ -49,7 +49,155 @@ struct LabelNode {
LabelNode::LabelNode(LabelType label_type, Expr** first)
: label_type(label_type), first(first), last(nullptr) {}
-struct Context {
+class BinaryReaderAST : public BinaryReaderNop {
+ public:
+ BinaryReaderAST(Module* out_module, BinaryErrorHandler* error_handler);
+
+ virtual bool OnError(const char* message);
+
+ virtual Result OnTypeCount(uint32_t count);
+ virtual Result OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types);
+
+ virtual Result OnImportCount(uint32_t count);
+ virtual Result OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name);
+ virtual Result OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index);
+ virtual Result OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits);
+ virtual Result OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits);
+ virtual Result OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_);
+
+ virtual Result OnFunctionCount(uint32_t count);
+ virtual Result OnFunction(uint32_t index, uint32_t sig_index);
+
+ virtual Result OnTableCount(uint32_t count);
+ virtual Result OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits);
+
+ virtual Result OnMemoryCount(uint32_t count);
+ virtual Result OnMemory(uint32_t index, const Limits* limits);
+
+ virtual Result OnGlobalCount(uint32_t count);
+ virtual Result BeginGlobal(uint32_t index, Type type, bool mutable_);
+ virtual Result BeginGlobalInitExpr(uint32_t index);
+ virtual Result EndGlobalInitExpr(uint32_t index);
+
+ virtual Result OnExportCount(uint32_t count);
+ virtual Result OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name);
+
+ virtual Result OnStartFunction(uint32_t func_index);
+
+ virtual Result OnFunctionBodyCount(uint32_t count);
+ virtual Result BeginFunctionBody(uint32_t index);
+ virtual Result OnLocalDecl(uint32_t decl_index, uint32_t count, Type type);
+
+ virtual Result OnBinaryExpr(Opcode opcode);
+ virtual Result OnBlockExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnBrExpr(uint32_t depth);
+ virtual Result OnBrIfExpr(uint32_t depth);
+ virtual Result OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth);
+ virtual Result OnCallExpr(uint32_t func_index);
+ virtual Result OnCallIndirectExpr(uint32_t sig_index);
+ virtual Result OnCompareExpr(Opcode opcode);
+ virtual Result OnConvertExpr(Opcode opcode);
+ virtual Result OnDropExpr();
+ virtual Result OnElseExpr();
+ virtual Result OnEndExpr();
+ virtual Result OnF32ConstExpr(uint32_t value_bits);
+ virtual Result OnF64ConstExpr(uint64_t value_bits);
+ virtual Result OnGetGlobalExpr(uint32_t global_index);
+ virtual Result OnGetLocalExpr(uint32_t local_index);
+ virtual Result OnGrowMemoryExpr();
+ virtual Result OnI32ConstExpr(uint32_t value);
+ virtual Result OnI64ConstExpr(uint64_t value);
+ virtual Result OnIfExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset);
+ virtual Result OnLoopExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnCurrentMemoryExpr();
+ virtual Result OnNopExpr();
+ virtual Result OnReturnExpr();
+ virtual Result OnSelectExpr();
+ virtual Result OnSetGlobalExpr(uint32_t global_index);
+ virtual Result OnSetLocalExpr(uint32_t local_index);
+ virtual Result OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset);
+ virtual Result OnTeeLocalExpr(uint32_t local_index);
+ virtual Result OnUnaryExpr(Opcode opcode);
+ virtual Result OnUnreachableExpr();
+ virtual Result EndFunctionBody(uint32_t index);
+
+ virtual Result OnElemSegmentCount(uint32_t count);
+ virtual Result BeginElemSegment(uint32_t index, uint32_t table_index);
+ virtual Result BeginElemSegmentInitExpr(uint32_t index);
+ virtual Result EndElemSegmentInitExpr(uint32_t index);
+ virtual Result OnElemSegmentFunctionIndexCount(uint32_t index,
+ uint32_t count);
+ virtual Result OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index);
+
+ virtual Result OnDataSegmentCount(uint32_t count);
+ virtual Result BeginDataSegment(uint32_t index, uint32_t memory_index);
+ virtual Result BeginDataSegmentInitExpr(uint32_t index);
+ virtual Result EndDataSegmentInitExpr(uint32_t index);
+ virtual Result OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size);
+
+ virtual Result OnFunctionNamesCount(uint32_t num_functions);
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name);
+ virtual Result OnLocalNameLocalCount(uint32_t function_index,
+ uint32_t num_locals);
+ virtual Result OnLocalName(uint32_t function_index,
+ uint32_t local_index,
+ StringSlice local_name);
+
+ virtual Result OnInitExprF32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprF64ConstExpr(uint32_t index, uint64_t value);
+ virtual Result OnInitExprGetGlobalExpr(uint32_t index, uint32_t global_index);
+ virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprI64ConstExpr(uint32_t index, uint64_t value);
+
+ private:
+ bool HandleError(uint32_t offset, const char* message);
+ void PrintError(const char* format, ...);
+ void PushLabel(LabelType label_type, Expr** first);
+ Result PopLabel();
+ Result GetLabelAt(LabelNode** label, uint32_t depth);
+ Result TopLabel(LabelNode** label);
+ Result AppendExpr(Expr* expr);
+
BinaryErrorHandler* error_handler = nullptr;
Module* module = nullptr;
@@ -59,50 +207,50 @@ struct Context {
Expr** current_init_expr = nullptr;
};
-} // namespace
+BinaryReaderAST::BinaryReaderAST(Module* out_module,
+ BinaryErrorHandler* error_handler)
+ : error_handler(error_handler), module(out_module) {}
-static bool handle_error(Context* ctx, uint32_t offset, const char* message);
-
-static void WABT_PRINTF_FORMAT(2, 3)
- print_error(Context* ctx, const char* format, ...) {
+void WABT_PRINTF_FORMAT(2, 3) BinaryReaderAST::PrintError(const char* format,
+ ...) {
WABT_SNPRINTF_ALLOCA(buffer, length, format);
- handle_error(ctx, WABT_UNKNOWN_OFFSET, buffer);
+ HandleError(WABT_UNKNOWN_OFFSET, buffer);
}
-static void push_label(Context* ctx, LabelType label_type, Expr** first) {
- ctx->max_depth++;
- ctx->label_stack.emplace_back(label_type, first);
+void BinaryReaderAST::PushLabel(LabelType label_type, Expr** first) {
+ max_depth++;
+ label_stack.emplace_back(label_type, first);
}
-static Result pop_label(Context* ctx) {
- if (ctx->label_stack.size() == 0) {
- print_error(ctx, "popping empty label stack");
+Result BinaryReaderAST::PopLabel() {
+ if (label_stack.size() == 0) {
+ PrintError("popping empty label stack");
return Result::Error;
}
- ctx->max_depth--;
- ctx->label_stack.pop_back();
+ max_depth--;
+ label_stack.pop_back();
return Result::Ok;
}
-static Result get_label_at(Context* ctx, LabelNode** label, uint32_t depth) {
- if (depth >= ctx->label_stack.size()) {
- print_error(ctx, "accessing stack depth: %u >= max: %" PRIzd, depth,
- ctx->label_stack.size());
+Result BinaryReaderAST::GetLabelAt(LabelNode** label, uint32_t depth) {
+ if (depth >= label_stack.size()) {
+ PrintError("accessing stack depth: %u >= max: %" PRIzd, depth,
+ label_stack.size());
return Result::Error;
}
- *label = &ctx->label_stack[ctx->label_stack.size() - depth - 1];
+ *label = &label_stack[label_stack.size() - depth - 1];
return Result::Ok;
}
-static Result top_label(Context* ctx, LabelNode** label) {
- return get_label_at(ctx, label, 0);
+Result BinaryReaderAST::TopLabel(LabelNode** label) {
+ return GetLabelAt(label, 0);
}
-static Result append_expr(Context* ctx, Expr* expr) {
+Result BinaryReaderAST::AppendExpr(Expr* expr) {
LabelNode* label;
- if (WABT_FAILED(top_label(ctx, &label))) {
+ if (WABT_FAILED(TopLabel(&label))) {
delete expr;
return Result::Error;
}
@@ -115,154 +263,132 @@ static Result append_expr(Context* ctx, Expr* expr) {
return Result::Ok;
}
-static bool handle_error(Context* ctx, uint32_t offset, const char* message) {
- if (ctx->error_handler->on_error) {
- return ctx->error_handler->on_error(offset, message,
- ctx->error_handler->user_data);
+bool BinaryReaderAST::HandleError(uint32_t offset, const char* message) {
+ if (error_handler->on_error) {
+ return error_handler->on_error(offset, message, error_handler->user_data);
}
return false;
}
-static bool on_error(BinaryReaderContext* reader_context, const char* message) {
- Context* ctx = static_cast<Context*>(reader_context->user_data);
- return handle_error(ctx, reader_context->offset, message);
+bool BinaryReaderAST::OnError(const char* message) {
+ return HandleError(state->offset, message);
}
-static Result on_signature_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->func_types.reserve(count);
+Result BinaryReaderAST::OnTypeCount(uint32_t count) {
+ module->func_types.reserve(count);
return Result::Ok;
}
-static Result on_signature(uint32_t index,
- uint32_t param_count,
- Type* param_types,
- uint32_t result_count,
- Type* result_types,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::FuncType;
field->func_type = new FuncType();
FuncType* func_type = field->func_type;
func_type->sig.param_types.assign(param_types, param_types + param_count);
func_type->sig.result_types.assign(result_types, result_types + result_count);
- ctx->module->func_types.push_back(func_type);
+ module->func_types.push_back(func_type);
return Result::Ok;
}
-static Result on_import_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->imports.reserve(count);
+Result BinaryReaderAST::OnImportCount(uint32_t count) {
+ module->imports.reserve(count);
return Result::Ok;
}
-static Result on_import(uint32_t index,
- StringSlice module_name,
- StringSlice field_name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
-
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::Import;
field->import = new Import();
Import* import = field->import;
import->module_name = dup_string_slice(module_name);
import->field_name = dup_string_slice(field_name);
- ctx->module->imports.push_back(import);
+ module->imports.push_back(import);
return Result::Ok;
}
-static Result on_import_func(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t func_index,
- uint32_t sig_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(import_index == ctx->module->imports.size() - 1);
- Import* import = ctx->module->imports[import_index];
+Result BinaryReaderAST::OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index) {
+ assert(import_index == module->imports.size() - 1);
+ Import* import = module->imports[import_index];
import->kind = ExternalKind::Func;
import->func = new Func();
import->func->decl.has_func_type = true;
import->func->decl.type_var.type = VarType::Index;
import->func->decl.type_var.index = sig_index;
- import->func->decl.sig = ctx->module->func_types[sig_index]->sig;
+ import->func->decl.sig = module->func_types[sig_index]->sig;
- ctx->module->funcs.push_back(import->func);
- ctx->module->num_func_imports++;
+ module->funcs.push_back(import->func);
+ module->num_func_imports++;
return Result::Ok;
}
-static Result on_import_table(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t table_index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(import_index == ctx->module->imports.size() - 1);
- Import* import = ctx->module->imports[import_index];
+Result BinaryReaderAST::OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ assert(import_index == module->imports.size() - 1);
+ Import* import = module->imports[import_index];
import->kind = ExternalKind::Table;
import->table = new Table();
import->table->elem_limits = *elem_limits;
- ctx->module->tables.push_back(import->table);
- ctx->module->num_table_imports++;
+ module->tables.push_back(import->table);
+ module->num_table_imports++;
return Result::Ok;
}
-static Result on_import_memory(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t memory_index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(import_index == ctx->module->imports.size() - 1);
- Import* import = ctx->module->imports[import_index];
+Result BinaryReaderAST::OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits) {
+ assert(import_index == module->imports.size() - 1);
+ Import* import = module->imports[import_index];
import->kind = ExternalKind::Memory;
import->memory = new Memory();
import->memory->page_limits = *page_limits;
- ctx->module->memories.push_back(import->memory);
- ctx->module->num_memory_imports++;
+ module->memories.push_back(import->memory);
+ module->num_memory_imports++;
return Result::Ok;
}
-static Result on_import_global(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t global_index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(import_index == ctx->module->imports.size() - 1);
- Import* import = ctx->module->imports[import_index];
+Result BinaryReaderAST::OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_) {
+ assert(import_index == module->imports.size() - 1);
+ Import* import = module->imports[import_index];
import->kind = ExternalKind::Global;
import->global = new Global();
import->global->type = type;
import->global->mutable_ = mutable_;
- ctx->module->globals.push_back(import->global);
- ctx->module->num_global_imports++;
+ module->globals.push_back(import->global);
+ module->num_global_imports++;
return Result::Ok;
}
-static Result on_function_signatures_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->funcs.reserve(ctx->module->num_func_imports + count);
+Result BinaryReaderAST::OnFunctionCount(uint32_t count) {
+ module->funcs.reserve(module->num_func_imports + count);
return Result::Ok;
}
-static Result on_function_signature(uint32_t index,
- uint32_t sig_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
-
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::OnFunction(uint32_t index, uint32_t sig_index) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::Func;
field->func = new Func();
@@ -270,99 +396,79 @@ static Result on_function_signature(uint32_t index,
func->decl.has_func_type = true;
func->decl.type_var.type = VarType::Index;
func->decl.type_var.index = sig_index;
- func->decl.sig = ctx->module->func_types[sig_index]->sig;
+ func->decl.sig = module->func_types[sig_index]->sig;
- ctx->module->funcs.push_back(func);
+ module->funcs.push_back(func);
return Result::Ok;
}
-static Result on_table_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->tables.reserve(ctx->module->num_table_imports + count);
+Result BinaryReaderAST::OnTableCount(uint32_t count) {
+ module->tables.reserve(module->num_table_imports + count);
return Result::Ok;
}
-static Result on_table(uint32_t index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
-
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::Table;
field->table = new Table();
field->table->elem_limits = *elem_limits;
- ctx->module->tables.push_back(field->table);
+ module->tables.push_back(field->table);
return Result::Ok;
}
-static Result on_memory_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->memories.reserve(ctx->module->num_memory_imports + count);
+Result BinaryReaderAST::OnMemoryCount(uint32_t count) {
+ module->memories.reserve(module->num_memory_imports + count);
return Result::Ok;
}
-static Result on_memory(uint32_t index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
-
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::OnMemory(uint32_t index, const Limits* page_limits) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::Memory;
field->memory = new Memory();
field->memory->page_limits = *page_limits;
- ctx->module->memories.push_back(field->memory);
+ module->memories.push_back(field->memory);
return Result::Ok;
}
-static Result on_global_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->globals.reserve(ctx->module->num_global_imports + count);
+Result BinaryReaderAST::OnGlobalCount(uint32_t count) {
+ module->globals.reserve(module->num_global_imports + count);
return Result::Ok;
}
-static Result begin_global(uint32_t index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
-
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::BeginGlobal(uint32_t index, Type type, bool mutable_) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::Global;
field->global = new Global();
field->global->type = type;
field->global->mutable_ = mutable_;
- ctx->module->globals.push_back(field->global);
+ module->globals.push_back(field->global);
return Result::Ok;
}
-static Result begin_global_init_expr(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(index == ctx->module->globals.size() - 1);
- Global* global = ctx->module->globals[index];
- ctx->current_init_expr = &global->init_expr;
+Result BinaryReaderAST::BeginGlobalInitExpr(uint32_t index) {
+ assert(index == module->globals.size() - 1);
+ Global* global = module->globals[index];
+ current_init_expr = &global->init_expr;
return Result::Ok;
}
-static Result end_global_init_expr(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->current_init_expr = nullptr;
+Result BinaryReaderAST::EndGlobalInitExpr(uint32_t index) {
+ current_init_expr = nullptr;
return Result::Ok;
}
-static Result on_export_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->exports.reserve(count);
+Result BinaryReaderAST::OnExportCount(uint32_t count) {
+ module->exports.reserve(count);
return Result::Ok;
}
-static Result on_export(uint32_t index,
- ExternalKind kind,
- uint32_t item_index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::Export;
field->export_ = new Export();
@@ -370,157 +476,135 @@ static Result on_export(uint32_t index,
export_->name = dup_string_slice(name);
switch (kind) {
case ExternalKind::Func:
- assert(item_index < ctx->module->funcs.size());
+ assert(item_index < module->funcs.size());
break;
case ExternalKind::Table:
- assert(item_index < ctx->module->tables.size());
+ assert(item_index < module->tables.size());
break;
case ExternalKind::Memory:
- assert(item_index < ctx->module->memories.size());
+ assert(item_index < module->memories.size());
break;
case ExternalKind::Global:
- assert(item_index < ctx->module->globals.size());
+ assert(item_index < module->globals.size());
break;
}
export_->var.type = VarType::Index;
export_->var.index = item_index;
export_->kind = kind;
- ctx->module->exports.push_back(export_);
+ module->exports.push_back(export_);
return Result::Ok;
}
-static Result on_start_function(uint32_t func_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::OnStartFunction(uint32_t func_index) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::Start;
field->start.type = VarType::Index;
- assert(func_index < ctx->module->funcs.size());
+ assert(func_index < module->funcs.size());
field->start.index = func_index;
- ctx->module->start = &field->start;
+ module->start = &field->start;
return Result::Ok;
}
-static Result on_function_bodies_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(ctx->module->num_func_imports + count == ctx->module->funcs.size());
- WABT_USE(ctx);
+Result BinaryReaderAST::OnFunctionBodyCount(uint32_t count) {
+ assert(module->num_func_imports + count == module->funcs.size());
return Result::Ok;
}
-static Result begin_function_body(BinaryReaderContext* context,
- uint32_t index) {
- Context* ctx = static_cast<Context*>(context->user_data);
- ctx->current_func = ctx->module->funcs[index];
- push_label(ctx, LabelType::Func, &ctx->current_func->first_expr);
+Result BinaryReaderAST::BeginFunctionBody(uint32_t index) {
+ current_func = module->funcs[index];
+ PushLabel(LabelType::Func, &current_func->first_expr);
return Result::Ok;
}
-static Result on_local_decl(uint32_t decl_index,
- uint32_t count,
- Type type,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- TypeVector& types = ctx->current_func->local_types;
+Result BinaryReaderAST::OnLocalDecl(uint32_t decl_index,
+ uint32_t count,
+ Type type) {
+ TypeVector& types = current_func->local_types;
types.reserve(types.size() + count);
for (size_t i = 0; i < count; ++i)
types.push_back(type);
return Result::Ok;
}
-static Result on_binary_expr(Opcode opcode, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnBinaryExpr(Opcode opcode) {
Expr* expr = Expr::CreateBinary(opcode);
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_block_expr(uint32_t num_types,
- Type* sig_types,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnBlockExpr(uint32_t num_types, Type* sig_types) {
Expr* expr = Expr::CreateBlock(new Block());
expr->block->sig.assign(sig_types, sig_types + num_types);
- append_expr(ctx, expr);
- push_label(ctx, LabelType::Block, &expr->block->first);
+ AppendExpr(expr);
+ PushLabel(LabelType::Block, &expr->block->first);
return Result::Ok;
}
-static Result on_br_expr(uint32_t depth, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnBrExpr(uint32_t depth) {
Expr* expr = Expr::CreateBr(Var(depth));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_br_if_expr(uint32_t depth, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnBrIfExpr(uint32_t depth) {
Expr* expr = Expr::CreateBrIf(Var(depth));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_br_table_expr(BinaryReaderContext* context,
- uint32_t num_targets,
- uint32_t* target_depths,
- uint32_t default_target_depth) {
- Context* ctx = static_cast<Context*>(context->user_data);
+Result BinaryReaderAST::OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth) {
VarVector* targets = new VarVector();
targets->resize(num_targets);
for (uint32_t i = 0; i < num_targets; ++i) {
(*targets)[i] = Var(target_depths[i]);
}
Expr* expr = Expr::CreateBrTable(targets, Var(default_target_depth));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_call_expr(uint32_t func_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(func_index < ctx->module->funcs.size());
+Result BinaryReaderAST::OnCallExpr(uint32_t func_index) {
+ assert(func_index < module->funcs.size());
Expr* expr = Expr::CreateCall(Var(func_index));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_call_indirect_expr(uint32_t sig_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(sig_index < ctx->module->func_types.size());
+Result BinaryReaderAST::OnCallIndirectExpr(uint32_t sig_index) {
+ assert(sig_index < module->func_types.size());
Expr* expr = Expr::CreateCallIndirect(Var(sig_index));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_compare_expr(Opcode opcode, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnCompareExpr(Opcode opcode) {
Expr* expr = Expr::CreateCompare(opcode);
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_convert_expr(Opcode opcode, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnConvertExpr(Opcode opcode) {
Expr* expr = Expr::CreateConvert(opcode);
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_current_memory_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnCurrentMemoryExpr() {
Expr* expr = Expr::CreateCurrentMemory();
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_drop_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnDropExpr() {
Expr* expr = Expr::CreateDrop();
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_else_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnElseExpr() {
LabelNode* label;
- CHECK_RESULT(top_label(ctx, &label));
+ CHECK_RESULT(TopLabel(&label));
if (label->label_type != LabelType::If) {
- print_error(ctx, "else expression without matching if");
+ PrintError("else expression without matching if");
return Result::Error;
}
LabelNode* parent_label;
- CHECK_RESULT(get_label_at(ctx, &parent_label, 1));
+ CHECK_RESULT(GetLabelAt(&parent_label, 1));
assert(parent_label->last->type == ExprType::If);
label->label_type = LabelType::Else;
@@ -529,196 +613,161 @@ static Result on_else_expr(void* user_data) {
return Result::Ok;
}
-static Result on_end_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- return pop_label(ctx);
+Result BinaryReaderAST::OnEndExpr() {
+ return PopLabel();
}
-static Result on_f32_const_expr(uint32_t value_bits, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnF32ConstExpr(uint32_t value_bits) {
Expr* expr = Expr::CreateConst(Const(Const::F32(), value_bits));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_f64_const_expr(uint64_t value_bits, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnF64ConstExpr(uint64_t value_bits) {
Expr* expr = Expr::CreateConst(Const(Const::F64(), value_bits));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_get_global_expr(uint32_t global_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnGetGlobalExpr(uint32_t global_index) {
Expr* expr = Expr::CreateGetGlobal(Var(global_index));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_get_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnGetLocalExpr(uint32_t local_index) {
Expr* expr = Expr::CreateGetLocal(Var(local_index));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_grow_memory_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnGrowMemoryExpr() {
Expr* expr = Expr::CreateGrowMemory();
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_i32_const_expr(uint32_t value, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnI32ConstExpr(uint32_t value) {
Expr* expr = Expr::CreateConst(Const(Const::I32(), value));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_i64_const_expr(uint64_t value, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnI64ConstExpr(uint64_t value) {
Expr* expr = Expr::CreateConst(Const(Const::I64(), value));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_if_expr(uint32_t num_types, Type* sig_types, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnIfExpr(uint32_t num_types, Type* sig_types) {
Expr* expr = Expr::CreateIf(new Block());
expr->if_.true_->sig.assign(sig_types, sig_types + num_types);
expr->if_.false_ = nullptr;
- append_expr(ctx, expr);
- push_label(ctx, LabelType::If, &expr->if_.true_->first);
+ AppendExpr(expr);
+ PushLabel(LabelType::If, &expr->if_.true_->first);
return Result::Ok;
}
-static Result on_load_expr(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
Expr* expr = Expr::CreateLoad(opcode, 1 << alignment_log2, offset);
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_loop_expr(uint32_t num_types,
- Type* sig_types,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnLoopExpr(uint32_t num_types, Type* sig_types) {
Expr* expr = Expr::CreateLoop(new Block());
expr->loop->sig.assign(sig_types, sig_types + num_types);
- append_expr(ctx, expr);
- push_label(ctx, LabelType::Loop, &expr->loop->first);
+ AppendExpr(expr);
+ PushLabel(LabelType::Loop, &expr->loop->first);
return Result::Ok;
}
-static Result on_nop_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnNopExpr() {
Expr* expr = Expr::CreateNop();
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_return_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnReturnExpr() {
Expr* expr = Expr::CreateReturn();
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_select_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnSelectExpr() {
Expr* expr = Expr::CreateSelect();
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_set_global_expr(uint32_t global_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnSetGlobalExpr(uint32_t global_index) {
Expr* expr = Expr::CreateSetGlobal(Var(global_index));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_set_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnSetLocalExpr(uint32_t local_index) {
Expr* expr = Expr::CreateSetLocal(Var(local_index));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_store_expr(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
Expr* expr = Expr::CreateStore(opcode, 1 << alignment_log2, offset);
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_tee_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnTeeLocalExpr(uint32_t local_index) {
Expr* expr = Expr::CreateTeeLocal(Var(local_index));
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_unary_expr(Opcode opcode, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnUnaryExpr(Opcode opcode) {
Expr* expr = Expr::CreateUnary(opcode);
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result on_unreachable_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderAST::OnUnreachableExpr() {
Expr* expr = Expr::CreateUnreachable();
- return append_expr(ctx, expr);
+ return AppendExpr(expr);
}
-static Result end_function_body(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(pop_label(ctx));
- ctx->current_func = nullptr;
+Result BinaryReaderAST::EndFunctionBody(uint32_t index) {
+ CHECK_RESULT(PopLabel());
+ current_func = nullptr;
return Result::Ok;
}
-static Result on_elem_segment_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->elem_segments.reserve(count);
+Result BinaryReaderAST::OnElemSegmentCount(uint32_t count) {
+ module->elem_segments.reserve(count);
return Result::Ok;
}
-static Result begin_elem_segment(uint32_t index,
- uint32_t table_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::BeginElemSegment(uint32_t index, uint32_t table_index) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::ElemSegment;
field->elem_segment = new ElemSegment();
field->elem_segment->table_var.type = VarType::Index;
field->elem_segment->table_var.index = table_index;
- ctx->module->elem_segments.push_back(field->elem_segment);
+ module->elem_segments.push_back(field->elem_segment);
return Result::Ok;
}
-static Result begin_elem_segment_init_expr(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(index == ctx->module->elem_segments.size() - 1);
- ElemSegment* segment = ctx->module->elem_segments[index];
- ctx->current_init_expr = &segment->offset;
+Result BinaryReaderAST::BeginElemSegmentInitExpr(uint32_t index) {
+ assert(index == module->elem_segments.size() - 1);
+ ElemSegment* segment = module->elem_segments[index];
+ current_init_expr = &segment->offset;
return Result::Ok;
}
-static Result end_elem_segment_init_expr(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->current_init_expr = nullptr;
+Result BinaryReaderAST::EndElemSegmentInitExpr(uint32_t index) {
+ current_init_expr = nullptr;
return Result::Ok;
}
-static Result on_elem_segment_function_index_count(BinaryReaderContext* context,
- uint32_t index,
- uint32_t count) {
- Context* ctx = static_cast<Context*>(context->user_data);
- assert(index == ctx->module->elem_segments.size() - 1);
- ElemSegment* segment = ctx->module->elem_segments[index];
+Result BinaryReaderAST::OnElemSegmentFunctionIndexCount(uint32_t index,
+ uint32_t count) {
+ assert(index == module->elem_segments.size() - 1);
+ ElemSegment* segment = module->elem_segments[index];
segment->vars.reserve(count);
return Result::Ok;
}
-static Result on_elem_segment_function_index(uint32_t index,
- uint32_t func_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(index == ctx->module->elem_segments.size() - 1);
- ElemSegment* segment = ctx->module->elem_segments[index];
+Result BinaryReaderAST::OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index) {
+ assert(index == module->elem_segments.size() - 1);
+ ElemSegment* segment = module->elem_segments[index];
segment->vars.emplace_back();
Var* var = &segment->vars.back();
var->type = VarType::Index;
@@ -726,142 +775,109 @@ static Result on_elem_segment_function_index(uint32_t index,
return Result::Ok;
}
-static Result on_data_segment_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->data_segments.reserve(count);
+Result BinaryReaderAST::OnDataSegmentCount(uint32_t count) {
+ module->data_segments.reserve(count);
return Result::Ok;
}
-static Result begin_data_segment(uint32_t index,
- uint32_t memory_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ModuleField* field = append_module_field(ctx->module);
+Result BinaryReaderAST::BeginDataSegment(uint32_t index,
+ uint32_t memory_index) {
+ ModuleField* field = append_module_field(module);
field->type = ModuleFieldType::DataSegment;
field->data_segment = new DataSegment();
field->data_segment->memory_var.type = VarType::Index;
field->data_segment->memory_var.index = memory_index;
- ctx->module->data_segments.push_back(field->data_segment);
+ module->data_segments.push_back(field->data_segment);
return Result::Ok;
}
-static Result begin_data_segment_init_expr(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(index == ctx->module->data_segments.size() - 1);
- DataSegment* segment = ctx->module->data_segments[index];
- ctx->current_init_expr = &segment->offset;
+Result BinaryReaderAST::BeginDataSegmentInitExpr(uint32_t index) {
+ assert(index == module->data_segments.size() - 1);
+ DataSegment* segment = module->data_segments[index];
+ current_init_expr = &segment->offset;
return Result::Ok;
}
-static Result end_data_segment_init_expr(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->current_init_expr = nullptr;
+Result BinaryReaderAST::EndDataSegmentInitExpr(uint32_t index) {
+ current_init_expr = nullptr;
return Result::Ok;
}
-static Result on_data_segment_data(uint32_t index,
- const void* data,
- uint32_t size,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(index == ctx->module->data_segments.size() - 1);
- DataSegment* segment = ctx->module->data_segments[index];
+Result BinaryReaderAST::OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size) {
+ assert(index == module->data_segments.size() - 1);
+ DataSegment* segment = module->data_segments[index];
segment->data = new char[size];
segment->size = size;
memcpy(segment->data, data, size);
return Result::Ok;
}
-static Result on_function_names_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (count > ctx->module->funcs.size()) {
- print_error(
- ctx, "expected function name count (%u) <= function count (%" PRIzd ")",
- count, ctx->module->funcs.size());
+Result BinaryReaderAST::OnFunctionNamesCount(uint32_t count) {
+ if (count > module->funcs.size()) {
+ PrintError("expected function name count (%u) <= function count (%" PRIzd
+ ")",
+ count, module->funcs.size());
return Result::Error;
}
return Result::Ok;
}
-static Result on_function_name(uint32_t index,
- StringSlice name,
- void* user_data) {
+Result BinaryReaderAST::OnFunctionName(uint32_t index, StringSlice name) {
if (string_slice_is_empty(&name))
return Result::Ok;
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->func_bindings.emplace(string_slice_to_string(name),
- Binding(index));
- Func* func = ctx->module->funcs[index];
+ module->func_bindings.emplace(string_slice_to_string(name), Binding(index));
+ Func* func = module->funcs[index];
func->name = dup_string_slice(name);
return Result::Ok;
}
-static Result on_local_name_local_count(uint32_t index,
- uint32_t count,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- Module* module = ctx->module;
+Result BinaryReaderAST::OnLocalNameLocalCount(uint32_t index, uint32_t count) {
assert(index < module->funcs.size());
Func* func = module->funcs[index];
uint32_t num_params_and_locals = get_num_params_and_locals(func);
if (count > num_params_and_locals) {
- print_error(ctx, "expected local name count (%d) <= local count (%d)",
- count, num_params_and_locals);
+ PrintError("expected local name count (%d) <= local count (%d)", count,
+ num_params_and_locals);
return Result::Error;
}
return Result::Ok;
}
-static Result on_init_expr_f32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- *ctx->current_init_expr = Expr::CreateConst(Const(Const::F32(), value));
+Result BinaryReaderAST::OnInitExprF32ConstExpr(uint32_t index, uint32_t value) {
+ *current_init_expr = Expr::CreateConst(Const(Const::F32(), value));
return Result::Ok;
}
-static Result on_init_expr_f64_const_expr(uint32_t index,
- uint64_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- *ctx->current_init_expr = Expr::CreateConst(Const(Const::F64(), value));
+Result BinaryReaderAST::OnInitExprF64ConstExpr(uint32_t index, uint64_t value) {
+ *current_init_expr = Expr::CreateConst(Const(Const::F64(), value));
return Result::Ok;
}
-static Result on_init_expr_get_global_expr(uint32_t index,
- uint32_t global_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- *ctx->current_init_expr = Expr::CreateGetGlobal(Var(global_index));
+Result BinaryReaderAST::OnInitExprGetGlobalExpr(uint32_t index,
+ uint32_t global_index) {
+ *current_init_expr = Expr::CreateGetGlobal(Var(global_index));
return Result::Ok;
}
-static Result on_init_expr_i32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- *ctx->current_init_expr = Expr::CreateConst(Const(Const::I32(), value));
+Result BinaryReaderAST::OnInitExprI32ConstExpr(uint32_t index, uint32_t value) {
+ *current_init_expr = Expr::CreateConst(Const(Const::I32(), value));
return Result::Ok;
}
-static Result on_init_expr_i64_const_expr(uint32_t index,
- uint64_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- *ctx->current_init_expr = Expr::CreateConst(Const(Const::I64(), value));
+Result BinaryReaderAST::OnInitExprI64ConstExpr(uint32_t index, uint64_t value) {
+ *current_init_expr = Expr::CreateConst(Const(Const::I64(), value));
return Result::Ok;
}
-static Result on_local_name(uint32_t func_index,
- uint32_t local_index,
- StringSlice name,
- void* user_data) {
+Result BinaryReaderAST::OnLocalName(uint32_t func_index,
+ uint32_t local_index,
+ StringSlice name) {
if (string_slice_is_empty(&name))
return Result::Ok;
- Context* ctx = static_cast<Context*>(user_data);
- Module* module = ctx->module;
Func* func = module->funcs[func_index];
uint32_t num_params = get_num_params(func);
BindingHash* bindings;
@@ -879,112 +895,15 @@ static Result on_local_name(uint32_t func_index,
return Result::Ok;
}
+} // namespace
+
Result read_binary_ast(const void* data,
size_t size,
const ReadBinaryOptions* options,
BinaryErrorHandler* error_handler,
struct Module* out_module) {
- Context ctx;
- ctx.error_handler = error_handler;
- ctx.module = out_module;
-
- BinaryReader reader;
- WABT_ZERO_MEMORY(reader);
- reader.user_data = &ctx;
- reader.on_error = on_error;
-
- reader.on_signature_count = on_signature_count;
- reader.on_signature = on_signature;
-
- reader.on_import_count = on_import_count;
- reader.on_import = on_import;
- reader.on_import_func = on_import_func;
- reader.on_import_table = on_import_table;
- reader.on_import_memory = on_import_memory;
- reader.on_import_global = on_import_global;
-
- reader.on_function_signatures_count = on_function_signatures_count;
- reader.on_function_signature = on_function_signature;
-
- reader.on_table_count = on_table_count;
- reader.on_table = on_table;
-
- reader.on_memory_count = on_memory_count;
- reader.on_memory = on_memory;
-
- reader.on_global_count = on_global_count;
- reader.begin_global = begin_global;
- reader.begin_global_init_expr = begin_global_init_expr;
- reader.end_global_init_expr = end_global_init_expr;
-
- reader.on_export_count = on_export_count;
- reader.on_export = on_export;
-
- reader.on_start_function = on_start_function;
-
- reader.on_function_bodies_count = on_function_bodies_count;
- reader.begin_function_body = begin_function_body;
- reader.on_local_decl = on_local_decl;
- reader.on_binary_expr = on_binary_expr;
- reader.on_block_expr = on_block_expr;
- reader.on_br_expr = on_br_expr;
- reader.on_br_if_expr = on_br_if_expr;
- reader.on_br_table_expr = on_br_table_expr;
- reader.on_call_expr = on_call_expr;
- reader.on_call_indirect_expr = on_call_indirect_expr;
- reader.on_compare_expr = on_compare_expr;
- reader.on_convert_expr = on_convert_expr;
- reader.on_current_memory_expr = on_current_memory_expr;
- reader.on_drop_expr = on_drop_expr;
- reader.on_else_expr = on_else_expr;
- reader.on_end_expr = on_end_expr;
- reader.on_f32_const_expr = on_f32_const_expr;
- reader.on_f64_const_expr = on_f64_const_expr;
- reader.on_get_global_expr = on_get_global_expr;
- reader.on_get_local_expr = on_get_local_expr;
- reader.on_grow_memory_expr = on_grow_memory_expr;
- reader.on_i32_const_expr = on_i32_const_expr;
- reader.on_i64_const_expr = on_i64_const_expr;
- reader.on_if_expr = on_if_expr;
- reader.on_load_expr = on_load_expr;
- reader.on_loop_expr = on_loop_expr;
- reader.on_nop_expr = on_nop_expr;
- reader.on_return_expr = on_return_expr;
- reader.on_select_expr = on_select_expr;
- reader.on_set_global_expr = on_set_global_expr;
- reader.on_set_local_expr = on_set_local_expr;
- reader.on_store_expr = on_store_expr;
- reader.on_tee_local_expr = on_tee_local_expr;
- reader.on_unary_expr = on_unary_expr;
- reader.on_unreachable_expr = on_unreachable_expr;
- reader.end_function_body = end_function_body;
-
- reader.on_elem_segment_count = on_elem_segment_count;
- reader.begin_elem_segment = begin_elem_segment;
- reader.begin_elem_segment_init_expr = begin_elem_segment_init_expr;
- reader.end_elem_segment_init_expr = end_elem_segment_init_expr;
- reader.on_elem_segment_function_index_count =
- on_elem_segment_function_index_count;
- reader.on_elem_segment_function_index = on_elem_segment_function_index;
-
- reader.on_data_segment_count = on_data_segment_count;
- reader.begin_data_segment = begin_data_segment;
- reader.begin_data_segment_init_expr = begin_data_segment_init_expr;
- reader.end_data_segment_init_expr = end_data_segment_init_expr;
- reader.on_data_segment_data = on_data_segment_data;
-
- reader.on_function_names_count = on_function_names_count;
- reader.on_function_name = on_function_name;
- reader.on_local_name_local_count = on_local_name_local_count;
- reader.on_local_name = on_local_name;
-
- reader.on_init_expr_f32_const_expr = on_init_expr_f32_const_expr;
- reader.on_init_expr_f64_const_expr = on_init_expr_f64_const_expr;
- reader.on_init_expr_get_global_expr = on_init_expr_get_global_expr;
- reader.on_init_expr_i32_const_expr = on_init_expr_i32_const_expr;
- reader.on_init_expr_i64_const_expr = on_init_expr_i64_const_expr;
-
- Result result = read_binary(data, size, &reader, 1, options);
+ BinaryReaderAST reader(out_module, error_handler);
+ Result result = read_binary(data, size, &reader, options);
return result;
}
diff --git a/src/binary-reader-interpreter.cc b/src/binary-reader-interpreter.cc
index b8948c0a..b22a4472 100644
--- a/src/binary-reader-interpreter.cc
+++ b/src/binary-reader-interpreter.cc
@@ -23,7 +23,7 @@
#include <vector>
-#include "binary-reader.h"
+#include "binary-reader-nop.h"
#include "interpreter.h"
#include "type-checker.h"
#include "writer.h"
@@ -34,27 +34,6 @@
return Result::Error; \
} while (0)
-#define CHECK_LOCAL(ctx, local_index) \
- do { \
- uint32_t max_local_index = \
- (ctx)->current_func->param_and_local_types.size(); \
- if ((local_index) >= max_local_index) { \
- print_error((ctx), "invalid local_index: %d (max %d)", (local_index), \
- max_local_index); \
- return Result::Error; \
- } \
- } while (0)
-
-#define CHECK_GLOBAL(ctx, global_index) \
- do { \
- uint32_t max_global_index = (ctx)->global_index_mapping.size(); \
- if ((global_index) >= max_global_index) { \
- print_error((ctx), "invalid global_index: %d (max %d)", (global_index), \
- max_global_index); \
- return Result::Error; \
- } \
- } while (0)
-
namespace wabt {
namespace {
@@ -72,14 +51,219 @@ struct Label {
Label::Label(uint32_t offset, uint32_t fixup_offset)
: offset(offset), fixup_offset(fixup_offset) {}
-struct Context {
- Context();
+struct ElemSegmentInfo {
+ ElemSegmentInfo(uint32_t* dst, uint32_t func_index)
+ : dst(dst), func_index(func_index) {}
+
+ uint32_t* dst;
+ uint32_t func_index;
+};
+
+struct DataSegmentInfo {
+ DataSegmentInfo(void* dst_data, const void* src_data, uint32_t size)
+ : dst_data(dst_data), src_data(src_data), size(size) {}
+
+ void* dst_data; // Not owned.
+ const void* src_data; // Not owned.
+ uint32_t size;
+};
+
+class BinaryReaderInterpreter : public BinaryReaderNop {
+ public:
+ BinaryReaderInterpreter(InterpreterEnvironment* env,
+ DefinedInterpreterModule* module,
+ size_t istream_offset,
+ BinaryErrorHandler* error_handler);
+
+ Result Init();
+ void StealOutputBuffer(OutputBuffer*);
+ size_t get_istream_offset() { return istream_offset; }
+
+ // Implement BinaryReader.
+ virtual bool OnError(const char* message);
+
+ virtual Result EndModule();
+
+ virtual Result OnTypeCount(uint32_t count);
+ virtual Result OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types);
+
+ virtual Result OnImportCount(uint32_t count);
+ virtual Result OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name);
+ virtual Result OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index);
+ virtual Result OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits);
+ virtual Result OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits);
+ virtual Result OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_);
+
+ virtual Result OnFunctionCount(uint32_t count);
+ virtual Result OnFunction(uint32_t index, uint32_t sig_index);
+
+ virtual Result OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits);
+
+ virtual Result OnMemory(uint32_t index, const Limits* limits);
+
+ virtual Result OnGlobalCount(uint32_t count);
+ virtual Result BeginGlobal(uint32_t index, Type type, bool mutable_);
+ virtual Result EndGlobalInitExpr(uint32_t index);
+
+ virtual Result OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name);
+
+ virtual Result OnStartFunction(uint32_t func_index);
+
+ virtual Result BeginFunctionBody(uint32_t index);
+ virtual Result OnLocalDeclCount(uint32_t count);
+ virtual Result OnLocalDecl(uint32_t decl_index, uint32_t count, Type type);
+
+ virtual Result OnBinaryExpr(Opcode opcode);
+ virtual Result OnBlockExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnBrExpr(uint32_t depth);
+ virtual Result OnBrIfExpr(uint32_t depth);
+ virtual Result OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth);
+ virtual Result OnCallExpr(uint32_t func_index);
+ virtual Result OnCallIndirectExpr(uint32_t sig_index);
+ virtual Result OnCompareExpr(Opcode opcode);
+ virtual Result OnConvertExpr(Opcode opcode);
+ virtual Result OnCurrentMemoryExpr();
+ virtual Result OnDropExpr();
+ virtual Result OnElseExpr();
+ virtual Result OnEndExpr();
+ virtual Result OnF32ConstExpr(uint32_t value_bits);
+ virtual Result OnF64ConstExpr(uint64_t value_bits);
+ virtual Result OnGetGlobalExpr(uint32_t global_index);
+ virtual Result OnGetLocalExpr(uint32_t local_index);
+ virtual Result OnGrowMemoryExpr();
+ virtual Result OnI32ConstExpr(uint32_t value);
+ virtual Result OnI64ConstExpr(uint64_t value);
+ virtual Result OnIfExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset);
+ virtual Result OnLoopExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnNopExpr();
+ virtual Result OnReturnExpr();
+ virtual Result OnSelectExpr();
+ virtual Result OnSetGlobalExpr(uint32_t global_index);
+ virtual Result OnSetLocalExpr(uint32_t local_index);
+ virtual Result OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset);
+ virtual Result OnTeeLocalExpr(uint32_t local_index);
+ virtual Result OnUnaryExpr(Opcode opcode);
+ virtual Result OnUnreachableExpr();
+ virtual Result EndFunctionBody(uint32_t index);
+
+ virtual Result EndElemSegmentInitExpr(uint32_t index);
+ virtual Result OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index);
+
+ virtual Result OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size);
+
+ virtual Result OnInitExprF32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprF64ConstExpr(uint32_t index, uint64_t value);
+ virtual Result OnInitExprGetGlobalExpr(uint32_t index, uint32_t global_index);
+ virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprI64ConstExpr(uint32_t index, uint64_t value);
+
+ private:
+ Label* GetLabel(uint32_t depth);
+ Label* TopLabel();
+ void PushLabel(uint32_t offset, uint32_t fixup_offset);
+ void PopLabel();
+
+ bool HandleError(uint32_t offset, const char* message);
+ void PrintError(const char* format, ...);
+ static void OnTypecheckerError(const char* msg, void* user_data);
+
+ uint32_t TranslateSigIndexToEnv(uint32_t sig_index);
+ InterpreterFuncSignature* GetSignatureByEnvIndex(uint32_t sig_index);
+ InterpreterFuncSignature* GetSignatureByModuleIndex(uint32_t sig_index);
+ uint32_t TranslateFuncIndexToEnv(uint32_t func_index);
+ uint32_t TranslateModuleFuncIndexToDefined(uint32_t func_index);
+ InterpreterFunc* GetFuncByEnvIndex(uint32_t func_index);
+ InterpreterFunc* GetFuncByModuleIndex(uint32_t func_index);
+ uint32_t TranslateGlobalIndexToEnv(uint32_t global_index);
+ InterpreterGlobal* GetGlobalByEnvIndex(uint32_t global_index);
+ InterpreterGlobal* GetGlobalByModuleIndex(uint32_t global_index);
+ Type GetGlobalTypeByModuleIndex(uint32_t global_index);
+ uint32_t TranslateLocalIndex(uint32_t local_index);
+ Type GetLocalTypeByIndex(InterpreterFunc* func, uint32_t local_index);
+
+ uint32_t GetIstreamOffset();
+
+ Result EmitDataAt(size_t offset, const void* data, size_t size);
+ Result EmitData(const void* data, size_t size);
+ Result EmitOpcode(Opcode opcode);
+ Result EmitOpcode(InterpreterOpcode opcode);
+ Result EmitI8(uint8_t value);
+ Result EmitI32(uint32_t value);
+ Result EmitI64(uint64_t value);
+ Result EmitI32At(uint32_t offset, uint32_t value);
+ Result EmitDropKeep(uint32_t drop, uint8_t keep);
+ Result AppendFixup(Uint32VectorVector* fixups_vector, uint32_t index);
+ Result EmitBrOffset(uint32_t depth, uint32_t offset);
+ Result GetBrDropKeepCount(uint32_t depth,
+ uint32_t* out_drop_count,
+ uint32_t* out_keep_count);
+ Result GetReturnDropKeepCount(uint32_t* out_drop_count,
+ uint32_t* out_keep_count);
+ Result EmitBr(uint32_t depth, uint32_t drop_count, uint32_t keep_count);
+ Result EmitBrTableOffset(uint32_t depth);
+ Result FixupTopLabel();
+ Result EmitFuncOffset(DefinedInterpreterFunc* func, uint32_t func_index);
+
+ Result CheckLocal(uint32_t local_index);
+ Result CheckGlobal(uint32_t global_index);
+ Result CheckImportKind(InterpreterImport* import, ExternalKind expected_kind);
+ Result CheckImportLimits(const Limits* declared_limits,
+ const Limits* actual_limits);
+ Result CheckHasMemory(Opcode opcode);
+ Result CheckAlign(uint32_t alignment_log2, uint32_t natural_alignment);
+
+ Result AppendExport(InterpreterModule* module,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name);
+
+ PrintErrorCallback MakePrintErrorCallback();
+ static void OnHostImportPrintError(const char* msg, void* user_data);
- BinaryReader* reader = nullptr;
BinaryErrorHandler* error_handler = nullptr;
InterpreterEnvironment* env = nullptr;
DefinedInterpreterModule* module = nullptr;
DefinedInterpreterFunc* current_func = nullptr;
+ TypeCheckerErrorHandler tc_error_handler;
TypeChecker typechecker;
std::vector<Label> label_stack;
Uint32VectorVector func_fixups;
@@ -95,7 +279,13 @@ struct Context {
uint32_t num_func_imports = 0;
uint32_t num_global_imports = 0;
- /* values cached in the Context so they can be shared between callbacks */
+ // Changes to linear memory and tables should not apply if a validation error
+ // occurs; these vectors cache the changes that must be applied after we know
+ // that there are no validation errors.
+ std::vector<ElemSegmentInfo> elem_segment_infos;
+ std::vector<DataSegmentInfo> data_segment_infos;
+
+ /* values cached so they can be shared between callbacks */
InterpreterTypedValue init_expr_value;
uint32_t table_offset = 0;
bool is_host_import = false;
@@ -103,282 +293,286 @@ struct Context {
uint32_t import_env_index = 0;
};
-Context::Context() {
+BinaryReaderInterpreter::BinaryReaderInterpreter(
+ InterpreterEnvironment* env,
+ DefinedInterpreterModule* module,
+ size_t istream_offset,
+ BinaryErrorHandler* error_handler)
+ : error_handler(error_handler),
+ env(env),
+ module(module),
+ istream_offset(istream_offset) {
WABT_ZERO_MEMORY(istream_writer);
+
+ tc_error_handler.on_error = OnTypecheckerError;
+ tc_error_handler.user_data = this;
+ typechecker.error_handler = &tc_error_handler;
}
-} // namespace
+Result BinaryReaderInterpreter::Init() {
+ return init_mem_writer_existing(&istream_writer, &env->istream);
+}
+
+void BinaryReaderInterpreter::StealOutputBuffer(OutputBuffer* output_buffer) {
+ steal_mem_writer_output_buffer(&istream_writer, output_buffer);
+}
-static Label* get_label(Context* ctx, uint32_t depth) {
- assert(depth < ctx->label_stack.size());
- return &ctx->label_stack[ctx->label_stack.size() - depth - 1];
+Label* BinaryReaderInterpreter::GetLabel(uint32_t depth) {
+ assert(depth < label_stack.size());
+ return &label_stack[label_stack.size() - depth - 1];
}
-static Label* top_label(Context* ctx) {
- return get_label(ctx, 0);
+Label* BinaryReaderInterpreter::TopLabel() {
+ return GetLabel(0);
}
-static bool handle_error(uint32_t offset, const char* message, Context* ctx) {
- if (ctx->error_handler->on_error) {
- return ctx->error_handler->on_error(offset, message,
- ctx->error_handler->user_data);
+bool BinaryReaderInterpreter::HandleError(uint32_t offset,
+ const char* message) {
+ if (error_handler->on_error) {
+ return error_handler->on_error(offset, message, error_handler->user_data);
}
return false;
}
-static void WABT_PRINTF_FORMAT(2, 3)
- print_error(Context* ctx, const char* format, ...) {
+void WABT_PRINTF_FORMAT(2, 3)
+ BinaryReaderInterpreter::PrintError(const char* format, ...) {
WABT_SNPRINTF_ALLOCA(buffer, length, format);
- handle_error(WABT_INVALID_OFFSET, buffer, ctx);
+ HandleError(WABT_INVALID_OFFSET, buffer);
}
-static void on_typechecker_error(const char* msg, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_error(ctx, "%s", msg);
+// static
+void BinaryReaderInterpreter::OnTypecheckerError(const char* msg,
+ void* user_data) {
+ static_cast<BinaryReaderInterpreter*>(user_data)->PrintError("%s", msg);
}
-static uint32_t translate_sig_index_to_env(Context* ctx, uint32_t sig_index) {
- assert(sig_index < ctx->sig_index_mapping.size());
- return ctx->sig_index_mapping[sig_index];
+uint32_t BinaryReaderInterpreter::TranslateSigIndexToEnv(uint32_t sig_index) {
+ assert(sig_index < sig_index_mapping.size());
+ return sig_index_mapping[sig_index];
}
-static InterpreterFuncSignature* get_signature_by_env_index(
- Context* ctx,
+InterpreterFuncSignature* BinaryReaderInterpreter::GetSignatureByEnvIndex(
uint32_t sig_index) {
- return &ctx->env->sigs[sig_index];
+ return &env->sigs[sig_index];
}
-static InterpreterFuncSignature* get_signature_by_module_index(
- Context* ctx,
+InterpreterFuncSignature* BinaryReaderInterpreter::GetSignatureByModuleIndex(
uint32_t sig_index) {
- return get_signature_by_env_index(ctx,
- translate_sig_index_to_env(ctx, sig_index));
+ return GetSignatureByEnvIndex(TranslateSigIndexToEnv(sig_index));
}
-static uint32_t translate_func_index_to_env(Context* ctx, uint32_t func_index) {
- assert(func_index < ctx->func_index_mapping.size());
- return ctx->func_index_mapping[func_index];
+uint32_t BinaryReaderInterpreter::TranslateFuncIndexToEnv(uint32_t func_index) {
+ assert(func_index < func_index_mapping.size());
+ return func_index_mapping[func_index];
}
-static uint32_t translate_module_func_index_to_defined(Context* ctx,
- uint32_t func_index) {
- assert(func_index >= ctx->num_func_imports);
- return func_index - ctx->num_func_imports;
+uint32_t BinaryReaderInterpreter::TranslateModuleFuncIndexToDefined(
+ uint32_t func_index) {
+ assert(func_index >= num_func_imports);
+ return func_index - num_func_imports;
}
-static InterpreterFunc* get_func_by_env_index(Context* ctx,
- uint32_t func_index) {
- return ctx->env->funcs[func_index].get();
+InterpreterFunc* BinaryReaderInterpreter::GetFuncByEnvIndex(
+ uint32_t func_index) {
+ return env->funcs[func_index].get();
}
-static InterpreterFunc* get_func_by_module_index(Context* ctx,
- uint32_t func_index) {
- return get_func_by_env_index(ctx,
- translate_func_index_to_env(ctx, func_index));
+InterpreterFunc* BinaryReaderInterpreter::GetFuncByModuleIndex(
+ uint32_t func_index) {
+ return GetFuncByEnvIndex(TranslateFuncIndexToEnv(func_index));
}
-static uint32_t translate_global_index_to_env(Context* ctx,
- uint32_t global_index) {
- return ctx->global_index_mapping[global_index];
+uint32_t BinaryReaderInterpreter::TranslateGlobalIndexToEnv(
+ uint32_t global_index) {
+ return global_index_mapping[global_index];
}
-static InterpreterGlobal* get_global_by_env_index(Context* ctx,
- uint32_t global_index) {
- return &ctx->env->globals[global_index];
+InterpreterGlobal* BinaryReaderInterpreter::GetGlobalByEnvIndex(
+ uint32_t global_index) {
+ return &env->globals[global_index];
}
-static InterpreterGlobal* get_global_by_module_index(Context* ctx,
- uint32_t global_index) {
- return get_global_by_env_index(
- ctx, translate_global_index_to_env(ctx, global_index));
+InterpreterGlobal* BinaryReaderInterpreter::GetGlobalByModuleIndex(
+ uint32_t global_index) {
+ return GetGlobalByEnvIndex(TranslateGlobalIndexToEnv(global_index));
}
-static Type get_global_type_by_module_index(Context* ctx,
- uint32_t global_index) {
- return get_global_by_module_index(ctx, global_index)->typed_value.type;
+Type BinaryReaderInterpreter::GetGlobalTypeByModuleIndex(
+ uint32_t global_index) {
+ return GetGlobalByModuleIndex(global_index)->typed_value.type;
}
-static Type get_local_type_by_index(InterpreterFunc* func,
- uint32_t local_index) {
+Type BinaryReaderInterpreter::GetLocalTypeByIndex(InterpreterFunc* func,
+ uint32_t local_index) {
assert(!func->is_host);
return func->as_defined()->param_and_local_types[local_index];
}
-static uint32_t get_istream_offset(Context* ctx) {
- return ctx->istream_offset;
+uint32_t BinaryReaderInterpreter::GetIstreamOffset() {
+ return istream_offset;
}
-static Result emit_data_at(Context* ctx,
- size_t offset,
- const void* data,
- size_t size) {
- return ctx->istream_writer.base.write_data(
- offset, data, size, ctx->istream_writer.base.user_data);
+Result BinaryReaderInterpreter::EmitDataAt(size_t offset,
+ const void* data,
+ size_t size) {
+ return istream_writer.base.write_data(offset, data, size,
+ istream_writer.base.user_data);
}
-static Result emit_data(Context* ctx, const void* data, size_t size) {
- CHECK_RESULT(emit_data_at(ctx, ctx->istream_offset, data, size));
- ctx->istream_offset += size;
+Result BinaryReaderInterpreter::EmitData(const void* data, size_t size) {
+ CHECK_RESULT(EmitDataAt(istream_offset, data, size));
+ istream_offset += size;
return Result::Ok;
}
-static Result emit_opcode(Context* ctx, Opcode opcode) {
- return emit_data(ctx, &opcode, sizeof(uint8_t));
+Result BinaryReaderInterpreter::EmitOpcode(Opcode opcode) {
+ return EmitData(&opcode, sizeof(uint8_t));
}
-static Result emit_opcode(Context* ctx, InterpreterOpcode opcode) {
- return emit_data(ctx, &opcode, sizeof(uint8_t));
+Result BinaryReaderInterpreter::EmitOpcode(InterpreterOpcode opcode) {
+ return EmitData(&opcode, sizeof(uint8_t));
}
-static Result emit_i8(Context* ctx, uint8_t value) {
- return emit_data(ctx, &value, sizeof(value));
+Result BinaryReaderInterpreter::EmitI8(uint8_t value) {
+ return EmitData(&value, sizeof(value));
}
-static Result emit_i32(Context* ctx, uint32_t value) {
- return emit_data(ctx, &value, sizeof(value));
+Result BinaryReaderInterpreter::EmitI32(uint32_t value) {
+ return EmitData(&value, sizeof(value));
}
-static Result emit_i64(Context* ctx, uint64_t value) {
- return emit_data(ctx, &value, sizeof(value));
+Result BinaryReaderInterpreter::EmitI64(uint64_t value) {
+ return EmitData(&value, sizeof(value));
}
-static Result emit_i32_at(Context* ctx, uint32_t offset, uint32_t value) {
- return emit_data_at(ctx, offset, &value, sizeof(value));
+Result BinaryReaderInterpreter::EmitI32At(uint32_t offset, uint32_t value) {
+ return EmitDataAt(offset, &value, sizeof(value));
}
-static Result emit_drop_keep(Context* ctx, uint32_t drop, uint8_t keep) {
+Result BinaryReaderInterpreter::EmitDropKeep(uint32_t drop, uint8_t keep) {
assert(drop != UINT32_MAX);
assert(keep <= 1);
if (drop > 0) {
if (drop == 1 && keep == 0) {
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Drop));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Drop));
} else {
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::DropKeep));
- CHECK_RESULT(emit_i32(ctx, drop));
- CHECK_RESULT(emit_i8(ctx, keep));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::DropKeep));
+ CHECK_RESULT(EmitI32(drop));
+ CHECK_RESULT(EmitI8(keep));
}
}
return Result::Ok;
}
-static Result append_fixup(Context* ctx,
- Uint32VectorVector* fixups_vector,
- uint32_t index) {
+Result BinaryReaderInterpreter::AppendFixup(Uint32VectorVector* fixups_vector,
+ uint32_t index) {
if (index >= fixups_vector->size())
fixups_vector->resize(index + 1);
- (*fixups_vector)[index].push_back(get_istream_offset(ctx));
+ (*fixups_vector)[index].push_back(GetIstreamOffset());
return Result::Ok;
}
-static Result emit_br_offset(Context* ctx, uint32_t depth, uint32_t offset) {
+Result BinaryReaderInterpreter::EmitBrOffset(uint32_t depth, uint32_t offset) {
if (offset == WABT_INVALID_OFFSET) {
/* depth_fixups stores the depth counting up from zero, where zero is the
* top-level function scope. */
- depth = ctx->label_stack.size() - 1 - depth;
- CHECK_RESULT(append_fixup(ctx, &ctx->depth_fixups, depth));
+ depth = label_stack.size() - 1 - depth;
+ CHECK_RESULT(AppendFixup(&depth_fixups, depth));
}
- CHECK_RESULT(emit_i32(ctx, offset));
+ CHECK_RESULT(EmitI32(offset));
return Result::Ok;
}
-static Result get_br_drop_keep_count(Context* ctx,
- uint32_t depth,
- uint32_t* out_drop_count,
- uint32_t* out_keep_count) {
+Result BinaryReaderInterpreter::GetBrDropKeepCount(uint32_t depth,
+ uint32_t* out_drop_count,
+ uint32_t* out_keep_count) {
TypeCheckerLabel* label;
- CHECK_RESULT(typechecker_get_label(&ctx->typechecker, depth, &label));
+ CHECK_RESULT(typechecker_get_label(&typechecker, depth, &label));
*out_keep_count =
label->label_type != LabelType::Loop ? label->sig.size() : 0;
- if (typechecker_is_unreachable(&ctx->typechecker)) {
+ if (typechecker_is_unreachable(&typechecker)) {
*out_drop_count = 0;
} else {
*out_drop_count =
- (ctx->typechecker.type_stack.size() - label->type_stack_limit) -
+ (typechecker.type_stack.size() - label->type_stack_limit) -
*out_keep_count;
}
return Result::Ok;
}
-static Result get_return_drop_keep_count(Context* ctx,
- uint32_t* out_drop_count,
- uint32_t* out_keep_count) {
- if (WABT_FAILED(get_br_drop_keep_count(ctx, ctx->label_stack.size() - 1,
- out_drop_count, out_keep_count))) {
+Result BinaryReaderInterpreter::GetReturnDropKeepCount(
+ uint32_t* out_drop_count,
+ uint32_t* out_keep_count) {
+ if (WABT_FAILED(GetBrDropKeepCount(label_stack.size() - 1, out_drop_count,
+ out_keep_count))) {
return Result::Error;
}
- *out_drop_count += ctx->current_func->param_and_local_types.size();
+ *out_drop_count += current_func->param_and_local_types.size();
return Result::Ok;
}
-static Result emit_br(Context* ctx,
- uint32_t depth,
- uint32_t drop_count,
- uint32_t keep_count) {
- CHECK_RESULT(emit_drop_keep(ctx, drop_count, keep_count));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Br));
- CHECK_RESULT(emit_br_offset(ctx, depth, get_label(ctx, depth)->offset));
+Result BinaryReaderInterpreter::EmitBr(uint32_t depth,
+ uint32_t drop_count,
+ uint32_t keep_count) {
+ CHECK_RESULT(EmitDropKeep(drop_count, keep_count));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Br));
+ CHECK_RESULT(EmitBrOffset(depth, GetLabel(depth)->offset));
return Result::Ok;
}
-static Result emit_br_table_offset(Context* ctx, uint32_t depth) {
+Result BinaryReaderInterpreter::EmitBrTableOffset(uint32_t depth) {
uint32_t drop_count, keep_count;
- CHECK_RESULT(get_br_drop_keep_count(ctx, depth, &drop_count, &keep_count));
- CHECK_RESULT(emit_br_offset(ctx, depth, get_label(ctx, depth)->offset));
- CHECK_RESULT(emit_i32(ctx, drop_count));
- CHECK_RESULT(emit_i8(ctx, keep_count));
+ CHECK_RESULT(GetBrDropKeepCount(depth, &drop_count, &keep_count));
+ CHECK_RESULT(EmitBrOffset(depth, GetLabel(depth)->offset));
+ CHECK_RESULT(EmitI32(drop_count));
+ CHECK_RESULT(EmitI8(keep_count));
return Result::Ok;
}
-static Result fixup_top_label(Context* ctx) {
- uint32_t offset = get_istream_offset(ctx);
- uint32_t top = ctx->label_stack.size() - 1;
- if (top >= ctx->depth_fixups.size()) {
+Result BinaryReaderInterpreter::FixupTopLabel() {
+ uint32_t offset = GetIstreamOffset();
+ uint32_t top = label_stack.size() - 1;
+ if (top >= depth_fixups.size()) {
/* nothing to fixup */
return Result::Ok;
}
- Uint32Vector& fixups = ctx->depth_fixups[top];
- for (uint32_t fixup: fixups)
- CHECK_RESULT(emit_i32_at(ctx, fixup, offset));
+ Uint32Vector& fixups = depth_fixups[top];
+ for (uint32_t fixup : fixups)
+ CHECK_RESULT(EmitI32At(fixup, offset));
fixups.clear();
return Result::Ok;
}
-static Result emit_func_offset(Context* ctx,
- DefinedInterpreterFunc* func,
- uint32_t func_index) {
+Result BinaryReaderInterpreter::EmitFuncOffset(DefinedInterpreterFunc* func,
+ uint32_t func_index) {
if (func->offset == WABT_INVALID_OFFSET) {
- uint32_t defined_index =
- translate_module_func_index_to_defined(ctx, func_index);
- CHECK_RESULT(append_fixup(ctx, &ctx->func_fixups, defined_index));
+ uint32_t defined_index = TranslateModuleFuncIndexToDefined(func_index);
+ CHECK_RESULT(AppendFixup(&func_fixups, defined_index));
}
- CHECK_RESULT(emit_i32(ctx, func->offset));
+ CHECK_RESULT(EmitI32(func->offset));
return Result::Ok;
}
-static bool on_error(BinaryReaderContext* ctx, const char* message) {
- return handle_error(ctx->offset, message,
- static_cast<Context*>(ctx->user_data));
+bool BinaryReaderInterpreter::OnError(const char* message) {
+ return HandleError(state->offset, message);
}
-static Result on_signature_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->sig_index_mapping.resize(count);
+Result BinaryReaderInterpreter::OnTypeCount(uint32_t count) {
+ sig_index_mapping.resize(count);
for (uint32_t i = 0; i < count; ++i)
- ctx->sig_index_mapping[i] = ctx->env->sigs.size() + i;
- ctx->env->sigs.resize(ctx->env->sigs.size() + count);
+ sig_index_mapping[i] = env->sigs.size() + i;
+ env->sigs.resize(env->sigs.size() + count);
return Result::Ok;
}
-static Result on_signature(uint32_t index,
- uint32_t param_count,
- Type* param_types,
- uint32_t result_count,
- Type* result_types,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- InterpreterFuncSignature* sig = get_signature_by_module_index(ctx, index);
+Result BinaryReaderInterpreter::OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types) {
+ InterpreterFuncSignature* sig = GetSignatureByModuleIndex(index);
sig->param_types.insert(sig->param_types.end(), param_types,
param_types + param_count);
sig->result_types.insert(sig->result_types.end(), result_types,
@@ -386,85 +580,97 @@ static Result on_signature(uint32_t index,
return Result::Ok;
}
-static Result on_import_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->module->imports.resize(count);
+Result BinaryReaderInterpreter::OnImportCount(uint32_t count) {
+ module->imports.resize(count);
return Result::Ok;
}
-static Result on_import(uint32_t index,
- StringSlice module_name,
- StringSlice field_name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- InterpreterImport* import = &ctx->module->imports[index];
+Result BinaryReaderInterpreter::OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name) {
+ InterpreterImport* import = &module->imports[index];
import->module_name = dup_string_slice(module_name);
import->field_name = dup_string_slice(field_name);
int module_index =
- ctx->env->registered_module_bindings.find_index(import->module_name);
+ env->registered_module_bindings.find_index(import->module_name);
if (module_index < 0) {
- print_error(ctx, "unknown import module \"" PRIstringslice "\"",
- WABT_PRINTF_STRING_SLICE_ARG(import->module_name));
+ PrintError("unknown import module \"" PRIstringslice "\"",
+ WABT_PRINTF_STRING_SLICE_ARG(import->module_name));
return Result::Error;
}
- InterpreterModule* module = ctx->env->modules[module_index].get();
+ InterpreterModule* module = env->modules[module_index].get();
if (module->is_host) {
/* We don't yet know the kind of a host import module, so just assume it
* exists for now. We'll fail later (in on_import_* below) if it doesn't
* exist). */
- ctx->is_host_import = true;
- ctx->host_import_module = module->as_host();
+ is_host_import = true;
+ host_import_module = module->as_host();
} else {
InterpreterExport* export_ =
get_interpreter_export_by_name(module, &import->field_name);
if (!export_) {
- print_error(ctx, "unknown module field \"" PRIstringslice "\"",
- WABT_PRINTF_STRING_SLICE_ARG(import->field_name));
+ PrintError("unknown module field \"" PRIstringslice "\"",
+ WABT_PRINTF_STRING_SLICE_ARG(import->field_name));
return Result::Error;
}
import->kind = export_->kind;
- ctx->is_host_import = false;
- ctx->import_env_index = export_->index;
+ is_host_import = false;
+ import_env_index = export_->index;
+ }
+ return Result::Ok;
+}
+
+Result BinaryReaderInterpreter::CheckLocal(uint32_t local_index) {
+ uint32_t max_local_index = current_func->param_and_local_types.size();
+ if (local_index >= max_local_index) {
+ PrintError("invalid local_index: %d (max %d)", local_index,
+ max_local_index);
+ return Result::Error;
+ }
+ return Result::Ok;
+}
+
+Result BinaryReaderInterpreter::CheckGlobal(uint32_t global_index) {
+ uint32_t max_global_index = global_index_mapping.size();
+ if (global_index >= max_global_index) {
+ PrintError("invalid global_index: %d (max %d)", global_index,
+ max_global_index);
+ return Result::Error;
}
return Result::Ok;
}
-static Result check_import_kind(Context* ctx,
- InterpreterImport* import,
- ExternalKind expected_kind) {
+Result BinaryReaderInterpreter::CheckImportKind(InterpreterImport* import,
+ ExternalKind expected_kind) {
if (import->kind != expected_kind) {
- print_error(ctx, "expected import \"" PRIstringslice "." PRIstringslice
- "\" to have kind %s, not %s",
- WABT_PRINTF_STRING_SLICE_ARG(import->module_name),
- WABT_PRINTF_STRING_SLICE_ARG(import->field_name),
- get_kind_name(expected_kind), get_kind_name(import->kind));
+ PrintError("expected import \"" PRIstringslice "." PRIstringslice
+ "\" to have kind %s, not %s",
+ WABT_PRINTF_STRING_SLICE_ARG(import->module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(import->field_name),
+ get_kind_name(expected_kind), get_kind_name(import->kind));
return Result::Error;
}
return Result::Ok;
}
-static Result check_import_limits(Context* ctx,
- const Limits* declared_limits,
- const Limits* actual_limits) {
+Result BinaryReaderInterpreter::CheckImportLimits(const Limits* declared_limits,
+ const Limits* actual_limits) {
if (actual_limits->initial < declared_limits->initial) {
- print_error(ctx,
- "actual size (%" PRIu64 ") smaller than declared (%" PRIu64 ")",
- actual_limits->initial, declared_limits->initial);
+ PrintError("actual size (%" PRIu64 ") smaller than declared (%" PRIu64 ")",
+ actual_limits->initial, declared_limits->initial);
return Result::Error;
}
if (declared_limits->has_max) {
if (!actual_limits->has_max) {
- print_error(ctx,
- "max size (unspecified) larger than declared (%" PRIu64 ")",
- declared_limits->max);
+ PrintError("max size (unspecified) larger than declared (%" PRIu64 ")",
+ declared_limits->max);
return Result::Error;
} else if (actual_limits->max > declared_limits->max) {
- print_error(ctx,
- "max size (%" PRIu64 ") larger than declared (%" PRIu64 ")",
- actual_limits->max, declared_limits->max);
+ PrintError("max size (%" PRIu64 ") larger than declared (%" PRIu64 ")",
+ actual_limits->max, declared_limits->max);
return Result::Error;
}
}
@@ -472,14 +678,13 @@ static Result check_import_limits(Context* ctx,
return Result::Ok;
}
-static Result append_export(Context* ctx,
- InterpreterModule* module,
- ExternalKind kind,
- uint32_t item_index,
- StringSlice name) {
+Result BinaryReaderInterpreter::AppendExport(InterpreterModule* module,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) {
if (module->export_bindings.find_index(name) != -1) {
- print_error(ctx, "duplicate export \"" PRIstringslice "\"",
- WABT_PRINTF_STRING_SLICE_ARG(name));
+ PrintError("duplicate export \"" PRIstringslice "\"",
+ WABT_PRINTF_STRING_SLICE_ARG(name));
return Result::Error;
}
@@ -491,1016 +696,820 @@ static Result append_export(Context* ctx,
return Result::Ok;
}
-static void on_host_import_print_error(const char* msg, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_error(ctx, "%s", msg);
+// static
+void BinaryReaderInterpreter::OnHostImportPrintError(const char* msg,
+ void* user_data) {
+ static_cast<BinaryReaderInterpreter*>(user_data)->PrintError("%s", msg);
}
-static PrintErrorCallback make_print_error_callback(Context* ctx) {
+PrintErrorCallback BinaryReaderInterpreter::MakePrintErrorCallback() {
PrintErrorCallback result;
- result.print_error = on_host_import_print_error;
- result.user_data = ctx;
+ result.print_error = OnHostImportPrintError;
+ result.user_data = this;
return result;
}
-static Result on_import_func(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t func_index,
- uint32_t sig_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- InterpreterImport* import = &ctx->module->imports[import_index];
- import->func.sig_index = translate_sig_index_to_env(ctx, sig_index);
+Result BinaryReaderInterpreter::OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index) {
+ InterpreterImport* import = &module->imports[import_index];
+ import->func.sig_index = TranslateSigIndexToEnv(sig_index);
uint32_t func_env_index;
- if (ctx->is_host_import) {
+ if (is_host_import) {
HostInterpreterFunc* func = new HostInterpreterFunc(
import->module_name, import->field_name, import->func.sig_index);
- ctx->env->funcs.emplace_back(func);
+ env->funcs.emplace_back(func);
InterpreterHostImportDelegate* host_delegate =
- &ctx->host_import_module->import_delegate;
- InterpreterFuncSignature* sig = &ctx->env->sigs[func->sig_index];
- CHECK_RESULT(host_delegate->import_func(import, func, sig,
- make_print_error_callback(ctx),
- host_delegate->user_data));
+ &host_import_module->import_delegate;
+ InterpreterFuncSignature* sig = &env->sigs[func->sig_index];
+ CHECK_RESULT(host_delegate->import_func(
+ import, func, sig, MakePrintErrorCallback(), host_delegate->user_data));
assert(func->callback);
- func_env_index = ctx->env->funcs.size() - 1;
- append_export(ctx, ctx->host_import_module, ExternalKind::Func,
- func_env_index, import->field_name);
+ func_env_index = env->funcs.size() - 1;
+ AppendExport(host_import_module, ExternalKind::Func, func_env_index,
+ import->field_name);
} else {
- CHECK_RESULT(check_import_kind(ctx, import, ExternalKind::Func));
- InterpreterFunc* func = ctx->env->funcs[ctx->import_env_index].get();
- if (!func_signatures_are_equal(ctx->env, import->func.sig_index,
+ CHECK_RESULT(CheckImportKind(import, ExternalKind::Func));
+ InterpreterFunc* func = env->funcs[import_env_index].get();
+ if (!func_signatures_are_equal(env, import->func.sig_index,
func->sig_index)) {
- print_error(ctx, "import signature mismatch");
+ PrintError("import signature mismatch");
return Result::Error;
}
- func_env_index = ctx->import_env_index;
+ func_env_index = import_env_index;
}
- ctx->func_index_mapping.push_back(func_env_index);
- ctx->num_func_imports++;
+ func_index_mapping.push_back(func_env_index);
+ num_func_imports++;
return Result::Ok;
}
-static Result on_import_table(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t table_index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->module->table_index != WABT_INVALID_INDEX) {
- print_error(ctx, "only one table allowed");
+Result BinaryReaderInterpreter::OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ if (module->table_index != WABT_INVALID_INDEX) {
+ PrintError("only one table allowed");
return Result::Error;
}
- InterpreterImport* import = &ctx->module->imports[import_index];
+ InterpreterImport* import = &module->imports[import_index];
- if (ctx->is_host_import) {
- ctx->env->tables.emplace_back(*elem_limits);
- InterpreterTable* table = &ctx->env->tables.back();
+ if (is_host_import) {
+ env->tables.emplace_back(*elem_limits);
+ InterpreterTable* table = &env->tables.back();
InterpreterHostImportDelegate* host_delegate =
- &ctx->host_import_module->import_delegate;
- CHECK_RESULT(host_delegate->import_table(import, table,
- make_print_error_callback(ctx),
- host_delegate->user_data));
+ &host_import_module->import_delegate;
+ CHECK_RESULT(host_delegate->import_table(
+ import, table, MakePrintErrorCallback(), host_delegate->user_data));
- CHECK_RESULT(check_import_limits(ctx, elem_limits, &table->limits));
+ CHECK_RESULT(CheckImportLimits(elem_limits, &table->limits));
- ctx->module->table_index = ctx->env->tables.size() - 1;
- append_export(ctx, ctx->host_import_module, ExternalKind::Table,
- ctx->module->table_index, import->field_name);
+ module->table_index = env->tables.size() - 1;
+ AppendExport(host_import_module, ExternalKind::Table, module->table_index,
+ import->field_name);
} else {
- CHECK_RESULT(check_import_kind(ctx, import, ExternalKind::Table));
- InterpreterTable* table = &ctx->env->tables[ctx->import_env_index];
- CHECK_RESULT(check_import_limits(ctx, elem_limits, &table->limits));
+ CHECK_RESULT(CheckImportKind(import, ExternalKind::Table));
+ InterpreterTable* table = &env->tables[import_env_index];
+ CHECK_RESULT(CheckImportLimits(elem_limits, &table->limits));
import->table.limits = *elem_limits;
- ctx->module->table_index = ctx->import_env_index;
+ module->table_index = import_env_index;
}
return Result::Ok;
}
-static Result on_import_memory(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t memory_index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->module->memory_index != WABT_INVALID_INDEX) {
- print_error(ctx, "only one memory allowed");
+Result BinaryReaderInterpreter::OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits) {
+ if (module->memory_index != WABT_INVALID_INDEX) {
+ PrintError("only one memory allowed");
return Result::Error;
}
- InterpreterImport* import = &ctx->module->imports[import_index];
+ InterpreterImport* import = &module->imports[import_index];
- if (ctx->is_host_import) {
- ctx->env->memories.emplace_back();
- InterpreterMemory* memory = &ctx->env->memories.back();
+ if (is_host_import) {
+ env->memories.emplace_back();
+ InterpreterMemory* memory = &env->memories.back();
InterpreterHostImportDelegate* host_delegate =
- &ctx->host_import_module->import_delegate;
- CHECK_RESULT(host_delegate->import_memory(import, memory,
- make_print_error_callback(ctx),
- host_delegate->user_data));
+ &host_import_module->import_delegate;
+ CHECK_RESULT(host_delegate->import_memory(
+ import, memory, MakePrintErrorCallback(), host_delegate->user_data));
- CHECK_RESULT(check_import_limits(ctx, page_limits, &memory->page_limits));
+ CHECK_RESULT(CheckImportLimits(page_limits, &memory->page_limits));
- ctx->module->memory_index = ctx->env->memories.size() - 1;
- append_export(ctx, ctx->host_import_module, ExternalKind::Memory,
- ctx->module->memory_index, import->field_name);
+ module->memory_index = env->memories.size() - 1;
+ AppendExport(host_import_module, ExternalKind::Memory, module->memory_index,
+ import->field_name);
} else {
- CHECK_RESULT(check_import_kind(ctx, import, ExternalKind::Memory));
- InterpreterMemory* memory = &ctx->env->memories[ctx->import_env_index];
- CHECK_RESULT(check_import_limits(ctx, page_limits, &memory->page_limits));
+ CHECK_RESULT(CheckImportKind(import, ExternalKind::Memory));
+ InterpreterMemory* memory = &env->memories[import_env_index];
+ CHECK_RESULT(CheckImportLimits(page_limits, &memory->page_limits));
import->memory.limits = *page_limits;
- ctx->module->memory_index = ctx->import_env_index;
+ module->memory_index = import_env_index;
}
return Result::Ok;
}
-static Result on_import_global(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t global_index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- InterpreterImport* import = &ctx->module->imports[import_index];
-
- uint32_t global_env_index = ctx->env->globals.size() - 1;
- if (ctx->is_host_import) {
- ctx->env->globals.emplace_back(InterpreterTypedValue(type), mutable_);
- InterpreterGlobal* global = &ctx->env->globals.back();
+Result BinaryReaderInterpreter::OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_) {
+ InterpreterImport* import = &module->imports[import_index];
+
+ uint32_t global_env_index = env->globals.size() - 1;
+ if (is_host_import) {
+ env->globals.emplace_back(InterpreterTypedValue(type), mutable_);
+ InterpreterGlobal* global = &env->globals.back();
InterpreterHostImportDelegate* host_delegate =
- &ctx->host_import_module->import_delegate;
- CHECK_RESULT(host_delegate->import_global(import, global,
- make_print_error_callback(ctx),
- host_delegate->user_data));
-
- global_env_index = ctx->env->globals.size() - 1;
- append_export(ctx, ctx->host_import_module, ExternalKind::Global,
- global_env_index, import->field_name);
+ &host_import_module->import_delegate;
+ CHECK_RESULT(host_delegate->import_global(
+ import, global, MakePrintErrorCallback(), host_delegate->user_data));
+
+ global_env_index = env->globals.size() - 1;
+ AppendExport(host_import_module, ExternalKind::Global, global_env_index,
+ import->field_name);
} else {
- CHECK_RESULT(check_import_kind(ctx, import, ExternalKind::Global));
+ CHECK_RESULT(CheckImportKind(import, ExternalKind::Global));
// TODO: check type and mutability
import->global.type = type;
import->global.mutable_ = mutable_;
- global_env_index = ctx->import_env_index;
+ global_env_index = import_env_index;
}
- ctx->global_index_mapping.push_back(global_env_index);
- ctx->num_global_imports++;
+ global_index_mapping.push_back(global_env_index);
+ num_global_imports++;
return Result::Ok;
}
-static Result on_function_signatures_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnFunctionCount(uint32_t count) {
for (uint32_t i = 0; i < count; ++i)
- ctx->func_index_mapping.push_back(ctx->env->funcs.size() + i);
- ctx->env->funcs.reserve(ctx->env->funcs.size() + count);
- ctx->func_fixups.resize(count);
+ func_index_mapping.push_back(env->funcs.size() + i);
+ env->funcs.reserve(env->funcs.size() + count);
+ func_fixups.resize(count);
return Result::Ok;
}
-static Result on_function_signature(uint32_t index,
- uint32_t sig_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnFunction(uint32_t index, uint32_t sig_index) {
DefinedInterpreterFunc* func =
- new DefinedInterpreterFunc(translate_sig_index_to_env(ctx, sig_index));
- ctx->env->funcs.emplace_back(func);
+ new DefinedInterpreterFunc(TranslateSigIndexToEnv(sig_index));
+ env->funcs.emplace_back(func);
return Result::Ok;
}
-static Result on_table(uint32_t index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->module->table_index != WABT_INVALID_INDEX) {
- print_error(ctx, "only one table allowed");
+Result BinaryReaderInterpreter::OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ if (module->table_index != WABT_INVALID_INDEX) {
+ PrintError("only one table allowed");
return Result::Error;
}
- ctx->env->tables.emplace_back(*elem_limits);
- ctx->module->table_index = ctx->env->tables.size() - 1;
+ env->tables.emplace_back(*elem_limits);
+ module->table_index = env->tables.size() - 1;
return Result::Ok;
}
-static Result on_memory(uint32_t index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->module->memory_index != WABT_INVALID_INDEX) {
- print_error(ctx, "only one memory allowed");
+Result BinaryReaderInterpreter::OnMemory(uint32_t index,
+ const Limits* page_limits) {
+ if (module->memory_index != WABT_INVALID_INDEX) {
+ PrintError("only one memory allowed");
return Result::Error;
}
- ctx->env->memories.emplace_back(*page_limits);
- ctx->module->memory_index = ctx->env->memories.size() - 1;
+ env->memories.emplace_back(*page_limits);
+ module->memory_index = env->memories.size() - 1;
return Result::Ok;
}
-static Result on_global_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnGlobalCount(uint32_t count) {
for (uint32_t i = 0; i < count; ++i)
- ctx->global_index_mapping.push_back(ctx->env->globals.size() + i);
- ctx->env->globals.resize(ctx->env->globals.size() + count);
+ global_index_mapping.push_back(env->globals.size() + i);
+ env->globals.resize(env->globals.size() + count);
return Result::Ok;
}
-static Result begin_global(uint32_t index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- InterpreterGlobal* global = get_global_by_module_index(ctx, index);
+Result BinaryReaderInterpreter::BeginGlobal(uint32_t index,
+ Type type,
+ bool mutable_) {
+ InterpreterGlobal* global = GetGlobalByModuleIndex(index);
global->typed_value.type = type;
global->mutable_ = mutable_;
return Result::Ok;
}
-static Result end_global_init_expr(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- InterpreterGlobal* global = get_global_by_module_index(ctx, index);
- if (ctx->init_expr_value.type != global->typed_value.type) {
- print_error(ctx, "type mismatch in global, expected %s but got %s.",
- get_type_name(global->typed_value.type),
- get_type_name(ctx->init_expr_value.type));
+Result BinaryReaderInterpreter::EndGlobalInitExpr(uint32_t index) {
+ InterpreterGlobal* global = GetGlobalByModuleIndex(index);
+ if (init_expr_value.type != global->typed_value.type) {
+ PrintError("type mismatch in global, expected %s but got %s.",
+ get_type_name(global->typed_value.type),
+ get_type_name(init_expr_value.type));
return Result::Error;
}
- global->typed_value = ctx->init_expr_value;
+ global->typed_value = init_expr_value;
return Result::Ok;
}
-static Result on_init_expr_f32_const_expr(uint32_t index,
- uint32_t value_bits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->init_expr_value.type = Type::F32;
- ctx->init_expr_value.value.f32_bits = value_bits;
+Result BinaryReaderInterpreter::OnInitExprF32ConstExpr(uint32_t index,
+ uint32_t value_bits) {
+ init_expr_value.type = Type::F32;
+ init_expr_value.value.f32_bits = value_bits;
return Result::Ok;
}
-static Result on_init_expr_f64_const_expr(uint32_t index,
- uint64_t value_bits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->init_expr_value.type = Type::F64;
- ctx->init_expr_value.value.f64_bits = value_bits;
+Result BinaryReaderInterpreter::OnInitExprF64ConstExpr(uint32_t index,
+ uint64_t value_bits) {
+ init_expr_value.type = Type::F64;
+ init_expr_value.value.f64_bits = value_bits;
return Result::Ok;
}
-static Result on_init_expr_get_global_expr(uint32_t index,
- uint32_t global_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (global_index >= ctx->num_global_imports) {
- print_error(ctx,
- "initializer expression can only reference an imported global");
+Result BinaryReaderInterpreter::OnInitExprGetGlobalExpr(uint32_t index,
+ uint32_t global_index) {
+ if (global_index >= num_global_imports) {
+ PrintError("initializer expression can only reference an imported global");
return Result::Error;
}
- InterpreterGlobal* ref_global = get_global_by_module_index(ctx, global_index);
+ InterpreterGlobal* ref_global = GetGlobalByModuleIndex(global_index);
if (ref_global->mutable_) {
- print_error(ctx,
- "initializer expression cannot reference a mutable global");
+ PrintError("initializer expression cannot reference a mutable global");
return Result::Error;
}
- ctx->init_expr_value = ref_global->typed_value;
+ init_expr_value = ref_global->typed_value;
return Result::Ok;
}
-static Result on_init_expr_i32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->init_expr_value.type = Type::I32;
- ctx->init_expr_value.value.i32 = value;
+Result BinaryReaderInterpreter::OnInitExprI32ConstExpr(uint32_t index,
+ uint32_t value) {
+ init_expr_value.type = Type::I32;
+ init_expr_value.value.i32 = value;
return Result::Ok;
}
-static Result on_init_expr_i64_const_expr(uint32_t index,
- uint64_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->init_expr_value.type = Type::I64;
- ctx->init_expr_value.value.i64 = value;
+Result BinaryReaderInterpreter::OnInitExprI64ConstExpr(uint32_t index,
+ uint64_t value) {
+ init_expr_value.type = Type::I64;
+ init_expr_value.value.i64 = value;
return Result::Ok;
}
-static Result on_export(uint32_t index,
- ExternalKind kind,
- uint32_t item_index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) {
switch (kind) {
case ExternalKind::Func:
- item_index = translate_func_index_to_env(ctx, item_index);
+ item_index = TranslateFuncIndexToEnv(item_index);
break;
case ExternalKind::Table:
- item_index = ctx->module->table_index;
+ item_index = module->table_index;
break;
case ExternalKind::Memory:
- item_index = ctx->module->memory_index;
+ item_index = module->memory_index;
break;
case ExternalKind::Global: {
- item_index = translate_global_index_to_env(ctx, item_index);
- InterpreterGlobal* global = &ctx->env->globals[item_index];
+ item_index = TranslateGlobalIndexToEnv(item_index);
+ InterpreterGlobal* global = &env->globals[item_index];
if (global->mutable_) {
- print_error(ctx, "mutable globals cannot be exported");
+ PrintError("mutable globals cannot be exported");
return Result::Error;
}
break;
}
}
- return append_export(ctx, ctx->module, kind, item_index, name);
+ return AppendExport(module, kind, item_index, name);
}
-static Result on_start_function(uint32_t func_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- uint32_t start_func_index = translate_func_index_to_env(ctx, func_index);
- InterpreterFunc* start_func = get_func_by_env_index(ctx, start_func_index);
- InterpreterFuncSignature* sig =
- get_signature_by_env_index(ctx, start_func->sig_index);
+Result BinaryReaderInterpreter::OnStartFunction(uint32_t func_index) {
+ uint32_t start_func_index = TranslateFuncIndexToEnv(func_index);
+ InterpreterFunc* start_func = GetFuncByEnvIndex(start_func_index);
+ InterpreterFuncSignature* sig = GetSignatureByEnvIndex(start_func->sig_index);
if (sig->param_types.size() != 0) {
- print_error(ctx, "start function must be nullary");
+ PrintError("start function must be nullary");
return Result::Error;
}
if (sig->result_types.size() != 0) {
- print_error(ctx, "start function must not return anything");
+ PrintError("start function must not return anything");
return Result::Error;
}
- ctx->module->start_func_index = start_func_index;
+ module->start_func_index = start_func_index;
return Result::Ok;
}
-static Result end_elem_segment_init_expr(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->init_expr_value.type != Type::I32) {
- print_error(ctx, "type mismatch in elem segment, expected i32 but got %s",
- get_type_name(ctx->init_expr_value.type));
+Result BinaryReaderInterpreter::EndElemSegmentInitExpr(uint32_t index) {
+ if (init_expr_value.type != Type::I32) {
+ PrintError("type mismatch in elem segment, expected i32 but got %s",
+ get_type_name(init_expr_value.type));
return Result::Error;
}
- ctx->table_offset = ctx->init_expr_value.value.i32;
+ table_offset = init_expr_value.value.i32;
return Result::Ok;
}
-static Result on_elem_segment_function_index_check(uint32_t index,
- uint32_t func_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(ctx->module->table_index != WABT_INVALID_INDEX);
- InterpreterTable* table = &ctx->env->tables[ctx->module->table_index];
- if (ctx->table_offset >= table->func_indexes.size()) {
- print_error(ctx,
- "elem segment offset is out of bounds: %u >= max value %" PRIzd,
- ctx->table_offset, table->func_indexes.size());
+Result BinaryReaderInterpreter::OnElemSegmentFunctionIndex(
+
+ uint32_t index,
+ uint32_t func_index) {
+ assert(module->table_index != WABT_INVALID_INDEX);
+ InterpreterTable* table = &env->tables[module->table_index];
+ if (table_offset >= table->func_indexes.size()) {
+ PrintError("elem segment offset is out of bounds: %u >= max value %" PRIzd,
+ table_offset, table->func_indexes.size());
return Result::Error;
}
- uint32_t max_func_index = ctx->func_index_mapping.size();
+ uint32_t max_func_index = func_index_mapping.size();
if (func_index >= max_func_index) {
- print_error(ctx, "invalid func_index: %d (max %d)", func_index,
- max_func_index);
+ PrintError("invalid func_index: %d (max %d)", func_index, max_func_index);
return Result::Error;
}
+ elem_segment_infos.emplace_back(&table->func_indexes[table_offset++],
+ TranslateFuncIndexToEnv(func_index));
return Result::Ok;
}
-static Result on_elem_segment_function_index(uint32_t index,
- uint32_t func_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(ctx->module->table_index != WABT_INVALID_INDEX);
- InterpreterTable* table = &ctx->env->tables[ctx->module->table_index];
- table->func_indexes[ctx->table_offset++] =
- translate_func_index_to_env(ctx, func_index);
- return Result::Ok;
-}
-
-static Result on_data_segment_data_check(uint32_t index,
- const void* src_data,
- uint32_t size,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- assert(ctx->module->memory_index != WABT_INVALID_INDEX);
- InterpreterMemory* memory = &ctx->env->memories[ctx->module->memory_index];
- if (ctx->init_expr_value.type != Type::I32) {
- print_error(ctx, "type mismatch in data segment, expected i32 but got %s",
- get_type_name(ctx->init_expr_value.type));
+Result BinaryReaderInterpreter::OnDataSegmentData(uint32_t index,
+ const void* src_data,
+ uint32_t size) {
+ assert(module->memory_index != WABT_INVALID_INDEX);
+ InterpreterMemory* memory = &env->memories[module->memory_index];
+ if (init_expr_value.type != Type::I32) {
+ PrintError("type mismatch in data segment, expected i32 but got %s",
+ get_type_name(init_expr_value.type));
return Result::Error;
}
- uint32_t address = ctx->init_expr_value.value.i32;
+ uint32_t address = init_expr_value.value.i32;
uint64_t end_address =
static_cast<uint64_t>(address) + static_cast<uint64_t>(size);
if (end_address > memory->data.size()) {
- print_error(ctx,
- "data segment is out of bounds: [%u, %" PRIu64
- ") >= max value %" PRIzd,
- address, end_address, memory->data.size());
+ PrintError("data segment is out of bounds: [%u, %" PRIu64
+ ") >= max value %" PRIzd,
+ address, end_address, memory->data.size());
return Result::Error;
}
- return Result::Ok;
-}
-static Result on_data_segment_data(uint32_t index,
- const void* src_data,
- uint32_t size,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (size > 0) {
- assert(ctx->module->memory_index != WABT_INVALID_INDEX);
- InterpreterMemory* memory = &ctx->env->memories[ctx->module->memory_index];
- uint32_t address = ctx->init_expr_value.value.i32;
- memcpy(&memory->data[address], src_data, size);
- }
+ if (size > 0)
+ data_segment_infos.emplace_back(&memory->data[address], src_data, size);
+
return Result::Ok;
}
-static void push_label(Context* ctx, uint32_t offset, uint32_t fixup_offset) {
- ctx->label_stack.emplace_back(offset, fixup_offset);
+void BinaryReaderInterpreter::PushLabel(uint32_t offset,
+ uint32_t fixup_offset) {
+ label_stack.emplace_back(offset, fixup_offset);
}
-static void pop_label(Context* ctx) {
- ctx->label_stack.pop_back();
+void BinaryReaderInterpreter::PopLabel() {
+ label_stack.pop_back();
/* reduce the depth_fixups stack as well, but it may be smaller than
* label_stack so only do it conditionally. */
- if (ctx->depth_fixups.size() > ctx->label_stack.size()) {
- ctx->depth_fixups.erase(ctx->depth_fixups.begin() + ctx->label_stack.size(),
- ctx->depth_fixups.end());
+ if (depth_fixups.size() > label_stack.size()) {
+ depth_fixups.erase(depth_fixups.begin() + label_stack.size(),
+ depth_fixups.end());
}
}
-// TODO(binji): remove this when the rest of the code is using std::vector
-#define INTERPRETER_TYPE_VECTOR_TO_TYPE_VECTOR(out, in) \
- TypeVector out; \
- { \
- size_t byte_size = (in).size() * sizeof((in)[0]); \
- (out).data = static_cast<decltype((out).data)>(alloca(byte_size)); \
- (out).size = (in).size(); \
- if (byte_size) { \
- memcpy((out).data, (in).data(), byte_size); \
- } \
- }
-
-static Result begin_function_body(BinaryReaderContext* context,
- uint32_t index) {
- Context* ctx = static_cast<Context*>(context->user_data);
- DefinedInterpreterFunc* func =
- get_func_by_module_index(ctx, index)->as_defined();
- InterpreterFuncSignature* sig =
- get_signature_by_env_index(ctx, func->sig_index);
+Result BinaryReaderInterpreter::BeginFunctionBody(uint32_t index) {
+ DefinedInterpreterFunc* func = GetFuncByModuleIndex(index)->as_defined();
+ InterpreterFuncSignature* sig = GetSignatureByEnvIndex(func->sig_index);
- func->offset = get_istream_offset(ctx);
+ func->offset = GetIstreamOffset();
func->local_decl_count = 0;
func->local_count = 0;
- ctx->current_func = func;
- ctx->depth_fixups.clear();
- ctx->label_stack.clear();
+ current_func = func;
+ depth_fixups.clear();
+ label_stack.clear();
/* fixup function references */
- uint32_t defined_index = translate_module_func_index_to_defined(ctx, index);
- Uint32Vector& fixups = ctx->func_fixups[defined_index];
- for (uint32_t fixup: fixups)
- CHECK_RESULT(emit_i32_at(ctx, fixup, func->offset));
+ uint32_t defined_index = TranslateModuleFuncIndexToDefined(index);
+ Uint32Vector& fixups = func_fixups[defined_index];
+ for (uint32_t fixup : fixups)
+ CHECK_RESULT(EmitI32At(fixup, func->offset));
/* append param types */
- for (Type param_type: sig->param_types)
+ for (Type param_type : sig->param_types)
func->param_and_local_types.push_back(param_type);
- CHECK_RESULT(
- typechecker_begin_function(&ctx->typechecker, &sig->result_types));
+ CHECK_RESULT(typechecker_begin_function(&typechecker, &sig->result_types));
/* push implicit func label (equivalent to return) */
- push_label(ctx, WABT_INVALID_OFFSET, WABT_INVALID_OFFSET);
+ PushLabel(WABT_INVALID_OFFSET, WABT_INVALID_OFFSET);
return Result::Ok;
}
-static Result end_function_body(uint32_t index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- fixup_top_label(ctx);
+Result BinaryReaderInterpreter::EndFunctionBody(uint32_t index) {
+ FixupTopLabel();
uint32_t drop_count, keep_count;
- CHECK_RESULT(get_return_drop_keep_count(ctx, &drop_count, &keep_count));
- CHECK_RESULT(typechecker_end_function(&ctx->typechecker));
- CHECK_RESULT(emit_drop_keep(ctx, drop_count, keep_count));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Return));
- pop_label(ctx);
- ctx->current_func = nullptr;
+ CHECK_RESULT(GetReturnDropKeepCount(&drop_count, &keep_count));
+ CHECK_RESULT(typechecker_end_function(&typechecker));
+ CHECK_RESULT(EmitDropKeep(drop_count, keep_count));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Return));
+ PopLabel();
+ current_func = nullptr;
return Result::Ok;
}
-static Result on_local_decl_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->current_func->local_decl_count = count;
+Result BinaryReaderInterpreter::OnLocalDeclCount(uint32_t count) {
+ current_func->local_decl_count = count;
return Result::Ok;
}
-static Result on_local_decl(uint32_t decl_index,
- uint32_t count,
- Type type,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->current_func->local_count += count;
+Result BinaryReaderInterpreter::OnLocalDecl(uint32_t decl_index,
+ uint32_t count,
+ Type type) {
+ current_func->local_count += count;
for (uint32_t i = 0; i < count; ++i)
- ctx->current_func->param_and_local_types.push_back(type);
+ current_func->param_and_local_types.push_back(type);
- if (decl_index == ctx->current_func->local_decl_count - 1) {
+ if (decl_index == current_func->local_decl_count - 1) {
/* last local declaration, allocate space for all locals. */
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Alloca));
- CHECK_RESULT(emit_i32(ctx, ctx->current_func->local_count));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Alloca));
+ CHECK_RESULT(EmitI32(current_func->local_count));
}
return Result::Ok;
}
-static Result check_has_memory(Context* ctx, Opcode opcode) {
- if (ctx->module->memory_index == WABT_INVALID_INDEX) {
- print_error(ctx, "%s requires an imported or defined memory.",
- get_opcode_name(opcode));
+Result BinaryReaderInterpreter::CheckHasMemory(Opcode opcode) {
+ if (module->memory_index == WABT_INVALID_INDEX) {
+ PrintError("%s requires an imported or defined memory.",
+ get_opcode_name(opcode));
return Result::Error;
}
return Result::Ok;
}
-static Result check_align(Context* ctx,
- uint32_t alignment_log2,
- uint32_t natural_alignment) {
+Result BinaryReaderInterpreter::CheckAlign(uint32_t alignment_log2,
+ uint32_t natural_alignment) {
if (alignment_log2 >= 32 || (1U << alignment_log2) > natural_alignment) {
- print_error(ctx, "alignment must not be larger than natural alignment (%u)",
- natural_alignment);
+ PrintError("alignment must not be larger than natural alignment (%u)",
+ natural_alignment);
return Result::Error;
}
return Result::Ok;
}
-static Result on_unary_expr(Opcode opcode, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_unary(&ctx->typechecker, opcode));
- CHECK_RESULT(emit_opcode(ctx, opcode));
+Result BinaryReaderInterpreter::OnUnaryExpr(Opcode opcode) {
+ CHECK_RESULT(typechecker_on_unary(&typechecker, opcode));
+ CHECK_RESULT(EmitOpcode(opcode));
return Result::Ok;
}
-static Result on_binary_expr(Opcode opcode, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_binary(&ctx->typechecker, opcode));
- CHECK_RESULT(emit_opcode(ctx, opcode));
+Result BinaryReaderInterpreter::OnBinaryExpr(Opcode opcode) {
+ CHECK_RESULT(typechecker_on_binary(&typechecker, opcode));
+ CHECK_RESULT(EmitOpcode(opcode));
return Result::Ok;
}
-static Result on_block_expr(uint32_t num_types,
- Type* sig_types,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnBlockExpr(uint32_t num_types,
+ Type* sig_types) {
TypeVector sig(sig_types, sig_types + num_types);
- CHECK_RESULT(typechecker_on_block(&ctx->typechecker, &sig));
- push_label(ctx, WABT_INVALID_OFFSET, WABT_INVALID_OFFSET);
+ CHECK_RESULT(typechecker_on_block(&typechecker, &sig));
+ PushLabel(WABT_INVALID_OFFSET, WABT_INVALID_OFFSET);
return Result::Ok;
}
-static Result on_loop_expr(uint32_t num_types,
- Type* sig_types,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnLoopExpr(uint32_t num_types,
+ Type* sig_types) {
TypeVector sig(sig_types, sig_types + num_types);
- CHECK_RESULT(typechecker_on_loop(&ctx->typechecker, &sig));
- push_label(ctx, get_istream_offset(ctx), WABT_INVALID_OFFSET);
+ CHECK_RESULT(typechecker_on_loop(&typechecker, &sig));
+ PushLabel(GetIstreamOffset(), WABT_INVALID_OFFSET);
return Result::Ok;
}
-static Result on_if_expr(uint32_t num_types, Type* sig_types, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnIfExpr(uint32_t num_types, Type* sig_types) {
TypeVector sig(sig_types, sig_types + num_types);
- CHECK_RESULT(typechecker_on_if(&ctx->typechecker, &sig));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::BrUnless));
- uint32_t fixup_offset = get_istream_offset(ctx);
- CHECK_RESULT(emit_i32(ctx, WABT_INVALID_OFFSET));
- push_label(ctx, WABT_INVALID_OFFSET, fixup_offset);
+ CHECK_RESULT(typechecker_on_if(&typechecker, &sig));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::BrUnless));
+ uint32_t fixup_offset = GetIstreamOffset();
+ CHECK_RESULT(EmitI32(WABT_INVALID_OFFSET));
+ PushLabel(WABT_INVALID_OFFSET, fixup_offset);
return Result::Ok;
}
-static Result on_else_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_else(&ctx->typechecker));
- Label* label = top_label(ctx);
+Result BinaryReaderInterpreter::OnElseExpr() {
+ CHECK_RESULT(typechecker_on_else(&typechecker));
+ Label* label = TopLabel();
uint32_t fixup_cond_offset = label->fixup_offset;
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Br));
- label->fixup_offset = get_istream_offset(ctx);
- CHECK_RESULT(emit_i32(ctx, WABT_INVALID_OFFSET));
- CHECK_RESULT(emit_i32_at(ctx, fixup_cond_offset, get_istream_offset(ctx)));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Br));
+ label->fixup_offset = GetIstreamOffset();
+ CHECK_RESULT(EmitI32(WABT_INVALID_OFFSET));
+ CHECK_RESULT(EmitI32At(fixup_cond_offset, GetIstreamOffset()));
return Result::Ok;
}
-static Result on_end_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnEndExpr() {
TypeCheckerLabel* label;
- CHECK_RESULT(typechecker_get_label(&ctx->typechecker, 0, &label));
+ CHECK_RESULT(typechecker_get_label(&typechecker, 0, &label));
LabelType label_type = label->label_type;
- CHECK_RESULT(typechecker_on_end(&ctx->typechecker));
+ CHECK_RESULT(typechecker_on_end(&typechecker));
if (label_type == LabelType::If || label_type == LabelType::Else) {
- CHECK_RESULT(emit_i32_at(ctx, top_label(ctx)->fixup_offset,
- get_istream_offset(ctx)));
+ CHECK_RESULT(EmitI32At(TopLabel()->fixup_offset, GetIstreamOffset()));
}
- fixup_top_label(ctx);
- pop_label(ctx);
+ FixupTopLabel();
+ PopLabel();
return Result::Ok;
}
-static Result on_br_expr(uint32_t depth, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnBrExpr(uint32_t depth) {
uint32_t drop_count, keep_count;
- CHECK_RESULT(get_br_drop_keep_count(ctx, depth, &drop_count, &keep_count));
- CHECK_RESULT(typechecker_on_br(&ctx->typechecker, depth));
- CHECK_RESULT(emit_br(ctx, depth, drop_count, keep_count));
+ CHECK_RESULT(GetBrDropKeepCount(depth, &drop_count, &keep_count));
+ CHECK_RESULT(typechecker_on_br(&typechecker, depth));
+ CHECK_RESULT(EmitBr(depth, drop_count, keep_count));
return Result::Ok;
}
-static Result on_br_if_expr(uint32_t depth, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnBrIfExpr(uint32_t depth) {
uint32_t drop_count, keep_count;
- CHECK_RESULT(typechecker_on_br_if(&ctx->typechecker, depth));
- CHECK_RESULT(get_br_drop_keep_count(ctx, depth, &drop_count, &keep_count));
+ CHECK_RESULT(typechecker_on_br_if(&typechecker, depth));
+ CHECK_RESULT(GetBrDropKeepCount(depth, &drop_count, &keep_count));
/* flip the br_if so if <cond> is true it can drop values from the stack */
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::BrUnless));
- uint32_t fixup_br_offset = get_istream_offset(ctx);
- CHECK_RESULT(emit_i32(ctx, WABT_INVALID_OFFSET));
- CHECK_RESULT(emit_br(ctx, depth, drop_count, keep_count));
- CHECK_RESULT(emit_i32_at(ctx, fixup_br_offset, get_istream_offset(ctx)));
- return Result::Ok;
-}
-
-static Result on_br_table_expr(BinaryReaderContext* context,
- uint32_t num_targets,
- uint32_t* target_depths,
- uint32_t default_target_depth) {
- Context* ctx = static_cast<Context*>(context->user_data);
- CHECK_RESULT(typechecker_begin_br_table(&ctx->typechecker));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::BrTable));
- CHECK_RESULT(emit_i32(ctx, num_targets));
- uint32_t fixup_table_offset = get_istream_offset(ctx);
- CHECK_RESULT(emit_i32(ctx, WABT_INVALID_OFFSET));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::BrUnless));
+ uint32_t fixup_br_offset = GetIstreamOffset();
+ CHECK_RESULT(EmitI32(WABT_INVALID_OFFSET));
+ CHECK_RESULT(EmitBr(depth, drop_count, keep_count));
+ CHECK_RESULT(EmitI32At(fixup_br_offset, GetIstreamOffset()));
+ return Result::Ok;
+}
+
+Result BinaryReaderInterpreter::OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth) {
+ CHECK_RESULT(typechecker_begin_br_table(&typechecker));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::BrTable));
+ CHECK_RESULT(EmitI32(num_targets));
+ uint32_t fixup_table_offset = GetIstreamOffset();
+ CHECK_RESULT(EmitI32(WABT_INVALID_OFFSET));
/* not necessary for the interpreter, but it makes it easier to disassemble.
* This opcode specifies how many bytes of data follow. */
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Data));
- CHECK_RESULT(emit_i32(ctx, (num_targets + 1) * WABT_TABLE_ENTRY_SIZE));
- CHECK_RESULT(emit_i32_at(ctx, fixup_table_offset, get_istream_offset(ctx)));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Data));
+ CHECK_RESULT(EmitI32((num_targets + 1) * WABT_TABLE_ENTRY_SIZE));
+ CHECK_RESULT(EmitI32At(fixup_table_offset, GetIstreamOffset()));
for (uint32_t i = 0; i <= num_targets; ++i) {
uint32_t depth = i != num_targets ? target_depths[i] : default_target_depth;
- CHECK_RESULT(typechecker_on_br_table_target(&ctx->typechecker, depth));
- CHECK_RESULT(emit_br_table_offset(ctx, depth));
+ CHECK_RESULT(typechecker_on_br_table_target(&typechecker, depth));
+ CHECK_RESULT(EmitBrTableOffset(depth));
}
- CHECK_RESULT(typechecker_end_br_table(&ctx->typechecker));
+ CHECK_RESULT(typechecker_end_br_table(&typechecker));
return Result::Ok;
}
-static Result on_call_expr(uint32_t func_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- InterpreterFunc* func = get_func_by_module_index(ctx, func_index);
- InterpreterFuncSignature* sig =
- get_signature_by_env_index(ctx, func->sig_index);
- CHECK_RESULT(typechecker_on_call(&ctx->typechecker, &sig->param_types,
- &sig->result_types));
+Result BinaryReaderInterpreter::OnCallExpr(uint32_t func_index) {
+ InterpreterFunc* func = GetFuncByModuleIndex(func_index);
+ InterpreterFuncSignature* sig = GetSignatureByEnvIndex(func->sig_index);
+ CHECK_RESULT(
+ typechecker_on_call(&typechecker, &sig->param_types, &sig->result_types));
if (func->is_host) {
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::CallHost));
- CHECK_RESULT(emit_i32(ctx, translate_func_index_to_env(ctx, func_index)));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::CallHost));
+ CHECK_RESULT(EmitI32(TranslateFuncIndexToEnv(func_index)));
} else {
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Call));
- CHECK_RESULT(emit_func_offset(ctx, func->as_defined(), func_index));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Call));
+ CHECK_RESULT(EmitFuncOffset(func->as_defined(), func_index));
}
return Result::Ok;
}
-static Result on_call_indirect_expr(uint32_t sig_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->module->table_index == WABT_INVALID_INDEX) {
- print_error(ctx, "found call_indirect operator, but no table");
+Result BinaryReaderInterpreter::OnCallIndirectExpr(uint32_t sig_index) {
+ if (module->table_index == WABT_INVALID_INDEX) {
+ PrintError("found call_indirect operator, but no table");
return Result::Error;
}
- InterpreterFuncSignature* sig = get_signature_by_module_index(ctx, sig_index);
- CHECK_RESULT(typechecker_on_call_indirect(
- &ctx->typechecker, &sig->param_types, &sig->result_types));
+ InterpreterFuncSignature* sig = GetSignatureByModuleIndex(sig_index);
+ CHECK_RESULT(typechecker_on_call_indirect(&typechecker, &sig->param_types,
+ &sig->result_types));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::CallIndirect));
- CHECK_RESULT(emit_i32(ctx, ctx->module->table_index));
- CHECK_RESULT(emit_i32(ctx, translate_sig_index_to_env(ctx, sig_index)));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::CallIndirect));
+ CHECK_RESULT(EmitI32(module->table_index));
+ CHECK_RESULT(EmitI32(TranslateSigIndexToEnv(sig_index)));
return Result::Ok;
}
-static Result on_drop_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_drop(&ctx->typechecker));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Drop));
+Result BinaryReaderInterpreter::OnCompareExpr(Opcode opcode) {
+ return OnBinaryExpr(opcode);
+}
+
+Result BinaryReaderInterpreter::OnConvertExpr(Opcode opcode) {
+ return OnUnaryExpr(opcode);
+}
+
+Result BinaryReaderInterpreter::OnDropExpr() {
+ CHECK_RESULT(typechecker_on_drop(&typechecker));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Drop));
return Result::Ok;
}
-static Result on_i32_const_expr(uint32_t value, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_const(&ctx->typechecker, Type::I32));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::I32Const));
- CHECK_RESULT(emit_i32(ctx, value));
+Result BinaryReaderInterpreter::OnI32ConstExpr(uint32_t value) {
+ CHECK_RESULT(typechecker_on_const(&typechecker, Type::I32));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::I32Const));
+ CHECK_RESULT(EmitI32(value));
return Result::Ok;
}
-static Result on_i64_const_expr(uint64_t value, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_const(&ctx->typechecker, Type::I64));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::I64Const));
- CHECK_RESULT(emit_i64(ctx, value));
+Result BinaryReaderInterpreter::OnI64ConstExpr(uint64_t value) {
+ CHECK_RESULT(typechecker_on_const(&typechecker, Type::I64));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::I64Const));
+ CHECK_RESULT(EmitI64(value));
return Result::Ok;
}
-static Result on_f32_const_expr(uint32_t value_bits, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_const(&ctx->typechecker, Type::F32));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::F32Const));
- CHECK_RESULT(emit_i32(ctx, value_bits));
+Result BinaryReaderInterpreter::OnF32ConstExpr(uint32_t value_bits) {
+ CHECK_RESULT(typechecker_on_const(&typechecker, Type::F32));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::F32Const));
+ CHECK_RESULT(EmitI32(value_bits));
return Result::Ok;
}
-static Result on_f64_const_expr(uint64_t value_bits, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_const(&ctx->typechecker, Type::F64));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::F64Const));
- CHECK_RESULT(emit_i64(ctx, value_bits));
+Result BinaryReaderInterpreter::OnF64ConstExpr(uint64_t value_bits) {
+ CHECK_RESULT(typechecker_on_const(&typechecker, Type::F64));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::F64Const));
+ CHECK_RESULT(EmitI64(value_bits));
return Result::Ok;
}
-static Result on_get_global_expr(uint32_t global_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_GLOBAL(ctx, global_index);
- Type type = get_global_type_by_module_index(ctx, global_index);
- CHECK_RESULT(typechecker_on_get_global(&ctx->typechecker, type));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::GetGlobal));
- CHECK_RESULT(emit_i32(ctx, translate_global_index_to_env(ctx, global_index)));
+Result BinaryReaderInterpreter::OnGetGlobalExpr(uint32_t global_index) {
+ CHECK_RESULT(CheckGlobal(global_index));
+ Type type = GetGlobalTypeByModuleIndex(global_index);
+ CHECK_RESULT(typechecker_on_get_global(&typechecker, type));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::GetGlobal));
+ CHECK_RESULT(EmitI32(TranslateGlobalIndexToEnv(global_index)));
return Result::Ok;
}
-static Result on_set_global_expr(uint32_t global_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_GLOBAL(ctx, global_index);
- InterpreterGlobal* global = get_global_by_module_index(ctx, global_index);
+Result BinaryReaderInterpreter::OnSetGlobalExpr(uint32_t global_index) {
+ CHECK_RESULT(CheckGlobal(global_index));
+ InterpreterGlobal* global = GetGlobalByModuleIndex(global_index);
if (!global->mutable_) {
- print_error(ctx, "can't set_global on immutable global at index %u.",
- global_index);
+ PrintError("can't set_global on immutable global at index %u.",
+ global_index);
return Result::Error;
}
CHECK_RESULT(
- typechecker_on_set_global(&ctx->typechecker, global->typed_value.type));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::SetGlobal));
- CHECK_RESULT(emit_i32(ctx, translate_global_index_to_env(ctx, global_index)));
+ typechecker_on_set_global(&typechecker, global->typed_value.type));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::SetGlobal));
+ CHECK_RESULT(EmitI32(TranslateGlobalIndexToEnv(global_index)));
return Result::Ok;
}
-static uint32_t translate_local_index(Context* ctx, uint32_t local_index) {
- return ctx->typechecker.type_stack.size() +
- ctx->current_func->param_and_local_types.size() - local_index;
+uint32_t BinaryReaderInterpreter::TranslateLocalIndex(uint32_t local_index) {
+ return typechecker.type_stack.size() +
+ current_func->param_and_local_types.size() - local_index;
}
-static Result on_get_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_LOCAL(ctx, local_index);
- Type type = get_local_type_by_index(ctx->current_func, local_index);
+Result BinaryReaderInterpreter::OnGetLocalExpr(uint32_t local_index) {
+ CHECK_RESULT(CheckLocal(local_index));
+ Type type = GetLocalTypeByIndex(current_func, local_index);
/* Get the translated index before calling typechecker_on_get_local
* because it will update the type stack size. We need the index to be
* relative to the old stack size. */
- uint32_t translated_local_index = translate_local_index(ctx, local_index);
- CHECK_RESULT(typechecker_on_get_local(&ctx->typechecker, type));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::GetLocal));
- CHECK_RESULT(emit_i32(ctx, translated_local_index));
+ uint32_t translated_local_index = TranslateLocalIndex(local_index);
+ CHECK_RESULT(typechecker_on_get_local(&typechecker, type));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::GetLocal));
+ CHECK_RESULT(EmitI32(translated_local_index));
return Result::Ok;
}
-static Result on_set_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_LOCAL(ctx, local_index);
- Type type = get_local_type_by_index(ctx->current_func, local_index);
- CHECK_RESULT(typechecker_on_set_local(&ctx->typechecker, type));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::SetLocal));
- CHECK_RESULT(emit_i32(ctx, translate_local_index(ctx, local_index)));
+Result BinaryReaderInterpreter::OnSetLocalExpr(uint32_t local_index) {
+ CHECK_RESULT(CheckLocal(local_index));
+ Type type = GetLocalTypeByIndex(current_func, local_index);
+ CHECK_RESULT(typechecker_on_set_local(&typechecker, type));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::SetLocal));
+ CHECK_RESULT(EmitI32(TranslateLocalIndex(local_index)));
return Result::Ok;
}
-static Result on_tee_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_LOCAL(ctx, local_index);
- Type type = get_local_type_by_index(ctx->current_func, local_index);
- CHECK_RESULT(typechecker_on_tee_local(&ctx->typechecker, type));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::TeeLocal));
- CHECK_RESULT(emit_i32(ctx, translate_local_index(ctx, local_index)));
+Result BinaryReaderInterpreter::OnTeeLocalExpr(uint32_t local_index) {
+ CHECK_RESULT(CheckLocal(local_index));
+ Type type = GetLocalTypeByIndex(current_func, local_index);
+ CHECK_RESULT(typechecker_on_tee_local(&typechecker, type));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::TeeLocal));
+ CHECK_RESULT(EmitI32(TranslateLocalIndex(local_index)));
return Result::Ok;
}
-static Result on_grow_memory_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(check_has_memory(ctx, Opcode::GrowMemory));
- CHECK_RESULT(typechecker_on_grow_memory(&ctx->typechecker));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::GrowMemory));
- CHECK_RESULT(emit_i32(ctx, ctx->module->memory_index));
+Result BinaryReaderInterpreter::OnGrowMemoryExpr() {
+ CHECK_RESULT(CheckHasMemory(Opcode::GrowMemory));
+ CHECK_RESULT(typechecker_on_grow_memory(&typechecker));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::GrowMemory));
+ CHECK_RESULT(EmitI32(module->memory_index));
return Result::Ok;
}
-static Result on_load_expr(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(check_has_memory(ctx, opcode));
- CHECK_RESULT(
- check_align(ctx, alignment_log2, get_opcode_memory_size(opcode)));
- CHECK_RESULT(typechecker_on_load(&ctx->typechecker, opcode));
- CHECK_RESULT(emit_opcode(ctx, opcode));
- CHECK_RESULT(emit_i32(ctx, ctx->module->memory_index));
- CHECK_RESULT(emit_i32(ctx, offset));
+Result BinaryReaderInterpreter::OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
+ CHECK_RESULT(CheckHasMemory(opcode));
+ CHECK_RESULT(CheckAlign(alignment_log2, get_opcode_memory_size(opcode)));
+ CHECK_RESULT(typechecker_on_load(&typechecker, opcode));
+ CHECK_RESULT(EmitOpcode(opcode));
+ CHECK_RESULT(EmitI32(module->memory_index));
+ CHECK_RESULT(EmitI32(offset));
return Result::Ok;
}
-static Result on_store_expr(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(check_has_memory(ctx, opcode));
- CHECK_RESULT(
- check_align(ctx, alignment_log2, get_opcode_memory_size(opcode)));
- CHECK_RESULT(typechecker_on_store(&ctx->typechecker, opcode));
- CHECK_RESULT(emit_opcode(ctx, opcode));
- CHECK_RESULT(emit_i32(ctx, ctx->module->memory_index));
- CHECK_RESULT(emit_i32(ctx, offset));
+Result BinaryReaderInterpreter::OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
+ CHECK_RESULT(CheckHasMemory(opcode));
+ CHECK_RESULT(CheckAlign(alignment_log2, get_opcode_memory_size(opcode)));
+ CHECK_RESULT(typechecker_on_store(&typechecker, opcode));
+ CHECK_RESULT(EmitOpcode(opcode));
+ CHECK_RESULT(EmitI32(module->memory_index));
+ CHECK_RESULT(EmitI32(offset));
return Result::Ok;
}
-static Result on_current_memory_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(check_has_memory(ctx, Opcode::CurrentMemory));
- CHECK_RESULT(typechecker_on_current_memory(&ctx->typechecker));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::CurrentMemory));
- CHECK_RESULT(emit_i32(ctx, ctx->module->memory_index));
+Result BinaryReaderInterpreter::OnCurrentMemoryExpr() {
+ CHECK_RESULT(CheckHasMemory(Opcode::CurrentMemory));
+ CHECK_RESULT(typechecker_on_current_memory(&typechecker));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::CurrentMemory));
+ CHECK_RESULT(EmitI32(module->memory_index));
return Result::Ok;
}
-static Result on_nop_expr(void* user_data) {
+Result BinaryReaderInterpreter::OnNopExpr() {
return Result::Ok;
}
-static Result on_return_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderInterpreter::OnReturnExpr() {
uint32_t drop_count, keep_count;
- CHECK_RESULT(get_return_drop_keep_count(ctx, &drop_count, &keep_count));
- CHECK_RESULT(typechecker_on_return(&ctx->typechecker));
- CHECK_RESULT(emit_drop_keep(ctx, drop_count, keep_count));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Return));
+ CHECK_RESULT(GetReturnDropKeepCount(&drop_count, &keep_count));
+ CHECK_RESULT(typechecker_on_return(&typechecker));
+ CHECK_RESULT(EmitDropKeep(drop_count, keep_count));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Return));
+ return Result::Ok;
+}
+
+Result BinaryReaderInterpreter::OnSelectExpr() {
+ CHECK_RESULT(typechecker_on_select(&typechecker));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Select));
return Result::Ok;
}
-static Result on_select_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_select(&ctx->typechecker));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Select));
+Result BinaryReaderInterpreter::OnUnreachableExpr() {
+ CHECK_RESULT(typechecker_on_unreachable(&typechecker));
+ CHECK_RESULT(EmitOpcode(InterpreterOpcode::Unreachable));
return Result::Ok;
}
-static Result on_unreachable_expr(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- CHECK_RESULT(typechecker_on_unreachable(&ctx->typechecker));
- CHECK_RESULT(emit_opcode(ctx, InterpreterOpcode::Unreachable));
+Result BinaryReaderInterpreter::EndModule() {
+ for (ElemSegmentInfo& info : elem_segment_infos) {
+ *info.dst = info.func_index;
+ }
+ for (DataSegmentInfo& info : data_segment_infos) {
+ memcpy(info.dst_data, info.src_data, info.size);
+ }
return Result::Ok;
}
+} // namespace
+
Result read_binary_interpreter(InterpreterEnvironment* env,
const void* data,
size_t size,
const ReadBinaryOptions* options,
BinaryErrorHandler* error_handler,
DefinedInterpreterModule** out_module) {
- Context ctx;
- BinaryReader reader;
-
- InterpreterEnvironmentMark mark = mark_interpreter_environment(env);
-
+ size_t istream_offset = env->istream.size;
DefinedInterpreterModule* module =
- new DefinedInterpreterModule(env->istream.size);
- env->modules.emplace_back(module);
+ new DefinedInterpreterModule(istream_offset);
- WABT_ZERO_MEMORY(reader);
+ BinaryReaderInterpreter reader(env, module, istream_offset, error_handler);
+ if (WABT_FAILED(reader.Init())) {
+ delete module;
+ return Result::Error;
+ }
- ctx.reader = &reader;
- ctx.error_handler = error_handler;
- ctx.env = env;
- ctx.module = module;
- ctx.istream_offset = env->istream.size;
- CHECK_RESULT(init_mem_writer_existing(&ctx.istream_writer, &env->istream));
+ InterpreterEnvironmentMark mark = mark_interpreter_environment(env);
+ env->modules.emplace_back(module);
- TypeCheckerErrorHandler tc_error_handler;
- tc_error_handler.on_error = on_typechecker_error;
- tc_error_handler.user_data = &ctx;
- ctx.typechecker.error_handler = &tc_error_handler;
-
- WABT_ZERO_MEMORY(reader);
- reader.user_data = &ctx;
- reader.on_error = on_error;
- reader.on_signature_count = on_signature_count;
- reader.on_signature = on_signature;
- reader.on_import_count = on_import_count;
- reader.on_import = on_import;
- reader.on_import_func = on_import_func;
- reader.on_import_table = on_import_table;
- reader.on_import_memory = on_import_memory;
- reader.on_import_global = on_import_global;
- reader.on_function_signatures_count = on_function_signatures_count;
- reader.on_function_signature = on_function_signature;
- reader.on_table = on_table;
- reader.on_memory = on_memory;
- reader.on_global_count = on_global_count;
- reader.begin_global = begin_global;
- reader.end_global_init_expr = end_global_init_expr;
- reader.on_export = on_export;
- reader.on_start_function = on_start_function;
- reader.begin_function_body = begin_function_body;
- reader.on_local_decl_count = on_local_decl_count;
- reader.on_local_decl = on_local_decl;
- reader.on_binary_expr = on_binary_expr;
- reader.on_block_expr = on_block_expr;
- reader.on_br_expr = on_br_expr;
- reader.on_br_if_expr = on_br_if_expr;
- reader.on_br_table_expr = on_br_table_expr;
- reader.on_call_expr = on_call_expr;
- reader.on_call_indirect_expr = on_call_indirect_expr;
- reader.on_compare_expr = on_binary_expr;
- reader.on_convert_expr = on_unary_expr;
- reader.on_current_memory_expr = on_current_memory_expr;
- reader.on_drop_expr = on_drop_expr;
- reader.on_else_expr = on_else_expr;
- reader.on_end_expr = on_end_expr;
- reader.on_f32_const_expr = on_f32_const_expr;
- reader.on_f64_const_expr = on_f64_const_expr;
- reader.on_get_global_expr = on_get_global_expr;
- reader.on_get_local_expr = on_get_local_expr;
- reader.on_grow_memory_expr = on_grow_memory_expr;
- reader.on_i32_const_expr = on_i32_const_expr;
- reader.on_i64_const_expr = on_i64_const_expr;
- reader.on_if_expr = on_if_expr;
- reader.on_load_expr = on_load_expr;
- reader.on_loop_expr = on_loop_expr;
- reader.on_nop_expr = on_nop_expr;
- reader.on_return_expr = on_return_expr;
- reader.on_select_expr = on_select_expr;
- reader.on_set_global_expr = on_set_global_expr;
- reader.on_set_local_expr = on_set_local_expr;
- reader.on_store_expr = on_store_expr;
- reader.on_tee_local_expr = on_tee_local_expr;
- reader.on_unary_expr = on_unary_expr;
- reader.on_unreachable_expr = on_unreachable_expr;
- reader.end_function_body = end_function_body;
- reader.end_elem_segment_init_expr = end_elem_segment_init_expr;
- reader.on_elem_segment_function_index = on_elem_segment_function_index_check;
- reader.on_data_segment_data = on_data_segment_data_check;
- reader.on_init_expr_f32_const_expr = on_init_expr_f32_const_expr;
- reader.on_init_expr_f64_const_expr = on_init_expr_f64_const_expr;
- reader.on_init_expr_get_global_expr = on_init_expr_get_global_expr;
- reader.on_init_expr_i32_const_expr = on_init_expr_i32_const_expr;
- reader.on_init_expr_i64_const_expr = on_init_expr_i64_const_expr;
-
- const uint32_t num_function_passes = 1;
- Result result =
- read_binary(data, size, &reader, num_function_passes, options);
- steal_mem_writer_output_buffer(&ctx.istream_writer, &env->istream);
+ Result result = read_binary(data, size, &reader, options);
+ reader.StealOutputBuffer(&env->istream);
if (WABT_SUCCEEDED(result)) {
- /* Another pass on the read binary to assign data and elem segments. */
- WABT_ZERO_MEMORY(reader);
- reader.user_data = &ctx;
- reader.on_error = on_error;
- reader.end_elem_segment_init_expr = end_elem_segment_init_expr;
- reader.on_elem_segment_function_index = on_elem_segment_function_index;
- reader.on_data_segment_data = on_data_segment_data;
- reader.on_init_expr_f32_const_expr = on_init_expr_f32_const_expr;
- reader.on_init_expr_f64_const_expr = on_init_expr_f64_const_expr;
- reader.on_init_expr_get_global_expr = on_init_expr_get_global_expr;
- reader.on_init_expr_i32_const_expr = on_init_expr_i32_const_expr;
- reader.on_init_expr_i64_const_expr = on_init_expr_i64_const_expr;
-
- result = read_binary(data, size, &reader, num_function_passes, options);
- assert(WABT_SUCCEEDED(result));
-
- env->istream.size = ctx.istream_offset;
- ctx.module->istream_end = env->istream.size;
+ env->istream.size = reader.get_istream_offset();
+ module->istream_end = env->istream.size;
*out_module = module;
} else {
reset_interpreter_environment_to_mark(env, mark);
diff --git a/src/binary-reader-linker.cc b/src/binary-reader-linker.cc
index 026c2f9d..40d3c420 100644
--- a/src/binary-reader-linker.cc
+++ b/src/binary-reader-linker.cc
@@ -18,7 +18,7 @@
#include <vector>
-#include "binary-reader.h"
+#include "binary-reader-nop.h"
#include "wasm-link.h"
#define RELOC_SIZE 5
@@ -28,21 +28,74 @@ namespace link {
namespace {
-struct Context {
+class BinaryReaderLinker : public BinaryReaderNop {
+ public:
+ explicit BinaryReaderLinker(LinkerInputBinary* binary);
+
+ virtual Result BeginSection(BinarySection section_type, uint32_t size);
+
+ virtual Result BeginCustomSection(uint32_t size, StringSlice section_name);
+
+ virtual Result OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name);
+ virtual Result OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index);
+ virtual Result OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_);
+
+ virtual Result OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits);
+
+ virtual Result OnMemory(uint32_t index, const Limits* limits);
+
+ virtual Result OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name);
+
+ virtual Result OnElemSegmentFunctionIndexCount(uint32_t index,
+ uint32_t count);
+
+ virtual Result BeginDataSegment(uint32_t index, uint32_t memory_index);
+ virtual Result OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size);
+
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name);
+
+ virtual Result OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name);
+ virtual Result OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend);
+
+ virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value);
+
+ private:
LinkerInputBinary* binary;
- Section* reloc_section;
- Section* current_section;
+ Section* reloc_section = nullptr;
+ Section* current_section = nullptr;
};
-} // namespace
+BinaryReaderLinker::BinaryReaderLinker(LinkerInputBinary* binary)
+ : binary(binary) {}
-static Result on_reloc_count(uint32_t count,
- BinarySection section_code,
- StringSlice section_name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- LinkerInputBinary* binary = ctx->binary;
+Result BinaryReaderLinker::OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name) {
if (section_code == BinarySection::Custom) {
WABT_FATAL("relocation for custom sections not yet supported\n");
}
@@ -50,7 +103,7 @@ static Result on_reloc_count(uint32_t count,
for (const std::unique_ptr<Section>& section : binary->sections) {
if (section->section_code != section_code)
continue;
- ctx->reloc_section = section.get();
+ reloc_section = section.get();
return Result::Ok;
}
@@ -58,26 +111,22 @@ static Result on_reloc_count(uint32_t count,
return Result::Error;
}
-static Result on_reloc(RelocType type,
- uint32_t offset,
- uint32_t index,
- int32_t addend,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
-
- if (offset + RELOC_SIZE > ctx->reloc_section->size) {
+Result BinaryReaderLinker::OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend) {
+ if (offset + RELOC_SIZE > reloc_section->size) {
WABT_FATAL("invalid relocation offset: %#x\n", offset);
}
- ctx->reloc_section->relocations.emplace_back(type, offset, index, addend);
+ reloc_section->relocations.emplace_back(type, offset, index, addend);
return Result::Ok;
}
-static Result on_import(uint32_t index,
- StringSlice module_name,
- StringSlice field_name,
- void* user_data) {
+Result BinaryReaderLinker::OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name) {
if (!string_slice_eq_cstr(&module_name, WABT_LINK_MODULE_NAME)) {
WABT_FATAL("unsupported import module: " PRIstringslice,
WABT_PRINTF_STRING_SLICE_ARG(module_name));
@@ -85,50 +134,43 @@ static Result on_import(uint32_t index,
return Result::Ok;
}
-static Result on_import_func(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t global_index,
- uint32_t sig_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->binary->function_imports.emplace_back();
- FunctionImport* import = &ctx->binary->function_imports.back();
+Result BinaryReaderLinker::OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ uint32_t sig_index) {
+ binary->function_imports.emplace_back();
+ FunctionImport* import = &binary->function_imports.back();
import->name = field_name;
import->sig_index = sig_index;
import->active = true;
- ctx->binary->active_function_imports++;
+ binary->active_function_imports++;
return Result::Ok;
}
-static Result on_import_global(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t global_index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->binary->global_imports.emplace_back();
- GlobalImport* import = &ctx->binary->global_imports.back();
+Result BinaryReaderLinker::OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_) {
+ binary->global_imports.emplace_back();
+ GlobalImport* import = &binary->global_imports.back();
import->name = field_name;
import->type = type;
import->mutable_ = mutable_;
- ctx->binary->active_global_imports++;
+ binary->active_global_imports++;
return Result::Ok;
}
-static Result begin_section(BinaryReaderContext* ctx,
- BinarySection section_code,
- uint32_t size) {
- Context* context = static_cast<Context*>(ctx->user_data);
- LinkerInputBinary* binary = context->binary;
+Result BinaryReaderLinker::BeginSection(BinarySection section_code,
+ uint32_t size) {
Section* sec = new Section();
binary->sections.emplace_back(sec);
- context->current_section = sec;
+ current_section = sec;
sec->section_code = section_code;
sec->size = size;
- sec->offset = ctx->offset;
+ sec->offset = state->offset;
sec->binary = binary;
if (sec->section_code != BinarySection::Custom &&
@@ -143,16 +185,13 @@ static Result begin_section(BinaryReaderContext* ctx,
return Result::Ok;
}
-static Result begin_custom_section(BinaryReaderContext* ctx,
- uint32_t size,
- StringSlice section_name) {
- Context* context = static_cast<Context*>(ctx->user_data);
- LinkerInputBinary* binary = context->binary;
- Section* sec = context->current_section;
- sec->data_custom.name = section_name;
+Result BinaryReaderLinker::BeginCustomSection(uint32_t size,
+ StringSlice section_name) {
+ Section* sec = current_section;
+ sec->data.custom.name = section_name;
/* Modify section size and offset to not include the name itself. */
- size_t delta = ctx->offset - sec->offset;
+ size_t delta = state->offset - sec->offset;
sec->offset = sec->offset + delta;
sec->size = sec->size - delta;
sec->payload_offset = sec->offset;
@@ -164,7 +203,8 @@ static Result begin_custom_section(BinaryReaderContext* ctx,
size_t bytes_read = read_u32_leb128(
&binary->data[sec->offset], &binary->data[binary->size], &name_type);
- if (static_cast<NameSectionSubsection>(name_type) != NameSectionSubsection::Function) {
+ if (static_cast<NameSectionSubsection>(name_type) !=
+ NameSectionSubsection::Function) {
WABT_FATAL("no function name section");
}
@@ -172,14 +212,14 @@ static Result begin_custom_section(BinaryReaderContext* ctx,
sec->payload_size -= bytes_read;
uint32_t subsection_size;
- bytes_read = read_u32_leb128(
- &binary->data[sec->offset], &binary->data[binary->size], &subsection_size);
+ bytes_read = read_u32_leb128(&binary->data[sec->offset],
+ &binary->data[binary->size], &subsection_size);
sec->payload_offset += bytes_read;
sec->payload_size -= bytes_read;
- bytes_read = read_u32_leb128(
- &binary->data[sec->payload_offset], &binary->data[binary->size], &sec->count);
+ bytes_read = read_u32_leb128(&binary->data[sec->payload_offset],
+ &binary->data[binary->size], &sec->count);
sec->payload_offset += bytes_read;
sec->payload_size -= bytes_read;
@@ -201,144 +241,97 @@ static Result begin_custom_section(BinaryReaderContext* ctx,
return Result::Ok;
}
-static Result on_table(uint32_t index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
+Result BinaryReaderLinker::OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits) {
if (elem_limits->has_max && (elem_limits->max != elem_limits->initial))
WABT_FATAL("Tables with max != initial not supported by wabt-link\n");
- Context* ctx = static_cast<Context*>(user_data);
- ctx->binary->table_elem_count = elem_limits->initial;
+ binary->table_elem_count = elem_limits->initial;
return Result::Ok;
}
-static Result on_elem_segment_function_index_count(BinaryReaderContext* ctx,
- uint32_t index,
- uint32_t count) {
- Context* context = static_cast<Context*>(ctx->user_data);
- Section* sec = context->current_section;
+Result BinaryReaderLinker::OnElemSegmentFunctionIndexCount(uint32_t index,
+ uint32_t count) {
+ Section* sec = current_section;
/* Modify the payload to include only the actual function indexes */
- size_t delta = ctx->offset - sec->payload_offset;
+ size_t delta = state->offset - sec->payload_offset;
sec->payload_offset += delta;
sec->payload_size -= delta;
return Result::Ok;
}
-static Result on_memory(uint32_t index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- Section* sec = ctx->current_section;
- sec->memory_limits = *page_limits;
- ctx->binary->memory_page_count = page_limits->initial;
+Result BinaryReaderLinker::OnMemory(uint32_t index, const Limits* page_limits) {
+ Section* sec = current_section;
+ sec->data.memory_limits = *page_limits;
+ binary->memory_page_count = page_limits->initial;
return Result::Ok;
}
-static Result begin_data_segment(uint32_t index,
- uint32_t memory_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- Section* sec = ctx->current_section;
- if (!sec->data_segments) {
- sec->data_segments = new std::vector<DataSegment>();
+Result BinaryReaderLinker::BeginDataSegment(uint32_t index,
+ uint32_t memory_index) {
+ Section* sec = current_section;
+ if (!sec->data.data_segments) {
+ sec->data.data_segments = new std::vector<DataSegment>();
}
- sec->data_segments->emplace_back();
- DataSegment& segment = sec->data_segments->back();
+ sec->data.data_segments->emplace_back();
+ DataSegment& segment = sec->data.data_segments->back();
segment.memory_index = memory_index;
return Result::Ok;
}
-static Result on_init_expr_i32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- Section* sec = ctx->current_section;
+Result BinaryReaderLinker::OnInitExprI32ConstExpr(uint32_t index,
+ uint32_t value) {
+ Section* sec = current_section;
if (sec->section_code != BinarySection::Data)
return Result::Ok;
- DataSegment& segment = sec->data_segments->back();
+ DataSegment& segment = sec->data.data_segments->back();
segment.offset = value;
return Result::Ok;
}
-static Result on_data_segment_data(uint32_t index,
- const void* src_data,
- uint32_t size,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- Section* sec = ctx->current_section;
- DataSegment& segment = sec->data_segments->back();
+Result BinaryReaderLinker::OnDataSegmentData(uint32_t index,
+ const void* src_data,
+ uint32_t size) {
+ Section* sec = current_section;
+ DataSegment& segment = sec->data.data_segments->back();
segment.data = static_cast<const uint8_t*>(src_data);
segment.size = size;
return Result::Ok;
}
-static Result on_export(uint32_t index,
- ExternalKind kind,
- uint32_t item_index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->binary->exports.emplace_back();
- Export* export_ = &ctx->binary->exports.back();
+Result BinaryReaderLinker::OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) {
+ binary->exports.emplace_back();
+ Export* export_ = &binary->exports.back();
export_->name = name;
export_->kind = kind;
export_->index = item_index;
return Result::Ok;
}
-static Result on_function_name(uint32_t index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- while (ctx->binary->debug_names.size() < index) {
- ctx->binary->debug_names.emplace_back();
+Result BinaryReaderLinker::OnFunctionName(uint32_t index, StringSlice name) {
+ while (binary->debug_names.size() < index) {
+ binary->debug_names.emplace_back();
}
- if (ctx->binary->debug_names.size() == index) {
- ctx->binary->debug_names.push_back(string_slice_to_string(name));
+ if (binary->debug_names.size() == index) {
+ binary->debug_names.push_back(string_slice_to_string(name));
}
return Result::Ok;
}
-Result read_binary_linker(LinkerInputBinary* input_info,
- LinkOptions* options) {
- Context context;
- WABT_ZERO_MEMORY(context);
- context.binary = input_info;
-
- BinaryReader reader;
- WABT_ZERO_MEMORY(reader);
- reader.user_data = &context;
- reader.begin_section = begin_section;
- reader.begin_custom_section = begin_custom_section;
-
- reader.on_reloc_count = on_reloc_count;
- reader.on_reloc = on_reloc;
-
- reader.on_import = on_import;
- reader.on_import_func = on_import_func;
- reader.on_import_global = on_import_global;
-
- reader.on_export = on_export;
-
- reader.on_table = on_table;
-
- reader.on_memory = on_memory;
-
- reader.begin_data_segment = begin_data_segment;
- reader.on_init_expr_i32_const_expr = on_init_expr_i32_const_expr;
- reader.on_data_segment_data = on_data_segment_data;
-
- reader.on_elem_segment_function_index_count =
- on_elem_segment_function_index_count;
+} // namespace
- reader.on_function_name = on_function_name;
+Result read_binary_linker(LinkerInputBinary* input_info, LinkOptions* options) {
+ BinaryReaderLinker reader(input_info);
ReadBinaryOptions read_options = WABT_READ_BINARY_OPTIONS_DEFAULT;
read_options.read_debug_names = true;
read_options.log_stream = options->log_stream;
- return read_binary(input_info->data, input_info->size, &reader, 1,
+ return read_binary(input_info->data, input_info->size, &reader,
&read_options);
}
diff --git a/src/binary-reader-logging.cc b/src/binary-reader-logging.cc
new file mode 100644
index 00000000..6657a3e5
--- /dev/null
+++ b/src/binary-reader-logging.cc
@@ -0,0 +1,592 @@
+/*
+ * Copyright 2017 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "binary-reader-logging.h"
+
+#include <inttypes.h>
+
+#include "stream.h"
+
+namespace wabt {
+
+#define INDENT_SIZE 2
+
+#define LOGF_NOINDENT(...) writef(stream, __VA_ARGS__)
+
+#define LOGF(...) \
+ do { \
+ WriteIndent(); \
+ LOGF_NOINDENT(__VA_ARGS__); \
+ } while (0)
+
+namespace {
+
+void sprint_limits(char* dst, size_t size, const Limits* limits) {
+ int result;
+ if (limits->has_max) {
+ result = wabt_snprintf(dst, size, "initial: %" PRIu64 ", max: %" PRIu64,
+ limits->initial, limits->max);
+ } else {
+ result = wabt_snprintf(dst, size, "initial: %" PRIu64, limits->initial);
+ }
+ WABT_USE(result);
+ assert(static_cast<size_t>(result) < size);
+}
+
+} // namespace
+
+BinaryReaderLogging::BinaryReaderLogging(Stream* stream, BinaryReader* forward)
+ : stream(stream), reader(forward), indent(0) {}
+
+void BinaryReaderLogging::Indent() {
+ indent += INDENT_SIZE;
+}
+
+void BinaryReaderLogging::Dedent() {
+ indent -= INDENT_SIZE;
+ assert(indent >= 0);
+}
+
+void BinaryReaderLogging::WriteIndent() {
+ static char s_indent[] =
+ " "
+ " ";
+ static size_t s_indent_len = sizeof(s_indent) - 1;
+ size_t i = indent;
+ while (i > s_indent_len) {
+ write_data(stream, s_indent, s_indent_len, nullptr);
+ i -= s_indent_len;
+ }
+ if (i > 0) {
+ write_data(stream, s_indent, indent, nullptr);
+ }
+}
+
+void BinaryReaderLogging::LogTypes(uint32_t type_count, Type* types) {
+ LOGF_NOINDENT("[");
+ for (uint32_t i = 0; i < type_count; ++i) {
+ LOGF_NOINDENT("%s", get_type_name(types[i]));
+ if (i != type_count - 1)
+ LOGF_NOINDENT(", ");
+ }
+ LOGF_NOINDENT("]");
+}
+
+bool BinaryReaderLogging::OnError(const char* message) {
+ return reader->OnError(message);
+}
+
+void BinaryReaderLogging::OnSetState(const State* s) {
+ BinaryReader::OnSetState(s);
+ reader->OnSetState(s);
+}
+
+Result BinaryReaderLogging::BeginModule(uint32_t version) {
+ LOGF("BeginModule(version: %u)\n", version);
+ Indent();
+ return reader->BeginModule(version);
+}
+
+Result BinaryReaderLogging::BeginSection(BinarySection section_type,
+ uint32_t size) {
+ return reader->BeginSection(section_type, size);
+}
+
+Result BinaryReaderLogging::BeginCustomSection(uint32_t size,
+ StringSlice section_name) {
+ LOGF("BeginCustomSection('" PRIstringslice "', size: %d)\n",
+ WABT_PRINTF_STRING_SLICE_ARG(section_name), size);
+ Indent();
+ return reader->BeginCustomSection(size, section_name);
+}
+
+Result BinaryReaderLogging::OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types) {
+ LOGF("OnType(index: %u, params: ", index);
+ LogTypes(param_count, param_types);
+ LOGF_NOINDENT(", results: ");
+ LogTypes(result_count, result_types);
+ LOGF_NOINDENT(")\n");
+ return reader->OnType(index, param_count, param_types, result_count,
+ result_types);
+}
+
+Result BinaryReaderLogging::OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name) {
+ LOGF("OnImport(index: %u, module: \"" PRIstringslice
+ "\", field: \"" PRIstringslice "\")\n",
+ index, WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name));
+ return reader->OnImport(index, module_name, field_name);
+}
+
+Result BinaryReaderLogging::OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index) {
+ LOGF("OnImportFunc(import_index: %u, func_index: %u, sig_index: %u)\n",
+ import_index, func_index, sig_index);
+ return reader->OnImportFunc(import_index, module_name, field_name, func_index,
+ sig_index);
+}
+
+Result BinaryReaderLogging::OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ char buf[100];
+ sprint_limits(buf, sizeof(buf), elem_limits);
+ LOGF("OnImportTable(import_index: %u, table_index: %u, elem_type: %s, %s)\n",
+ import_index, table_index, get_type_name(elem_type), buf);
+ return reader->OnImportTable(import_index, module_name, field_name,
+ table_index, elem_type, elem_limits);
+}
+
+Result BinaryReaderLogging::OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits) {
+ char buf[100];
+ sprint_limits(buf, sizeof(buf), page_limits);
+ LOGF("OnImportMemory(import_index: %u, memory_index: %u, %s)\n", import_index,
+ memory_index, buf);
+ return reader->OnImportMemory(import_index, module_name, field_name,
+ memory_index, page_limits);
+}
+
+Result BinaryReaderLogging::OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_) {
+ LOGF(
+ "OnImportGlobal(import_index: %u, global_index: %u, type: %s, mutable: "
+ "%s)\n",
+ import_index, global_index, get_type_name(type),
+ mutable_ ? "true" : "false");
+ return reader->OnImportGlobal(import_index, module_name, field_name,
+ global_index, type, mutable_);
+}
+
+Result BinaryReaderLogging::OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ char buf[100];
+ sprint_limits(buf, sizeof(buf), elem_limits);
+ LOGF("OnTable(index: %u, elem_type: %s, %s)\n", index,
+ get_type_name(elem_type), buf);
+ return reader->OnTable(index, elem_type, elem_limits);
+}
+
+Result BinaryReaderLogging::OnMemory(uint32_t index,
+ const Limits* page_limits) {
+ char buf[100];
+ sprint_limits(buf, sizeof(buf), page_limits);
+ LOGF("OnMemory(index: %u, %s)\n", index, buf);
+ return reader->OnMemory(index, page_limits);
+}
+
+Result BinaryReaderLogging::BeginGlobal(uint32_t index,
+ Type type,
+ bool mutable_) {
+ LOGF("BeginGlobal(index: %u, type: %s, mutable: %s)\n", index,
+ get_type_name(type), mutable_ ? "true" : "false");
+ return reader->BeginGlobal(index, type, mutable_);
+}
+
+Result BinaryReaderLogging::OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) {
+ LOGF("OnExport(index: %u, kind: %s, item_index: %u, name: \"" PRIstringslice
+ "\")\n",
+ index, get_kind_name(kind), item_index,
+ WABT_PRINTF_STRING_SLICE_ARG(name));
+ return reader->OnExport(index, kind, item_index, name);
+}
+
+Result BinaryReaderLogging::OnLocalDecl(uint32_t decl_index,
+ uint32_t count,
+ Type type) {
+ LOGF("OnLocalDecl(index: %u, count: %u, type: %s)\n", decl_index, count,
+ get_type_name(type));
+ return reader->OnLocalDecl(decl_index, count, type);
+}
+
+Result BinaryReaderLogging::OnBlockExpr(uint32_t num_types, Type* sig_types) {
+ LOGF("OnBlockExpr(sig: ");
+ LogTypes(num_types, sig_types);
+ LOGF_NOINDENT(")\n");
+ return reader->OnBlockExpr(num_types, sig_types);
+}
+
+Result BinaryReaderLogging::OnBrExpr(uint32_t depth) {
+ LOGF("OnBrExpr(depth: %u)\n", depth);
+ return reader->OnBrExpr(depth);
+}
+
+Result BinaryReaderLogging::OnBrIfExpr(uint32_t depth) {
+ LOGF("OnBrIfExpr(depth: %u)\n", depth);
+ return reader->OnBrIfExpr(depth);
+}
+
+Result BinaryReaderLogging::OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth) {
+ LOGF("OnBrTableExpr(num_targets: %u, depths: [", num_targets);
+ for (uint32_t i = 0; i < num_targets; ++i) {
+ LOGF_NOINDENT("%u", target_depths[i]);
+ if (i != num_targets - 1)
+ LOGF_NOINDENT(", ");
+ }
+ LOGF_NOINDENT("], default: %u)\n", default_target_depth);
+ return reader->OnBrTableExpr(num_targets, target_depths,
+ default_target_depth);
+}
+
+Result BinaryReaderLogging::OnF32ConstExpr(uint32_t value_bits) {
+ float value;
+ memcpy(&value, &value_bits, sizeof(value));
+ LOGF("OnF32ConstExpr(%g (0x04%x))\n", value, value_bits);
+ return reader->OnF32ConstExpr(value_bits);
+}
+
+Result BinaryReaderLogging::OnF64ConstExpr(uint64_t value_bits) {
+ double value;
+ memcpy(&value, &value_bits, sizeof(value));
+ LOGF("OnF64ConstExpr(%g (0x08%" PRIx64 "))\n", value, value_bits);
+ return reader->OnF64ConstExpr(value_bits);
+}
+
+Result BinaryReaderLogging::OnI32ConstExpr(uint32_t value) {
+ LOGF("OnI32ConstExpr(%u (0x%x))\n", value, value);
+ return reader->OnI32ConstExpr(value);
+}
+
+Result BinaryReaderLogging::OnI64ConstExpr(uint64_t value) {
+ LOGF("OnI64ConstExpr(%" PRIu64 " (0x%" PRIx64 "))\n", value, value);
+ return reader->OnI64ConstExpr(value);
+}
+
+Result BinaryReaderLogging::OnIfExpr(uint32_t num_types, Type* sig_types) {
+ LOGF("OnIfExpr(sig: ");
+ LogTypes(num_types, sig_types);
+ LOGF_NOINDENT(")\n");
+ return reader->OnIfExpr(num_types, sig_types);
+}
+
+Result BinaryReaderLogging::OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
+ LOGF("OnLoadExpr(opcode: \"%s\" (%u), align log2: %u, offset: %u)\n",
+ get_opcode_name(opcode), static_cast<unsigned>(opcode), alignment_log2,
+ offset);
+ return reader->OnLoadExpr(opcode, alignment_log2, offset);
+}
+
+Result BinaryReaderLogging::OnLoopExpr(uint32_t num_types, Type* sig_types) {
+ LOGF("OnLoopExpr(sig: ");
+ LogTypes(num_types, sig_types);
+ LOGF_NOINDENT(")\n");
+ return reader->OnLoopExpr(num_types, sig_types);
+}
+
+Result BinaryReaderLogging::OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
+ LOGF("OnStoreExpr(opcode: \"%s\" (%u), align log2: %u, offset: %u)\n",
+ get_opcode_name(opcode), static_cast<unsigned>(opcode), alignment_log2,
+ offset);
+ return reader->OnStoreExpr(opcode, alignment_log2, offset);
+}
+
+Result BinaryReaderLogging::OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size) {
+ LOGF("OnDataSegmentData(index:%u, size:%u)\n", index, size);
+ return reader->OnDataSegmentData(index, data, size);
+}
+
+Result BinaryReaderLogging::OnFunctionNameSubsection(uint32_t index,
+ uint32_t name_type,
+ uint32_t subsection_size) {
+ LOGF("OnFunctionNameSubsection(index:%u, nametype:%u, size:%u)\n", index,
+ name_type, subsection_size);
+ return reader->OnFunctionNameSubsection(index, name_type, subsection_size);
+}
+
+Result BinaryReaderLogging::OnFunctionName(uint32_t index, StringSlice name) {
+ LOGF("OnFunctionName(index: %u, name: \"" PRIstringslice "\")\n", index,
+ WABT_PRINTF_STRING_SLICE_ARG(name));
+ return reader->OnFunctionName(index, name);
+}
+
+Result BinaryReaderLogging::OnLocalNameSubsection(uint32_t index,
+ uint32_t name_type,
+ uint32_t subsection_size) {
+ LOGF("OnLocalNameSubsection(index:%u, nametype:%u, size:%u)\n", index,
+ name_type, subsection_size);
+ return reader->OnLocalNameSubsection(index, name_type, subsection_size);
+}
+
+Result BinaryReaderLogging::OnLocalName(uint32_t func_index,
+ uint32_t local_index,
+ StringSlice name) {
+ LOGF("OnLocalName(func_index: %u, local_index: %u, name: \"" PRIstringslice
+ "\")\n",
+ func_index, local_index, WABT_PRINTF_STRING_SLICE_ARG(name));
+ return reader->OnLocalName(func_index, local_index, name);
+}
+
+Result BinaryReaderLogging::OnInitExprF32ConstExpr(uint32_t index,
+ uint32_t value_bits) {
+ float value;
+ memcpy(&value, &value_bits, sizeof(value));
+ LOGF("OnInitExprF32ConstExpr(index: %u, value: %g (0x04%x))\n", index, value,
+ value_bits);
+ return reader->OnInitExprF32ConstExpr(index, value_bits);
+}
+
+Result BinaryReaderLogging::OnInitExprF64ConstExpr(uint32_t index,
+ uint64_t value_bits) {
+ double value;
+ memcpy(&value, &value_bits, sizeof(value));
+ LOGF("OnInitExprF64ConstExpr(index: %u value: %g (0x08%" PRIx64 "))\n", index,
+ value, value_bits);
+ return reader->OnInitExprF64ConstExpr(index, value_bits);
+}
+
+Result BinaryReaderLogging::OnInitExprI32ConstExpr(uint32_t index,
+ uint32_t value) {
+ LOGF("OnInitExprI32ConstExpr(index: %u, value: %u)\n", index, value);
+ return reader->OnInitExprI32ConstExpr(index, value);
+}
+
+Result BinaryReaderLogging::OnInitExprI64ConstExpr(uint32_t index,
+ uint64_t value) {
+ LOGF("OnInitExprI64ConstExpr(index: %u, value: %" PRIu64 ")\n", index, value);
+ return reader->OnInitExprI64ConstExpr(index, value);
+}
+
+Result BinaryReaderLogging::OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name) {
+ LOGF("OnRelocCount(count: %d, section: %s, section_name: " PRIstringslice
+ ")\n",
+ count, get_section_name(section_code),
+ WABT_PRINTF_STRING_SLICE_ARG(section_name));
+ return reader->OnRelocCount(count, section_code, section_name);
+}
+
+Result BinaryReaderLogging::OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend) {
+ LOGF("OnReloc(type: %s, offset: %u, index: %u, addend: %d)\n",
+ get_reloc_type_name(type), offset, index, addend);
+ return reader->OnReloc(type, offset, index, addend);
+}
+
+#define DEFINE_BEGIN(name) \
+ Result BinaryReaderLogging::name(uint32_t size) { \
+ LOGF(#name "(%u)\n", size); \
+ Indent(); \
+ return reader->name(size); \
+ }
+
+#define DEFINE_END(name) \
+ Result BinaryReaderLogging::name() { \
+ Dedent(); \
+ LOGF(#name "\n"); \
+ return reader->name(); \
+ }
+
+#define DEFINE_UINT32(name) \
+ Result BinaryReaderLogging::name(uint32_t value) { \
+ LOGF(#name "(%u)\n", value); \
+ return reader->name(value); \
+ }
+
+#define DEFINE_UINT32_DESC(name, desc) \
+ Result BinaryReaderLogging::name(uint32_t value) { \
+ LOGF(#name "(" desc ": %u)\n", value); \
+ return reader->name(value); \
+ }
+
+#define DEFINE_UINT32_UINT32(name, desc0, desc1) \
+ Result BinaryReaderLogging::name(uint32_t value0, uint32_t value1) { \
+ LOGF(#name "(" desc0 ": %u, " desc1 ": %u)\n", value0, value1); \
+ return reader->name(value0, value1); \
+ }
+
+#define DEFINE_OPCODE(name) \
+ Result BinaryReaderLogging::name(Opcode opcode) { \
+ LOGF(#name "(\"%s\" (%u))\n", get_opcode_name(opcode), \
+ static_cast<unsigned>(opcode)); \
+ return reader->name(opcode); \
+ }
+
+#define DEFINE0(name) \
+ Result BinaryReaderLogging::name() { \
+ LOGF(#name "\n"); \
+ return reader->name(); \
+ }
+
+DEFINE_END(EndModule)
+
+DEFINE_END(EndCustomSection)
+
+DEFINE_BEGIN(BeginTypeSection)
+DEFINE_UINT32(OnTypeCount)
+DEFINE_END(EndTypeSection)
+
+DEFINE_BEGIN(BeginImportSection)
+DEFINE_UINT32(OnImportCount)
+DEFINE_END(EndImportSection)
+
+DEFINE_BEGIN(BeginFunctionSection)
+DEFINE_UINT32(OnFunctionCount)
+DEFINE_UINT32_UINT32(OnFunction, "index", "sig_index")
+DEFINE_END(EndFunctionSection)
+
+DEFINE_BEGIN(BeginTableSection)
+DEFINE_UINT32(OnTableCount)
+DEFINE_END(EndTableSection)
+
+DEFINE_BEGIN(BeginMemorySection)
+DEFINE_UINT32(OnMemoryCount)
+DEFINE_END(EndMemorySection)
+
+DEFINE_BEGIN(BeginGlobalSection)
+DEFINE_UINT32(OnGlobalCount)
+DEFINE_UINT32(BeginGlobalInitExpr)
+DEFINE_UINT32(EndGlobalInitExpr)
+DEFINE_UINT32(EndGlobal)
+DEFINE_END(EndGlobalSection)
+
+DEFINE_BEGIN(BeginExportSection)
+DEFINE_UINT32(OnExportCount)
+DEFINE_END(EndExportSection)
+
+DEFINE_BEGIN(BeginStartSection)
+DEFINE_UINT32(OnStartFunction)
+DEFINE_END(EndStartSection)
+
+DEFINE_BEGIN(BeginCodeSection)
+DEFINE_UINT32(OnFunctionBodyCount)
+DEFINE_UINT32(BeginFunctionBody)
+DEFINE_UINT32(EndFunctionBody)
+DEFINE_UINT32(OnLocalDeclCount)
+DEFINE_OPCODE(OnBinaryExpr)
+DEFINE_UINT32_DESC(OnCallExpr, "func_index")
+DEFINE_UINT32_DESC(OnCallIndirectExpr, "sig_index")
+DEFINE_OPCODE(OnCompareExpr)
+DEFINE_OPCODE(OnConvertExpr)
+DEFINE0(OnCurrentMemoryExpr)
+DEFINE0(OnDropExpr)
+DEFINE0(OnElseExpr)
+DEFINE0(OnEndExpr)
+DEFINE_UINT32_DESC(OnGetGlobalExpr, "index")
+DEFINE_UINT32_DESC(OnGetLocalExpr, "index")
+DEFINE0(OnGrowMemoryExpr)
+DEFINE0(OnNopExpr)
+DEFINE0(OnReturnExpr)
+DEFINE0(OnSelectExpr)
+DEFINE_UINT32_DESC(OnSetGlobalExpr, "index")
+DEFINE_UINT32_DESC(OnSetLocalExpr, "index")
+DEFINE_UINT32_DESC(OnTeeLocalExpr, "index")
+DEFINE0(OnUnreachableExpr)
+DEFINE_OPCODE(OnUnaryExpr)
+DEFINE_END(EndCodeSection)
+
+DEFINE_BEGIN(BeginElemSection)
+DEFINE_UINT32(OnElemSegmentCount)
+DEFINE_UINT32_UINT32(BeginElemSegment, "index", "table_index")
+DEFINE_UINT32(BeginElemSegmentInitExpr)
+DEFINE_UINT32(EndElemSegmentInitExpr)
+DEFINE_UINT32_UINT32(OnElemSegmentFunctionIndexCount, "index", "count")
+DEFINE_UINT32_UINT32(OnElemSegmentFunctionIndex, "index", "func_index")
+DEFINE_UINT32(EndElemSegment)
+DEFINE_END(EndElemSection)
+
+DEFINE_BEGIN(BeginDataSection)
+DEFINE_UINT32(OnDataSegmentCount)
+DEFINE_UINT32_UINT32(BeginDataSegment, "index", "memory_index")
+DEFINE_UINT32(BeginDataSegmentInitExpr)
+DEFINE_UINT32(EndDataSegmentInitExpr)
+DEFINE_UINT32(EndDataSegment)
+DEFINE_END(EndDataSection)
+
+DEFINE_BEGIN(BeginNamesSection)
+DEFINE_UINT32(OnFunctionNamesCount)
+DEFINE_UINT32(OnLocalNameFunctionCount)
+DEFINE_UINT32_UINT32(OnLocalNameLocalCount, "index", "count")
+DEFINE_END(EndNamesSection)
+
+DEFINE_BEGIN(BeginRelocSection)
+DEFINE_END(EndRelocSection)
+DEFINE_UINT32_UINT32(OnInitExprGetGlobalExpr, "index", "global_index")
+
+// We don't need to log these (the individual opcodes are logged instead), but
+// we still need to forward the calls.
+Result BinaryReaderLogging::OnOpcode(Opcode opcode) {
+ return reader->OnOpcode(opcode);
+}
+
+Result BinaryReaderLogging::OnOpcodeBare() {
+ return reader->OnOpcodeBare();
+}
+
+Result BinaryReaderLogging::OnOpcodeUint32(uint32_t value) {
+ return reader->OnOpcodeUint32(value);
+}
+
+Result BinaryReaderLogging::OnOpcodeUint32Uint32(uint32_t value,
+ uint32_t value2) {
+ return reader->OnOpcodeUint32Uint32(value, value2);
+}
+
+Result BinaryReaderLogging::OnOpcodeUint64(uint64_t value) {
+ return reader->OnOpcodeUint64(value);
+}
+
+Result BinaryReaderLogging::OnOpcodeF32(uint32_t value) {
+ return reader->OnOpcodeF32(value);
+}
+
+Result BinaryReaderLogging::OnOpcodeF64(uint64_t value) {
+ return reader->OnOpcodeF64(value);
+}
+
+Result BinaryReaderLogging::OnOpcodeBlockSig(uint32_t num_types,
+ Type* sig_types) {
+ return reader->OnOpcodeBlockSig(num_types, sig_types);
+}
+
+Result BinaryReaderLogging::OnEndFunc() {
+ return reader->OnEndFunc();
+}
+
+} // namespace wabt
diff --git a/src/binary-reader-logging.h b/src/binary-reader-logging.h
new file mode 100644
index 00000000..021420cb
--- /dev/null
+++ b/src/binary-reader-logging.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2017 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WABT_BINARY_READER_LOGGING_H_
+#define WABT_BINARY_READER_LOGGING_H_
+
+#include "binary-reader.h"
+
+namespace wabt {
+
+struct Stream;
+
+class BinaryReaderLogging : public BinaryReader {
+ public:
+ BinaryReaderLogging(Stream*, BinaryReader* forward);
+
+ virtual bool OnError(const char* message);
+ virtual void OnSetState(const State* s);
+
+ virtual Result BeginModule(uint32_t version);
+ virtual Result EndModule();
+
+ virtual Result BeginSection(BinarySection section_type, uint32_t size);
+
+ virtual Result BeginCustomSection(uint32_t size, StringSlice section_name);
+ virtual Result EndCustomSection();
+
+ virtual Result BeginTypeSection(uint32_t size);
+ virtual Result OnTypeCount(uint32_t count);
+ virtual Result OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types);
+ virtual Result EndTypeSection();
+
+ virtual Result BeginImportSection(uint32_t size);
+ virtual Result OnImportCount(uint32_t count);
+ virtual Result OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name);
+ virtual Result OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index);
+ virtual Result OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits);
+ virtual Result OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits);
+ virtual Result OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_);
+ virtual Result EndImportSection();
+
+ virtual Result BeginFunctionSection(uint32_t size);
+ virtual Result OnFunctionCount(uint32_t count);
+ virtual Result OnFunction(uint32_t index, uint32_t sig_index);
+ virtual Result EndFunctionSection();
+
+ virtual Result BeginTableSection(uint32_t size);
+ virtual Result OnTableCount(uint32_t count);
+ virtual Result OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits);
+ virtual Result EndTableSection();
+
+ virtual Result BeginMemorySection(uint32_t size);
+ virtual Result OnMemoryCount(uint32_t count);
+ virtual Result OnMemory(uint32_t index, const Limits* limits);
+ virtual Result EndMemorySection();
+
+ virtual Result BeginGlobalSection(uint32_t size);
+ virtual Result OnGlobalCount(uint32_t count);
+ virtual Result BeginGlobal(uint32_t index, Type type, bool mutable_);
+ virtual Result BeginGlobalInitExpr(uint32_t index);
+ virtual Result EndGlobalInitExpr(uint32_t index);
+ virtual Result EndGlobal(uint32_t index);
+ virtual Result EndGlobalSection();
+
+ virtual Result BeginExportSection(uint32_t size);
+ virtual Result OnExportCount(uint32_t count);
+ virtual Result OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name);
+ virtual Result EndExportSection();
+
+ virtual Result BeginStartSection(uint32_t size);
+ virtual Result OnStartFunction(uint32_t func_index);
+ virtual Result EndStartSection();
+
+ virtual Result BeginCodeSection(uint32_t size);
+ virtual Result OnFunctionBodyCount(uint32_t count);
+ virtual Result BeginFunctionBody(uint32_t index);
+ virtual Result OnLocalDeclCount(uint32_t count);
+ virtual Result OnLocalDecl(uint32_t decl_index, uint32_t count, Type type);
+
+ virtual Result OnOpcode(Opcode opcode);
+ virtual Result OnOpcodeBare();
+ virtual Result OnOpcodeUint32(uint32_t value);
+ virtual Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2);
+ virtual Result OnOpcodeUint64(uint64_t value);
+ virtual Result OnOpcodeF32(uint32_t value);
+ virtual Result OnOpcodeF64(uint64_t value);
+ virtual Result OnOpcodeBlockSig(uint32_t num_types, Type* sig_types);
+ virtual Result OnBinaryExpr(Opcode opcode);
+ virtual Result OnBlockExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnBrExpr(uint32_t depth);
+ virtual Result OnBrIfExpr(uint32_t depth);
+ virtual Result OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth);
+ virtual Result OnCallExpr(uint32_t func_index);
+ virtual Result OnCallIndirectExpr(uint32_t sig_index);
+ virtual Result OnCompareExpr(Opcode opcode);
+ virtual Result OnConvertExpr(Opcode opcode);
+ virtual Result OnCurrentMemoryExpr();
+ virtual Result OnDropExpr();
+ virtual Result OnElseExpr();
+ virtual Result OnEndExpr();
+ virtual Result OnEndFunc();
+ virtual Result OnF32ConstExpr(uint32_t value_bits);
+ virtual Result OnF64ConstExpr(uint64_t value_bits);
+ virtual Result OnGetGlobalExpr(uint32_t global_index);
+ virtual Result OnGetLocalExpr(uint32_t local_index);
+ virtual Result OnGrowMemoryExpr();
+ virtual Result OnI32ConstExpr(uint32_t value);
+ virtual Result OnI64ConstExpr(uint64_t value);
+ virtual Result OnIfExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset);
+ virtual Result OnLoopExpr(uint32_t num_types, Type* sig_types);
+ virtual Result OnNopExpr();
+ virtual Result OnReturnExpr();
+ virtual Result OnSelectExpr();
+ virtual Result OnSetGlobalExpr(uint32_t global_index);
+ virtual Result OnSetLocalExpr(uint32_t local_index);
+ virtual Result OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset);
+ virtual Result OnTeeLocalExpr(uint32_t local_index);
+ virtual Result OnUnaryExpr(Opcode opcode);
+ virtual Result OnUnreachableExpr();
+ virtual Result EndFunctionBody(uint32_t index);
+ virtual Result EndCodeSection();
+
+ virtual Result BeginElemSection(uint32_t size);
+ virtual Result OnElemSegmentCount(uint32_t count);
+ virtual Result BeginElemSegment(uint32_t index, uint32_t table_index);
+ virtual Result BeginElemSegmentInitExpr(uint32_t index);
+ virtual Result EndElemSegmentInitExpr(uint32_t index);
+ virtual Result OnElemSegmentFunctionIndexCount(uint32_t index,
+ uint32_t count);
+ virtual Result OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index);
+ virtual Result EndElemSegment(uint32_t index);
+ virtual Result EndElemSection();
+
+ virtual Result BeginDataSection(uint32_t size);
+ virtual Result OnDataSegmentCount(uint32_t count);
+ virtual Result BeginDataSegment(uint32_t index, uint32_t memory_index);
+ virtual Result BeginDataSegmentInitExpr(uint32_t index);
+ virtual Result EndDataSegmentInitExpr(uint32_t index);
+ virtual Result OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size);
+ virtual Result EndDataSegment(uint32_t index);
+ virtual Result EndDataSection();
+
+ virtual Result BeginNamesSection(uint32_t size);
+ virtual Result OnFunctionNameSubsection(uint32_t index,
+ uint32_t name_type,
+ uint32_t subsection_size);
+ virtual Result OnFunctionNamesCount(uint32_t num_functions);
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name);
+ virtual Result OnLocalNameSubsection(uint32_t index,
+ uint32_t name_type,
+ uint32_t subsection_size);
+ virtual Result OnLocalNameFunctionCount(uint32_t num_functions);
+ virtual Result OnLocalNameLocalCount(uint32_t function_index,
+ uint32_t num_locals);
+ virtual Result OnLocalName(uint32_t function_index,
+ uint32_t local_index,
+ StringSlice local_name);
+ virtual Result EndNamesSection();
+
+ virtual Result BeginRelocSection(uint32_t size);
+ virtual Result OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name);
+ virtual Result OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend);
+ virtual Result EndRelocSection();
+
+ virtual Result OnInitExprF32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprF64ConstExpr(uint32_t index, uint64_t value);
+ virtual Result OnInitExprGetGlobalExpr(uint32_t index, uint32_t global_index);
+ virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprI64ConstExpr(uint32_t index, uint64_t value);
+
+ private:
+ void Indent();
+ void Dedent();
+ void WriteIndent();
+ void LogTypes(uint32_t type_count, Type* types);
+
+ Stream* stream;
+ BinaryReader* reader;
+ int indent;
+};
+
+} // namespace wabt
+
+#endif // WABT_BINARY_READER_LOGGING_H_
diff --git a/src/binary-reader-nop.h b/src/binary-reader-nop.h
new file mode 100644
index 00000000..c00614cc
--- /dev/null
+++ b/src/binary-reader-nop.h
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2016 WebAssembly Community Group participants
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef WABT_BINARY_READER_NOP_H_
+#define WABT_BINARY_READER_NOP_H_
+
+#include "binary-reader.h"
+
+namespace wabt {
+
+class BinaryReaderNop : public BinaryReader {
+ public:
+ virtual bool OnError(const char* message) { return false; }
+
+ /* Module */
+ virtual Result BeginModule(uint32_t version) { return Result::Ok; }
+ virtual Result EndModule() { return Result::Ok; }
+
+ virtual Result BeginSection(BinarySection section_type, uint32_t size) {
+ return Result::Ok;
+ }
+
+ /* Custom section */
+ virtual Result BeginCustomSection(uint32_t size, StringSlice section_name) {
+ return Result::Ok;
+ }
+ virtual Result EndCustomSection() { return Result::Ok; }
+
+ /* Type section */
+ virtual Result BeginTypeSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnTypeCount(uint32_t count) { return Result::Ok; }
+ virtual Result OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types) {
+ return Result::Ok;
+ }
+ virtual Result EndTypeSection() { return Result::Ok; }
+
+ /* Import section */
+ virtual Result BeginImportSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnImportCount(uint32_t count) { return Result::Ok; }
+ virtual Result OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name) {
+ return Result::Ok;
+ }
+ virtual Result OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index) {
+ return Result::Ok;
+ }
+ virtual Result OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ return Result::Ok;
+ }
+ virtual Result OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits) {
+ return Result::Ok;
+ }
+ virtual Result OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_) {
+ return Result::Ok;
+ }
+ virtual Result EndImportSection() { return Result::Ok; }
+
+ /* Function section */
+ virtual Result BeginFunctionSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnFunctionCount(uint32_t count) { return Result::Ok; }
+ virtual Result OnFunction(uint32_t index, uint32_t sig_index) {
+ return Result::Ok;
+ }
+ virtual Result EndFunctionSection() { return Result::Ok; }
+
+ /* Table section */
+ virtual Result BeginTableSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnTableCount(uint32_t count) { return Result::Ok; }
+ virtual Result OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ return Result::Ok;
+ }
+ virtual Result EndTableSection() { return Result::Ok; }
+
+ /* Memory section */
+ virtual Result BeginMemorySection(uint32_t size) { return Result::Ok; }
+ virtual Result OnMemoryCount(uint32_t count) { return Result::Ok; }
+ virtual Result OnMemory(uint32_t index, const Limits* limits) {
+ return Result::Ok;
+ }
+ virtual Result EndMemorySection() { return Result::Ok; }
+
+ /* Global section */
+ virtual Result BeginGlobalSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnGlobalCount(uint32_t count) { return Result::Ok; }
+ virtual Result BeginGlobal(uint32_t index, Type type, bool mutable_) {
+ return Result::Ok;
+ }
+ virtual Result BeginGlobalInitExpr(uint32_t index) { return Result::Ok; }
+ virtual Result EndGlobalInitExpr(uint32_t index) { return Result::Ok; }
+ virtual Result EndGlobal(uint32_t index) { return Result::Ok; }
+ virtual Result EndGlobalSection() { return Result::Ok; }
+
+ /* Exports section */
+ virtual Result BeginExportSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnExportCount(uint32_t count) { return Result::Ok; }
+ virtual Result OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) {
+ return Result::Ok;
+ }
+ virtual Result EndExportSection() { return Result::Ok; }
+
+ /* Start section */
+ virtual Result BeginStartSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnStartFunction(uint32_t func_index) { return Result::Ok; }
+ virtual Result EndStartSection() { return Result::Ok; }
+
+ /* Code section */
+ virtual Result BeginCodeSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnFunctionBodyCount(uint32_t count) { return Result::Ok; }
+ virtual Result BeginFunctionBody(uint32_t index) { return Result::Ok; }
+ virtual Result OnLocalDeclCount(uint32_t count) { return Result::Ok; }
+ virtual Result OnLocalDecl(uint32_t decl_index, uint32_t count, Type type) {
+ return Result::Ok;
+ }
+
+ /* Function expressions; called between BeginFunctionBody and
+ EndFunctionBody */
+ virtual Result OnOpcode(Opcode Opcode) { return Result::Ok; }
+ virtual Result OnOpcodeBare() { return Result::Ok; }
+ virtual Result OnOpcodeUint32(uint32_t value) { return Result::Ok; }
+ virtual Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) {
+ return Result::Ok;
+ }
+ virtual Result OnOpcodeUint64(uint64_t value) { return Result::Ok; }
+ virtual Result OnOpcodeF32(uint32_t value) { return Result::Ok; }
+ virtual Result OnOpcodeF64(uint64_t value) { return Result::Ok; }
+ virtual Result OnOpcodeBlockSig(uint32_t num_types, Type* sig_types) {
+ return Result::Ok;
+ }
+ virtual Result OnBinaryExpr(Opcode opcode) { return Result::Ok; }
+ virtual Result OnBlockExpr(uint32_t num_types, Type* sig_types) {
+ return Result::Ok;
+ }
+ virtual Result OnBrExpr(uint32_t depth) { return Result::Ok; }
+ virtual Result OnBrIfExpr(uint32_t depth) { return Result::Ok; }
+ virtual Result OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth) {
+ return Result::Ok;
+ }
+ virtual Result OnCallExpr(uint32_t func_index) { return Result::Ok; }
+ virtual Result OnCallIndirectExpr(uint32_t sig_index) { return Result::Ok; }
+ virtual Result OnCompareExpr(Opcode opcode) { return Result::Ok; }
+ virtual Result OnConvertExpr(Opcode opcode) { return Result::Ok; }
+ virtual Result OnCurrentMemoryExpr() { return Result::Ok; }
+ virtual Result OnDropExpr() { return Result::Ok; }
+ virtual Result OnElseExpr() { return Result::Ok; }
+ virtual Result OnEndExpr() { return Result::Ok; }
+ virtual Result OnEndFunc() { return Result::Ok; }
+ virtual Result OnF32ConstExpr(uint32_t value_bits) { return Result::Ok; }
+ virtual Result OnF64ConstExpr(uint64_t value_bits) { return Result::Ok; }
+ virtual Result OnGetGlobalExpr(uint32_t global_index) { return Result::Ok; }
+ virtual Result OnGetLocalExpr(uint32_t local_index) { return Result::Ok; }
+ virtual Result OnGrowMemoryExpr() { return Result::Ok; }
+ virtual Result OnI32ConstExpr(uint32_t value) { return Result::Ok; }
+ virtual Result OnI64ConstExpr(uint64_t value) { return Result::Ok; }
+ virtual Result OnIfExpr(uint32_t num_types, Type* sig_types) {
+ return Result::Ok;
+ }
+ virtual Result OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
+ return Result::Ok;
+ }
+ virtual Result OnLoopExpr(uint32_t num_types, Type* sig_types) {
+ return Result::Ok;
+ }
+ virtual Result OnNopExpr() { return Result::Ok; }
+ virtual Result OnReturnExpr() { return Result::Ok; }
+ virtual Result OnSelectExpr() { return Result::Ok; }
+ virtual Result OnSetGlobalExpr(uint32_t global_index) { return Result::Ok; }
+ virtual Result OnSetLocalExpr(uint32_t local_index) { return Result::Ok; }
+ virtual Result OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
+ return Result::Ok;
+ }
+ virtual Result OnTeeLocalExpr(uint32_t local_index) { return Result::Ok; }
+ virtual Result OnUnaryExpr(Opcode opcode) { return Result::Ok; }
+ virtual Result OnUnreachableExpr() { return Result::Ok; }
+ virtual Result EndFunctionBody(uint32_t index) { return Result::Ok; }
+ virtual Result EndCodeSection() { return Result::Ok; }
+
+ /* Elem section */
+ virtual Result BeginElemSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnElemSegmentCount(uint32_t count) { return Result::Ok; }
+ virtual Result BeginElemSegment(uint32_t index, uint32_t table_index) {
+ return Result::Ok;
+ }
+ virtual Result BeginElemSegmentInitExpr(uint32_t index) { return Result::Ok; }
+ virtual Result EndElemSegmentInitExpr(uint32_t index) { return Result::Ok; }
+ virtual Result OnElemSegmentFunctionIndexCount(uint32_t index,
+ uint32_t count) {
+ return Result::Ok;
+ }
+ virtual Result OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index) {
+ return Result::Ok;
+ }
+ virtual Result EndElemSegment(uint32_t index) { return Result::Ok; }
+ virtual Result EndElemSection() { return Result::Ok; }
+
+ /* Data section */
+ virtual Result BeginDataSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnDataSegmentCount(uint32_t count) { return Result::Ok; }
+ virtual Result BeginDataSegment(uint32_t index, uint32_t memory_index) {
+ return Result::Ok;
+ }
+ virtual Result BeginDataSegmentInitExpr(uint32_t index) { return Result::Ok; }
+ virtual Result EndDataSegmentInitExpr(uint32_t index) { return Result::Ok; }
+ virtual Result OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size) {
+ return Result::Ok;
+ }
+ virtual Result EndDataSegment(uint32_t index) { return Result::Ok; }
+ virtual Result EndDataSection() { return Result::Ok; }
+
+ /* Names section */
+ virtual Result BeginNamesSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnFunctionNameSubsection(uint32_t index,
+ uint32_t name_type,
+ uint32_t subsection_size) {
+ return Result::Ok;
+ }
+ virtual Result OnFunctionNamesCount(uint32_t num_functions) {
+ return Result::Ok;
+ }
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name) {
+ return Result::Ok;
+ }
+ virtual Result OnLocalNameSubsection(uint32_t index,
+ uint32_t name_type,
+ uint32_t subsection_size) {
+ return Result::Ok;
+ }
+ virtual Result OnLocalNameFunctionCount(uint32_t num_functions) {
+ return Result::Ok;
+ }
+ virtual Result OnLocalNameLocalCount(uint32_t function_index,
+ uint32_t num_locals) {
+ return Result::Ok;
+ }
+ virtual Result OnLocalName(uint32_t function_index,
+ uint32_t local_index,
+ StringSlice local_name) {
+ return Result::Ok;
+ }
+ virtual Result EndNamesSection() { return Result::Ok; }
+
+ /* Reloc section */
+ virtual Result BeginRelocSection(uint32_t size) { return Result::Ok; }
+ virtual Result OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name) {
+ return Result::Ok;
+ }
+ virtual Result OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend) {
+ return Result::Ok;
+ }
+ virtual Result EndRelocSection() { return Result::Ok; }
+
+ /* InitExpr - used by elem, data and global sections; these functions are
+ * only called between calls to Begin*InitExpr and End*InitExpr */
+ virtual Result OnInitExprF32ConstExpr(uint32_t index, uint32_t value) {
+ return Result::Ok;
+ }
+ virtual Result OnInitExprF64ConstExpr(uint32_t index, uint64_t value) {
+ return Result::Ok;
+ }
+ virtual Result OnInitExprGetGlobalExpr(uint32_t index,
+ uint32_t global_index) {
+ return Result::Ok;
+ }
+ virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value) {
+ return Result::Ok;
+ }
+ virtual Result OnInitExprI64ConstExpr(uint32_t index, uint64_t value) {
+ return Result::Ok;
+ }
+};
+
+} // namespace wabt
+
+#endif /* WABT_BINARY_READER_H_ */
diff --git a/src/binary-reader-objdump.cc b/src/binary-reader-objdump.cc
index bb251fa2..c6698289 100644
--- a/src/binary-reader-objdump.cc
+++ b/src/binary-reader-objdump.cc
@@ -23,7 +23,7 @@
#include <vector>
-#include "binary-reader.h"
+#include "binary-reader-nop.h"
#include "literal.h"
namespace wabt {
@@ -32,36 +32,48 @@ namespace {
typedef std::vector<uint32_t> Uint32Vector;
-struct Context {
- ObjdumpOptions* options;
- Stream* out_stream;
- const uint8_t* data;
- size_t size;
- Opcode current_opcode;
- size_t current_opcode_offset;
- size_t last_opcode_end;
- int indent_level;
- bool print_details;
- bool header_printed;
- int section_found;
-
+class BinaryReaderObjdumpBase : public BinaryReaderNop {
+ public:
+ BinaryReaderObjdumpBase(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options);
+
+ virtual Result OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name);
+ virtual Result OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend);
+
+ protected:
+ bool ShouldPrintDetails();
+ void PrintDetails(const char* fmt, ...);
+
+ ObjdumpOptions* options = nullptr;
+ const uint8_t* data = nullptr;
+ size_t size = 0;
+ bool print_details = false;
+ BinarySection reloc_section = BinarySection::Invalid;
uint32_t section_starts[kBinarySectionCount];
- BinarySection reloc_section;
-
- uint32_t next_reloc;
};
-} // namespace
+BinaryReaderObjdumpBase::BinaryReaderObjdumpBase(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options)
+ : options(options), data(data), size(size) {
+ WABT_ZERO_MEMORY(section_starts);
+}
-static bool should_print_details(Context* ctx) {
- if (ctx->options->mode != ObjdumpMode::Details)
+bool BinaryReaderObjdumpBase::ShouldPrintDetails() {
+ if (options->mode != ObjdumpMode::Details)
return false;
- return ctx->print_details;
+ return print_details;
}
-static void WABT_PRINTF_FORMAT(2, 3)
- print_details(Context* ctx, const char* fmt, ...) {
- if (!should_print_details(ctx))
+void WABT_PRINTF_FORMAT(2, 3)
+ BinaryReaderObjdumpBase::PrintDetails(const char* fmt, ...) {
+ if (!ShouldPrintDetails())
return;
va_list args;
va_start(args, fmt);
@@ -69,40 +81,224 @@ static void WABT_PRINTF_FORMAT(2, 3)
va_end(args);
}
-static Result begin_section(BinaryReaderContext* ctx,
- BinarySection section_code,
- uint32_t size) {
- Context* context = static_cast<Context*>(ctx->user_data);
- context->section_starts[static_cast<size_t>(section_code)] = ctx->offset;
+Result BinaryReaderObjdumpBase::OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name) {
+ reloc_section = section_code;
+ PrintDetails(" - section: %s\n", get_section_name(section_code));
+ return Result::Ok;
+}
+
+Result BinaryReaderObjdumpBase::OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend) {
+ uint32_t total_offset =
+ section_starts[static_cast<size_t>(reloc_section)] + offset;
+ PrintDetails(" - %-18s idx=%#-4x addend=%#-4x offset=%#x(file=%#x)\n",
+ get_reloc_type_name(type), index, addend, offset, total_offset);
+ return Result::Ok;
+}
+
+class BinaryReaderObjdumpPrepass : public BinaryReaderObjdumpBase {
+ public:
+ BinaryReaderObjdumpPrepass(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options);
+
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name);
+ virtual Result OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend);
+};
+
+BinaryReaderObjdumpPrepass::BinaryReaderObjdumpPrepass(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options)
+ : BinaryReaderObjdumpBase(data, size, options) {}
+
+Result BinaryReaderObjdumpPrepass::OnFunctionName(uint32_t index,
+ StringSlice name) {
+ if (options->mode == ObjdumpMode::Prepass) {
+ options->function_names.resize(index + 1);
+ options->function_names[index] = string_slice_to_string(name);
+ } else {
+ PrintDetails(" - func[%d] " PRIstringslice "\n", index,
+ WABT_PRINTF_STRING_SLICE_ARG(name));
+ }
+ return Result::Ok;
+}
+
+Result BinaryReaderObjdumpPrepass::OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend) {
+ BinaryReaderObjdumpBase::OnReloc(type, offset, index, addend);
+ if (reloc_section == BinarySection::Code) {
+ options->code_relocations.emplace_back(type, offset, index, addend);
+ }
+ return Result::Ok;
+}
+
+class BinaryReaderObjdump : public BinaryReaderObjdumpBase {
+ public:
+ BinaryReaderObjdump(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options);
+
+ virtual Result BeginModule(uint32_t version);
+ virtual Result EndModule();
+
+ virtual Result BeginSection(BinarySection section_type, uint32_t size);
+
+ virtual Result BeginCustomSection(uint32_t size, StringSlice section_name);
+
+ virtual Result OnTypeCount(uint32_t count);
+ virtual Result OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types);
+
+ virtual Result OnImportCount(uint32_t count);
+ virtual Result OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index);
+ virtual Result OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits);
+ virtual Result OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits);
+ virtual Result OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_);
+
+ virtual Result OnFunctionCount(uint32_t count);
+ virtual Result OnFunction(uint32_t index, uint32_t sig_index);
+
+ virtual Result OnTableCount(uint32_t count);
+ virtual Result OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits);
+
+ virtual Result OnMemoryCount(uint32_t count);
+ virtual Result OnMemory(uint32_t index, const Limits* limits);
+
+ virtual Result OnGlobalCount(uint32_t count);
+ virtual Result BeginGlobal(uint32_t index, Type type, bool mutable_);
+
+ virtual Result OnExportCount(uint32_t count);
+ virtual Result OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name);
+
+ virtual Result OnFunctionBodyCount(uint32_t count);
+ virtual Result BeginFunctionBody(uint32_t index);
+
+ virtual Result OnOpcode(Opcode Opcode);
+ virtual Result OnOpcodeBare();
+ virtual Result OnOpcodeUint32(uint32_t value);
+ virtual Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2);
+ virtual Result OnOpcodeUint64(uint64_t value);
+ virtual Result OnOpcodeF32(uint32_t value);
+ virtual Result OnOpcodeF64(uint64_t value);
+ virtual Result OnOpcodeBlockSig(uint32_t num_types, Type* sig_types);
+
+ virtual Result OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth);
+ virtual Result OnEndExpr();
+ virtual Result OnEndFunc();
+
+ virtual Result OnElemSegmentCount(uint32_t count);
+ virtual Result BeginElemSegment(uint32_t index, uint32_t table_index);
+ virtual Result OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index);
+
+ virtual Result OnDataSegmentCount(uint32_t count);
+ virtual Result BeginDataSegment(uint32_t index, uint32_t memory_index);
+ virtual Result OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size);
+
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name);
+ virtual Result OnLocalName(uint32_t function_index,
+ uint32_t local_index,
+ StringSlice local_name);
+
+ virtual Result OnInitExprF32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprF64ConstExpr(uint32_t index, uint64_t value);
+ virtual Result OnInitExprGetGlobalExpr(uint32_t index, uint32_t global_index);
+ virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value);
+ virtual Result OnInitExprI64ConstExpr(uint32_t index, uint64_t value);
+
+ private:
+ Result OnCount(uint32_t count);
+ void LogOpcode(const uint8_t* data, size_t data_size, const char* fmt, ...);
+
+ Stream* out_stream = nullptr;
+ Opcode current_opcode = Opcode::Unreachable;
+ size_t current_opcode_offset = 0;
+ size_t last_opcode_end = 0;
+ int indent_level = 0;
+ bool header_printed = false;
+ int section_found = false;
+ uint32_t next_reloc = 0;
+};
+
+BinaryReaderObjdump::BinaryReaderObjdump(const uint8_t* data,
+ size_t size,
+ ObjdumpOptions* options)
+ : BinaryReaderObjdumpBase(data, size, options),
+ out_stream(init_stdout_stream()) {}
+
+Result BinaryReaderObjdump::BeginSection(BinarySection section_code,
+ uint32_t size) {
+ section_starts[static_cast<size_t>(section_code)] = state->offset;
const char* name = get_section_name(section_code);
- bool section_match = !context->options->section_name ||
- !strcasecmp(context->options->section_name, name);
+ bool section_match =
+ !options->section_name || !strcasecmp(options->section_name, name);
if (section_match)
- context->section_found = true;
+ section_found = true;
- switch (context->options->mode) {
+ switch (options->mode) {
case ObjdumpMode::Prepass:
break;
case ObjdumpMode::Headers:
printf("%9s start=%#010" PRIzx " end=%#010" PRIzx " (size=%#010x) ", name,
- ctx->offset, ctx->offset + size, size);
+ state->offset, state->offset + size, size);
break;
case ObjdumpMode::Details:
if (section_match) {
if (section_code != BinarySection::Code)
printf("%s:\n", name);
- context->print_details = true;
+ print_details = true;
} else {
- context->print_details = false;
+ print_details = false;
}
break;
case ObjdumpMode::RawData:
if (section_match) {
printf("\nContents of section %s:\n", name);
- write_memory_dump(context->out_stream, context->data + ctx->offset,
- size, ctx->offset, PrintChars::Yes, nullptr, nullptr);
+ write_memory_dump(out_stream, data + state->offset, size, state->offset,
+ PrintChars::Yes, nullptr, nullptr);
}
break;
case ObjdumpMode::Disassemble:
@@ -111,40 +307,36 @@ static Result begin_section(BinaryReaderContext* ctx,
return Result::Ok;
}
-static Result begin_custom_section(BinaryReaderContext* ctx,
- uint32_t size,
- StringSlice section_name) {
- Context* context = static_cast<Context*>(ctx->user_data);
- print_details(context, " - name: \"" PRIstringslice "\"\n",
- WABT_PRINTF_STRING_SLICE_ARG(section_name));
- if (context->options->mode == ObjdumpMode::Headers) {
+Result BinaryReaderObjdump::BeginCustomSection(uint32_t size,
+ StringSlice section_name) {
+ PrintDetails(" - name: \"" PRIstringslice "\"\n",
+ WABT_PRINTF_STRING_SLICE_ARG(section_name));
+ if (options->mode == ObjdumpMode::Headers) {
printf("\"" PRIstringslice "\"\n",
WABT_PRINTF_STRING_SLICE_ARG(section_name));
}
return Result::Ok;
}
-static Result on_count(uint32_t count, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->options->mode == ObjdumpMode::Headers) {
+Result BinaryReaderObjdump::OnCount(uint32_t count) {
+ if (options->mode == ObjdumpMode::Headers) {
printf("count: %d\n", count);
}
return Result::Ok;
}
-static Result begin_module(uint32_t version, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->options->print_header) {
- const char* basename = strrchr(ctx->options->infile, '/');
+Result BinaryReaderObjdump::BeginModule(uint32_t version) {
+ if (options->print_header) {
+ const char* basename = strrchr(options->infile, '/');
if (basename)
basename++;
else
- basename = ctx->options->infile;
+ basename = options->infile;
printf("%s:\tfile format wasm %#08x\n", basename, version);
- ctx->header_printed = true;
+ header_printed = true;
}
- switch (ctx->options->mode) {
+ switch (options->mode) {
case ObjdumpMode::Headers:
printf("\n");
printf("Sections:\n\n");
@@ -165,11 +357,10 @@ static Result begin_module(uint32_t version, void* user_data) {
return Result::Ok;
}
-static Result end_module(void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->options->section_name) {
- if (!ctx->section_found) {
- printf("Section not found: %s\n", ctx->options->section_name);
+Result BinaryReaderObjdump::EndModule() {
+ if (options->section_name) {
+ if (!section_found) {
+ printf("Section not found: %s\n", options->section_name);
return Result::Error;
}
}
@@ -177,44 +368,44 @@ static Result end_module(void* user_data) {
return Result::Ok;
}
-static Result on_opcode(BinaryReaderContext* ctx, Opcode opcode) {
- Context* context = static_cast<Context*>(ctx->user_data);
+Result BinaryReaderObjdump::OnOpcode(Opcode opcode) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
- if (context->options->debug) {
+ if (options->debug) {
const char* opcode_name = get_opcode_name(opcode);
- printf("on_opcode: %#" PRIzx ": %s\n", ctx->offset, opcode_name);
+ printf("on_opcode: %#" PRIzx ": %s\n", state->offset, opcode_name);
}
- if (context->last_opcode_end) {
- if (ctx->offset != context->last_opcode_end + 1) {
- uint8_t missing_opcode = ctx->data[context->last_opcode_end];
+ if (last_opcode_end) {
+ if (state->offset != last_opcode_end + 1) {
+ uint8_t missing_opcode = data[last_opcode_end];
const char* opcode_name =
get_opcode_name(static_cast<Opcode>(missing_opcode));
fprintf(stderr, "warning: %#" PRIzx " missing opcode callback at %#" PRIzx
" (%#02x=%s)\n",
- ctx->offset, context->last_opcode_end + 1,
- ctx->data[context->last_opcode_end], opcode_name);
+ state->offset, last_opcode_end + 1, data[last_opcode_end],
+ opcode_name);
return Result::Error;
}
}
- context->current_opcode_offset = ctx->offset;
- context->current_opcode = opcode;
+ current_opcode_offset = state->offset;
+ current_opcode = opcode;
return Result::Ok;
}
#define IMMEDIATE_OCTET_COUNT 9
-static void log_opcode(Context* ctx,
- const uint8_t* data,
- size_t data_size,
- const char* fmt,
- ...) {
- size_t offset = ctx->current_opcode_offset;
+void BinaryReaderObjdump::LogOpcode(const uint8_t* data,
+ size_t data_size,
+ const char* fmt,
+ ...) {
+ size_t offset = current_opcode_offset;
// Print binary data
printf(" %06" PRIzx ": %02x", offset - 1,
- static_cast<unsigned>(ctx->current_opcode));
+ static_cast<unsigned>(current_opcode));
for (size_t i = 0; i < data_size && i < IMMEDIATE_OCTET_COUNT;
i++, offset++) {
printf(" %02x", data[offset]);
@@ -225,14 +416,14 @@ static void log_opcode(Context* ctx,
printf(" | ");
// Print disassemble
- int indent_level = ctx->indent_level;
- if (ctx->current_opcode == Opcode::Else)
+ int indent_level = this->indent_level;
+ if (current_opcode == Opcode::Else)
indent_level--;
for (int j = 0; j < indent_level; j++) {
printf(" ");
}
- const char* opcode_name = get_opcode_name(ctx->current_opcode);
+ const char* opcode_name = get_opcode_name(current_opcode);
printf("%s", opcode_name);
if (fmt) {
printf(" ");
@@ -244,15 +435,15 @@ static void log_opcode(Context* ctx,
printf("\n");
- ctx->last_opcode_end = ctx->current_opcode_offset + data_size;
+ last_opcode_end = current_opcode_offset + data_size;
- if (ctx->options->relocs) {
- if (ctx->next_reloc < ctx->options->code_relocations.size()) {
- Reloc* reloc = &ctx->options->code_relocations[ctx->next_reloc];
+ if (options->relocs) {
+ if (next_reloc < options->code_relocations.size()) {
+ Reloc* reloc = &options->code_relocations[next_reloc];
size_t code_start =
- ctx->section_starts[static_cast<size_t>(BinarySection::Code)];
+ section_starts[static_cast<size_t>(BinarySection::Code)];
size_t abs_offset = code_start + reloc->offset;
- if (ctx->last_opcode_end > abs_offset) {
+ if (last_opcode_end > abs_offset) {
printf(" %06" PRIzx ": %-18s %d", abs_offset,
get_reloc_type_name(reloc->type), reloc->index);
switch (reloc->type) {
@@ -265,85 +456,92 @@ static void log_opcode(Context* ctx,
break;
}
printf("\n");
- ctx->next_reloc++;
+ next_reloc++;
}
}
}
}
-static Result on_opcode_bare(BinaryReaderContext* ctx) {
- Context* context = static_cast<Context*>(ctx->user_data);
- log_opcode(context, ctx->data, 0, nullptr);
+Result BinaryReaderObjdump::OnOpcodeBare() {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ LogOpcode(data, 0, nullptr);
return Result::Ok;
}
-static Result on_opcode_uint32(BinaryReaderContext* ctx, uint32_t value) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
- log_opcode(context, ctx->data, immediate_len, "%#x", value);
+Result BinaryReaderObjdump::OnOpcodeUint32(uint32_t value) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
+ LogOpcode(data, immediate_len, "%#x", value);
return Result::Ok;
}
-static Result on_opcode_uint32_uint32(BinaryReaderContext* ctx,
- uint32_t value,
- uint32_t value2) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
- log_opcode(context, ctx->data, immediate_len, "%lu %lu", value, value2);
+Result BinaryReaderObjdump::OnOpcodeUint32Uint32(uint32_t value,
+ uint32_t value2) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
+ LogOpcode(data, immediate_len, "%lu %lu", value, value2);
return Result::Ok;
}
-static Result on_opcode_uint64(BinaryReaderContext* ctx, uint64_t value) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
- log_opcode(context, ctx->data, immediate_len, "%d", value);
+Result BinaryReaderObjdump::OnOpcodeUint64(uint64_t value) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
+ LogOpcode(data, immediate_len, "%d", value);
return Result::Ok;
}
-static Result on_opcode_f32(BinaryReaderContext* ctx, uint32_t value) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
+Result BinaryReaderObjdump::OnOpcodeF32(uint32_t value) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
char buffer[WABT_MAX_FLOAT_HEX];
write_float_hex(buffer, sizeof(buffer), value);
- log_opcode(context, ctx->data, immediate_len, buffer);
+ LogOpcode(data, immediate_len, buffer);
return Result::Ok;
}
-static Result on_opcode_f64(BinaryReaderContext* ctx, uint64_t value) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
+Result BinaryReaderObjdump::OnOpcodeF64(uint64_t value) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
char buffer[WABT_MAX_DOUBLE_HEX];
write_double_hex(buffer, sizeof(buffer), value);
- log_opcode(context, ctx->data, immediate_len, buffer);
+ LogOpcode(data, immediate_len, buffer);
return Result::Ok;
}
-Result on_br_table_expr(BinaryReaderContext* ctx,
- uint32_t num_targets,
- uint32_t* target_depths,
- uint32_t default_target_depth) {
- Context* context = static_cast<Context*>(ctx->user_data);
- size_t immediate_len = ctx->offset - context->current_opcode_offset;
+Result BinaryReaderObjdump::OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth) {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ size_t immediate_len = state->offset - current_opcode_offset;
/* TODO(sbc): Print targets */
- log_opcode(context, ctx->data, immediate_len, nullptr);
+ LogOpcode(data, immediate_len, nullptr);
return Result::Ok;
}
-static Result on_end_func(void* user_data) {
- Context* context = static_cast<Context*>(user_data);
- log_opcode(context, nullptr, 0, nullptr);
+Result BinaryReaderObjdump::OnEndFunc() {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ LogOpcode(nullptr, 0, nullptr);
return Result::Ok;
}
-static Result on_end_expr(void* user_data) {
- Context* context = static_cast<Context*>(user_data);
- context->indent_level--;
- assert(context->indent_level >= 0);
- log_opcode(context, nullptr, 0, nullptr);
+Result BinaryReaderObjdump::OnEndExpr() {
+ if (options->mode != ObjdumpMode::Disassemble)
+ return Result::Ok;
+ indent_level--;
+ assert(indent_level >= 0);
+ LogOpcode(nullptr, 0, nullptr);
return Result::Ok;
}
-static const char* type_name(Type type) {
+const char* type_name(Type type) {
switch (type) {
case Type::I32:
return "i32";
@@ -363,27 +561,26 @@ static const char* type_name(Type type) {
}
}
-static Result on_opcode_block_sig(BinaryReaderContext* ctx,
- uint32_t num_types,
- Type* sig_types) {
- Context* context = static_cast<Context*>(ctx->user_data);
+Result BinaryReaderObjdump::OnOpcodeBlockSig(uint32_t num_types,
+ Type* sig_types) {
if (num_types)
- log_opcode(context, ctx->data, 1, "%s", type_name(*sig_types));
+ LogOpcode(data, 1, "%s", type_name(*sig_types));
else
- log_opcode(context, ctx->data, 1, nullptr);
- context->indent_level++;
+ LogOpcode(data, 1, nullptr);
+ indent_level++;
return Result::Ok;
}
-static Result on_signature(uint32_t index,
- uint32_t param_count,
- Type* param_types,
- uint32_t result_count,
- Type* result_types,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderObjdump::OnTypeCount(uint32_t count) {
+ return OnCount(count);
+}
- if (!should_print_details(ctx))
+Result BinaryReaderObjdump::OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types) {
+ if (!ShouldPrintDetails())
return Result::Ok;
printf(" - [%d] (", index);
for (uint32_t i = 0; i < param_count; i++) {
@@ -401,380 +598,245 @@ static Result on_signature(uint32_t index,
return Result::Ok;
}
-static Result on_function_signature(uint32_t index,
- uint32_t sig_index,
- void* user_data) {
- print_details(static_cast<Context*>(user_data), " - func[%d] sig=%d\n", index,
- sig_index);
+Result BinaryReaderObjdump::OnFunctionCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnFunction(uint32_t index, uint32_t sig_index) {
+ PrintDetails(" - func[%d] sig=%d\n", index, sig_index);
return Result::Ok;
}
-static Result begin_function_body(BinaryReaderContext* context,
- uint32_t index) {
- Context* ctx = static_cast<Context*>(context->user_data);
+Result BinaryReaderObjdump::OnFunctionBodyCount(uint32_t count) {
+ return OnCount(count);
+}
- if (ctx->options->mode == ObjdumpMode::Disassemble) {
- if (index < ctx->options->function_names.size() &&
- !ctx->options->function_names[index].empty())
- printf("%06" PRIzx " <%s>:\n", context->offset,
- ctx->options->function_names[index].c_str());
+Result BinaryReaderObjdump::BeginFunctionBody(uint32_t index) {
+ if (options->mode == ObjdumpMode::Disassemble) {
+ if (index < options->function_names.size() &&
+ !options->function_names[index].empty())
+ printf("%06" PRIzx " <%s>:\n", state->offset,
+ options->function_names[index].c_str());
else
- printf("%06" PRIzx " func[%d]:\n", context->offset, index);
+ printf("%06" PRIzx " func[%d]:\n", state->offset, index);
}
- ctx->last_opcode_end = 0;
+ last_opcode_end = 0;
return Result::Ok;
}
-static Result on_import_func(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t func_index,
- uint32_t sig_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx,
- " - func[%d] sig=%d <- " PRIstringslice "." PRIstringslice "\n",
- func_index, sig_index,
- WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name));
+Result BinaryReaderObjdump::OnImportCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index) {
+ PrintDetails(" - func[%d] sig=%d <- " PRIstringslice "." PRIstringslice "\n",
+ func_index, sig_index, WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name));
return Result::Ok;
}
-static Result on_import_table(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t table_index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(
- ctx, " - " PRIstringslice "." PRIstringslice
- " -> table elem_type=%s init=%" PRId64 " max=%" PRId64 "\n",
- WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name),
- get_type_name(elem_type), elem_limits->initial, elem_limits->max);
+Result BinaryReaderObjdump::OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t table_index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ PrintDetails(" - " PRIstringslice "." PRIstringslice
+ " -> table elem_type=%s init=%" PRId64 " max=%" PRId64 "\n",
+ WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name),
+ get_type_name(elem_type), elem_limits->initial,
+ elem_limits->max);
return Result::Ok;
}
-static Result on_import_memory(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t memory_index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - " PRIstringslice "." PRIstringslice " -> memory\n",
- WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name));
+Result BinaryReaderObjdump::OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits) {
+ PrintDetails(" - " PRIstringslice "." PRIstringslice " -> memory\n",
+ WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name));
return Result::Ok;
}
-static Result on_import_global(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t global_index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - global[%d] %s mutable=%d <- " PRIstringslice
- "." PRIstringslice "\n",
- global_index, get_type_name(type), mutable_,
- WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name));
- return Result::Ok;
-}
-
-static Result on_memory(uint32_t index,
- const Limits* page_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - memory[%d] pages: initial=%" PRId64, index,
- page_limits->initial);
+Result BinaryReaderObjdump::OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_) {
+ PrintDetails(" - global[%d] %s mutable=%d <- " PRIstringslice
+ "." PRIstringslice "\n",
+ global_index, get_type_name(type), mutable_,
+ WABT_PRINTF_STRING_SLICE_ARG(module_name),
+ WABT_PRINTF_STRING_SLICE_ARG(field_name));
+ return Result::Ok;
+}
+
+Result BinaryReaderObjdump::OnMemoryCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnMemory(uint32_t index,
+ const Limits* page_limits) {
+ PrintDetails(" - memory[%d] pages: initial=%" PRId64, index,
+ page_limits->initial);
if (page_limits->has_max)
- print_details(ctx, " max=%" PRId64, page_limits->max);
- print_details(ctx, "\n");
+ PrintDetails(" max=%" PRId64, page_limits->max);
+ PrintDetails("\n");
return Result::Ok;
}
-static Result on_table(uint32_t index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - table[%d] type=%s initial=%" PRId64, index,
- get_type_name(elem_type), elem_limits->initial);
+Result BinaryReaderObjdump::OnTableCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits) {
+ PrintDetails(" - table[%d] type=%s initial=%" PRId64, index,
+ get_type_name(elem_type), elem_limits->initial);
if (elem_limits->has_max)
- print_details(ctx, " max=%" PRId64, elem_limits->max);
- print_details(ctx, "\n");
+ PrintDetails(" max=%" PRId64, elem_limits->max);
+ PrintDetails("\n");
return Result::Ok;
}
-static Result on_export(uint32_t index,
- ExternalKind kind,
- uint32_t item_index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - %s[%d] ", get_kind_name(kind), item_index);
- print_details(ctx, PRIstringslice, WABT_PRINTF_STRING_SLICE_ARG(name));
- print_details(ctx, "\n");
+Result BinaryReaderObjdump::OnExportCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) {
+ PrintDetails(" - %s[%d] ", get_kind_name(kind), item_index);
+ PrintDetails(PRIstringslice, WABT_PRINTF_STRING_SLICE_ARG(name));
+ PrintDetails("\n");
return Result::Ok;
}
-static Result on_elem_segment_function_index(uint32_t index,
- uint32_t func_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - func[%d]\n", func_index);
+Result BinaryReaderObjdump::OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index) {
+ PrintDetails(" - func[%d]\n", func_index);
return Result::Ok;
}
-static Result begin_elem_segment(uint32_t index,
- uint32_t table_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - segment[%d] table=%d\n", index, table_index);
+Result BinaryReaderObjdump::OnElemSegmentCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::BeginElemSegment(uint32_t index,
+ uint32_t table_index) {
+ PrintDetails(" - segment[%d] table=%d\n", index, table_index);
return Result::Ok;
}
-static Result begin_global(uint32_t index,
- Type type,
- bool mutable_,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - global[%d] %s mutable=%d", index, get_type_name(type),
- mutable_);
+Result BinaryReaderObjdump::OnGlobalCount(uint32_t count) {
+ return OnCount(count);
+}
+
+Result BinaryReaderObjdump::BeginGlobal(uint32_t index,
+ Type type,
+ bool mutable_) {
+ PrintDetails(" - global[%d] %s mutable=%d", index, get_type_name(type),
+ mutable_);
return Result::Ok;
}
-static Result on_init_expr_f32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderObjdump::OnInitExprF32ConstExpr(uint32_t index,
+ uint32_t value) {
char buffer[WABT_MAX_FLOAT_HEX];
write_float_hex(buffer, sizeof(buffer), value);
- print_details(ctx, " - init f32=%s\n", buffer);
+ PrintDetails(" - init f32=%s\n", buffer);
return Result::Ok;
}
-static Result on_init_expr_f64_const_expr(uint32_t index,
- uint64_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderObjdump::OnInitExprF64ConstExpr(uint32_t index,
+ uint64_t value) {
char buffer[WABT_MAX_DOUBLE_HEX];
write_float_hex(buffer, sizeof(buffer), value);
- print_details(ctx, " - init f64=%s\n", buffer);
+ PrintDetails(" - init f64=%s\n", buffer);
return Result::Ok;
}
-static Result on_init_expr_get_global_expr(uint32_t index,
- uint32_t global_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - init global=%d\n", global_index);
+Result BinaryReaderObjdump::OnInitExprGetGlobalExpr(uint32_t index,
+ uint32_t global_index) {
+ PrintDetails(" - init global=%d\n", global_index);
return Result::Ok;
}
-static Result on_init_expr_i32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - init i32=%d\n", value);
+Result BinaryReaderObjdump::OnInitExprI32ConstExpr(uint32_t index,
+ uint32_t value) {
+ PrintDetails(" - init i32=%d\n", value);
return Result::Ok;
}
-static Result on_init_expr_i64_const_expr(uint32_t index,
- uint64_t value,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - init i64=%" PRId64 "\n", value);
+Result BinaryReaderObjdump::OnInitExprI64ConstExpr(uint32_t index,
+ uint64_t value) {
+ PrintDetails(" - init i64=%" PRId64 "\n", value);
return Result::Ok;
}
-static Result on_function_name(uint32_t index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (ctx->options->mode == ObjdumpMode::Prepass) {
- ctx->options->function_names.resize(index+1);
- ctx->options->function_names[index] = string_slice_to_string(name);
- } else {
- print_details(ctx, " - func[%d] " PRIstringslice "\n", index,
- WABT_PRINTF_STRING_SLICE_ARG(name));
- }
+Result BinaryReaderObjdump::OnFunctionName(uint32_t index, StringSlice name) {
+ PrintDetails(" - func[%d] " PRIstringslice "\n", index,
+ WABT_PRINTF_STRING_SLICE_ARG(name));
return Result::Ok;
}
-static Result on_local_name(uint32_t func_index,
- uint32_t local_index,
- StringSlice name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
+Result BinaryReaderObjdump::OnLocalName(uint32_t func_index,
+ uint32_t local_index,
+ StringSlice name) {
if (name.length) {
- print_details(ctx, " - func[%d] local[%d] " PRIstringslice "\n", func_index,
- local_index, WABT_PRINTF_STRING_SLICE_ARG(name));
+ PrintDetails(" - func[%d] local[%d] " PRIstringslice "\n", func_index,
+ local_index, WABT_PRINTF_STRING_SLICE_ARG(name));
}
return Result::Ok;
}
-Result on_reloc_count(uint32_t count,
- BinarySection section_code,
- StringSlice section_name,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- ctx->reloc_section = section_code;
- print_details(ctx, " - section: %s\n", get_section_name(section_code));
- return Result::Ok;
-}
-
-Result on_reloc(RelocType type,
- uint32_t offset,
- uint32_t index,
- int32_t addend,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- uint32_t total_offset =
- ctx->section_starts[static_cast<size_t>(ctx->reloc_section)] + offset;
- print_details(ctx, " - %-18s idx=%#-4x addend=%#-4x offset=%#x(file=%#x)\n",
- get_reloc_type_name(type), index, addend, offset, total_offset);
- if (ctx->options->mode == ObjdumpMode::Prepass &&
- ctx->reloc_section == BinarySection::Code) {
- ctx->options->code_relocations.emplace_back(type, offset, index, addend);
- }
- return Result::Ok;
+Result BinaryReaderObjdump::OnDataSegmentCount(uint32_t count) {
+ return OnCount(count);
}
-static Result begin_data_segment(uint32_t index,
- uint32_t memory_index,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- print_details(ctx, " - memory[%d]", memory_index);
+Result BinaryReaderObjdump::BeginDataSegment(uint32_t index,
+ uint32_t memory_index) {
+ PrintDetails(" - memory[%d]", memory_index);
return Result::Ok;
}
-static Result on_data_segment_data(uint32_t index,
- const void* src_data,
- uint32_t size,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (should_print_details(ctx)) {
- write_memory_dump(ctx->out_stream, src_data, size, 0, PrintChars::Yes,
- " - ", nullptr);
+Result BinaryReaderObjdump::OnDataSegmentData(uint32_t index,
+ const void* src_data,
+ uint32_t size) {
+ if (ShouldPrintDetails()) {
+ write_memory_dump(out_stream, src_data, size, 0, PrintChars::Yes, " - ",
+ nullptr);
}
return Result::Ok;
}
+} // namespace
+
Result read_binary_objdump(const uint8_t* data,
size_t size,
ObjdumpOptions* options) {
- Context context;
- WABT_ZERO_MEMORY(context);
- context.header_printed = false;
- context.print_details = false;
- context.section_found = false;
- context.data = data;
- context.size = size;
- context.options = options;
- context.out_stream = init_stdout_stream();
-
- BinaryReader reader;
- WABT_ZERO_MEMORY(reader);
- if (options->mode == ObjdumpMode::Prepass) {
- reader.on_function_name = on_function_name;
- reader.on_reloc_count = on_reloc_count;
- reader.on_reloc = on_reloc;
- } else {
- reader.begin_module = begin_module;
- reader.end_module = end_module;
-
- reader.begin_section = begin_section;
-
- // User section
- reader.begin_custom_section = begin_custom_section;
-
- // Signature section
- reader.on_signature_count = on_count;
- reader.on_signature = on_signature;
-
- // Import section
- reader.on_import_count = on_count;
- reader.on_import_func = on_import_func;
- reader.on_import_table = on_import_table;
- reader.on_import_memory = on_import_memory;
- reader.on_import_global = on_import_global;
-
- // Function sigs section
- reader.on_function_signatures_count = on_count;
- reader.on_function_signature = on_function_signature;
-
- // Table section
- reader.on_table_count = on_count;
- reader.on_table = on_table;
-
- // Memory section
- reader.on_memory_count = on_count;
- reader.on_memory = on_memory;
-
- // Globl seciont
- reader.begin_global = begin_global;
- reader.on_global_count = on_count;
-
- // Export section
- reader.on_export_count = on_count;
- reader.on_export = on_export;
-
- // Body section
- reader.on_function_bodies_count = on_count;
- reader.begin_function_body = begin_function_body;
-
- // Elems section
- reader.begin_elem_segment = begin_elem_segment;
- reader.on_elem_segment_count = on_count;
- reader.on_elem_segment_function_index = on_elem_segment_function_index;
-
- // Data section
- reader.begin_data_segment = begin_data_segment;
- reader.on_data_segment_data = on_data_segment_data;
- reader.on_data_segment_count = on_count;
-
- // Known "User" sections:
- // - Names section
- reader.on_function_name = on_function_name;
- reader.on_local_name = on_local_name;
-
- reader.on_reloc_count = on_reloc_count;
- reader.on_reloc = on_reloc;
-
- reader.on_init_expr_i32_const_expr = on_init_expr_i32_const_expr;
- reader.on_init_expr_i64_const_expr = on_init_expr_i64_const_expr;
- reader.on_init_expr_f32_const_expr = on_init_expr_f32_const_expr;
- reader.on_init_expr_f64_const_expr = on_init_expr_f64_const_expr;
- reader.on_init_expr_get_global_expr = on_init_expr_get_global_expr;
- }
-
- if (options->mode == ObjdumpMode::Disassemble) {
- reader.on_opcode = on_opcode;
- reader.on_opcode_bare = on_opcode_bare;
- reader.on_opcode_uint32 = on_opcode_uint32;
- reader.on_opcode_uint32_uint32 = on_opcode_uint32_uint32;
- reader.on_opcode_uint64 = on_opcode_uint64;
- reader.on_opcode_f32 = on_opcode_f32;
- reader.on_opcode_f64 = on_opcode_f64;
- reader.on_opcode_block_sig = on_opcode_block_sig;
- reader.on_end_expr = on_end_expr;
- reader.on_end_func = on_end_func;
- reader.on_br_table_expr = on_br_table_expr;
- }
-
- reader.user_data = &context;
-
ReadBinaryOptions read_options = WABT_READ_BINARY_OPTIONS_DEFAULT;
read_options.read_debug_names = true;
read_options.log_stream = options->log_stream;
- return read_binary(data, size, &reader, 1, &read_options);
+
+ if (options->mode == ObjdumpMode::Prepass) {
+ BinaryReaderObjdumpPrepass reader(data, size, options);
+ return read_binary(data, size, &reader, &read_options);
+ } else {
+ BinaryReaderObjdump reader(data, size, options);
+ return read_binary(data, size, &reader, &read_options);
+ }
}
} // namespace wabt
diff --git a/src/binary-reader-opcnt.cc b/src/binary-reader-opcnt.cc
index 8e428e1f..61c5dd19 100644
--- a/src/binary-reader-opcnt.cc
+++ b/src/binary-reader-opcnt.cc
@@ -22,20 +22,34 @@
#include <stdint.h>
#include <stdio.h>
-#include "binary-reader.h"
+#include "binary-reader-nop.h"
#include "common.h"
namespace wabt {
namespace {
-struct Context {
+class BinaryReaderOpcnt : public BinaryReaderNop {
+ public:
+ explicit BinaryReaderOpcnt(OpcntData* data);
+
+ virtual Result OnOpcode(Opcode opcode);
+ virtual Result OnI32ConstExpr(uint32_t value);
+ virtual Result OnGetLocalExpr(uint32_t local_index);
+ virtual Result OnSetLocalExpr(uint32_t local_index);
+ virtual Result OnTeeLocalExpr(uint32_t local_index);
+ virtual Result OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset);
+ virtual Result OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset);
+
+ private:
OpcntData* opcnt_data;
};
-} // namespace
-
-static Result add_int_counter_value(IntCounterVector* vec, intmax_t value) {
+static Result AddIntCounterValue(IntCounterVector* vec, intmax_t value) {
for (IntCounter& counter : *vec) {
if (counter.value == value) {
++counter.count;
@@ -46,9 +60,9 @@ static Result add_int_counter_value(IntCounterVector* vec, intmax_t value) {
return Result::Ok;
}
-static Result add_int_pair_counter_value(IntPairCounterVector* vec,
- intmax_t first,
- intmax_t second) {
+static Result AddIntPairCounterValue(IntPairCounterVector* vec,
+ intmax_t first,
+ intmax_t second) {
for (IntPairCounter& pair : *vec) {
if (pair.first == first && pair.second == second) {
++pair.count;
@@ -59,9 +73,10 @@ static Result add_int_pair_counter_value(IntPairCounterVector* vec,
return Result::Ok;
}
-static Result on_opcode(BinaryReaderContext* context, Opcode opcode) {
- Context* ctx = static_cast<Context*>(context->user_data);
- IntCounterVector& opcnt_vec = ctx->opcnt_data->opcode_vec;
+BinaryReaderOpcnt::BinaryReaderOpcnt(OpcntData* data) : opcnt_data(data) {}
+
+Result BinaryReaderOpcnt::OnOpcode(Opcode opcode) {
+ IntCounterVector& opcnt_vec = opcnt_data->opcode_vec;
while (static_cast<size_t>(opcode) >= opcnt_vec.size()) {
opcnt_vec.emplace_back(opcnt_vec.size(), 0);
}
@@ -69,69 +84,51 @@ static Result on_opcode(BinaryReaderContext* context, Opcode opcode) {
return Result::Ok;
}
-static Result on_i32_const_expr(uint32_t value, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- return add_int_counter_value(&ctx->opcnt_data->i32_const_vec,
- static_cast<int32_t>(value));
+Result BinaryReaderOpcnt::OnI32ConstExpr(uint32_t value) {
+ return AddIntCounterValue(&opcnt_data->i32_const_vec,
+ static_cast<int32_t>(value));
}
-static Result on_get_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- return add_int_counter_value(&ctx->opcnt_data->get_local_vec, local_index);
+Result BinaryReaderOpcnt::OnGetLocalExpr(uint32_t local_index) {
+ return AddIntCounterValue(&opcnt_data->get_local_vec, local_index);
}
-static Result on_set_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- return add_int_counter_value(&ctx->opcnt_data->set_local_vec, local_index);
+Result BinaryReaderOpcnt::OnSetLocalExpr(uint32_t local_index) {
+ return AddIntCounterValue(&opcnt_data->set_local_vec, local_index);
}
-static Result on_tee_local_expr(uint32_t local_index, void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- return add_int_counter_value(&ctx->opcnt_data->tee_local_vec, local_index);
+Result BinaryReaderOpcnt::OnTeeLocalExpr(uint32_t local_index) {
+ return AddIntCounterValue(&opcnt_data->tee_local_vec, local_index);
}
-static Result on_load_expr(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (opcode == Opcode::I32Load)
- return add_int_pair_counter_value(&ctx->opcnt_data->i32_load_vec,
- alignment_log2, offset);
+Result BinaryReaderOpcnt::OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
+ if (opcode == Opcode::I32Load) {
+ return AddIntPairCounterValue(&opcnt_data->i32_load_vec, alignment_log2,
+ offset);
+ }
return Result::Ok;
}
-static Result on_store_expr(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data) {
- Context* ctx = static_cast<Context*>(user_data);
- if (opcode == Opcode::I32Store)
- return add_int_pair_counter_value(&ctx->opcnt_data->i32_store_vec,
- alignment_log2, offset);
+Result BinaryReaderOpcnt::OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) {
+ if (opcode == Opcode::I32Store) {
+ return AddIntPairCounterValue(&opcnt_data->i32_store_vec, alignment_log2,
+ offset);
+ }
return Result::Ok;
}
+} // namespace
+
Result read_binary_opcnt(const void* data,
- size_t size,
- const struct ReadBinaryOptions* options,
- OpcntData* opcnt_data) {
- Context ctx;
- WABT_ZERO_MEMORY(ctx);
- ctx.opcnt_data = opcnt_data;
-
- BinaryReader reader;
- WABT_ZERO_MEMORY(reader);
- reader.user_data = &ctx;
- reader.on_opcode = on_opcode;
- reader.on_i32_const_expr = on_i32_const_expr;
- reader.on_get_local_expr = on_get_local_expr;
- reader.on_set_local_expr = on_set_local_expr;
- reader.on_tee_local_expr = on_tee_local_expr;
- reader.on_load_expr = on_load_expr;
- reader.on_store_expr = on_store_expr;
-
- return read_binary(data, size, &reader, 1, options);
+ size_t size,
+ const struct ReadBinaryOptions* options,
+ OpcntData* opcnt_data) {
+ BinaryReaderOpcnt reader(opcnt_data);
+ return read_binary(data, size, &reader, options);
}
} // namespace wabt
diff --git a/src/binary-reader.cc b/src/binary-reader.cc
index 67ea4672..4ac9c746 100644
--- a/src/binary-reader.cc
+++ b/src/binary-reader.cc
@@ -27,6 +27,7 @@
#include <vector>
#include "binary.h"
+#include "binary-reader-logging.h"
#include "config.h"
#include "stream.h"
@@ -34,70 +35,17 @@
#include <alloca.h>
#endif
-#define INDENT_SIZE 2
-
-#define INITIAL_PARAM_TYPES_CAPACITY 128
-#define INITIAL_BR_TABLE_TARGET_CAPACITY 1000
-
namespace wabt {
namespace {
-#define CALLBACK_CTX(member, ...) \
- RAISE_ERROR_UNLESS( \
- WABT_SUCCEEDED( \
- ctx->reader->member \
- ? ctx->reader->member(get_user_context(ctx), __VA_ARGS__) \
- : Result::Ok), \
- #member " callback failed")
-
-#define CALLBACK_CTX0(member) \
- RAISE_ERROR_UNLESS( \
- WABT_SUCCEEDED(ctx->reader->member \
- ? ctx->reader->member(get_user_context(ctx)) \
- : Result::Ok), \
- #member " callback failed")
-
-#define CALLBACK_SECTION(member, section_size) \
- CALLBACK_CTX(member, section_size)
-
-#define CALLBACK0(member) \
- RAISE_ERROR_UNLESS( \
- WABT_SUCCEEDED(ctx->reader->member \
- ? ctx->reader->member(ctx->reader->user_data) \
- : Result::Ok), \
- #member " callback failed")
-
-#define CALLBACK(member, ...) \
- RAISE_ERROR_UNLESS( \
- WABT_SUCCEEDED( \
- ctx->reader->member \
- ? ctx->reader->member(__VA_ARGS__, ctx->reader->user_data) \
- : Result::Ok), \
- #member " callback failed")
-
-#define FORWARD0(member) \
- return ctx->reader->member ? ctx->reader->member(ctx->reader->user_data) \
- : Result::Ok
-
-#define FORWARD_CTX0(member) \
- if (!ctx->reader->member) \
- return Result::Ok; \
- BinaryReaderContext new_ctx = *context; \
- new_ctx.user_data = ctx->reader->user_data; \
- return ctx->reader->member(&new_ctx);
-
-#define FORWARD_CTX(member, ...) \
- if (!ctx->reader->member) \
- return Result::Ok; \
- BinaryReaderContext new_ctx = *context; \
- new_ctx.user_data = ctx->reader->user_data; \
- return ctx->reader->member(&new_ctx, __VA_ARGS__);
-
-#define FORWARD(member, ...) \
- return ctx->reader->member \
- ? ctx->reader->member(__VA_ARGS__, ctx->reader->user_data) \
- : Result::Ok
+#define CALLBACK0(member) \
+ RAISE_ERROR_UNLESS(WABT_SUCCEEDED(ctx->reader->member()), \
+ #member " callback failed")
+
+#define CALLBACK(member, ...) \
+ RAISE_ERROR_UNLESS(WABT_SUCCEEDED(ctx->reader->member(__VA_ARGS__)), \
+ #member " callback failed")
#define RAISE_ERROR(...) raise_error(ctx, __VA_ARGS__)
@@ -106,12 +54,9 @@ namespace {
RAISE_ERROR(__VA_ARGS__);
struct Context {
- const uint8_t* data = nullptr;
- size_t data_size = 0;
- size_t offset = 0;
size_t read_end = 0; /* Either the section end or data_size. */
- BinaryReaderContext user_ctx;
BinaryReader* reader = nullptr;
+ BinaryReader::State state;
jmp_buf error_jmp_buf;
TypeVector param_types;
std::vector<uint32_t> target_depths;
@@ -131,43 +76,26 @@ struct Context {
uint32_t num_function_bodies = 0;
};
-struct LoggingContext {
- Stream* stream;
- BinaryReader* reader;
- int indent;
-};
-
} // namespace
-static BinaryReaderContext* get_user_context(Context* ctx) {
- ctx->user_ctx.user_data = ctx->reader->user_data;
- ctx->user_ctx.data = ctx->data;
- ctx->user_ctx.size = ctx->data_size;
- ctx->user_ctx.offset = ctx->offset;
- return &ctx->user_ctx;
-}
-
static void WABT_PRINTF_FORMAT(2, 3)
raise_error(Context* ctx, const char* format, ...) {
WABT_SNPRINTF_ALLOCA(buffer, length, format);
- bool handled = false;
- if (ctx->reader->on_error) {
- handled = ctx->reader->on_error(get_user_context(ctx), buffer);
- }
+ bool handled = ctx->reader->OnError(buffer);
if (!handled) {
/* Not great to just print, but we don't want to eat the error either. */
- fprintf(stderr, "*ERROR*: @0x%08zx: %s\n", ctx->offset, buffer);
+ fprintf(stderr, "*ERROR*: @0x%08zx: %s\n", ctx->state.offset, buffer);
}
longjmp(ctx->error_jmp_buf, 1);
}
-#define IN_SIZE(type) \
- if (ctx->offset + sizeof(type) > ctx->read_end) { \
- RAISE_ERROR("unable to read " #type ": %s", desc); \
- } \
- memcpy(out_value, ctx->data + ctx->offset, sizeof(type)); \
- ctx->offset += sizeof(type)
+#define IN_SIZE(type) \
+ if (ctx->state.offset + sizeof(type) > ctx->read_end) { \
+ RAISE_ERROR("unable to read " #type ": %s", desc); \
+ } \
+ memcpy(out_value, ctx->state.data + ctx->state.offset, sizeof(type)); \
+ ctx->state.offset += sizeof(type)
static void in_u8(Context* ctx, uint8_t* out_value, const char* desc) {
IN_SIZE(uint8_t);
@@ -234,12 +162,12 @@ size_t read_u32_leb128(const uint8_t* p,
}
static void in_u32_leb128(Context* ctx, uint32_t* out_value, const char* desc) {
- const uint8_t* p = ctx->data + ctx->offset;
- const uint8_t* end = ctx->data + ctx->read_end;
+ const uint8_t* p = ctx->state.data + ctx->state.offset;
+ const uint8_t* end = ctx->state.data + ctx->read_end;
size_t bytes_read = read_u32_leb128(p, end, out_value);
if (!bytes_read)
RAISE_ERROR("unable to read u32 leb128: %s", desc);
- ctx->offset += bytes_read;
+ ctx->state.offset += bytes_read;
}
size_t read_i32_leb128(const uint8_t* p,
@@ -279,54 +207,54 @@ size_t read_i32_leb128(const uint8_t* p,
}
static void in_i32_leb128(Context* ctx, uint32_t* out_value, const char* desc) {
- const uint8_t* p = ctx->data + ctx->offset;
- const uint8_t* end = ctx->data + ctx->read_end;
+ const uint8_t* p = ctx->state.data + ctx->state.offset;
+ const uint8_t* end = ctx->state.data + ctx->read_end;
size_t bytes_read = read_i32_leb128(p, end, out_value);
if (!bytes_read)
RAISE_ERROR("unable to read i32 leb128: %s", desc);
- ctx->offset += bytes_read;
+ ctx->state.offset += bytes_read;
}
static void in_i64_leb128(Context* ctx, uint64_t* out_value, const char* desc) {
- const uint8_t* p = ctx->data + ctx->offset;
- const uint8_t* end = ctx->data + ctx->read_end;
+ const uint8_t* p = ctx->state.data + ctx->state.offset;
+ const uint8_t* end = ctx->state.data + ctx->read_end;
if (p < end && (p[0] & 0x80) == 0) {
uint64_t result = LEB128_1(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 6);
- ctx->offset += 1;
+ ctx->state.offset += 1;
} else if (p + 1 < end && (p[1] & 0x80) == 0) {
uint64_t result = LEB128_2(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 13);
- ctx->offset += 2;
+ ctx->state.offset += 2;
} else if (p + 2 < end && (p[2] & 0x80) == 0) {
uint64_t result = LEB128_3(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 20);
- ctx->offset += 3;
+ ctx->state.offset += 3;
} else if (p + 3 < end && (p[3] & 0x80) == 0) {
uint64_t result = LEB128_4(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 27);
- ctx->offset += 4;
+ ctx->state.offset += 4;
} else if (p + 4 < end && (p[4] & 0x80) == 0) {
uint64_t result = LEB128_5(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 34);
- ctx->offset += 5;
+ ctx->state.offset += 5;
} else if (p + 5 < end && (p[5] & 0x80) == 0) {
uint64_t result = LEB128_6(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 41);
- ctx->offset += 6;
+ ctx->state.offset += 6;
} else if (p + 6 < end && (p[6] & 0x80) == 0) {
uint64_t result = LEB128_7(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 48);
- ctx->offset += 7;
+ ctx->state.offset += 7;
} else if (p + 7 < end && (p[7] & 0x80) == 0) {
uint64_t result = LEB128_8(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 55);
- ctx->offset += 8;
+ ctx->state.offset += 8;
} else if (p + 8 < end && (p[8] & 0x80) == 0) {
uint64_t result = LEB128_9(uint64_t);
*out_value = SIGN_EXTEND(int64_t, result, 62);
- ctx->offset += 9;
+ ctx->state.offset += 9;
} else if (p + 9 < end && (p[9] & 0x80) == 0) {
/* the top bits should be a sign-extension of the sign bit */
bool sign_bit_set = (p[9] & 0x1);
@@ -337,7 +265,7 @@ static void in_i64_leb128(Context* ctx, uint64_t* out_value, const char* desc) {
}
uint64_t result = LEB128_10(uint64_t);
*out_value = result;
- ctx->offset += 10;
+ ctx->state.offset += 10;
} else {
/* past the end */
RAISE_ERROR("unable to read i64 leb128: %s", desc);
@@ -371,12 +299,13 @@ static void in_str(Context* ctx, StringSlice* out_str, const char* desc) {
uint32_t str_len = 0;
in_u32_leb128(ctx, &str_len, "string length");
- if (ctx->offset + str_len > ctx->read_end)
+ if (ctx->state.offset + str_len > ctx->read_end)
RAISE_ERROR("unable to read string: %s", desc);
- out_str->start = reinterpret_cast<const char*>(ctx->data) + ctx->offset;
+ out_str->start =
+ reinterpret_cast<const char*>(ctx->state.data) + ctx->state.offset;
out_str->length = str_len;
- ctx->offset += str_len;
+ ctx->state.offset += str_len;
}
static void in_bytes(Context* ctx,
@@ -386,12 +315,13 @@ static void in_bytes(Context* ctx,
uint32_t data_size = 0;
in_u32_leb128(ctx, &data_size, "data size");
- if (ctx->offset + data_size > ctx->read_end)
+ if (ctx->state.offset + data_size > ctx->read_end)
RAISE_ERROR("unable to read data: %s", desc);
- *out_data = static_cast<const uint8_t*>(ctx->data) + ctx->offset;
+ *out_data =
+ static_cast<const uint8_t*>(ctx->state.data) + ctx->state.offset;
*out_data_size = data_size;
- ctx->offset += data_size;
+ ctx->state.offset += data_size;
}
static bool is_valid_external_kind(uint8_t kind) {
@@ -431,624 +361,6 @@ static uint32_t num_total_globals(Context* ctx) {
return ctx->num_global_imports + ctx->num_globals;
}
-/* Logging */
-
-static void indent(LoggingContext* ctx) {
- ctx->indent += INDENT_SIZE;
-}
-
-static void dedent(LoggingContext* ctx) {
- ctx->indent -= INDENT_SIZE;
- assert(ctx->indent >= 0);
-}
-
-static void write_indent(LoggingContext* ctx) {
- static char s_indent[] =
- " "
- " ";
- static size_t s_indent_len = sizeof(s_indent) - 1;
- size_t indent = ctx->indent;
- while (indent > s_indent_len) {
- write_data(ctx->stream, s_indent, s_indent_len, nullptr);
- indent -= s_indent_len;
- }
- if (indent > 0) {
- write_data(ctx->stream, s_indent, indent, nullptr);
- }
-}
-
-#define LOGF_NOINDENT(...) writef(ctx->stream, __VA_ARGS__)
-
-#define LOGF(...) \
- do { \
- write_indent(ctx); \
- LOGF_NOINDENT(__VA_ARGS__); \
- } while (0)
-
-static bool logging_on_error(BinaryReaderContext* context,
- const char* message) {
- LoggingContext* ctx = static_cast<LoggingContext*>(context->user_data);
- // Can't use FORWARD_CTX because it returns Result by default.
- if (!ctx->reader->on_error)
- return false;
- BinaryReaderContext new_ctx = *context;
- new_ctx.user_data = ctx->reader->user_data;
- return ctx->reader->on_error(&new_ctx, message);
-}
-
-static Result logging_begin_section(BinaryReaderContext* context,
- BinarySection section_type,
- uint32_t size) {
- LoggingContext* ctx = static_cast<LoggingContext*>(context->user_data);
- FORWARD_CTX(begin_section, section_type, size);
-}
-
-static Result logging_begin_custom_section(BinaryReaderContext* context,
- uint32_t size,
- StringSlice section_name) {
- LoggingContext* ctx = static_cast<LoggingContext*>(context->user_data);
- LOGF("begin_custom_section: '" PRIstringslice "' size=%d\n",
- WABT_PRINTF_STRING_SLICE_ARG(section_name), size);
- indent(ctx);
- FORWARD_CTX(begin_custom_section, size, section_name);
-}
-
-#define LOGGING_BEGIN(name) \
- static Result logging_begin_##name(BinaryReaderContext* context, \
- uint32_t size) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(context->user_data); \
- LOGF("begin_" #name "(%u)\n", size); \
- indent(ctx); \
- FORWARD_CTX(begin_##name, size); \
- }
-
-#define LOGGING_END(name) \
- static Result logging_end_##name(BinaryReaderContext* context) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(context->user_data); \
- dedent(ctx); \
- LOGF("end_" #name "\n"); \
- FORWARD_CTX0(end_##name); \
- }
-
-#define LOGGING_UINT32(name) \
- static Result logging_##name(uint32_t value, void* user_data) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data); \
- LOGF(#name "(%u)\n", value); \
- FORWARD(name, value); \
- }
-
-#define LOGGING_UINT32_CTX(name) \
- static Result logging_##name(BinaryReaderContext* context, uint32_t value) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(context->user_data); \
- LOGF(#name "(%u)\n", value); \
- FORWARD_CTX(name, value); \
- }
-
-#define LOGGING_UINT32_DESC(name, desc) \
- static Result logging_##name(uint32_t value, void* user_data) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data); \
- LOGF(#name "(" desc ": %u)\n", value); \
- FORWARD(name, value); \
- }
-
-#define LOGGING_UINT32_UINT32(name, desc0, desc1) \
- static Result logging_##name(uint32_t value0, uint32_t value1, \
- void* user_data) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data); \
- LOGF(#name "(" desc0 ": %u, " desc1 ": %u)\n", value0, value1); \
- FORWARD(name, value0, value1); \
- }
-
-#define LOGGING_UINT32_UINT32_CTX(name, desc0, desc1) \
- static Result logging_##name(BinaryReaderContext* context, uint32_t value0, \
- uint32_t value1) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(context->user_data); \
- LOGF(#name "(" desc0 ": %u, " desc1 ": %u)\n", value0, value1); \
- FORWARD_CTX(name, value0, value1); \
- }
-
-#define LOGGING_OPCODE(name) \
- static Result logging_##name(Opcode opcode, void* user_data) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data); \
- LOGF(#name "(\"%s\" (%u))\n", get_opcode_name(opcode), \
- static_cast<unsigned>(opcode)); \
- FORWARD(name, opcode); \
- }
-
-#define LOGGING0(name) \
- static Result logging_##name(void* user_data) { \
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data); \
- LOGF(#name "\n"); \
- FORWARD0(name); \
- }
-
-LOGGING_UINT32(begin_module)
-LOGGING0(end_module)
-LOGGING_END(custom_section)
-LOGGING_BEGIN(signature_section)
-LOGGING_UINT32(on_signature_count)
-LOGGING_END(signature_section)
-LOGGING_BEGIN(import_section)
-LOGGING_UINT32(on_import_count)
-LOGGING_END(import_section)
-LOGGING_BEGIN(function_signatures_section)
-LOGGING_UINT32(on_function_signatures_count)
-LOGGING_UINT32_UINT32(on_function_signature, "index", "sig_index")
-LOGGING_END(function_signatures_section)
-LOGGING_BEGIN(table_section)
-LOGGING_UINT32(on_table_count)
-LOGGING_END(table_section)
-LOGGING_BEGIN(memory_section)
-LOGGING_UINT32(on_memory_count)
-LOGGING_END(memory_section)
-LOGGING_BEGIN(global_section)
-LOGGING_UINT32(on_global_count)
-LOGGING_UINT32(begin_global_init_expr)
-LOGGING_UINT32(end_global_init_expr)
-LOGGING_UINT32(end_global)
-LOGGING_END(global_section)
-LOGGING_BEGIN(export_section)
-LOGGING_UINT32(on_export_count)
-LOGGING_END(export_section)
-LOGGING_BEGIN(start_section)
-LOGGING_UINT32(on_start_function)
-LOGGING_END(start_section)
-LOGGING_BEGIN(function_bodies_section)
-LOGGING_UINT32(on_function_bodies_count)
-LOGGING_UINT32_CTX(begin_function_body)
-LOGGING_UINT32(end_function_body)
-LOGGING_UINT32(on_local_decl_count)
-LOGGING_OPCODE(on_binary_expr)
-LOGGING_UINT32_DESC(on_call_expr, "func_index")
-LOGGING_UINT32_DESC(on_call_import_expr, "import_index")
-LOGGING_UINT32_DESC(on_call_indirect_expr, "sig_index")
-LOGGING_OPCODE(on_compare_expr)
-LOGGING_OPCODE(on_convert_expr)
-LOGGING0(on_current_memory_expr)
-LOGGING0(on_drop_expr)
-LOGGING0(on_else_expr)
-LOGGING0(on_end_expr)
-LOGGING_UINT32_DESC(on_get_global_expr, "index")
-LOGGING_UINT32_DESC(on_get_local_expr, "index")
-LOGGING0(on_grow_memory_expr)
-LOGGING0(on_nop_expr)
-LOGGING0(on_return_expr)
-LOGGING0(on_select_expr)
-LOGGING_UINT32_DESC(on_set_global_expr, "index")
-LOGGING_UINT32_DESC(on_set_local_expr, "index")
-LOGGING_UINT32_DESC(on_tee_local_expr, "index")
-LOGGING0(on_unreachable_expr)
-LOGGING_OPCODE(on_unary_expr)
-LOGGING_END(function_bodies_section)
-LOGGING_BEGIN(elem_section)
-LOGGING_UINT32(on_elem_segment_count)
-LOGGING_UINT32_UINT32(begin_elem_segment, "index", "table_index")
-LOGGING_UINT32(begin_elem_segment_init_expr)
-LOGGING_UINT32(end_elem_segment_init_expr)
-LOGGING_UINT32_UINT32_CTX(on_elem_segment_function_index_count,
- "index",
- "count")
-LOGGING_UINT32_UINT32(on_elem_segment_function_index, "index", "func_index")
-LOGGING_UINT32(end_elem_segment)
-LOGGING_END(elem_section)
-LOGGING_BEGIN(data_section)
-LOGGING_UINT32(on_data_segment_count)
-LOGGING_UINT32_UINT32(begin_data_segment, "index", "memory_index")
-LOGGING_UINT32(begin_data_segment_init_expr)
-LOGGING_UINT32(end_data_segment_init_expr)
-LOGGING_UINT32(end_data_segment)
-LOGGING_END(data_section)
-LOGGING_BEGIN(names_section)
-LOGGING_UINT32(on_function_names_count)
-LOGGING_UINT32(on_local_name_function_count)
-LOGGING_UINT32_UINT32(on_local_name_local_count, "index", "count")
-LOGGING_END(names_section)
-LOGGING_BEGIN(reloc_section)
-LOGGING_END(reloc_section)
-LOGGING_UINT32_UINT32(on_init_expr_get_global_expr, "index", "global_index")
-
-static void sprint_limits(char* dst, size_t size, const Limits* limits) {
- int result;
- if (limits->has_max) {
- result = wabt_snprintf(dst, size, "initial: %" PRIu64 ", max: %" PRIu64,
- limits->initial, limits->max);
- } else {
- result = wabt_snprintf(dst, size, "initial: %" PRIu64, limits->initial);
- }
- WABT_USE(result);
- assert(static_cast<size_t>(result) < size);
-}
-
-static void log_types(LoggingContext* ctx, uint32_t type_count, Type* types) {
- LOGF_NOINDENT("[");
- for (uint32_t i = 0; i < type_count; ++i) {
- LOGF_NOINDENT("%s", get_type_name(types[i]));
- if (i != type_count - 1)
- LOGF_NOINDENT(", ");
- }
- LOGF_NOINDENT("]");
-}
-
-static Result logging_on_signature(uint32_t index,
- uint32_t param_count,
- Type* param_types,
- uint32_t result_count,
- Type* result_types,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_signature(index: %u, params: ", index);
- log_types(ctx, param_count, param_types);
- LOGF_NOINDENT(", results: ");
- log_types(ctx, result_count, result_types);
- LOGF_NOINDENT(")\n");
- FORWARD(on_signature, index, param_count, param_types, result_count,
- result_types);
-}
-
-static Result logging_on_import(uint32_t index,
- StringSlice module_name,
- StringSlice field_name,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_import(index: %u, module: \"" PRIstringslice
- "\", field: \"" PRIstringslice "\")\n",
- index, WABT_PRINTF_STRING_SLICE_ARG(module_name),
- WABT_PRINTF_STRING_SLICE_ARG(field_name));
- FORWARD(on_import, index, module_name, field_name);
-}
-
-static Result logging_on_import_func(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t func_index,
- uint32_t sig_index,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_import_func(import_index: %u, func_index: %u, sig_index: %u)\n",
- import_index, func_index, sig_index);
- FORWARD(on_import_func, import_index, module_name, field_name,
- func_index, sig_index);
-}
-
-static Result logging_on_import_table(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t table_index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- char buf[100];
- sprint_limits(buf, sizeof(buf), elem_limits);
- LOGF(
- "on_import_table(import_index: %u, table_index: %u, elem_type: %s, %s)\n",
- import_index, table_index, get_type_name(elem_type), buf);
- FORWARD(on_import_table, import_index, module_name, field_name,
- table_index, elem_type, elem_limits);
-}
-
-static Result logging_on_import_memory(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t memory_index,
- const Limits* page_limits,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- char buf[100];
- sprint_limits(buf, sizeof(buf), page_limits);
- LOGF("on_import_memory(import_index: %u, memory_index: %u, %s)\n",
- import_index, memory_index, buf);
- FORWARD(on_import_memory, import_index, module_name, field_name,
- memory_index, page_limits);
-}
-
-static Result logging_on_import_global(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t global_index,
- Type type,
- bool mutable_,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF(
- "on_import_global(import_index: %u, global_index: %u, type: %s, mutable: "
- "%s)\n",
- import_index, global_index, get_type_name(type),
- mutable_ ? "true" : "false");
- FORWARD(on_import_global, import_index, module_name, field_name,
- global_index, type, mutable_);
-}
-
-static Result logging_on_table(uint32_t index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- char buf[100];
- sprint_limits(buf, sizeof(buf), elem_limits);
- LOGF("on_table(index: %u, elem_type: %s, %s)\n", index,
- get_type_name(elem_type), buf);
- FORWARD(on_table, index, elem_type, elem_limits);
-}
-
-static Result logging_on_memory(uint32_t index,
- const Limits* page_limits,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- char buf[100];
- sprint_limits(buf, sizeof(buf), page_limits);
- LOGF("on_memory(index: %u, %s)\n", index, buf);
- FORWARD(on_memory, index, page_limits);
-}
-
-static Result logging_begin_global(uint32_t index,
- Type type,
- bool mutable_,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("begin_global(index: %u, type: %s, mutable: %s)\n", index,
- get_type_name(type), mutable_ ? "true" : "false");
- FORWARD(begin_global, index, type, mutable_);
-}
-
-static Result logging_on_export(uint32_t index,
- ExternalKind kind,
- uint32_t item_index,
- StringSlice name,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_export(index: %u, kind: %s, item_index: %u, name: \"" PRIstringslice
- "\")\n",
- index, get_kind_name(kind), item_index,
- WABT_PRINTF_STRING_SLICE_ARG(name));
- FORWARD(on_export, index, kind, item_index, name);
-}
-
-static Result logging_begin_function_body_pass(uint32_t index,
- uint32_t pass,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("begin_function_body_pass(index: %u, pass: %u)\n", index, pass);
- indent(ctx);
- FORWARD(begin_function_body_pass, index, pass);
-}
-
-static Result logging_on_local_decl(uint32_t decl_index,
- uint32_t count,
- Type type,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_local_decl(index: %u, count: %u, type: %s)\n", decl_index, count,
- get_type_name(type));
- FORWARD(on_local_decl, decl_index, count, type);
-}
-
-static Result logging_on_block_expr(uint32_t num_types,
- Type* sig_types,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_block_expr(sig: ");
- log_types(ctx, num_types, sig_types);
- LOGF_NOINDENT(")\n");
- FORWARD(on_block_expr, num_types, sig_types);
-}
-
-static Result logging_on_br_expr(uint32_t depth, void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_br_expr(depth: %u)\n", depth);
- FORWARD(on_br_expr, depth);
-}
-
-static Result logging_on_br_if_expr(uint32_t depth, void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_br_if_expr(depth: %u)\n", depth);
- FORWARD(on_br_if_expr, depth);
-}
-
-static Result logging_on_br_table_expr(BinaryReaderContext* context,
- uint32_t num_targets,
- uint32_t* target_depths,
- uint32_t default_target_depth) {
- LoggingContext* ctx = static_cast<LoggingContext*>(context->user_data);
- LOGF("on_br_table_expr(num_targets: %u, depths: [", num_targets);
- for (uint32_t i = 0; i < num_targets; ++i) {
- LOGF_NOINDENT("%u", target_depths[i]);
- if (i != num_targets - 1)
- LOGF_NOINDENT(", ");
- }
- LOGF_NOINDENT("], default: %u)\n", default_target_depth);
- FORWARD_CTX(on_br_table_expr, num_targets, target_depths,
- default_target_depth);
-}
-
-static Result logging_on_f32_const_expr(uint32_t value_bits, void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- float value;
- memcpy(&value, &value_bits, sizeof(value));
- LOGF("on_f32_const_expr(%g (0x04%x))\n", value, value_bits);
- FORWARD(on_f32_const_expr, value_bits);
-}
-
-static Result logging_on_f64_const_expr(uint64_t value_bits, void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- double value;
- memcpy(&value, &value_bits, sizeof(value));
- LOGF("on_f64_const_expr(%g (0x08%" PRIx64 "))\n", value, value_bits);
- FORWARD(on_f64_const_expr, value_bits);
-}
-
-static Result logging_on_i32_const_expr(uint32_t value, void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_i32_const_expr(%u (0x%x))\n", value, value);
- FORWARD(on_i32_const_expr, value);
-}
-
-static Result logging_on_i64_const_expr(uint64_t value, void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_i64_const_expr(%" PRIu64 " (0x%" PRIx64 "))\n", value, value);
- FORWARD(on_i64_const_expr, value);
-}
-
-static Result logging_on_if_expr(uint32_t num_types,
- Type* sig_types,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_if_expr(sig: ");
- log_types(ctx, num_types, sig_types);
- LOGF_NOINDENT(")\n");
- FORWARD(on_if_expr, num_types, sig_types);
-}
-
-static Result logging_on_load_expr(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_load_expr(opcode: \"%s\" (%u), align log2: %u, offset: %u)\n",
- get_opcode_name(opcode), static_cast<unsigned>(opcode), alignment_log2,
- offset);
- FORWARD(on_load_expr, opcode, alignment_log2, offset);
-}
-
-static Result logging_on_loop_expr(uint32_t num_types,
- Type* sig_types,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_loop_expr(sig: ");
- log_types(ctx, num_types, sig_types);
- LOGF_NOINDENT(")\n");
- FORWARD(on_loop_expr, num_types, sig_types);
-}
-
-static Result logging_on_store_expr(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_store_expr(opcode: \"%s\" (%u), align log2: %u, offset: %u)\n",
- get_opcode_name(opcode), static_cast<unsigned>(opcode), alignment_log2,
- offset);
- FORWARD(on_store_expr, opcode, alignment_log2, offset);
-}
-
-static Result logging_end_function_body_pass(uint32_t index,
- uint32_t pass,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- dedent(ctx);
- LOGF("end_function_body_pass(index: %u, pass: %u)\n", index, pass);
- FORWARD(end_function_body_pass, index, pass);
-}
-
-static Result logging_on_data_segment_data(uint32_t index,
- const void* data,
- uint32_t size,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_data_segment_data(index:%u, size:%u)\n", index, size);
- FORWARD(on_data_segment_data, index, data, size);
-}
-
-static Result logging_on_function_name_subsection(uint32_t index,
- uint32_t name_type,
- uint32_t subsection_size,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_function_name_subsection(index:%u, nametype:%u, size:%u)\n", index, name_type, subsection_size);
- FORWARD(on_function_name_subsection, index, name_type, subsection_size);
-}
-
-static Result logging_on_function_name(uint32_t index,
- StringSlice name,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_function_name(index: %u, name: \"" PRIstringslice "\")\n", index,
- WABT_PRINTF_STRING_SLICE_ARG(name));
- FORWARD(on_function_name, index, name);
-}
-
-static Result logging_on_local_name_subsection(uint32_t index,
- uint32_t name_type,
- uint32_t subsection_size,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_local_name_subsection(index:%u, nametype:%u, size:%u)\n", index, name_type, subsection_size);
- FORWARD(on_local_name_subsection, index, name_type, subsection_size);
-}
-
-static Result logging_on_local_name(uint32_t func_index,
- uint32_t local_index,
- StringSlice name,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_local_name(func_index: %u, local_index: %u, name: \"" PRIstringslice
- "\")\n",
- func_index, local_index, WABT_PRINTF_STRING_SLICE_ARG(name));
- FORWARD(on_local_name, func_index, local_index, name);
-}
-
-static Result logging_on_init_expr_f32_const_expr(uint32_t index,
- uint32_t value_bits,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- float value;
- memcpy(&value, &value_bits, sizeof(value));
- LOGF("on_init_expr_f32_const_expr(index: %u, value: %g (0x04%x))\n", index,
- value, value_bits);
- FORWARD(on_init_expr_f32_const_expr, index, value_bits);
-}
-
-static Result logging_on_init_expr_f64_const_expr(uint32_t index,
- uint64_t value_bits,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- double value;
- memcpy(&value, &value_bits, sizeof(value));
- LOGF("on_init_expr_f64_const_expr(index: %u value: %g (0x08%" PRIx64 "))\n",
- index, value, value_bits);
- FORWARD(on_init_expr_f64_const_expr, index, value_bits);
-}
-
-static Result logging_on_init_expr_i32_const_expr(uint32_t index,
- uint32_t value,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_init_expr_i32_const_expr(index: %u, value: %u)\n", index, value);
- FORWARD(on_init_expr_i32_const_expr, index, value);
-}
-
-static Result logging_on_init_expr_i64_const_expr(uint32_t index,
- uint64_t value,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_init_expr_i64_const_expr(index: %u, value: %" PRIu64 ")\n", index,
- value);
- FORWARD(on_init_expr_i64_const_expr, index, value);
-}
-
-static Result logging_on_reloc_count(uint32_t count,
- BinarySection section_code,
- StringSlice section_name,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_reloc_count(count: %d, section: %s, section_name: " PRIstringslice
- ")\n",
- count, get_section_name(section_code),
- WABT_PRINTF_STRING_SLICE_ARG(section_name));
- FORWARD(on_reloc_count, count, section_code, section_name);
-}
-
-static Result logging_on_reloc(RelocType type,
- uint32_t offset,
- uint32_t index,
- int32_t addend,
- void* user_data) {
- LoggingContext* ctx = static_cast<LoggingContext*>(user_data);
- LOGF("on_reloc(type: %s, offset: %u, index: %u, addend: %d)\n",
- get_reloc_type_name(type), offset, index, addend);
- FORWARD(on_reloc, type, offset, index, addend);
-}
-
static void read_init_expr(Context* ctx, uint32_t index) {
uint8_t opcode;
in_u8(ctx, &opcode, "opcode");
@@ -1056,35 +368,35 @@ static void read_init_expr(Context* ctx, uint32_t index) {
case Opcode::I32Const: {
uint32_t value = 0;
in_i32_leb128(ctx, &value, "init_expr i32.const value");
- CALLBACK(on_init_expr_i32_const_expr, index, value);
+ CALLBACK(OnInitExprI32ConstExpr, index, value);
break;
}
case Opcode::I64Const: {
uint64_t value = 0;
in_i64_leb128(ctx, &value, "init_expr i64.const value");
- CALLBACK(on_init_expr_i64_const_expr, index, value);
+ CALLBACK(OnInitExprI64ConstExpr, index, value);
break;
}
case Opcode::F32Const: {
uint32_t value_bits = 0;
in_f32(ctx, &value_bits, "init_expr f32.const value");
- CALLBACK(on_init_expr_f32_const_expr, index, value_bits);
+ CALLBACK(OnInitExprF32ConstExpr, index, value_bits);
break;
}
case Opcode::F64Const: {
uint64_t value_bits = 0;
in_f64(ctx, &value_bits, "init_expr f64.const value");
- CALLBACK(on_init_expr_f64_const_expr, index, value_bits);
+ CALLBACK(OnInitExprF64ConstExpr, index, value_bits);
break;
}
case Opcode::GetGlobal: {
uint32_t global_index;
in_u32_leb128(ctx, &global_index, "init_expr get_global index");
- CALLBACK(on_init_expr_get_global_expr, index, global_index);
+ CALLBACK(OnInitExprGetGlobalExpr, index, global_index);
break;
}
@@ -1164,15 +476,15 @@ static void read_global_header(Context* ctx,
static void read_function_body(Context* ctx, uint32_t end_offset) {
bool seen_end_opcode = false;
- while (ctx->offset < end_offset) {
+ while (ctx->state.offset < end_offset) {
uint8_t opcode_u8;
in_u8(ctx, &opcode_u8, "opcode");
Opcode opcode = static_cast<Opcode>(opcode_u8);
- CALLBACK_CTX(on_opcode, opcode);
+ CALLBACK(OnOpcode, opcode);
switch (opcode) {
case Opcode::Unreachable:
- CALLBACK0(on_unreachable_expr);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK0(OnUnreachableExpr);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::Block: {
@@ -1181,8 +493,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
"expected valid block signature type");
uint32_t num_types = sig_type == Type::Void ? 0 : 1;
- CALLBACK(on_block_expr, num_types, &sig_type);
- CALLBACK_CTX(on_opcode_block_sig, num_types, &sig_type);
+ CALLBACK(OnBlockExpr, num_types, &sig_type);
+ CALLBACK(OnOpcodeBlockSig, num_types, &sig_type);
break;
}
@@ -1192,8 +504,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
"expected valid block signature type");
uint32_t num_types = sig_type == Type::Void ? 0 : 1;
- CALLBACK(on_loop_expr, num_types, &sig_type);
- CALLBACK_CTX(on_opcode_block_sig, num_types, &sig_type);
+ CALLBACK(OnLoopExpr, num_types, &sig_type);
+ CALLBACK(OnOpcodeBlockSig, num_types, &sig_type);
break;
}
@@ -1203,34 +515,34 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
RAISE_ERROR_UNLESS(is_inline_sig_type(sig_type),
"expected valid block signature type");
uint32_t num_types = sig_type == Type::Void ? 0 : 1;
- CALLBACK(on_if_expr, num_types, &sig_type);
- CALLBACK_CTX(on_opcode_block_sig, num_types, &sig_type);
+ CALLBACK(OnIfExpr, num_types, &sig_type);
+ CALLBACK(OnOpcodeBlockSig, num_types, &sig_type);
break;
}
case Opcode::Else:
- CALLBACK0(on_else_expr);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK0(OnElseExpr);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::Select:
- CALLBACK0(on_select_expr);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK0(OnSelectExpr);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::Br: {
uint32_t depth;
in_u32_leb128(ctx, &depth, "br depth");
- CALLBACK(on_br_expr, depth);
- CALLBACK_CTX(on_opcode_uint32, depth);
+ CALLBACK(OnBrExpr, depth);
+ CALLBACK(OnOpcodeUint32, depth);
break;
}
case Opcode::BrIf: {
uint32_t depth;
in_u32_leb128(ctx, &depth, "br_if depth");
- CALLBACK(on_br_if_expr, depth);
- CALLBACK_CTX(on_opcode_uint32, depth);
+ CALLBACK(OnBrIfExpr, depth);
+ CALLBACK(OnOpcodeUint32, depth);
break;
}
@@ -1252,96 +564,96 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
uint32_t* target_depths =
num_targets ? ctx->target_depths.data() : nullptr;
- CALLBACK_CTX(on_br_table_expr, num_targets, target_depths,
- default_target_depth);
+ CALLBACK(OnBrTableExpr, num_targets, target_depths,
+ default_target_depth);
break;
}
case Opcode::Return:
- CALLBACK0(on_return_expr);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK0(OnReturnExpr);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::Nop:
- CALLBACK0(on_nop_expr);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK0(OnNopExpr);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::Drop:
- CALLBACK0(on_drop_expr);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK0(OnDropExpr);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::End:
- if (ctx->offset == end_offset) {
+ if (ctx->state.offset == end_offset) {
seen_end_opcode = true;
- CALLBACK0(on_end_func);
+ CALLBACK0(OnEndFunc);
} else {
- CALLBACK0(on_end_expr);
+ CALLBACK0(OnEndExpr);
}
break;
case Opcode::I32Const: {
uint32_t value = 0;
in_i32_leb128(ctx, &value, "i32.const value");
- CALLBACK(on_i32_const_expr, value);
- CALLBACK_CTX(on_opcode_uint32, value);
+ CALLBACK(OnI32ConstExpr, value);
+ CALLBACK(OnOpcodeUint32, value);
break;
}
case Opcode::I64Const: {
uint64_t value = 0;
in_i64_leb128(ctx, &value, "i64.const value");
- CALLBACK(on_i64_const_expr, value);
- CALLBACK_CTX(on_opcode_uint64, value);
+ CALLBACK(OnI64ConstExpr, value);
+ CALLBACK(OnOpcodeUint64, value);
break;
}
case Opcode::F32Const: {
uint32_t value_bits = 0;
in_f32(ctx, &value_bits, "f32.const value");
- CALLBACK(on_f32_const_expr, value_bits);
- CALLBACK_CTX(on_opcode_f32, value_bits);
+ CALLBACK(OnF32ConstExpr, value_bits);
+ CALLBACK(OnOpcodeF32, value_bits);
break;
}
case Opcode::F64Const: {
uint64_t value_bits = 0;
in_f64(ctx, &value_bits, "f64.const value");
- CALLBACK(on_f64_const_expr, value_bits);
- CALLBACK_CTX(on_opcode_f64, value_bits);
+ CALLBACK(OnF64ConstExpr, value_bits);
+ CALLBACK(OnOpcodeF64, value_bits);
break;
}
case Opcode::GetGlobal: {
uint32_t global_index;
in_u32_leb128(ctx, &global_index, "get_global global index");
- CALLBACK(on_get_global_expr, global_index);
- CALLBACK_CTX(on_opcode_uint32, global_index);
+ CALLBACK(OnGetGlobalExpr, global_index);
+ CALLBACK(OnOpcodeUint32, global_index);
break;
}
case Opcode::GetLocal: {
uint32_t local_index;
in_u32_leb128(ctx, &local_index, "get_local local index");
- CALLBACK(on_get_local_expr, local_index);
- CALLBACK_CTX(on_opcode_uint32, local_index);
+ CALLBACK(OnGetLocalExpr, local_index);
+ CALLBACK(OnOpcodeUint32, local_index);
break;
}
case Opcode::SetGlobal: {
uint32_t global_index;
in_u32_leb128(ctx, &global_index, "set_global global index");
- CALLBACK(on_set_global_expr, global_index);
- CALLBACK_CTX(on_opcode_uint32, global_index);
+ CALLBACK(OnSetGlobalExpr, global_index);
+ CALLBACK(OnOpcodeUint32, global_index);
break;
}
case Opcode::SetLocal: {
uint32_t local_index;
in_u32_leb128(ctx, &local_index, "set_local local index");
- CALLBACK(on_set_local_expr, local_index);
- CALLBACK_CTX(on_opcode_uint32, local_index);
+ CALLBACK(OnSetLocalExpr, local_index);
+ CALLBACK(OnOpcodeUint32, local_index);
break;
}
@@ -1350,8 +662,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
in_u32_leb128(ctx, &func_index, "call function index");
RAISE_ERROR_UNLESS(func_index < num_total_funcs(ctx),
"invalid call function index");
- CALLBACK(on_call_expr, func_index);
- CALLBACK_CTX(on_opcode_uint32, func_index);
+ CALLBACK(OnCallExpr, func_index);
+ CALLBACK(OnOpcodeUint32, func_index);
break;
}
@@ -1364,16 +676,16 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
in_u32_leb128(ctx, &reserved, "call_indirect reserved");
RAISE_ERROR_UNLESS(reserved == 0,
"call_indirect reserved value must be 0");
- CALLBACK(on_call_indirect_expr, sig_index);
- CALLBACK_CTX(on_opcode_uint32_uint32, sig_index, reserved);
+ CALLBACK(OnCallIndirectExpr, sig_index);
+ CALLBACK(OnOpcodeUint32Uint32, sig_index, reserved);
break;
}
case Opcode::TeeLocal: {
uint32_t local_index;
in_u32_leb128(ctx, &local_index, "tee_local local index");
- CALLBACK(on_tee_local_expr, local_index);
- CALLBACK_CTX(on_opcode_uint32, local_index);
+ CALLBACK(OnTeeLocalExpr, local_index);
+ CALLBACK(OnOpcodeUint32, local_index);
break;
}
@@ -1396,8 +708,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
uint32_t offset;
in_u32_leb128(ctx, &offset, "load offset");
- CALLBACK(on_load_expr, opcode, alignment_log2, offset);
- CALLBACK_CTX(on_opcode_uint32_uint32, alignment_log2, offset);
+ CALLBACK(OnLoadExpr, opcode, alignment_log2, offset);
+ CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
break;
}
@@ -1415,8 +727,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
uint32_t offset;
in_u32_leb128(ctx, &offset, "store offset");
- CALLBACK(on_store_expr, opcode, alignment_log2, offset);
- CALLBACK_CTX(on_opcode_uint32_uint32, alignment_log2, offset);
+ CALLBACK(OnStoreExpr, opcode, alignment_log2, offset);
+ CALLBACK(OnOpcodeUint32Uint32, alignment_log2, offset);
break;
}
@@ -1425,8 +737,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
in_u32_leb128(ctx, &reserved, "current_memory reserved");
RAISE_ERROR_UNLESS(reserved == 0,
"current_memory reserved value must be 0");
- CALLBACK0(on_current_memory_expr);
- CALLBACK_CTX(on_opcode_uint32, reserved);
+ CALLBACK0(OnCurrentMemoryExpr);
+ CALLBACK(OnOpcodeUint32, reserved);
break;
}
@@ -1435,8 +747,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
in_u32_leb128(ctx, &reserved, "grow_memory reserved");
RAISE_ERROR_UNLESS(reserved == 0,
"grow_memory reserved value must be 0");
- CALLBACK0(on_grow_memory_expr);
- CALLBACK_CTX(on_opcode_uint32, reserved);
+ CALLBACK0(OnGrowMemoryExpr);
+ CALLBACK(OnOpcodeUint32, reserved);
break;
}
@@ -1484,8 +796,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
case Opcode::F64Min:
case Opcode::F64Max:
case Opcode::F64Copysign:
- CALLBACK(on_binary_expr, opcode);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK(OnBinaryExpr, opcode);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::I32Eq:
@@ -1520,8 +832,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
case Opcode::F64Le:
case Opcode::F64Gt:
case Opcode::F64Ge:
- CALLBACK(on_compare_expr, opcode);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK(OnCompareExpr, opcode);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::I32Clz:
@@ -1544,8 +856,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
case Opcode::F64Trunc:
case Opcode::F64Nearest:
case Opcode::F64Sqrt:
- CALLBACK(on_unary_expr, opcode);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK(OnUnaryExpr, opcode);
+ CALLBACK0(OnOpcodeBare);
break;
case Opcode::I32TruncSF32:
@@ -1575,8 +887,8 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
case Opcode::I64ReinterpretF64:
case Opcode::I32Eqz:
case Opcode::I64Eqz:
- CALLBACK(on_convert_expr, opcode);
- CALLBACK_CTX0(on_opcode_bare);
+ CALLBACK(OnConvertExpr, opcode);
+ CALLBACK0(OnOpcodeBare);
break;
default:
@@ -1584,7 +896,7 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
static_cast<unsigned>(opcode));
}
}
- RAISE_ERROR_UNLESS(ctx->offset == end_offset,
+ RAISE_ERROR_UNLESS(ctx->state.offset == end_offset,
"function body longer than given size");
RAISE_ERROR_UNLESS(seen_end_opcode, "function body must end with END opcode");
}
@@ -1592,17 +904,17 @@ static void read_function_body(Context* ctx, uint32_t end_offset) {
static void read_custom_section(Context* ctx, uint32_t section_size) {
StringSlice section_name;
in_str(ctx, &section_name, "section name");
- CALLBACK_CTX(begin_custom_section, section_size, section_name);
+ CALLBACK(BeginCustomSection, section_size, section_name);
bool name_section_ok = ctx->last_known_section >= BinarySection::Import;
if (ctx->options->read_debug_names && name_section_ok &&
strncmp(section_name.start, WABT_BINARY_SECTION_NAME,
section_name.length) == 0) {
- CALLBACK_SECTION(begin_names_section, section_size);
+ CALLBACK(BeginNamesSection, section_size);
uint32_t i = 0;
size_t previous_read_end = ctx->read_end;
uint32_t previous_subsection_type = 0;
- while (ctx->offset < ctx->read_end) {
+ while (ctx->state.offset < ctx->read_end) {
uint32_t name_type;
uint32_t subsection_size;
in_u32_leb128(ctx, &name_type, "name type");
@@ -1614,74 +926,74 @@ static void read_custom_section(Context* ctx, uint32_t section_size) {
}
previous_subsection_type = name_type;
in_u32_leb128(ctx, &subsection_size, "subsection size");
- size_t subsection_end = ctx->offset + subsection_size;
+ size_t subsection_end = ctx->state.offset + subsection_size;
if (subsection_end > ctx->read_end)
RAISE_ERROR("invalid sub-section size: extends past end");
ctx->read_end = subsection_end;
switch (static_cast<NameSectionSubsection>(name_type)) {
case NameSectionSubsection::Function:
- CALLBACK(on_function_name_subsection, i, name_type, subsection_size);
+ CALLBACK(OnFunctionNameSubsection, i, name_type, subsection_size);
if (subsection_size) {
uint32_t num_names;
in_u32_leb128(ctx, &num_names, "name count");
- CALLBACK(on_function_names_count, num_names);
+ CALLBACK(OnFunctionNamesCount, num_names);
for (uint32_t j = 0; j < num_names; ++j) {
uint32_t function_index;
StringSlice function_name;
in_u32_leb128(ctx, &function_index, "function index");
in_str(ctx, &function_name, "function name");
- CALLBACK(on_function_name, function_index, function_name);
+ CALLBACK(OnFunctionName, function_index, function_name);
}
}
break;
case NameSectionSubsection::Local:
- CALLBACK(on_local_name_subsection, i, name_type, subsection_size);
+ CALLBACK(OnLocalNameSubsection, i, name_type, subsection_size);
if (subsection_size) {
uint32_t num_funcs;
in_u32_leb128(ctx, &num_funcs, "function count");
- CALLBACK(on_local_name_function_count, num_funcs);
+ CALLBACK(OnLocalNameFunctionCount, num_funcs);
for (uint32_t j = 0; j < num_funcs; ++j) {
uint32_t function_index;
in_u32_leb128(ctx, &function_index, "function index");
uint32_t num_locals;
in_u32_leb128(ctx, &num_locals, "local count");
- CALLBACK(on_local_name_local_count, function_index, num_locals);
+ CALLBACK(OnLocalNameLocalCount, function_index, num_locals);
for (uint32_t k = 0; k < num_locals; ++k) {
uint32_t local_index;
StringSlice local_name;
in_u32_leb128(ctx, &local_index, "named index");
in_str(ctx, &local_name, "name");
- CALLBACK(on_local_name, function_index, local_index, local_name);
+ CALLBACK(OnLocalName, function_index, local_index, local_name);
}
}
}
break;
default:
/* unknown subsection, skip it */
- ctx->offset = subsection_end;
+ ctx->state.offset = subsection_end;
break;
}
++i;
- if (ctx->offset != subsection_end) {
+ if (ctx->state.offset != subsection_end) {
RAISE_ERROR("unfinished sub-section (expected end: 0x%" PRIzx ")",
subsection_end);
}
ctx->read_end = previous_read_end;
}
- CALLBACK_CTX0(end_names_section);
+ CALLBACK0(EndNamesSection);
} else if (strncmp(section_name.start, WABT_BINARY_SECTION_RELOC,
strlen(WABT_BINARY_SECTION_RELOC)) == 0) {
- CALLBACK_SECTION(begin_reloc_section, section_size);
+ CALLBACK(BeginRelocSection, section_size);
uint32_t num_relocs, section;
in_u32_leb128(ctx, &section, "section");
WABT_ZERO_MEMORY(section_name);
if (static_cast<BinarySection>(section) == BinarySection::Custom)
in_str(ctx, &section_name, "section name");
in_u32_leb128(ctx, &num_relocs, "relocation count");
- CALLBACK(on_reloc_count, num_relocs, static_cast<BinarySection>(section),
+ CALLBACK(OnRelocCount, num_relocs, static_cast<BinarySection>(section),
section_name);
for (uint32_t i = 0; i < num_relocs; ++i) {
uint32_t reloc_type, offset, index, addend = 0;
@@ -1698,20 +1010,20 @@ static void read_custom_section(Context* ctx, uint32_t section_size) {
default:
break;
}
- CALLBACK(on_reloc, type, offset, index, addend);
+ CALLBACK(OnReloc, type, offset, index, addend);
}
- CALLBACK_CTX0(end_reloc_section);
+ CALLBACK0(EndRelocSection);
} else {
/* This is an unknown custom section, skip it. */
- ctx->offset = ctx->read_end;
+ ctx->state.offset = ctx->read_end;
}
- CALLBACK_CTX0(end_custom_section);
+ CALLBACK0(EndCustomSection);
}
static void read_type_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_signature_section, section_size);
+ CALLBACK(BeginTypeSection, section_size);
in_u32_leb128(ctx, &ctx->num_signatures, "type count");
- CALLBACK(on_signature_count, ctx->num_signatures);
+ CALLBACK(OnTypeCount, ctx->num_signatures);
for (uint32_t i = 0; i < ctx->num_signatures; ++i) {
Type form;
@@ -1747,16 +1059,15 @@ static void read_type_section(Context* ctx, uint32_t section_size) {
Type* param_types = num_params ? ctx->param_types.data() : nullptr;
- CALLBACK(on_signature, i, num_params, param_types, num_results,
- &result_type);
+ CALLBACK(OnType, i, num_params, param_types, num_results, &result_type);
}
- CALLBACK_CTX0(end_signature_section);
+ CALLBACK0(EndTypeSection);
}
static void read_import_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_import_section, section_size);
+ CALLBACK(BeginImportSection, section_size);
in_u32_leb128(ctx, &ctx->num_imports, "import count");
- CALLBACK(on_import_count, ctx->num_imports);
+ CALLBACK(OnImportCount, ctx->num_imports);
for (uint32_t i = 0; i < ctx->num_imports; ++i) {
StringSlice module_name;
in_str(ctx, &module_name, "import module name");
@@ -1771,8 +1082,8 @@ static void read_import_section(Context* ctx, uint32_t section_size) {
in_u32_leb128(ctx, &sig_index, "import signature index");
RAISE_ERROR_UNLESS(sig_index < ctx->num_signatures,
"invalid import signature index");
- CALLBACK(on_import, i, module_name, field_name);
- CALLBACK(on_import_func, i, module_name, field_name,
+ CALLBACK(OnImport, i, module_name, field_name);
+ CALLBACK(OnImportFunc, i, module_name, field_name,
ctx->num_func_imports, sig_index);
ctx->num_func_imports++;
break;
@@ -1782,8 +1093,8 @@ static void read_import_section(Context* ctx, uint32_t section_size) {
Type elem_type;
Limits elem_limits;
read_table(ctx, &elem_type, &elem_limits);
- CALLBACK(on_import, i, module_name, field_name);
- CALLBACK(on_import_table, i, module_name, field_name,
+ CALLBACK(OnImport, i, module_name, field_name);
+ CALLBACK(OnImportTable, i, module_name, field_name,
ctx->num_table_imports, elem_type, &elem_limits);
ctx->num_table_imports++;
break;
@@ -1792,8 +1103,8 @@ static void read_import_section(Context* ctx, uint32_t section_size) {
case ExternalKind::Memory: {
Limits page_limits;
read_memory(ctx, &page_limits);
- CALLBACK(on_import, i, module_name, field_name);
- CALLBACK(on_import_memory, i, module_name, field_name,
+ CALLBACK(OnImport, i, module_name, field_name);
+ CALLBACK(OnImportMemory, i, module_name, field_name,
ctx->num_memory_imports, &page_limits);
ctx->num_memory_imports++;
break;
@@ -1803,8 +1114,8 @@ static void read_import_section(Context* ctx, uint32_t section_size) {
Type type;
bool mutable_;
read_global_header(ctx, &type, &mutable_);
- CALLBACK(on_import, i, module_name, field_name);
- CALLBACK(on_import_global, i, module_name, field_name,
+ CALLBACK(OnImport, i, module_name, field_name);
+ CALLBACK(OnImportGlobal, i, module_name, field_name,
ctx->num_global_imports, type, mutable_);
ctx->num_global_imports++;
break;
@@ -1814,76 +1125,76 @@ static void read_import_section(Context* ctx, uint32_t section_size) {
RAISE_ERROR("invalid import kind: %d", kind);
}
}
- CALLBACK_CTX0(end_import_section);
+ CALLBACK0(EndImportSection);
}
static void read_function_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_function_signatures_section, section_size);
+ CALLBACK(BeginFunctionSection, section_size);
in_u32_leb128(ctx, &ctx->num_function_signatures, "function signature count");
- CALLBACK(on_function_signatures_count, ctx->num_function_signatures);
+ CALLBACK(OnFunctionCount, ctx->num_function_signatures);
for (uint32_t i = 0; i < ctx->num_function_signatures; ++i) {
uint32_t func_index = ctx->num_func_imports + i;
uint32_t sig_index;
in_u32_leb128(ctx, &sig_index, "function signature index");
RAISE_ERROR_UNLESS(sig_index < ctx->num_signatures,
"invalid function signature index: %d", sig_index);
- CALLBACK(on_function_signature, func_index, sig_index);
+ CALLBACK(OnFunction, func_index, sig_index);
}
- CALLBACK_CTX0(end_function_signatures_section);
+ CALLBACK0(EndFunctionSection);
}
static void read_table_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_table_section, section_size);
+ CALLBACK(BeginTableSection, section_size);
in_u32_leb128(ctx, &ctx->num_tables, "table count");
RAISE_ERROR_UNLESS(ctx->num_tables <= 1, "table count (%d) must be 0 or 1",
ctx->num_tables);
- CALLBACK(on_table_count, ctx->num_tables);
+ CALLBACK(OnTableCount, ctx->num_tables);
for (uint32_t i = 0; i < ctx->num_tables; ++i) {
uint32_t table_index = ctx->num_table_imports + i;
Type elem_type;
Limits elem_limits;
read_table(ctx, &elem_type, &elem_limits);
- CALLBACK(on_table, table_index, elem_type, &elem_limits);
+ CALLBACK(OnTable, table_index, elem_type, &elem_limits);
}
- CALLBACK_CTX0(end_table_section);
+ CALLBACK0(EndTableSection);
}
static void read_memory_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_memory_section, section_size);
+ CALLBACK(BeginMemorySection, section_size);
in_u32_leb128(ctx, &ctx->num_memories, "memory count");
RAISE_ERROR_UNLESS(ctx->num_memories <= 1, "memory count must be 0 or 1");
- CALLBACK(on_memory_count, ctx->num_memories);
+ CALLBACK(OnMemoryCount, ctx->num_memories);
for (uint32_t i = 0; i < ctx->num_memories; ++i) {
uint32_t memory_index = ctx->num_memory_imports + i;
Limits page_limits;
read_memory(ctx, &page_limits);
- CALLBACK(on_memory, memory_index, &page_limits);
+ CALLBACK(OnMemory, memory_index, &page_limits);
}
- CALLBACK_CTX0(end_memory_section);
+ CALLBACK0(EndMemorySection);
}
static void read_global_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_global_section, section_size);
+ CALLBACK(BeginGlobalSection, section_size);
in_u32_leb128(ctx, &ctx->num_globals, "global count");
- CALLBACK(on_global_count, ctx->num_globals);
+ CALLBACK(OnGlobalCount, ctx->num_globals);
for (uint32_t i = 0; i < ctx->num_globals; ++i) {
uint32_t global_index = ctx->num_global_imports + i;
Type global_type;
bool mutable_;
read_global_header(ctx, &global_type, &mutable_);
- CALLBACK(begin_global, global_index, global_type, mutable_);
- CALLBACK(begin_global_init_expr, global_index);
+ CALLBACK(BeginGlobal, global_index, global_type, mutable_);
+ CALLBACK(BeginGlobalInitExpr, global_index);
read_init_expr(ctx, global_index);
- CALLBACK(end_global_init_expr, global_index);
- CALLBACK(end_global, global_index);
+ CALLBACK(EndGlobalInitExpr, global_index);
+ CALLBACK(EndGlobal, global_index);
}
- CALLBACK_CTX0(end_global_section);
+ CALLBACK0(EndGlobalSection);
}
static void read_export_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_export_section, section_size);
+ CALLBACK(BeginExportSection, section_size);
in_u32_leb128(ctx, &ctx->num_exports, "export count");
- CALLBACK(on_export_count, ctx->num_exports);
+ CALLBACK(OnExportCount, ctx->num_exports);
for (uint32_t i = 0; i < ctx->num_exports; ++i) {
StringSlice name;
in_str(ctx, &name, "export item name");
@@ -1914,70 +1225,70 @@ static void read_export_section(Context* ctx, uint32_t section_size) {
break;
}
- CALLBACK(on_export, i, static_cast<ExternalKind>(external_kind), item_index,
+ CALLBACK(OnExport, i, static_cast<ExternalKind>(external_kind), item_index,
name);
}
- CALLBACK_CTX0(end_export_section);
+ CALLBACK0(EndExportSection);
}
static void read_start_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_start_section, section_size);
+ CALLBACK(BeginStartSection, section_size);
uint32_t func_index;
in_u32_leb128(ctx, &func_index, "start function index");
RAISE_ERROR_UNLESS(func_index < num_total_funcs(ctx),
"invalid start function index");
- CALLBACK(on_start_function, func_index);
- CALLBACK_CTX0(end_start_section);
+ CALLBACK(OnStartFunction, func_index);
+ CALLBACK0(EndStartSection);
}
static void read_elem_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_elem_section, section_size);
+ CALLBACK(BeginElemSection, section_size);
uint32_t num_elem_segments;
in_u32_leb128(ctx, &num_elem_segments, "elem segment count");
- CALLBACK(on_elem_segment_count, num_elem_segments);
+ CALLBACK(OnElemSegmentCount, num_elem_segments);
RAISE_ERROR_UNLESS(num_elem_segments == 0 || num_total_tables(ctx) > 0,
"elem section without table section");
for (uint32_t i = 0; i < num_elem_segments; ++i) {
uint32_t table_index;
in_u32_leb128(ctx, &table_index, "elem segment table index");
- CALLBACK(begin_elem_segment, i, table_index);
- CALLBACK(begin_elem_segment_init_expr, i);
+ CALLBACK(BeginElemSegment, i, table_index);
+ CALLBACK(BeginElemSegmentInitExpr, i);
read_init_expr(ctx, i);
- CALLBACK(end_elem_segment_init_expr, i);
+ CALLBACK(EndElemSegmentInitExpr, i);
uint32_t num_function_indexes;
in_u32_leb128(ctx, &num_function_indexes,
"elem segment function index count");
- CALLBACK_CTX(on_elem_segment_function_index_count, i, num_function_indexes);
+ CALLBACK(OnElemSegmentFunctionIndexCount, i, num_function_indexes);
for (uint32_t j = 0; j < num_function_indexes; ++j) {
uint32_t func_index;
in_u32_leb128(ctx, &func_index, "elem segment function index");
- CALLBACK(on_elem_segment_function_index, i, func_index);
+ CALLBACK(OnElemSegmentFunctionIndex, i, func_index);
}
- CALLBACK(end_elem_segment, i);
+ CALLBACK(EndElemSegment, i);
}
- CALLBACK_CTX0(end_elem_section);
+ CALLBACK0(EndElemSection);
}
static void read_code_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_function_bodies_section, section_size);
+ CALLBACK(BeginCodeSection, section_size);
in_u32_leb128(ctx, &ctx->num_function_bodies, "function body count");
RAISE_ERROR_UNLESS(ctx->num_function_signatures == ctx->num_function_bodies,
"function signature count != function body count");
- CALLBACK(on_function_bodies_count, ctx->num_function_bodies);
+ CALLBACK(OnFunctionBodyCount, ctx->num_function_bodies);
for (uint32_t i = 0; i < ctx->num_function_bodies; ++i) {
uint32_t func_index = ctx->num_func_imports + i;
- uint32_t func_offset = ctx->offset;
- ctx->offset = func_offset;
- CALLBACK_CTX(begin_function_body, func_index);
+ uint32_t func_offset = ctx->state.offset;
+ ctx->state.offset = func_offset;
+ CALLBACK(BeginFunctionBody, func_index);
uint32_t body_size;
in_u32_leb128(ctx, &body_size, "function body size");
- uint32_t body_start_offset = ctx->offset;
+ uint32_t body_start_offset = ctx->state.offset;
uint32_t end_offset = body_start_offset + body_size;
uint32_t num_local_decls;
in_u32_leb128(ctx, &num_local_decls, "local declaration count");
- CALLBACK(on_local_decl_count, num_local_decls);
+ CALLBACK(OnLocalDeclCount, num_local_decls);
for (uint32_t k = 0; k < num_local_decls; ++k) {
uint32_t num_local_types;
in_u32_leb128(ctx, &num_local_types, "local type count");
@@ -1985,50 +1296,50 @@ static void read_code_section(Context* ctx, uint32_t section_size) {
in_type(ctx, &local_type, "local type");
RAISE_ERROR_UNLESS(is_concrete_type(local_type),
"expected valid local type");
- CALLBACK(on_local_decl, k, num_local_types, local_type);
+ CALLBACK(OnLocalDecl, k, num_local_types, local_type);
}
read_function_body(ctx, end_offset);
- CALLBACK(end_function_body, func_index);
+ CALLBACK(EndFunctionBody, func_index);
}
- CALLBACK_CTX0(end_function_bodies_section);
+ CALLBACK0(EndCodeSection);
}
static void read_data_section(Context* ctx, uint32_t section_size) {
- CALLBACK_SECTION(begin_data_section, section_size);
+ CALLBACK(BeginDataSection, section_size);
uint32_t num_data_segments;
in_u32_leb128(ctx, &num_data_segments, "data segment count");
- CALLBACK(on_data_segment_count, num_data_segments);
+ CALLBACK(OnDataSegmentCount, num_data_segments);
RAISE_ERROR_UNLESS(num_data_segments == 0 || num_total_memories(ctx) > 0,
"data section without memory section");
for (uint32_t i = 0; i < num_data_segments; ++i) {
uint32_t memory_index;
in_u32_leb128(ctx, &memory_index, "data segment memory index");
- CALLBACK(begin_data_segment, i, memory_index);
- CALLBACK(begin_data_segment_init_expr, i);
+ CALLBACK(BeginDataSegment, i, memory_index);
+ CALLBACK(BeginDataSegmentInitExpr, i);
read_init_expr(ctx, i);
- CALLBACK(end_data_segment_init_expr, i);
+ CALLBACK(EndDataSegmentInitExpr, i);
uint32_t data_size;
const void* data;
in_bytes(ctx, &data, &data_size, "data segment data");
- CALLBACK(on_data_segment_data, i, data, data_size);
- CALLBACK(end_data_segment, i);
+ CALLBACK(OnDataSegmentData, i, data, data_size);
+ CALLBACK(EndDataSegment, i);
}
- CALLBACK_CTX0(end_data_section);
+ CALLBACK0(EndDataSection);
}
static void read_sections(Context* ctx) {
- while (ctx->offset < ctx->data_size) {
+ while (ctx->state.offset < ctx->state.size) {
uint32_t section_code;
uint32_t section_size;
/* Temporarily reset read_end to the full data size so the next section
* can be read. */
- ctx->read_end = ctx->data_size;
+ ctx->read_end = ctx->state.size;
in_u32_leb128(ctx, &section_code, "section code");
in_u32_leb128(ctx, &section_size, "section size");
- ctx->read_end = ctx->offset + section_size;
+ ctx->read_end = ctx->state.offset + section_size;
if (section_code >= kBinarySectionCount) {
RAISE_ERROR("invalid section code: %u; max is %u", section_code,
kBinarySectionCount - 1);
@@ -2036,7 +1347,7 @@ static void read_sections(Context* ctx) {
BinarySection section = static_cast<BinarySection>(section_code);
- if (ctx->read_end > ctx->data_size)
+ if (ctx->read_end > ctx->state.size)
RAISE_ERROR("invalid section size: extends past end");
if (ctx->last_known_section != BinarySection::Invalid &&
@@ -2045,7 +1356,7 @@ static void read_sections(Context* ctx) {
RAISE_ERROR("section %s out of order", get_section_name(section));
}
- CALLBACK_CTX(begin_section, section, section_size);
+ CALLBACK(BeginSection, section, section_size);
#define V(Name, name, code) \
case BinarySection::Name: \
@@ -2062,7 +1373,7 @@ static void read_sections(Context* ctx) {
#undef V
- if (ctx->offset != ctx->read_end) {
+ if (ctx->state.offset != ctx->read_end) {
RAISE_ERROR("unfinished section (expected end: 0x%" PRIzx ")",
ctx->read_end);
}
@@ -2075,175 +1386,14 @@ static void read_sections(Context* ctx) {
Result read_binary(const void* data,
size_t size,
BinaryReader* reader,
- uint32_t num_function_passes,
const ReadBinaryOptions* options) {
- LoggingContext logging_context;
- WABT_ZERO_MEMORY(logging_context);
- logging_context.reader = reader;
- logging_context.stream = options->log_stream;
-
- BinaryReader logging_reader;
- WABT_ZERO_MEMORY(logging_reader);
- logging_reader.user_data = &logging_context;
-
- logging_reader.on_error = logging_on_error;
- logging_reader.begin_section = logging_begin_section;
- logging_reader.begin_module = logging_begin_module;
- logging_reader.end_module = logging_end_module;
-
- logging_reader.begin_custom_section = logging_begin_custom_section;
- logging_reader.end_custom_section = logging_end_custom_section;
-
- logging_reader.begin_signature_section = logging_begin_signature_section;
- logging_reader.on_signature_count = logging_on_signature_count;
- logging_reader.on_signature = logging_on_signature;
- logging_reader.end_signature_section = logging_end_signature_section;
-
- logging_reader.begin_import_section = logging_begin_import_section;
- logging_reader.on_import_count = logging_on_import_count;
- logging_reader.on_import = logging_on_import;
- logging_reader.on_import_func = logging_on_import_func;
- logging_reader.on_import_table = logging_on_import_table;
- logging_reader.on_import_memory = logging_on_import_memory;
- logging_reader.on_import_global = logging_on_import_global;
- logging_reader.end_import_section = logging_end_import_section;
-
- logging_reader.begin_function_signatures_section =
- logging_begin_function_signatures_section;
- logging_reader.on_function_signatures_count =
- logging_on_function_signatures_count;
- logging_reader.on_function_signature = logging_on_function_signature;
- logging_reader.end_function_signatures_section =
- logging_end_function_signatures_section;
-
- logging_reader.begin_table_section = logging_begin_table_section;
- logging_reader.on_table_count = logging_on_table_count;
- logging_reader.on_table = logging_on_table;
- logging_reader.end_table_section = logging_end_table_section;
-
- logging_reader.begin_memory_section = logging_begin_memory_section;
- logging_reader.on_memory_count = logging_on_memory_count;
- logging_reader.on_memory = logging_on_memory;
- logging_reader.end_memory_section = logging_end_memory_section;
-
- logging_reader.begin_global_section = logging_begin_global_section;
- logging_reader.on_global_count = logging_on_global_count;
- logging_reader.begin_global = logging_begin_global;
- logging_reader.begin_global_init_expr = logging_begin_global_init_expr;
- logging_reader.end_global_init_expr = logging_end_global_init_expr;
- logging_reader.end_global = logging_end_global;
- logging_reader.end_global_section = logging_end_global_section;
-
- logging_reader.begin_export_section = logging_begin_export_section;
- logging_reader.on_export_count = logging_on_export_count;
- logging_reader.on_export = logging_on_export;
- logging_reader.end_export_section = logging_end_export_section;
-
- logging_reader.begin_start_section = logging_begin_start_section;
- logging_reader.on_start_function = logging_on_start_function;
- logging_reader.end_start_section = logging_end_start_section;
-
- logging_reader.begin_function_bodies_section =
- logging_begin_function_bodies_section;
- logging_reader.on_function_bodies_count = logging_on_function_bodies_count;
- logging_reader.begin_function_body_pass = logging_begin_function_body_pass;
- logging_reader.begin_function_body = logging_begin_function_body;
- logging_reader.on_local_decl_count = logging_on_local_decl_count;
- logging_reader.on_local_decl = logging_on_local_decl;
- logging_reader.on_binary_expr = logging_on_binary_expr;
- logging_reader.on_block_expr = logging_on_block_expr;
- logging_reader.on_br_expr = logging_on_br_expr;
- logging_reader.on_br_if_expr = logging_on_br_if_expr;
- logging_reader.on_br_table_expr = logging_on_br_table_expr;
- logging_reader.on_call_expr = logging_on_call_expr;
- logging_reader.on_call_import_expr = logging_on_call_import_expr;
- logging_reader.on_call_indirect_expr = logging_on_call_indirect_expr;
- logging_reader.on_compare_expr = logging_on_compare_expr;
- logging_reader.on_convert_expr = logging_on_convert_expr;
- logging_reader.on_drop_expr = logging_on_drop_expr;
- logging_reader.on_else_expr = logging_on_else_expr;
- logging_reader.on_end_expr = logging_on_end_expr;
- logging_reader.on_f32_const_expr = logging_on_f32_const_expr;
- logging_reader.on_f64_const_expr = logging_on_f64_const_expr;
- logging_reader.on_get_global_expr = logging_on_get_global_expr;
- logging_reader.on_get_local_expr = logging_on_get_local_expr;
- logging_reader.on_grow_memory_expr = logging_on_grow_memory_expr;
- logging_reader.on_i32_const_expr = logging_on_i32_const_expr;
- logging_reader.on_i64_const_expr = logging_on_i64_const_expr;
- logging_reader.on_if_expr = logging_on_if_expr;
- logging_reader.on_load_expr = logging_on_load_expr;
- logging_reader.on_loop_expr = logging_on_loop_expr;
- logging_reader.on_current_memory_expr = logging_on_current_memory_expr;
- logging_reader.on_nop_expr = logging_on_nop_expr;
- logging_reader.on_return_expr = logging_on_return_expr;
- logging_reader.on_select_expr = logging_on_select_expr;
- logging_reader.on_set_global_expr = logging_on_set_global_expr;
- logging_reader.on_set_local_expr = logging_on_set_local_expr;
- logging_reader.on_store_expr = logging_on_store_expr;
- logging_reader.on_tee_local_expr = logging_on_tee_local_expr;
- logging_reader.on_unary_expr = logging_on_unary_expr;
- logging_reader.on_unreachable_expr = logging_on_unreachable_expr;
- logging_reader.end_function_body = logging_end_function_body;
- logging_reader.end_function_body_pass = logging_end_function_body_pass;
- logging_reader.end_function_bodies_section =
- logging_end_function_bodies_section;
-
- logging_reader.begin_elem_section = logging_begin_elem_section;
- logging_reader.on_elem_segment_count = logging_on_elem_segment_count;
- logging_reader.begin_elem_segment = logging_begin_elem_segment;
- logging_reader.begin_elem_segment_init_expr =
- logging_begin_elem_segment_init_expr;
- logging_reader.end_elem_segment_init_expr =
- logging_end_elem_segment_init_expr;
- logging_reader.on_elem_segment_function_index_count =
- logging_on_elem_segment_function_index_count;
- logging_reader.on_elem_segment_function_index =
- logging_on_elem_segment_function_index;
- logging_reader.end_elem_segment = logging_end_elem_segment;
- logging_reader.end_elem_section = logging_end_elem_section;
-
- logging_reader.begin_data_section = logging_begin_data_section;
- logging_reader.on_data_segment_count = logging_on_data_segment_count;
- logging_reader.begin_data_segment = logging_begin_data_segment;
- logging_reader.begin_data_segment_init_expr =
- logging_begin_data_segment_init_expr;
- logging_reader.end_data_segment_init_expr =
- logging_end_data_segment_init_expr;
- logging_reader.on_data_segment_data = logging_on_data_segment_data;
- logging_reader.end_data_segment = logging_end_data_segment;
- logging_reader.end_data_section = logging_end_data_section;
-
- logging_reader.begin_names_section = logging_begin_names_section;
- logging_reader.on_function_name_subsection = logging_on_function_name_subsection;
- logging_reader.on_function_names_count = logging_on_function_names_count;
- logging_reader.on_function_name = logging_on_function_name;
- logging_reader.on_local_name_subsection = logging_on_local_name_subsection;
- logging_reader.on_local_name_function_count = logging_on_local_name_function_count;
- logging_reader.on_local_name_local_count = logging_on_local_name_local_count;
- logging_reader.on_local_name = logging_on_local_name;
- logging_reader.end_names_section = logging_end_names_section;
-
- logging_reader.begin_reloc_section = logging_begin_reloc_section;
- logging_reader.on_reloc_count = logging_on_reloc_count;
- logging_reader.on_reloc = logging_on_reloc;
- logging_reader.end_reloc_section = logging_end_reloc_section;
-
- logging_reader.on_init_expr_f32_const_expr =
- logging_on_init_expr_f32_const_expr;
- logging_reader.on_init_expr_f64_const_expr =
- logging_on_init_expr_f64_const_expr;
- logging_reader.on_init_expr_get_global_expr =
- logging_on_init_expr_get_global_expr;
- logging_reader.on_init_expr_i32_const_expr =
- logging_on_init_expr_i32_const_expr;
- logging_reader.on_init_expr_i64_const_expr =
- logging_on_init_expr_i64_const_expr;
-
+ BinaryReaderLogging logging_reader(options->log_stream, reader);
Context context;
/* all the macros assume a Context* named ctx */
Context* ctx = &context;
- ctx->data = static_cast<const uint8_t*>(data);
- ctx->data_size = ctx->read_end = size;
+ ctx->state.data = static_cast<const uint8_t*>(data);
+ ctx->state.size = ctx->read_end = size;
+ ctx->state.offset = 0;
ctx->reader = options->log_stream ? &logging_reader : reader;
ctx->options = options;
ctx->last_known_section = BinarySection::Invalid;
@@ -2252,6 +1402,8 @@ Result read_binary(const void* data,
return Result::Error;
}
+ ctx->reader->OnSetState(&ctx->state);
+
uint32_t magic;
in_u32(ctx, &magic, "magic");
RAISE_ERROR_UNLESS(magic == WABT_BINARY_MAGIC, "bad magic value");
@@ -2261,9 +1413,9 @@ Result read_binary(const void* data,
"bad wasm file version: %#x (expected %#x)", version,
WABT_BINARY_VERSION);
- CALLBACK(begin_module, version);
+ CALLBACK(BeginModule, version);
read_sections(ctx);
- CALLBACK0(end_module);
+ CALLBACK0(EndModule);
return Result::Ok;
}
diff --git a/src/binary-reader.h b/src/binary-reader.h
index df7e8071..55ac8dd2 100644
--- a/src/binary-reader.h
+++ b/src/binary-reader.h
@@ -33,303 +33,244 @@ struct ReadBinaryOptions {
bool read_debug_names;
};
-struct BinaryReaderContext {
- const uint8_t* data;
- size_t size;
- size_t offset;
- void* user_data;
-};
-
-struct BinaryReader {
- void* user_data;
-
- bool (*on_error)(BinaryReaderContext* ctx, const char* message);
-
- /* module */
- Result (*begin_module)(uint32_t version, void* user_data);
- Result (*end_module)(void* user_data);
-
- Result (*begin_section)(BinaryReaderContext* ctx,
- BinarySection section_type,
- uint32_t size);
-
- /* custom section */
- Result (*begin_custom_section)(BinaryReaderContext* ctx,
- uint32_t size,
- StringSlice section_name);
- Result (*end_custom_section)(BinaryReaderContext* ctx);
-
- /* signatures section */
- /* TODO(binji): rename to "type" section */
- Result (*begin_signature_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_signature_count)(uint32_t count, void* user_data);
- Result (*on_signature)(uint32_t index,
- uint32_t param_count,
- Type* param_types,
- uint32_t result_count,
- Type* result_types,
- void* user_data);
- Result (*end_signature_section)(BinaryReaderContext* ctx);
-
- /* import section */
- Result (*begin_import_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_import_count)(uint32_t count, void* user_data);
- Result (*on_import)(uint32_t index,
- StringSlice module_name,
- StringSlice field_name,
- void* user_data);
- Result (*on_import_func)(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t func_index,
- uint32_t sig_index,
- void* user_data);
- Result (*on_import_table)(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t table_index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data);
- Result (*on_import_memory)(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t memory_index,
- const Limits* page_limits,
- void* user_data);
- Result (*on_import_global)(uint32_t import_index,
- StringSlice module_name,
- StringSlice field_name,
- uint32_t global_index,
- Type type,
- bool mutable_,
- void* user_data);
- Result (*end_import_section)(BinaryReaderContext* ctx);
-
- /* function signatures section */
- /* TODO(binji): rename to "function" section */
- Result (*begin_function_signatures_section)(BinaryReaderContext* ctx,
- uint32_t size);
- Result (*on_function_signatures_count)(uint32_t count, void* user_data);
- Result (*on_function_signature)(uint32_t index,
- uint32_t sig_index,
- void* user_data);
- Result (*end_function_signatures_section)(BinaryReaderContext* ctx);
-
- /* table section */
- Result (*begin_table_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_table_count)(uint32_t count, void* user_data);
- Result (*on_table)(uint32_t index,
- Type elem_type,
- const Limits* elem_limits,
- void* user_data);
- Result (*end_table_section)(BinaryReaderContext* ctx);
-
- /* memory section */
- Result (*begin_memory_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_memory_count)(uint32_t count, void* user_data);
- Result (*on_memory)(uint32_t index, const Limits* limits, void* user_data);
- Result (*end_memory_section)(BinaryReaderContext* ctx);
-
- /* global section */
- Result (*begin_global_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_global_count)(uint32_t count, void* user_data);
- Result (*begin_global)(uint32_t index,
- Type type,
- bool mutable_,
- void* user_data);
- Result (*begin_global_init_expr)(uint32_t index, void* user_data);
- Result (*end_global_init_expr)(uint32_t index, void* user_data);
- Result (*end_global)(uint32_t index, void* user_data);
- Result (*end_global_section)(BinaryReaderContext* ctx);
-
- /* exports section */
- Result (*begin_export_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_export_count)(uint32_t count, void* user_data);
- Result (*on_export)(uint32_t index,
- ExternalKind kind,
- uint32_t item_index,
- StringSlice name,
- void* user_data);
- Result (*end_export_section)(BinaryReaderContext* ctx);
-
- /* start section */
- Result (*begin_start_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_start_function)(uint32_t func_index, void* user_data);
- Result (*end_start_section)(BinaryReaderContext* ctx);
-
- /* function bodies section */
- /* TODO(binji): rename to code section */
- Result (*begin_function_bodies_section)(BinaryReaderContext* ctx,
- uint32_t size);
- Result (*on_function_bodies_count)(uint32_t count, void* user_data);
- Result (*begin_function_body_pass)(uint32_t index,
- uint32_t pass,
- void* user_data);
- Result (*begin_function_body)(BinaryReaderContext* ctx, uint32_t index);
- Result (*on_local_decl_count)(uint32_t count, void* user_data);
- Result (*on_local_decl)(uint32_t decl_index,
- uint32_t count,
- Type type,
- void* user_data);
-
- /* function expressions; called between begin_function_body and
- end_function_body */
- Result (*on_opcode)(BinaryReaderContext* ctx, Opcode Opcode);
- Result (*on_opcode_bare)(BinaryReaderContext* ctx);
- Result (*on_opcode_uint32)(BinaryReaderContext* ctx, uint32_t value);
- Result (*on_opcode_uint32_uint32)(BinaryReaderContext* ctx,
- uint32_t value,
- uint32_t value2);
- Result (*on_opcode_uint64)(BinaryReaderContext* ctx, uint64_t value);
- Result (*on_opcode_f32)(BinaryReaderContext* ctx, uint32_t value);
- Result (*on_opcode_f64)(BinaryReaderContext* ctx, uint64_t value);
- Result (*on_opcode_block_sig)(BinaryReaderContext* ctx,
- uint32_t num_types,
- Type* sig_types);
- Result (*on_binary_expr)(Opcode opcode, void* user_data);
- Result (*on_block_expr)(uint32_t num_types, Type* sig_types, void* user_data);
- Result (*on_br_expr)(uint32_t depth, void* user_data);
- Result (*on_br_if_expr)(uint32_t depth, void* user_data);
- Result (*on_br_table_expr)(BinaryReaderContext* ctx,
- uint32_t num_targets,
- uint32_t* target_depths,
- uint32_t default_target_depth);
- Result (*on_call_expr)(uint32_t func_index, void* user_data);
- Result (*on_call_import_expr)(uint32_t import_index, void* user_data);
- Result (*on_call_indirect_expr)(uint32_t sig_index, void* user_data);
- Result (*on_compare_expr)(Opcode opcode, void* user_data);
- Result (*on_convert_expr)(Opcode opcode, void* user_data);
- Result (*on_drop_expr)(void* user_data);
- Result (*on_else_expr)(void* user_data);
- Result (*on_end_expr)(void* user_data);
- Result (*on_end_func)(void* user_data);
- Result (*on_f32_const_expr)(uint32_t value_bits, void* user_data);
- Result (*on_f64_const_expr)(uint64_t value_bits, void* user_data);
- Result (*on_get_global_expr)(uint32_t global_index, void* user_data);
- Result (*on_get_local_expr)(uint32_t local_index, void* user_data);
- Result (*on_grow_memory_expr)(void* user_data);
- Result (*on_i32_const_expr)(uint32_t value, void* user_data);
- Result (*on_i64_const_expr)(uint64_t value, void* user_data);
- Result (*on_if_expr)(uint32_t num_types, Type* sig_types, void* user_data);
- Result (*on_load_expr)(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data);
- Result (*on_loop_expr)(uint32_t num_types, Type* sig_types, void* user_data);
- Result (*on_current_memory_expr)(void* user_data);
- Result (*on_nop_expr)(void* user_data);
- Result (*on_return_expr)(void* user_data);
- Result (*on_select_expr)(void* user_data);
- Result (*on_set_global_expr)(uint32_t global_index, void* user_data);
- Result (*on_set_local_expr)(uint32_t local_index, void* user_data);
- Result (*on_store_expr)(Opcode opcode,
- uint32_t alignment_log2,
- uint32_t offset,
- void* user_data);
- Result (*on_tee_local_expr)(uint32_t local_index, void* user_data);
- Result (*on_unary_expr)(Opcode opcode, void* user_data);
- Result (*on_unreachable_expr)(void* user_data);
- Result (*end_function_body)(uint32_t index, void* user_data);
- Result (*end_function_body_pass)(uint32_t index,
- uint32_t pass,
- void* user_data);
- Result (*end_function_bodies_section)(BinaryReaderContext* ctx);
-
- /* elem section */
- Result (*begin_elem_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_elem_segment_count)(uint32_t count, void* user_data);
- Result (*begin_elem_segment)(uint32_t index,
+class BinaryReader {
+ public:
+ struct State {
+ const uint8_t* data;
+ size_t size;
+ size_t offset;
+ };
+
+ virtual ~BinaryReader() {}
+
+ virtual bool OnError(const char* message) = 0;
+ virtual void OnSetState(const State* s) { state = s; }
+
+ /* Module */
+ virtual Result BeginModule(uint32_t version) = 0;
+ virtual Result EndModule() = 0;
+
+ virtual Result BeginSection(BinarySection section_type, uint32_t size) = 0;
+
+ /* Custom section */
+ virtual Result BeginCustomSection(uint32_t size,
+ StringSlice section_name) = 0;
+ virtual Result EndCustomSection() = 0;
+
+ /* Type section */
+ virtual Result BeginTypeSection(uint32_t size) = 0;
+ virtual Result OnTypeCount(uint32_t count) = 0;
+ virtual Result OnType(uint32_t index,
+ uint32_t param_count,
+ Type* param_types,
+ uint32_t result_count,
+ Type* result_types) = 0;
+ virtual Result EndTypeSection() = 0;
+
+ /* Import section */
+ virtual Result BeginImportSection(uint32_t size) = 0;
+ virtual Result OnImportCount(uint32_t count) = 0;
+ virtual Result OnImport(uint32_t index,
+ StringSlice module_name,
+ StringSlice field_name) = 0;
+ virtual Result OnImportFunc(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t func_index,
+ uint32_t sig_index) = 0;
+ virtual Result OnImportTable(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
uint32_t table_index,
- void* user_data);
- Result (*begin_elem_segment_init_expr)(uint32_t index, void* user_data);
- Result (*end_elem_segment_init_expr)(uint32_t index, void* user_data);
- Result (*on_elem_segment_function_index_count)(BinaryReaderContext* ctx,
- uint32_t index,
- uint32_t count);
- Result (*on_elem_segment_function_index)(uint32_t index,
- uint32_t func_index,
- void* user_data);
- Result (*end_elem_segment)(uint32_t index, void* user_data);
- Result (*end_elem_section)(BinaryReaderContext* ctx);
-
- /* data section */
- Result (*begin_data_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_data_segment_count)(uint32_t count, void* user_data);
- Result (*begin_data_segment)(uint32_t index,
- uint32_t memory_index,
- void* user_data);
- Result (*begin_data_segment_init_expr)(uint32_t index, void* user_data);
- Result (*end_data_segment_init_expr)(uint32_t index, void* user_data);
- Result (*on_data_segment_data)(uint32_t index,
- const void* data,
- uint32_t size,
- void* user_data);
- Result (*end_data_segment)(uint32_t index, void* user_data);
- Result (*end_data_section)(BinaryReaderContext* ctx);
-
- /* names section */
- Result (*begin_names_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_function_name_subsection)(uint32_t index,
- uint32_t name_type,
- uint32_t subsection_size,
- void* user_data);
- Result (*on_function_names_count)(uint32_t num_functions,
- void* user_data);
- Result (*on_function_name)(uint32_t function_index,
- StringSlice function_name,
- void* user_data);
- Result (*on_local_name_subsection)(uint32_t index,
- uint32_t name_type,
- uint32_t subsection_size,
- void* user_data);
- Result (*on_local_name_function_count)(uint32_t num_functions,
- void* user_data);
- Result (*on_local_name_local_count)(uint32_t function_index,
- uint32_t num_locals,
- void* user_data);
- Result (*on_local_name)(uint32_t function_index,
- uint32_t local_index,
- StringSlice local_name,
- void* user_data);
- Result (*end_names_section)(BinaryReaderContext* ctx);
-
- /* names section */
- Result (*begin_reloc_section)(BinaryReaderContext* ctx, uint32_t size);
- Result (*on_reloc_count)(uint32_t count,
- BinarySection section_code,
- StringSlice section_name,
- void* user_data);
- Result (*on_reloc)(RelocType type,
- uint32_t offset,
- uint32_t index,
- int32_t addend,
- void* user_data);
- Result (*end_reloc_section)(BinaryReaderContext* ctx);
-
- /* init_expr - used by elem, data and global sections; these functions are
- * only called between calls to begin_*_init_expr and end_*_init_expr */
- Result (*on_init_expr_f32_const_expr)(uint32_t index,
- uint32_t value,
- void* user_data);
- Result (*on_init_expr_f64_const_expr)(uint32_t index,
- uint64_t value,
- void* user_data);
- Result (*on_init_expr_get_global_expr)(uint32_t index,
- uint32_t global_index,
- void* user_data);
- Result (*on_init_expr_i32_const_expr)(uint32_t index,
- uint32_t value,
- void* user_data);
- Result (*on_init_expr_i64_const_expr)(uint32_t index,
- uint64_t value,
- void* user_data);
+ Type elem_type,
+ const Limits* elem_limits) = 0;
+ virtual Result OnImportMemory(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t memory_index,
+ const Limits* page_limits) = 0;
+ virtual Result OnImportGlobal(uint32_t import_index,
+ StringSlice module_name,
+ StringSlice field_name,
+ uint32_t global_index,
+ Type type,
+ bool mutable_) = 0;
+ virtual Result EndImportSection() = 0;
+
+ /* Function section */
+ virtual Result BeginFunctionSection(uint32_t size) = 0;
+ virtual Result OnFunctionCount(uint32_t count) = 0;
+ virtual Result OnFunction(uint32_t index, uint32_t sig_index) = 0;
+ virtual Result EndFunctionSection() = 0;
+
+ /* Table section */
+ virtual Result BeginTableSection(uint32_t size) = 0;
+ virtual Result OnTableCount(uint32_t count) = 0;
+ virtual Result OnTable(uint32_t index,
+ Type elem_type,
+ const Limits* elem_limits) = 0;
+ virtual Result EndTableSection() = 0;
+
+ /* Memory section */
+ virtual Result BeginMemorySection(uint32_t size) = 0;
+ virtual Result OnMemoryCount(uint32_t count) = 0;
+ virtual Result OnMemory(uint32_t index, const Limits* limits) = 0;
+ virtual Result EndMemorySection() = 0;
+
+ /* Global section */
+ virtual Result BeginGlobalSection(uint32_t size) = 0;
+ virtual Result OnGlobalCount(uint32_t count) = 0;
+ virtual Result BeginGlobal(uint32_t index, Type type, bool mutable_) = 0;
+ virtual Result BeginGlobalInitExpr(uint32_t index) = 0;
+ virtual Result EndGlobalInitExpr(uint32_t index) = 0;
+ virtual Result EndGlobal(uint32_t index) = 0;
+ virtual Result EndGlobalSection() = 0;
+
+ /* Exports section */
+ virtual Result BeginExportSection(uint32_t size) = 0;
+ virtual Result OnExportCount(uint32_t count) = 0;
+ virtual Result OnExport(uint32_t index,
+ ExternalKind kind,
+ uint32_t item_index,
+ StringSlice name) = 0;
+ virtual Result EndExportSection() = 0;
+
+ /* Start section */
+ virtual Result BeginStartSection(uint32_t size) = 0;
+ virtual Result OnStartFunction(uint32_t func_index) = 0;
+ virtual Result EndStartSection() = 0;
+
+ /* Code section */
+ virtual Result BeginCodeSection(uint32_t size) = 0;
+ virtual Result OnFunctionBodyCount(uint32_t count) = 0;
+ virtual Result BeginFunctionBody(uint32_t index) = 0;
+ virtual Result OnLocalDeclCount(uint32_t count) = 0;
+ virtual Result OnLocalDecl(uint32_t decl_index,
+ uint32_t count,
+ Type type) = 0;
+
+ /* Function expressions; called between BeginFunctionBody and
+ EndFunctionBody */
+ virtual Result OnOpcode(Opcode Opcode) = 0;
+ virtual Result OnOpcodeBare() = 0;
+ virtual Result OnOpcodeUint32(uint32_t value) = 0;
+ virtual Result OnOpcodeUint32Uint32(uint32_t value, uint32_t value2) = 0;
+ virtual Result OnOpcodeUint64(uint64_t value) = 0;
+ virtual Result OnOpcodeF32(uint32_t value) = 0;
+ virtual Result OnOpcodeF64(uint64_t value) = 0;
+ virtual Result OnOpcodeBlockSig(uint32_t num_types, Type* sig_types) = 0;
+ virtual Result OnBinaryExpr(Opcode opcode) = 0;
+ virtual Result OnBlockExpr(uint32_t num_types, Type* sig_types) = 0;
+ virtual Result OnBrExpr(uint32_t depth) = 0;
+ virtual Result OnBrIfExpr(uint32_t depth) = 0;
+ virtual Result OnBrTableExpr(uint32_t num_targets,
+ uint32_t* target_depths,
+ uint32_t default_target_depth) = 0;
+ virtual Result OnCallExpr(uint32_t func_index) = 0;
+ virtual Result OnCallIndirectExpr(uint32_t sig_index) = 0;
+ virtual Result OnCompareExpr(Opcode opcode) = 0;
+ virtual Result OnConvertExpr(Opcode opcode) = 0;
+ virtual Result OnCurrentMemoryExpr() = 0;
+ virtual Result OnDropExpr() = 0;
+ virtual Result OnElseExpr() = 0;
+ virtual Result OnEndExpr() = 0;
+ virtual Result OnEndFunc() = 0;
+ virtual Result OnF32ConstExpr(uint32_t value_bits) = 0;
+ virtual Result OnF64ConstExpr(uint64_t value_bits) = 0;
+ virtual Result OnGetGlobalExpr(uint32_t global_index) = 0;
+ virtual Result OnGetLocalExpr(uint32_t local_index) = 0;
+ virtual Result OnGrowMemoryExpr() = 0;
+ virtual Result OnI32ConstExpr(uint32_t value) = 0;
+ virtual Result OnI64ConstExpr(uint64_t value) = 0;
+ virtual Result OnIfExpr(uint32_t num_types, Type* sig_types) = 0;
+ virtual Result OnLoadExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) = 0;
+ virtual Result OnLoopExpr(uint32_t num_types, Type* sig_types) = 0;
+ virtual Result OnNopExpr() = 0;
+ virtual Result OnReturnExpr() = 0;
+ virtual Result OnSelectExpr() = 0;
+ virtual Result OnSetGlobalExpr(uint32_t global_index) = 0;
+ virtual Result OnSetLocalExpr(uint32_t local_index) = 0;
+ virtual Result OnStoreExpr(Opcode opcode,
+ uint32_t alignment_log2,
+ uint32_t offset) = 0;
+ virtual Result OnTeeLocalExpr(uint32_t local_index) = 0;
+ virtual Result OnUnaryExpr(Opcode opcode) = 0;
+ virtual Result OnUnreachableExpr() = 0;
+ virtual Result EndFunctionBody(uint32_t index) = 0;
+ virtual Result EndCodeSection() = 0;
+
+ /* Elem section */
+ virtual Result BeginElemSection(uint32_t size) = 0;
+ virtual Result OnElemSegmentCount(uint32_t count) = 0;
+ virtual Result BeginElemSegment(uint32_t index, uint32_t table_index) = 0;
+ virtual Result BeginElemSegmentInitExpr(uint32_t index) = 0;
+ virtual Result EndElemSegmentInitExpr(uint32_t index) = 0;
+ virtual Result OnElemSegmentFunctionIndexCount(uint32_t index,
+ uint32_t count) = 0;
+ virtual Result OnElemSegmentFunctionIndex(uint32_t index,
+ uint32_t func_index) = 0;
+ virtual Result EndElemSegment(uint32_t index) = 0;
+ virtual Result EndElemSection() = 0;
+
+ /* Data section */
+ virtual Result BeginDataSection(uint32_t size) = 0;
+ virtual Result OnDataSegmentCount(uint32_t count) = 0;
+ virtual Result BeginDataSegment(uint32_t index, uint32_t memory_index) = 0;
+ virtual Result BeginDataSegmentInitExpr(uint32_t index) = 0;
+ virtual Result EndDataSegmentInitExpr(uint32_t index) = 0;
+ virtual Result OnDataSegmentData(uint32_t index,
+ const void* data,
+ uint32_t size) = 0;
+ virtual Result EndDataSegment(uint32_t index) = 0;
+ virtual Result EndDataSection() = 0;
+
+ /* Names section */
+ virtual Result BeginNamesSection(uint32_t size) = 0;
+ virtual Result OnFunctionNameSubsection(uint32_t index,
+ uint32_t name_type,
+ uint32_t subsection_size) = 0;
+ virtual Result OnFunctionNamesCount(uint32_t num_functions) = 0;
+ virtual Result OnFunctionName(uint32_t function_index,
+ StringSlice function_name) = 0;
+ virtual Result OnLocalNameSubsection(uint32_t index,
+ uint32_t name_type,
+ uint32_t subsection_size) = 0;
+ virtual Result OnLocalNameFunctionCount(uint32_t num_functions) = 0;
+ virtual Result OnLocalNameLocalCount(uint32_t function_index,
+ uint32_t num_locals) = 0;
+ virtual Result OnLocalName(uint32_t function_index,
+ uint32_t local_index,
+ StringSlice local_name) = 0;
+ virtual Result EndNamesSection() = 0;
+
+ /* Reloc section */
+ virtual Result BeginRelocSection(uint32_t size) = 0;
+ virtual Result OnRelocCount(uint32_t count,
+ BinarySection section_code,
+ StringSlice section_name) = 0;
+ virtual Result OnReloc(RelocType type,
+ uint32_t offset,
+ uint32_t index,
+ int32_t addend) = 0;
+ virtual Result EndRelocSection() = 0;
+
+ /* InitExpr - used by elem, data and global sections; these functions are
+ * only called between calls to Begin*InitExpr and End*InitExpr */
+ virtual Result OnInitExprF32ConstExpr(uint32_t index, uint32_t value) = 0;
+ virtual Result OnInitExprF64ConstExpr(uint32_t index, uint64_t value) = 0;
+ virtual Result OnInitExprGetGlobalExpr(uint32_t index,
+ uint32_t global_index) = 0;
+ virtual Result OnInitExprI32ConstExpr(uint32_t index, uint32_t value) = 0;
+ virtual Result OnInitExprI64ConstExpr(uint32_t index, uint64_t value) = 0;
+
+ const State* state = nullptr;
};
Result read_binary(const void* data,
size_t size,
BinaryReader* reader,
- uint32_t num_function_passes,
const ReadBinaryOptions* options);
size_t read_u32_leb128(const uint8_t* ptr,
diff --git a/src/tools/wasm-link.cc b/src/tools/wasm-link.cc
index 4fbce6bc..602fdcec 100644
--- a/src/tools/wasm-link.cc
+++ b/src/tools/wasm-link.cc
@@ -128,11 +128,13 @@ Section::Section()
payload_size(0),
payload_offset(0),
count(0),
- output_payload_offset(0) {}
+ output_payload_offset(0) {
+ WABT_ZERO_MEMORY(data);
+}
Section::~Section() {
if (section_code == BinarySection::Data) {
- delete data_segments;
+ delete data.data_segments;
}
}
@@ -359,7 +361,7 @@ static void write_memory_section(Context* ctx,
limits.has_max = true;
for (size_t i = 0; i < sections.size(); i++) {
Section* sec = sections[i];
- limits.initial += sec->memory_limits.initial;
+ limits.initial += sec->data.memory_limits.initial;
}
limits.max = limits.initial;
write_limits(stream, &limits);
@@ -466,8 +468,8 @@ static void write_data_section(Context* ctx,
write_u32_leb128(stream, total_count, "data segment count");
for (size_t i = 0; i < sections.size(); i++) {
Section* sec = sections[i];
- for (size_t j = 0; j < sec->data_segments->size(); j++) {
- const DataSegment& segment = (*sec->data_segments)[j];
+ for (size_t j = 0; j < sec->data.data_segments->size(); j++) {
+ const DataSegment& segment = (*sec->data.data_segments)[j];
write_data_segment(stream, segment,
sec->binary->memory_page_offset * WABT_PAGE_SIZE);
}
diff --git a/src/wasm-link.h b/src/wasm-link.h
index 6ddbe148..cb978de0 100644
--- a/src/wasm-link.h
+++ b/src/wasm-link.h
@@ -83,12 +83,12 @@ struct Section {
union {
/* CUSTOM section data */
- SectionDataCustom data_custom;
+ SectionDataCustom custom;
/* DATA section data */
std::vector<DataSegment>* data_segments;
/* MEMORY section data */
Limits memory_limits;
- };
+ } data;
/* The offset at which this section appears within the combined output
* section. */