blueloveTH 2 лет назад
Родитель
Сommit
9077da4d6c
6 измененных файлов с 37 добавлено и 31 удалено
  1. 2 2
      src/ceval.h
  2. 3 3
      src/codeobject.h
  3. 18 20
      src/compiler.h
  4. 8 2
      src/expr.h
  5. 4 2
      src/obj.h
  6. 2 2
      src/vm.h

+ 2 - 2
src/ceval.h

@@ -15,7 +15,7 @@ __NEXT_STEP:;
     * For example, frame->popx() returns a strong reference which may be dangerous
     * `Args` containing strong references is safe if it is passed to `call` or `fast_call`
     */
-    heap._auto_collect(this);
+    //heap._auto_collect(this);
 
     const Bytecode& byte = frame->next_bytecode();
     switch (byte.op)
@@ -38,7 +38,7 @@ __NEXT_STEP:;
     case OP_LOAD_ELLIPSIS: frame->push(Ellipsis); DISPATCH();
     case OP_LOAD_BUILTIN_EVAL: frame->push(builtins->attr(m_eval)); DISPATCH();
     case OP_LOAD_FUNCTION: {
-        const FunctionDecl* decl = &frame->co->func_decls[byte.arg];
+        FuncDecl_ decl = frame->co->func_decls[byte.arg];
         PyObject* obj = VAR(Function({decl, frame->_module, frame->_locals}));
         frame->push(obj);
     } DISPATCH();

+ 3 - 3
src/codeobject.h

@@ -60,7 +60,7 @@ struct CodeObject {
     std::set<StrName> global_names;
     std::vector<CodeBlock> blocks = { CodeBlock{NO_BLOCK, -1} };
     std::map<StrName, int> labels;
-    std::vector<FunctionDecl> func_decls;
+    std::vector<FuncDecl_> func_decls;
 
     // may be.. just use a large NameDict?
     uint32_t perfect_locals_capacity = 2;
@@ -71,8 +71,8 @@ struct CodeObject {
     void _mark() const {
         for(PyObject* v : consts) OBJ_MARK(v);
         for(auto& decl: func_decls){
-            decl.kwargs._mark();
-            decl.code->_mark();
+            decl->kwargs._mark();
+            decl->code->_mark();
         }
     }
 };

+ 18 - 20
src/compiler.h

@@ -169,14 +169,12 @@ class Compiler {
 
     // PASS
     void exprLambda(){
-        auto e = make_expr<LambdaExpr>();
-        e->decl.name = "<lambda>";
-        e->scope = name_scope();
+        auto e = make_expr<LambdaExpr>(name_scope());
         if(!match(TK(":"))){
             _compile_f_args(e->decl, false);
             consume(TK(":"));
         }
-        e->decl.code = push_context(lexer->src, "<lambda>");
+        e->decl->code = push_context(lexer->src, e->decl->name.str());
         EXPR(false); // https://github.com/blueloveTH/pocketpy/issues/37
         ctx()->emit(OP_RETURN_VALUE, BC_NOARG, BC_KEEPLINE);
         pop_context();
@@ -754,7 +752,7 @@ class Compiler {
         ctx()->emit(OP_END_CLASS, BC_NOARG, BC_KEEPLINE);
     }
 
-    void _compile_f_args(FunctionDecl& func, bool enable_type_hints){
+    void _compile_f_args(FuncDecl_ decl, bool enable_type_hints){
         int state = 0;      // 0 for args, 1 for *args, 2 for k=v, 3 for **kwargs
         do {
             if(state == 3) SyntaxError("**kwargs should be the last argument");
@@ -769,7 +767,7 @@ class Compiler {
 
             consume(TK("@id"));
             const Str& name = prev().str();
-            if(func.has_name(name)) SyntaxError("duplicate argument name");
+            if(decl->has_name(name)) SyntaxError("duplicate argument name");
 
             // eat type hints
             if(enable_type_hints && match(TK(":"))) consume(TK("@id"));
@@ -778,16 +776,16 @@ class Compiler {
 
             switch (state)
             {
-                case 0: func.args.push_back(name); break;
-                case 1: func.starred_arg = name; state+=1; break;
+                case 0: decl->args.push_back(name); break;
+                case 1: decl->starred_arg = name; state+=1; break;
                 case 2: {
                     consume(TK("="));
                     PyObject* value = read_literal();
                     if(value == nullptr){
                         SyntaxError(Str("expect a literal, not ") + TK_STR(curr().type));
                     }
-                    func.kwargs.set(name, value);
-                    func.kwargs_order.push_back(name);
+                    decl->kwargs.set(name, value);
+                    decl->kwargs_order.push_back(name);
                 } break;
                 case 3: SyntaxError("**kwargs is not supported yet"); break;
             }
@@ -796,38 +794,38 @@ class Compiler {
 
     void compile_function(){
         // TODO: bug, if there are multiple decorators, will cause error
-        FunctionDecl func;
+        FuncDecl_ decl = make_sp<FuncDecl>();
         StrName obj_name;
         consume(TK("@id"));
-        func.name = prev().str();
+        decl->name = prev().str();
         if(!ctx()->is_compiling_class && match(TK("::"))){
             consume(TK("@id"));
-            obj_name = func.name;
-            func.name = prev().str();
+            obj_name = decl->name;
+            decl->name = prev().str();
         }
         consume(TK("("));
         if (!match(TK(")"))) {
-            _compile_f_args(func, true);
+            _compile_f_args(decl, true);
             consume(TK(")"));
         }
         if(match(TK("->"))){
             if(!match(TK("None"))) consume(TK("@id"));
         }
-        func.code = push_context(lexer->src, func.name.str());
+        decl->code = push_context(lexer->src, decl->name.str());
         compile_block_body();
         pop_context();
-        ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(func), prev().line);
+        ctx()->emit(OP_LOAD_FUNCTION, ctx()->add_func_decl(decl), prev().line);
         if(!ctx()->is_compiling_class){
             if(obj_name.empty()){
-                auto e = make_expr<NameExpr>(func.name, name_scope());
+                auto e = make_expr<NameExpr>(decl->name, name_scope());
                 e->emit_store(ctx());
             } else {
                 ctx()->emit(OP_LOAD_NAME, ctx()->add_name(obj_name), prev().line);
-                int index = ctx()->add_name(func.name);
+                int index = ctx()->add_name(decl->name);
                 ctx()->emit(OP_STORE_ATTR, index, prev().line);
             }
         }else{
-            ctx()->emit(OP_STORE_CLASS_ATTR, ctx()->add_name(func.name), BC_KEEPLINE);
+            ctx()->emit(OP_STORE_CLASS_ATTR, ctx()->add_name(decl->name), BC_KEEPLINE);
         }
     }
 

+ 8 - 2
src/expr.h

@@ -96,7 +96,7 @@ struct CodeEmitContext{
         return co->consts.size() - 1;
     }
 
-    int add_func_decl(FunctionDecl decl){
+    int add_func_decl(FuncDecl_ decl){
         co->func_decls.push_back(decl);
         return co->func_decls.size() - 1;
     }
@@ -477,9 +477,15 @@ struct SetCompExpr: CompExpr{
 };
 
 struct LambdaExpr: Expr{
-    FunctionDecl decl;
+    FuncDecl_ decl;
     NameScope scope;
     Str str() const override { return "<lambda>"; }
+    
+    LambdaExpr(NameScope scope){
+        this->decl = make_sp<FuncDecl>();
+        this->decl->name = "<lambda>";
+        this->scope = scope;
+    }
 
     void emit(CodeEmitContext* ctx) override {
         int index = ctx->add_func_decl(decl);

+ 4 - 2
src/obj.h

@@ -24,7 +24,7 @@ struct NativeFunc {
     PyObject* operator()(VM* vm, Args& args) const;
 };
 
-struct FunctionDecl {
+struct FuncDecl {
     StrName name;
     CodeObject_ code;
     std::vector<StrName> args;
@@ -40,8 +40,10 @@ struct FunctionDecl {
     }
 };
 
+using FuncDecl_ = shared_ptr<FuncDecl>;
+
 struct Function{
-    const FunctionDecl* decl;
+    FuncDecl_ decl;
     PyObject* _module;
     NameDict_ _closure;
 };

+ 2 - 2
src/vm.h

@@ -626,8 +626,8 @@ inline Str VM::disassemble(CodeObject_ co){
     ss << '\n' << consts.str() << '\n' << names.str();
 
     for(auto& decl: co->func_decls){
-        ss << "\n\n" << "Disassembly of " << decl.name.str() << ":\n";
-        ss << disassemble(decl.code);
+        ss << "\n\n" << "Disassembly of " << decl->name.str() << ":\n";
+        ss << disassemble(decl->code);
     }
     return Str(ss.str());
 }