Skip to content

Commit

Permalink
Core run 測試
Browse files Browse the repository at this point in the history
  • Loading branch information
LuisHsu committed May 17, 2019
1 parent 5952adb commit 086f02b
Show file tree
Hide file tree
Showing 8 changed files with 182 additions and 37 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 3.5)
project(WasmVM)
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR})
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11")
set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS_DEBUG} -std=c++11")
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 11)

# pthread
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
Expand Down
58 changes: 45 additions & 13 deletions src/lib/core/Core.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <core/Core.h>

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <Opcodes.h>
Expand All @@ -8,6 +9,7 @@
#include <dataTypes/Value.h>
#include <dataTypes/Label.h>
#include <dataTypes/Frame.h>
#include <dataTypes/Entry.h>
#include <instance/FuncInst.h>
#include <instance/InstrInst.h>
#include <instance/MemInst.h>
Expand Down Expand Up @@ -590,18 +592,39 @@ static int run_numeric_instr(Stack* stack, NumericInstrInst* instr, uint8_t opco
static void* exec_Core(void* corePtr)
{
Core* core = (Core*) corePtr;
core->status = Core_Running;
int* result = (int*) malloc(sizeof(int));
*result = 0;
while (core->status == Core_Running && *result == 0 && core->stack->curFrame) {
FuncInst* func = (FuncInst*) core->store->funcs->at(core->store->funcs, core->stack->curLabel->funcAddr);
if(core->stack->curLabel->instrIndex >= func->code->size) {
// No end in the function, manual do end
Label* label = NULL;
if(pop_Label(core->stack, &label)) {
core->status = Core_Stop;
*result = -1;
return result;
#ifndef NDEBUG
for(stackNode* cur = core->stack->entries->head; cur != NULL; cur = cur->next) {
Entry* entry = (Entry*)cur->data;
if(entry->entryType == Entry_Value) {
Value* retValue = (Value*)entry;
switch (retValue->type) {
case Value_i32:
printf("[%d] i32 %d\n", core->stack->curLabel->funcAddr, retValue->value.i32);
break;
case Value_i64:
printf("[%d] i64 %lld\n", core->stack->curLabel->funcAddr, retValue->value.i64);
break;
case Value_f32:
printf("[%d] f32 %f\n", core->stack->curLabel->funcAddr, retValue->value.f32);
break;
case Value_f64:
printf("[%d] f64 %lf\n", core->stack->curLabel->funcAddr, retValue->value.f64);
break;
default:
break;
}
} else {
break;
}
}
#endif
stack* valStack = new_stack(NULL);
for(uint32_t i = 0; i < func->type->results->length; ++i) {
Value* retValue = NULL;
Expand All @@ -612,6 +635,14 @@ static void* exec_Core(void* corePtr)
}
valStack->push(valStack, retValue);
}

Label* label = NULL;
if(pop_Label(core->stack, &label)) {
core->status = Core_Stop;
*result = -1;
return result;
}

Frame* frame = NULL;
if(pop_Frame(core->stack, &frame)) {
core->status = Core_Stop;
Expand All @@ -633,6 +664,7 @@ static void* exec_Core(void* corePtr)
free_stack(valStack);
free_Label(label);
free_Frame(frame);
continue;
}
InstrInst* instr = (InstrInst*)func->code->at(func->code, core->stack->curLabel->instrIndex);
switch (instr->opcode) {
Expand Down Expand Up @@ -858,7 +890,7 @@ static int run_Core(Core* core)
}
}
push_Frame(core->stack, frame);
Label* label = new_Label(core->startFuncAddr, 0, (startFunc->code->size > 0) ? startFunc->code->size - 1 : 0);
Label* label = new_Label(core->startFuncAddr, 0, startFunc->code->size);
label->resultTypes = startFunc->type->results;
push_Label(core->stack, label);
// Run in thread
Expand All @@ -870,27 +902,26 @@ static int stop_core(Core* core)
{
core->status = Core_Stop;
int* resultPtr = NULL;
pthread_join(core->thread, &resultPtr);
pthread_join(core->thread, (void**)&resultPtr);
int result = (resultPtr) ? *resultPtr : 0;
free(resultPtr);
free_Stack(core->stack);
core->stack = NULL;
int result = *resultPtr;
free(resultPtr);
return result;
}

static int pause_core(Core* core)
{
core->status = Core_Paused;
int* resultPtr = NULL;
pthread_join(core->thread, &resultPtr);
pthread_join(core->thread, (void**)&resultPtr);
int result = *resultPtr;
free(resultPtr);
return result;
}

static int resume_core(Core* core)
{
core->status = Core_Running;
return pthread_create(&core->thread, NULL, exec_Core, (void*)core);
}

Expand All @@ -911,7 +942,8 @@ Core* new_Core(Store *store, ModuleInst* module, uint32_t startFuncAddr)

void free_Core(Core* core)
{
core->stop(core);
free_Stack(core->stack);
if(core->status != Core_Stop) {
core->stop(core);
}
free(core);
}
37 changes: 22 additions & 15 deletions src/lib/core/Stack.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ Stack* new_Stack()
}
void free_Stack(Stack* thisStack)
{
free_stack(thisStack->entries);
if(thisStack) {
free_stack(thisStack->entries);
}
free(thisStack);
}
void push_Label(Stack* thisStack, Label* label)
Expand Down Expand Up @@ -61,12 +63,15 @@ int pop_Label(Stack* thisStack, Label** label)
}
// Save results
stack* results = new_stack(NULL);
for(uint32_t i = 0; i < thisStack->curLabel->resultTypes->length; ++i) {
Value* result = NULL;
if(pop_Value(thisStack, &result)) {
return -3;
vector* resultTypes = thisStack->curLabel->resultTypes;
if(resultTypes) {
for(uint32_t i = 0; i < thisStack->curLabel->resultTypes->length; ++i) {
Value* result = NULL;
if(pop_Value(thisStack, &result)) {
return -3;
}
results->push(results, result);
}
results->push(results, result);
}
// Pop label
for(stackNode* cur = thisStack->entries->head; cur != NULL; cur = thisStack->entries->head) {
Expand All @@ -84,17 +89,19 @@ int pop_Label(Stack* thisStack, Label** label)
}
}
// Restore results
vector* resultTypes = (*label)->resultTypes;
for(uint32_t i = 0; i < resultTypes->length; ++i) {
ValueType* type = (ValueType*)resultTypes->at(resultTypes, i);
Value* result = NULL;
results->pop(results, (void**)&result);
if(result->type != *type) {
free(result);
return -4;
if(resultTypes) {
for(uint32_t i = 0; i < resultTypes->length; ++i) {
ValueType* type = (ValueType*)resultTypes->at(resultTypes, i);
Value* result = NULL;
results->pop(results, (void**)&result);
if(result->type != *type) {
free(result);
return -4;
}
push_Value(thisStack, result);
}
push_Value(thisStack, result);
}
free_stack(results);
// Update curlabel
for(stackNode* cur = thisStack->entries->head; cur != NULL; cur = cur->next) {
Entry* entry = (Entry*)cur->data;
Expand Down
1 change: 1 addition & 0 deletions src/lib/dataTypes/Label.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Label* new_Label(uint32_t funcAddr, uint32_t instrIndex, uint32_t contInstr)
label->funcAddr = funcAddr;
label->instrIndex = instrIndex;
label->contInstr = contInstr;
label->resultTypes = NULL;
return label;
}
void free_Label(Label *label)
Expand Down
1 change: 1 addition & 0 deletions test/unittests/lib/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@ endmacro(add_core_unittest unittest)

add_core_unittest(stack_unittest)
add_core_unittest(store_unittest)
add_core_unittest(core_unittest)

add_subdirectory(runtime)
108 changes: 108 additions & 0 deletions test/unittests/lib/core/core_unittest.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#include <skypat/skypat.h>

#define _Bool bool
extern "C" {
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <Opcodes.h>
#include <core/Core.h>
#include <core/Store.h>
#include <instance/ModuleInst.h>
#include <instance/FuncInst.h>
#include <instance/NumericInstrInst.h>
#include <dataTypes/Value.h>
#include <dataTypes/FuncType.h>
}
#undef _Bool

SKYPAT_F(Core, create_delete)
{
// Prepare
Store* store = new_Store();
char* moduleName = (char*) malloc(sizeof(char) * 5);
strcpy(moduleName, "test");
ModuleInst* module = new_ModuleInst(moduleName);
FuncType* funcType = new_FuncType();
module->types->push_back(module->types, funcType);
uint32_t funcAddr = 0;
module->funcaddrs->push_back(module->funcaddrs, &funcAddr);
FuncInst* func = new_FuncInst(module, funcType);
NumericInstrInst* instr1 = new_NumericInstrInst();
instr1->parent.opcode = Op_i32_const;
instr1->constant.parent.entryType = Entry_Value;
instr1->constant.type = Value_i32;
instr1->constant.value.i32 = 5;
func->code->push_back(func->code, instr1);
ValueType localType1 = Value_i32;
func->locals->push_back(func->locals, &localType1);
store->funcs->push_back(store->funcs, func);

// Check
Core* core = new_Core(store, module, 0);
EXPECT_EQ(core->stack, NULL);
EXPECT_NE(core->store, NULL);
EXPECT_EQ(core->startFuncAddr, 0);
EXPECT_EQ(core->status, Core_Stop);
EXPECT_EQ(core->module, module);

// Clean
free_Core(core);
free_Store(store);
free_ModuleInst(module);
}

SKYPAT_F(Core, run_valid)
{
// Prepare
Store* store = new_Store();
char* moduleName = (char*) malloc(sizeof(char) * 5);
strcpy(moduleName, "test");
ModuleInst* module = new_ModuleInst(moduleName);
FuncType* funcType = new_FuncType();
module->types->push_back(module->types, funcType);
uint32_t funcAddr = 0;
module->funcaddrs->push_back(module->funcaddrs, &funcAddr);
FuncInst* func = new_FuncInst(module, funcType);
NumericInstrInst* instr1 = new_NumericInstrInst();
instr1->parent.opcode = Op_i32_const;
instr1->constant.parent.entryType = Entry_Value;
instr1->constant.type = Value_i32;
instr1->constant.value.i32 = 5;
func->code->push_back(func->code, instr1);
NumericInstrInst* instr2 = new_NumericInstrInst();
instr2->parent.opcode = Op_i32_const;
instr2->constant.parent.entryType = Entry_Value;
instr2->constant.type = Value_i32;
instr2->constant.value.i32 = 7;
func->code->push_back(func->code, instr2);
NumericInstrInst* instr3 = new_NumericInstrInst();
instr3->parent.opcode = Op_i32_add;
func->code->push_back(func->code, instr3);
ValueType localType1 = Value_i32;
func->locals->push_back(func->locals, &localType1);
store->funcs->push_back(store->funcs, func);

// Check
char buf[100];
fflush(stdout);
int oldOut = dup(STDOUT_FILENO);
memset(buf, 0, sizeof(char) * 100);
freopen("/dev/null", "a", stdout);
setvbuf(stdout, buf, _IOFBF, 100);

Core* core = new_Core(store, module, 0);
EXPECT_EQ(core->run(core), 0);
EXPECT_EQ(core->stop(core), 0);
EXPECT_FALSE(strcmp(buf, "[0] i32 12\n"));

freopen("/dev/null", "a", stdout);
dup2(oldOut, STDOUT_FILENO);
setvbuf(stdout, NULL, _IONBF, 100);

// Clean
free_Core(core);
free_Store(store);
free_ModuleInst(module);
}
6 changes: 1 addition & 5 deletions test/unittests/lib/core/runtime/else_unittest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ SKYPAT_F(Runtime_control_if, regular)
Stack* stack = new_Stack();

// Label: {Entry, funcAddr, instrIndex, contInstr}
Label* currentLabel = (Label*)malloc(sizeof(Label));
currentLabel->parent.entryType = Entry_Label;
currentLabel->funcAddr = 0;
currentLabel->instrIndex = 1;
currentLabel->contInstr = 2;
Label* currentLabel = new_Label(0, 4, 4);

ControlInstrInst* currentControl = new_ControlInstrInst();
currentControl->elseAddr = 3;
Expand Down
4 changes: 2 additions & 2 deletions test/unittests/lib/core/runtime/if_unittest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ SKYPAT_F(Runtime_control_if, regular)
runtime_if(stack, currentControl);
pop_Label(stack, &result);
// Expect label's instrIndex to be ControlInstrInst's elseAddr.
EXPECT_EQ(result->instrIndex, 3);
EXPECT_EQ(result->instrIndex, 4);
// curLabel should be updated to the latest label's function address.
EXPECT_EQ(result->funcAddr, 0);
EXPECT_EQ(result->contInstr, 4);
Expand All @@ -41,7 +41,7 @@ SKYPAT_F(Runtime_control_if, regular)
push_Value(stack, new_i32Value(1));
runtime_if(stack, currentControl);
pop_Label(stack, &result);
EXPECT_EQ(result->instrIndex, 1);
EXPECT_EQ(result->instrIndex, 2);
EXPECT_EQ(result->funcAddr, 0);
EXPECT_EQ(result->contInstr, 4);
free(result);
Expand Down

0 comments on commit 086f02b

Please sign in to comment.