static void write_action(Context* ctx, const WasmAction* action) { write_key(ctx, "action"); wasm_writef(&ctx->json_stream, "{"); write_key(ctx, "type"); if (action->type == WASM_ACTION_TYPE_INVOKE) { write_string(ctx, "invoke"); } else { assert(action->type == WASM_ACTION_TYPE_GET); write_string(ctx, "get"); } write_separator(ctx); if (action->module_var.type != WASM_VAR_TYPE_INDEX) { write_key(ctx, "module"); write_var(ctx, &action->module_var); write_separator(ctx); } if (action->type == WASM_ACTION_TYPE_INVOKE) { write_key(ctx, "field"); write_escaped_string_slice(ctx, action->invoke.name); write_separator(ctx); write_key(ctx, "args"); write_const_vector(ctx, &action->invoke.args); } else { write_key(ctx, "field"); write_escaped_string_slice(ctx, action->get.name); } wasm_writef(&ctx->json_stream, "}"); }
static void write_const_vector(Context* ctx, const WasmConstVector* consts) { wasm_writef(&ctx->json_stream, "["); size_t i; for (i = 0; i < consts->size; ++i) { const WasmConst* const_ = &consts->data[i]; write_const(ctx, const_); if (i != consts->size - 1) write_separator(ctx); } wasm_writef(&ctx->json_stream, "]"); }
static void write_action_result_type(Context* ctx, WasmScript* script, const WasmAction* action) { const WasmModule* module = wasm_get_module_by_var(script, &action->module_var); const WasmExport* export; wasm_writef(&ctx->json_stream, "["); switch (action->type) { case WASM_ACTION_TYPE_INVOKE: { export = wasm_get_export_by_name(module, &action->invoke.name); assert(export->kind == WASM_EXTERNAL_KIND_FUNC); WasmFunc* func = wasm_get_func_by_var(module, &export->var); size_t num_results = wasm_get_num_results(func); size_t i; for (i = 0; i < num_results; ++i) write_type_object(ctx, wasm_get_result_type(func, i)); break; } case WASM_ACTION_TYPE_GET: { export = wasm_get_export_by_name(module, &action->get.name); assert(export->kind == WASM_EXTERNAL_KIND_GLOBAL); WasmGlobal* global = wasm_get_global_by_var(module, &export->var); write_type_object(ctx, global->type); break; }
static void write_buffer_to_file(const char* filename, WasmOutputBuffer* buffer) { if (s_dump_module) { if (s_verbose) wasm_writef(&s_log_stream, ";; dump\n"); wasm_write_output_buffer_memory_dump(&s_log_stream, buffer); } if (filename) { wasm_write_output_buffer_to_file(buffer, filename); } }
static void write_escaped_string_slice(Context* ctx, WasmStringSlice ss) { size_t i; wasm_write_char(&ctx->json_stream, '"'); for (i = 0; i < ss.length; ++i) { uint8_t c = ss.start[i]; if (c < 0x20 || c == '\\' || c == '"') { wasm_writef(&ctx->json_stream, "\\u%04x", c); } else { wasm_write_char(&ctx->json_stream, c); } } wasm_write_char(&ctx->json_stream, '"'); }
void wasm_write_memory_dump(WasmStream* stream, const void* start, size_t size, size_t offset, WasmPrintChars print_chars, const char* desc) { const uint8_t* p = start; const uint8_t* end = p + size; while (p < end) { const uint8_t* line = p; const uint8_t* line_end = p + DUMP_OCTETS_PER_LINE; wasm_writef(stream, "%07" PRIzx ": ", (size_t)p - (size_t)start + offset); while (p < line_end) { int i; for (i = 0; i < DUMP_OCTETS_PER_GROUP; ++i, ++p) { if (p < end) { wasm_writef(stream, "%02x", *p); } else { wasm_write_char(stream, ' '); wasm_write_char(stream, ' '); } } wasm_write_char(stream, ' '); } wasm_write_char(stream, ' '); p = line; int i; for (i = 0; i < DUMP_OCTETS_PER_LINE && p < end; ++i, ++p) if (print_chars) wasm_write_char(stream, isprint(*p) ? *p : '.'); /* if there are multiple lines, only print the desc on the last one */ if (p >= end && desc) wasm_writef(stream, " ; %s", desc); wasm_write_char(stream, '\n'); } }
void wasm_move_data(WasmStream* stream, size_t dst_offset, size_t src_offset, size_t size) { if (WASM_FAILED(stream->result)) return; if (stream->log_stream) { wasm_writef(stream->log_stream, "; move data: [%" PRIzx ", %" PRIzx ") -> [%" PRIzx ", %" PRIzx ")\n", src_offset, src_offset + size, dst_offset, dst_offset + size); } if (stream->writer->write_data) { stream->result = stream->writer->move_data(dst_offset, src_offset, size, stream->writer->user_data); } }
static void write_const(Context* ctx, const WasmConst* const_) { wasm_writef(&ctx->json_stream, "{"); write_key(ctx, "type"); /* Always write the values as strings, even though they may be representable * as JSON numbers. This way the formatting is consistent. */ switch (const_->type) { case WASM_TYPE_I32: write_string(ctx, "i32"); write_separator(ctx); write_key(ctx, "value"); wasm_writef(&ctx->json_stream, "\"%u\"", const_->u32); break; case WASM_TYPE_I64: write_string(ctx, "i64"); write_separator(ctx); write_key(ctx, "value"); wasm_writef(&ctx->json_stream, "\"%" PRIu64 "\"", const_->u64); break; case WASM_TYPE_F32: { /* TODO(binji): write as hex float */ write_string(ctx, "f32"); write_separator(ctx); write_key(ctx, "value"); wasm_writef(&ctx->json_stream, "\"%u\"", const_->f32_bits); break; } case WASM_TYPE_F64: { /* TODO(binji): write as hex float */ write_string(ctx, "f64"); write_separator(ctx); write_key(ctx, "value"); wasm_writef(&ctx->json_stream, "\"%" PRIu64 "\"", const_->f64_bits); break; } default: assert(0); } wasm_writef(&ctx->json_stream, "}"); }
static void write_type_object(Context* ctx, WasmType type) { wasm_writef(&ctx->json_stream, "{"); write_key(ctx, "type"); write_string(ctx, wasm_get_type_name(type)); wasm_writef(&ctx->json_stream, "}"); }
static void write_var(Context* ctx, const WasmVar* var) { if (var->type == WASM_VAR_TYPE_INDEX) wasm_writef(&ctx->json_stream, "\"%" PRIu64 "\"", var->index); else write_escaped_string_slice(ctx, var->name); }
static void write_location(Context* ctx, const WasmLocation* loc) { write_key(ctx, "line"); wasm_writef(&ctx->json_stream, "%d", loc->line); }
static void write_separator(Context* ctx) { wasm_writef(&ctx->json_stream, ", "); }
static void write_key(Context* ctx, const char* key) { wasm_writef(&ctx->json_stream, "\"%s\": ", key); }
static void write_string(Context* ctx, const char* s) { wasm_writef(&ctx->json_stream, "\"%s\"", s); }