suppot REPL/NORMAL MODE for unused stack val

This commit is contained in:
lyon 2023-08-29 13:56:48 +08:00
parent b1d7161c4d
commit 1e6337bc71
9 changed files with 177 additions and 97 deletions

View File

@ -12,7 +12,7 @@
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
"args": [
// "--gtest_filter=vm.keyword_2"
"--gtest_filter=builtin.eq"
"--gtest_filter=builtin.repl_mode"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",

View File

@ -4,7 +4,7 @@ import pika_lua, pika_cjson, cjson_test, json
import GTestTask, TempDevTest
import cb_test
import configparser, network, math, struct
import test_module1, test_cmodule, test_module4, import_test, test
import test_module1, test_cmodule, test_module4, import_test
import hashlib, hmac, aes, base64, time, os, zlib
import _thread, weakref, eventloop
import this

View File

@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
#include "dataMemory.h"
#include "PikaVM.h"
char log_buff[LOG_BUFF_MAX][LOG_SIZE] = {0};
uint32_t log_index = 0;
@ -43,3 +44,10 @@ void __pks_hook_instruct(void) {
g_hook_cnt++;
g_hook_func();
}
volatile pika_bool g_always_repl_mode = pika_true;
PIKA_WEAK void pika_hook_unused_stack_arg(VMState* vm, Arg* arg) {
if (vm->run_state->in_repl || g_always_repl_mode) {
arg_print(arg, pika_true, "\r\n");
}
}

View File

@ -54,6 +54,16 @@ static char _f_getchar(void) {
pika_assert(0);
return -1;
}
static char _fmem_getchar(void) {
char c = 0;
size_t n = fread(&c, 1, 1, (FILE*)_f_getchar_fp);
if (n > 0) {
return c;
}
return 0;
}
void pikaScriptShell_withGetchar(PikaObj* self, sh_getchar getchar_fn);
}
@ -93,6 +103,28 @@ void pikaScriptShell_withGetchar(PikaObj* self, sh_getchar getchar_fn);
EXPECT_EQ(pikaMemNow(), 0); \
}
#define TEST_RUN_LINES_REPL(_test_suite_, _test_name_, _lines_) \
TEST(_test_suite_, _test_name_) { \
/* init */ \
extern volatile pika_bool g_always_repl_mode; \
g_always_repl_mode = pika_false; \
g_PikaMemInfo.heapUsedMax = 0; \
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); \
extern unsigned char pikaModules_py_a[]; \
obj_linkLibrary(pikaMain, pikaModules_py_a); \
/* run */ \
__platform_printf("BEGIN\r\n"); \
_f_getchar_fp = fmemopen((void*)_lines_, strlen(_lines_), "rb"); \
pikaScriptShell_withGetchar(pikaMain, _fmem_getchar); \
fclose((FILE*)_f_getchar_fp); \
/* collect */ \
/* assert */ \
/* deinit */ \
obj_deinit(pikaMain); \
EXPECT_EQ(pikaMemNow(), 0); \
g_always_repl_mode = pika_true; \
}
#define TEST_RUN_SINGLE_FILE_ASSERT(_test_suite_, _test_name_, _file_name_, \
__expt__) \
TEST(_test_suite_, _test_name_) { \
@ -193,6 +225,19 @@ void pikaScriptShell_withGetchar(PikaObj* self, sh_getchar getchar_fn);
EXPECT_EQ(pikaMemNow(), 0); \
}
#define TEST_RUN_LINES_EXCEPT_OUTPUT2(_test_suite_, _test_name_, _lines_, \
_except_output1_, _except_output2_) \
TEST(_test_suite_, _test_name_) { \
PikaObj* self = newRootObj("root", New_PikaMain); \
extern unsigned char pikaModules_py_a[]; \
obj_linkLibrary(self, pikaModules_py_a); \
obj_run(self, (_lines_)); /* collect */ /* assert */ \
EXPECT_STREQ(log_buff[0], (_except_output1_)); \
EXPECT_STREQ(log_buff[1], (_except_output2_)); \
obj_deinit(self); \
EXPECT_EQ(pikaMemNow(), 0); \
}
#if USE_GOOGLE_TEST
#include "gtest/gtest.h"
#define TEST_START

View File

@ -2023,7 +2023,7 @@ static enum shellCTRL __obj_shellLineHandler_REPL(PikaObj* self,
return SHELL_CTRL_EXIT;
}
/* run single line */
obj_run(self, input_line);
_pikaVM_runPyLines(self, input_line, pika_true);
return SHELL_CTRL_CONTINUE;
}

View File

@ -1160,7 +1160,8 @@ Arg* obj_runMethodArg(PikaObj* self,
PikaObj* method_args_obj,
Arg* method_arg) {
RunState run_state = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
.try_result = TRY_RESULT_NONE,
.in_repl = pika_false};
return obj_runMethodArgWithState(self, method_args_obj, method_arg,
&run_state);
}
@ -1891,7 +1892,8 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
PikaObj* oBuiltin = NULL;
arg_newReg(arg_reg1, 32);
RunState tSubRunState = {.try_state = vm->run_state->try_state,
.try_result = TRY_RESULT_NONE};
.try_result = TRY_RESULT_NONE,
.in_repl = pika_false};
pika_assert(NULL != vm->run_state);
if (NULL != sRunPath) {
@ -3652,7 +3654,9 @@ static ByteCodeFrame* _cache_bcf_fn_bc(PikaObj* self, uint8_t* bytecode) {
return _cache_bytecodeframe(self);
}
static VMParameters* _pikaVM_runPyLines(PikaObj* self, char* py_lines) {
VMParameters* _pikaVM_runPyLines(PikaObj* self,
char* py_lines,
pika_bool in_repl) {
VMParameters* globals = NULL;
ByteCodeFrame bytecode_frame_stack = {0};
ByteCodeFrame* bytecode_frame_p = NULL;
@ -3678,7 +3682,7 @@ static VMParameters* _pikaVM_runPyLines(PikaObj* self, char* py_lines) {
goto __exit;
}
/* run byteCode */
globals = pikaVM_runByteCodeFrame(self, bytecode_frame_p);
globals = _pikaVM_runByteCodeFrame(self, bytecode_frame_p, in_repl);
goto __exit;
__exit:
if (!is_use_heap_bytecode) {
@ -3758,12 +3762,13 @@ VMParameters* pikaVM_runSingleFile(PikaObj* self, char* filename) {
}
VMParameters* pikaVM_run(PikaObj* self, char* py_lines) {
return _pikaVM_runPyLines(self, py_lines);
return _pikaVM_runPyLines(self, py_lines, pika_false);
}
VMParameters* pikaVM_runByteCode(PikaObj* self, const uint8_t* bytecode) {
RunState run_state = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
.try_result = TRY_RESULT_NONE,
.in_repl = pika_false};
return _do_pikaVM_runByteCode(self, self, self, (uint8_t*)bytecode,
&run_state, pika_true);
}
@ -3805,7 +3810,8 @@ Arg* _do_pikaVM_runByteCodeReturn(PikaObj* self,
VMParameters* pikaVM_runByteCodeInconstant(PikaObj* self, uint8_t* bytecode) {
RunState run_state = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
.try_result = TRY_RESULT_NONE,
.in_repl = pika_false};
return _do_pikaVM_runByteCode(self, self, self, (uint8_t*)bytecode,
&run_state, pika_false);
}
@ -4151,6 +4157,12 @@ void byteCodeFrame_print(ByteCodeFrame* self) {
self->const_pool.size + self->instruct_array.size);
}
PIKA_WEAK void pika_hook_unused_stack_arg(VMState* vm, Arg* arg) {
if (vm->run_state->in_repl) {
arg_print(arg, pika_true, "\r\n");
}
}
void VMState_solveUnusedStack(VMState* vm) {
uint8_t top = stack_getTop(&(vm->stack));
for (int i = 0; i < top; i++) {
@ -4164,7 +4176,7 @@ void VMState_solveUnusedStack(VMState* vm) {
arg_deinit(arg);
continue;
}
arg_print(arg, pika_true, "\r\n");
pika_hook_unused_stack_arg(vm, arg);
arg_deinit(arg);
}
}
@ -4273,14 +4285,23 @@ static VMParameters* _pikaVM_runByteCodeFrameWithState(
return result;
}
VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame) {
RunState run_state = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
VMParameters* _pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame,
pika_bool in_repl) {
RunState run_state = {
.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE,
.in_repl = in_repl,
};
return _pikaVM_runByteCodeFrameWithState(self, self, self, byteCode_frame,
0, &run_state);
}
VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame) {
return _pikaVM_runByteCodeFrame(self, byteCode_frame, pika_false);
}
void constPool_printAsArray(ConstPool* self) {
uint8_t* const_size_str = (uint8_t*)&(self->size);
pika_platform_printf("0x%02x, ", *(const_size_str));

View File

@ -69,6 +69,7 @@ typedef struct RunState RunState;
struct RunState {
TRY_STATE try_state;
TRY_RESULT try_result;
pika_bool in_repl;
};
typedef struct VMState VMState;
@ -186,6 +187,9 @@ struct VMInstructionSet {
VMParameters* pikaVM_run(PikaObj* self, char* pyLine);
VMParameters* pikaVM_runAsm(PikaObj* self, char* pikaAsm);
VMParameters* _pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame,
pika_bool in_repl);
VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame);
@ -386,6 +390,10 @@ typedef struct {
PikaObj* lreg[PIKA_REGIST_SIZE];
} VMLocals;
VMParameters* _pikaVM_runPyLines(PikaObj* self,
char* py_lines,
pika_bool in_repl);
#endif
#ifdef __cplusplus

View File

@ -2,4 +2,4 @@
#define PIKA_VERSION_MINOR 12
#define PIKA_VERSION_MICRO 5
#define PIKA_EDIT_TIME "2023/08/17 23:33:21"
#define PIKA_EDIT_TIME "2023/08/29 13:56:27"

View File

@ -7,29 +7,31 @@ extern "C" {
#include "PikaPlatform.h"
#define __PIKA_ADAPTER_RTT_H__
typedef signed long ssize_t; /* Used for a count of bytes or an error indication. */
typedef int8_t rt_int8_t; /**< 8bit integer type */
typedef int16_t rt_int16_t; /**< 16bit integer type */
typedef int32_t rt_int32_t; /**< 32bit integer type */
typedef uint8_t rt_uint8_t; /**< 8bit unsigned integer type */
typedef uint16_t rt_uint16_t; /**< 16bit unsigned integer type */
typedef uint32_t rt_uint32_t; /**< 32bit unsigned integer type */
typedef int64_t rt_int64_t; /**< 64bit integer type */
typedef uint64_t rt_uint64_t; /**< 64bit unsigned integer type */
typedef size_t rt_size_t; /**< Type for size number */
typedef ssize_t rt_ssize_t; /**< Used for a count of bytes or an error indication */
typedef signed long
ssize_t; /* Used for a count of bytes or an error indication. */
typedef int8_t rt_int8_t; /**< 8bit integer type */
typedef int16_t rt_int16_t; /**< 16bit integer type */
typedef int32_t rt_int32_t; /**< 32bit integer type */
typedef uint8_t rt_uint8_t; /**< 8bit unsigned integer type */
typedef uint16_t rt_uint16_t; /**< 16bit unsigned integer type */
typedef uint32_t rt_uint32_t; /**< 32bit unsigned integer type */
typedef int64_t rt_int64_t; /**< 64bit integer type */
typedef uint64_t rt_uint64_t; /**< 64bit unsigned integer type */
typedef size_t rt_size_t; /**< Type for size number */
typedef ssize_t
rt_ssize_t; /**< Used for a count of bytes or an error indication */
/* RT-Thread basic data type definitions */
typedef int rt_bool_t; /**< boolean type */
typedef signed long rt_base_t; /**< Nbit CPU related date type */
typedef unsigned long rt_ubase_t; /**< Nbit unsigned CPU related data type */
typedef rt_base_t rt_err_t; /**< Type for error number */
typedef rt_uint32_t rt_time_t; /**< Type for time stamp */
typedef rt_uint32_t rt_tick_t; /**< Type for tick count */
typedef rt_base_t rt_flag_t; /**< Type for flags */
typedef rt_ubase_t rt_dev_t; /**< Type for device */
typedef rt_base_t rt_off_t; /**< Type for offset */
#define rt_inline static __inline
typedef int rt_bool_t; /**< boolean type */
typedef signed long rt_base_t; /**< Nbit CPU related date type */
typedef unsigned long rt_ubase_t; /**< Nbit unsigned CPU related data type */
typedef rt_base_t rt_err_t; /**< Type for error number */
typedef rt_uint32_t rt_time_t; /**< Type for time stamp */
typedef rt_uint32_t rt_tick_t; /**< Type for tick count */
typedef rt_base_t rt_flag_t; /**< Type for flags */
typedef rt_ubase_t rt_dev_t; /**< Type for device */
typedef rt_base_t rt_off_t; /**< Type for offset */
#define rt_inline static __inline
#define RT_NULL 0
/* boolean type definitions */
@ -72,88 +74,84 @@ typedef rt_base_t rt_off_t; /**< Type for offset */
/**
* Double List structure
*/
struct rt_list_node
{
struct rt_list_node *next; /**< point to next node. */
struct rt_list_node *prev; /**< point to prev node. */
struct rt_list_node {
struct rt_list_node* next; /**< point to next node. */
struct rt_list_node* prev; /**< point to prev node. */
};
typedef struct rt_list_node rt_list_t; /**< Type for lists. */
typedef struct rt_list_node rt_list_t; /**< Type for lists. */
/**
* Base structure of Kernel object
*/
struct rt_object
{
struct rt_object {
#if RT_NAME_MAX > 0
char name[RT_NAME_MAX]; /**< dynamic name of kernel object */
char name[RT_NAME_MAX]; /**< dynamic name of kernel object */
#else
const char *name; /**< static name of kernel object */
#endif /* RT_NAME_MAX > 0 */
rt_uint8_t type; /**< type of kernel object */
rt_uint8_t flag; /**< flag of kernel object */
rt_list_t list; /**< list node of kernel object */
const char* name; /**< static name of kernel object */
#endif /* RT_NAME_MAX > 0 */
rt_uint8_t type; /**< type of kernel object */
rt_uint8_t flag; /**< flag of kernel object */
rt_list_t list; /**< list node of kernel object */
};
typedef struct rt_object *rt_object_t; /**< Type for kernel objects. */
typedef struct rt_object* rt_object_t; /**< Type for kernel objects. */
/**
* device (I/O) class type
*/
enum rt_device_class_type
{
RT_Device_Class_Char = 0, /**< character device */
RT_Device_Class_Block, /**< block device */
RT_Device_Class_NetIf, /**< net interface */
RT_Device_Class_MTD, /**< memory device */
RT_Device_Class_CAN, /**< CAN device */
RT_Device_Class_RTC, /**< RTC device */
RT_Device_Class_Sound, /**< Sound device */
RT_Device_Class_Graphic, /**< Graphic device */
RT_Device_Class_I2CBUS, /**< I2C bus device */
RT_Device_Class_USBDevice, /**< USB slave device */
RT_Device_Class_USBHost, /**< USB host bus */
RT_Device_Class_USBOTG, /**< USB OTG bus */
RT_Device_Class_SPIBUS, /**< SPI bus device */
RT_Device_Class_SPIDevice, /**< SPI device */
RT_Device_Class_SDIO, /**< SDIO bus device */
RT_Device_Class_PM, /**< PM pseudo device */
RT_Device_Class_Pipe, /**< Pipe device */
RT_Device_Class_Portal, /**< Portal device */
RT_Device_Class_Timer, /**< Timer device */
RT_Device_Class_Miscellaneous, /**< Miscellaneous device */
RT_Device_Class_Sensor, /**< Sensor device */
RT_Device_Class_Touch, /**< Touch device */
RT_Device_Class_PHY, /**< PHY device */
RT_Device_Class_Security, /**< Security device */
RT_Device_Class_WLAN, /**< WLAN device */
RT_Device_Class_Pin, /**< Pin device */
RT_Device_Class_ADC, /**< ADC device */
RT_Device_Class_DAC, /**< DAC device */
RT_Device_Class_WDT, /**< WDT device */
RT_Device_Class_PWM, /**< PWM device */
RT_Device_Class_Bus, /**< Bus device */
RT_Device_Class_Unknown /**< unknown device */
enum rt_device_class_type {
RT_Device_Class_Char = 0, /**< character device */
RT_Device_Class_Block, /**< block device */
RT_Device_Class_NetIf, /**< net interface */
RT_Device_Class_MTD, /**< memory device */
RT_Device_Class_CAN, /**< CAN device */
RT_Device_Class_RTC, /**< RTC device */
RT_Device_Class_Sound, /**< Sound device */
RT_Device_Class_Graphic, /**< Graphic device */
RT_Device_Class_I2CBUS, /**< I2C bus device */
RT_Device_Class_USBDevice, /**< USB slave device */
RT_Device_Class_USBHost, /**< USB host bus */
RT_Device_Class_USBOTG, /**< USB OTG bus */
RT_Device_Class_SPIBUS, /**< SPI bus device */
RT_Device_Class_SPIDevice, /**< SPI device */
RT_Device_Class_SDIO, /**< SDIO bus device */
RT_Device_Class_PM, /**< PM pseudo device */
RT_Device_Class_Pipe, /**< Pipe device */
RT_Device_Class_Portal, /**< Portal device */
RT_Device_Class_Timer, /**< Timer device */
RT_Device_Class_Miscellaneous, /**< Miscellaneous device */
RT_Device_Class_Sensor, /**< Sensor device */
RT_Device_Class_Touch, /**< Touch device */
RT_Device_Class_PHY, /**< PHY device */
RT_Device_Class_Security, /**< Security device */
RT_Device_Class_WLAN, /**< WLAN device */
RT_Device_Class_Pin, /**< Pin device */
RT_Device_Class_ADC, /**< ADC device */
RT_Device_Class_DAC, /**< DAC device */
RT_Device_Class_WDT, /**< WDT device */
RT_Device_Class_PWM, /**< PWM device */
RT_Device_Class_Bus, /**< Bus device */
RT_Device_Class_Unknown /**< unknown device */
};
typedef struct rt_device *rt_device_t;
typedef struct rt_device* rt_device_t;
/**
* Device structure
*/
struct rt_device
{
struct rt_object parent; /**< inherit from rt_object */
enum rt_device_class_type type; /**< device type */
rt_uint16_t flag; /**< device flag */
rt_uint16_t open_flag; /**< device open flag */
struct rt_device {
struct rt_object parent; /**< inherit from rt_object */
enum rt_device_class_type type; /**< device type */
rt_uint16_t flag; /**< device flag */
rt_uint16_t open_flag; /**< device open flag */
rt_uint8_t ref_count; /**< reference count */
rt_uint8_t device_id; /**< 0 - 255 */
rt_uint8_t ref_count; /**< reference count */
rt_uint8_t device_id; /**< 0 - 255 */
/* device call back */
rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);
rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);
rt_err_t (*tx_complete)(rt_device_t dev, void* buffer);
const struct rt_device_ops *ops;
void *user_data; /**< device private data */
const struct rt_device_ops* ops;
void* user_data; /**< device private data */
};
#endif