This commit is contained in:
xjc 2023-09-30 00:52:08 +08:00
commit acb8bdbef8
26 changed files with 597 additions and 1027 deletions

View File

@ -0,0 +1,8 @@
import PikaDebug as pdb
pdb.set_trace()
pdb.set_break('pdb_set_break', 48)
print('line 1')
print('line 2')
print('line 3')
print('line 4')
print('line 5')

View File

@ -4,3 +4,12 @@ class Debuger:
def set_trace(self):
pass
def set_trace():
pass
def set_break(module: str, pc_break: int):
pass
def reset_break(module: str, pc_break: int):
pass

View File

@ -1,56 +1,23 @@
#include "PikaVM.h"
#include "dataStrs.h"
extern volatile PikaObj* __pikaMain;
static enum shellCTRL __obj_shellLineHandler_debug(PikaObj* self,
char* input_line,
struct ShellConfig* config) {
/* continue */
if (strEqu("c", input_line)) {
return SHELL_CTRL_EXIT;
}
/* next */
if (strEqu("n", input_line)) {
return SHELL_CTRL_EXIT;
}
/* launch shell */
if (strEqu("sh", input_line)) {
/* exit pika shell */
pikaScriptShell((PikaObj*)__pikaMain);
return SHELL_CTRL_CONTINUE;
}
/* quit */
if (strEqu("q", input_line)) {
obj_setInt(self, "enable", 0);
return SHELL_CTRL_EXIT;
}
/* print */
if (strIsStartWith(input_line, "p ")) {
char* path = input_line + 2;
Arg* asm_buff = arg_newStr("B0\n1 REF ");
asm_buff = arg_strAppend(asm_buff, path);
asm_buff = arg_strAppend(asm_buff, "\n0 RUN print\n");
pikaVM_runAsm((PikaObj*)__pikaMain, arg_getStr(asm_buff));
arg_deinit(asm_buff);
return SHELL_CTRL_CONTINUE;
}
obj_run((PikaObj*)__pikaMain, input_line);
return SHELL_CTRL_CONTINUE;
}
void PikaDebug_Debuger___init__(PikaObj* self) {
/* global enable contral */
obj_setInt(self, "enable", 1);
}
void PikaDebug_Debuger_set_trace(PikaObj* self) {
if (!obj_getInt(self, "enable")) {
return;
}
struct ShellConfig cfg = {
.prefix = "(pika-debug) ",
.handler = __obj_shellLineHandler_debug,
.fn_getchar = __platform_getchar,
};
_do_pikaScriptShell(self, &cfg);
pika_debug_set_trace(self);
}
void PikaDebug_set_trace(PikaObj* self) {
PikaDebug_Debuger_set_trace(self);
}
void PikaDebug_set_break(PikaObj* self, char* module, int pc_break) {
pika_debug_set_break(module, pc_break);
}
void PikaDebug_reset_break(PikaObj* self, char* module, int pc_break) {
pika_debug_reset_break(module, pc_break);
}

View File

@ -12,7 +12,8 @@
// "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain",
"args": [
// "--gtest_filter=vm.keyword_2"
"--gtest_filter=vm.exit_vm"
// "--gtest_filter=compiler.find_break_point"
"--gtest_filter=pikaMain.REPL_pdb_set_break"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",

View File

@ -129,7 +129,7 @@
"editor.defaultFormatter": "tamasfe.even-better-toml"
},
"[python]": {
"editor.defaultFormatter": "ms-python.autopep8"
"editor.defaultFormatter": "ms-python.python"
},
"[c]": {
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"

View File

@ -4,3 +4,12 @@ class Debuger:
def set_trace(self):
pass
def set_trace():
pass
def set_break(module: str, pc_break: int):
pass
def reset_break(module: str, pc_break: int):
pass

View File

@ -1,4 +1,5 @@
import PikaStdLib, PikaStdDevice, PikaMath, PikaDebug, PikaCV, PikaNN
import PikaDebug as pdb
import PikaStdLib, PikaStdDevice, PikaMath, PikaCV, PikaNN
import random, re, modbus, socket, unittest, binascii, ctypes, requests, mqtt
import pika_lua, pika_cjson, cjson_test, json
import GTestTask, TempDevTest

View File

@ -1,56 +1,23 @@
#include "PikaVM.h"
#include "dataStrs.h"
extern volatile PikaObj* __pikaMain;
static enum shellCTRL __obj_shellLineHandler_debug(PikaObj* self,
char* input_line,
struct ShellConfig* config) {
/* continue */
if (strEqu("c", input_line)) {
return SHELL_CTRL_EXIT;
}
/* next */
if (strEqu("n", input_line)) {
return SHELL_CTRL_EXIT;
}
/* launch shell */
if (strEqu("sh", input_line)) {
/* exit pika shell */
pikaScriptShell((PikaObj*)__pikaMain);
return SHELL_CTRL_CONTINUE;
}
/* quit */
if (strEqu("q", input_line)) {
obj_setInt(self, "enable", 0);
return SHELL_CTRL_EXIT;
}
/* print */
if (strIsStartWith(input_line, "p ")) {
char* path = input_line + 2;
Arg* asm_buff = arg_newStr("B0\n1 REF ");
asm_buff = arg_strAppend(asm_buff, path);
asm_buff = arg_strAppend(asm_buff, "\n0 RUN print\n");
pikaVM_runAsm((PikaObj*)__pikaMain, arg_getStr(asm_buff));
arg_deinit(asm_buff);
return SHELL_CTRL_CONTINUE;
}
obj_run((PikaObj*)__pikaMain, input_line);
return SHELL_CTRL_CONTINUE;
}
void PikaDebug_Debuger___init__(PikaObj* self) {
/* global enable contral */
obj_setInt(self, "enable", 1);
}
void PikaDebug_Debuger_set_trace(PikaObj* self) {
if (!obj_getInt(self, "enable")) {
return;
}
struct ShellConfig cfg = {
.prefix = "(pika-debug) ",
.handler = __obj_shellLineHandler_debug,
.fn_getchar = __platform_getchar,
};
_do_pikaScriptShell(self, &cfg);
pika_debug_set_trace(self);
}
void PikaDebug_set_trace(PikaObj* self) {
PikaDebug_Debuger_set_trace(self);
}
void PikaDebug_set_break(PikaObj* self, char* module, int pc_break) {
pika_debug_set_break(module, pc_break);
}
void PikaDebug_reset_break(PikaObj* self, char* module, int pc_break) {
pika_debug_reset_break(module, pc_break);
}

View File

@ -8,7 +8,7 @@
#endif
void (*global_do_sleep_ms)(uint32_t);
extern volatile VMSignal g_PikaVMSignal;
extern volatile VMState g_PikaVMState;
volatile int g_pika_local_timezone = 8;
static void _do_sleep_ms_tick(uint32_t ms) {

View File

@ -1,806 +0,0 @@
#include "test_common.h"
TEST_START
TEST(compiler, file) {
char* lines =
"len = calls.len()\n"
"mode = 'none'\n"
"info_index = 0\n"
"for i in range(0, len):\n"
" if len == 0:\n"
" break\n"
" if info_index == 0:\n"
" mode = calls[i]\n"
" info_index = 1\n"
" elif info_index == 1:\n"
" if mode == 'always':\n"
" todo = calls[i]\n"
" todo()\n"
" info_index = 0\n"
" elif mode == 'when':\n"
" when = calls[i]\n"
" info_index = 2\n"
" elif mode == 'period_ms':\n"
" period_ms = calls[i]\n"
" info_index = 2\n"
" elif info_index == 2:\n"
" if mode == 'when':\n"
" if when():\n"
" todo = calls[i]\n"
" todo()\n"
" info_index = 0\n"
" elif mode == 'period_ms':\n"
" todo = calls[i]\n"
" info_index = 3\n"
" elif info_index == 3:\n"
" if mode == 'period_ms':\n"
" if tick > calls[i]:\n"
" todo()\n"
" calls[i] = tick + period_ms\n"
" info_index = 0\n"
"\n";
pikaCompile("task.bin", lines);
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, task) {
char* lines =
"len = calls.len()\n"
"mode = 'none'\n"
"info_index = 0\n"
"for i in range(0, len):\n"
" if len == 0:\n"
" break\n"
" if info_index == 0:\n"
" mode = calls[i]\n"
" info_index = 1\n"
" elif info_index == 1:\n"
" if mode == 'always':\n"
" todo = calls[i]\n"
" todo()\n"
" info_index = 0\n"
" elif mode == 'when':\n"
" when = calls[i]\n"
" info_index = 2\n"
" elif mode == 'period_ms':\n"
" period_ms = calls[i]\n"
" info_index = 2\n"
" elif info_index == 2:\n"
" if mode == 'when':\n"
" if when():\n"
" todo = calls[i]\n"
" todo()\n"
" info_index = 0\n"
" elif mode == 'period_ms':\n"
" todo = calls[i]\n"
" info_index = 3\n"
" elif info_index == 3:\n"
" if mode == 'period_ms':\n"
" if tick > calls[i]:\n"
" todo()\n"
" calls[i] = tick + period_ms\n"
" info_index = 0\n"
"\n";
Args buffs = {0};
char* pikaAsm = pika_lines2Asm(&buffs, lines);
ByteCodeFrame bytecode_frame;
byteCodeFrame_init(&bytecode_frame);
byteCodeFrame_appendFromAsm(&bytecode_frame, pikaAsm);
/* do something */
byteCodeFrame_print(&bytecode_frame);
printf("Asm size: %d\r\n", (int)strGetSize(pikaAsm));
byteCodeFrame_printAsArray(&bytecode_frame);
/* deinit */
byteCodeFrame_deinit(&bytecode_frame);
strsDeinit(&buffs);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, demo1) {
char* lines = "append(__val)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, snake_file) {
char* lines =
"from PikaObj import *\n"
"import PikaStdLib\n"
"import machine \n"
"\n"
"# hardware init\n"
"lcd = machine.LCD()\n"
"lcd.init()\n"
"lcd.clear('white')\n"
"key = machine.KEY()\n"
"key.init()\n"
"time = machine.Time()\n"
"x_max = 120\n"
"y_max = 150\n"
"\n"
"# snake init\n"
"s = machine.Point()\n"
"w = 9\n"
"h = 9\n"
"s.x = 50\n"
"s.y = 10\n"
"len = 0\n"
"while len < 3:\n"
" b = s\n"
" i = 0\n"
" while i < len:\n"
" b = b.next\n"
" i = i + 1\n"
" b.next = machine.Point()\n"
" b.next.x = b.x - 10\n"
" b.next.y = b.y\n"
" b.next.prev = b\n"
" len = len + 1\n"
"# ring link\n"
"b.next = s\n"
"s.prev = b\n"
"\n"
"i = 0\n"
"b = s\n"
"while i < len:\n"
" lcd.fill(b.x, b.y, w, h, 'blue')\n"
" b = b.next\n"
" i = i + 1\n"
"\n"
"print('snake lengh')\n"
"print(len)\n"
"\n"
"# fruit init\n"
"f = machine.Point()\n"
"f.x = 30\n"
"f.y = 20\n"
"lcd.fill(f.x, f.y, w, h, 'green')\n"
"\n"
"# memory check\n"
"mem = PikaStdLib.MemChecker()\n"
"print('mem used max:')\n"
"mem.max()\n"
"\n"
"# main loop\n"
"d = 0\n"
"isUpdate = 1\n"
"isEat = 0\n"
"while True:\n"
" if isUpdate:\n"
" # isUpdate = 0\n"
" # check eat fruit\n"
" if f.x == s.x and f.y == s.y:\n"
" # have eat fruit\n"
" isEat = 1\n"
" f.x = f.x + 30\n"
" if f.x > x_max:\n"
" f.x = f.x - x_max\n"
" f.y = f.y + 30\n"
" if f.y > y_max:\n"
" f.y = f.y - y_max\n"
" lcd.fill(f.x, f.y, w, h, 'green')\n"
" # move snake by the direction\n"
" if d == 0:\n"
" x_new = s.x + 10\n"
" y_new = s.y\n"
" if x_new > x_max:\n"
" x_new = 0\n"
" elif d == 1:\n"
" x_new = s.x\n"
" y_new = s.y - 10\n"
" if y_new < 0:\n"
" y_new = y_max\n"
" elif d == 2:\n"
" x_new = s.x\n"
" y_new = s.y + 10\n"
" if y_new > y_max:\n"
" y_new = 0\n"
" elif d == 3:\n"
" x_new = s.x - 10\n"
" y_new = s.y\n"
" if x_new < 0:\n"
" x_new = x_max\n"
" if isEat:\n"
" isEat = 0\n"
" b_new = machine.Point()\n"
" b_new.x = x_new\n"
" b_new.y = y_new\n"
" b_new.prev = s.prev\n"
" b_new.next = s\n"
" s.prev.next = b_new\n"
" s.prev = b_new\n"
" s = b_new\n"
" len = len + 1\n"
" print('snake lengh')\n"
" print(len)\n"
" print('mem used max:')\n"
" mem.max()\n"
" # drow the snake and fruit\n"
" # clear last body\n"
" lcd.fill(s.prev.x, s.prev.y, w, h, 'white')\n"
" # new body\n"
" s.prev.x = x_new\n"
" s.prev.y = y_new\n"
" # head is last body\n"
" s = s.prev\n"
" lcd.fill(s.x, s.y, w, h, 'blue')\n"
" b = s\n"
" i = 0\n"
" # scan key\n"
" key_val = key.get()\n"
" if key_val == 0:\n"
" d = 0\n"
" isUpdate = 1\n"
" elif key_val == 1:\n"
" d = 1\n"
" isUpdate = 1\n"
" elif key_val == 2:\n"
" d = 2\n"
" isUpdate = 1\n"
" elif key_val == 3:\n"
" d = 3\n"
" isUpdate = 1\n";
pikaCompile("snake.bin", lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, import_bf_mem) {
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
char* lines =
"def mytest():\n"
" print('test')\n"
"\n";
ByteCodeFrame bf;
byteCodeFrame_init(&bf);
pika_lines2Bytes(&bf, lines);
obj_importModuleWithByteCodeFrame(pikaMain, "mtest", &bf);
byteCodeFrame_deinit(&bf);
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, import_bf1) {
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
char* lines =
"def mytest():\n"
" print('test_import_bf1')\n"
"\n";
ByteCodeFrame bf;
byteCodeFrame_init(&bf);
pika_lines2Bytes(&bf, lines);
obj_importModuleWithByteCodeFrame(pikaMain, "mtest", &bf);
obj_run(pikaMain,
"mtest.mytest()\n"
"\n");
EXPECT_STREQ(log_buff[0], "test_import_bf1\r\n");
byteCodeFrame_deinit(&bf);
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, import_bf2) {
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
char* lines =
"class Test:\n"
" def mytest(self):\n"
" print('test_import_bf2')\n"
"\n";
ByteCodeFrame bf;
byteCodeFrame_init(&bf);
pika_lines2Bytes(&bf, lines);
obj_importModuleWithByteCodeFrame(pikaMain, "mtest", &bf);
obj_run(pikaMain,
"m = mtest.Test()\n"
"m.mytest()\n"
"\n");
byteCodeFrame_deinit(&bf);
obj_deinit(pikaMain);
EXPECT_STREQ(log_buff[0], "test_import_bf2\r\n");
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, file1) {
pikaCompileFile("test/python/main.py");
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, file2) {
pikaCompileFile("test/python/main_snake_LCD.py");
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, init) {
LibObj* lib = New_LibObj(NULL);
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, lib_link_bytecode) {
LibObj* lib = New_LibObj(NULL);
LibObj_dynamicLink(lib, "module1", (uint8_t*)0x3344);
LibObj_dynamicLink(lib, "module2", (uint8_t*)0x33433);
LibObj_dynamicLink(lib, "module3", (uint8_t*)0x33433);
LibObj_dynamicLink(lib, "module4", (uint8_t*)0x33433);
LibObj_dynamicLink(lib, "module5", (uint8_t*)0x33433);
EXPECT_STREQ(obj_getStr(lib, "module1.name"), "module1");
EXPECT_EQ((uintptr_t)obj_getPtr(lib, "module1.bytecode"), 0x3344);
/* deinit */
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, lib_push_file) {
LibObj* lib = New_LibObj(NULL);
LibObj_staticLinkFile(lib, "test/python/main.py.o");
/* deinit */
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, lib_push_files) {
LibObj* lib = New_LibObj(NULL);
LibObj_staticLinkFile(lib, "test/python/main.py.o");
LibObj_staticLinkFile(lib, "test/python/main_snake_LCD.py.o");
LibObj_listModules(lib);
/* asset */
EXPECT_STREQ(log_buff[0], "main\r\n");
EXPECT_STREQ(log_buff[1], "main_snake_LCD\r\n");
/* deinit */
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, lib_compile_link) {
LibObj* lib = New_LibObj(NULL);
pikaCompileFile("test/python/UnitTest.py");
pikaCompileFile("test/python/main.py");
pikaCompileFile("test/python/main_snake_LCD.py");
LibObj_staticLinkFile(lib, "test/python/UnitTest.py.o");
LibObj_staticLinkFile(lib, "test/python/main.py.o");
LibObj_staticLinkFile(lib, "test/python/main_snake_LCD.py.o");
LibObj_listModules(lib);
/* asset */
EXPECT_STREQ(log_buff[0], "UnitTest\r\n");
EXPECT_STREQ(log_buff[1], "main\r\n");
EXPECT_STREQ(log_buff[2], "main_snake_LCD\r\n");
/* deinit */
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, compile_link_import) {
LibObj* lib = New_LibObj(NULL);
pikaCompileFile("test/python/test_module1.py");
LibObj_staticLinkFile(lib, "test/python/test_module1.py.o");
LibObj_listModules(lib);
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
obj_linkLibObj(pikaMain, lib);
obj_run(pikaMain,
"import test_module1\n"
"test_module1.mytest()\n");
/* asset */
EXPECT_STREQ(log_buff[0], "test_module_1_hello\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, lib_to_file) {
LibObj* lib = New_LibObj(NULL);
pikaCompileFile("test/python/UnitTest.py");
pikaCompileFile("test/python/main.py");
pikaCompileFile("test/python/main_snake_LCD.py");
LibObj_staticLinkFile(lib, "test/python/UnitTest.py.o");
LibObj_staticLinkFile(lib, "test/python/main.py.o");
LibObj_staticLinkFile(lib, "test/python/main_snake_LCD.py.o");
LibObj_listModules(lib);
LibObj_linkFile(lib, "test/python/lib_to_file.py.a");
/* asset */
EXPECT_STREQ(log_buff[0], "UnitTest\r\n");
EXPECT_STREQ(log_buff[1], "main\r\n");
EXPECT_STREQ(log_buff[2], "main_snake_LCD\r\n");
/* deinit */
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, save2) {
LibObj* lib = New_LibObj(NULL);
pikaCompileFile("test/python/test_module1.py");
pikaCompileFile("test/python/test_module2.py");
pikaCompileFile("test/python/test_module3.py");
LibObj_staticLinkFile(lib, "test/python/test_module1.py.o");
LibObj_staticLinkFile(lib, "test/python/test_module2.py.o");
LibObj_staticLinkFile(lib, "test/python/test_module3.py.o");
LibObj_listModules(lib);
LibObj_linkFile(lib, "test/python/test_module.py.a");
/* asset */
EXPECT_STREQ(log_buff[0], "test_module1\r\n");
EXPECT_STREQ(log_buff[1], "test_module2\r\n");
EXPECT_STREQ(log_buff[2], "test_module3\r\n");
/* deinit */
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, load_file) {
/* compile */
LibObj* lib = New_LibObj(NULL);
LibObj_loadLibraryFile(lib, "test/python/test_module.py.a");
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
obj_linkLibObj(pikaMain, lib);
obj_run(pikaMain,
"import test_module1\n"
"import test_module2\n"
"import test_module3\n"
"test_module1.mytest()\n"
"test_module2.mytest()\n"
"test_module3.mytest()\n");
/* asset */
EXPECT_STREQ(log_buff[2], "test_module_1_hello\r\n");
EXPECT_STREQ(log_buff[1], "test_module_2_hello\r\n");
EXPECT_STREQ(log_buff[0], "test_module_3_hello\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, load_no_file) {
/* compile */
LibObj* lib = New_LibObj(NULL);
int res = LibObj_loadLibraryFile(lib, "test/python/mian.py.o");
EXPECT_EQ(res, PIKA_RES_ERR_IO_ERROR);
/* deinit */
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, load_err_file_type) {
/* compile */
LibObj* lib = New_LibObj(NULL);
int res = LibObj_loadLibraryFile(lib, "test/python/main.py.o");
EXPECT_EQ(res, PIKA_RES_ERR_OPERATION_FAILED);
/* deinit */
LibObj_deinit(lib);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(lib, lib_file_to_array) {
Lib_loadLibraryFileToArray("test/python/lib_to_file.py.a", "test/python");
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(make, maker) {
PikaMaker* maker = New_PikaMaker();
pikaMaker_deinit(maker);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(make, compile) {
PikaMaker* maker = New_PikaMaker();
pikaMaker_setPWD(maker, "package/pikascript/");
pikaMaker_compileModule(maker, "main");
pikaMaker_deinit(maker);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(make, depend) {
PikaMaker* maker = New_PikaMaker();
pikaMaker_setPWD(maker, "package/pikascript/");
pikaMaker_getDependencies(maker, "main");
pikaMaker_printStates(maker);
// char* uncompiled = pikaMaker_getFirstNocompiled(maker);
// EXPECT_STREQ(uncompiled, "test_module1");
pikaMaker_deinit(maker);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(make, compile_depend) {
PikaMaker* maker = New_PikaMaker();
pikaMaker_setPWD(maker, "package/pikascript/");
pikaMaker_getDependencies(maker, "main");
char* uncompiled = pikaMaker_getFirstNocompiled(maker);
pika_assert(NULL != uncompiled);
pikaMaker_compileModule(maker, uncompiled);
pikaMaker_getDependencies(maker, uncompiled);
uncompiled = pikaMaker_getFirstNocompiled(maker);
// EXPECT_STREQ(uncompiled, "test_module3");
pikaMaker_printStates(maker);
pikaMaker_deinit(maker);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(make, compile_depend_all) {
PikaMaker* maker = New_PikaMaker();
pikaMaker_setPWD(maker, "package/pikascript/");
pikaMaker_compileModuleWithDepends(maker, "main");
pikaMaker_printStates(maker);
pikaMaker_deinit(maker);
EXPECT_EQ(pikaMemNow(), 0);
}
// TEST(make, compile_link_all) {
// PikaMaker* maker = New_PikaMaker();
// pikaMaker_setPWD(maker, "package/pikascript/");
// pikaMaker_compileModuleWithDepends(maker, "main");
// pikaMaker_printStates(maker);
// pikaMaker_linkCompiledModules(maker, "pikaModules.py.a");
// pikaMaker_deinit(maker);
// EXPECT_EQ(pikaMemNow(), 0);
// }
TEST(compiler, __str__) {
char* lines = "@res_str = __str__()";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __len__) {
char* lines = "@res_len = __len__()";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __del__) {
char* lines = "__del__()";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, event_cb) {
char* lines = "_eventCallBack(_eventSignal)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, event_cb_lvgl) {
char* lines = "_res = eventCallBack(eventData)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __setitem__) {
char* lines = "__setitem__(__key, __val)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __getitem__) {
char* lines = "@res_item = __getitem__(__key)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __add__) {
char* lines = "@res_add = __add__(__others)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __eq__) {
char* lines = "@res_eq = __eq__(__others)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __iter__) {
char* lines = "@res_iter = __iter__()";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __sub__) {
char* lines = "@res_sub = __sub__(__others)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __contains__) {
char* lines = "@res_contains = __contains__(__others)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __callback) {
char* lines = "__callback(__frameBuffer, __isNewFrame)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, __list) {
char* lines =
"@res_list = []\n"
"for __item in __list:\n"
" @res_list.append(__item)\n"
"del __item\n"
"del __list\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, getattr) {
char* lines = "@res = __getattribute__(@name)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, getattr2) {
char* lines = "@res = __getattr__(@name)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, setattr) {
char* lines = "__setattr__(@name, @value)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, dict_update) {
char* lines =
"for @item in @other:\n"
" @self[@item] = @other[@item]\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, i_pp) {
char* lines =
"i = 0\n"
"while i < 10000:\n"
" i += 1\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, benchmark) {
char* lines =
"num = 0\n"
"i = 2\n"
"while i < 1000:\n"
" is_prime = 1\n"
" j = 2\n"
" while j < i:\n"
" if i%j==0 :\n"
" is_prime = 0\n"
" break\n"
" j += 1 \n"
" if is_prime:\n"
" num = num + i\n"
" i += 1\n"
"\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, for_print_1k) {
char* lines =
"for i in range(1000):\n"
" print(i)\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, bc_fn) {
char* lines =
"def test():\n"
" print('test')\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, starrd) {
char* lines = "@l = __len__()";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, starrd_get) {
char* lines = "@a = __getitem__(@d)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, thread_arg) {
char* lines = "thread(*args)";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, prime_100) {
char* lines =
"num = 0\n"
"i = 2\n"
"for i in range(2,100):\n"
" j=2\n"
" is_prime = 1\n"
" for j in range(2,i):\n"
" if i%j==0 :\n"
" is_prime = 0\n"
" break\n"
" if is_prime:\n"
" num = num + i\n"
"\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, getattr_fn) {
char* lines = "@res = @obj.@name\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, str_join) {
char* lines =
"@res_join = \"\"\n"
"@num = len(@val)\n"
"for i in range(@num):\n"
" @res_join += @val[i]\n"
" if i != @num - 1:\n"
" @res_join += @str\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, thread_void_arg) {
char* lines = "thread()";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, max) {
char* lines =
"@res_max = @list[0]\n"
"for @item in @list:\n"
" if @item > @res_max:\n"
" @res_max = @item\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, min) {
char* lines =
"@res_max = @list[0]\n"
"for @item in @list:\n"
" if @item < @res_max:\n"
" @res_max = @item\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, contains) {
char* lines =
"@res_contains = 0\n"
"for @item in @list:\n"
" if @item == @val:\n"
" @res_contains = 1\n"
" break\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(compiler, fn1) {
char* lines = "@r = @f(@d)\n";
pika_lines2Array(lines);
EXPECT_EQ(pikaMemNow(), 0);
}
TEST_END

View File

@ -559,7 +559,7 @@ TEST(module, REPL_script) {
fclose((FILE*)f_getchar_fp);
/* collect */
/* assert */
EXPECT_STREQ(log_buff[4], "mem used max:\r\n");
EXPECT_STREQ(log_buff[3], "mem used max:\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);

View File

@ -2927,6 +2927,25 @@ TEST(pikaMain, REPL_key_down_over) {
EXPECT_EQ(pikaMemNow(), 0);
}
TEST(pikaMain, REPL_pdb_set_break) {
char lines[] = "pdb.set_break('pdb_set_break', 36)\nn\nn\nn\n";
write_to_getchar_buffer(lines, strGetSize(lines));
/* init */
g_PikaMemInfo.heapUsedMax = 0;
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
extern unsigned char pikaModules_py_a[];
obj_linkLibrary(pikaMain, pikaModules_py_a);
pikaVM_runSingleFile(pikaMain, "test/python/builtins/pdb_set_break.py");
/* run */
__platform_printf("BEGIN\r\n");
/* collect */
/* assert */
// EXPECT_STREQ(log_buff[1], "2\r\n");
/* deinit */
obj_deinit(pikaMain);
EXPECT_EQ(pikaMemNow(), 0);
}
#endif
#if PIKA_SHELL_FILTER_ENABLE

View File

@ -51,3 +51,26 @@ PIKA_WEAK void pika_hook_unused_stack_arg(PikaVMFrame* vm, Arg* arg) {
arg_print(arg, pika_true, "\r\n");
}
}
#define GETCHAR_BUFFER_SIZE 1024
uint8_t getchar_buffer[GETCHAR_BUFFER_SIZE] = {0};
size_t getchar_buffer_index = 0;
int write_to_getchar_buffer(const char* str, size_t size) {
if (size > GETCHAR_BUFFER_SIZE - getchar_buffer_index) {
return -1;
}
memcpy(getchar_buffer + getchar_buffer_index, str, size);
getchar_buffer_index += size;
return 0;
}
char pika_platform_getchar(void) {
if (getchar_buffer_index > 0) {
char c = getchar_buffer[0];
memmove(getchar_buffer, getchar_buffer + 1, getchar_buffer_index - 1);
getchar_buffer_index--;
return c;
}
return getchar();
}

View File

@ -1,4 +1,6 @@
#include <stdio.h>
#define LOG_BUFF_MAX 100
#define LOG_SIZE 512
void mem_pool_deinit(void);
void mem_pool_init(void);
int write_to_getchar_buffer(const char* str, size_t size);

View File

@ -1,7 +1,5 @@
import PikaUI as ui
from PikaStdLib import MemChecker as mem
class MainContainer(ui.Container):
def onclick_next(self, event):
print('Page1: onclick_next')

View File

@ -0,0 +1,8 @@
import PikaDebug as pdb
pdb.set_trace()
pdb.set_break('pdb_set_break', 48)
print('line 1')
print('line 2')
print('line 3')
print('line 4')
print('line 5')

View File

@ -37,13 +37,14 @@
#include "dataQueue.h"
#include "dataString.h"
#include "dataStrs.h"
#include "PikaParser.h"
#if __linux
#include "signal.h"
#include "termios.h"
#include "unistd.h"
#endif
extern volatile VMSignal g_PikaVMSignal;
extern volatile VMState g_PikaVMState;
volatile PikaObjState g_PikaObjState = {
.helpModulesCmodule = NULL,
.inRootObj = pika_false,
@ -1790,7 +1791,9 @@ enum shellCTRL _inner_do_obj_runChar(PikaObj* self,
}
shell->lineBuff[shell->line_position] = '\0';
ctrl = shell->handler(self, shell->lineBuff, shell);
pika_platform_printf("%s", shell->prefix);
if (SHELL_CTRL_EXIT != ctrl) {
pika_platform_printf("%s", shell->prefix);
}
__clearBuff(shell);
goto __exit;
}
@ -2032,7 +2035,9 @@ static enum shellCTRL __obj_shellLineHandler_REPL(PikaObj* self,
return SHELL_CTRL_EXIT;
}
/* run single line */
_pikaVM_runPyLines(self, input_line, pika_true);
pikaVM_run_ex_cfg cfg = {0};
cfg.in_repl = pika_true;
pikaVM_run_ex(self, input_line, &cfg);
return SHELL_CTRL_CONTINUE;
}
@ -2542,6 +2547,17 @@ PikaObj* obj_importModuleWithByteCode(PikaObj* self,
pikaVM_runByteCode(obj_getObj((PikaObj*)__pikaMain, name),
(uint8_t*)byteCode);
PikaObj* module_obj = obj_getObj((PikaObj*)__pikaMain, name);
PikaVMThread vm_thread = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
pikaVM_runBytecode_ex_cfg cfg = {0};
cfg.globals = module_obj;
cfg.locals = module_obj;
cfg.name = name;
cfg.vm_thread = &vm_thread;
cfg.is_const_bytecode = pika_true;
pikaVM_runByteCode_ex(module_obj, byteCode, &cfg);
}
if (self != (PikaObj*)__pikaMain) {
/* import to other module context */
@ -2617,7 +2633,16 @@ int obj_runModule(PikaObj* self, char* module_name) {
if (NULL == bytecode) {
return 1;
}
pikaVM_runByteCode(self, bytecode);
PikaVMThread vm_thread = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
pikaVM_runBytecode_ex_cfg cfg = {0};
cfg.globals = self;
cfg.locals = self;
cfg.name = module_name;
cfg.vm_thread = &vm_thread;
cfg.is_const_bytecode = pika_true;
pikaVM_runByteCode_ex(self, bytecode, &cfg);
return 0;
}
@ -2791,8 +2816,8 @@ static void _thread_event(void* arg) {
while (1) {
pika_GIL_ENTER();
#if PIKA_EVENT_ENABLE
if (g_PikaVMSignal.event_thread_exit) {
g_PikaVMSignal.event_thread_exit_done = 1;
if (g_PikaVMState.event_thread_exit) {
g_PikaVMState.event_thread_exit_done = 1;
break;
}
#endif
@ -2814,11 +2839,11 @@ PIKA_RES _do_pika_eventListener_send(PikaEventListener* self,
#else
_RETURN_WHEN_NOT_ZERO(pika_GIL_ENTER(), -1);
#if PIKA_EVENT_THREAD_ENABLE
if (!g_PikaVMSignal.event_thread) {
if (!g_PikaVMState.event_thread) {
/* using multi thread */
if (_VM_is_first_lock()) {
// avoid _VMEvent_pickupEvent() in _time.c as soon as possible
g_PikaVMSignal.event_thread = pika_platform_thread_init(
g_PikaVMState.event_thread = pika_platform_thread_init(
"pika_event", _thread_event, NULL, PIKA_EVENT_THREAD_STACK_SIZE,
PIKA_THREAD_PRIO, PIKA_THREAD_TICK);
pika_debug("event thread init");
@ -2870,11 +2895,11 @@ Arg* pika_eventListener_sendSignalAwaitResult(PikaEventListener* self,
while (1) {
};
#else
extern volatile VMSignal g_PikaVMSignal;
int tail = g_PikaVMSignal.cq.tail;
extern volatile VMState g_PikaVMState;
int tail = g_PikaVMState.cq.tail;
pika_eventListener_sendSignal(self, eventId, eventSignal);
while (1) {
Arg* res = g_PikaVMSignal.cq.res[tail];
Arg* res = g_PikaVMState.cq.res[tail];
pika_platform_thread_yield();
if (NULL != res) {
return res;
@ -4443,3 +4468,73 @@ size_t pikaDict_getBytesSize(PikaDict* self, char* name) {
void pikaDict_deinit(PikaDict* self) {
obj_deinit(self);
}
PIKA_RES insert_label_at_line(const char* filename,
int N,
char* buff,
int buff_size) {
FILE* file = pika_platform_fopen(filename, "r");
if (!file) {
return PIKA_RES_ERR_IO_ERROR;
}
int line_count = 1;
int buff_index = 0;
char ch;
while ((pika_platform_fread(&ch, 1, 1, file)) != 0) {
if (line_count == N) {
char* label = "#!label\n";
int label_length = strGetSize(label);
if (buff_index + label_length >= buff_size) {
pika_platform_fclose(file);
return PIKA_RES_ERR_IO_ERROR; // Insufficient buffer size
}
strCopy(buff + buff_index, label);
buff_index += label_length;
line_count++; // Skip this line since we're adding a label
}
if (ch == '\n') {
line_count++;
}
if (buff_index >=
buff_size - 1) { // -1 to leave space for null terminator
pika_platform_fclose(file);
return PIKA_RES_ERR_IO_ERROR; // Insufficient buffer size
}
buff[buff_index] = ch;
buff_index++;
}
buff[buff_index] = '\0'; // Null terminate the buffer
pika_platform_fclose(file);
return PIKA_RES_OK;
}
int32_t pika_debug_find_break_point_pc(char* pyFile, uint32_t pyLine) {
ByteCodeFrame bytecode_frame;
byteCodeFrame_init(&bytecode_frame);
char* file_buff = pikaMalloc(PIKA_READ_FILE_BUFF_SIZE);
FILE* file = pika_platform_fopen(pyFile, "r");
if (!file) {
goto __exit;
}
if (PIKA_RES_OK != insert_label_at_line(pyFile, pyLine, file_buff,
PIKA_READ_FILE_BUFF_SIZE)) {
goto __exit;
}
pika_lines2Bytes(&bytecode_frame, file_buff);
__exit:
if (NULL != file) {
pika_platform_fclose(file);
}
byteCodeFrame_deinit(&bytecode_frame);
pikaFree(file_buff, PIKA_READ_FILE_BUFF_SIZE);
return bytecode_frame.label_pc;
}

View File

@ -69,8 +69,11 @@ struct InstructArray {
typedef struct ByteCodeFrame ByteCodeFrame;
struct ByteCodeFrame {
char* name;
Hash name_hash;
ConstPool const_pool;
InstructArray instruct_array;
int32_t label_pc;
};
typedef struct NativeProperty NativeProperty;
@ -459,6 +462,8 @@ struct ShellConfig {
ShellHistory* history;
#endif
pika_bool no_echo;
PikaObj* locals;
PikaObj* globals;
};
#if PIKA_SHELL_HISTORY_ENABLE
@ -808,6 +813,8 @@ uint32_t pikaGC_printFreeList(void);
int pika_GIL_EXIT(void);
int pika_GIL_ENTER(void);
int32_t pika_debug_find_break_point_pc(char* pyFile, uint32_t pyLine);
typedef PikaObj PikaList;
typedef PikaObj PikaTuple;
typedef PikaObj PikaDict;

View File

@ -2954,6 +2954,11 @@ char* parser_lines2Target(Parser* self, char* sPyLines) {
__parse_line:
/* parse single Line to Asm */
if (strEqu(sLine, "#!label")) {
self->bytecode_frame->label_pc =
self->bytecode_frame->instruct_array.size;
goto __next_line;
}
sBackendCode = parser_line2Target(self, sLine);
__parse_after:
if (NULL == sBackendCode) {

View File

@ -103,6 +103,7 @@ struct Parser {
pika_bool isGenBytecode;
ByteCodeFrame* bytecode_frame;
uint8_t thisBlockDeepth;
uint32_t label_pc;
};
typedef struct LexToken LexToken;

View File

@ -38,20 +38,24 @@
#endif
static pika_platform_thread_mutex_t g_pikaGIL = {0};
volatile VMSignal g_PikaVMSignal = {.signal_ctrl = VM_SIGNAL_CTRL_NONE,
.vm_cnt = 0,
volatile VMState g_PikaVMState = {
.signal_ctrl = VM_SIGNAL_CTRL_NONE,
.vm_cnt = 0,
#if PIKA_EVENT_ENABLE
.cq =
{
.head = 0,
.tail = 0,
.res = {0},
},
.event_pickup_cnt = 0,
.event_thread = NULL,
.event_thread_exit = pika_false
.cq =
{
.head = 0,
.tail = 0,
.res = {0},
},
.event_pickup_cnt = 0,
.event_thread = NULL,
.event_thread_exit = pika_false,
#endif
#if PIKA_DEBUG_BREAK_POINT_MAX > 0
.break_module_hash = {0},
.break_point_pc = {0},
.break_point_cnt = 0,
#endif
};
extern volatile PikaObjState g_PikaObjState;
@ -127,14 +131,14 @@ int _VM_is_first_lock(void) {
}
int _VMEvent_getVMCnt(void) {
return g_PikaVMSignal.vm_cnt;
return g_PikaVMState.vm_cnt;
}
int _VMEvent_getEventPickupCnt(void) {
#if !PIKA_EVENT_ENABLE
return -1;
#else
return g_PikaVMSignal.event_pickup_cnt;
return g_PikaVMState.event_pickup_cnt;
#endif
}
@ -209,21 +213,21 @@ void _VMEvent_deinit(void) {
pika_platform_panic_handle();
#else
for (int i = 0; i < PIKA_EVENT_LIST_SIZE; i++) {
if (NULL != g_PikaVMSignal.cq.res[i]) {
arg_deinit(g_PikaVMSignal.cq.res[i]);
g_PikaVMSignal.cq.res[i] = NULL;
if (NULL != g_PikaVMState.cq.res[i]) {
arg_deinit(g_PikaVMState.cq.res[i]);
g_PikaVMState.cq.res[i] = NULL;
}
if (NULL != g_PikaVMSignal.cq.data[i]) {
arg_deinit(g_PikaVMSignal.cq.data[i]);
g_PikaVMSignal.cq.data[i] = NULL;
if (NULL != g_PikaVMState.cq.data[i]) {
arg_deinit(g_PikaVMState.cq.data[i]);
g_PikaVMState.cq.data[i] = NULL;
}
}
if (NULL != g_PikaVMSignal.event_thread) {
g_PikaVMSignal.event_thread_exit = 1;
pika_platform_thread_destroy(g_PikaVMSignal.event_thread);
g_PikaVMSignal.event_thread = NULL;
if (NULL != g_PikaVMState.event_thread) {
g_PikaVMState.event_thread_exit = 1;
pika_platform_thread_destroy(g_PikaVMState.event_thread);
g_PikaVMState.event_thread = NULL;
pika_GIL_EXIT();
while (!g_PikaVMSignal.event_thread_exit_done) {
while (!g_PikaVMState.event_thread_exit_done) {
pika_platform_thread_yield();
}
pika_GIL_ENTER();
@ -243,24 +247,23 @@ PIKA_RES __eventListener_pushEvent(PikaEventListener* lisener,
arg_setType(eventData, ARG_TYPE_OBJECT);
}
/* push to event_cq_buff */
if (_ecq_isFull(&g_PikaVMSignal.cq)) {
if (_ecq_isFull(&g_PikaVMState.cq)) {
// pika_debug("event_cq_buff is full");
arg_deinit(eventData);
return PIKA_RES_ERR_SIGNAL_EVENT_FULL;
}
if (g_PikaVMSignal.cq.res[g_PikaVMSignal.cq.tail] != NULL) {
arg_deinit(g_PikaVMSignal.cq.res[g_PikaVMSignal.cq.tail]);
g_PikaVMSignal.cq.res[g_PikaVMSignal.cq.tail] = NULL;
if (g_PikaVMState.cq.res[g_PikaVMState.cq.tail] != NULL) {
arg_deinit(g_PikaVMState.cq.res[g_PikaVMState.cq.tail]);
g_PikaVMState.cq.res[g_PikaVMState.cq.tail] = NULL;
}
if (g_PikaVMSignal.cq.data[g_PikaVMSignal.cq.tail] != NULL) {
arg_deinit(g_PikaVMSignal.cq.data[g_PikaVMSignal.cq.tail]);
g_PikaVMSignal.cq.data[g_PikaVMSignal.cq.tail] = NULL;
if (g_PikaVMState.cq.data[g_PikaVMState.cq.tail] != NULL) {
arg_deinit(g_PikaVMState.cq.data[g_PikaVMState.cq.tail]);
g_PikaVMState.cq.data[g_PikaVMState.cq.tail] = NULL;
}
g_PikaVMSignal.cq.id[g_PikaVMSignal.cq.tail] = eventId;
g_PikaVMSignal.cq.data[g_PikaVMSignal.cq.tail] = eventData;
g_PikaVMSignal.cq.listener[g_PikaVMSignal.cq.tail] = lisener;
g_PikaVMSignal.cq.tail =
(g_PikaVMSignal.cq.tail + 1) % PIKA_EVENT_LIST_SIZE;
g_PikaVMState.cq.id[g_PikaVMState.cq.tail] = eventId;
g_PikaVMState.cq.data[g_PikaVMState.cq.tail] = eventData;
g_PikaVMState.cq.listener[g_PikaVMState.cq.tail] = lisener;
g_PikaVMState.cq.tail = (g_PikaVMState.cq.tail + 1) % PIKA_EVENT_LIST_SIZE;
return PIKA_RES_OK;
#endif
}
@ -275,15 +278,14 @@ PIKA_RES __eventListener_popEvent(PikaEventListener** lisener_p,
return PIKA_RES_ERR_OPERATION_FAILED;
#else
/* pop from event_cq_buff */
if (_ecq_isEmpty(&g_PikaVMSignal.cq)) {
if (_ecq_isEmpty(&g_PikaVMState.cq)) {
return PIKA_RES_ERR_SIGNAL_EVENT_EMPTY;
}
*id = g_PikaVMSignal.cq.id[g_PikaVMSignal.cq.head];
*data = g_PikaVMSignal.cq.data[g_PikaVMSignal.cq.head];
*lisener_p = g_PikaVMSignal.cq.listener[g_PikaVMSignal.cq.head];
*head = g_PikaVMSignal.cq.head;
g_PikaVMSignal.cq.head =
(g_PikaVMSignal.cq.head + 1) % PIKA_EVENT_LIST_SIZE;
*id = g_PikaVMState.cq.id[g_PikaVMState.cq.head];
*data = g_PikaVMState.cq.data[g_PikaVMState.cq.head];
*lisener_p = g_PikaVMState.cq.listener[g_PikaVMState.cq.head];
*head = g_PikaVMState.cq.head;
g_PikaVMState.cq.head = (g_PikaVMState.cq.head + 1) % PIKA_EVENT_LIST_SIZE;
return PIKA_RES_OK;
#endif
}
@ -303,23 +305,23 @@ void __VMEvent_pickupEvent(char* info) {
int head;
if (PIKA_RES_OK == __eventListener_popEvent(&event_lisener, &event_id,
&event_data, &head)) {
g_PikaVMSignal.event_pickup_cnt++;
g_PikaVMState.event_pickup_cnt++;
pika_debug("pickup_info: %s", info);
pika_debug("pickup_cnt: %d", g_PikaVMSignal.event_pickup_cnt);
Arg* res =
__eventListener_runEvent(event_lisener, event_id, event_data);
g_PikaVMSignal.cq.res[head] = res;
g_PikaVMSignal.event_pickup_cnt--;
g_PikaVMState.cq.res[head] = res;
g_PikaVMState.event_pickup_cnt--;
}
#endif
}
VM_SIGNAL_CTRL VMSignal_getCtrl(void) {
return g_PikaVMSignal.signal_ctrl;
return g_PikaVMState.signal_ctrl;
}
void pika_vm_exit(void) {
g_PikaVMSignal.signal_ctrl = VM_SIGNAL_CTRL_EXIT;
g_PikaVMState.signal_ctrl = VM_SIGNAL_CTRL_EXIT;
}
void pika_vm_exit_await(void) {
@ -333,7 +335,7 @@ void pika_vm_exit_await(void) {
}
void pika_vmSignal_setCtrlClear(void) {
g_PikaVMSignal.signal_ctrl = VM_SIGNAL_CTRL_NONE;
g_PikaVMState.signal_ctrl = VM_SIGNAL_CTRL_NONE;
}
/* head declare start */
@ -401,6 +403,21 @@ static int PikaVMFrame_getInvokeDeepthNow(PikaVMFrame* vm) {
return instructUnit_getInvokeDeepth(ins_unit);
}
pika_bool PikaVMFrame_checkBreakPoint(PikaVMFrame* vm) {
#if !PIKA_DEBUG_BREAK_POINT_MAX
return pika_false;
#else
if (g_PikaVMState.break_point_cnt == 0) {
return pika_false;
}
if (NULL == vm->bytecode_frame->name) {
return pika_false;
}
Hash module_hash = byteCodeFrame_getNameHash(vm->bytecode_frame);
return pika_debug_check_break_hash(module_hash, vm->pc);
#endif
}
static int32_t PikaVMFrame_getAddrOffsetOfJmpBack(PikaVMFrame* vm) {
int offset = 0;
int blockDeepthGot = -1;
@ -731,9 +748,9 @@ Arg* _vm_get(PikaVMFrame* vm, PikaObj* self, Arg* aKey, Arg* aObj) {
0x73, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x00, /* const pool */
};
if (NULL != vm) {
aRes = _do_pikaVM_runByteCodeReturn(oArg, oArg, oArg,
(uint8_t*)bytes, vm->vm_thread,
pika_true, "@res_item");
aRes = pikaVM_runByteCode_exReturn(oArg, oArg, oArg,
(uint8_t*)bytes, vm->vm_thread,
pika_true, "@res_item");
} else {
aRes = pikaVM_runByteCodeReturn(oArg, (uint8_t*)bytes, "@res_item");
}
@ -1811,6 +1828,13 @@ InstructUnit* byteCodeFrame_findInsForward(ByteCodeFrame* bcframe,
pika_true);
}
Hash byteCodeFrame_getNameHash(ByteCodeFrame* bcframe) {
if (0 == bcframe->name_hash) {
bcframe->name_hash = hash_time33(bcframe->name);
}
return bcframe->name_hash;
}
InstructUnit* byteCodeFrame_findInsUnitBackward(ByteCodeFrame* bcframe,
int32_t pc_start,
enum InstructIndex index,
@ -3565,6 +3589,70 @@ const VM_instruct_handler VM_instruct_handler_table[__INSTRUCTION_CNT] = {
};
#endif
extern volatile PikaObj* __pikaMain;
static enum shellCTRL __obj_shellLineHandler_debug(PikaObj* self,
char* input_line,
struct ShellConfig* config) {
/* continue */
if (strEqu("c", input_line)) {
return SHELL_CTRL_EXIT;
}
/* next */
if (strEqu("n", input_line)) {
return SHELL_CTRL_EXIT;
}
/* launch shell */
if (strEqu("sh", input_line)) {
/* exit pika shell */
pikaScriptShell((PikaObj*)__pikaMain);
return SHELL_CTRL_CONTINUE;
}
/* quit */
if (strEqu("q", input_line)) {
obj_setInt(self, "enable", 0);
return SHELL_CTRL_EXIT;
}
/* print */
if (strIsStartWith(input_line, "p ")) {
char* path = input_line + 2;
Arg* asm_buff = arg_newStr("print(");
asm_buff = arg_strAppend(asm_buff, path);
asm_buff = arg_strAppend(asm_buff, ")\n");
pikaVM_run_ex_cfg cfg = {0};
cfg.globals = config->globals;
cfg.in_repl = pika_true;
pikaVM_run_ex(config->locals, arg_getStr(asm_buff), &cfg);
arg_deinit(asm_buff);
return SHELL_CTRL_CONTINUE;
}
pikaVM_run_ex_cfg cfg = {0};
cfg.globals = config->globals;
cfg.in_repl = pika_true;
pikaVM_run_ex(config->locals, input_line, &cfg);
return SHELL_CTRL_CONTINUE;
}
void pika_debug_set_trace(PikaObj* self) {
if (!obj_getInt(self, "enable")) {
return;
}
char* name = "stdin";
pika_assert(NULL != self->vmFrame);
if (NULL != self->vmFrame->bytecode_frame->name) {
name = self->vmFrame->bytecode_frame->name;
}
pika_platform_printf("%s:%d\n", name, self->vmFrame->pc);
struct ShellConfig cfg = {
.prefix = "(Pdb-pika) ",
.handler = __obj_shellLineHandler_debug,
.fn_getchar = __platform_getchar,
.locals = self->vmFrame->locals,
.globals = self->vmFrame->globals,
};
_do_pikaScriptShell(self, &cfg);
shConfig_deinit(&cfg);
}
static int pikaVM_runInstructUnit(PikaObj* self,
PikaVMFrame* vm,
InstructUnit* ins_unit) {
@ -3576,6 +3664,9 @@ static int pikaVM_runInstructUnit(PikaObj* self,
char* data = PikaVMFrame_getConstWithInstructUnit(vm, ins_unit);
/* run instruct */
pika_assert(NULL != vm->vm_thread);
if (PikaVMFrame_checkBreakPoint(vm)) {
pika_debug_set_trace(self);
}
#if PIKA_INSTRUCT_EXTENSION_ENABLE
const VMInstruction* ins = instructUnit_getInstruct(instruct);
@ -3751,14 +3842,16 @@ static ByteCodeFrame* _cache_bcf_fn_bc(PikaObj* self, uint8_t* bytecode) {
return _cache_bytecodeframe(self);
}
VMParameters* _pikaVM_runPyLines(PikaObj* self,
char* py_lines,
pika_bool in_repl) {
VMParameters* globals = NULL;
VMParameters* pikaVM_run_ex(PikaObj* self,
char* py_lines,
pikaVM_run_ex_cfg* cfg) {
ByteCodeFrame bytecode_frame_stack = {0};
ByteCodeFrame* bytecode_frame_p = NULL;
uint8_t is_use_heap_bytecode = 0;
PikaObj* globals = self;
if (NULL != cfg->globals) {
globals = cfg->globals;
}
/*
* the first obj_run, cache bytecode to heap, to support 'def' and
* 'class'
@ -3779,7 +3872,11 @@ VMParameters* _pikaVM_runPyLines(PikaObj* self,
goto __exit;
}
/* run byteCode */
globals = _pikaVM_runByteCodeFrame(self, bytecode_frame_p, in_repl);
if (NULL != cfg->module_name) {
byteCodeFrame_setName(bytecode_frame_p, cfg->module_name);
}
globals = _pikaVM_runByteCodeFrameGlobals(self, globals, bytecode_frame_p,
cfg->in_repl);
goto __exit;
__exit:
if (!is_use_heap_bytecode) {
@ -3788,12 +3885,9 @@ __exit:
return globals;
}
VMParameters* _do_pikaVM_runByteCode(PikaObj* self,
VMParameters* locals,
VMParameters* globals,
uint8_t* bytecode,
PikaVMThread* vm_thread,
pika_bool is_const_bytecode) {
VMParameters* pikaVM_runByteCode_ex(PikaObj* self,
uint8_t* bytecode,
pikaVM_runBytecode_ex_cfg* cfg) {
ByteCodeFrame bytecode_frame_stack = {0};
ByteCodeFrame* bytecode_frame_p = NULL;
uint8_t is_use_heap_bytecode = 1;
@ -3807,24 +3901,24 @@ VMParameters* _do_pikaVM_runByteCode(PikaObj* self,
/* get bytecode_ptr from stack */
bytecode_frame_p = &bytecode_frame_stack;
/* no def/class ins, no need cache bytecode */
is_const_bytecode = pika_true;
cfg->is_const_bytecode = pika_true;
}
/* load or generate byte code frame */
/* load bytecode */
_do_byteCodeFrame_loadByteCode(bytecode_frame_p, bytecode,
is_const_bytecode);
_do_byteCodeFrame_loadByteCode(bytecode_frame_p, bytecode, cfg->name,
cfg->is_const_bytecode);
/* run byteCode */
globals = _pikaVM_runByteCodeFrameWithState(self, locals, globals,
bytecode_frame_p, 0, vm_thread);
cfg->globals = _pikaVM_runByteCodeFrameWithState(
self, cfg->locals, cfg->globals, bytecode_frame_p, 0, cfg->vm_thread);
goto __exit;
__exit:
if (!is_use_heap_bytecode) {
byteCodeFrame_deinit(&bytecode_frame_stack);
}
return globals;
return cfg->globals;
}
VMParameters* pikaVM_runByteCodeFile(PikaObj* self, char* filename) {
@ -3852,21 +3946,33 @@ VMParameters* pikaVM_runSingleFile(PikaObj* self, char* filename) {
char* lines = (char*)arg_getBytes(file_arg);
lines = strsFilePreProcess(&buffs, lines);
/* clear the void line */
VMParameters* res = pikaVM_run(self, lines);
pikaVM_run_ex_cfg cfg = {0};
cfg.in_repl = pika_false;
char* module_name = strsPathGetFileName(&buffs, filename);
module_name = strsPopToken(&buffs, &module_name, '.');
cfg.module_name = module_name;
VMParameters* res = pikaVM_run_ex(self, lines, &cfg);
arg_deinit(file_arg);
strsDeinit(&buffs);
return res;
}
VMParameters* pikaVM_run(PikaObj* self, char* py_lines) {
return _pikaVM_runPyLines(self, py_lines, pika_false);
pikaVM_run_ex_cfg cfg = {0};
cfg.in_repl = pika_false;
return pikaVM_run_ex(self, py_lines, &cfg);
}
VMParameters* pikaVM_runByteCode(PikaObj* self, const uint8_t* bytecode) {
PikaVMThread vm_thread = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
return _do_pikaVM_runByteCode(self, self, self, (uint8_t*)bytecode,
&vm_thread, pika_true);
pikaVM_runBytecode_ex_cfg cfg = {0};
cfg.locals = self;
cfg.globals = self;
cfg.name = NULL;
cfg.vm_thread = &vm_thread;
cfg.is_const_bytecode = pika_true;
return pikaVM_runByteCode_ex(self, (uint8_t*)bytecode, &cfg);
}
Arg* pikaVM_runByteCodeReturn(PikaObj* self,
@ -3884,15 +3990,19 @@ Arg* pikaVM_runByteCodeReturn(PikaObj* self,
return ret;
}
Arg* _do_pikaVM_runByteCodeReturn(PikaObj* self,
VMParameters* locals,
VMParameters* globals,
uint8_t* bytecode,
PikaVMThread* vm_thread,
pika_bool is_const_bytecode,
char* return_name) {
_do_pikaVM_runByteCode(self, locals, globals, bytecode, vm_thread,
is_const_bytecode);
Arg* pikaVM_runByteCode_exReturn(PikaObj* self,
VMParameters* locals,
VMParameters* globals,
uint8_t* bytecode,
PikaVMThread* vm_thread,
pika_bool is_const_bytecode,
char* return_name) {
pikaVM_runBytecode_ex_cfg cfg = {0};
cfg.locals = locals;
cfg.globals = globals;
cfg.vm_thread = vm_thread;
cfg.is_const_bytecode = is_const_bytecode;
pikaVM_runByteCode_ex(self, bytecode, &cfg);
Arg* ret = args_getArg(self->list, return_name);
if (NULL == ret) {
return NULL;
@ -3907,8 +4017,12 @@ Arg* _do_pikaVM_runByteCodeReturn(PikaObj* self,
VMParameters* pikaVM_runByteCodeInconstant(PikaObj* self, uint8_t* bytecode) {
PikaVMThread vm_thread = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
return _do_pikaVM_runByteCode(self, self, self, (uint8_t*)bytecode,
&vm_thread, pika_false);
pikaVM_runBytecode_ex_cfg cfg = {0};
cfg.locals = self;
cfg.globals = self;
cfg.vm_thread = &vm_thread;
cfg.is_const_bytecode = pika_false;
return pikaVM_runByteCode_ex(self, (uint8_t*)bytecode, &cfg);
}
void constPool_update(ConstPool* self) {
@ -4017,11 +4131,14 @@ void byteCodeFrame_init(ByteCodeFrame* self) {
can not init */
constPool_init(&(self->const_pool));
instructArray_init(&(self->instruct_array));
self->name = NULL;
self->label_pc = -1;
}
extern const char magic_code_pyo[4];
void _do_byteCodeFrame_loadByteCode(ByteCodeFrame* self,
uint8_t* bytes,
char* name,
pika_bool is_const) {
if (bytes[0] == magic_code_pyo[0] && bytes[1] == magic_code_pyo[1] &&
bytes[2] == magic_code_pyo[2] && bytes[3] == magic_code_pyo[3]) {
@ -4037,6 +4154,7 @@ void _do_byteCodeFrame_loadByteCode(ByteCodeFrame* self,
self->const_pool.size = *const_size_p;
self->const_pool.content_start =
(char*)((uintptr_t)const_size_p + sizeof(*const_size_p));
byteCodeFrame_setName(self, name);
if (!is_const) {
pika_assert(NULL == self->instruct_array.arg_buff);
pika_assert(NULL == self->instruct_array.arg_buff);
@ -4051,13 +4169,23 @@ void _do_byteCodeFrame_loadByteCode(ByteCodeFrame* self,
pika_assert(NULL != self->const_pool.content_start);
}
void byteCodeFrame_setName(ByteCodeFrame* self, char* name) {
if (name != NULL && self->name == NULL) {
self->name = pika_platform_malloc(strGetSize(name) + 1);
pika_platform_memcpy(self->name, name, strGetSize(name) + 1);
}
}
void byteCodeFrame_loadByteCode(ByteCodeFrame* self, uint8_t* bytes) {
_do_byteCodeFrame_loadByteCode(self, bytes, pika_true);
_do_byteCodeFrame_loadByteCode(self, bytes, NULL, pika_true);
}
void byteCodeFrame_deinit(ByteCodeFrame* self) {
constPool_deinit(&(self->const_pool));
instructArray_deinit(&(self->instruct_array));
if (NULL != self->name) {
pika_platform_free(self->name);
}
}
void instructArray_init(InstructArray* self) {
@ -4313,13 +4441,13 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
int size = bytecode_frame->instruct_array.size;
/* locals is the local scope */
if (g_PikaVMSignal.vm_cnt == 0) {
if (g_PikaVMState.vm_cnt == 0) {
pika_vmSignal_setCtrlClear();
}
PikaVMFrame* vm =
PikaVMFrame_create(locals, globals, bytecode_frame, pc, vm_thread);
vm->in_repl = in_repl;
g_PikaVMSignal.vm_cnt++;
g_PikaVMState.vm_cnt++;
while (vm->pc < size) {
if (vm->pc == VM_PC_EXIT) {
break;
@ -4332,6 +4460,7 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
vm->vm_thread->error_code = 0;
vm->vm_thread->line_error_code = 0;
}
self->vmFrame = vm;
vm->pc = pikaVM_runInstructUnit(self, vm, this_ins_unit);
vm->ins_cnt++;
#if PIKA_INSTRUCT_HOOK_ENABLE
@ -4376,12 +4505,71 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
}
PikaVMFrame_solveUnusedStack(vm);
stack_deinit(&(vm->stack));
g_PikaVMSignal.vm_cnt--;
g_PikaVMState.vm_cnt--;
VMParameters* result = locals;
pikaFree(vm, sizeof(PikaVMFrame));
self->vmFrame = NULL;
return result;
}
pika_bool pika_debug_check_break(char* module_name, int pc_break) {
Hash h = hash_time33(module_name);
for (int i = 0; i < g_PikaVMState.break_point_cnt; i++) {
if (g_PikaVMState.break_module_hash[i] == h &&
g_PikaVMState.break_point_pc[i] == pc_break) {
return pika_true;
}
}
return pika_false;
}
pika_bool pika_debug_check_break_hash(Hash module_hash, int pc_break) {
for (int i = 0; i < g_PikaVMState.break_point_cnt; i++) {
if (g_PikaVMState.break_module_hash[i] == module_hash &&
g_PikaVMState.break_point_pc[i] == pc_break) {
return pika_true;
}
}
return pika_false;
}
PIKA_RES pika_debug_set_break(char* module_name, int pc_break) {
if (pika_debug_check_break(module_name, pc_break)) {
return PIKA_RES_OK;
}
if (g_PikaVMState.break_point_cnt >= PIKA_DEBUG_BREAK_POINT_MAX) {
return PIKA_RES_ERR_RUNTIME_ERROR;
}
Hash h = hash_time33(module_name);
g_PikaVMState.break_module_hash[g_PikaVMState.break_point_cnt] = h;
g_PikaVMState.break_point_pc[g_PikaVMState.break_point_cnt] = pc_break;
g_PikaVMState.break_point_cnt++;
return PIKA_RES_OK;
}
PIKA_RES pika_debug_reset_break(char* module_name, int pc_break) {
if (!pika_debug_check_break(module_name, pc_break)) {
return PIKA_RES_OK;
}
Hash h = hash_time33(module_name);
for (int i = 0; i < g_PikaVMState.break_point_cnt; i++) {
if (g_PikaVMState.break_module_hash[i] == h &&
g_PikaVMState.break_point_pc[i] == pc_break) {
// Move subsequent break points one position forward
for (int j = i; j < g_PikaVMState.break_point_cnt - 1; j++) {
g_PikaVMState.break_module_hash[j] =
g_PikaVMState.break_module_hash[j + 1];
g_PikaVMState.break_point_pc[j] =
g_PikaVMState.break_point_pc[j + 1];
}
// Decrease the count of break points
g_PikaVMState.break_point_cnt--;
return PIKA_RES_OK;
}
}
return PIKA_RES_ERR_RUNTIME_ERROR;
}
static VMParameters* _pikaVM_runByteCodeFrameWithState(
PikaObj* self,
VMParameters* locals,
@ -4402,6 +4590,16 @@ VMParameters* _pikaVM_runByteCodeFrame(PikaObj* self,
0, &vm_thread, in_repl);
}
VMParameters* _pikaVM_runByteCodeFrameGlobals(PikaObj* self,
PikaObj* globals,
ByteCodeFrame* byteCode_frame,
pika_bool in_repl) {
PikaVMThread vm_thread = {.try_state = TRY_STATE_NONE,
.try_result = TRY_RESULT_NONE};
return __pikaVM_runByteCodeFrameWithState(
self, self, globals, byteCode_frame, 0, &vm_thread, in_repl);
}
VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame) {
return _pikaVM_runByteCodeFrame(self, byteCode_frame, pika_false);

View File

@ -95,8 +95,8 @@ typedef struct JmpBufCQ {
} JmpBufCQ;
#endif
typedef struct VMSignal VMSignal;
struct VMSignal {
typedef struct VMState VMState;
struct VMState {
VM_SIGNAL_CTRL signal_ctrl;
int vm_cnt;
#if PIKA_EVENT_ENABLE
@ -106,6 +106,11 @@ struct VMSignal {
pika_bool event_thread_exit;
pika_bool event_thread_exit_done;
#endif
#if PIKA_DEBUG_BREAK_POINT_MAX > 0
Hash break_module_hash[PIKA_DEBUG_BREAK_POINT_MAX];
uint32_t break_point_pc[PIKA_DEBUG_BREAK_POINT_MAX];
int break_point_cnt;
#endif
};
typedef Arg* (*VM_instruct_handler)(PikaObj* self,
@ -136,6 +141,10 @@ VMParameters* pikaVM_runAsm(PikaObj* self, char* pikaAsm);
VMParameters* _pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame,
pika_bool in_repl);
VMParameters* _pikaVM_runByteCodeFrameGlobals(PikaObj* self,
PikaObj* globals,
ByteCodeFrame* byteCode_frame,
pika_bool in_repl);
VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
ByteCodeFrame* byteCode_frame);
@ -208,6 +217,14 @@ static inline char* PikaVMFrame_getConstWithInstructUnit(
instructUnit_getConstPoolIndex(ins_unit));
}
pika_bool PikaVMFrame_checkBreakPoint(PikaVMFrame* vm);
typedef struct {
PikaObj* globals;
pika_bool in_repl;
char* module_name;
} pikaVM_run_ex_cfg;
char* constPool_getNow(ConstPool* self);
char* constPool_getNext(ConstPool* self);
char* constPool_getByIndex(ConstPool* self, uint16_t index);
@ -215,6 +232,7 @@ void constPool_print(ConstPool* self);
void byteCodeFrame_init(ByteCodeFrame* bf);
void byteCodeFrame_deinit(ByteCodeFrame* bf);
void byteCodeFrame_setName(ByteCodeFrame* self, char* name);
size_t byteCodeFrame_getSize(ByteCodeFrame* bf);
InstructUnit* byteCodeFrame_findInstructUnit(ByteCodeFrame* bcframe,
int32_t iPcStart,
@ -229,6 +247,7 @@ InstructUnit* byteCodeFrame_findInsForward(ByteCodeFrame* bcframe,
int32_t pc_start,
enum InstructIndex index,
int32_t* p_offset);
Hash byteCodeFrame_getNameHash(ByteCodeFrame* bcframe);
void instructArray_init(InstructArray* ins_array);
void instructArray_deinit(InstructArray* ins_array);
void instructArray_append(InstructArray* ins_array, InstructUnit* ins_unit);
@ -287,13 +306,13 @@ VMParameters* pikaVM_runByteCodeInconstant(PikaObj* self, uint8_t* bytecode);
Arg* pikaVM_runByteCodeReturn(PikaObj* self,
const uint8_t* bytecode,
char* returnName);
Arg* _do_pikaVM_runByteCodeReturn(PikaObj* self,
VMParameters* locals,
VMParameters* globals,
uint8_t* bytecode,
PikaVMThread* vm_thread,
pika_bool is_const_bytecode,
char* return_name);
Arg* pikaVM_runByteCode_exReturn(PikaObj* self,
VMParameters* locals,
VMParameters* globals,
uint8_t* bytecode,
PikaVMThread* vm_thread,
pika_bool is_const_bytecode,
char* return_name);
InstructUnit* instructArray_getNow(InstructArray* self);
InstructUnit* instructArray_getNext(InstructArray* self);
VMParameters* pikaVM_runSingleFile(PikaObj* self, char* filename);
@ -306,14 +325,22 @@ Arg* _vm_slice(PikaVMFrame* vm,
Arg* obj,
Arg* start,
int step);
VMParameters* _do_pikaVM_runByteCode(PikaObj* self,
VMParameters* locals,
VMParameters* globals,
uint8_t* bytecode,
PikaVMThread* vm_thread,
pika_bool is_const_bytecode);
typedef struct {
VMParameters* locals;
VMParameters* globals;
char* name;
PikaVMThread* vm_thread;
pika_bool is_const_bytecode;
} pikaVM_runBytecode_ex_cfg;
VMParameters* pikaVM_runByteCode_ex(PikaObj* self,
uint8_t* bytecode,
pikaVM_runBytecode_ex_cfg* cfg);
void _do_byteCodeFrame_loadByteCode(ByteCodeFrame* self,
uint8_t* bytes,
char* name,
pika_bool is_const);
Arg* _vm_get(PikaVMFrame* vm, PikaObj* self, Arg* key, Arg* obj);
VM_SIGNAL_CTRL VMSignal_getCtrl(void);
@ -332,6 +359,11 @@ void __VMEvent_pickupEvent(char* info);
void _pikaVM_yield(void);
int _VM_lock_init(void);
int _VM_is_first_lock(void);
PIKA_RES pika_debug_set_break(char* module_name, int pc_break);
void pika_debug_set_trace(PikaObj* self);
PIKA_RES pika_debug_reset_break(char* module_name, int pc_break);
pika_bool pika_debug_check_break_hash(Hash module_hash, int pc_break);
pika_bool pika_debug_check_break(char* module_name, int pc_break);
#define _VMEvent_pickupEvent() __VMEvent_pickupEvent(__FILE__)
@ -339,9 +371,9 @@ typedef struct {
PikaObj* lreg[PIKA_REGIST_SIZE];
} VMLocals;
VMParameters* _pikaVM_runPyLines(PikaObj* self,
char* py_lines,
pika_bool in_repl);
VMParameters* pikaVM_run_ex(PikaObj* self,
char* py_lines,
pikaVM_run_ex_cfg* cfg);
#endif

View File

@ -2,4 +2,4 @@
#define PIKA_VERSION_MINOR 12
#define PIKA_VERSION_MICRO 6
#define PIKA_EDIT_TIME "2023/09/27 22:21:23"
#define PIKA_EDIT_TIME "2023/09/30 00:30:20"

View File

@ -290,6 +290,10 @@ extern "C" {
#define PIKA_DEBUG_ENABLE 0
#endif
#ifndef PIKA_DEBUG_BREAK_POINT_MAX
#define PIKA_DEBUG_BREAK_POINT_MAX 8
#endif
#ifndef PIKA_FILEIO_ENABLE
#define PIKA_FILEIO_ENABLE 1
#endif

View File

@ -40,7 +40,7 @@ void PikaStdData_List___init__(PikaObj *self) {}
void PikaStdData_List_append(PikaObj *self, Arg *arg) {}
void PikaStdData_Dict___init__(PikaObj *self) {}
void PikaStdData_Dict_set(PikaObj *self, char *key, Arg *val) {}
PikaObj *New_builtins_object(Args *args){return NULL;};
PikaObj *New_builtins_object(Args *args) { return NULL; };
PikaObj *New_PikaStdLib_SysObj(Args *args) { return NULL; };
PikaObj *New_builtins(Args *args) { return NULL; };
PikaObj *New_builtins_RangeObj(Args *args) { return NULL; }
@ -50,6 +50,23 @@ char *string_slice(Args *outBuffs, char *str, int start, int end) {
}
int PikaStdData_FILEIO_init(PikaObj *self, char *path, char *mode) { return 0; }
static int handle_breakpoint_option(int argc, char **argv, int i) {
if (0 == strcmp(argv[i], "--break-point")) {
if (i + 2 < argc) {
uint32_t pc =
pika_debug_find_break_point_pc(argv[i + 1], atoi(argv[i + 2]));
// printf("break point pc: %d\r\n", pc);
/* json output */
printf("{\"pc\":%d}\r\n", pc);
return 0;
} else {
printf("Invalid --break-point option usage.\n");
return -1;
}
}
return -1;
}
static int _do_main(int argc, char **argv) {
int parc = argc - 1;
PikaMaker *maker = New_PikaMaker();
@ -68,6 +85,11 @@ static int _do_main(int argc, char **argv) {
/* delete --xxx yyy */
for (int i = 1; i < argc; i++) {
int res = handle_breakpoint_option(argc, argv, i);
if (0 == res) {
return 0;
}
if (0 == strcmp(argv[i], "--add-file")) {
// printf("before delete: %d\r\n", parc);
// for (int j = 0; j < parc; j++) {