Просмотр исходного кода

Merge pull request #1 from blueloveTH/new_str

New _Str implementation
BLUELOVETH 3 лет назад
Родитель
Сommit
d0fa268245
10 измененных файлов с 208 добавлено и 106 удалено
  1. 1 1
      build_cpp.sh
  2. 1 1
      build_wasm.sh
  3. 1 1
      src/codeobject.h
  4. 3 3
      src/iter.h
  5. 17 9
      src/main.cpp
  6. 9 3
      src/obj.h
  7. 5 5
      src/pocketpy.h
  8. 142 64
      src/str.h
  9. 21 19
      src/vm.h
  10. 8 0
      test_cpp_1.sh

+ 1 - 1
build_cpp.sh

@@ -1 +1 @@
-g++ -o pocketpy src/main.cpp --std=c++17 -O1 -pthread
+g++ -o pocketpy src/main.cpp --std=c++17 -O1 -pthread -Wno-literal-suffix

+ 1 - 1
build_wasm.sh

@@ -1,3 +1,3 @@
 rm -rf web/lib/
 mkdir -p web/lib/
-emcc src/main.cpp -fexceptions -sEXIT_RUNTIME -O3 -sEXPORTED_FUNCTIONS=_repl_input,_repl_start -sEXPORTED_RUNTIME_METHODS=ccall -o web/lib/pocketpy.js
+em++ src/main.cpp -fexceptions -sEXIT_RUNTIME -O3 -sEXPORTED_FUNCTIONS=_repl_input,_repl_start -sEXPORTED_RUNTIME_METHODS=ccall -o web/lib/pocketpy.js

+ 1 - 1
src/codeobject.h

@@ -112,7 +112,7 @@ struct CodeObject {
             auto fn = std::get_if<_Func>(&co_consts[i]->_native);
             if(fn) ss << '\n' << (*fn)->code->name << ":\n" << (*fn)->code->toString();
         }
-        return _Str(ss);
+        return _Str(ss.str());
     }
 };
 

+ 3 - 3
src/iter.h

@@ -44,14 +44,14 @@ public:
 class StringIterator : public _Iterator {
 private:
     size_t index = 0;
-    const _Str* str;
+    _Str str;
 public:
     StringIterator(VM* vm, PyVar _ref) : _Iterator(vm, _ref) {
-        str = &std::get<_Str>(_ref->_native);
+        str = std::get<_Str>(_ref->_native);
     }
 
     bool hasNext(){
-        return index < str->u8_length();
+        return index < str.u8_length();
     }
 
     PyVar next();

+ 17 - 9
src/main.cpp

@@ -69,17 +69,25 @@ int main(int argc, char** argv){
         });
         if(code == nullptr) return 1;
         //std::cout << code->toString() << std::endl;
+
         Timer("Running time").run([=]{
-            vm->startExec(code);
-            while(pkpy_tvm_get_state(vm) != THREAD_FINISHED){
-                if(pkpy_tvm_get_state(vm) == THREAD_SUSPENDED){
-                    std::string line;
-                    std::getline(std::cin, line);
-                    pkpy_tvm_write_stdin(vm, line.c_str());
-                    pkpy_tvm_resume(vm);
-                }
-            }
+            vm->exec(code);
         });
+
+        // for(auto& kv : _strIntern)
+        //     std::cout << kv.first << ", ";
+
+        // Timer("Running time").run([=]{
+        //     vm->startExec(code);
+        //     while(pkpy_tvm_get_state(vm) != THREAD_FINISHED){
+        //         if(pkpy_tvm_get_state(vm) == THREAD_SUSPENDED){
+        //             std::string line;
+        //             std::getline(std::cin, line);
+        //             pkpy_tvm_write_stdin(vm, line.c_str());
+        //             pkpy_tvm_resume(vm);
+        //         }
+        //     }
+        // });
         return 0;
     }
 

+ 9 - 3
src/obj.h

@@ -84,19 +84,25 @@ const int _SIZEOF_VALUE = sizeof(_Value);
 struct PyObject {
     PyVarDict attribs;
     _Value _native;
+    PyVar _type;
 
     inline bool isType(const PyVar& type){
-        return attribs[__class__] == type;
+        return this->_type == type;
+    }
+
+    inline void setType(const PyVar& type){
+        this->_type = type;
+        this->attribs[__class__] = type;
     }
 
     // currently __name__ is only used for 'type'
     _Str getName(){
-        _Value val = attribs["__name__"]->_native;
+        _Value val = attribs[__name__]->_native;
         return std::get<_Str>(val);
     }
 
     _Str getTypeName(){
-        return attribs[__class__]->getName();
+        return _type->getName();
     }
 
     PyObject(_Value val): _native(val) {}

+ 5 - 5
src/pocketpy.h

@@ -126,7 +126,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
 
     _vm->bindMethod("type", "__new__", [](VM* vm, PyVarList args) {
         vm->__checkArgSize(args, 1);
-        return args[0]->attribs[__class__];
+        return args[0]->_type;
     });
 
     _vm->bindMethod("range", "__new__", [](VM* vm, PyVarList args) {
@@ -354,7 +354,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
         const _Str& _self (vm->PyStr_AS_C(args[0]));
         _StrStream ss;
         for(auto c : _self.str()) ss << (char)toupper(c);
-        return vm->PyStr(ss);
+        return vm->PyStr(ss.str());
     });
 
     _vm->bindMethod("str", "lower", [](VM* vm, PyVarList args) {
@@ -362,7 +362,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
         const _Str& _self (vm->PyStr_AS_C(args[0]));
         _StrStream ss;
         for(auto c : _self.str()) ss << (char)tolower(c);
-        return vm->PyStr(ss);
+        return vm->PyStr(ss.str());
     });
 
     _vm->bindMethod("str", "replace", [](VM* vm, PyVarList args) {
@@ -403,7 +403,7 @@ void __initializeBuiltinFunctions(VM* _vm) {
             if(i > 0) ss << _self;
             ss << vm->PyStr_AS_C(vm->asStr(_list[i]));
         }
-        return vm->PyStr(ss);
+        return vm->PyStr(ss.str());
     });
 
     /************ PyList ************/
@@ -713,7 +713,7 @@ extern "C" {
         _StrStream* s_out = dynamic_cast<_StrStream*>(vm->_stdout);
         _StrStream* s_err = dynamic_cast<_StrStream*>(vm->_stderr);
         if(s_out == nullptr || s_err == nullptr) UNREACHABLE();
-        PyOutputDump* dump = new PyOutputDump(*s_out, *s_err);
+        PyOutputDump* dump = new PyOutputDump(s_out->str(), s_err->str());
         s_out->str("");
         s_err->str("");
         return dump;

Разница между файлами не показана из-за своего большого размера
+ 142 - 64
src/str.h


+ 21 - 19
src/vm.h

@@ -30,7 +30,7 @@
         }else{                                      \
             __checkType(ptype, _tp_type);           \
             _raw = new PyObject(_native);           \
-            _raw->attribs[__class__] = ptype;       \
+            _raw->setType(ptype);                   \
         }                                           \
         PyVar obj = PyVar(_raw, [this](PyObject* p){\
             if(_pool##name.size() < max_size){      \
@@ -116,7 +116,7 @@ private:
                 PyVarList items = frame->popNValuesReversed(this, byte.arg);
                 _StrStream ss;
                 for(const auto& i : items) ss << PyStr_AS_C(asStr(i));
-                frame->push(PyStr(ss));
+                frame->push(PyStr(ss.str()));
             } break;
             case OP_LOAD_EVAL_FN: {
                 frame->push(builtins->attribs["eval"]);
@@ -371,11 +371,10 @@ public:
 
     PyVar asBool(const PyVar& obj){
         if(obj == None) return False;
-        PyVar tp = obj->attribs[__class__];
-        if(tp == _tp_bool) return obj;
-        if(tp == _tp_int) return PyBool(PyInt_AS_C(obj) != 0);
-        if(tp == _tp_float) return PyBool(PyFloat_AS_C(obj) != 0.0);
-        PyVarOrNull len_fn = getAttr(obj, "__len__", false);
+        if(obj->_type == _tp_bool) return obj;
+        if(obj->_type == _tp_int) return PyBool(PyInt_AS_C(obj) != 0);
+        if(obj->_type == _tp_float) return PyBool(PyFloat_AS_C(obj) != 0.0);
+        PyVarOrNull len_fn = getAttr(obj, __len__, false);
         if(len_fn != nullptr){
             PyVar ret = call(len_fn, {});
             return PyBool(PyInt_AS_C(ret) > 0);
@@ -384,7 +383,7 @@ public:
     }
 
     PyVar fastCall(const PyVar& obj, const _Str& name, PyVarList args){
-        PyVar cls = obj->attribs[__class__];
+        PyVar cls = obj->_type;
         while(cls != None) {
             auto it = cls->attribs.find(name);
             if(it != cls->attribs.end()){
@@ -414,6 +413,7 @@ public:
 
         if(callable->isType(_tp_bounded_method)){
             auto& bm = PyBoundedMethod_AS_C(callable);
+            // TODO: avoid insertion here, bad performance
             args.insert(args.begin(), bm.obj);
             callable = bm.method;
         }
@@ -516,7 +516,7 @@ public:
 
     PyVar newUserClassType(_Str name, PyVar base){
         PyVar obj = newClassType(name, base);
-        setAttr(obj, "__name__", PyStr(name));
+        setAttr(obj, __name__, PyStr(name));
         _types.erase(name);
         return obj;
     }
@@ -524,7 +524,7 @@ public:
     PyVar newClassType(_Str name, PyVar base=nullptr) {
         if(base == nullptr) base = _tp_object;
         PyVar obj = std::make_shared<PyObject>((_Int)0);
-        setAttr(obj, __class__, _tp_type);
+        obj->setType(_tp_type);
         setAttr(obj, __base__, base);
         _types[name] = obj;
         return obj;
@@ -533,13 +533,13 @@ public:
     PyVar newObject(PyVar type, _Value _native) {
         __checkType(type, _tp_type);
         PyVar obj = std::make_shared<PyObject>(_native);
-        setAttr(obj, __class__, type);
+        obj->setType(type);
         return obj;
     }
 
     PyVar newModule(_Str name, bool saveToPath=true) {
         PyVar obj = newObject(_tp_module, (_Int)-2);
-        setAttr(obj, "__name__", PyStr(name));
+        setAttr(obj, __name__, PyStr(name));
         if(saveToPath) _modules[name] = obj;
         return obj;
     }
@@ -548,7 +548,7 @@ public:
         auto it = obj->attribs.find(name);
         if(it != obj->attribs.end()) return it->second;
 
-        PyVar cls = obj->attribs[__class__];
+        PyVar cls = obj->_type;
         while(cls != None) {
             it = cls->attribs.find(name);
             if(it != cls->attribs.end()){
@@ -570,6 +570,7 @@ public:
     }
 
     void bindMethod(_Str typeName, _Str funcName, _CppFunc fn) {
+        funcName.intern();
         PyVar type = _types[typeName];
         PyVar func = PyNativeFunction(fn);
         setAttr(type, funcName, func);
@@ -586,6 +587,7 @@ public:
     }
 
     void bindFunc(PyVar module, _Str funcName, _CppFunc fn) {
+        funcName.intern();
         __checkType(module, _tp_module);
         PyVar func = PyNativeFunction(fn);
         setAttr(module, funcName, func);
@@ -593,7 +595,7 @@ public:
 
     bool isInstance(PyVar obj, PyVar type){
         __checkType(type, _tp_type);
-        PyVar t = obj->attribs[__class__];
+        PyVar t = obj->_type;
         while (t != None){
             if (t == type) return true;
             t = t->attribs[__base__];
@@ -691,15 +693,15 @@ public:
         this->True = newObject(_tp_bool, true);
         this->False = newObject(_tp_bool, false);
         this->builtins = newModule("builtins");
-        this->_main = newModule("__main__", false);
+        this->_main = newModule("__main__"_c, false);
 
         setAttr(_tp_type, __base__, _tp_object);
-        setAttr(_tp_type, __class__, _tp_type);
+        _tp_type->setType(_tp_type);
         setAttr(_tp_object, __base__, None);
-        setAttr(_tp_object, __class__, _tp_type);
+        _tp_object->setType(_tp_type);
         
         for (auto& [name, type] : _types) {
-            setAttr(type, "__name__", PyStr(name));
+            setAttr(type, __name__, PyStr(name));
         }
 
         this->__py2py_call_signal = newObject(_tp_object, (_Int)7);
@@ -916,7 +918,7 @@ PyVar RangeIterator::next(){
 }
 
 PyVar StringIterator::next(){
-    return vm->PyStr(str->u8_getitem(index++));
+    return vm->PyStr(str.u8_getitem(index++));
 }
 
 enum ThreadState {

+ 8 - 0
test_cpp_1.sh

@@ -0,0 +1,8 @@
+g++ -o pocketpy src/main.cpp --std=c++17 -pg -O1 -pthread -Wno-literal-suffix
+
+./pocketpy tests/1.py
+
+gprof pocketpy gmon.out > gprof.txt
+
+#gprof pocketpy | gprof2dot | dot -Tsvg -o output.svg
+rm gmon.out

Некоторые файлы не были показаны из-за большого количества измененных файлов