diff --git a/examples/socket/socket_json.py b/examples/socket/socket_json.py index 6e8a74dfa..07c91bcfa 100644 --- a/examples/socket/socket_json.py +++ b/examples/socket/socket_json.py @@ -24,17 +24,18 @@ def socket_server_task(host, port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, port)) s.listen(5) - print("socket server waiting accept") global server_started server_started = True - accept, addr = s.accept() - print("socket server accepted at", addr) while True: try: - data = accept.recv(1024) - print('socket server recv:', data.decode()) - # accept.send(data) - accept.send(json.dumps(test_data)) + print("socket server waiting accept") + accept, addr = s.accept() + print("socket server accepted at", addr) + while True: + data = accept.recv(1024) + print('socket server recv:', data.decode()) + # accept.send(data) + accept.send(json.dumps(test_data)) except Exception: print('socket server closing accept') accept.close() diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 64545a91a..6430b3457 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -11,7 +11,7 @@ "program": "${workspaceFolder}/build/test/pikascript_test", // "program": "${workspaceFolder}/build/boot/demo06-pikamain/pikascript_demo06-pikamain", "args": [ - // "--gtest_filter=parser.def_add" + "--gtest_filter=except.while_try_while" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/src/PikaVM.c b/src/PikaVM.c index 1a054413f..4e91e3f90 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -297,37 +297,44 @@ static int VMState_getInvokeDeepthNow(VMState* vm) { static int32_t VMState_getAddrOffsetOfJmpBack(VMState* vm) { int offset = 0; - int loop_deepth = -1; + int blockDeepthGot = -1; + int blockDeepthNow = VMState_getBlockDeepthNow(vm); /* find loop deepth */ while (1) { offset -= instructUnit_getSize(); - InstructUnit* ins_unit_now = + InstructUnit* insUnitThis = VMState_getInstructUnitWithOffset(vm, offset); - uint16_t invoke_deepth = instructUnit_getInvokeDeepth(ins_unit_now); - enum Instruct ins = instructUnit_getInstruct(ins_unit_now); - char* data = VMState_getConstWithInstructUnit(vm, ins_unit_now); - if ((0 == invoke_deepth) && (JEZ == ins) && data[0] == '2') { - InstructUnit* ins_unit_last = VMState_getInstructUnitWithOffset( + uint16_t invokeDeepth = instructUnit_getInvokeDeepth(insUnitThis); + enum Instruct ins = instructUnit_getInstruct(insUnitThis); + char* data = VMState_getConstWithInstructUnit(vm, insUnitThis); + if ((0 == invokeDeepth) && (JEZ == ins) && data[0] == '2') { + InstructUnit* insUnitLast = VMState_getInstructUnitWithOffset( vm, offset - instructUnit_getSize()); - enum Instruct ins_last = instructUnit_getInstruct(ins_unit_last); + enum Instruct insLast = instructUnit_getInstruct(insUnitLast); /* skip try stmt */ - if (GER != ins_last) { - loop_deepth = instructUnit_getBlockDeepth(ins_unit_now); - break; + if (GER == insLast) { + continue; } + /* skip inner break */ + int blockDeepthThis = instructUnit_getBlockDeepth(insUnitThis); + if (blockDeepthThis >= blockDeepthNow) { + continue; + } + blockDeepthGot = instructUnit_getBlockDeepth(insUnitThis); + break; } } offset = 0; while (1) { offset += instructUnit_getSize(); - InstructUnit* ins_unit_now = + InstructUnit* insUnitThis = VMState_getInstructUnitWithOffset(vm, offset); - enum Instruct ins = instructUnit_getInstruct(ins_unit_now); - char* data = VMState_getConstWithInstructUnit(vm, ins_unit_now); - int block_deepth_now = instructUnit_getBlockDeepth(ins_unit_now); - if ((block_deepth_now == loop_deepth) && (JMP == ins) && + enum Instruct ins = instructUnit_getInstruct(insUnitThis); + char* data = VMState_getConstWithInstructUnit(vm, insUnitThis); + int blockDeepthThis = instructUnit_getBlockDeepth(insUnitThis); + if ((blockDeepthThis == blockDeepthGot) && (JMP == ins) && data[0] == '-' && data[1] == '1') { return offset; } diff --git a/test/except-test.cpp b/test/except-test.cpp index 85b117c11..f894261f9 100644 --- a/test/except-test.cpp +++ b/test/except-test.cpp @@ -187,6 +187,20 @@ TEST(except, except_break) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(except, while_try_while) { + /* init */ + pikaMemInfo.heapUsedMax = 0; + PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain); + __platform_printf("BEGIN\r\n"); + /* run */ + pikaVM_runSingleFile(pikaMain, "test/python/except/while_try_while.py"); + /* collect */ + /* assert */ + /* deinit */ + obj_deinit(pikaMain); + EXPECT_EQ(pikaMemNow(), 0); +} + #endif TEST_END \ No newline at end of file diff --git a/test/parse-test.cpp b/test/parse-test.cpp index 3054fdac7..402f05372 100644 --- a/test/parse-test.cpp +++ b/test/parse-test.cpp @@ -5338,6 +5338,56 @@ TEST(parser, hint_assign) { EXPECT_EQ(pikaMemNow(), 0); } +TEST(parser, while_try_while) { + pikaMemInfo.heapUsedMax = 0; + Args* buffs = New_strBuff(); + char* lines = + "while True:\n" + " print(\"before try\")\n" + " try:\n" + " print(\"after try\")\n" + " while True:\n" + " raise\n" + " except:\n" + " break\n"; + printf("%s\r\n", lines); + char* pikaAsm = Parser_linesToAsm(buffs, lines); + printf("%s", pikaAsm); + EXPECT_STREQ(pikaAsm, + "B0\n" + "0 REF True\n" + "0 JEZ 2\n" + "B1\n" + "1 STR before try\n" + "0 RUN print\n" + "B1\n" + "0 TRY \n" + "B2\n" + "1 STR after try\n" + "0 RUN print\n" + "B2\n" + "0 REF True\n" + "0 JEZ 2\n" + "B3\n" + "0 REF RuntimeError\n" + "0 RIS \n" + "B2\n" + "0 JMP -1\n" + "B1\n" + "0 NTR \n" + "0 GER \n" + "0 JEZ 2\n" + "B1\n" + "0 EXP \n" + "B2\n" + "0 BRK \n" + "B0\n" + "0 JMP -1\n" + "B0\n"); + args_deinit(buffs); + EXPECT_EQ(pikaMemNow(), 0); +} + #endif TEST_END \ No newline at end of file diff --git a/test/python/except/while_try_while.py b/test/python/except/while_try_while.py new file mode 100644 index 000000000..d1e42ad97 --- /dev/null +++ b/test/python/except/while_try_while.py @@ -0,0 +1,12 @@ + + +while True: + print("before try") + try: + print("after try") + while True: + raise + except: + break + +print("after while") diff --git a/test/python/socket/socket_json.py b/test/python/socket/socket_json.py index 6e8a74dfa..07c91bcfa 100644 --- a/test/python/socket/socket_json.py +++ b/test/python/socket/socket_json.py @@ -24,17 +24,18 @@ def socket_server_task(host, port): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind((host, port)) s.listen(5) - print("socket server waiting accept") global server_started server_started = True - accept, addr = s.accept() - print("socket server accepted at", addr) while True: try: - data = accept.recv(1024) - print('socket server recv:', data.decode()) - # accept.send(data) - accept.send(json.dumps(test_data)) + print("socket server waiting accept") + accept, addr = s.accept() + print("socket server accepted at", addr) + while True: + data = accept.recv(1024) + print('socket server recv:', data.decode()) + # accept.send(data) + accept.send(json.dumps(test_data)) except Exception: print('socket server closing accept') accept.close()