Add wamrc AoT compiler building support for Windows(MSVC) (#332)
This commit is contained in:
@ -125,7 +125,11 @@ enum {
|
||||
#endif
|
||||
|
||||
/* WASM Interpreter labels-as-values feature */
|
||||
#ifdef __GNUC__
|
||||
#define WASM_ENABLE_LABELS_AS_VALUES 1
|
||||
#else
|
||||
#define WASM_ENABLE_LABELS_AS_VALUES 0
|
||||
#endif
|
||||
|
||||
/* Enable fast interpreter or not */
|
||||
#ifndef WASM_ENABLE_FAST_INTERP
|
||||
|
||||
@ -29,6 +29,16 @@ typedef struct {
|
||||
#define REG_ATOMIC_WAIT_SYM()
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN32) || defined(_WIN32_)) && defined(NDEBUG)
|
||||
#define REG_COMMON_SYMBOLS \
|
||||
REG_SYM(aot_set_exception_with_id), \
|
||||
REG_SYM(aot_invoke_native), \
|
||||
REG_SYM(aot_call_indirect), \
|
||||
REG_SYM(wasm_runtime_enlarge_memory), \
|
||||
REG_SYM(wasm_runtime_set_exception), \
|
||||
REG_BULK_MEMORY_SYM() \
|
||||
REG_ATOMIC_WAIT_SYM()
|
||||
#else /* else of (defined(_WIN32) || defined(_WIN32_)) && defined(NDEBUG) */
|
||||
#define REG_COMMON_SYMBOLS \
|
||||
REG_SYM(aot_set_exception_with_id), \
|
||||
REG_SYM(aot_invoke_native), \
|
||||
@ -49,6 +59,7 @@ typedef struct {
|
||||
REG_SYM(rintf), \
|
||||
REG_BULK_MEMORY_SYM() \
|
||||
REG_ATOMIC_WAIT_SYM()
|
||||
#endif /* end of (defined(_WIN32) || defined(_WIN32_)) && defined(NDEBUG) */
|
||||
|
||||
#define CHECK_RELOC_OFFSET(data_size) do { \
|
||||
if (!check_reloc_offset(target_section_size, reloc_offset, data_size, \
|
||||
|
||||
@ -1747,7 +1747,7 @@ aot_set_aux_stack(WASMExecEnv *exec_env,
|
||||
set the initial value for the global */
|
||||
uint32 global_offset =
|
||||
module->globals[stack_top_idx].data_offset;
|
||||
uint8 *global_addr = module_inst->global_data.ptr + global_offset;
|
||||
uint8 *global_addr = (uint8 *)module_inst->global_data.ptr + global_offset;
|
||||
*(int32*)global_addr = start_offset;
|
||||
|
||||
/* The aux stack boundary is a constant value,
|
||||
|
||||
@ -15,11 +15,13 @@ void __umoddi3();
|
||||
|
||||
static SymbolMap target_sym_map[] = {
|
||||
REG_COMMON_SYMBOLS
|
||||
#if !defined(_WIN32) && !defined(_WIN32_)
|
||||
/* compiler-rt symbols that come from compiler(e.g. gcc) */
|
||||
REG_SYM(__divdi3),
|
||||
REG_SYM(__udivdi3),
|
||||
REG_SYM(__moddi3),
|
||||
REG_SYM(__umoddi3)
|
||||
#endif
|
||||
};
|
||||
|
||||
static void
|
||||
|
||||
27
core/iwasm/common/arch/invokeNative_ia32.asm
Normal file
27
core/iwasm/common/arch/invokeNative_ia32.asm
Normal file
@ -0,0 +1,27 @@
|
||||
;
|
||||
; Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
;
|
||||
|
||||
.386
|
||||
.model flat
|
||||
.code
|
||||
_invokeNative PROC
|
||||
push ebp
|
||||
mov ebp,esp
|
||||
mov ecx, [ebp+16] ; ecx = argc */
|
||||
mov edx, [ebp+12] ; edx = argv */
|
||||
test ecx, ecx
|
||||
jz skip_push_args ; if ecx == 0, skip pushing arguments */
|
||||
lea edx, [edx+ecx*4-4] ; edx = edx + ecx * 4 - 4 */
|
||||
sub edx,esp ; edx = edx - esp */
|
||||
loop_push:
|
||||
push [esp+edx]
|
||||
loop loop_push ; loop ecx counts */
|
||||
skip_push_args:
|
||||
mov edx, [ebp+8] ; edx = func_ptr */
|
||||
call edx
|
||||
leave
|
||||
ret
|
||||
_invokeNative ENDP
|
||||
END
|
||||
@ -13,7 +13,11 @@ file (GLOB c_source_all ${IWASM_COMMON_DIR}/*.c)
|
||||
if (WAMR_BUILD_TARGET STREQUAL "X86_64" OR WAMR_BUILD_TARGET STREQUAL "AMD_64")
|
||||
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_em64.s)
|
||||
elseif (WAMR_BUILD_TARGET STREQUAL "X86_32")
|
||||
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_ia32.s)
|
||||
if (WAMR_BUILD_PLATFORM STREQUAL "windows")
|
||||
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_ia32.asm)
|
||||
else ()
|
||||
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_ia32.s)
|
||||
endif ()
|
||||
elseif (WAMR_BUILD_TARGET MATCHES "ARM.*")
|
||||
if (WAMR_BUILD_TARGET MATCHES "ARM.*_VFP")
|
||||
set (source_all ${c_source_all} ${IWASM_COMMON_DIR}/arch/invokeNative_arm_vfp.s)
|
||||
|
||||
@ -1785,7 +1785,7 @@ aot_global_set(const AOTModuleInstance *inst_aot,
|
||||
.type;
|
||||
}
|
||||
|
||||
data = inst_aot->global_data.ptr + data_offset;
|
||||
data = (void *)((uint8 *)inst_aot->global_data.ptr + data_offset);
|
||||
switch (val_type_rt) {
|
||||
case VALUE_TYPE_I32:
|
||||
bh_assert(WASM_I32 == v->kind);
|
||||
@ -1834,7 +1834,7 @@ aot_global_get(const AOTModuleInstance *inst_aot,
|
||||
.type;
|
||||
}
|
||||
|
||||
data = inst_aot->global_data.ptr + data_offset;
|
||||
data = (void *)((uint8 *)inst_aot->global_data.ptr + data_offset);
|
||||
switch (val_type_rt) {
|
||||
case VALUE_TYPE_I32:
|
||||
out->kind = WASM_I32;
|
||||
|
||||
@ -91,7 +91,9 @@ struct wasm_export_type_t {
|
||||
};
|
||||
|
||||
/* Runtime Objects */
|
||||
struct wasm_ref_t {};
|
||||
struct wasm_ref_t {
|
||||
uint32 obj;
|
||||
};
|
||||
|
||||
struct wasm_trap_t {
|
||||
wasm_byte_vec_t *message;
|
||||
|
||||
@ -8,6 +8,11 @@
|
||||
#include "wasm_export.h"
|
||||
#include "../interpreter/wasm.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN32_)
|
||||
#define strncasecmp _strnicmp
|
||||
#define strcasecmp _stricmp
|
||||
#endif
|
||||
|
||||
void
|
||||
wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
|
||||
|
||||
@ -213,8 +218,17 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
|
||||
padding = PAD_ZERO_BEFORE;
|
||||
goto still_might_format;
|
||||
}
|
||||
/* Fall through */
|
||||
case '1' ... '9':
|
||||
goto handle_1_to_9;
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
handle_1_to_9:
|
||||
if (min_width < 0) {
|
||||
min_width = *fmt - '0';
|
||||
} else {
|
||||
|
||||
18
core/shared/platform/windows/platform_init.c
Normal file
18
core/shared/platform/windows/platform_init.c
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_api_vmcore.h"
|
||||
|
||||
int
|
||||
bh_platform_init()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bh_platform_destroy()
|
||||
{
|
||||
}
|
||||
|
||||
66
core/shared/platform/windows/platform_internal.h
Normal file
66
core/shared/platform/windows/platform_internal.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _PLATFORM_INTERNAL_H
|
||||
#define _PLATFORM_INTERNAL_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdint.h>
|
||||
#include <Windows.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef BH_PLATFORM_WINDOWS
|
||||
#define BH_PLATFORM_WINDOWS
|
||||
#endif
|
||||
|
||||
/* Stack size of applet threads's native part. */
|
||||
#define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
|
||||
|
||||
/* Default thread priority */
|
||||
#define BH_THREAD_DEFAULT_PRIORITY 0
|
||||
|
||||
typedef void *korp_tid;
|
||||
typedef void *korp_mutex;
|
||||
typedef void *korp_sem;
|
||||
typedef void *korp_thread;
|
||||
|
||||
typedef struct {
|
||||
korp_sem s;
|
||||
unsigned int waiting_count;
|
||||
} korp_cond;
|
||||
|
||||
#define os_printf printf
|
||||
#define os_vprintf vprintf
|
||||
|
||||
static inline size_t getpagesize() {
|
||||
SYSTEM_INFO S;
|
||||
GetNativeSystemInfo(&S);
|
||||
return S.dwPageSize;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _PLATFORM_INTERNAL_H */
|
||||
|
||||
27
core/shared/platform/windows/posix_malloc.c
Normal file
27
core/shared/platform/windows/posix_malloc.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_api_vmcore.h"
|
||||
|
||||
void *
|
||||
os_malloc(unsigned size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void *
|
||||
os_realloc(void *ptr, unsigned size)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
void
|
||||
os_free(void *ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
18
core/shared/platform/windows/shared_platform.cmake
Normal file
18
core/shared/platform/windows/shared_platform.cmake
Normal file
@ -0,0 +1,18 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (PLATFORM_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_definitions(-DBH_PLATFORM_WINDOWS)
|
||||
add_definitions(-DHAVE_STRUCT_TIMESPEC)
|
||||
|
||||
|
||||
include_directories(${PLATFORM_SHARED_DIR})
|
||||
include_directories(${PLATFORM_SHARED_DIR}/../include)
|
||||
|
||||
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
||||
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all})
|
||||
|
||||
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
|
||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
||||
79
core/shared/platform/windows/win_memmap.c
Normal file
79
core/shared/platform/windows/win_memmap.c
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_api_vmcore.h"
|
||||
void * os_mmap(void *hint, size_t size, int prot, int flags)
|
||||
{
|
||||
DWORD AllocType = MEM_RESERVE | MEM_COMMIT;
|
||||
DWORD flProtect = PAGE_NOACCESS;
|
||||
size_t request_size, page_size;
|
||||
void *addr;
|
||||
|
||||
page_size = getpagesize();
|
||||
request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||
|
||||
if (request_size < size)
|
||||
/* integer overflow */
|
||||
return NULL;
|
||||
|
||||
if (prot & MMAP_PROT_EXEC) {
|
||||
if (prot & MMAP_PROT_WRITE)
|
||||
flProtect = PAGE_EXECUTE_READWRITE;
|
||||
else
|
||||
flProtect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
else if (prot & MMAP_PROT_WRITE)
|
||||
flProtect = PAGE_READWRITE;
|
||||
else if (prot & MMAP_PROT_READ)
|
||||
flProtect = PAGE_READONLY;
|
||||
|
||||
|
||||
addr = VirtualAlloc((LPVOID)hint, request_size, AllocType,
|
||||
flProtect);
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
os_munmap(void *addr, size_t size)
|
||||
{
|
||||
size_t page_size = getpagesize();
|
||||
size_t request_size = (size + page_size - 1) & ~(page_size - 1);
|
||||
if (addr) {
|
||||
|
||||
if (VirtualFree(addr, 0, MEM_RELEASE) == 0) {
|
||||
if (VirtualFree(addr, size, MEM_DECOMMIT) == 0) {
|
||||
os_printf("os_munmap error addr:%p, size:0x%lx, errno:%d\n",
|
||||
addr, request_size, errno);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
os_mprotect(void *addr, size_t size, int prot)
|
||||
{
|
||||
DWORD AllocType = MEM_RESERVE | MEM_COMMIT;
|
||||
DWORD flProtect = PAGE_NOACCESS;
|
||||
if (!addr)
|
||||
return 0;
|
||||
|
||||
if (prot & MMAP_PROT_EXEC) {
|
||||
if (prot & MMAP_PROT_WRITE)
|
||||
flProtect = PAGE_EXECUTE_READWRITE;
|
||||
else
|
||||
flProtect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
else if (prot & MMAP_PROT_WRITE)
|
||||
flProtect = PAGE_READWRITE;
|
||||
else if (prot & MMAP_PROT_READ)
|
||||
flProtect = PAGE_READONLY;
|
||||
|
||||
return VirtualProtect((LPVOID)addr, size, flProtect, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
os_dcache_flush(void)
|
||||
{
|
||||
}
|
||||
162
core/shared/platform/windows/win_thread.c
Normal file
162
core/shared/platform/windows/win_thread.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include "platform_api_vmcore.h"
|
||||
#include "platform_api_extension.h"
|
||||
|
||||
typedef struct {
|
||||
thread_start_routine_t start;
|
||||
void* stack;
|
||||
uint32 stack_size;
|
||||
void* arg;
|
||||
} thread_wrapper_arg;
|
||||
|
||||
static void *os_thread_wrapper(void *arg)
|
||||
{
|
||||
thread_wrapper_arg * targ = arg;
|
||||
thread_start_routine_t start_func = targ->start;
|
||||
void *thread_arg = targ->arg;
|
||||
os_printf("THREAD CREATED %p\n", &targ);
|
||||
targ->stack = (void *)((uintptr_t)(&arg) & (uintptr_t)~0xfff);
|
||||
BH_FREE(targ);
|
||||
start_func(thread_arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int os_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
|
||||
void *arg, unsigned int stack_size, int prio)
|
||||
{
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
int os_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
|
||||
unsigned int stack_size)
|
||||
{
|
||||
return os_thread_create_with_prio(tid, start, arg, stack_size,
|
||||
BH_THREAD_DEFAULT_PRIORITY);
|
||||
}
|
||||
|
||||
korp_tid os_self_thread()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int os_mutex_init(korp_mutex *mutex)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_recursive_mutex_init(korp_mutex *mutex)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_mutex_destroy(korp_mutex *mutex)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
/* Returned error (EINVAL, EAGAIN and EDEADLK) from
|
||||
locking the mutex indicates some logic error present in
|
||||
the program somewhere.
|
||||
Don't try to recover error for an existing unknown error.*/
|
||||
int os_mutex_lock(korp_mutex *mutex)
|
||||
{
|
||||
return BHT_ERROR;
|
||||
}
|
||||
|
||||
/* Returned error (EINVAL, EAGAIN and EPERM) from
|
||||
unlocking the mutex indicates some logic error present
|
||||
in the program somewhere.
|
||||
Don't try to recover error for an existing unknown error.*/
|
||||
int os_mutex_unlock(korp_mutex *mutex)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_cond_init(korp_cond *cond)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_cond_destroy(korp_cond *cond)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_cond_wait(korp_cond *cond, korp_mutex *mutex)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
|
||||
int gettimeofday(struct timeval * tp, struct timezone * tzp)
|
||||
{
|
||||
// Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's
|
||||
// This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC)
|
||||
// until 00:00:00 January 1, 1970
|
||||
static const uint64_t EPOCH = ((uint64_t) 116444736000000000ULL);
|
||||
|
||||
SYSTEMTIME system_time;
|
||||
FILETIME file_time;
|
||||
uint64_t time;
|
||||
|
||||
GetSystemTime( &system_time );
|
||||
SystemTimeToFileTime( &system_time, &file_time );
|
||||
time = ((uint64_t)file_time.dwLowDateTime ) ;
|
||||
time += ((uint64_t)file_time.dwHighDateTime) << 32;
|
||||
|
||||
tp->tv_sec = (long) ((time - EPOCH) / 10000000L);
|
||||
tp->tv_usec = (long) (system_time.wMilliseconds * 1000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void msec_nsec_to_abstime(struct timespec *ts, int usec)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
ts->tv_sec = (long int)(tv.tv_sec + usec / 1000000);
|
||||
ts->tv_nsec = (long int)(tv.tv_usec * 1000 + (usec % 1000000) * 1000);
|
||||
|
||||
if (ts->tv_nsec >= 1000000000L) {
|
||||
ts->tv_sec++;
|
||||
ts->tv_nsec -= 1000000000L;
|
||||
}
|
||||
}
|
||||
|
||||
int os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int useconds)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_cond_signal(korp_cond *cond)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_thread_join(korp_tid thread, void **value_ptr)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
int os_thread_detach(korp_tid thread)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
void os_thread_exit(void *retval)
|
||||
{
|
||||
return BHT_OK;
|
||||
}
|
||||
|
||||
uint8 *os_thread_get_stack_boundary()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
16
core/shared/platform/windows/win_time.c
Normal file
16
core/shared/platform/windows/win_time.c
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "platform_api_vmcore.h"
|
||||
|
||||
uint64
|
||||
os_time_get_boot_microsecond()
|
||||
{
|
||||
struct timespec ts;
|
||||
timespec_get(&ts, TIME_UTC);
|
||||
|
||||
return ((uint64) ts.tv_sec) * 1000 * 1000 + ((uint64)ts.tv_nsec) / 1000;
|
||||
}
|
||||
|
||||
@ -2,8 +2,59 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#if defined(_WIN32) || defined(_WIN32_)
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN32_)
|
||||
char*
|
||||
bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
|
||||
{
|
||||
char *buffer;
|
||||
int file;
|
||||
uint32 file_size, read_size;
|
||||
struct stat stat_buf;
|
||||
|
||||
if (!filename || !ret_size) {
|
||||
printf("Read file to buffer failed: invalid filename or ret size.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_sopen_s(&file, filename, _O_RDONLY| _O_BINARY, _SH_DENYNO, 0)) {
|
||||
printf("Read file to buffer failed: open file %s failed.\n",
|
||||
filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fstat(file, &stat_buf) != 0) {
|
||||
printf("Read file to buffer failed: fstat file %s failed.\n",
|
||||
filename);
|
||||
_close(file);
|
||||
return NULL;
|
||||
}
|
||||
file_size = (uint32)stat_buf.st_size;
|
||||
|
||||
if (!(buffer = (char *)BH_MALLOC(file_size))) {
|
||||
printf("Read file to buffer failed: alloc memory failed.\n");
|
||||
_close(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
read_size = _read(file, buffer, file_size);
|
||||
_close(file);
|
||||
|
||||
if (read_size < file_size) {
|
||||
printf("Read file to buffer failed: read file content failed.\n");
|
||||
BH_FREE(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*ret_size = file_size;
|
||||
return buffer;
|
||||
}
|
||||
#else /* else of defined(_WIN32) || defined(_WIN32_) */
|
||||
char*
|
||||
bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
|
||||
{
|
||||
@ -50,4 +101,4 @@ bh_read_file_to_buffer(const char *filename, uint32 *ret_size)
|
||||
*ret_size = file_size;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
#endif /* end of defined(_WIN32) || defined(_WIN32_) */
|
||||
|
||||
Reference in New Issue
Block a user