blueloveTH 2 лет назад
Родитель
Сommit
6ea82f01fd
6 измененных файлов с 75 добавлено и 11 удалено
  1. 2 2
      src/codeobject.h
  2. 4 4
      src/compiler.h
  3. 64 0
      src/memory.h
  4. 2 2
      src/obj.h
  5. 2 2
      src/parser.h
  6. 1 1
      src/vm.h

+ 2 - 2
src/codeobject.h

@@ -47,11 +47,11 @@ struct CodeBlock {
 };
 
 struct CodeObject {
-    std::shared_ptr<SourceData> src;
+    shared_ptr<SourceData> src;
     Str name;
     bool is_generator = false;
 
-    CodeObject(std::shared_ptr<SourceData> src, Str name) {
+    CodeObject(shared_ptr<SourceData> src, Str name) {
         this->src = src;
         this->name = name;
     }

+ 4 - 4
src/compiler.h

@@ -35,7 +35,7 @@ public:
     Compiler(VM* vm, const char* source, Str filename, CompileMode mode){
         this->vm = vm;
         this->parser = std::make_unique<Parser>(
-            std::make_shared<SourceData>(source, filename, mode)
+            make_sp<SourceData>(source, filename, mode)
         );
 
 // http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
@@ -394,7 +394,7 @@ private:
             _compile_f_args(func, false);
             consume(TK(":"));
         }
-        func.code = std::make_shared<CodeObject>(parser->src, func.name.str());
+        func.code = make_sp<CodeObject>(parser->src, func.name.str());
         this->codes.push(func.code);
         co()->_rvalue += 1; EXPR(); co()->_rvalue -= 1;
         emit(OP_RETURN_VALUE);
@@ -1090,7 +1090,7 @@ private:
         if(match(TK("->"))){
             if(!match(TK("None"))) consume(TK("@id"));
         }
-        func.code = std::make_shared<CodeObject>(parser->src, func.name.str());
+        func.code = make_sp<CodeObject>(parser->src, func.name.str());
         this->codes.push(func.code);
         compile_block_body();
         func.code->optimize(vm);
@@ -1154,7 +1154,7 @@ public:
         if(used) UNREACHABLE();
         used = true;
 
-        CodeObject_ code = std::make_shared<CodeObject>(parser->src, Str("<module>"));
+        CodeObject_ code = make_sp<CodeObject>(parser->src, Str("<module>"));
         codes.push(code);
 
         lex_token(); lex_token();

+ 64 - 0
src/memory.h

@@ -4,6 +4,70 @@
 
 namespace pkpy{
 
+template <typename T>
+struct shared_ptr {
+    int* counter;
+
+    T* _t() const noexcept { return (T*)(counter + 1); }
+    void _inc_counter() { if(counter) ++(*counter); }
+    void _dec_counter() { if(counter && --(*counter) == 0) {((T*)(counter + 1))->~T(); free(counter);} }
+
+public:
+    shared_ptr() : counter(nullptr) {}
+    shared_ptr(int* counter) : counter(counter) {}
+    shared_ptr(const shared_ptr& other) : counter(other.counter) {
+        _inc_counter();
+    }
+    shared_ptr(shared_ptr&& other) noexcept : counter(other.counter) {
+        other.counter = nullptr;
+    }
+    ~shared_ptr() { _dec_counter(); }
+
+    bool operator==(const shared_ptr& other) const { return counter == other.counter; }
+    bool operator!=(const shared_ptr& other) const { return counter != other.counter; }
+    bool operator<(const shared_ptr& other) const { return counter < other.counter; }
+    bool operator>(const shared_ptr& other) const { return counter > other.counter; }
+    bool operator<=(const shared_ptr& other) const { return counter <= other.counter; }
+    bool operator>=(const shared_ptr& other) const { return counter >= other.counter; }
+    bool operator==(std::nullptr_t) const { return counter == nullptr; }
+    bool operator!=(std::nullptr_t) const { return counter != nullptr; }
+
+    shared_ptr& operator=(const shared_ptr& other) {
+        _dec_counter();
+        counter = other.counter;
+        _inc_counter();
+        return *this;
+    }
+
+    shared_ptr& operator=(shared_ptr&& other) noexcept {
+        _dec_counter();
+        counter = other.counter;
+        other.counter = nullptr;
+        return *this;
+    }
+
+    T& operator*() const { return *_t(); }
+    T* operator->() const { return _t(); }
+    T* get() const { return _t(); }
+
+    int use_count() const { 
+        return counter ? *counter : 0;
+    }
+
+    void reset(){
+        _dec_counter();
+        counter = nullptr;
+    }
+};
+
+template <typename T, typename... Args>
+shared_ptr<T> make_sp(Args&&... args) {
+    int* p = (int*)malloc(sizeof(int) + sizeof(T));
+    *p = 1;
+    new(p+1) T(std::forward<Args>(args)...);
+    return shared_ptr<T>(p);
+}
+
 template<typename T, int __Bucket, int __BucketSize=32, bool __ZeroCheck=true>
 struct FreeListA {
     std::vector<T*> buckets[__Bucket+1];

+ 2 - 2
src/obj.h

@@ -13,8 +13,8 @@ struct BaseRef;
 class VM;
 
 typedef std::function<PyObject*(VM*, Args&)> NativeFuncRaw;
-typedef std::shared_ptr<CodeObject> CodeObject_;
-typedef std::shared_ptr<NameDict> NameDict_;
+typedef shared_ptr<CodeObject> CodeObject_;
+typedef shared_ptr<NameDict> NameDict_;
 
 struct NativeFunc {
     NativeFuncRaw f;

+ 2 - 2
src/parser.h

@@ -95,7 +95,7 @@ enum Precedence {
 
 // The context of the parsing phase for the compiler.
 struct Parser {
-    std::shared_ptr<SourceData> src;
+    shared_ptr<SourceData> src;
 
     const char* token_start;
     const char* curr_char;
@@ -290,7 +290,7 @@ struct Parser {
         else set_next_token(one);
     }
 
-    Parser(std::shared_ptr<SourceData> src) {
+    Parser(shared_ptr<SourceData> src) {
         this->src = src;
         this->token_start = src->source;
         this->curr_char = src->source;

+ 1 - 1
src/vm.h

@@ -737,7 +737,7 @@ inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, boo
         return f(this, args);
     } else if(is_type(callable, tp_function)){
         const Function& fn = CAST(Function&, callable);
-        NameDict_ locals = std::make_shared<NameDict>(
+        NameDict_ locals = make_sp<NameDict>(
             fn.code->perfect_locals_capacity,
             kLocalsLoadFactor,
             fn.code->perfect_hash_seed