blueloveTH 1 рік тому
батько
коміт
ffbc7e9ade

+ 2 - 0
include/pocketpy/interpreter/vm.h

@@ -27,6 +27,8 @@ typedef struct VM {
 
 
     py_Callbacks callbacks;
     py_Callbacks callbacks;
 
 
+    py_TValue ascii_literals[128+1];
+
     py_TValue last_retval;
     py_TValue last_retval;
     py_TValue curr_exception;
     py_TValue curr_exception;
     volatile bool is_signal_interrupted;
     volatile bool is_signal_interrupted;

+ 14 - 4
src/interpreter/vm.c

@@ -83,6 +83,12 @@ void VM__ctor(VM* self) {
     ValueStack__ctor(&self->stack);
     ValueStack__ctor(&self->stack);
 
 
     /* Init Builtin Types */
     /* Init Builtin Types */
+    for(int i = 0; i < 128; i++) {
+        char* p = py_newstrn(&self->ascii_literals[i], 1);
+        *p = i;
+    }
+    py_newstrn(&self->ascii_literals[128], 0);
+
     // 0: unused
     // 0: unused
     void* placeholder = TypeList__emplace(&self->types);
     void* placeholder = TypeList__emplace(&self->types);
     memset(placeholder, 0, sizeof(py_TypeInfo));
     memset(placeholder, 0, sizeof(py_TypeInfo));
@@ -153,7 +159,7 @@ void VM__ctor(VM* self) {
 
 
     validate(tp_StopIteration, pk_StopIteration__register());
     validate(tp_StopIteration, pk_StopIteration__register());
     py_setdict(&self->builtins, py_name("StopIteration"), py_tpobject(tp_StopIteration));
     py_setdict(&self->builtins, py_name("StopIteration"), py_tpobject(tp_StopIteration));
-    
+
     INJECT_BUILTIN_EXC(SyntaxError, tp_Exception);
     INJECT_BUILTIN_EXC(SyntaxError, tp_Exception);
     INJECT_BUILTIN_EXC(StackOverflowError, tp_Exception);
     INJECT_BUILTIN_EXC(StackOverflowError, tp_Exception);
     INJECT_BUILTIN_EXC(OSError, tp_Exception);
     INJECT_BUILTIN_EXC(OSError, tp_Exception);
@@ -224,8 +230,8 @@ void VM__ctor(VM* self) {
     pk__add_module_importlib();
     pk__add_module_importlib();
 
 
     pk__add_module_conio();
     pk__add_module_conio();
-    pk__add_module_lz4();       // optional
-    pk__add_module_libhv();     // optional
+    pk__add_module_lz4();    // optional
+    pk__add_module_libhv();  // optional
     pk__add_module_pkpy();
     pk__add_module_pkpy();
 
 
     // add python builtins
     // add python builtins
@@ -509,7 +515,7 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
                 memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
                 memcpy(argv, self->__vectorcall_buffer, co->nlocals * sizeof(py_TValue));
                 Frame* frame = Frame__new(co, &fn->module, p0, argv, true);
                 Frame* frame = Frame__new(co, &fn->module, p0, argv, true);
                 pk_newgenerator(py_retval(), frame, p0, self->stack.sp);
                 pk_newgenerator(py_retval(), frame, p0, self->stack.sp);
-                self->stack.sp = p0;    // reset the stack
+                self->stack.sp = p0;  // reset the stack
                 return RES_RETURN;
                 return RES_RETURN;
             }
             }
             default: c11__unreachable();
             default: c11__unreachable();
@@ -640,6 +646,10 @@ void ManagedHeap__mark(ManagedHeap* self) {
     for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
     for(py_TValue* p = vm->stack.begin; p != vm->stack.end; p++) {
         pk__mark_value(p);
         pk__mark_value(p);
     }
     }
+    // mark ascii literals
+    for(int i = 0; i < c11__count_array(vm->ascii_literals); i++) {
+        pk__mark_value(&vm->ascii_literals[i]);
+    }
     // mark modules
     // mark modules
     ModuleDict__apply_mark(&vm->modules, mark_object);
     ModuleDict__apply_mark(&vm->modules, mark_object);
     // mark types
     // mark types

+ 1 - 2
src/public/modules.c

@@ -456,8 +456,7 @@ static bool builtins_chr(int argc, py_Ref argv) {
     PY_CHECK_ARG_TYPE(0, tp_int);
     PY_CHECK_ARG_TYPE(0, tp_int);
     py_i64 val = py_toint(py_arg(0));
     py_i64 val = py_toint(py_arg(0));
     if(val < 0 || val > 128) { return ValueError("chr() arg not in range(128)"); }
     if(val < 0 || val > 128) { return ValueError("chr() arg not in range(128)"); }
-    char* data = py_newstrn(py_retval(), 1);
-    data[0] = (char)val;
+    py_assign(py_retval(), &pk_current_vm->ascii_literals[val]);
     return true;
     return true;
 }
 }
 
 

+ 11 - 0
src/public/py_str.c

@@ -21,6 +21,17 @@ char* py_newstrn(py_Ref out, int size) {
 }
 }
 
 
 void py_newstrv(py_OutRef out, c11_sv sv) {
 void py_newstrv(py_OutRef out, c11_sv sv) {
+    if(sv.size == 0) {
+        *out = pk_current_vm->ascii_literals[128];
+        return;
+    }
+    if(sv.size == 1) {
+        int c = sv.data[0];
+        if(c >= 0 && c < 128) {
+            *out = pk_current_vm->ascii_literals[c];
+            return;
+        }
+    }
     char* data = py_newstrn(out, sv.size);
     char* data = py_newstrn(out, sv.size);
     memcpy(data, sv.data, sv.size);
     memcpy(data, sv.data, sv.size);
 }
 }

+ 2 - 0
tests/04_str.py

@@ -190,6 +190,8 @@ assert (1 != '1') is True
 assert (1 == '1') is False
 assert (1 == '1') is False
 assert 1 == 1.0
 assert 1 == 1.0
 
 
+assert chr(97) is 'a'
+
 exit()
 exit()
 
 
 # test format()
 # test format()