mirror of
https://gitee.com/Lyon1998/pikapython.git
synced 2025-01-29 17:22:56 +08:00
Merge branch 'master' of https://gitee.com/xie-jc/pikapython
This commit is contained in:
commit
acb8bdbef8
8
examples/builtins/pdb_set_break.py
Normal file
8
examples/builtins/pdb_set_break.py
Normal 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')
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
3
port/linux/.vscode/launch.json
vendored
3
port/linux/.vscode/launch.json
vendored
@ -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}",
|
||||
|
2
port/linux/.vscode/settings.json
vendored
2
port/linux/.vscode/settings.json
vendored
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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')
|
||||
|
8
port/linux/test/python/builtins/pdb_set_break.py
Normal file
8
port/linux/test/python/builtins/pdb_set_break.py
Normal 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')
|
117
src/PikaObj.c
117
src/PikaObj.c
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -103,6 +103,7 @@ struct Parser {
|
||||
pika_bool isGenBytecode;
|
||||
ByteCodeFrame* bytecode_frame;
|
||||
uint8_t thisBlockDeepth;
|
||||
uint32_t label_pc;
|
||||
};
|
||||
|
||||
typedef struct LexToken LexToken;
|
||||
|
380
src/PikaVM.c
380
src/PikaVM.c
@ -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);
|
||||
|
68
src/PikaVM.h
68
src/PikaVM.h
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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++) {
|
||||
|
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user