Преглед изворни кода

raise when list out of index, fix 'for except brea'

pikastech пре 3 година
родитељ
комит
b09cae79d3

+ 8 - 1
package/PikaStdLib/PikaStdData_Tuple.c

@@ -32,7 +32,14 @@ Arg* PikaStdData_Tuple___next__(PikaObj* self) {
 }
 
 Arg* PikaStdData_Tuple___getitem__(PikaObj* self, Arg* __key) {
-    return PikaStdData_Tuple_get(self, arg_getInt(__key));
+    int i = arg_getInt(__key);
+    PikaList* list = obj_getPtr(self, "list");
+    if (i < 0 || i >= pikaList_getSize(list)) {
+        obj_setErrorCode(self, PIKA_RES_ERR_INDEX);
+        obj_setSysOut(self, "IndexError: index out of range");
+        return NULL;
+    }
+    return PikaStdData_Tuple_get(self, i);
 }
 
 void PikaStdData_Tuple___del__(PikaObj* self) {

+ 1 - 1
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=vm.cb_2"
+                "--gtest_filter=except.except_break"
             ],
             "stopAtEntry": false,
             "cwd": "${workspaceFolder}",

+ 8 - 1
port/linux/package/pikascript/pikascript-lib/PikaStdLib/PikaStdData_Tuple.c

@@ -32,7 +32,14 @@ Arg* PikaStdData_Tuple___next__(PikaObj* self) {
 }
 
 Arg* PikaStdData_Tuple___getitem__(PikaObj* self, Arg* __key) {
-    return PikaStdData_Tuple_get(self, arg_getInt(__key));
+    int i = arg_getInt(__key);
+    PikaList* list = obj_getPtr(self, "list");
+    if (i < 0 || i >= pikaList_getSize(list)) {
+        obj_setErrorCode(self, PIKA_RES_ERR_INDEX);
+        obj_setSysOut(self, "IndexError: index out of range");
+        return NULL;
+    }
+    return PikaStdData_Tuple_get(self, i);
 }
 
 void PikaStdData_Tuple___del__(PikaObj* self) {

+ 0 - 4
src/PikaParser.c

@@ -2818,10 +2818,6 @@ char* AST_genAsm(AST* ast, Args* outBuffs) {
                 pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 GER \n");
                 pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 JEZ 2\n");
             }
-
-            if (strEqu(block_type, "except")) {
-                pikaAsm = strsAppend(outBuffs, pikaAsm, (char*)"0 SER 0\n");
-            }
 #endif
             /* goto the while start when exit while block */
             if (strEqu(block_type, "for")) {

+ 1 - 0
src/PikaPlatform.h

@@ -101,6 +101,7 @@ typedef enum {
     PIKA_RES_ERR_ASSERT = -16,
     PIKA_RES_ERR_SIGNAL_EVENT_FULL = -17,
     PIKA_RES_ERR_SIGNAL_EVENT_EMPTY = -18,
+    PIKA_RES_ERR_INDEX = -19,
 } PIKA_RES;
 
 /* clang-format off */

+ 10 - 2
src/PikaVM.c

@@ -306,8 +306,14 @@ static int32_t VMState_getAddrOffsetOfJmpBack(VMState* vm) {
         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') {
-            loop_deepth = instructUnit_getBlockDeepth(ins_unit_now);
-            break;
+            InstructUnit* ins_unit_last = VMState_getInstructUnitWithOffset(
+                vm, offset - instructUnit_getSize());
+            enum Instruct ins_last = instructUnit_getInstruct(ins_unit_last);
+            /* skip try stmt */
+            if (GER != ins_last) {
+                loop_deepth = instructUnit_getBlockDeepth(ins_unit_now);
+                break;
+            }
         }
     }
 
@@ -494,6 +500,7 @@ Arg* __vm_get(VMState* vm, PikaObj* self, Arg* key, Arg* obj) {
             arg_obj = arg_getPtr(obj);
         }
         obj_setArg(arg_obj, "__key", key);
+        obj_removeArg(arg_obj, "__res");
         /* clang-format off */
         PIKA_PYTHON(
         __res = __getitem__(__key)
@@ -677,6 +684,7 @@ static Arg* VM_instruction_handler_EXP(PikaObj* self,
                                        VMState* vm,
                                        char* data,
                                        Arg* arg_ret_reg) {
+    vm->try_error_code = 0;
     return NULL;
 }
 

+ 26 - 0
test/except-test.cpp

@@ -161,6 +161,32 @@ TEST(except, trycmodule1) {
     EXPECT_EQ(pikaMemNow(), 0);
 }
 
+TEST(except, except_break) {
+    /* init */
+    pikaMemInfo.heapUsedMax = 0;
+    PikaObj* pikaMain = newRootObj("pikaMain", New_PikaMain);
+    __platform_printf("BEGIN\r\n");
+    /* run */
+    obj_run(pikaMain,
+            "l = [1,2,3]\n"
+            "sum = 0\n"
+            "for i in range(10):\n"
+            "    try:\n"
+            "        sum += l[i]\n"
+            "    except Exception:\n"
+            "        print('in excepton')\n"
+            "        break\n"
+            "print(sum)\n"
+            "\n"
+            );
+    /* collect */
+    /* assert */
+    EXPECT_EQ(obj_getInt(pikaMain, "sum"), 6);
+    /* deinit */
+    obj_deinit(pikaMain);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
 #endif
 
 TEST_END

+ 47 - 3
test/parse-test.cpp

@@ -3225,11 +3225,57 @@ TEST(parser, try1) {
                  "B1\n"
                  "1 STR in except\n"
                  "0 RUN print\n"
-                 "0 SER 0\n"
                  "B0\n");
     args_deinit(buffs);
     EXPECT_EQ(pikaMemNow(), 0);
 }
+
+
+TEST(parser, except_issue) {
+    pikaMemInfo.heapUsedMax = 0;
+    Args* buffs = New_strBuff();
+    char* lines =
+        "try:\n"
+        "    a = 1\n"
+        "    raise 0x25 + 256\n"
+        "    raise\n"
+        "except Excepthon:\n"
+        "    print('in except')\n"
+        "    break\n"
+        "\n";
+    printf("%s\n", lines);
+    char* pikaAsm = Parser_linesToAsm(buffs, lines);
+    printf("%s", pikaAsm);
+    EXPECT_STREQ(pikaAsm,
+                 "B0\n"
+                 "0 TRY \n"
+                 "B1\n"
+                 "0 NUM 1\n"
+                 "0 OUT a\n"
+                 "B1\n"
+                 "1 NUM 0x25\n"
+                 "1 NUM 256\n"
+                 "0 OPT +\n"
+                 "0 RIS \n"
+                 "B1\n"
+                 "0 REF RuntimeError\n"
+                 "0 RIS \n"
+                 "B0\n"
+                 "0 NTR \n"
+                 "0 GER \n"
+                 "0 JEZ 2\n"
+                 "B0\n"
+                 "0 EXP \n"
+                 "B1\n"
+                 "1 STR in except\n"
+                 "0 RUN print\n"
+                 "B1\n"
+                 "0 BRK \n"
+                 "B0\n");
+    args_deinit(buffs);
+    EXPECT_EQ(pikaMemNow(), 0);
+}
+
 #endif
 
 TEST(parser, optissue1) {
@@ -3798,7 +3844,6 @@ TEST(parser, except_for) {
                  "0 EXP \n"
                  "B2\n"
                  "0 REF b\n"
-                 "0 SER 0\n"
                  "B0\n"
                  "0 JMP -1\n"
                  "B0\n"
@@ -4139,7 +4184,6 @@ TEST(parser, except_dict) {
                  "B1\n"
                  "1 STR in except\n"
                  "0 RUN print\n"
-                 "0 SER 0\n"
                  "B0\n");
     args_deinit(buffs);
     EXPECT_EQ(pikaMemNow(), 0);

+ 3 - 1
test/pikaMain-test.cpp

@@ -729,6 +729,7 @@ TEST(pikaMain, obj_no_free) {
     EXPECT_EQ(pikaMemNow(), 0);
 }
 
+#if 0
 TEST(pikaMain, list__setitem__) {
     /* init */
     pikaMemInfo.heapUsedMax = 0;
@@ -748,6 +749,7 @@ TEST(pikaMain, list__setitem__) {
     obj_deinit(pikaMain);
     EXPECT_EQ(pikaMemNow(), 0);
 }
+#endif
 
 TEST(pikaMain, string__getitem__) {
     /* init */
@@ -875,7 +877,7 @@ TEST(pikaMain, list_index) {
     __platform_printf("BEGIN\n");
     obj_run(pikaMain,
             "list = PikaStdData.List()\n"
-            "list[0] = 2\n"
+            "list.append(2)\n"
             "res = list[0]\n"
             "\n");
     /* collect */