diff options
Diffstat (limited to 'src/binary-reader-opcnt.cc')
-rw-r--r-- | src/binary-reader-opcnt.cc | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/src/binary-reader-opcnt.cc b/src/binary-reader-opcnt.cc new file mode 100644 index 00000000..b79e656a --- /dev/null +++ b/src/binary-reader-opcnt.cc @@ -0,0 +1,163 @@ +/* + * 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. + */ + +#include "binary-reader-opcnt.h" + +#include <assert.h> +#include <inttypes.h> +#include <stdarg.h> +#include <stdint.h> +#include <stdio.h> + +#include "binary-reader.h" +#include "common.h" + +typedef struct Context { + WabtOpcntData* opcnt_data; +} Context; + +static WabtResult add_int_counter_value(WabtIntCounterVector* vec, + intmax_t value) { + size_t i; + for (i = 0; i < vec->size; ++i) { + if (vec->data[i].value == value) { + ++vec->data[i].count; + return WABT_OK; + } + } + WabtIntCounter counter; + counter.value = value; + counter.count = 1; + wabt_append_int_counter_value(vec, &counter); + return WABT_OK; +} + +static WabtResult add_int_pair_counter_value(WabtIntPairCounterVector* vec, + intmax_t first, + intmax_t second) { + size_t i; + for (i = 0; i < vec->size; ++i) { + if (vec->data[i].first == first && vec->data[i].second == second) { + ++vec->data[i].count; + return WABT_OK; + } + } + WabtIntPairCounter counter; + counter.first = first; + counter.second = second; + counter.count = 1; + wabt_append_int_pair_counter_value(vec, &counter); + return WABT_OK; +} + +static WabtResult on_opcode(WabtBinaryReaderContext* context, + WabtOpcode opcode) { + Context* ctx = (Context*)context->user_data; + WabtIntCounterVector* opcnt_vec = &ctx->opcnt_data->opcode_vec; + while (opcode >= opcnt_vec->size) { + WabtIntCounter Counter; + Counter.value = opcnt_vec->size; + Counter.count = 0; + wabt_append_int_counter_value(opcnt_vec, &Counter); + } + ++opcnt_vec->data[opcode].count; + return WABT_OK; +} + +static WabtResult on_i32_const_expr(uint32_t value, void* user_data) { + Context* ctx = (Context*)user_data; + return add_int_counter_value(&ctx->opcnt_data->i32_const_vec, (int32_t)value); +} + +static WabtResult on_get_local_expr(uint32_t local_index, void* user_data) { + Context* ctx = (Context*)user_data; + return add_int_counter_value(&ctx->opcnt_data->get_local_vec, local_index); +} + +static WabtResult on_set_local_expr(uint32_t local_index, void* user_data) { + Context* ctx = (Context*)user_data; + return add_int_counter_value(&ctx->opcnt_data->set_local_vec, local_index); +} + +static WabtResult on_tee_local_expr(uint32_t local_index, void* user_data) { + Context* ctx = (Context*)user_data; + return add_int_counter_value(&ctx->opcnt_data->tee_local_vec, local_index); +} + +static WabtResult on_load_expr(WabtOpcode opcode, + uint32_t alignment_log2, + uint32_t offset, + void* user_data) { + Context* ctx = (Context*)user_data; + if (opcode == WABT_OPCODE_I32_LOAD) + return add_int_pair_counter_value(&ctx->opcnt_data->i32_load_vec, + alignment_log2, offset); + return WABT_OK; +} + +static WabtResult on_store_expr(WabtOpcode opcode, + uint32_t alignment_log2, + uint32_t offset, + void* user_data) { + Context* ctx = (Context*)user_data; + if (opcode == WABT_OPCODE_I32_STORE) + return add_int_pair_counter_value(&ctx->opcnt_data->i32_store_vec, + alignment_log2, offset); + return WABT_OK; +} + +static void on_error(WabtBinaryReaderContext* ctx, const char* message) { + WabtDefaultErrorHandlerInfo info; + info.header = "error reading binary"; + info.out_file = stdout; + info.print_header = WABT_PRINT_ERROR_HEADER_ONCE; + wabt_default_binary_error_callback(ctx->offset, message, &info); +} + +void wabt_init_opcnt_data(WabtOpcntData* data) { + WABT_ZERO_MEMORY(*data); +} + +void wabt_destroy_opcnt_data(WabtOpcntData* data) { + wabt_destroy_int_counter_vector(&data->opcode_vec); + wabt_destroy_int_counter_vector(&data->i32_const_vec); + wabt_destroy_int_counter_vector(&data->get_local_vec); + wabt_destroy_int_pair_counter_vector(&data->i32_load_vec); +} + +WabtResult wabt_read_binary_opcnt(const void* data, + size_t size, + const struct WabtReadBinaryOptions* options, + WabtOpcntData* opcnt_data) { + Context ctx; + WABT_ZERO_MEMORY(ctx); + ctx.opcnt_data = opcnt_data; + + WabtBinaryReader reader; + WABT_ZERO_MEMORY(reader); + reader.user_data = &ctx; + reader.on_error = on_error; + 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 wabt_read_binary(data, size, &reader, 1, options); +} + |