From 76eaa1dac68c58303c06b334d3568e20e058439e Mon Sep 17 00:00:00 2001 From: lyon Date: Wed, 24 May 2023 00:51:13 +0800 Subject: [PATCH] fix __getitem__ without __len__ --- port/linux/.vscode/launch.json | 2 +- src/PikaObj.c | 11 ++++++++++- src/PikaObj.h | 3 ++- src/PikaVM.c | 21 +++++++++++++-------- test/python/builtin/getitem.py | 10 ++++++++++ 5 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 test/python/builtin/getitem.py diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index 473b18167..97bec9c45 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -24,7 +24,7 @@ // "--gtest_filter=lua.eval" // "--gtest_filter=eventloop.once1" // "--gtest_filter=parser.fn_fn" - // "--gtest_filter=builtin.isinstance" + "--gtest_filter=builtin.getitem" // "--gtest_filter=except.isinstance" // "--gtest_filter=VM.run_def_add" // "--gtest_filter=parser.slice_fn" diff --git a/src/PikaObj.c b/src/PikaObj.c index d2a10cef9..a4765e0e4 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -1235,7 +1235,7 @@ exit: return err; } -int32_t obj_isArgExist(PikaObj* self, char* argPath) { +pika_bool obj_isArgExist(PikaObj* self, char* argPath) { if (NULL == argPath) { return 0; } @@ -1259,6 +1259,15 @@ exit: return res; } +pika_bool obj_isMethodExist(PikaObj* self, char* method) { + Arg* arg = obj_getMethodArg(self, method); + if (NULL == arg) { + return pika_false; + } + arg_deinit(arg); + return pika_true; +} + VMParameters* obj_run(PikaObj* self, char* cmd) { return pikaVM_run(self, cmd); } diff --git a/src/PikaObj.h b/src/PikaObj.h index 33639958b..b25fd126b 100644 --- a/src/PikaObj.h +++ b/src/PikaObj.h @@ -280,7 +280,8 @@ int32_t class_defineRunTimeConstructor(PikaObj* self, ByteCodeFrame* bytecode_frame); int32_t obj_removeArg(PikaObj* self, char* argPath); -int32_t obj_isArgExist(PikaObj* self, char* argPath); +pika_bool obj_isArgExist(PikaObj* self, char* argPath); +pika_bool obj_isMethodExist(PikaObj* self, char* method); PikaObj* obj_newObjFromConstructor(PikaObj* self, char* name, NewFun newClassFun); diff --git a/src/PikaVM.c b/src/PikaVM.c index f7d295426..87f117bd9 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -533,6 +533,9 @@ static int _obj_getLen(PikaObj* self) { 0x00, 0x5f, 0x5f, 0x6c, 0x65, 0x6e, 0x5f, 0x5f, 0x00, 0x40, 0x6c, 0x00, /* const pool */ }; + if (!obj_isMethodExist(self, "__len__")) { + return -1; + } pikaVM_runByteCode(self, bytes); int len = obj_getInt(self, "@l"); obj_removeArg(self, "@l"); @@ -609,15 +612,17 @@ Arg* _vm_get(VMState* vm, PikaObj* self, Arg* aKey, Arg* aObj) { iIndex = arg_getInt(aKey); } - if (iIndex < 0) { - iIndex += iLen; - arg_setInt(aKey, "", iIndex); - } + if (iLen != -1) { + if (iIndex < 0) { + iIndex += iLen; + arg_setInt(aKey, "", iIndex); + } - if (iIndex >= iLen) { - VMState_setErrorCode(vm, PIKA_RES_ERR_OUT_OF_RANGE); - pika_platform_printf("IndexError: index out of range\r\n"); - return arg_newNone(); + if (iIndex >= iLen) { + VMState_setErrorCode(vm, PIKA_RES_ERR_OUT_OF_RANGE); + pika_platform_printf("IndexError: index out of range\r\n"); + return arg_newNone(); + } } if (ARG_TYPE_STRING == eType) { diff --git a/test/python/builtin/getitem.py b/test/python/builtin/getitem.py new file mode 100644 index 000000000..24fbc6afd --- /dev/null +++ b/test/python/builtin/getitem.py @@ -0,0 +1,10 @@ + +class Test: + def __getitem__(self, key): + return key + + +t = Test() +assert t[1] == 1 +assert t['a'] == 'a' +print("PASS")