blueloveTH 1 år sedan
förälder
incheckning
2e31412d3a

+ 11 - 13
3rd/libhv/src/HttpServer.cpp

@@ -208,34 +208,32 @@ static bool libhv_HttpServer_ws_recv(int argc, py_Ref argv) {
         py_newnone(py_retval());
         py_newnone(py_retval());
         return true;
         return true;
     }
     }
-    py_newtuple(py_retval(), 2);
+    py_Ref data = py_newtuple(py_retval(), 2);
     switch(msg.type) {
     switch(msg.type) {
         case WsMessageType::onopen: {
         case WsMessageType::onopen: {
             // "onopen", (channel, request)
             // "onopen", (channel, request)
             assert(msg.request != nullptr);
             assert(msg.request != nullptr);
-            py_newstr(py_tuple_getitem(py_retval(), 0), "onopen");
-            py_Ref args = py_tuple_getitem(py_retval(), 1);
-            py_newtuple(args, 2);
-            py_newint(py_tuple_getitem(args, 0), (py_i64)msg.channel);
-            libhv_HttpRequest_create(py_tuple_getitem(args, 1), msg.request);
+            py_newstr(py_offset(data, 0), "onopen");
+            py_Ref p = py_newtuple(py_offset(data, 1), 2);
+            py_newint(py_offset(p, 0), (py_i64)msg.channel);
+            libhv_HttpRequest_create(py_offset(p, 1), msg.request);
             break;
             break;
         }
         }
         case WsMessageType::onclose: {
         case WsMessageType::onclose: {
             // "onclose", channel
             // "onclose", channel
-            py_newstr(py_tuple_getitem(py_retval(), 0), "onclose");
-            py_newint(py_tuple_getitem(py_retval(), 1), (py_i64)msg.channel);
+            py_newstr(py_offset(data, 0), "onclose");
+            py_newint(py_offset(data, 1), (py_i64)msg.channel);
             break;
             break;
         }
         }
         case WsMessageType::onmessage: {
         case WsMessageType::onmessage: {
             // "onmessage", (channel, body)
             // "onmessage", (channel, body)
-            py_newstr(py_tuple_getitem(py_retval(), 0), "onmessage");
-            py_Ref args = py_tuple_getitem(py_retval(), 1);
-            py_newtuple(args, 2);
-            py_newint(py_tuple_getitem(args, 0), (py_i64)msg.channel);
+            py_newstr(py_offset(data, 0), "onmessage");
+            py_Ref p = py_newtuple(py_offset(data, 1), 2);
+            py_newint(py_offset(p, 0), (py_i64)msg.channel);
             c11_sv sv;
             c11_sv sv;
             sv.data = msg.body.data();
             sv.data = msg.body.data();
             sv.size = msg.body.size();
             sv.size = msg.body.size();
-            py_newstrv(py_tuple_getitem(args, 1), sv);
+            py_newstrv(py_offset(p, 1), sv);
             break;
             break;
         }
         }
     }
     }

+ 8 - 9
3rd/libhv/src/WebSocketClient.cpp

@@ -59,7 +59,7 @@ py_Type libhv_register_WebSocketClient(py_GlobalRef mod) {
                     http_headers* p_headers = (http_headers*)ctx;
                     http_headers* p_headers = (http_headers*)ctx;
                     if(!py_checkstr(key)) return false;
                     if(!py_checkstr(key)) return false;
                     if(!py_checkstr(value)) return false;
                     if(!py_checkstr(value)) return false;
-                    p_headers->operator[](py_tostr(key)) = py_tostr(value);
+                    p_headers->operator[] (py_tostr(key)) = py_tostr(value);
                     return true;
                     return true;
                 },
                 },
                 &headers);
                 &headers);
@@ -99,22 +99,21 @@ py_Type libhv_register_WebSocketClient(py_GlobalRef mod) {
             py_newnone(py_retval());
             py_newnone(py_retval());
             return true;
             return true;
         } else {
         } else {
-            py_newtuple(py_retval(), 2);
+            py_Ref p = py_newtuple(py_retval(), 2);
             switch(mq_msg.first) {
             switch(mq_msg.first) {
                 case WsMessageType::onopen: {
                 case WsMessageType::onopen: {
-                    py_newstr(py_tuple_getitem(py_retval(), 0), "onopen");
-                    py_newnone(py_tuple_getitem(py_retval(), 1));
+                    py_newstr(py_offset(p, 0), "onopen");
+                    py_newnone(py_offset(p, 1));
                     break;
                     break;
                 }
                 }
                 case WsMessageType::onclose: {
                 case WsMessageType::onclose: {
-                    py_newstr(py_tuple_getitem(py_retval(), 0), "onclose");
-                    py_newnone(py_tuple_getitem(py_retval(), 1));
+                    py_newstr(py_offset(p, 0), "onclose");
+                    py_newnone(py_offset(p, 1));
                     break;
                     break;
                 }
                 }
                 case WsMessageType::onmessage: {
                 case WsMessageType::onmessage: {
-                    py_newstr(py_tuple_getitem(py_retval(), 0), "onmessage");
-                    py_newstrv(py_tuple_getitem(py_retval(), 1),
-                               {mq_msg.second.data(), (int)mq_msg.second.size()});
+                    py_newstr(py_offset(p, 0), "onmessage");
+                    py_newstrv(py_offset(p, 1), {mq_msg.second.data(), (int)mq_msg.second.size()});
                     break;
                     break;
                 }
                 }
             }
             }

+ 1 - 1
include/pocketpy/pocketpy.h

@@ -175,7 +175,7 @@ PK_API void py_newellipsis(py_OutRef);
 PK_API void py_newnil(py_OutRef);
 PK_API void py_newnil(py_OutRef);
 /// Create a `tuple` with `n` UNINITIALIZED elements.
 /// Create a `tuple` with `n` UNINITIALIZED elements.
 /// You should initialize all elements before using it.
 /// You should initialize all elements before using it.
-PK_API void py_newtuple(py_OutRef, int n);
+PK_API py_ObjectRef py_newtuple(py_OutRef, int n);
 /// Create an empty `list`.
 /// Create an empty `list`.
 PK_API void py_newlist(py_OutRef);
 PK_API void py_newlist(py_OutRef);
 /// Create a `list` with `n` UNINITIALIZED elements.
 /// Create a `list` with `n` UNINITIALIZED elements.

+ 2 - 2
src/compiler/compiler.c

@@ -2193,9 +2193,9 @@ static Error* read_literal(Compiler* self, py_Ref out) {
                 if(curr()->type == TK_RPAREN) break;
                 if(curr()->type == TK_RPAREN) break;
             }
             }
             consume(TK_RPAREN);
             consume(TK_RPAREN);
-            py_newtuple(out, count);
+            py_Ref p = py_newtuple(out, count);
             for(int i = 0; i < count; i++) {
             for(int i = 0; i < count; i++) {
-                py_tuple_setitem(out, i, &cpnts[i]);
+                p[i] = cpnts[i];
             }
             }
             return NULL;
             return NULL;
         }
         }

+ 3 - 4
src/interpreter/ceval.c

@@ -474,11 +474,10 @@ FrameResult VM__run_top_frame(VM* self) {
             }
             }
             case OP_BUILD_TUPLE: {
             case OP_BUILD_TUPLE: {
                 py_TValue tmp;
                 py_TValue tmp;
-                py_newtuple(&tmp, byte.arg);
+                py_Ref p = py_newtuple(&tmp, byte.arg);
                 py_TValue* begin = SP() - byte.arg;
                 py_TValue* begin = SP() - byte.arg;
-                for(int i = 0; i < byte.arg; i++) {
-                    py_tuple_setitem(&tmp, i, begin + i);
-                }
+                for(int i = 0; i < byte.arg; i++)
+                    p[i] = begin[i];
                 SP() = begin;
                 SP() = begin;
                 PUSH(&tmp);
                 PUSH(&tmp);
                 DISPATCH();
                 DISPATCH();

+ 2 - 2
src/interpreter/vm.c

@@ -405,9 +405,9 @@ static bool
     if(decl->starred_arg != -1) {
     if(decl->starred_arg != -1) {
         int exceed_argc = p1 - t;
         int exceed_argc = p1 - t;
         py_Ref vargs = &buffer[decl->starred_arg];
         py_Ref vargs = &buffer[decl->starred_arg];
-        py_newtuple(vargs, exceed_argc);
+        py_Ref data = py_newtuple(vargs, exceed_argc);
         for(int j = 0; j < exceed_argc; j++) {
         for(int j = 0; j < exceed_argc; j++) {
-            py_tuple_setitem(vargs, j, t++);
+            data[j] = *t++;
         }
         }
     } else {
     } else {
         // kwdefaults override
         // kwdefaults override

+ 9 - 13
src/modules/array2d.c

@@ -606,8 +606,7 @@ static bool array2d_like_get_bounding_rect(int argc, py_Ref argv) {
     if(width <= 0 || height <= 0) {
     if(width <= 0 || height <= 0) {
         return ValueError("value not found");
         return ValueError("value not found");
     } else {
     } else {
-        py_newtuple(py_retval(), 4);
-        py_TValue* data = py_tuple_data(py_retval());
+        py_TValue* data = py_newtuple(py_retval(), 4);
         py_newint(&data[0], left);
         py_newint(&data[0], left);
         py_newint(&data[1], top);
         py_newint(&data[1], top);
         py_newint(&data[2], width);
         py_newint(&data[2], width);
@@ -786,8 +785,7 @@ static bool array2d_like_iterator__next__(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARGC(1);
     c11_array2d_like_iterator* self = py_touserdata(argv);
     c11_array2d_like_iterator* self = py_touserdata(argv);
     if(self->j >= self->array->n_rows) return StopIteration();
     if(self->j >= self->array->n_rows) return StopIteration();
-    py_newtuple(py_retval(), 2);
-    py_TValue* data = py_tuple_data(py_retval());
+    py_TValue* data = py_newtuple(py_retval(), 2);
     py_newvec2i(&data[0],
     py_newvec2i(&data[0],
                 (c11_vec2i){
                 (c11_vec2i){
                     {self->i, self->j}
                     {self->i, self->j}
@@ -1081,14 +1079,13 @@ static bool chunked_array2d__delitem__(int argc, py_Ref argv) {
 static bool chunked_array2d__iter__(int argc, py_Ref argv) {
 static bool chunked_array2d__iter__(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARGC(1);
     c11_chunked_array2d* self = py_touserdata(argv);
     c11_chunked_array2d* self = py_touserdata(argv);
-    py_newtuple(py_pushtmp(), self->chunks.length);
+    py_Ref data = py_newtuple(py_pushtmp(), self->chunks.length);
     for(int i = 0; i < self->chunks.length; i++) {
     for(int i = 0; i < self->chunks.length; i++) {
-        py_Ref slot = py_tuple_getitem(py_peek(-1), i);
         c11_chunked_array2d_chunks_KV* kv =
         c11_chunked_array2d_chunks_KV* kv =
             c11__at(c11_chunked_array2d_chunks_KV, &self->chunks, i);
             c11__at(c11_chunked_array2d_chunks_KV, &self->chunks, i);
-        py_newtuple(slot, 2);
-        py_newvec2i(py_tuple_getitem(slot, 0), kv->key);
-        py_tuple_setitem(slot, 1, &kv->value[0]);
+        py_Ref p = py_newtuple(&data[i], 2);
+        py_newvec2i(&p[0], kv->key);  // pos
+        p[1] = kv->value[0];          // context
     }
     }
     bool ok = py_iter(py_peek(-1));
     bool ok = py_iter(py_peek(-1));
     if(!ok) return false;
     if(!ok) return false;
@@ -1147,10 +1144,9 @@ static bool chunked_array2d_world_to_chunk(int argc, py_Ref argv) {
     c11_vec2i pos = py_tovec2i(&argv[1]);
     c11_vec2i pos = py_tovec2i(&argv[1]);
     c11_vec2i chunk_pos, local_pos;
     c11_vec2i chunk_pos, local_pos;
     c11_chunked_array2d__world_to_chunk(self, pos.x, pos.y, &chunk_pos, &local_pos);
     c11_chunked_array2d__world_to_chunk(self, pos.x, pos.y, &chunk_pos, &local_pos);
-    py_newtuple(py_retval(), 2);
-    py_TValue* data = py_tuple_data(py_retval());
-    py_newvec2i(&data[0], chunk_pos);
-    py_newvec2i(&data[1], local_pos);
+    py_TValue* p = py_newtuple(py_retval(), 2);
+    py_newvec2i(&p[0], chunk_pos);
+    py_newvec2i(&p[1], local_pos);
     return true;
     return true;
 }
 }
 
 

+ 3 - 3
src/modules/linalg.c

@@ -432,12 +432,12 @@ static bool vec2_smoothdamp_STATIC(int argc, py_Ref argv) {
     }
     }
 
 
     py_Ref ret = py_retval();
     py_Ref ret = py_retval();
-    py_newtuple(ret, 2);
-    py_newvec2(py_tuple_getitem(ret, 0),
+    py_Ref p = py_newtuple(ret, 2);
+    py_newvec2(&p[0],
                (c11_vec2){
                (c11_vec2){
                    {output_x, output_y}
                    {output_x, output_y}
     });
     });
-    py_newvec2(py_tuple_getitem(ret, 1), currentVelocity);
+    py_newvec2(&p[1], currentVelocity);
     return true;
     return true;
 }
 }
 
 

+ 3 - 5
src/modules/math.c

@@ -136,11 +136,9 @@ static bool math_modf(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARGC(1);
     double i;
     double i;
     double f = modf(py_tofloat(py_arg(0)), &i);
     double f = modf(py_tofloat(py_arg(0)), &i);
-    py_newtuple(py_retval(), 2);
-    py_Ref _0 = py_tuple_getitem(py_retval(), 0);
-    py_Ref _1 = py_tuple_getitem(py_retval(), 1);
-    py_newfloat(_0, f);
-    py_newfloat(_1, i);
+    py_Ref p = py_newtuple(py_retval(), 2);
+    py_newfloat(&p[0], f);
+    py_newfloat(&p[1], i);
     return true;
     return true;
 }
 }
 
 

+ 5 - 7
src/modules/pickle.c

@@ -477,22 +477,21 @@ static py_Type pkl__fix_type(py_Type type, c11_smallmap_n2i* type_mapping) {
 
 
 bool py_pickle_loads_body(const unsigned char* p, int memo_length, c11_smallmap_n2i* type_mapping) {
 bool py_pickle_loads_body(const unsigned char* p, int memo_length, c11_smallmap_n2i* type_mapping) {
     py_StackRef p0 = py_peek(0);
     py_StackRef p0 = py_peek(0);
-    py_StackRef memo = py_pushtmp();
-    py_newtuple(memo, memo_length);
+    py_Ref p_memo = py_newtuple(py_pushtmp(), memo_length);
     while(true) {
     while(true) {
         PickleOp op = (PickleOp)*p;
         PickleOp op = (PickleOp)*p;
         p++;
         p++;
         switch(op) {
         switch(op) {
             case PKL_MEMO_GET: {
             case PKL_MEMO_GET: {
                 int index = pkl__read_int(&p);
                 int index = pkl__read_int(&p);
-                py_Ref val = py_tuple_getitem(memo, index);
+                py_Ref val = &p_memo[index];
                 assert(!py_isnil(val));
                 assert(!py_isnil(val));
                 py_push(val);
                 py_push(val);
                 break;
                 break;
             }
             }
             case PKL_MEMO_SET: {
             case PKL_MEMO_SET: {
                 int index = pkl__read_int(&p);
                 int index = pkl__read_int(&p);
-                py_tuple_setitem(memo, index, py_peek(-1));
+                p_memo[index] = *py_peek(-1);
                 break;
                 break;
             }
             }
             case PKL_NIL: {
             case PKL_NIL: {
@@ -589,10 +588,9 @@ bool py_pickle_loads_body(const unsigned char* p, int memo_length, c11_smallmap_
             case PKL_BUILD_TUPLE: {
             case PKL_BUILD_TUPLE: {
                 int length = pkl__read_int(&p);
                 int length = pkl__read_int(&p);
                 py_OutRef val = py_retval();
                 py_OutRef val = py_retval();
-                py_newtuple(val, length);
+                py_Ref p = py_newtuple(val, length);
                 for(int i = length - 1; i >= 0; i--) {
                 for(int i = length - 1; i >= 0; i--) {
-                    py_StackRef item = py_peek(-1);
-                    py_tuple_setitem(val, i, item);
+                    p[i] = *py_peek(-1);
                     py_pop();
                     py_pop();
                 }
                 }
                 py_push(val);
                 py_push(val);

+ 7 - 7
src/public/py_dict.c

@@ -496,14 +496,14 @@ static bool dict_items(int argc, py_Ref argv) {
 static bool dict_keys(int argc, py_Ref argv) {
 static bool dict_keys(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARGC(1);
     Dict* self = py_touserdata(argv);
     Dict* self = py_touserdata(argv);
-    py_newtuple(py_retval(), self->length);
+    py_Ref p = py_newtuple(py_retval(), self->length);
     DictIterator iter;
     DictIterator iter;
     DictIterator__ctor(&iter, self);
     DictIterator__ctor(&iter, self);
     int i = 0;
     int i = 0;
     while(1) {
     while(1) {
         DictEntry* entry = DictIterator__next(&iter);
         DictEntry* entry = DictIterator__next(&iter);
         if(!entry) break;
         if(!entry) break;
-        py_tuple_setitem(py_retval(), i++, &entry->key);
+        p[i++] = entry->key;
     }
     }
     assert(i == self->length);
     assert(i == self->length);
     return true;
     return true;
@@ -512,14 +512,14 @@ static bool dict_keys(int argc, py_Ref argv) {
 static bool dict_values(int argc, py_Ref argv) {
 static bool dict_values(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARGC(1);
     Dict* self = py_touserdata(argv);
     Dict* self = py_touserdata(argv);
-    py_newtuple(py_retval(), self->length);
+    py_Ref p = py_newtuple(py_retval(), self->length);
     DictIterator iter;
     DictIterator iter;
     DictIterator__ctor(&iter, self);
     DictIterator__ctor(&iter, self);
     int i = 0;
     int i = 0;
     while(1) {
     while(1) {
         DictEntry* entry = DictIterator__next(&iter);
         DictEntry* entry = DictIterator__next(&iter);
         if(!entry) break;
         if(!entry) break;
-        py_tuple_setitem(py_retval(), i++, &entry->val);
+        p[i++] = entry->val;
     }
     }
     assert(i == self->length);
     assert(i == self->length);
     return true;
     return true;
@@ -570,9 +570,9 @@ static bool dict_items__next__(int argc, py_Ref argv) {
     DictIterator* iter = py_touserdata(py_arg(0));
     DictIterator* iter = py_touserdata(py_arg(0));
     DictEntry* entry = (DictIterator__next(iter));
     DictEntry* entry = (DictIterator__next(iter));
     if(entry) {
     if(entry) {
-        py_newtuple(py_retval(), 2);
-        py_tuple_setitem(py_retval(), 0, &entry->key);
-        py_tuple_setitem(py_retval(), 1, &entry->val);
+        py_Ref p = py_newtuple(py_retval(), 2);
+        p[0] = entry->key;
+        p[1] = entry->val;
         return true;
         return true;
     }
     }
     return StopIteration();
     return StopIteration();

+ 2 - 2
src/public/py_exception.c

@@ -88,8 +88,8 @@ static bool BaseException_args(int argc, py_Ref argv){
     PY_CHECK_ARGC(1);
     PY_CHECK_ARGC(1);
     py_Ref arg = py_getslot(argv, 0);
     py_Ref arg = py_getslot(argv, 0);
     if(!py_isnil(arg)) {
     if(!py_isnil(arg)) {
-        py_newtuple(py_retval(), 1);
-        py_setslot(py_retval(), 0, arg);
+        py_Ref p = py_newtuple(py_retval(), 1);
+        p[0] = *arg;
     }else{
     }else{
         py_newtuple(py_retval(), 0);
         py_newtuple(py_retval(), 0);
     }
     }

+ 9 - 9
src/public/py_mappingproxy.c

@@ -57,26 +57,26 @@ static bool namedict_items(int argc, py_Ref argv) {
         for(int j = 0; j < PK_MAGIC_SLOTS_COMMON_LENGTH; j++) {
         for(int j = 0; j < PK_MAGIC_SLOTS_COMMON_LENGTH; j++) {
             if(py_isnil(ti->magic_0 + j)) continue;
             if(py_isnil(ti->magic_0 + j)) continue;
             py_Ref slot = py_list_emplace(py_retval());
             py_Ref slot = py_list_emplace(py_retval());
-            py_newtuple(slot, 2);
-            py_assign(py_tuple_getitem(slot, 0), py_name2ref(j + PK_MAGIC_SLOTS_UNCOMMON_LENGTH));
-            py_assign(py_tuple_getitem(slot, 1), ti->magic_0 + j);
+            py_Ref p = py_newtuple(slot, 2);
+            p[0] = *py_name2ref(j + PK_MAGIC_SLOTS_UNCOMMON_LENGTH);
+            p[1] = ti->magic_0[j];
         }
         }
         if(ti->magic_1) {
         if(ti->magic_1) {
             for(int j = 0; j < PK_MAGIC_SLOTS_UNCOMMON_LENGTH; j++) {
             for(int j = 0; j < PK_MAGIC_SLOTS_UNCOMMON_LENGTH; j++) {
                 if(py_isnil(ti->magic_1 + j)) continue;
                 if(py_isnil(ti->magic_1 + j)) continue;
                 py_Ref slot = py_list_emplace(py_retval());
                 py_Ref slot = py_list_emplace(py_retval());
-                py_newtuple(slot, 2);
-                py_assign(py_tuple_getitem(slot, 0), py_name2ref(j));
-                py_assign(py_tuple_getitem(slot, 1), ti->magic_1 + j);
+                py_Ref p = py_newtuple(slot, 2);
+                p[0] = *py_name2ref(j);
+                p[1] = ti->magic_1[j];
             }
             }
         }
         }
     }
     }
     for(int i = 0; i < dict->length; i++) {
     for(int i = 0; i < dict->length; i++) {
         py_Ref slot = py_list_emplace(py_retval());
         py_Ref slot = py_list_emplace(py_retval());
-        py_newtuple(slot, 2);
+        py_Ref p = py_newtuple(slot, 2);
         NameDict_KV* kv = c11__at(NameDict_KV, dict, i);
         NameDict_KV* kv = c11__at(NameDict_KV, dict, i);
-        py_assign(py_tuple_getitem(slot, 0), py_name2ref(kv->key));
-        py_assign(py_tuple_getitem(slot, 1), &kv->value);
+        p[0] = *py_name2ref(kv->key);
+        p[1] = kv->value;
     }
     }
     return true;
     return true;
 }
 }

+ 3 - 3
src/public/py_number.c

@@ -181,9 +181,9 @@ static bool int__divmod__(int argc, py_Ref argv) {
     py_i64 lhs = py_toint(&argv[0]);
     py_i64 lhs = py_toint(&argv[0]);
     py_i64 rhs = py_toint(&argv[1]);
     py_i64 rhs = py_toint(&argv[1]);
     if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero");
     if(rhs == 0) return ZeroDivisionError("integer division or modulo by zero");
-    py_newtuple(py_retval(), 2);
-    py_newint(py_getslot(py_retval(), 0), cpy11__fast_floor_div(lhs, rhs));
-    py_newint(py_getslot(py_retval(), 1), cpy11__fast_mod(lhs, rhs));
+    py_Ref p = py_newtuple(py_retval(), 2);
+    py_newint(&p[0], cpy11__fast_floor_div(lhs, rhs));
+    py_newint(&p[1], cpy11__fast_mod(lhs, rhs));
     return true;
     return true;
 }
 }
 
 

+ 6 - 5
src/public/py_tuple.c

@@ -5,12 +5,13 @@
 #include "pocketpy/objects/object.h"
 #include "pocketpy/objects/object.h"
 #include "pocketpy/interpreter/vm.h"
 #include "pocketpy/interpreter/vm.h"
 
 
-void py_newtuple(py_Ref out, int n) {
+py_ObjectRef py_newtuple(py_Ref out, int n) {
     VM* vm = pk_current_vm;
     VM* vm = pk_current_vm;
     PyObject* obj = ManagedHeap__gcnew(&vm->heap, tp_tuple, n, 0);
     PyObject* obj = ManagedHeap__gcnew(&vm->heap, tp_tuple, n, 0);
     out->type = tp_tuple;
     out->type = tp_tuple;
     out->is_ptr = true;
     out->is_ptr = true;
     out->_obj = obj;
     out->_obj = obj;
+    return PyObject__slots(obj);
 }
 }
 
 
 py_Ref py_tuple_getitem(py_Ref self, int i) { return py_getslot(self, i); }
 py_Ref py_tuple_getitem(py_Ref self, int i) { return py_getslot(self, i); }
@@ -59,9 +60,9 @@ static bool tuple__new__(int argc, py_Ref argv) {
         py_Ref tmp = py_pushtmp();
         py_Ref tmp = py_pushtmp();
         *tmp = *py_retval();  // backup the list
         *tmp = *py_retval();  // backup the list
         int length = py_list_len(tmp);
         int length = py_list_len(tmp);
-        py_newtuple(py_retval(), length);
+        py_Ref p = py_newtuple(py_retval(), length);
         for(int i = 0; i < py_tuple_len(py_retval()); i++) {
         for(int i = 0; i < py_tuple_len(py_retval()); i++) {
-            py_tuple_setitem(py_retval(), i, py_list_getitem(tmp, i));
+            p[i] = *py_list_getitem(tmp, i);
         }
         }
         py_pop();
         py_pop();
         return true;
         return true;
@@ -86,9 +87,9 @@ static bool tuple__getitem__(int argc, py_Ref argv) {
         py_newlist(tmp);
         py_newlist(tmp);
         PK_SLICE_LOOP(i, start, stop, step) py_list_append(tmp, py_getslot(argv, i));
         PK_SLICE_LOOP(i, start, stop, step) py_list_append(tmp, py_getslot(argv, i));
         // convert list to tuple
         // convert list to tuple
-        py_newtuple(py_retval(), py_list_len(tmp));
+        py_Ref p = py_newtuple(py_retval(), py_list_len(tmp));
         for(int i = 0; i < py_tuple_len(py_retval()); i++) {
         for(int i = 0; i < py_tuple_len(py_retval()); i++) {
-            py_tuple_setitem(py_retval(), i, py_list_getitem(tmp, i));
+            p[i] = *py_list_getitem(tmp, i);
         }
         }
         py_pop();
         py_pop();
         return true;
         return true;