Add unit test suites (#3490)

This commit is contained in:
Zhang, Yi 2024-06-04 11:24:27 +08:00 committed by GitHub
parent 0a80cc4e94
commit 380cd7b0e7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
194 changed files with 14104 additions and 34 deletions

View File

@ -1,51 +1,52 @@
# Copyright (C) 2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required (VERSION 3.14)
cmake_minimum_required(VERSION 2.9)
project (wamr_unit_tests)
project(unit-test)
include (CTest)
SET(CMAKE_BUILD_TYPE Debug)
if (NOT DEFINED WAMR_BUILD_INTERP)
# Enable Interpreter by default
set (WAMR_BUILD_INTERP 1)
endif ()
# add_definitions (-m32)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
if (NOT DEFINED WAMR_BUILD_PLATFORM)
string (TOLOWER ${CMAKE_HOST_SYSTEM_NAME} WAMR_BUILD_PLATFORM)
endif ()
if(WAMR_BUILD_TARGET STREQUAL "X86_32")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
endif()
set (WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
add_library (vmlib ${WAMR_RUNTIME_LIB_SOURCE})
# Prevent overriding the parent project's compiler/linker
# settings on Windows
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# Fetch Google test
include (FetchContent)
FetchContent_Declare (
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# For Windows: Prevent overriding the parent project's compiler/linker settings
set (gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable (googletest)
include (GoogleTest)
SET(GOOGLETEST_INCLUDED 1)
add_library (wamr_gtest_main main.cpp)
target_link_libraries (wamr_gtest_main PUBLIC gtest vmlib)
include(GoogleTest)
enable_testing()
function (create_wamr_unit_test test_name)
set (sources ${ARGN})
add_executable (${test_name} ${sources})
target_link_libraries (
${test_name}
wamr_gtest_main
vmlib
${LLVM_AVAILABLE_LIBS}
)
gtest_discover_tests (${test_name})
endfunction ()
if (WAMR_BUILD_LIB_WASI_THREADS EQUAL 1)
include (${IWASM_DIR}/libraries/lib-wasi-threads/unit-test/lib_wasi_threads_unit_tests.cmake)
endif ()
add_subdirectory(wasm-vm)
add_subdirectory(interpreter)
add_subdirectory(aot)
add_subdirectory(wasm-c-api)
add_subdirectory(libc-builtin)
add_subdirectory(shared-utils)
add_subdirectory(running-modes)
add_subdirectory(runtime-common)
add_subdirectory(custom-section)
add_subdirectory(compilation)
add_subdirectory(linear-memory-wasm)
add_subdirectory(linear-memory-aot)
add_subdirectory(aot-stack-frame)
add_subdirectory(linux-perf)
add_subdirectory(gc)
add_subdirectory(memory64)
add_subdirectory(tid-allocator)

View File

@ -0,0 +1,55 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-aot-stack-frame)
add_definitions (-DRUN_ON_LINUX)
set (WAMR_BUILD_AOT 1)
set (WAMR_BUILD_INTERP 0)
set (WAMR_BUILD_JIT 0)
set (WAMR_BUILD_SIMD 1)
set (WAMR_BUILD_REF_TYPES 1)
set (WAMR_BUILD_LIBC_WASI 0)
set (WAMR_BUILD_LIBC_BUILTIN 0)
set (WAMR_BUILD_MULTI_MODULE 0)
set (WAMR_DISABLE_HW_BOUND_CHECK 1)
set (WAMR_DISABLE_WRITE_GS_BASE 1)
include (../unit_common.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
add_definitions (-DAOT_STACK_FRAME_DEBUG)
#add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${PLATFORM_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${NATIVE_INTERFACE_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
${IWASM_AOT_SOURCE}
${WASM_APP_LIB_SOURCE_ALL}
)
# Automatically build wasm-apps for this test
add_subdirectory(wasm-apps)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable (aot_stack_frame_test ${unit_test_sources})
add_dependencies (aot_stack_frame_test aot-stack-frame-test-wasm)
target_link_libraries (aot_stack_frame_test ${LLVM_AVAILABLE_LIBS} gtest_main )
#gtest_discover_tests(aot_stack_frame_test)

View File

@ -0,0 +1,288 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "gtest/gtest.h"
#include "bh_platform.h"
#include "wasm_runtime_common.h"
#include "aot_runtime.h"
#include "test_helper.h"
#ifndef __aligned
#define __aligned(n)
#endif
#include "wasm-apps/test_aot.h"
typedef struct MyAOTFrame {
uintptr_t func_index;
/* Instruction pointer: offset to the bytecode array */
uintptr_t ip_offset;
/* Operand stack top pointer of the current frame */
uint32 *sp;
#if WASM_ENABLE_GC != 0
/* Frame ref flags (GC only) */
uint8 *frame_ref;
#endif
uint32 lp[1];
} MyAOTFrame;
class AOTStackFrameTest : public testing::Test
{
protected:
virtual void SetUp()
{
memset(&init_args, 0, sizeof(RuntimeInitArgs));
init_args.mem_alloc_type = Alloc_With_Pool;
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
ASSERT_EQ(wasm_runtime_full_init(&init_args), true);
}
virtual void TearDown()
{
DestroyFrames();
wasm_runtime_destroy();
}
public:
static void DestroyFrames()
{
if (my_frames) {
for (uint32 i = 0; i < my_frame_num; i++) {
if (my_frames[i])
wasm_runtime_free(my_frames[i]);
}
wasm_runtime_free(my_frames);
my_frames = NULL;
my_frame_num = 0;
}
}
public:
RuntimeInitArgs init_args;
wasm_module_t module = NULL;
wasm_module_inst_t module_inst = NULL;
wasm_function_inst_t func_inst = NULL;
wasm_exec_env_t exec_env = NULL;
static MyAOTFrame **my_frames;
static uint32 my_frame_num;
char error_buf[128];
char global_heap_buf[512 * 1024];
unsigned char test_aot_buf[16 * 1024];
unsigned argv[8];
};
MyAOTFrame **AOTStackFrameTest::my_frames = NULL;
uint32 AOTStackFrameTest::my_frame_num = 0;
extern "C" {
typedef void (*stack_frame_callback_t)(struct WASMExecEnv *exec_env);
void
aot_set_stack_frame_callback(stack_frame_callback_t callback);
void
aot_stack_frame_cb(struct WASMExecEnv *exec_env)
{
AOTModuleInstance *module_inst = (AOTModuleInstance *)exec_env->module_inst;
AOTModule *module = (AOTModule *)module_inst->module;
AOTFrame *frame = (AOTFrame *)exec_env->cur_frame;
MyAOTFrame *my_frame, **my_frames;
uint32 all_cell_num, max_local_cell_num, max_stack_cell_num;
uint32 frame_size_old, frame_size, i, frame_num = 0, aot_func_idx;
AOTStackFrameTest::DestroyFrames();
while (frame) {
frame_num++;
frame = frame->prev_frame;
}
my_frames =
(MyAOTFrame **)wasm_runtime_malloc(sizeof(MyAOTFrame *) * frame_num);
bh_assert(my_frames);
frame = (AOTFrame *)exec_env->cur_frame;
for (i = 0; i < frame_num; i++) {
aot_func_idx = frame->func_index;
max_local_cell_num = module->max_local_cell_nums[aot_func_idx];
max_stack_cell_num = module->max_stack_cell_nums[aot_func_idx];
all_cell_num = max_local_cell_num + max_stack_cell_num;
frame_size_old = (uint32)offsetof(AOTFrame, lp) + all_cell_num * 4;
frame_size = (uint32)offsetof(MyAOTFrame, lp) + all_cell_num * 4;
my_frames[frame_num - 1 - i] = my_frame =
(MyAOTFrame *)wasm_runtime_malloc(frame_size);
my_frame->func_index = aot_func_idx;
my_frame->ip_offset = frame->ip_offset;
my_frame->sp = my_frame->lp + (frame->sp - frame->lp);
#if WASM_ENABLE_GC != 0
my_frame->frame_ref =
(uint8 *)my_frame->lp + (frame->frame_ref - (uint8 *)frame->lp);
#endif
bh_memcpy_s(my_frame->lp, all_cell_num * 4, frame->lp,
all_cell_num * 4);
frame = frame->prev_frame;
}
AOTStackFrameTest::my_frames = my_frames;
AOTStackFrameTest::my_frame_num = frame_num;
}
}
TEST_F(AOTStackFrameTest, test1)
{
MyAOTFrame *frame, **frames;
uint32 frame_num;
aot_set_stack_frame_callback(aot_stack_frame_cb);
bh_memcpy_s(test_aot_buf, sizeof(test_aot_buf), test_aot, sizeof(test_aot));
module = wasm_runtime_load(test_aot_buf, sizeof(test_aot), error_buf,
sizeof(error_buf));
ASSERT_TRUE(module != NULL);
module_inst = wasm_runtime_instantiate(module, 16384, 0, error_buf,
sizeof(error_buf));
ASSERT_TRUE(module_inst != NULL);
exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
ASSERT_TRUE(exec_env != NULL);
func_inst = wasm_runtime_lookup_function(module_inst, "test1");
ASSERT_TRUE(func_inst != NULL);
argv[0] = 33;
argv[1] = 44;
wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
ASSERT_TRUE(wasm_runtime_get_exception(module_inst));
frames = AOTStackFrameTest::my_frames;
frame_num = AOTStackFrameTest::my_frame_num;
ASSERT_TRUE(frames != NULL);
ASSERT_TRUE(frame_num == 1);
ASSERT_TRUE(frames[0]->lp[0] == 33);
ASSERT_TRUE(frames[0]->lp[1] == 44);
ASSERT_TRUE(frames[0]->lp[2] == 0x11223344);
ASSERT_TRUE(*(uint64 *)(frames[0]->lp + 3) == 0x12345678ABCDEF99LL);
ASSERT_TRUE(*(float *)(frames[0]->lp + 5) == 5566.7788f);
ASSERT_TRUE(*(double *)(frames[0]->lp + 6) == 99887766.55443322);
wasm_runtime_destroy_exec_env(exec_env);
exec_env = NULL;
wasm_runtime_deinstantiate(module_inst);
module_inst = NULL;
wasm_runtime_unload(module);
module = NULL;
}
TEST_F(AOTStackFrameTest, test2)
{
MyAOTFrame *frame, **frames;
uint32 frame_num;
aot_set_stack_frame_callback(aot_stack_frame_cb);
bh_memcpy_s(test_aot_buf, sizeof(test_aot_buf), test_aot, sizeof(test_aot));
module = wasm_runtime_load(test_aot_buf, sizeof(test_aot), error_buf,
sizeof(error_buf));
ASSERT_TRUE(module != NULL);
module_inst = wasm_runtime_instantiate(module, 16384, 0, error_buf,
sizeof(error_buf));
ASSERT_TRUE(module_inst != NULL);
exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
ASSERT_TRUE(exec_env != NULL);
func_inst = wasm_runtime_lookup_function(module_inst, "test2");
ASSERT_TRUE(func_inst != NULL);
argv[0] = 1234;
argv[1] = 5678;
wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
ASSERT_TRUE(wasm_runtime_get_exception(module_inst));
frames = AOTStackFrameTest::my_frames;
frame_num = AOTStackFrameTest::my_frame_num;
ASSERT_TRUE(frames != NULL);
ASSERT_TRUE(frame_num == 1);
ASSERT_TRUE(frames[0]->lp[0] == 1234);
ASSERT_TRUE(frames[0]->lp[1] == 5678);
ASSERT_TRUE(frames[0]->lp[2] == 0x11223344);
ASSERT_TRUE(*(uint64 *)(frames[0]->lp + 3) == 0x12345678ABCDEF99LL);
ASSERT_TRUE(*(float *)(frames[0]->lp + 5) == 5566.7788f);
ASSERT_TRUE(*(double *)(frames[0]->lp + 6) == 99887766.55443322);
ASSERT_TRUE(frames[0]->lp[8] == 0x1234);
ASSERT_TRUE(frames[0]->lp[9] == 0x5678);
}
TEST_F(AOTStackFrameTest, test3)
{
MyAOTFrame *frame, **frames;
uint32 frame_num;
aot_set_stack_frame_callback(aot_stack_frame_cb);
bh_memcpy_s(test_aot_buf, sizeof(test_aot_buf), test_aot, sizeof(test_aot));
module = wasm_runtime_load(test_aot_buf, sizeof(test_aot), error_buf,
sizeof(error_buf));
ASSERT_TRUE(module != NULL);
module_inst = wasm_runtime_instantiate(module, 16384, 0, error_buf,
sizeof(error_buf));
ASSERT_TRUE(module_inst != NULL);
exec_env = wasm_runtime_create_exec_env(module_inst, 8 * 1024);
ASSERT_TRUE(exec_env != NULL);
func_inst = wasm_runtime_lookup_function(module_inst, "test3");
ASSERT_TRUE(func_inst != NULL);
argv[0] = 1234;
argv[1] = 5678;
wasm_runtime_call_wasm(exec_env, func_inst, 2, argv);
ASSERT_TRUE(wasm_runtime_get_exception(module_inst));
frames = AOTStackFrameTest::my_frames;
frame_num = AOTStackFrameTest::my_frame_num;
ASSERT_TRUE(frames != NULL);
ASSERT_TRUE(frame_num == 2);
ASSERT_TRUE(frames[0]->sp - frames[0]->lp == 5);
ASSERT_TRUE(frames[0]->ip_offset == 24);
ASSERT_TRUE(frames[0]->lp[0] == 1234);
ASSERT_TRUE(frames[0]->lp[1] == 5678);
ASSERT_TRUE(frames[0]->lp[2] == 0x11223344);
ASSERT_TRUE(*(uint64 *)(frames[0]->lp + 3) == 0x12345678ABCDEF99LL);
ASSERT_TRUE(frames[1]->lp[0] == 0x1234);
ASSERT_TRUE(frames[1]->lp[1] == 0x5678);
ASSERT_TRUE(frames[1]->lp[2] == 0x11223344);
ASSERT_TRUE(*(uint64 *)(frames[1]->lp + 3) == 0x12345678ABCDEF99LL);
ASSERT_TRUE(*(float *)(frames[1]->lp + 5) == 5566.7788f);
ASSERT_TRUE(*(double *)(frames[1]->lp + 6) == 99887766.55443322);
}

View File

@ -0,0 +1,27 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project(wasm-apps-aot-stack-frame)
add_custom_target(aot-stack-frame-test-wasm ALL
COMMAND cmake -B ${CMAKE_CURRENT_BINARY_DIR}/build-wamrc
-S ${WAMR_ROOT_DIR}/wamr-compiler
&& cmake --build ${CMAKE_CURRENT_BINARY_DIR}/build-wamrc
&& /opt/wabt/bin/wat2wasm
-o ${CMAKE_CURRENT_BINARY_DIR}/test.wasm
${CMAKE_CURRENT_LIST_DIR}/test.wast
&& ${CMAKE_CURRENT_BINARY_DIR}/build-wamrc/wamrc
--enable-dump-call-stack --bounds-checks=1
-o ${CMAKE_CURRENT_BINARY_DIR}/test.aot
${CMAKE_CURRENT_BINARY_DIR}/test.wasm
&& cmake -B ${CMAKE_CURRENT_BINARY_DIR}/build-binarydump
-S ${WAMR_ROOT_DIR}/test-tools/binarydump-tool
&& cmake --build ${CMAKE_CURRENT_BINARY_DIR}/build-binarydump
&& ${CMAKE_CURRENT_BINARY_DIR}/build-binarydump/binarydump
-o ${CMAKE_CURRENT_LIST_DIR}/test_aot.h -n test_aot
${CMAKE_CURRENT_BINARY_DIR}/test.aot
)

View File

@ -0,0 +1,36 @@
(module
(func $test1 (export "test1") (param i32 i32) (result i32)
i32.const 0x11223344
i64.const 0x1234_5678_ABCD_EF99
f32.const 5566.7788
f64.const 99887766.55443322
unreachable
)
(func $test2 (export "test2") (param f32 f32) (result i32)
i32.const 0x11223344
i64.const 0x1234_5678_ABCD_EF99
f32.const 5566.7788
f64.const 99887766.55443322
loop
i32.const 0x1234
i32.const 0x5678
unreachable
end
unreachable
)
(func $test3 (export "test3") (param i32 i32) (result i32)
i32.const 0x11223344
i64.const 0x1234_5678_ABCD_EF99
i32.const 0x1234
i32.const 0x5678
call $test1
drop
drop
)
)

View File

@ -0,0 +1,59 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-aot)
add_definitions (-DRUN_ON_LINUX)
add_definitions (-Dattr_container_malloc=malloc)
add_definitions (-Dattr_container_free=free)
add_definitions (-DWASM_ENABLE_WAMR_COMPILER=1)
add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
set (WAMR_BUILD_LIBC_WASI 0)
set (WAMR_BUILD_APP_FRAMEWORK 1)
include (../unit_common.cmake)
set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
if (NOT EXISTS "${LLVM_SRC_ROOT}/build")
message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build")
endif ()
set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}")
find_package(LLVM REQUIRED CONFIG)
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include (${IWASM_DIR}/compilation/iwasm_compl.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${PLATFORM_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${NATIVE_INTERFACE_SOURCE}
${LIBC_BUILTIN_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
${IWASM_AOT_SOURCE}
${IWASM_COMPL_SOURCE}
)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable (aot_test ${unit_test_sources})
target_link_libraries (aot_test ${LLVM_AVAILABLE_LIBS} gtest_main )
gtest_discover_tests(aot_test)

1190
tests/unit/aot/aot_test.cc Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,89 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#pragma once
#include "wasm_export.h"
#include <functional>
template<int MaxAllocCount>
class MockAllocator
{
private:
RuntimeInitArgs init_args;
public:
MockAllocator()
{
memset(&init_args, 0, sizeof(RuntimeInitArgs));
init_args.mem_alloc_type = Alloc_With_Allocator;
init_args.mem_alloc_option.allocator.malloc_func = (void *)my_malloc;
init_args.mem_alloc_option.allocator.realloc_func = (void *)realloc;
init_args.mem_alloc_option.allocator.free_func = (void *)free;
/* Set count to INT32_MIN so the initialization will not fail */
alloc_count = INT32_MIN;
wasm_runtime_full_init(&init_args);
reset_count();
}
~MockAllocator() { wasm_runtime_destroy(); }
void reset_count() { alloc_count = 0; }
protected:
static int32_t alloc_count;
static void *my_malloc(int32_t size)
{
if (alloc_count >= MaxAllocCount) {
return nullptr;
}
alloc_count++;
return malloc(size);
}
};
template<int MaxAllocCount>
int32_t MockAllocator<MaxAllocCount>::alloc_count = 0;
class DumpAllocUsage : public MockAllocator<INT32_MAX>
{
public:
DumpAllocUsage()
: MockAllocator<INT32_MAX>()
{}
~DumpAllocUsage()
{
std::cout << "Alloc usage count: " << alloc_count << std::endl;
}
};
template<int AllocRequired>
void
LIMIT_MALLOC_COUNT(std::function<void()> func)
{
{
MockAllocator<AllocRequired> allocator;
func();
}
if (AllocRequired > 1)
LIMIT_MALLOC_COUNT<AllocRequired - 1>(func);
}
template<>
void
LIMIT_MALLOC_COUNT<0>(std::function<void()> func)
{
{
MockAllocator<0> allocator;
func();
}
}

View File

@ -0,0 +1,325 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#pragma once
#include "wasm_export.h"
#include "gtest/gtest.h"
#include <iostream>
#include <memory>
#include <fstream>
template<int Size = 512 * 1024>
class WAMRRuntimeRAII
{
private:
char global_heap_buf[Size];
RuntimeInitArgs init_args;
public:
WAMRRuntimeRAII()
{
memset(&init_args, 0, sizeof(RuntimeInitArgs));
init_args.mem_alloc_type = Alloc_With_Pool;
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
wasm_runtime_full_init(&init_args);
}
~WAMRRuntimeRAII() { wasm_runtime_destroy(); }
};
class WAMRModule
{
private:
wasm_module_t module_;
public:
WAMRModule(uint8_t *buffer, uint32_t size)
{
module_ = wasm_runtime_load(buffer, size, NULL, 0);
}
~WAMRModule() { wasm_runtime_unload(module_); }
wasm_module_t get() const { return module_; }
};
class WAMRInstance
{
private:
wasm_module_inst_t module_inst_;
public:
WAMRInstance(WAMRModule &module, uint32_t stack_size = 8192,
uint32_t heap_size = 8192)
{
module_inst_ = wasm_runtime_instantiate(module.get(), stack_size,
heap_size, NULL, 0);
}
~WAMRInstance() { wasm_runtime_deinstantiate(module_inst_); }
wasm_module_inst_t get() const { return module_inst_; }
};
class WAMRExecEnv
{
private:
wasm_exec_env_t exec_env_;
public:
WAMRExecEnv(WAMRInstance &instance, uint32_t stack_size = 8192)
{
exec_env_ = wasm_runtime_create_exec_env(instance.get(), stack_size);
}
~WAMRExecEnv() { wasm_runtime_destroy_exec_env(exec_env_); }
wasm_exec_env_t get() const { return exec_env_; }
wasm_module_inst_t get_inst() const
{
return wasm_runtime_get_module_inst(exec_env_);
}
};
static uint8_t dummy_wasm_buffer[] = {
0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x05, 0x03, 0x01, 0x00,
0x02, 0x06, 0x08, 0x01, 0x7F, 0x01, 0x41, 0x80, 0x88, 0x04, 0x0B, 0x07,
0x0A, 0x01, 0x06, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x00,
0x19, 0x04, 0x6E, 0x61, 0x6D, 0x65, 0x07, 0x12, 0x01, 0x00, 0x0F, 0x5F,
0x5F, 0x73, 0x74, 0x61, 0x63, 0x6B, 0x5F, 0x70, 0x6F, 0x69, 0x6E, 0x74,
0x65, 0x72, 0x00, 0x76, 0x09, 0x70, 0x72, 0x6F, 0x64, 0x75, 0x63, 0x65,
0x72, 0x73, 0x01, 0x0C, 0x70, 0x72, 0x6F, 0x63, 0x65, 0x73, 0x73, 0x65,
0x64, 0x2D, 0x62, 0x79, 0x01, 0x05, 0x63, 0x6C, 0x61, 0x6E, 0x67, 0x56,
0x31, 0x33, 0x2E, 0x30, 0x2E, 0x30, 0x20, 0x28, 0x68, 0x74, 0x74, 0x70,
0x73, 0x3A, 0x2F, 0x2F, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2E, 0x63,
0x6F, 0x6D, 0x2F, 0x6C, 0x6C, 0x76, 0x6D, 0x2F, 0x6C, 0x6C, 0x76, 0x6D,
0x2D, 0x70, 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x20, 0x66, 0x64, 0x31,
0x64, 0x38, 0x63, 0x32, 0x66, 0x30, 0x34, 0x64, 0x64, 0x65, 0x32, 0x33,
0x62, 0x65, 0x65, 0x30, 0x66, 0x62, 0x33, 0x61, 0x37, 0x64, 0x30, 0x36,
0x39, 0x61, 0x39, 0x62, 0x31, 0x30, 0x34, 0x36, 0x64, 0x61, 0x39, 0x37,
0x39, 0x29
};
class DummyExecEnv
{
private:
std::shared_ptr<WAMRExecEnv> dummy_exec_env_;
std::shared_ptr<WAMRInstance> inst_;
std::shared_ptr<WAMRModule> mod_;
std::vector<uint8_t> my_wasm_buffer;
private:
void construct(uint8_t *buf, uint32_t len)
{
std::vector<uint8_t> buffer(buf, buf + len);
my_wasm_buffer = buffer;
mod_ = std::make_shared<WAMRModule>(my_wasm_buffer.data(),
my_wasm_buffer.size());
EXPECT_NE(mod_.get(), nullptr);
inst_ = std::make_shared<WAMRInstance>(*mod_);
EXPECT_NE(inst_.get(), nullptr);
dummy_exec_env_ = std::make_shared<WAMRExecEnv>(*inst_);
EXPECT_NE(dummy_exec_env_.get(), nullptr);
}
public:
DummyExecEnv() { construct(dummy_wasm_buffer, sizeof(dummy_wasm_buffer)); }
DummyExecEnv(uint8_t *buf, uint32_t len) { construct(buf, len); }
DummyExecEnv(std::string filename)
{
std::ifstream wasm_file(filename, std::ios::binary);
std::vector<uint8_t> buffer(std::istreambuf_iterator<char>(wasm_file),
{});
construct(buffer.data(), buffer.size());
}
~DummyExecEnv() {}
wasm_exec_env_t get() const { return dummy_exec_env_->get(); }
void *app_to_native(uint32_t app_addr) const
{
return wasm_runtime_addr_app_to_native(inst_->get(), app_addr);
}
uint32_t native_to_app(void *ptr) const
{
return wasm_runtime_addr_native_to_app(inst_->get(), ptr);
}
const char *get_exception() const
{
return wasm_runtime_get_exception(inst_->get());
}
void set_exception(std::string str) const
{
wasm_runtime_set_exception(inst_->get(), str.c_str());
}
void clear_exception() const { wasm_runtime_clear_exception(inst_->get()); }
bool execute(const char *func_name, uint32_t argc, uint32_t argv[])
{
wasm_function_inst_t func;
if (!(func = wasm_runtime_lookup_function(inst_->get(), func_name))) {
return false;
}
return wasm_runtime_call_wasm(dummy_exec_env_->get(), func, argc, argv);
}
};
class WAMRVaList
{
private:
void *buffer_;
uint32_t current_loc_;
uint32_t capacity_;
wasm_exec_env_t exec_env_;
void _append(void *ptr, uint32_t size)
{
if (current_loc_ + size >= capacity_) {
capacity_ *= 2;
buffer_ = realloc(buffer_, capacity_);
ASSERT_NE(buffer_, nullptr);
}
memcpy((void *)((uintptr_t)buffer_ + current_loc_), ptr, size);
current_loc_ += size;
}
public:
explicit WAMRVaList(wasm_exec_env_t exec_env)
: exec_env_(exec_env)
{
capacity_ = 64;
buffer_ = malloc(capacity_);
EXPECT_NE(buffer_, nullptr);
current_loc_ = 0;
}
~WAMRVaList()
{
current_loc_ = 0;
free(buffer_);
}
template<typename T>
void add(T arg)
{
if (std::is_floating_point<T>::value) {
/* float data should be 8 bytes aligned */
current_loc_ = ((current_loc_ + 7) & ~7);
_append(&arg, sizeof(T));
}
else if (std::is_integral<T>::value) {
if (sizeof(T) > 4) {
current_loc_ = ((current_loc_ + 7) & ~7);
}
_append(&arg, sizeof(T));
}
}
void add(std::string arg)
{
void *native_addr;
auto inst = wasm_runtime_get_module_inst(exec_env_);
uint32_t addr =
wasm_runtime_module_malloc(inst, arg.size() + 1, &native_addr);
ASSERT_NE(addr, 0);
memcpy(native_addr, arg.data(), arg.size());
*(char *)((uintptr_t)native_addr + arg.size()) = 0;
_append(&addr, sizeof(uint32_t));
}
void add(const char *arg) { add(std::string(arg)); }
char *get() const
{
auto inst = wasm_runtime_get_module_inst(exec_env_);
uint32_t addr = wasm_runtime_module_dup_data(
inst, (const char *)buffer_, current_loc_);
EXPECT_NE(addr, 0);
return (char *)wasm_runtime_addr_app_to_native(inst, addr);
}
};
/* Get memory space in app */
class AppMemory
{
private:
wasm_exec_env_t exec_env_;
void *native_addr_;
uint32_t app_addr_;
public:
AppMemory(wasm_exec_env_t exec_env, uint32_t size)
: exec_env_(exec_env)
{
app_addr_ = wasm_runtime_module_malloc(get_module_inst(exec_env_), size,
&native_addr_);
}
~AppMemory()
{
wasm_runtime_module_free(get_module_inst(exec_env_), app_addr_);
}
void *get_native_addr() const
{
return wasm_runtime_addr_app_to_native(get_module_inst(exec_env_),
app_addr_);
}
uint32_t get_app_addr() const { return app_addr_; }
};
/* Put the data to app */
class AppData
{
private:
wasm_exec_env_t exec_env_;
void *native_addr_;
uint32_t app_addr_;
public:
AppData(wasm_exec_env_t exec_env, void *data, uint32_t size)
: exec_env_(exec_env)
{
app_addr_ = wasm_runtime_module_dup_data(get_module_inst(exec_env_),
(const char *)data, size);
}
AppData(wasm_exec_env_t exec_env, std::string str)
: exec_env_(exec_env)
{
app_addr_ = wasm_runtime_module_dup_data(get_module_inst(exec_env_),
(const char *)str.c_str(),
str.size() + 1);
}
~AppData()
{
wasm_runtime_module_free(get_module_inst(exec_env_), app_addr_);
}
void *get_native_addr() const
{
return wasm_runtime_addr_app_to_native(get_module_inst(exec_env_),
app_addr_);
}
uint32_t get_app_addr() const { return app_addr_; }
};

View File

@ -0,0 +1,72 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-compilation)
add_definitions (-DRUN_ON_LINUX)
add_definitions (-Dattr_container_malloc=malloc)
add_definitions (-Dattr_container_free=free)
add_definitions (-DWASM_ENABLE_WAMR_COMPILER=1)
add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
set (WAMR_BUILD_LIBC_WASI 0)
set (WAMR_BUILD_APP_FRAMEWORK 0)
set (WAMR_BUILD_THREAD_MGR 1)
set (WAMR_BUILD_AOT 1)
include (../unit_common.cmake)
set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
if (NOT EXISTS "${LLVM_SRC_ROOT}/build")
message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build")
endif ()
set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}")
find_package(LLVM REQUIRED CONFIG)
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include (${IWASM_DIR}/compilation/iwasm_compl.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${WAMR_RUNTIME_LIB_SOURCE}
${UNCOMMON_SHARED_SOURCE}
${SRC_LIST}
${PLATFORM_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${LIB_HOST_AGENT_SOURCE}
${NATIVE_INTERFACE_SOURCE}
${LIBC_BUILTIN_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
${IWASM_AOT_SOURCE}
${IWASM_COMPL_SOURCE}
${WASM_APP_LIB_SOURCE_ALL}
)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable (compilation_test ${unit_test_sources})
target_link_libraries (compilation_test ${LLVM_AVAILABLE_LIBS} gtest_main )
add_custom_command(TARGET compilation_test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_LIST_DIR}/wasm-apps/main.wasm
${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Copy main.wasm to the directory: build/compilation."
)
gtest_discover_tests(compilation_test)

View File

@ -0,0 +1,203 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "wasm_export.h"
#include "aot_export.h"
#include "bh_read_file.h"
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
extern "C" {
char *
aot_generate_tempfile_name(const char *prefix, const char *extension,
char *buffer, uint32 len);
}
class aot_compiler_test_suit : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase()
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
static void TearDownTestCase() { free(WASM_FILE); }
WAMRRuntimeRAII<512 * 1024> runtime;
};
void
test_aot_emit_object_file_with_option(AOTCompOption *option_ptr)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
aot_comp_data_t comp_data = nullptr;
aot_comp_context_t comp_ctx = nullptr;
char out_file_name[] = "test.aot";
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data(wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, option_ptr);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_STREQ(aot_get_last_error(), "");
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
EXPECT_TRUE(aot_emit_object_file(comp_ctx, out_file_name));
}
TEST_F(aot_compiler_test_suit, aot_emit_object_file)
{
AOTCompOption option = { 0 };
uint32_t i = 0;
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
// Test opt_level in range from 0 to 3.
for (i = 0; i <= 3; i++) {
option.opt_level = i;
test_aot_emit_object_file_with_option(&option);
}
// Test size_level in range from 0 to 3.
option.opt_level = 3;
for (i = 0; i <= 3; i++) {
option.size_level = i;
test_aot_emit_object_file_with_option(&option);
}
// Test output_format in range from AOT_FORMAT_FILE to AOT_LLVMIR_OPT_FILE.
option.size_level = 3;
for (i = AOT_FORMAT_FILE; i <= AOT_LLVMIR_OPT_FILE; i++) {
option.output_format = i;
test_aot_emit_object_file_with_option(&option);
}
// Test bounds_checks in range 0 to 2.
option.output_format = AOT_FORMAT_FILE;
for (i = 0; i <= 2; i++) {
option.bounds_checks = i;
test_aot_emit_object_file_with_option(&option);
}
// Test all enable option is false.
option.bounds_checks = 2;
option.enable_simd = false;
option.enable_aux_stack_check = false;
option.enable_bulk_memory = false;
option.enable_ref_types = false;
test_aot_emit_object_file_with_option(&option);
}
TEST_F(aot_compiler_test_suit, aot_emit_llvm_file)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
aot_comp_data_t comp_data = nullptr;
aot_comp_context_t comp_ctx = nullptr;
AOTCompOption option = { 0 };
char out_file_name[] = "out_file_name_test";
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data(wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_STREQ(aot_get_last_error(), "");
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
EXPECT_EQ(true, aot_emit_llvm_file(comp_ctx, out_file_name));
}
TEST_F(aot_compiler_test_suit, aot_generate_tempfile_name)
{
char obj_file_name[64];
// Test common case.
aot_generate_tempfile_name("wamrc-obj", "o", obj_file_name,
sizeof(obj_file_name));
EXPECT_NE(nullptr, strstr(obj_file_name, ".o"));
// Test abnormal cases.
EXPECT_EQ(nullptr,
aot_generate_tempfile_name("wamrc-obj", "o", obj_file_name, 0));
char obj_file_name_1[20];
EXPECT_EQ(nullptr, aot_generate_tempfile_name(
"wamrc-obj", "12345678901234567890", obj_file_name_1,
sizeof(obj_file_name_1)));
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "wasm_export.h"
#include "aot_export.h"
#include "bh_read_file.h"
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
extern "C" {
uint8 *
aot_emit_aot_file_buf(AOTCompContext *comp_ctx, AOTCompData *comp_data,
uint32 *p_aot_file_size);
}
class aot_emit_aot_file_test_suite : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase()
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
static void TearDownTestCase() { free(WASM_FILE); }
WAMRRuntimeRAII<512 * 1024> runtime;
};
TEST_F(aot_emit_aot_file_test_suite, aot_emit_aot_file)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
aot_comp_data_t comp_data = nullptr;
aot_comp_context_t comp_ctx = nullptr;
AOTCompOption option = { 0 };
char out_file_name[] = "test.aot";
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = false;
option.enable_aux_stack_check = false;
option.enable_bulk_memory = false;
option.enable_ref_types = false;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data(wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
EXPECT_EQ(false, aot_emit_aot_file(comp_ctx, comp_data, nullptr));
}

View File

@ -0,0 +1,112 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "gtest/gtest.h"
#include "aot_emit_compare.h"
class compilation_aot_emit_compare_test : public testing::Test
{
protected:
virtual void SetUp() {}
virtual void TearDown() {}
public:
};
TEST_F(compilation_aot_emit_compare_test, aot_compile_op_i32_compare)
{
AOTCompContext comp_ctx = { 0 };
AOTFuncContext func_ctx = { 0 };
IntCond cond = INT_EQZ;
IntCond cond1 = INT_EQZ;
/* false cond = 0 */
EXPECT_FALSE(aot_compile_op_i32_compare(&comp_ctx, &func_ctx, cond));
/* false cond = -1 */
EXPECT_FALSE(
aot_compile_op_i32_compare(&comp_ctx, &func_ctx, (IntCond)(-1)));
/* false cond = [1:10] || [11:100] */
for (int i = 0; i < 0xFFFF; i++) {
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
cond = (IntCond)(1 + (rand() % (INT_GE_U - 1 + 1)));
cond1 = (IntCond)((INT_GE_U + 1) + (rand() % (100 - 1 + 1)));
EXPECT_FALSE(aot_compile_op_i32_compare(&comp_ctx, &func_ctx, cond));
EXPECT_FALSE(aot_compile_op_i32_compare(&comp_ctx, &func_ctx, cond1));
}
}
TEST_F(compilation_aot_emit_compare_test, aot_compile_op_i64_compare)
{
AOTCompContext comp_ctx = { 0 };
AOTFuncContext func_ctx = { 0 };
IntCond cond = INT_EQZ;
IntCond cond1 = INT_EQZ;
/* false cond = 0 */
// EXPECT_FALSE(aot_compile_op_i64_compare(&comp_ctx, &func_ctx, cond));
/* false cond = -1 */
EXPECT_FALSE(
aot_compile_op_i64_compare(&comp_ctx, &func_ctx, (IntCond)(-1)));
/* false cond = [1:10] || [11:100] */
for (int i = 0; i < 0xFFFF; i++) {
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
cond = (IntCond)(1 + (rand() % (INT_GE_U - 1 + 1)));
cond1 = (IntCond)((INT_GE_U + 1) + (rand() % (100 - 1 + 1)));
EXPECT_FALSE(aot_compile_op_i64_compare(&comp_ctx, &func_ctx, cond));
EXPECT_FALSE(aot_compile_op_i64_compare(&comp_ctx, &func_ctx, cond1));
}
}
TEST_F(compilation_aot_emit_compare_test, aot_compile_op_f32_compare)
{
AOTCompContext comp_ctx = { 0 };
AOTFuncContext func_ctx = { 0 };
FloatCond cond = FLOAT_EQ;
FloatCond cond1 = FLOAT_EQ;
/* false cond = 0 */
EXPECT_FALSE(aot_compile_op_f32_compare(&comp_ctx, &func_ctx, cond));
/* false cond = -1 */
EXPECT_FALSE(
aot_compile_op_f32_compare(&comp_ctx, &func_ctx, (FloatCond)(-1)));
/* false cond = [1:10] || [7:100] */
for (int i = 0; i < 0xFFFF; i++) {
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
cond = (FloatCond)(1 + (rand() % (FLOAT_UNO - 1 + 1)));
cond1 = (FloatCond)((FLOAT_UNO + 1) + (rand() % (100 - 1 + 1)));
EXPECT_FALSE(aot_compile_op_f32_compare(&comp_ctx, &func_ctx, cond));
EXPECT_FALSE(aot_compile_op_f32_compare(&comp_ctx, &func_ctx, cond1));
}
}
TEST_F(compilation_aot_emit_compare_test, aot_compile_op_f64_compare)
{
AOTCompContext comp_ctx = { 0 };
AOTFuncContext func_ctx = { 0 };
FloatCond cond = FLOAT_EQ;
FloatCond cond1 = FLOAT_EQ;
/* false cond = 0 */
EXPECT_FALSE(aot_compile_op_f64_compare(&comp_ctx, &func_ctx, cond));
/* false cond = -1 */
EXPECT_FALSE(
aot_compile_op_f64_compare(&comp_ctx, &func_ctx, (FloatCond)(-1)));
/* false cond = [1:10] || [7:100] */
for (int i = 0; i < 0xFFFF; i++) {
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
cond = (FloatCond)(1 + (rand() % (FLOAT_UNO - 1 + 1)));
cond1 = (FloatCond)((FLOAT_UNO + 1) + (rand() % (100 - 1 + 1)));
EXPECT_FALSE(aot_compile_op_f64_compare(&comp_ctx, &func_ctx, cond));
EXPECT_FALSE(aot_compile_op_f64_compare(&comp_ctx, &func_ctx, cond1));
}
}

View File

@ -0,0 +1,196 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "bh_read_file.h"
#include "aot.h"
#include "aot_llvm.h"
#include "aot_emit_control.h"
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
class aot_emit_control_test_suite : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase()
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
static void TearDownTestCase() { free(WASM_FILE); }
WAMRRuntimeRAII<512 * 1024> runtime;
};
TEST_F(aot_emit_control_test_suite, check_suspend_flags)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
AOTCompOption option = { 0 };
char out_file_name[] = "out_file_name_test";
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
EXPECT_EQ(true, check_suspend_flags(comp_ctx, func_ctx, false));
}
TEST_F(aot_emit_control_test_suite, aot_compile_op_block)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
AOTCompOption option = { 0 };
char out_file_name[] = "out_file_name_test";
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
func_ctx->block_stack.block_list_end = nullptr;
EXPECT_EQ(false, aot_compile_op_block(comp_ctx, func_ctx, nullptr, nullptr,
0, 0, nullptr, 0, nullptr));
}
TEST_F(aot_emit_control_test_suite, aot_compile_op_else)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
AOTCompOption option = { 0 };
char out_file_name[] = "out_file_name_test";
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
func_ctx->block_stack.block_list_end = nullptr;
EXPECT_EQ(false, aot_compile_op_else(comp_ctx, func_ctx, nullptr));
AOTBlock block_list_end_test;
block_list_end_test.label_type = LABEL_TYPE_FUNCTION;
func_ctx->block_stack.block_list_end = &block_list_end_test;
EXPECT_EQ(false, aot_compile_op_else(comp_ctx, func_ctx, nullptr));
block_list_end_test.label_type = LABEL_TYPE_IF;
block_list_end_test.llvm_else_block = nullptr;
EXPECT_EQ(false, aot_compile_op_else(comp_ctx, func_ctx, nullptr));
}

View File

@ -0,0 +1,101 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "bh_read_file.h"
#include "aot_emit_control.h"
#include "aot_emit_function.h"
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
class aot_emit_function_test_suite : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase()
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
static void TearDownTestCase() { free(WASM_FILE); }
WAMRRuntimeRAII<512 * 1024> runtime;
};
TEST_F(aot_emit_function_test_suite, aot_compile_op_call)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
AOTCompOption option = { 0 };
char out_file_name[] = "out_file_name_test";
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
EXPECT_EQ(false, aot_compile_op_call(comp_ctx, func_ctx, 9999, true));
}

View File

@ -0,0 +1,335 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "gtest/gtest.h"
#include "bh_platform.h"
#include "bh_read_file.h"
#include "aot_emit_memory.h"
#include "test_helper.h"
#define DEFAULT_CYCLE_TIMES 0xFFFF
#define DEFAULT_MAX_RAND_NUM 0xFFFFFFFF
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
class compilation_aot_emit_memory_test : public testing::Test
{
protected:
void SetUp() override
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
AOTCompOption option = { 0 };
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
/* default value, enable or disable depends on the platform */
option.stack_bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = reinterpret_cast<WASMModule *>(wasm_runtime_load(
wasm_file_buf, wasm_file_size, error_buf, sizeof(error_buf)));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data(wasm_module, NULL, false);
EXPECT_NE(comp_data, nullptr);
// properly init compilation and function context, to do that,
// use as a dummy module(instead of compile the function in it, simply
// test the APIs)
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
func_ctx = comp_ctx->func_ctxes[0];
EXPECT_NE(func_ctx, nullptr);
}
void TearDown() override
{
aot_destroy_comp_context(comp_ctx);
aot_destroy_comp_data(comp_data);
wasm_runtime_unload(reinterpret_cast<WASMModuleCommon *>(wasm_module));
}
public:
WASMModule *wasm_module = nullptr;
AOTCompData *comp_data = nullptr;
AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
WAMRRuntimeRAII<512 * 1024> runtime;
};
TEST_F(compilation_aot_emit_memory_test, aot_check_memory_overflow)
{
uint32 offset = 64;
uint32 bytes = 4;
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
aot_check_memory_overflow(comp_ctx, func_ctx, offset, bytes, false);
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_i32_load)
{
uint32 align = 0;
uint32 offset = 1024;
uint32 bytes = 0;
bool sign = false;
bool atomic = false;
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
align = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
bytes = (1 + (rand() % (4 - 1 + 1)));
printf("---%d", aot_compile_op_i32_load(comp_ctx, func_ctx, align,
offset, bytes, sign, atomic));
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_i64_load)
{
uint32 align = 0;
uint32 offset = 1024;
uint32 bytes = 0;
bool sign = false;
bool atomic = false;
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
align = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
bytes = (1 + (rand() % (4 - 1 + 1)));
sign = !sign;
atomic = !atomic;
aot_compile_op_i64_load(comp_ctx, func_ctx, align, offset, bytes, sign,
atomic);
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_f32_load)
{
uint32 align = 10;
uint32 offset = 10;
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
align = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
aot_compile_op_f32_load(comp_ctx, func_ctx, align, offset);
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_f64_load)
{
uint32 align = 10;
uint32 offset = 10;
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
align = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
offset = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
aot_compile_op_f64_load(comp_ctx, func_ctx, align, offset);
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_i32_store)
{
uint32 align = 0;
uint32 offset = 0;
uint32 bytes = 0;
bool atomic = false;
EXPECT_FALSE(aot_compile_op_i32_store(comp_ctx, func_ctx, align, offset,
bytes, atomic));
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
bytes = (1 + (rand() % (4 - 1 + 1)));
offset = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
align = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
atomic = !atomic;
EXPECT_FALSE(aot_compile_op_i32_store(comp_ctx, func_ctx, align, offset,
bytes, atomic));
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_i64_store)
{
uint32 align = 0;
uint32 offset = 0;
uint32 bytes = 0;
bool atomic = false;
EXPECT_FALSE(aot_compile_op_i64_store(comp_ctx, func_ctx, align, offset,
bytes, atomic));
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
bytes = (1 + (rand() % (8 - 1 + 1)));
offset = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
align = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
atomic = !atomic;
EXPECT_FALSE(aot_compile_op_i64_store(comp_ctx, func_ctx, align, offset,
bytes, atomic));
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_f32_store)
{
uint32 align = 0;
uint32 offset = 0;
EXPECT_FALSE(aot_compile_op_f32_store(comp_ctx, func_ctx, align, offset));
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
offset = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
align = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
EXPECT_FALSE(
aot_compile_op_f32_store(comp_ctx, func_ctx, align, offset));
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_f64_store)
{
uint32 align = 0;
uint32 offset = 0;
EXPECT_FALSE(aot_compile_op_f64_store(comp_ctx, func_ctx, align, offset));
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
offset = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
align = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
EXPECT_FALSE(
aot_compile_op_f64_store(comp_ctx, func_ctx, align, offset));
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_size)
{
aot_compile_op_memory_size(comp_ctx, func_ctx);
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_grow)
{
aot_compile_op_memory_grow(comp_ctx, func_ctx);
}
#if WASM_ENABLE_BULK_MEMORY != 0
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_init)
{
uint32 seg_index = 0;
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
seg_index = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
aot_compile_op_memory_init(comp_ctx, func_ctx, seg_index);
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_data_drop)
{
uint32 seg_index = 0;
/* Generate random number range[m,n] int a=m+rand()%(n-m+1); */
for (uint32 i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
seg_index = (1 + (rand() % (0xFFFFFFFF - 1 + 1)));
aot_compile_op_data_drop(comp_ctx, func_ctx, seg_index);
}
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_copy)
{
aot_compile_op_memory_copy(comp_ctx, func_ctx);
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_memory_fill)
{
aot_compile_op_memory_fill(comp_ctx, func_ctx);
}
#endif
#if WASM_ENABLE_SHARED_MEMORY != 0
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_atomic_rmw)
{
uint8 atomic_op = LLVMAtomicRMWBinOpAdd;
uint8 op_type = VALUE_TYPE_I32;
uint32 align = 4;
uint32 offset = 64;
uint32 bytes = 4;
aot_compile_op_atomic_rmw(comp_ctx, func_ctx, atomic_op, op_type, align,
offset, bytes);
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_atomic_cmpxchg)
{
uint8 op_type = VALUE_TYPE_I32;
uint32 align = 4;
uint32 offset = 64;
uint32 bytes = 4;
aot_compile_op_atomic_cmpxchg(comp_ctx, func_ctx, op_type, align, offset,
bytes);
}
TEST_F(compilation_aot_emit_memory_test, aot_compile_op_atomic_wait)
{
uint8 op_type = VALUE_TYPE_I32;
uint32 align = 4;
uint32 offset = 64;
uint32 bytes = 4;
aot_compile_op_atomic_wait(comp_ctx, func_ctx, op_type, align, offset,
bytes);
}
TEST_F(compilation_aot_emit_memory_test, aot_compiler_op_atomic_notify)
{
uint32 align = 4;
uint32 offset = 64;
uint32 bytes = 4;
aot_compiler_op_atomic_notify(comp_ctx, func_ctx, align, offset, bytes);
}
#endif

View File

@ -0,0 +1,119 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "bh_read_file.h"
#include "aot_llvm.h"
#include "aot_emit_numberic.h"
#include "aot_compiler.h"
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
class aot_emit_numberic_test_suite : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase()
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
static void TearDownTestCase() { free(WASM_FILE); }
WAMRRuntimeRAII<512 * 1024> runtime;
};
TEST_F(aot_emit_numberic_test_suite, aot_compile_op_functions)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
AOTCompOption option = { 0 };
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
EXPECT_EQ(false,
aot_compile_op_f32_arithmetic(comp_ctx, func_ctx, FLOAT_SUB));
EXPECT_EQ(false, aot_compile_op_f32_copysign(comp_ctx, func_ctx));
EXPECT_EQ(false, aot_compile_op_f32_math(comp_ctx, func_ctx, FLOAT_NEG));
EXPECT_EQ(false,
aot_compile_op_f64_arithmetic(comp_ctx, func_ctx, FLOAT_SUB));
EXPECT_EQ(false, aot_compile_op_f64_copysign(comp_ctx, func_ctx));
EXPECT_EQ(false, aot_compile_op_f64_math(comp_ctx, func_ctx, FLOAT_NEG));
EXPECT_EQ(false, aot_compile_op_i32_clz(comp_ctx, func_ctx));
EXPECT_EQ(false, aot_compile_op_i32_ctz(comp_ctx, func_ctx));
EXPECT_EQ(false, aot_compile_op_i32_popcnt(comp_ctx, func_ctx));
EXPECT_EQ(false, aot_compile_op_i32_shift(comp_ctx, func_ctx, INT_SHR_S));
EXPECT_EQ(false, aot_compile_op_i64_arithmetic(comp_ctx, func_ctx, INT_SUB,
nullptr));
EXPECT_EQ(false, aot_compile_op_i64_bitwise(comp_ctx, func_ctx, INT_OR));
EXPECT_EQ(false, aot_compile_op_i64_clz(comp_ctx, func_ctx));
EXPECT_EQ(false, aot_compile_op_i64_ctz(comp_ctx, func_ctx));
EXPECT_EQ(false, aot_compile_op_i64_popcnt(comp_ctx, func_ctx));
EXPECT_EQ(false, aot_compile_op_i64_shift(comp_ctx, func_ctx, INT_SHR_S));
}

View File

@ -0,0 +1,143 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "bh_read_file.h"
#include "aot_llvm.h"
#include "aot_emit_parametric.h"
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
class aot_emit_parametric_test_suite : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase()
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
static void TearDownTestCase() { free(WASM_FILE); }
WAMRRuntimeRAII<512 * 1024> runtime;
};
TEST_F(aot_emit_parametric_test_suite, aot_compile_op_select)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
AOTCompOption option = { 0 };
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
EXPECT_FALSE(aot_compile_op_select(comp_ctx, func_ctx, true));
EXPECT_FALSE(aot_compile_op_select(comp_ctx, func_ctx, false));
}
TEST_F(aot_emit_parametric_test_suite, aot_compile_op_drop)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
AOTCompOption option = { 0 };
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
func_ctx->block_stack.block_list_end = nullptr;
EXPECT_FALSE(aot_compile_op_drop(comp_ctx, func_ctx, true));
EXPECT_FALSE(aot_compile_op_drop(comp_ctx, func_ctx, false));
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "bh_read_file.h"
#include "aot_llvm.h"
#include "aot_emit_table.h"
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
class aot_emit_table_test_suite : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase()
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
static void TearDownTestCase() { free(WASM_FILE); }
WAMRRuntimeRAII<512 * 1024> runtime;
};
TEST_F(aot_emit_table_test_suite, get_tbl_inst_offset)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTFuncContext *func_ctx = nullptr;
AOTCompOption option = { 0 };
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
EXPECT_NE(0, get_tbl_inst_offset(comp_ctx, func_ctx, 6));
EXPECT_NE(0, get_tbl_inst_offset(comp_ctx, func_ctx, 1));
EXPECT_NE(0, get_tbl_inst_offset(comp_ctx, func_ctx, 0));
((AOTCompData *)comp_ctx->comp_data)->import_table_count = 1;
AOTImportTable import_tables_test;
((AOTCompData *)comp_ctx->comp_data)->import_tables = &import_tables_test;
EXPECT_NE(0, get_tbl_inst_offset(comp_ctx, func_ctx, 6));
}

View File

@ -0,0 +1,97 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "gtest/gtest.h"
#include "aot_emit_variable.h"
#define DEFAULT_CYCLE_TIMES 0xFFFF
#define DEFAULT_MAX_RAND_NUM 0xFFFFFFFF
class compilation_aot_emit_variable_test : public testing::Test
{
protected:
virtual void SetUp() {}
virtual void TearDown() {}
public:
AOTCompContext comp_ctx = { 0 };
AOTFuncContext func_ctx = { 0 };
};
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_get_local)
{
AOTCompContext *pcomp_ctx = &comp_ctx;
AOTFuncContext *pfunc_ctx = &func_ctx;
uint32 local_idx = 0;
// aot_compile_op_get_local(NULL, pfunc_ctx, local_idx);
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
// aot_compile_op_get_local(pcomp_ctx, pfunc_ctx, local_idx);
// }
}
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_set_local)
{
AOTCompContext *pcomp_ctx = &comp_ctx;
AOTFuncContext *pfunc_ctx = &func_ctx;
uint32 local_idx = 0;
// aot_compile_op_set_local(pcomp_ctx, pfunc_ctx, local_idx);
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
// aot_compile_op_set_local(pcomp_ctx, pfunc_ctx, local_idx);
// }
}
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_tee_local)
{
AOTCompContext *pcomp_ctx = &comp_ctx;
AOTFuncContext *pfunc_ctx = &func_ctx;
uint32 local_idx = 0;
// aot_compile_op_tee_local(pcomp_ctx, pfunc_ctx, local_idx);
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
// aot_compile_op_tee_local(pcomp_ctx, pfunc_ctx, local_idx);
// }
}
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_get_global)
{
AOTCompContext *pcomp_ctx = &comp_ctx;
AOTFuncContext *pfunc_ctx = &func_ctx;
uint32 global_idx = 0;
// aot_compile_op_get_global(pcomp_ctx, pfunc_ctx, global_idx);
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
// aot_compile_op_get_global(pcomp_ctx, pfunc_ctx, global_idx);
// }
}
TEST_F(compilation_aot_emit_variable_test, aot_compile_op_set_global)
{
AOTCompContext *pcomp_ctx = &comp_ctx;
AOTFuncContext *pfunc_ctx = &func_ctx;
uint32 global_idx = 0;
bool is_aux_stack = false;
// aot_compile_op_set_global(pcomp_ctx, pfunc_ctx, global_idx,
// is_aux_stack);
// for (uint32_t i = 0; i < DEFAULT_CYCLE_TIMES; i++) {
// is_aux_stack = is_aux_stack ? false : ture;
// local_idx = (1 + (rand() % (DEFAULT_MAX_RAND_NUM - 1 + 1)));
// aot_compile_op_set_global(pcomp_ctx, pfunc_ctx,
// global_idx,is_aux_stack);
// }
}

View File

@ -0,0 +1,305 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "bh_read_file.h"
#include "aot_llvm.h"
#include "aot_compiler.h"
static std::string CWD;
static std::string MAIN_WASM = "/main.wasm";
static char *WASM_FILE;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
class aot_llvm_test_suite : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase()
{
CWD = get_binary_path();
WASM_FILE = strdup((CWD + MAIN_WASM).c_str());
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
static void TearDownTestCase() { free(WASM_FILE); }
WAMRRuntimeRAII<512 * 1024> runtime;
};
TEST_F(aot_llvm_test_suite, aot_functions)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTCompOption option = { 0 };
AOTFuncContext *func_ctx = nullptr;
WASMValue wasm_value;
LLVMTypeRef param_types[1];
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
param_types[0] = F64_TYPE;
EXPECT_TRUE(aot_call_llvm_intrinsic(comp_ctx, func_ctx, "f32_demote_f64",
F32_TYPE, param_types, 0));
/* Test function aot_get_native_symbol_index. */
AOTNativeSymbol elem_insert_1;
elem_insert_1.index = -1;
bh_list_insert(&comp_ctx->native_symbols, &elem_insert_1);
AOTNativeSymbol elem_insert_2;
strcpy(elem_insert_2.symbol, "f64#_test");
elem_insert_2.index = -1;
bh_list_insert(&comp_ctx->native_symbols, &elem_insert_2);
comp_ctx->pointer_size = sizeof(uint32);
strcpy(comp_ctx->target_arch, "i386");
EXPECT_NE(-1, aot_get_native_symbol_index(comp_ctx, "f64#_test"));
}
TEST_F(aot_llvm_test_suite, wasm_type_to_llvm_type) {}
TEST_F(aot_llvm_test_suite, aot_build_zero_function_ret)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTCompOption option = { 0 };
AOTFuncContext *func_ctx = nullptr;
AOTFuncType func_type;
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = false;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
func_ctx = comp_ctx->func_ctxes[1];
func_type.result_count = 1;
func_type.param_count = 0;
func_type.types[func_type.param_count] = VALUE_TYPE_I32;
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
func_type.types[func_type.param_count] = VALUE_TYPE_I64;
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
func_type.types[func_type.param_count] = VALUE_TYPE_F32;
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
func_type.types[func_type.param_count] = VALUE_TYPE_F64;
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
func_type.types[func_type.param_count] = VALUE_TYPE_V128;
EXPECT_NE(0, aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type));
/* THe current optimization, if not actually use ref_types in wasm module,
* it will set to false, so test false condition */
func_type.types[func_type.param_count] = VALUE_TYPE_FUNCREF;
EXPECT_DEATH(aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type),
".*");
func_type.types[func_type.param_count] = VALUE_TYPE_EXTERNREF;
EXPECT_DEATH(aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type),
".*");
func_type.types[func_type.param_count] = 0xFF;
EXPECT_DEATH(aot_build_zero_function_ret(comp_ctx, func_ctx, &func_type),
".*");
}
TEST_F(aot_llvm_test_suite, aot_destroy_comp_context)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTCompOption option = { 0 };
AOTFuncContext *func_ctx = nullptr;
AOTFuncType func_type;
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
AOTNativeSymbol elem_insert_1;
elem_insert_1.index = -1;
bh_list_insert(&comp_ctx->native_symbols, &elem_insert_1);
aot_destroy_comp_context(comp_ctx);
aot_destroy_comp_context(nullptr);
}
TEST_F(aot_llvm_test_suite, aot_create_comp_context)
{
const char *wasm_file = WASM_FILE;
unsigned int wasm_file_size = 0;
unsigned char *wasm_file_buf = nullptr;
char error_buf[128] = { 0 };
wasm_module_t wasm_module = nullptr;
struct AOTCompData *comp_data = nullptr;
struct AOTCompContext *comp_ctx = nullptr;
AOTCompOption option = { 0 };
option.opt_level = 3;
option.size_level = 3;
option.output_format = AOT_FORMAT_FILE;
/* default value, enable or disable depends on the platform */
option.bounds_checks = 2;
option.enable_simd = true;
option.enable_aux_stack_check = true;
option.enable_bulk_memory = true;
option.enable_ref_types = true;
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
EXPECT_NE(wasm_file_buf, nullptr);
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
EXPECT_NE(wasm_module, nullptr);
comp_data = aot_create_comp_data((WASMModule *)wasm_module, NULL, false);
EXPECT_NE(nullptr, comp_data);
option.enable_thread_mgr = true;
option.enable_tail_call = true;
option.is_indirect_mode = true;
option.disable_llvm_intrinsics = true;
option.disable_llvm_lto = true;
option.is_jit_mode = true;
option.target_arch = (char *)"arm";
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
option.output_format = 100;
comp_ctx = aot_create_comp_context(comp_data, &option);
// Test every target_arch.
option.is_jit_mode = false;
option.target_arch = (char *)"arm";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.target_arch = (char *)"armeb";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.target_arch = (char *)"thumb";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.target_arch = (char *)"thumbeb";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.target_arch = (char *)"aarch64";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.target_arch = (char *)"aarch64_be";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.target_arch = (char *)"help";
comp_ctx = aot_create_comp_context(comp_data, &option);
// Test every target_abi.
option.target_arch = (char *)"arm";
option.target_abi = (char *)"test";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.target_abi = (char *)"help";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.target_abi = (char *)"msvc";
option.target_arch = (char *)"i386";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.cpu_features = (char *)"test";
comp_ctx = aot_create_comp_context(comp_data, &option);
option.is_sgx_platform = true;
comp_ctx = aot_create_comp_context(comp_data, &option);
comp_data->func_count = 0;
comp_ctx = aot_create_comp_context(comp_data, &option);
}

Binary file not shown.

View File

@ -0,0 +1,65 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-custom-section)
add_definitions (-DRUN_ON_LINUX)
set (WAMR_BUILD_LIBC_WASI 0)
set (WAMR_BUILD_LIBC_BUILTIN 0)
set (WAMR_BUILD_JIT 0)
set (WAMR_BUILD_LAZY_JIT 0)
set (WAMR_BUILD_AOT 1)
add_definitions(-DWASM_ENABLE_WAMR_COMPILER=1)
add_definitions (-DWASM_ENABLE_DUMP_CALL_STACK=1)
add_definitions (-DWASM_ENABLE_AOT_STACK_FRAME=1)
# Feature to test
set (WAMR_BUILD_LOAD_CUSTOM_SECTION 1)
include (../unit_common.cmake)
set (LLVM_SRC_ROOT "${WAMR_ROOT_DIR}/core/deps/llvm")
if (NOT EXISTS "${LLVM_SRC_ROOT}/build")
message (FATAL_ERROR "Cannot find LLVM dir: ${LLVM_SRC_ROOT}/build")
endif ()
set (CMAKE_PREFIX_PATH "${LLVM_SRC_ROOT}/build;${CMAKE_PREFIX_PATH}")
find_package(LLVM REQUIRED CONFIG)
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
include (${IWASM_DIR}/compilation/iwasm_compl.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${PLATFORM_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${NATIVE_INTERFACE_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
${IWASM_AOT_SOURCE}
${IWASM_COMPL_SOURCE}
${WASM_APP_LIB_SOURCE_ALL}
)
# Automatically build wasm-apps for this test
add_subdirectory(wasm-apps)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable (custom_section_test ${unit_test_sources})
target_link_libraries (custom_section_test ${LLVM_AVAILABLE_LIBS} gtest_main )
gtest_discover_tests(custom_section_test)

View File

@ -0,0 +1,161 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "gtest/gtest.h"
#include "bh_platform.h"
#include <fstream>
#include "test_helper.h"
#include "aot_export.h"
class CustomSectionTest : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
public:
WAMRRuntimeRAII<1 * 1024 * 1024> runtime;
};
TEST_F(CustomSectionTest, get_custom_section_from_wasm_module_t)
{
uint32_t length, len_from_aot;
const uint8_t *content, *content_from_aot;
std::ifstream wasm_file("wasm-apps/app.wasm", std::ios::binary);
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(wasm_file),
{});
{
WAMRModule module(buffer.data(), buffer.size());
aot_comp_data_t comp_data = NULL;
aot_comp_context_t comp_ctx = NULL;
std::vector<const char *> sections_to_emit{
"name",
".debug_info",
".debug_abbrev",
/* skip ".debug_line" section in AoT module */
".debug_str",
"producers",
};
AOTCompOption option = { 0 };
option.custom_sections = (char **)sections_to_emit.data();
option.custom_sections_count = 5;
{
/* Compile an AoT module */
comp_data = aot_create_comp_data(module.get(), NULL, false);
EXPECT_NE(comp_data, nullptr);
comp_ctx = aot_create_comp_context(comp_data, &option);
EXPECT_NE(comp_ctx, nullptr);
EXPECT_TRUE(aot_compile_wasm(comp_ctx));
EXPECT_TRUE(aot_emit_aot_file(comp_ctx, comp_data, "temp.aot"));
}
std::ifstream aot_file("temp.aot", std::ios::binary);
std::vector<unsigned char> aot_buffer(
std::istreambuf_iterator<char>(aot_file), {});
WAMRModule aot_module(aot_buffer.data(), aot_buffer.size());
/* name */
content =
wasm_runtime_get_custom_section(module.get(), "name", &length);
EXPECT_NE(content, nullptr);
EXPECT_GT(length, 0);
/* TODO: aot_emit_name_section don't
EMIT_U32(AOT_CUSTOM_SECTION_RAW);*
EMIT_STR("name");
but instead
EMIT_U32(AOT_CUSTOM_SECTION_NAME);
can't use get_custom_section to get it
*/
// content_from_aot = wasm_runtime_get_custom_section(
// aot_module.get(), "name", &len_from_aot);
// EXPECT_NE(content_from_aot, nullptr);
// EXPECT_EQ(len_from_aot, length);
// EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
/* .debug_info */
content = wasm_runtime_get_custom_section(module.get(), ".debug_info",
&length);
EXPECT_NE(content, nullptr);
EXPECT_GT(length, 0);
content_from_aot = wasm_runtime_get_custom_section(
aot_module.get(), ".debug_info", &len_from_aot);
EXPECT_NE(content_from_aot, nullptr);
EXPECT_EQ(len_from_aot, length);
EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
/* .debug_abbrev */
content = wasm_runtime_get_custom_section(module.get(), ".debug_abbrev",
&length);
EXPECT_NE(content, nullptr);
EXPECT_GT(length, 0);
content_from_aot = wasm_runtime_get_custom_section(
aot_module.get(), ".debug_abbrev", &len_from_aot);
EXPECT_NE(content_from_aot, nullptr);
EXPECT_EQ(len_from_aot, length);
EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
/* .debug_line */
content = wasm_runtime_get_custom_section(module.get(), ".debug_line",
&length);
EXPECT_NE(content, nullptr);
EXPECT_GT(length, 0);
content_from_aot = wasm_runtime_get_custom_section(
aot_module.get(), ".debug_line", &len_from_aot);
EXPECT_EQ(content_from_aot, nullptr);
/* .debug_str */
content = wasm_runtime_get_custom_section(module.get(), ".debug_str",
&length);
EXPECT_NE(content, nullptr);
EXPECT_GT(length, 0);
content_from_aot = wasm_runtime_get_custom_section(
aot_module.get(), ".debug_str", &len_from_aot);
EXPECT_NE(content_from_aot, nullptr);
EXPECT_EQ(len_from_aot, length);
EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
/* producers */
content =
wasm_runtime_get_custom_section(module.get(), "producers", &length);
EXPECT_NE(content, nullptr);
EXPECT_GT(length, 0);
content_from_aot = wasm_runtime_get_custom_section(
aot_module.get(), "producers", &len_from_aot);
EXPECT_NE(content_from_aot, nullptr);
EXPECT_EQ(len_from_aot, length);
EXPECT_EQ(memcmp(content_from_aot, content, length), 0);
/* Not exist */
content = wasm_runtime_get_custom_section(module.get(), "producers1",
&length);
EXPECT_EQ(content, nullptr);
content_from_aot = wasm_runtime_get_custom_section(
aot_module.get(), "producers1", &len_from_aot);
EXPECT_EQ(content_from_aot, nullptr);
}
}

View File

@ -0,0 +1,14 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project(wasm-apps-custom-section)
# Add -g option so there will be debugger related custom sections
add_custom_target(app.wasm ALL
COMMAND /opt/wasi-sdk/bin/clang -g -nostdlib
-Wl,--no-entry,--export-all
-o ${CMAKE_CURRENT_BINARY_DIR}/app.wasm
${CMAKE_CURRENT_LIST_DIR}/app.c
)

View File

@ -0,0 +1,10 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
int
main(int argc, char const *argv[])
{
return 0;
}

View File

@ -0,0 +1,51 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-wamr-gc)
add_definitions (-DRUN_ON_LINUX)
set (WAMR_BUILD_GC 1)
set (WAMR_BUILD_INTERP 1)
set (WAMR_BUILD_AOT 0)
set (WAMR_BUILD_APP_FRAMEWORK 0)
include (../unit_common.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${WAMR_RUNTIME_LIB_SOURCE}
${UNCOMMON_SHARED_SOURCE}
${SRC_LIST}
${PLATFORM_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${LIB_HOST_AGENT_SOURCE}
${NATIVE_INTERFACE_SOURCE}
${LIBC_BUILTIN_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
${IWASM_AOT_SOURCE}
${IWASM_COMPL_SOURCE}
${WASM_APP_LIB_SOURCE_ALL}
)
add_executable (gc_test ${unit_test_sources})
target_link_libraries (gc_test gtest_main)
add_custom_command(TARGET gc_test POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_LIST_DIR}/wasm-apps/*.was*
${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Copy wasm files to directory ${CMAKE_CURRENT_BINARY_DIR}"
)
#gtest_discover_tests(gc_test)

102
tests/unit/gc/gc_test.cc Normal file
View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "gtest/gtest.h"
#include "bh_platform.h"
#include "bh_read_file.h"
#include "wasm_export.h"
class WasmGCTest : public testing::Test
{
private:
std::string get_binary_path()
{
char cwd[1024] = { 0 };
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
return NULL;
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
protected:
void SetUp()
{
CWD = get_binary_path();
memset(&init_args, 0, sizeof(RuntimeInitArgs));
init_args.mem_alloc_type = Alloc_With_Pool;
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
ASSERT_EQ(wasm_runtime_full_init(&init_args), true);
cleanup = true;
}
void TearDown()
{
if (cleanup) {
wasm_runtime_destroy();
}
}
public:
bool load_wasm_file(const char *wasm_file)
{
const char *file;
unsigned char *wasm_file_buf;
uint32 wasm_file_size;
file = strdup((CWD + "/" + wasm_file).c_str());
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(file, &wasm_file_size);
if (!wasm_file_buf)
return false;
module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
if (!module)
return false;
return true;
}
public:
std::string CWD;
RuntimeInitArgs init_args;
wasm_module_t module = NULL;
wasm_module_inst_t module_inst = NULL;
wasm_function_inst_t func_inst = NULL;
wasm_exec_env_t exec_env = NULL;
char error_buf[128];
char global_heap_buf[512 * 1024];
bool cleanup = true;
};
TEST_F(WasmGCTest, Test_app1)
{
ASSERT_TRUE(load_wasm_file("test1.wasm"));
ASSERT_TRUE(load_wasm_file("test2.wasm"));
ASSERT_TRUE(load_wasm_file("test3.wasm"));
ASSERT_TRUE(load_wasm_file("test4.wasm"));
ASSERT_TRUE(load_wasm_file("test5.wasm"));
ASSERT_TRUE(load_wasm_file("test6.wasm"));
ASSERT_TRUE(load_wasm_file("struct1.wasm"));
ASSERT_TRUE(load_wasm_file("struct2.wasm"));
ASSERT_TRUE(load_wasm_file("struct3.wasm"));
ASSERT_TRUE(load_wasm_file("func1.wasm"));
ASSERT_TRUE(load_wasm_file("func2.wasm"));
}

Binary file not shown.

View File

@ -0,0 +1,35 @@
(module
(type $t (func))
(func (export "test") (param structref i31ref)
(local funcref)
(local funcref)
(local funcref)
(local externref)
(local externref)
(local externref)
(local anyref)
(local eqref)
(local structref)
(local arrayref)
(local i31ref)
(local (ref null 0))
(local (ref null 0))
(local (ref null 0))
(local (ref null 1))
(local (ref null func))
(local (ref null 0))
(local (ref null extern))
(local (ref null any))
(local (ref null eq))
(local (ref null i31))
(local (ref null struct))
local.get 0
ref.test null array
drop
local.get 1
ref.cast i31
drop
)
)

Binary file not shown.

View File

@ -0,0 +1,78 @@
(module
(type $t0 (func))
(type $t1 (func (param (ref null 1))))
(type $t2 (func (param funcref externref (ref func)(ref extern)
anyref eqref structref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 1) (ref $t0) (ref null func)
(ref null extern) (ref null 2) (ref null $t0))
(result (ref null func))))
(type $t3 (func (param i32 i32) (result (ref null 3))))
(type $t4 (func))
(type $t5 (func (param (ref null 3))))
(type $t6 (func (param funcref externref (ref func)(ref extern)
anyref eqref structref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))
(result (ref null func))))
(type $t7 (func (param i32 i32) (result (ref null 4))))
(type $t11 (struct (field i8 (mut i16) (mut i32) i64 f32 f64
funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null struct)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))))
(type $t12 (struct))
(type $t13 (struct (field)))
(type $t14 (struct (field i8)))
(type $t15 (struct (field i8 i8 i8 i8)))
(type $t16 (struct (field $x1 i32) (field $y1 i32)))
(type $t17 (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type $t18 (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type $t19 (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
(type $t20 (struct (field i8 (mut i16) (mut i32) i64 f32 f64
funcref externref (ref func)(ref extern)
anyref eqref structref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))))
(type $t21 (struct))
(type $t22 (struct (field)))
(type $t23 (struct (field i8)))
(type $t24 (struct (field i8 i8 i8 i8)))
(type $t25 (struct (field $x3 i32) (field $y3 i32)))
(type $t26 (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type $t27 (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type $t28 (struct (field $x4 i32) (field f32 f64) (field $y4 i32)))
(type $t31 (array i8))
(type $t32 (array i16))
(type $t33 (array i32))
(type $t34 (array i64))
(type $t35 (array f32))
(type $t36 (array f64))
(type $t37 (array anyref))
(type $t38 (array (ref i31)))
(type $t39 (array (ref 0)))
(type $t40 (array (ref null 1)))
(type $t43 (array (mut i8)))
(type $t44 (array (mut i16)))
(type $t45 (array (mut i32)))
(type $t46 (array (mut i64)))
(type $t47 (array (mut i32)))
(type $t48 (array (mut i64)))
(type $t49 (array (mut anyref)))
(type $t50 (array (mut (ref struct))))
(type $t51 (array (mut (ref 0))))
(type $t52 (array (mut (ref null i31))))
)

Binary file not shown.

View File

@ -0,0 +1,91 @@
(module
(type $ftype0 (func (param i32)))
(type $ftype1 (func (param i32 i64) (result i32)))
(type $ftype2 (func (param f32 f64) (result f64)))
(type $t0 (func (param (ref 1) (ref 2) (ref null 1) (ref null 2))))
(type $t1 (func (param funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 3) (ref null $t0))
(result (ref null func))))
(type $t2 (func (param i32 i32) (result (ref null 4))))
;; Duplicated types
(type $t3 (func))
(type $t4 (func (param (ref 1) (ref 2) (ref null 1) (ref null 2))))
(type $t5 (func (param funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 3) (ref null $t0))
(result (ref null func))))
(type $t6 (func (param i32 i32) (result (ref null 4))))
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))))
(type (struct))
(type (struct (field)))
(type (struct (field i8)))
(type (struct (field i8 i8 i8 i8)))
(type (struct (field $x1 i32) (field $y1 i32)))
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
;; Duplicated types
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))))
(type (struct))
(type (struct (field)))
(type (struct (field i8)))
(type (struct (field i8 i8 i8 i8)))
(type (struct (field $x3 i32) (field $y3 i32)))
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type (struct (field $x4 i32) (field f32 f64) (field $y4 i32)))
(type (array i8))
(type (array i16))
(type (array i32))
(type (array i64))
(type (array f32))
(type (array f64))
(type (array anyref))
(type (array (ref array)))
(type (array (ref 0)))
(type (array (ref null 1)))
(type (array (mut i8)))
(type (array (mut i16)))
(type (array (mut i32)))
(type (array (mut i64)))
(type (array (mut i32)))
(type (array (mut i64)))
(type (array (mut anyref)))
(type (array (mut (ref array))))
(type (array (mut (ref 0))))
(type (array (mut (ref null i31))))
(global $g0 funcref (ref.func $f0))
(global $g1 externref (ref.null extern))
(global $g2 anyref (ref.null any))
(global $g3 eqref (ref.null array))
(global $g4 arrayref (ref.null array))
(global $g5 i31ref (ref.null i31))
(func $f0)
)

Binary file not shown.

View File

@ -0,0 +1,10 @@
(module
(type (struct))
(type (struct (field)))
(type (struct (field i8)))
(type (struct (field i8 i8 i8 i8)))
(type (struct (field $x1 i32) (field $y1 i32)))
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
)

Binary file not shown.

View File

@ -0,0 +1,33 @@
(module
(type $vec (struct (field f32) (field $y (mut f32)) (field $z f32)))
;;(global (ref $vec) (struct.new_canon $vec (f32.const 1) (f32.const 2) (f32.const 3)))
(global (ref $vec) (struct.new_canon_default $vec))
(func (export "new") (result anyref)
(struct.new_canon_default $vec)
)
(func $get_0 (param $v (ref $vec)) (result f32)
(struct.get $vec 0 (local.get $v))
)
(func (export "get_0") (result f32)
(call $get_0 (struct.new_canon_default $vec))
)
(func $set_get_y (param $v (ref $vec)) (param $y f32) (result f32)
(struct.set $vec $y (local.get $v) (local.get $y))
(struct.get $vec $y (local.get $v))
)
(func (export "set_get_y") (param $y f32) (result f32)
(call $set_get_y (struct.new_canon_default $vec) (local.get $y))
)
(func $set_get_1 (param $v (ref $vec)) (param $y f32) (result f32)
(struct.set $vec 1 (local.get $v) (local.get $y))
(struct.get $vec $y (local.get $v))
)
(func (export "set_get_1") (param $y f32) (result f32)
(call $set_get_1 (struct.new_canon_default $vec) (local.get $y))
)
)

Binary file not shown.

View File

@ -0,0 +1,9 @@
(module
(type $t (struct (field i32 (mut i32))))
(func (export "struct.get-null")
(local (ref null $t)) (drop (struct.get $t 1 (local.get 0)))
)
(func (export "struct.set-null")
(local (ref null $t)) (struct.set $t 1 (local.get 0) (i32.const 0))
)
)

Binary file not shown.

View File

@ -0,0 +1,108 @@
(module
(type $ftype0 (func (param i32)))
(type $ftype1 (func (param i32 i64) (result i32)))
(type $ftype2 (func (param f32 f64) (result f64)))
(type $t0 (func (param (ref 1) (ref 2) (ref null 1) (ref null 2))))
(type $t1 (func (param funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 3) (ref null $t0))
(result (ref null func))))
(type $t2 (func (param i32 i32) (result (ref null 4))))
;; Duplicated types
(type $t3 (func))
(type $t4 (func (param (ref 1) (ref 2) (ref null 1) (ref null 2))))
(type $t5 (func (param funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 3) (ref null $t0))
(result (ref null func))))
(type $t6 (func (param i32 i32) (result (ref null 4))))
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))))
(type (struct))
(type (struct (field)))
(type (struct (field i8)))
(type (struct (field i8 i8 i8 i8)))
(type (struct (field $x1 i32) (field $y1 i32)))
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
;; Duplicated types
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
funcref externref (ref func)(ref extern)
anyref eqref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))))
(type (struct))
(type (struct (field)))
(type (struct (field i8)))
(type (struct (field i8 i8 i8 i8)))
(type (struct (field $x3 i32) (field $y3 i32)))
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type (struct (field $x4 i32) (field f32 f64) (field $y4 i32)))
(type (array i8))
(type (array i16))
(type (array i32))
(type (array i64))
(type (array f32))
(type (array f64))
(type (array anyref))
(type (array (ref array)))
(type (array (ref 0)))
(type (array (ref null 1)))
(type (array (mut i8)))
(type (array (mut i16)))
(type (array (mut i32)))
(type (array (mut i64)))
(type (array (mut i32)))
(type (array (mut i64)))
(type (array (mut anyref)))
(type (array (mut (ref array))))
(type (array (mut (ref 0))))
(type (array (mut (ref null i31))))
(table 10 funcref)
(table 20 externref)
;; non-defaultable element type
;; (table 30 (ref func))
;; (table 40 (ref extern))
(table 50 anyref)
(table 60 eqref)
(table 100 arrayref)
(table 100 i31ref)
(table 100 (ref null 0))
(table 100 (ref null 2))
(table 100 (ref null func))
(table 100 (ref null extern))
(table 100 (ref null any))
(table 100 (ref null eq))
(table 100 (ref null i31))
(table 100 (ref null array))
;; non-defaultable element type
;; (table 100 (ref 0))
;; (table 100 (ref $t0))
;; (table 100 (ref 3))
;; (table 100 (ref $t0))
(table 100 (ref null func))
(table 100 (ref null extern))
(table 100 (ref null 5))
(table 100 (ref null $t0))
)

Binary file not shown.

View File

@ -0,0 +1,117 @@
(module
(type $t (func))
(type $t0 (func (param (ref null $t) (ref $t) (ref null 0) (ref 0) (ref null 1) (ref 1))))
(type $t1 (func (param funcref externref anyref eqref
i31ref structref arrayref
nullref nullfuncref nullexternref
(ref null func) (ref null extern) (ref null any) (ref null eq)
(ref null i31) (ref null struct) (ref null array)
(ref null none) (ref null nofunc) (ref null noextern)
(ref func) (ref extern) (ref any) (ref eq)
(ref i31) (ref struct) (ref array)
(ref none) (ref nofunc) (ref noextern)
(ref null 0) (ref null $t0) (ref null $t1)
(ref null func) (ref null extern) (ref null any) (ref null eq)
(ref null i31) (ref null struct) (ref null array)
(ref $t) (ref $t0) (ref $t1)
(ref func) (ref extern) (ref any) (ref eq)
(ref i31) (ref struct) (ref array))
(result (ref null func) (ref null extern) (ref $t0))))
(type $t2 (func (param i32 i32) (result (ref null $t1))))
;; Duplicated types
(type $t3 (func))
(type $t4 (func (param (ref null $t) (ref $t) (ref null 0) (ref 0) (ref null 1) (ref 1))))
(type $t5 (func (param funcref externref anyref eqref
i31ref structref arrayref
nullref nullfuncref nullexternref
(ref null func) (ref null extern) (ref null any) (ref null eq)
(ref null i31) (ref null struct) (ref null array)
(ref null none) (ref null nofunc) (ref null noextern)
(ref func) (ref extern) (ref any) (ref eq)
(ref i31) (ref struct) (ref array)
(ref none) (ref nofunc) (ref noextern)
(ref null 0) (ref null $t0) (ref null $t1)
(ref null func) (ref null extern) (ref null any) (ref null eq)
(ref null i31) (ref null struct) (ref null array)
(ref $t) (ref $t0) (ref $t1)
(ref func) (ref extern) (ref any) (ref eq)
(ref i31) (ref struct) (ref array))
(result (ref null func) (ref null extern) (ref $t0))))
(type $t6 (func (param i32 i32) (result (ref null $t1))))
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
funcref externref (ref func) (ref extern)
anyref eqref structref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null struct) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))))
(type (struct))
(type (struct (field)))
(type (struct (field i8)))
(type (struct (field i8 i8 i8 i8)))
(type (struct (field $x1 i32) (field $y1 i32)))
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type (struct (field $x2 i32) (field f32 f64) (field $y2 i32)))
;; Duplicated types
(type (struct (field i8 (mut i16) (mut i32) i64 f32 f64
funcref externref (ref func) (ref extern)
anyref eqref structref arrayref i31ref
(ref null 0) (ref null 2) (ref null func) (ref null extern)
(ref null any) (ref null eq) (ref null i31) (ref null struct) (ref null array)
(ref 0) (ref $t0) (ref 3) (ref $t0) (ref null func)
(ref null extern) (ref null 5) (ref null $t0))))
(type (struct))
(type (struct (field)))
(type (struct (field i8)))
(type (struct (field i8 i8 i8 i8)))
(type (struct (field $x3 i32) (field $y3 i32)))
(type (struct (field i8 i16 i32 i64 f32 f64 anyref funcref (ref 0) (ref null 1))))
(type (struct (field i32 i64 i8) (field) (field) (field (ref null i31) anyref)))
(type (struct (field $x4 i32) (field f32 f64) (field $y4 i32)))
(type (array i8))
(type (array i16))
(type (array i32))
(type (array i64))
(type (array f32))
(type (array f64))
(type (array anyref))
(type (array (ref struct)))
(type (array (ref array)))
(type (array (ref null struct)))
(type (array (ref null array)))
(type (array (ref 0)))
(type (array (ref null 1)))
(type (array (mut i8)))
(type (array (mut i16)))
(type (array (mut i32)))
(type (array (mut i64)))
(type (array (mut i32)))
(type (array (mut i64)))
(type (array (mut anyref)))
(type (array (mut (ref struct))))
(type (array (mut (ref array))))
(type (array (mut (ref null struct))))
(type (array (mut (ref null array))))
(type (array (mut (ref 0))))
(type (array (mut (ref null i31))))
;; sub types
(type $e0 (sub (array i32)))
(type $e1 (sub $e0 (array i32)))
(type $e2 (sub (array anyref)))
(type $e3 (sub (array (ref null $e0))))
(type $e4 (sub (array (ref $e1))))
(type $e5 (sub $e1 (array i32)))
(type $m1 (sub (array (mut i32))))
(type $m2 (sub $m1 (array (mut i32))))
)

Binary file not shown.

View File

@ -0,0 +1,104 @@
(module
(type $ft (func))
(type $st (struct))
(type $at (array i8))
(table $ta 10 anyref)
(table $tf 10 funcref)
(table $te 10 externref)
(elem declare func $f)
(func $f)
(func (export "init") (param $x externref)
(table.set $ta (i32.const 0) (ref.null any))
(table.set $ta (i32.const 1) (ref.null struct))
(table.set $ta (i32.const 2) (ref.null none))
(table.set $ta (i32.const 3) (i31.new (i32.const 7)))
(table.set $ta (i32.const 4) (struct.new_canon_default $st))
(table.set $ta (i32.const 5) (array.new_canon_default $at (i32.const 0)))
(table.set $ta (i32.const 6) (extern.internalize (local.get $x)))
(table.set $ta (i32.const 7) (extern.internalize (ref.null extern)))
(table.set $tf (i32.const 0) (ref.null nofunc))
(table.set $tf (i32.const 1) (ref.null func))
(table.set $tf (i32.const 2) (ref.func $f))
(table.set $te (i32.const 0) (ref.null noextern))
(table.set $te (i32.const 1) (ref.null extern))
(table.set $te (i32.const 2) (local.get $x))
(table.set $te (i32.const 3) (extern.externalize (i31.new (i32.const 8))))
(table.set $te (i32.const 4) (extern.externalize (struct.new_canon_default $st)))
(table.set $te (i32.const 5) (extern.externalize (ref.null any)))
)
(func (export "ref_test_null_data") (param $i i32) (result i32)
(i32.add
(ref.is_null (table.get $ta (local.get $i)))
(ref.test null none (table.get $ta (local.get $i)))
)
)
(func (export "ref_test_any") (param $i i32) (result i32)
(i32.add
(ref.test any (table.get $ta (local.get $i)))
(ref.test null any (table.get $ta (local.get $i)))
)
)
(func (export "ref_test_eq") (param $i i32) (result i32)
(i32.add
(ref.test eq (table.get $ta (local.get $i)))
(ref.test null eq (table.get $ta (local.get $i)))
)
)
(func (export "ref_test_i31") (param $i i32) (result i32)
(i32.add
(ref.test i31 (table.get $ta (local.get $i)))
(ref.test null i31 (table.get $ta (local.get $i)))
)
)
(func (export "ref_test_struct") (param $i i32) (result i32)
(i32.add
(ref.test struct (table.get $ta (local.get $i)))
(ref.test null struct (table.get $ta (local.get $i)))
)
)
(func (export "ref_test_array") (param $i i32) (result i32)
(i32.add
(ref.test array (table.get $ta (local.get $i)))
(ref.test null array (table.get $ta (local.get $i)))
)
)
(func (export "ref_test_null_func") (param $i i32) (result i32)
(i32.add
(ref.is_null (table.get $tf (local.get $i)))
(ref.test null nofunc (table.get $tf (local.get $i)))
)
)
(func (export "ref_test_func") (param $i i32) (result i32)
(i32.add
(ref.test func (table.get $tf (local.get $i)))
(ref.test null func (table.get $tf (local.get $i)))
)
)
(func (export "ref_test_null_extern") (param $i i32) (result i32)
(i32.add
(ref.is_null (table.get $te (local.get $i)))
(ref.test null noextern (table.get $te (local.get $i)))
)
)
(func (export "ref_test_extern") (param $i i32) (result i32)
(i32.add
(ref.test extern (table.get $te (local.get $i)))
(ref.test null extern (table.get $te (local.get $i)))
)
)
)

Binary file not shown.

View File

@ -0,0 +1,146 @@
(module
(type $t0 (sub (struct)))
(type $t1 (sub $t0 (struct (field i32))))
(type $t1' (sub $t0 (struct (field i32))))
(type $t2 (sub $t1 (struct (field i32 i32))))
(type $t2' (sub $t1' (struct (field i32 i32))))
(type $t3 (sub $t0 (struct (field i32 i32))))
(type $t0' (sub $t0 (struct)))
(type $t4 (sub $t0' (struct (field i32 i32))))
(table 20 (ref null struct))
(func $init
(table.set (i32.const 0) (struct.new_canon_default $t0))
(table.set (i32.const 10) (struct.new_canon_default $t0))
(table.set (i32.const 1) (struct.new_canon_default $t1))
(table.set (i32.const 11) (struct.new_canon_default $t1'))
(table.set (i32.const 2) (struct.new_canon_default $t2))
(table.set (i32.const 12) (struct.new_canon_default $t2'))
(table.set (i32.const 3) (struct.new_canon_default $t3))
(table.set (i32.const 4) (struct.new_canon_default $t4))
)
(func (export "test-sub")
(call $init)
(block $l
;; must hold
(br_if $l (i32.eqz (ref.test null $t0 (ref.null struct))))
(br_if $l (i32.eqz (ref.test null $t0 (ref.null $t0))))
(br_if $l (i32.eqz (ref.test null $t0 (ref.null $t1))))
(br_if $l (i32.eqz (ref.test null $t0 (ref.null $t2))))
(br_if $l (i32.eqz (ref.test null $t0 (ref.null $t3))))
(br_if $l (i32.eqz (ref.test null $t0 (ref.null $t4))))
(br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 0)))))
(br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 1)))))
(br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 3)))))
(br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 4)))))
(br_if $l (i32.eqz (ref.test null $t1 (ref.null struct))))
(br_if $l (i32.eqz (ref.test null $t1 (ref.null $t0))))
(br_if $l (i32.eqz (ref.test null $t1 (ref.null $t1))))
(br_if $l (i32.eqz (ref.test null $t1 (ref.null $t2))))
(br_if $l (i32.eqz (ref.test null $t1 (ref.null $t3))))
(br_if $l (i32.eqz (ref.test null $t1 (ref.null $t4))))
(br_if $l (i32.eqz (ref.test null $t1 (table.get (i32.const 1)))))
(br_if $l (i32.eqz (ref.test null $t1 (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test null $t2 (ref.null struct))))
(br_if $l (i32.eqz (ref.test null $t2 (ref.null $t0))))
(br_if $l (i32.eqz (ref.test null $t2 (ref.null $t1))))
(br_if $l (i32.eqz (ref.test null $t2 (ref.null $t2))))
(br_if $l (i32.eqz (ref.test null $t2 (ref.null $t3))))
(br_if $l (i32.eqz (ref.test null $t2 (ref.null $t4))))
(br_if $l (i32.eqz (ref.test null $t2 (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test null $t3 (ref.null struct))))
(br_if $l (i32.eqz (ref.test null $t3 (ref.null $t0))))
(br_if $l (i32.eqz (ref.test null $t3 (ref.null $t1))))
(br_if $l (i32.eqz (ref.test null $t3 (ref.null $t2))))
(br_if $l (i32.eqz (ref.test null $t3 (ref.null $t3))))
(br_if $l (i32.eqz (ref.test null $t3 (ref.null $t4))))
(br_if $l (i32.eqz (ref.test null $t3 (table.get (i32.const 3)))))
(br_if $l (i32.eqz (ref.test null $t4 (ref.null struct))))
(br_if $l (i32.eqz (ref.test null $t4 (ref.null $t0))))
(br_if $l (i32.eqz (ref.test null $t4 (ref.null $t1))))
(br_if $l (i32.eqz (ref.test null $t4 (ref.null $t2))))
(br_if $l (i32.eqz (ref.test null $t4 (ref.null $t3))))
(br_if $l (i32.eqz (ref.test null $t4 (ref.null $t4))))
(br_if $l (i32.eqz (ref.test null $t4 (table.get (i32.const 4)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 0)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 1)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 3)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 4)))))
(br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 1)))))
(br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test $t2 (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test $t3 (table.get (i32.const 3)))))
(br_if $l (i32.eqz (ref.test $t4 (table.get (i32.const 4)))))
;; must not hold
(br_if $l (ref.test $t0 (ref.null struct)))
(br_if $l (ref.test $t1 (ref.null struct)))
(br_if $l (ref.test $t2 (ref.null struct)))
(br_if $l (ref.test $t3 (ref.null struct)))
(br_if $l (ref.test $t4 (ref.null struct)))
(br_if $l (ref.test $t1 (table.get (i32.const 0))))
(br_if $l (ref.test $t1 (table.get (i32.const 3))))
(br_if $l (ref.test $t1 (table.get (i32.const 4))))
(br_if $l (ref.test $t2 (table.get (i32.const 0))))
(br_if $l (ref.test $t2 (table.get (i32.const 1))))
(br_if $l (ref.test $t2 (table.get (i32.const 3))))
(br_if $l (ref.test $t2 (table.get (i32.const 4))))
(br_if $l (ref.test $t3 (table.get (i32.const 0))))
(br_if $l (ref.test $t3 (table.get (i32.const 1))))
(br_if $l (ref.test $t3 (table.get (i32.const 2))))
(br_if $l (ref.test $t3 (table.get (i32.const 4))))
(br_if $l (ref.test $t4 (table.get (i32.const 0))))
(br_if $l (ref.test $t4 (table.get (i32.const 1))))
(br_if $l (ref.test $t4 (table.get (i32.const 2))))
(br_if $l (ref.test $t4 (table.get (i32.const 3))))
(return)
)
(unreachable)
)
(func (export "test-canon")
(call $init)
(block $l
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 0)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 1)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 3)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 4)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 10)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 11)))))
(br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 12)))))
(br_if $l (i32.eqz (ref.test $t1' (table.get (i32.const 1)))))
(br_if $l (i32.eqz (ref.test $t1' (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 11)))))
(br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 12)))))
(br_if $l (i32.eqz (ref.test $t2' (table.get (i32.const 2)))))
(br_if $l (i32.eqz (ref.test $t2 (table.get (i32.const 12)))))
(return)
)
(unreachable)
)
)

Binary file not shown.

View File

@ -0,0 +1,46 @@
(module
(type $ft (func))
(type $st (struct))
(type $at (array i8))
(table 10 anyref)
(elem declare func $f)
(func $f)
(func (export "init") (param $x externref)
(table.set (i32.const 0) (ref.null any))
(table.set (i32.const 1) (i31.new (i32.const 7)))
(table.set (i32.const 2) (struct.new_canon_default $st))
(table.set (i32.const 3) (array.new_canon_default $at (i32.const 0)))
(table.set (i32.const 4) (extern.internalize (local.get $x)))
(table.set (i32.const 5) (ref.null i31))
(table.set (i32.const 6) (ref.null struct))
(table.set (i32.const 7) (ref.null none))
)
(func (export "ref_cast_non_null") (param $i i32)
(drop (ref.as_non_null (table.get (local.get $i))))
(drop (ref.cast null any (table.get (local.get $i))))
)
(func (export "ref_cast_null") (param $i i32)
(drop (ref.cast null any (table.get (local.get $i))))
(drop (ref.cast null struct (table.get (local.get $i))))
(drop (ref.cast null array (table.get (local.get $i))))
(drop (ref.cast null i31 (table.get (local.get $i))))
(drop (ref.cast null none (table.get (local.get $i))))
)
(func (export "ref_cast_i31") (param $i i32)
(drop (ref.cast i31 (table.get (local.get $i))))
(drop (ref.cast null i31 (table.get (local.get $i))))
)
(func (export "ref_cast_struct") (param $i i32)
(drop (ref.cast struct (table.get (local.get $i))))
(drop (ref.cast null struct (table.get (local.get $i))))
)
(func (export "ref_cast_array") (param $i i32)
(drop (ref.cast array (table.get (local.get $i))))
(drop (ref.cast null array (table.get (local.get $i))))
)
)

Binary file not shown.

View File

@ -0,0 +1,85 @@
(module
(type $t0 (sub (struct)))
(type $t1 (sub $t0 (struct (field i32))))
(type $t1' (sub $t0 (struct (field i32))))
(type $t2 (sub $t1 (struct (field i32 i32))))
(type $t2' (sub $t1' (struct (field i32 i32))))
(type $t3 (sub $t0 (struct (field i32 i32))))
(type $t0' (sub $t0 (struct)))
(type $t4 (sub $t0' (struct (field i32 i32))))
(table 20 (ref null struct))
(func $init
(table.set (i32.const 0) (struct.new_canon_default $t0))
(table.set (i32.const 10) (struct.new_canon_default $t0))
(table.set (i32.const 1) (struct.new_canon_default $t1))
(table.set (i32.const 11) (struct.new_canon_default $t1'))
(table.set (i32.const 2) (struct.new_canon_default $t2))
(table.set (i32.const 12) (struct.new_canon_default $t2'))
(table.set (i32.const 3) (struct.new_canon_default $t3))
(table.set (i32.const 4) (struct.new_canon_default $t4))
)
(func (export "test-sub")
(call $init)
(drop (ref.cast null $t0 (ref.null struct)))
(drop (ref.cast null $t0 (table.get (i32.const 0))))
(drop (ref.cast null $t0 (table.get (i32.const 1))))
(drop (ref.cast null $t0 (table.get (i32.const 2))))
(drop (ref.cast null $t0 (table.get (i32.const 3))))
(drop (ref.cast null $t0 (table.get (i32.const 4))))
(drop (ref.cast null $t0 (ref.null struct)))
(drop (ref.cast null $t1 (table.get (i32.const 1))))
(drop (ref.cast null $t1 (table.get (i32.const 2))))
(drop (ref.cast null $t0 (ref.null struct)))
(drop (ref.cast null $t2 (table.get (i32.const 2))))
(drop (ref.cast null $t0 (ref.null struct)))
(drop (ref.cast null $t3 (table.get (i32.const 3))))
(drop (ref.cast null $t4 (table.get (i32.const 4))))
(drop (ref.cast $t0 (table.get (i32.const 0))))
(drop (ref.cast $t0 (table.get (i32.const 1))))
(drop (ref.cast $t0 (table.get (i32.const 2))))
(drop (ref.cast $t0 (table.get (i32.const 3))))
(drop (ref.cast $t0 (table.get (i32.const 4))))
(drop (ref.cast $t1 (table.get (i32.const 1))))
(drop (ref.cast $t1 (table.get (i32.const 2))))
(drop (ref.cast $t2 (table.get (i32.const 2))))
(drop (ref.cast $t3 (table.get (i32.const 3))))
(drop (ref.cast $t4 (table.get (i32.const 4))))
)
(func (export "test-canon")
(call $init)
(drop (ref.cast $t0 (table.get (i32.const 0))))
(drop (ref.cast $t0 (table.get (i32.const 1))))
(drop (ref.cast $t0 (table.get (i32.const 2))))
(drop (ref.cast $t0 (table.get (i32.const 3))))
(drop (ref.cast $t0 (table.get (i32.const 4))))
(drop (ref.cast $t0 (table.get (i32.const 10))))
(drop (ref.cast $t0 (table.get (i32.const 11))))
(drop (ref.cast $t0 (table.get (i32.const 12))))
(drop (ref.cast $t1' (table.get (i32.const 1))))
(drop (ref.cast $t1' (table.get (i32.const 2))))
(drop (ref.cast $t1 (table.get (i32.const 11))))
(drop (ref.cast $t1 (table.get (i32.const 12))))
(drop (ref.cast $t2' (table.get (i32.const 2))))
(drop (ref.cast $t2 (table.get (i32.const 12))))
)
)

Binary file not shown.

View File

@ -0,0 +1,27 @@
(module
(type $st (sub (struct)))
(type $st' (sub (struct (field i32))))
(type $at (array i8))
(type $st-sub1 (sub $st (struct)))
(type $st-sub2 (sub $st (struct)))
(type $st'-sub1 (sub $st' (struct (field i32))))
(type $st'-sub2 (sub $st' (struct (field i32))))
(table 20 (ref null eq))
(func (export "init")
(table.set (i32.const 0) (ref.null eq))
(table.set (i32.const 1) (ref.null i31))
(table.set (i32.const 2) (i31.new (i32.const 7)))
(table.set (i32.const 3) (i31.new (i32.const 7)))
(table.set (i32.const 4) (i31.new (i32.const 8)))
(table.set (i32.const 5) (struct.new_canon_default $st))
(table.set (i32.const 6) (struct.new_canon_default $st))
(table.set (i32.const 7) (array.new_canon_default $at (i32.const 0)))
(table.set (i32.const 8) (array.new_canon_default $at (i32.const 0)))
)
(func (export "eq") (param $i i32) (param $j i32) (result i32)
(ref.eq (table.get (local.get $i)) (table.get (local.get $j)))
)
)

1
tests/unit/interpreter/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build/*

View File

@ -0,0 +1,42 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-interpreter)
add_definitions (-DRUN_ON_LINUX)
add_definitions (-Dattr_container_malloc=malloc)
add_definitions (-Dattr_container_free=free)
# add_definitions (-DWASM_ENABLE_WAMR_COMPILER=1)
set (WAMR_BUILD_LIBC_WASI 0)
set (WAMR_BUILD_APP_FRAMEWORK 1)
set (WAMR_BUILD_AOT 0)
include (../unit_common.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${PLATFORM_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${NATIVE_INTERFACE_SOURCE}
${LIBC_BUILTIN_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
)
# Now simply link against gtest or gtest_main as needed. Eg
add_executable (interpreter_test ${unit_test_sources})
target_link_libraries (interpreter_test ${LLVM_AVAILABLE_LIBS} gtest_main )
gtest_discover_tests(interpreter_test)

View File

@ -0,0 +1,50 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include <limits.h>
#include "gtest/gtest.h"
#include "wasm_runtime_common.h"
#include "bh_platform.h"
// To use a test fixture, derive a class from testing::Test.
class InterpreterTest : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp()
{
memset(&init_args, 0, sizeof(RuntimeInitArgs));
init_args.mem_alloc_type = Alloc_With_Pool;
init_args.mem_alloc_option.pool.heap_buf = global_heap_buf;
init_args.mem_alloc_option.pool.heap_size = sizeof(global_heap_buf);
ASSERT_EQ(wasm_runtime_full_init(&init_args), true);
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() { wasm_runtime_destroy(); }
public:
char global_heap_buf[512 * 1024];
RuntimeInitArgs init_args;
};
TEST_F(InterpreterTest, wasm_runtime_is_built_in_module)
{
bool ret = wasm_runtime_is_built_in_module("env");
ASSERT_TRUE(ret);
ret = ret = wasm_runtime_is_built_in_module("env1");
ASSERT_FALSE(ret);
}

View File

@ -0,0 +1,32 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-libc-builtin)
add_definitions (-DRUN_ON_LINUX)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set (WAMR_BUILD_LIBC_WASI 0)
set (WAMR_BUILD_APP_FRAMEWORK 0)
include (../unit_common.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${WAMR_RUNTIME_LIB_SOURCE}
)
add_executable (libc_builtin_test ${unit_test_sources})
target_link_libraries (libc_builtin_test gtest_main)
gtest_discover_tests(libc_builtin_test)

View File

@ -0,0 +1,170 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#pragma once
#include "bh_platform.h"
#include "wasm_export.h"
extern "C" {
typedef char *_va_list;
typedef int (*printf_func_type)(wasm_exec_env_t exec_env, const char *format,
_va_list va_args);
typedef int (*sprintf_func_type)(wasm_exec_env_t exec_env, char *str,
const char *format, _va_list va_args);
typedef int (*snprintf_func_type)(wasm_exec_env_t exec_env, char *str,
uint32 size, const char *format,
_va_list va_args);
typedef int (*puts_func_type)(wasm_exec_env_t exec_env, const char *str);
typedef int (*putchar_func_type)(wasm_exec_env_t exec_env, int c);
typedef uint32 (*strdup_func_type)(wasm_exec_env_t exec_env, const char *str);
typedef uint32 (*_strdup_func_type)(wasm_exec_env_t exec_env, const char *str);
typedef int32 (*memcmp_func_type)(wasm_exec_env_t exec_env, const void *s1,
const void *s2, uint32 size);
typedef uint32 (*memcpy_func_type)(wasm_exec_env_t exec_env, void *dst,
const void *src, uint32 size);
typedef uint32 (*memmove_func_type)(wasm_exec_env_t exec_env, void *dst,
void *src, uint32 size);
typedef uint32 (*memset_func_type)(wasm_exec_env_t exec_env, void *s, int32 c,
uint32 size);
typedef uint32 (*strchr_func_type)(wasm_exec_env_t exec_env, const char *s,
int32 c);
typedef int32 (*strcmp_func_type)(wasm_exec_env_t exec_env, const char *s1,
const char *s2);
typedef int32 (*strncmp_func_type)(wasm_exec_env_t exec_env, const char *s1,
const char *s2, uint32 size);
typedef uint32 (*strcpy_func_type)(wasm_exec_env_t exec_env, char *dst,
const char *src);
typedef uint32 (*strncpy_func_type)(wasm_exec_env_t exec_env, char *dst,
const char *src, uint32 size);
typedef uint32 (*strlen_func_type)(wasm_exec_env_t exec_env, const char *s);
typedef uint32 (*malloc_func_type)(wasm_exec_env_t exec_env, uint32 size);
typedef uint32 (*calloc_func_type)(wasm_exec_env_t exec_env, uint32 nmemb,
uint32 size);
typedef uint32 (*realloc_func_type)(wasm_exec_env_t exec_env, uint32 ptr,
uint32 new_size);
typedef void (*free_func_type)(wasm_exec_env_t exec_env, void *ptr);
typedef int32 (*atoi_func_type)(wasm_exec_env_t exec_env, const char *s);
typedef void (*exit_func_type)(wasm_exec_env_t exec_env, int32 status);
typedef int32 (*strtol_func_type)(wasm_exec_env_t exec_env, const char *nptr,
char **endptr, int32 base);
typedef uint32 (*strtoul_func_type)(wasm_exec_env_t exec_env, const char *nptr,
char **endptr, int32 base);
typedef uint32 (*memchr_func_type)(wasm_exec_env_t exec_env, const void *s,
int32 c, uint32 n);
typedef int32 (*strncasecmp_func_type)(wasm_exec_env_t exec_env, const char *s1,
const char *s2, uint32 n);
typedef uint32 (*strspn_func_type)(wasm_exec_env_t exec_env, const char *s,
const char *accept);
typedef uint32 (*strcspn_func_type)(wasm_exec_env_t exec_env, const char *s,
const char *reject);
typedef uint32 (*strstr_func_type)(wasm_exec_env_t exec_env, const char *s,
const char *find);
typedef int32 (*isupper_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*isalpha_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*isspace_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*isgraph_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*isprint_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*isdigit_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*isxdigit_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*tolower_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*toupper_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef int32 (*isalnum_func_type)(wasm_exec_env_t exec_env, int32 c);
typedef void (*setTempRet0_func_type)(wasm_exec_env_t exec_env,
uint32 temp_ret);
typedef uint32 (*getTempRet0_func_type)(wasm_exec_env_t exec_env);
typedef uint32 (*llvm_bswap_i16_func_type)(wasm_exec_env_t exec_env,
uint32 data);
typedef uint32 (*llvm_bswap_i32_func_type)(wasm_exec_env_t exec_env,
uint32 data);
typedef uint32 (*bitshift64Lshr_func_type)(wasm_exec_env_t exec_env,
uint32 uint64_part0,
uint32 uint64_part1, uint32 bits);
typedef uint32 (*bitshift64Shl_func_type)(wasm_exec_env_t exec_env,
uint32 int64_part0,
uint32 int64_part1, uint32 bits);
typedef void (*llvm_stackrestore_func_type)(wasm_exec_env_t exec_env,
uint32 llvm_stack);
typedef uint32 (*llvm_stacksave_func_type)(wasm_exec_env_t exec_env);
typedef uint32 (*emscripten_memcpy_big_func_type)(wasm_exec_env_t exec_env,
void *dst, const void *src,
uint32 size);
typedef void (*abort_func_type)(wasm_exec_env_t exec_env, int32 code);
typedef void (*abortStackOverflow_func_type)(wasm_exec_env_t exec_env,
int32 code);
typedef void (*nullFunc_X_func_type)(wasm_exec_env_t exec_env, int32 code);
typedef uint32 (*__cxa_allocate_exception_func_type)(wasm_exec_env_t exec_env,
uint32 thrown_size);
typedef void (*__cxa_begin_catch_func_type)(wasm_exec_env_t exec_env,
void *exception_object);
typedef void (*__cxa_throw_func_type)(wasm_exec_env_t exec_env,
void *thrown_exception, void *tinfo,
uint32 table_elem_idx);
struct timespec_app {
int64 tv_sec;
int32 tv_nsec;
};
typedef uint32 (*clock_gettime_func_type)(wasm_exec_env_t exec_env,
uint32 clk_id,
struct timespec_app *ts_app);
typedef uint64 (*clock_func_type)(wasm_exec_env_t exec_env);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-linear-memory-aot)
add_definitions (-DRUN_ON_LINUX)
set (WAMR_BUILD_LIBC_WASI 0)
set (WAMR_BUILD_APP_FRAMEWORK 0)
set (WAMR_BUILD_MEMORY_PROFILING 1)
set (WAMR_BUILD_INTERP 0)
set (WAMR_BUILD_AOT 1)
include (../unit_common.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${WAMR_RUNTIME_LIB_SOURCE}
${UNCOMMON_SHARED_SOURCE}
${SRC_LIST}
${PLATFORM_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${LIB_HOST_AGENT_SOURCE}
${NATIVE_INTERFACE_SOURCE}
${LIBC_BUILTIN_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
${IWASM_AOT_SOURCE}
${IWASM_COMPL_SOURCE}
${WASM_APP_LIB_SOURCE_ALL}
)
# Test case: .aot file with hardware bound check.
add_executable (linear_memory_test_aot ${unit_test_sources})
target_link_libraries (linear_memory_test_aot gtest_main)
gtest_discover_tests(linear_memory_test_aot)
target_compile_definitions(linear_memory_test_aot PRIVATE WAMR_DISABLE_HW_BOUND_CHECK=0)
# Ensure that aot compiled is completed before linear_memory_test_aot is built
set(dummy_output "${CMAKE_CURRENT_BINARY_DIR}/dummy_output")
add_custom_command(OUTPUT ${dummy_output}
COMMAND ./build_aot.sh
COMMAND ${CMAKE_COMMAND} -E touch ${dummy_output}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/build_aot.sh
COMMENT "Executing script to compile aot files"
VERBATIM
)
add_custom_target(
RunBuildAot ALL
DEPENDS ${dummy_output}
)
add_dependencies(linear_memory_test_aot RunBuildAot)
add_custom_command(TARGET linear_memory_test_aot POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_SOURCE_DIR}/build/*.aot
${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Copy aot files to the directory: build/linear-memory-aot."
)
# Test case: .aot file with no hardware bound check.
add_executable (linear_memory_test_aot_no_hw_bound ${unit_test_sources})
target_link_libraries (linear_memory_test_aot_no_hw_bound gtest_main)
gtest_discover_tests(linear_memory_test_aot_no_hw_bound)
target_compile_definitions(linear_memory_test_aot_no_hw_bound PRIVATE WAMR_DISABLE_HW_BOUND_CHECK=1)

View File

@ -0,0 +1,45 @@
#!/bin/bash
#
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
#
# Define a list of .wasm files
file_names=("mem_grow_out_of_bounds_01" "mem_grow_out_of_bounds_02"
"mem_page_01" "mem_page_02" "mem_page_03" "mem_page_05"
"mem_page_07" "mem_page_08" "mem_page_09" "mem_page_10"
"mem_page_12" "mem_page_14" "mem_page_16" "mem_page_20" "out_of_bounds")
WORKDIR="$PWD"
WAMRC_ROOT_DIR="${WORKDIR}/../../../wamr-compiler"
WAMRC="${WAMRC_ROOT_DIR}/build/wamrc"
WAST2WASM="/opt/wabt/bin/wat2wasm"
# build wamrc if not exist
if [ ! -s "$WAMRC" ]; then
cd $WAMRC_ROOT_DIR
if [ -d "$WAMRC/build" ]; then
rm -r build
fi
cmake -B build && cmake --build build -j $(nproc)
cd $WORKDIR
fi
# error if not exist
if [ ! -s "$WAST2WASM" ]; then
echo "please install wabt first" && exit -1
fi
# Iterate over the files array
rm -r build
mkdir build
for file_name in "${file_names[@]}"; do
# wast to wasm
$WAST2WASM "${file_name}.wast" -o "build/${file_name}.wasm"
# compile the aot files, x86-64, x86-32, no_hw_bounds, no_hw_bounds_x32
$WAMRC -o "build/${file_name}.aot" "build/${file_name}.wasm"
$WAMRC --target=i386 -o "build/${file_name}_32.aot" "build/${file_name}.wasm"
$WAMRC --bounds-checks=1 -o "build/${file_name}_no_hw_bounds.aot" "build/${file_name}.wasm"
$WAMRC --bounds-checks=1 --target=i386 -o "build/${file_name}_no_hw_bounds_32.aot" "build/${file_name}.wasm"
done

View File

@ -0,0 +1,361 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "bh_read_file.h"
#include "wasm_runtime_common.h"
static std::string CWD;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
#if WASM_DISABLE_HW_BOUND_CHECK != 0
#define TEST_SUITE_NAME linear_memory_test_suite_aot_no_hw_bound
#else
#define TEST_SUITE_NAME linear_memory_test_suite_aot
#endif
class TEST_SUITE_NAME : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase() { CWD = get_binary_path(); }
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
WAMRRuntimeRAII<512 * 1024> runtime;
};
struct ret_env {
wasm_exec_env_t exec_env;
wasm_module_t aot_module;
wasm_module_inst_t aot_module_inst;
unsigned char *aot_file_buf;
char error_buf[128];
};
struct ret_env
load_aot(char *aot_file_tested, unsigned int app_heap_size)
{
std::string aot_mem_page = aot_file_tested;
const char *aot_file = strdup((CWD + aot_mem_page).c_str());
wasm_module_inst_t aot_module_inst = nullptr;
wasm_module_t aot_module = nullptr;
wasm_exec_env_t exec_env = nullptr;
unsigned char *aot_file_buf = nullptr;
unsigned int aot_file_size = 0;
unsigned int stack_size = 16 * 1024, heap_size = app_heap_size;
char error_buf[128] = { 0 };
struct ret_env ret_module_env;
memset(ret_module_env.error_buf, 0, 128);
aot_file_buf =
(unsigned char *)bh_read_file_to_buffer(aot_file, &aot_file_size);
if (!aot_file_buf) {
goto fail;
}
aot_module = wasm_runtime_load(aot_file_buf, aot_file_size, error_buf,
sizeof(error_buf));
if (!aot_module) {
memcpy(ret_module_env.error_buf, error_buf, 128);
goto fail;
}
aot_module_inst = wasm_runtime_instantiate(
aot_module, stack_size, heap_size, error_buf, sizeof(error_buf));
if (!aot_module_inst) {
memcpy(ret_module_env.error_buf, error_buf, 128);
goto fail;
}
exec_env = wasm_runtime_create_exec_env(aot_module_inst, stack_size);
fail:
ret_module_env.exec_env = exec_env;
ret_module_env.aot_module = aot_module;
ret_module_env.aot_module_inst = aot_module_inst;
ret_module_env.aot_file_buf = aot_file_buf;
return ret_module_env;
}
void
destroy_module_env(struct ret_env module_env)
{
if (module_env.exec_env) {
wasm_runtime_destroy_exec_env(module_env.exec_env);
}
if (module_env.aot_module_inst) {
wasm_runtime_deinstantiate(module_env.aot_module_inst);
}
if (module_env.aot_module) {
wasm_runtime_unload(module_env.aot_module);
}
if (module_env.aot_file_buf) {
wasm_runtime_free(module_env.aot_file_buf);
}
}
TEST_F(TEST_SUITE_NAME, test_aot_mem_page_count)
{
struct ret_env tmp_module_env;
const unsigned int num_normal_aot = 9;
const unsigned int num_error_aot = 2;
#if UINTPTR_MAX == UINT64_MAX
const char *aot_file_normal[num_normal_aot] = {
"/mem_page_01.aot", "/mem_page_02.aot", "/mem_page_05.aot",
"/mem_page_07.aot", "/mem_page_08.aot", "/mem_page_09.aot",
"/mem_page_10.aot", "/mem_page_12.aot", "/mem_page_14.aot"
};
const char *aot_file_error[num_error_aot] = { "/mem_page_03.aot",
"/mem_page_16.aot" };
#else
const char *aot_file_normal[num_normal_aot] = {
"/mem_page_01_32.aot", "/mem_page_02_32.aot", "/mem_page_05_32.aot",
"/mem_page_07_32.aot", "/mem_page_08_32.aot", "/mem_page_09_32.aot",
"/mem_page_10_32.aot", "/mem_page_12_32.aot", "/mem_page_14_32.aot"
};
const char *aot_file_error[num_error_aot] = { "/mem_page_03_32.aot",
"/mem_page_16_32.aot" };
#endif
// Test normal wasm file.
for (int i = 0; i < num_normal_aot; i++) {
#if UINTPTR_MAX != UINT64_MAX
// 32 bit do not load this wasm.
if ((0 == strcmp("/mem_page_14_32.aot", aot_file_normal[i]))) {
continue;
}
#endif
tmp_module_env = load_aot((char *)aot_file_normal[i], 16 * 1024);
EXPECT_NE(nullptr, tmp_module_env.aot_module);
EXPECT_NE(nullptr, tmp_module_env.aot_file_buf);
destroy_module_env(tmp_module_env);
}
// Test error wasm file.
for (int i = 0; i < num_error_aot; i++) {
tmp_module_env = load_aot((char *)aot_file_error[i], 16 * 1024);
if (0 != strlen(tmp_module_env.error_buf)) {
/* 3 and 16 are for legit for loader, the init and max page count
* can be 65536, but they can't allocate any host managed heap, so
* instantiating errors */
EXPECT_EQ(0, strncmp("AOT module instantiate failed",
(const char *)tmp_module_env.error_buf, 29));
printf("%s\n", tmp_module_env.error_buf);
}
destroy_module_env(tmp_module_env);
}
}
TEST_F(TEST_SUITE_NAME, test_aot_about_app_heap)
{
struct ret_env tmp_module_env;
// Test case: init_page_count = 65536, app heap size = 1.
#if UINTPTR_MAX == UINT64_MAX
tmp_module_env = load_aot((char *)"/mem_page_03.aot", 1);
#else
tmp_module_env = load_aot((char *)"/mem_page_03_32.aot", 1);
#endif
EXPECT_EQ(
0, strncmp("AOT module", (const char *)tmp_module_env.error_buf, 10));
destroy_module_env(tmp_module_env);
// Test case: init_page_count = 65535, app heap size = 65537.
#if UINTPTR_MAX == UINT64_MAX
tmp_module_env = load_aot((char *)"/mem_page_20.aot", 65537);
#else
tmp_module_env = load_aot((char *)"/mem_page_20_32.aot", 65537);
#endif
EXPECT_EQ(
0, strncmp("AOT module", (const char *)tmp_module_env.error_buf, 10));
destroy_module_env(tmp_module_env);
}
TEST_F(TEST_SUITE_NAME, test_throw_exception_out_of_bounds)
{
struct ret_env tmp_module_env;
WASMFunctionInstanceCommon *func = nullptr;
bool ret = false;
uint32 argv[1] = { 9999 * 64 * 1024 };
const char *exception = nullptr;
/* TODO: use no_hw_bounds version when disable */
#if UINTPTR_MAX == UINT64_MAX
tmp_module_env = load_aot((char *)"/out_of_bounds.aot", 16 * 1024);
#else
tmp_module_env = load_aot((char *)"/out_of_bounds_32.aot", 16 * 1024);
#endif
func = wasm_runtime_lookup_function(tmp_module_env.aot_module_inst, "load");
if (!func) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
ret = wasm_runtime_call_wasm(tmp_module_env.exec_env, func, 1, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
}
exception = wasm_runtime_get_exception(tmp_module_env.aot_module_inst);
EXPECT_EQ(0,
strncmp("Exception: out of bounds memory access", exception, 38));
failed_out_of_bounds:
destroy_module_env(tmp_module_env);
}
TEST_F(TEST_SUITE_NAME, test_mem_grow_out_of_bounds)
{
struct ret_env tmp_module_env;
WASMFunctionInstanceCommon *func_mem_grow = nullptr;
WASMFunctionInstanceCommon *func_mem_size = nullptr;
bool ret = false;
uint32 argv[1] = { 65535 };
const char *exception = nullptr;
/* TODO: use no_hw_bounds version when disable */
// Test case: module((memory 2)), memory.grow 65535, then memory.size.
#if UINTPTR_MAX == UINT64_MAX
tmp_module_env = load_aot((char *)"/mem_grow_out_of_bounds_01.aot", 0);
#else
tmp_module_env = load_aot((char *)"/mem_grow_out_of_bounds_01_32.aot", 0);
#endif
func_mem_grow = wasm_runtime_lookup_function(tmp_module_env.aot_module_inst,
"mem_grow");
if (!func_mem_grow) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
func_mem_size = wasm_runtime_lookup_function(tmp_module_env.aot_module_inst,
"mem_size");
if (!func_mem_size) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_grow, 1, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
EXPECT_EQ(-1, argv[0]);
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_size, 0, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
EXPECT_EQ(2, argv[0]);
// Test case: wasm_runtime_instantiate(heap_size=32768), memory.grow 65534,
// memory.grow 1.
destroy_module_env(tmp_module_env);
#if UINTPTR_MAX == UINT64_MAX
tmp_module_env = load_aot((char *)"/mem_grow_out_of_bounds_02.aot", 32768);
#else
tmp_module_env =
load_aot((char *)"/mem_grow_out_of_bounds_02_32.aot", 32768);
#endif
func_mem_grow = wasm_runtime_lookup_function(tmp_module_env.aot_module_inst,
"mem_grow");
if (!func_mem_grow) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
func_mem_size = wasm_runtime_lookup_function(tmp_module_env.aot_module_inst,
"mem_size");
if (!func_mem_size) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_size, 0, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
EXPECT_EQ(2, argv[0]);
argv[0] = 65534;
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_grow, 1, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
#if UINTPTR_MAX == UINT64_MAX
EXPECT_EQ(2, argv[0]);
#else
EXPECT_EQ(-1, argv[0]);
#endif
argv[0] = 1;
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_grow, 1, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
#if UINTPTR_MAX == UINT64_MAX
EXPECT_EQ(-1, argv[0]);
#else
EXPECT_EQ(2, argv[0]);
#endif
failed_out_of_bounds:
destroy_module_env(tmp_module_env);
}

View File

@ -0,0 +1,16 @@
(module
(type $0 (func (result i32)))
(type $1 (func (param i32) (result i32)))
(memory 2)
(export "mem_grow" (func $6))
(export "mem_size" (func $7))
(func $6 (type $1) (param $0 i32) (result i32)
local.get $0
memory.grow
)
(func $7 (type $0) (result i32)
memory.size
)
)

View File

@ -0,0 +1,16 @@
(module
(type $0 (func (result i32)))
(type $1 (func (param i32) (result i32)))
(memory 1)
(export "mem_grow" (func $6))
(export "mem_size" (func $7))
(func $6 (type $1) (param $0 i32) (result i32)
local.get $0
memory.grow
)
(func $7 (type $0) (result i32)
memory.size
)
)

View File

@ -0,0 +1 @@
(module (memory 0))

View File

@ -0,0 +1 @@
(module (memory 1))

View File

@ -0,0 +1 @@
(module (memory 65536))

View File

@ -0,0 +1 @@
(module (memory 0 0))

View File

@ -0,0 +1 @@
(module (memory 1 1))

View File

@ -0,0 +1 @@
(module (memory 0 1))

View File

@ -0,0 +1 @@
(module (memory 1 256))

View File

@ -0,0 +1 @@
(module (memory 0 65535))

View File

@ -0,0 +1 @@
(module (memory 0 65536))

View File

@ -0,0 +1 @@
(module (memory 65535 65536))

View File

@ -0,0 +1 @@
(module (memory 65536 65536))

View File

@ -0,0 +1 @@
(module (memory 65535))

View File

@ -0,0 +1,10 @@
(module
(type $1 (func (param i32) (result i32)))
(memory $3 0)
(export "load" (func $4))
(func $4 (type $1) (param $0 i32) (result i32)
local.get $0
i32.load
)
)

View File

@ -0,0 +1,2 @@
build 64 bit target: cmake ..
build 32 bit target: cmake .. -DWAMR_BUILD_TARGET=X86_32

View File

@ -0,0 +1,59 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
cmake_minimum_required(VERSION 2.9)
project (test-linear-memory-wasm)
add_definitions (-DRUN_ON_LINUX)
set (WAMR_BUILD_LIBC_WASI 0)
set (WAMR_BUILD_APP_FRAMEWORK 0)
set (WAMR_BUILD_MEMORY_PROFILING 1)
set (WAMR_BUILD_INTERP 1)
set (WAMR_BUILD_AOT 0)
include (../unit_common.cmake)
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE source_all ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
set (UNIT_SOURCE ${source_all})
set (unit_test_sources
${UNIT_SOURCE}
${WAMR_RUNTIME_LIB_SOURCE}
${UNCOMMON_SHARED_SOURCE}
${SRC_LIST}
${PLATFORM_SHARED_SOURCE}
${UTILS_SHARED_SOURCE}
${MEM_ALLOC_SHARED_SOURCE}
${LIB_HOST_AGENT_SOURCE}
${NATIVE_INTERFACE_SOURCE}
${LIBC_BUILTIN_SOURCE}
${IWASM_COMMON_SOURCE}
${IWASM_INTERP_SOURCE}
${IWASM_AOT_SOURCE}
${IWASM_COMPL_SOURCE}
${WASM_APP_LIB_SOURCE_ALL}
)
# Test case: .wasm file with hardware bound check.
add_executable (linear_memory_test_wasm ${unit_test_sources})
target_link_libraries (linear_memory_test_wasm gtest_main)
gtest_discover_tests(linear_memory_test_wasm)
target_compile_definitions(linear_memory_test_wasm PRIVATE WAMR_DISABLE_HW_BOUND_CHECK=0)
add_custom_command(TARGET linear_memory_test_wasm POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${CMAKE_CURRENT_LIST_DIR}/wasm_files/*
${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Copy wasm files to the directory: build/linear-memory-wasm."
)
# Test case: .wasm file with no hardware bound check.
add_executable (linear_memory_test_wasm_no_hw_bound ${unit_test_sources})
target_link_libraries (linear_memory_test_wasm_no_hw_bound gtest_main)
gtest_discover_tests(linear_memory_test_wasm_no_hw_bound)
target_compile_definitions(linear_memory_test_wasm_no_hw_bound PRIVATE WAMR_DISABLE_HW_BOUND_CHECK=1)

View File

@ -0,0 +1,327 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "test_helper.h"
#include "gtest/gtest.h"
#include "bh_read_file.h"
#include "wasm_runtime_common.h"
static std::string CWD;
static std::string
get_binary_path()
{
char cwd[1024];
memset(cwd, 0, 1024);
if (readlink("/proc/self/exe", cwd, 1024) <= 0) {
}
char *path_end = strrchr(cwd, '/');
if (path_end != NULL) {
*path_end = '\0';
}
return std::string(cwd);
}
#if WASM_DISABLE_HW_BOUND_CHECK != 0
#define TEST_SUITE_NAME linear_memory_test_suite_wasm_no_hw_bound
#else
#define TEST_SUITE_NAME linear_memory_test_suite_wasm
#endif
class TEST_SUITE_NAME : public testing::Test
{
protected:
// You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the varaibles.
// Otherwise, this can be skipped.
virtual void SetUp() {}
static void SetUpTestCase() { CWD = get_binary_path(); }
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
virtual void TearDown() {}
WAMRRuntimeRAII<512 * 1024> runtime;
};
struct ret_env {
wasm_exec_env_t exec_env;
wasm_module_t wasm_module;
wasm_module_inst_t wasm_module_inst;
unsigned char *wasm_file_buf;
char error_buf[128];
};
struct ret_env
load_wasm(char *wasm_file_tested, unsigned int app_heap_size)
{
std::string wasm_mem_page = wasm_file_tested;
const char *wasm_file = strdup((CWD + wasm_mem_page).c_str());
wasm_module_inst_t wasm_module_inst = nullptr;
wasm_module_t wasm_module = nullptr;
wasm_exec_env_t exec_env = nullptr;
unsigned char *wasm_file_buf = nullptr;
unsigned int wasm_file_size = 0;
unsigned int stack_size = 16 * 1024, heap_size = app_heap_size;
char error_buf[128] = { 0 };
struct ret_env ret_module_env;
memset(ret_module_env.error_buf, 0, 128);
wasm_file_buf =
(unsigned char *)bh_read_file_to_buffer(wasm_file, &wasm_file_size);
if (!wasm_file_buf) {
goto fail;
}
wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size, error_buf,
sizeof(error_buf));
if (!wasm_module) {
memcpy(ret_module_env.error_buf, error_buf, 128);
goto fail;
}
wasm_module_inst = wasm_runtime_instantiate(
wasm_module, stack_size, heap_size, error_buf, sizeof(error_buf));
if (!wasm_module_inst) {
memcpy(ret_module_env.error_buf, error_buf, 128);
goto fail;
}
exec_env = wasm_runtime_create_exec_env(wasm_module_inst, stack_size);
fail:
ret_module_env.exec_env = exec_env;
ret_module_env.wasm_module = wasm_module;
ret_module_env.wasm_module_inst = wasm_module_inst;
ret_module_env.wasm_file_buf = wasm_file_buf;
return ret_module_env;
}
void
destroy_module_env(struct ret_env module_env)
{
if (module_env.exec_env) {
wasm_runtime_destroy_exec_env(module_env.exec_env);
}
if (module_env.wasm_module_inst) {
wasm_runtime_deinstantiate(module_env.wasm_module_inst);
}
if (module_env.wasm_module) {
wasm_runtime_unload(module_env.wasm_module);
}
if (module_env.wasm_file_buf) {
wasm_runtime_free(module_env.wasm_file_buf);
}
}
TEST_F(TEST_SUITE_NAME, test_wasm_mem_page_count)
{
struct ret_env tmp_module_env;
unsigned int num_normal_wasm = 9;
unsigned int num_error_wasm = 10;
const char *wasm_file_normal[num_normal_wasm] = {
"/wasm_mem_page_01.wasm", "/wasm_mem_page_02.wasm",
"/wasm_mem_page_05.wasm", "/wasm_mem_page_07.wasm",
"/wasm_mem_page_08.wasm", "/wasm_mem_page_09.wasm",
"/wasm_mem_page_10.wasm", "/wasm_mem_page_12.wasm",
"/wasm_mem_page_14.wasm"
};
const char *wasm_file_error[num_error_wasm] = {
"/wasm_mem_page_03.wasm", "/wasm_mem_page_04.wasm",
"/wasm_mem_page_06.wasm", "/wasm_mem_page_11.wasm",
"/wasm_mem_page_13.wasm", "/wasm_mem_page_15.wasm",
"/wasm_mem_page_16.wasm", "/wasm_mem_page_17.wasm",
"/wasm_mem_page_18.wasm", "/wasm_mem_page_19.wasm"
};
// Test normal wasm file.
for (int i = 0; i < num_normal_wasm; i++) {
#if UINTPTR_MAX != UINT64_MAX
// 32 bit do not load this wasm.
if ((0 == strcmp("/wasm_mem_page_12.wasm", wasm_file_normal[i]))
|| (0 == strcmp("/wasm_mem_page_14.wasm", wasm_file_normal[i]))) {
continue;
}
#endif
tmp_module_env = load_wasm((char *)wasm_file_normal[i], 16 * 1024);
EXPECT_NE(nullptr, tmp_module_env.wasm_module);
EXPECT_NE(nullptr, tmp_module_env.wasm_file_buf);
#if WASM_DISABLE_HW_BOUND_CHECK == 0
EXPECT_NE(nullptr, tmp_module_env.exec_env);
EXPECT_NE(nullptr, tmp_module_env.wasm_module_inst);
#endif
destroy_module_env(tmp_module_env);
}
// Test error wasm file.
for (int i = 0; i < num_error_wasm; i++) {
tmp_module_env = load_wasm((char *)wasm_file_error[i], 16 * 1024);
if (0 != strlen(tmp_module_env.error_buf)) {
EXPECT_EQ(0, strncmp("WASM module",
(const char *)tmp_module_env.error_buf, 11));
}
destroy_module_env(tmp_module_env);
}
}
TEST_F(TEST_SUITE_NAME, test_wasm_about_app_heap)
{
struct ret_env tmp_module_env;
// Test case: init_page_count = 65536, app heap size = 1.
tmp_module_env = load_wasm((char *)"/wasm_mem_page_03.wasm", 1);
EXPECT_EQ(0, strncmp("WASM module instantiate failed",
(const char *)tmp_module_env.error_buf, 30));
destroy_module_env(tmp_module_env);
// Test case: init_page_count = 65535, app heap size = 65537.
tmp_module_env = load_wasm((char *)"/wasm_mem_page_20.wasm", 65537);
EXPECT_EQ(0, strncmp("WASM module instantiate failed",
(const char *)tmp_module_env.error_buf, 30));
destroy_module_env(tmp_module_env);
}
TEST_F(TEST_SUITE_NAME, test_throw_exception_out_of_bounds)
{
struct ret_env tmp_module_env;
WASMFunctionInstanceCommon *func = nullptr;
bool ret = false;
uint32 argv[1] = { 9999 * 64 * 1024 };
const char *exception = nullptr;
tmp_module_env = load_wasm((char *)"/out_of_bounds.wasm", 16 * 1024);
func =
wasm_runtime_lookup_function(tmp_module_env.wasm_module_inst, "load");
if (!func) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
ret = wasm_runtime_call_wasm(tmp_module_env.exec_env, func, 1, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
}
exception = wasm_runtime_get_exception(tmp_module_env.wasm_module_inst);
EXPECT_EQ(0,
strncmp("Exception: out of bounds memory access", exception, 38));
failed_out_of_bounds:
destroy_module_env(tmp_module_env);
}
TEST_F(TEST_SUITE_NAME, test_mem_grow_out_of_bounds)
{
struct ret_env tmp_module_env;
WASMFunctionInstanceCommon *func_mem_grow = nullptr;
WASMFunctionInstanceCommon *func_mem_size = nullptr;
bool ret = false;
// after refactor, the 65536 pages to one 4G page optimization is removed
// the size can be 65536 now, so use 2 + 65535 to test OOB
uint32 argv[1] = { 65535 };
const char *exception = nullptr;
// Test case: module((memory 2)), memory.grow 65535, then memory.size.
tmp_module_env = load_wasm((char *)"/mem_grow_out_of_bounds_01.wasm", 0);
func_mem_grow = wasm_runtime_lookup_function(
tmp_module_env.wasm_module_inst, "mem_grow");
if (!func_mem_grow) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
func_mem_size = wasm_runtime_lookup_function(
tmp_module_env.wasm_module_inst, "mem_size");
if (!func_mem_size) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_grow, 1, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
EXPECT_EQ(-1, argv[0]);
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_size, 0, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
EXPECT_EQ(2, argv[0]);
// Test case: wasm_runtime_instantiate(heap_size=32768), memory.grow 65535,
// memory.grow 1.
destroy_module_env(tmp_module_env);
tmp_module_env =
load_wasm((char *)"/mem_grow_out_of_bounds_02.wasm", 32768);
func_mem_grow = wasm_runtime_lookup_function(
tmp_module_env.wasm_module_inst, "mem_grow");
if (!func_mem_grow) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
func_mem_size = wasm_runtime_lookup_function(
tmp_module_env.wasm_module_inst, "mem_size");
if (!func_mem_size) {
printf("\nFailed to wasm_runtime_lookup_function!\n");
goto failed_out_of_bounds;
}
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_size, 0, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
EXPECT_EQ(2, argv[0]);
argv[0] = 65535;
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_grow, 1, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
EXPECT_NE(2, argv[0]);
argv[0] = 1;
ret =
wasm_runtime_call_wasm(tmp_module_env.exec_env, func_mem_grow, 1, argv);
if (!ret) {
printf("\nFailed to wasm_runtime_call_wasm!\n");
goto failed_out_of_bounds;
}
EXPECT_EQ(2, argv[0]);
failed_out_of_bounds:
destroy_module_env(tmp_module_env);
}

View File

@ -0,0 +1,16 @@
(module
(type $0 (func (result i32)))
(type $1 (func (param i32) (result i32)))
(memory 2)
(export "mem_grow" (func $6))
(export "mem_size" (func $7))
(func $6 (type $1) (param $0 i32) (result i32)
local.get $0
memory.grow
)
(func $7 (type $0) (result i32)
memory.size
)
)

View File

@ -0,0 +1,16 @@
(module
(type $0 (func (result i32)))
(type $1 (func (param i32) (result i32)))
(memory 1)
(export "mem_grow" (func $6))
(export "mem_size" (func $7))
(func $6 (type $1) (param $0 i32) (result i32)
local.get $0
memory.grow
)
(func $7 (type $0) (result i32)
memory.size
)
)

View File

@ -0,0 +1 @@
(module (memory 0))

View File

@ -0,0 +1 @@
(module (memory 1))

View File

@ -0,0 +1 @@
(module (memory 65536))

View File

@ -0,0 +1 @@
(module (memory 65537)) ;; Should report an error.

View File

@ -0,0 +1 @@
(module (memory 0 0))

View File

@ -0,0 +1 @@
(module (memory 1 0)) ;; Should report an error.

View File

@ -0,0 +1 @@
(module (memory 1 1))

View File

@ -0,0 +1 @@
(module (memory 0 1))

View File

@ -0,0 +1 @@
(module (memory 1 256))

View File

@ -0,0 +1 @@
(module (memory 0 65535))

View File

@ -0,0 +1 @@
(module (memory 65535 0)) ;; Should report an error.

View File

@ -0,0 +1 @@
(module (memory 0 65536))

View File

@ -0,0 +1 @@
(module (memory 65536 0)) ;; Should report an error.

View File

@ -0,0 +1 @@
(module (memory 65535 65536))

View File

@ -0,0 +1 @@
(module (memory 65536 65535)) ;; Should report an error.

View File

@ -0,0 +1 @@
(module (memory 65536 65536))

View File

@ -0,0 +1 @@
(module (memory 65537 65537)) ;; Should report an error.

Some files were not shown because too many files have changed in this diff Show More