예제 #1
0
파일: VM.cpp 프로젝트: Gwill/luna
    void VM::GenerateClosure(Value *a, Instruction i)
    {
        GET_CALLINFO_AND_PROTO();
        auto a_proto = proto->GetChildFunction(Instruction::GetParamBx(i));
        a->type_ = ValueT_Closure;
        a->closure_ = state_->NewClosure();
        a->closure_->SetPrototype(a_proto);

        // Prepare all upvalues
        auto new_closure = a->closure_;
        auto closure = call->func_->closure_;
        auto count = a_proto->GetUpvalueCount();
        for (std::size_t i = 0; i < count; ++i)
        {
            auto upvalue_info = a_proto->GetUpvalue(i);
            if (upvalue_info->parent_local_)
            {
                // Transform local variable to upvalue
                auto reg = call->register_ + upvalue_info->register_index_;
                if (reg->type_ != ValueT_Upvalue)
                {
                    auto upvalue = state_->NewUpvalue();
                    upvalue->SetValue(*reg);
                    reg->type_ = ValueT_Upvalue;
                    reg->upvalue_ = upvalue;
                    new_closure->AddUpvalue(upvalue);
                }
                else
                {
                    new_closure->AddUpvalue(reg->upvalue_);
                }
            }
            else
            {
                // Get upvalue from parent upvalue list
                auto upvalue = closure->GetUpvalue(upvalue_info->register_index_);
                new_closure->AddUpvalue(upvalue);
            }
        }
    }
예제 #2
0
    void CodeGenerateVisitor::Visit(Chunk *chunk, void *data)
    {
        // Generate function
        auto func = state_->NewFunction();
        func->SetBaseInfo(chunk->module_, 0);
        func->SetSuperior(func_);
        func_ = func;

        func_state_ = gen_state_.PushFunctionState();

        chunk->block_->Accept(this, data);

        // Generate closure
        auto cl = state_->NewClosure();
        cl->SetPrototype(func);
        // Add Env as closure upvalue
        cl->AddUpvalue(state_->GetGlobal(), Upvalue::Stack);

        // Add closure to stack
        state_->stack_.top_->closure_ = cl;
        state_->stack_.top_->type_ = ValueT_Closure;
        state_->stack_.top_++;
    }