WasmResult wasm_ast_lexer_get_source_line(WasmAstLexer* lexer,
                                          const WasmLocation* loc,
                                          size_t line_max_length,
                                          char* line,
                                          size_t* out_line_length,
                                          int* out_column_offset) {
  WasmResult result;
  size_t line_start; /* inclusive */
  size_t line_end;   /* exclusive */
  result = get_offsets_from_line(lexer, loc->line, &line_start, &line_end);
  if (WASM_FAILED(result))
    return result;

  size_t new_line_start;
  size_t new_line_end;
  clamp_source_line_offsets_to_location(line_start, line_end, loc->first_column,
                                        loc->last_column, line_max_length,
                                        &new_line_start, &new_line_end);
  WasmBool has_start_ellipsis = line_start != new_line_start;
  WasmBool has_end_ellipsis = line_end != new_line_end;

  char* write_start = line;
  size_t line_length = new_line_end - new_line_start;
  size_t read_start = new_line_start;
  size_t read_length = line_length;
  if (has_start_ellipsis) {
    memcpy(line, "...", 3);
    read_start += 3;
    write_start += 3;
    read_length -= 3;
  }
  if (has_end_ellipsis) {
    memcpy(line + line_length - 3, "...", 3);
    read_length -= 3;
  }

  if (lexer->source.type == WASM_LEXER_SOURCE_TYPE_BUFFER) {
    char* buffer_read_start = (char*)lexer->source.buffer.data + read_start;
    memcpy(write_start, buffer_read_start, read_length);
  } else {
    assert(lexer->source.type == WASM_LEXER_SOURCE_TYPE_FILE);
    FILE* lexer_file = lexer->source.file;
    long old_offset = ftell(lexer_file);
    if (old_offset == -1)
      return WASM_ERROR;
    if (fseek(lexer_file, read_start, SEEK_SET) == -1)
      return WASM_ERROR;
    if (fread(write_start, 1, read_length, lexer_file) < read_length)
      return WASM_ERROR;
    if (fseek(lexer_file, old_offset, SEEK_SET) == -1)
      return WASM_ERROR;
  }

  line[line_length] = '\0';

  *out_line_length = line_length;
  *out_column_offset = new_line_start - line_start;
  return WASM_OK;
}
static WasmResult get_offsets_from_line(WasmAstLexer* lexer,
                                        int line,
                                        size_t* out_line_start,
                                        size_t* out_line_end) {
  size_t line_start;
  if (WASM_FAILED(get_line_start_offset(lexer, line, &line_start)))
    return WASM_ERROR;

  size_t line_end;
  if (WASM_FAILED(scan_forward_for_line_offset(lexer, line, line_start,
                                               WASM_LINE_OFFSET_POSITION_END,
                                               line, &line_end)))
    return WASM_ERROR;
  *out_line_start = line_start;
  *out_line_end = line_end;
  return WASM_OK;
}
Example #3
0
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);
  }
}
Example #4
0
void wasm_write_data_at(WasmStream* stream,
                        size_t offset,
                        const void* src,
                        size_t size,
                        WasmPrintChars print_chars,
                        const char* desc) {
  if (WASM_FAILED(stream->result))
    return;
  if (stream->log_stream) {
    wasm_write_memory_dump(stream->log_stream, src, size, offset, print_chars,
                           desc);
  }
  if (stream->writer->write_data) {
    stream->result = stream->writer->write_data(offset, src, size,
                                                stream->writer->user_data);
  }
}
int main(int argc, char** argv) {
  WasmStackAllocator stack_allocator;
  WasmAllocator* allocator;

  wasm_init_stdio();

  wasm_init_file_writer_existing(&s_log_stream_writer, stdout);
  wasm_init_stream(&s_log_stream, &s_log_stream_writer.base, NULL);
  parse_options(argc, argv);

  if (s_use_libc_allocator) {
    allocator = &g_wasm_libc_allocator;
  } else {
    wasm_init_stack_allocator(&stack_allocator, &g_wasm_libc_allocator);
    allocator = &stack_allocator.allocator;
  }

  WasmAstLexer* lexer = wasm_new_ast_file_lexer(allocator, s_infile);
  if (!lexer)
    WASM_FATAL("unable to read %s\n", s_infile);

  WasmScript script;
  WasmResult result = wasm_parse_ast(lexer, &script, &s_error_handler);

  if (WASM_SUCCEEDED(result)) {
    result =
        wasm_resolve_names_script(allocator, lexer, &script, &s_error_handler);

    if (WASM_SUCCEEDED(result) && s_validate) {
      result =
          wasm_validate_script(allocator, lexer, &script, &s_error_handler);
    }

    if (WASM_SUCCEEDED(result) && s_validate_assert_invalid_and_malformed) {
      WasmDefaultErrorHandlerInfo assert_invalid_info;
      WasmSourceErrorHandler assert_invalid_error_handler;
      init_source_error_handler(&assert_invalid_error_handler,
                                &assert_invalid_info, "assert_invalid error");

      WasmDefaultErrorHandlerInfo assert_malformed_info;
      WasmSourceErrorHandler assert_malformed_error_handler;
      init_source_error_handler(&assert_malformed_error_handler,
                                &assert_malformed_info,
                                "assert_malformed error");

      result = wasm_validate_assert_invalid_and_malformed(
          allocator, lexer, &script, &assert_invalid_error_handler,
          &assert_malformed_error_handler, &s_error_handler);
    }

    if (WASM_SUCCEEDED(result)) {
      if (s_spec) {
        s_write_binary_spec_options.json_filename = s_outfile;
        s_write_binary_spec_options.write_binary_options =
            s_write_binary_options;
        result = wasm_write_binary_spec_script(allocator, &script, s_infile,
                                               &s_write_binary_spec_options);
      } else {
        WasmMemoryWriter writer;
        WASM_ZERO_MEMORY(writer);
        if (WASM_FAILED(wasm_init_mem_writer(allocator, &writer)))
          WASM_FATAL("unable to open memory writer for writing\n");

        result = wasm_write_binary_script(allocator, &writer.base, &script,
                                          &s_write_binary_options);
        if (WASM_SUCCEEDED(result))
          write_buffer_to_file(s_outfile, &writer.buf);
        wasm_close_mem_writer(&writer);
      }
    }
  }

  wasm_destroy_ast_lexer(lexer);

  if (s_use_libc_allocator)
    wasm_destroy_script(&script);
  wasm_print_allocator_stats(allocator);
  wasm_destroy_allocator(allocator);
  return result;
}