Skip to content

Commit 8acef2e

Browse files
committed
support pks_vm_exit()
1 parent 1019f30 commit 8acef2e

File tree

8 files changed

+126
-17
lines changed

8 files changed

+126
-17
lines changed

package/PikaStdLib/PikaStdLib.pyi

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from PikaObj import *
22

3+
34
class MemChecker:
45
def max(self): ...
56
def now(self): ...
@@ -102,6 +103,10 @@ class SysObj:
102103
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
103104
def setattr(obj: object, name: str, val: any): ...
104105

106+
@staticmethod
107+
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
108+
def exit(): ...
109+
105110

106111
@PIKA_C_MACRO_IF("0")
107112
class RangeObj:
@@ -111,4 +116,3 @@ class RangeObj:
111116
@PIKA_C_MACRO_IF("0")
112117
class StringObj:
113118
def __next__(self) -> any: ...
114-

package/PikaStdLib/PikaStdLib_SysObj.c

+4
Original file line numberDiff line numberDiff line change
@@ -538,3 +538,7 @@ void PikaStdLib_SysObj_setattr(PikaObj* self,
538538
exit:
539539
return;
540540
}
541+
542+
void PikaStdLib_SysObj_exit(PikaObj *self){
543+
pks_vm_exit();
544+
}

port/linux/package/pikascript/PikaStdLib.pyi

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from PikaObj import *
22

3+
34
class MemChecker:
45
def max(self): ...
56
def now(self): ...
@@ -102,6 +103,10 @@ class SysObj:
102103
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
103104
def setattr(obj: object, name: str, val: any): ...
104105

106+
@staticmethod
107+
@PIKA_C_MACRO_IF("!PIKA_NANO_ENABLE")
108+
def exit(): ...
109+
105110

106111
@PIKA_C_MACRO_IF("0")
107112
class RangeObj:
@@ -111,4 +116,3 @@ class RangeObj:
111116
@PIKA_C_MACRO_IF("0")
112117
class StringObj:
113118
def __next__(self) -> any: ...
114-

port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdLib_SysObj.c

+4
Original file line numberDiff line numberDiff line change
@@ -538,3 +538,7 @@ void PikaStdLib_SysObj_setattr(PikaObj* self,
538538
exit:
539539
return;
540540
}
541+
542+
void PikaStdLib_SysObj_exit(PikaObj *self){
543+
pks_vm_exit();
544+
}

port/linux/test/VM-test.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -1612,3 +1612,57 @@ TEST(vm, test64) {
16121612
obj_deinit(pikaMain);
16131613
EXPECT_EQ(pikaMemNow(), 0);
16141614
}
1615+
1616+
#if !PIKA_NANO_ENABLE
1617+
TEST(vm, exit) {
1618+
/* init */
1619+
pikaMemInfo.heapUsedMax = 0;
1620+
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
1621+
extern unsigned char pikaModules_py_a[];
1622+
obj_linkLibrary(pikaMain, pikaModules_py_a);
1623+
/* run */
1624+
__platform_printf("BEGIN\r\n");
1625+
obj_run(pikaMain,
1626+
"i = 0\n"
1627+
"while True:\n"
1628+
" i += 1\n"
1629+
" print(i)\n"
1630+
" if i == 10:\n"
1631+
" exit()\n");
1632+
/* collect */
1633+
int i = obj_getInt(pikaMain, "i");
1634+
/* assert */
1635+
EXPECT_EQ(i, 10);
1636+
/* deinit */
1637+
obj_deinit(pikaMain);
1638+
EXPECT_EQ(pikaMemNow(), 0);
1639+
}
1640+
1641+
TEST(vm, exit_fn) {
1642+
/* init */
1643+
pikaMemInfo.heapUsedMax = 0;
1644+
PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
1645+
extern unsigned char pikaModules_py_a[];
1646+
obj_linkLibrary(pikaMain, pikaModules_py_a);
1647+
/* run */
1648+
__platform_printf("BEGIN\r\n");
1649+
obj_run(pikaMain,
1650+
"i = 0\n"
1651+
"def test():\n"
1652+
" global i\n"
1653+
" while True:\n"
1654+
" i += 1\n"
1655+
" print(i)\n"
1656+
" if i == 10:\n"
1657+
" exit()\n"
1658+
"while True:\n"
1659+
" test()\n");
1660+
/* collect */
1661+
int i = obj_getInt(pikaMain, "i");
1662+
/* assert */
1663+
EXPECT_EQ(i, 10);
1664+
/* deinit */
1665+
obj_deinit(pikaMain);
1666+
EXPECT_EQ(pikaMemNow(), 0);
1667+
}
1668+
#endif

src/PikaVM.c

+39-14
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,23 @@
3636
#include <math.h>
3737
#endif
3838

39+
static volatile VMSignal PikaVMSignal = {
40+
.signal_ctrl = VM_SIGNAL_CTRL_NONE,
41+
.vm_cnt = 0,
42+
};
43+
44+
VM_SIGNAL_CTRL VMSignal_getCtrl(void) {
45+
return PikaVMSignal.signal_ctrl;
46+
}
47+
48+
void pks_vm_exit(void) {
49+
PikaVMSignal.signal_ctrl = VM_SIGNAL_CTRL_EXIT;
50+
}
51+
52+
void pks_vmSignal_setCtrlElear(void) {
53+
PikaVMSignal.signal_ctrl = VM_SIGNAL_CTRL_NONE;
54+
}
55+
3956
/* head declare start */
4057
static uint8_t VMState_getInputArgNum(VMState* vm);
4158
static VMParameters* __pikaVM_runByteCodeFrameWithState(
@@ -1009,35 +1026,35 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
10091026
goto exit;
10101027
}
10111028

1012-
#if !PIKA_NANO_ENABLE
1029+
#if !PIKA_NANO_ENABLE
10131030
/* support for super() */
10141031
if (strEqu(run_path, "super")) {
10151032
run_path = _find_super_class_name(vm);
10161033
vm->in_super = 1;
10171034
skip_init = 1;
10181035
}
1019-
#endif
1036+
#endif
10201037

10211038
/* return tiny obj */
10221039
if (strEqu(run_path, "TinyObj")) {
10231040
return_arg = arg_newMetaObj(New_TinyObj);
10241041
goto exit;
10251042
}
10261043

1027-
#if !PIKA_NANO_ENABLE
1044+
#if !PIKA_NANO_ENABLE
10281045
if (!skip_init && vm->in_super) {
10291046
vm->in_super = PIKA_FALSE;
10301047
obj_this = obj_getPtr(vm->locals, _find_self_name(vm));
10311048
}
1032-
#endif
1049+
#endif
10331050

10341051
/* get method host obj from reg */
10351052
if (NULL == method_host && _checkLReg(run_path)) {
10361053
uint8_t reg_index = _getLRegIndex(run_path);
10371054
method_host = vm->lreg[reg_index];
10381055
}
10391056

1040-
#if !PIKA_NANO_ENABLE
1057+
#if !PIKA_NANO_ENABLE
10411058
/* get method host obj from stack */
10421059
if (NULL == method_host && run_path[0] == '.') {
10431060
/* get method host obj from stack */
@@ -1063,7 +1080,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self,
10631080
stack_pushArg(&(vm->stack), stack_tmp[i]);
10641081
}
10651082
}
1066-
#endif
1083+
#endif
10671084

10681085
/* get method host obj from self */
10691086
if (NULL == method_host) {
@@ -1978,9 +1995,9 @@ static Arg* VM_instruction_handler_RIS(PikaObj* self,
19781995
VMState* vm,
19791996
char* data,
19801997
Arg* arg_ret_reg) {
1981-
#if PIKA_NANO_ENABLE
1998+
#if PIKA_NANO_ENABLE
19821999
return NULL;
1983-
#endif
2000+
#endif
19842001
Arg* err_arg = stack_popArg_alloc(&(vm->stack));
19852002
PIKA_RES err = (PIKA_RES)arg_getInt(err_arg);
19862003
VMState_setErrorCode(vm, err);
@@ -1992,9 +2009,9 @@ static Arg* VM_instruction_handler_ASS(PikaObj* self,
19922009
VMState* vm,
19932010
char* data,
19942011
Arg* arg_ret_reg) {
1995-
#if PIKA_NANO_ENABLE
2012+
#if PIKA_NANO_ENABLE
19962013
return NULL;
1997-
#endif
2014+
#endif
19982015
arg_newReg(reg1, PIKA_ARG_BUFF_SIZE);
19992016
arg_newReg(reg2, PIKA_ARG_BUFF_SIZE);
20002017
Arg* arg1 = NULL;
@@ -2169,7 +2186,7 @@ static int pikaVM_runInstructUnit(PikaObj* self,
21692186
/* raise jmp */
21702187
if (vm->run_state->try_state == TRY_STATE_INNER) {
21712188
vm->jmp = VM_JMP_RAISE;
2172-
}else{
2189+
} else {
21732190
/* exit */
21742191
vm->jmp = VM_JMP_EXIT;
21752192
}
@@ -2195,8 +2212,8 @@ static int pikaVM_runInstructUnit(PikaObj* self,
21952212
pc_next = vm->pc + VMState_getAddrOffsetOfContinue(vm);
21962213
goto exit;
21972214
}
2198-
/* raise */
2199-
#if !PIKA_NANO_ENABLE
2215+
/* raise */
2216+
#if !PIKA_NANO_ENABLE
22002217
if (VM_JMP_RAISE == vm->jmp) {
22012218
int offset = VMState_getAddrOffsetOfRaise(vm);
22022219
if (0 == offset) {
@@ -2208,7 +2225,7 @@ static int pikaVM_runInstructUnit(PikaObj* self,
22082225
pc_next = vm->pc + offset;
22092226
goto exit;
22102227
}
2211-
#endif
2228+
#endif
22122229
/* static jmp */
22132230
if (vm->jmp != 0) {
22142231
pc_next = vm->pc + VMState_getAddrOffsetFromJmp(vm);
@@ -2668,7 +2685,14 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
26682685
};
26692686
stack_init(&(vm.stack));
26702687
VMState_initReg(&vm);
2688+
if (PikaVMSignal.vm_cnt == 0) {
2689+
pks_vmSignal_setCtrlElear();
2690+
}
2691+
PikaVMSignal.vm_cnt++;
26712692
while (vm.pc < size) {
2693+
if (VMSignal_getCtrl() == VM_SIGNAL_CTRL_EXIT) {
2694+
vm.pc = VM_PC_EXIT;
2695+
}
26722696
if (vm.pc == VM_PC_EXIT) {
26732697
break;
26742698
}
@@ -2721,6 +2745,7 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState(
27212745
}
27222746
VMState_solveUnusedStack(&vm);
27232747
stack_deinit(&(vm.stack));
2748+
PikaVMSignal.vm_cnt--;
27242749
return locals;
27252750
}
27262751

src/PikaVM.h

+14
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,17 @@ struct OperatorInfo {
9898
VMState* vm;
9999
};
100100

101+
typedef enum VM_SIGNAL_CTRL {
102+
VM_SIGNAL_CTRL_NONE = 0,
103+
VM_SIGNAL_CTRL_EXIT,
104+
} VM_SIGNAL_CTRL;
105+
106+
typedef struct VMSignal VMSignal;
107+
struct VMSignal {
108+
VM_SIGNAL_CTRL signal_ctrl;
109+
int vm_cnt;
110+
};
111+
101112
VMParameters* pikaVM_run(PikaObj* self, char* pyLine);
102113
VMParameters* pikaVM_runAsm(PikaObj* self, char* pikaAsm);
103114
VMParameters* pikaVM_runByteCodeFrame(PikaObj* self,
@@ -193,5 +204,8 @@ void __vm_List_append(PikaObj* self, Arg* arg);
193204
void __vm_List___init__(PikaObj* self);
194205
void __vm_Dict_set(PikaObj* self, Arg* arg, char* key);
195206
void __vm_Dict___init__(PikaObj* self);
207+
VM_SIGNAL_CTRL VMSignal_getCtrl(void);
208+
void pks_vm_exit(void);
209+
void pks_vmSignal_setCtrlElear(void);
196210

197211
#endif

src/dataMemory.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
#include "dataMemory.h"
3030
#include "PikaPlatform.h"
3131

32-
PikaMemInfo pikaMemInfo = {0};
32+
volatile PikaMemInfo pikaMemInfo = {0};
3333

3434
void* pikaMalloc(uint32_t size) {
3535
/* pika memory lock */

0 commit comments

Comments
 (0)