// File: marxn[P]pupp/src/parser/function.cpp
// Function: FunctionNode::Provision()
bool FunctionNode::Provision()
{
        list<FuncArgDef*>::iterator i;
        for(i = this->ArgList->begin(); i!=this->ArgList->end(); i++)
        {
                string argname = (*i)->GetName();
                DataType argtype = (*i)->GetType();
                VariableDef * localvar = new VariableDef(argname);
                localvar->SetVarType(argtype);
                this->AddVariable(localvar);
                
                unsigned long varindex = localvar->GetVarIndex();
                (*i)->SetArgIndex(varindex);
        }

        Node * parent = this->GetParentNode();
        if(parent==NULL)
        {
                cerr<<"pupp provision error: A function cannot be defined without a context."<<endl;
                return false;
        }

        list<ClosureVarDesc*>::iterator j;

        if(this->CopyList!=NULL)
        {
                int pos = 0;
                
                for(j = this->CopyList->begin(); j!= this->CopyList->end(); j++)
                {
                        //Because its parent is NOT a Node but a lambda exp, the layer has to be set to 0 to skip the exp.
                        //This is extremely unusual.
                        unsigned long layer = 0; 
                        
                        string varname = (*j)->GetVarName();
                        VariableDef * vardef = parent->FindVariable(varname, &layer);
                        if(vardef==NULL)
                        {
                                cerr<<"pupp provision error: Variable "<<varname<<" has not been defined"<<endl;
                                return false;
                        }
                        
                        VariableDef * newvardef = new VariableDef(varname);
                        newvardef->SetVarType(vardef->GetVarType());
                        newvardef->SetNeedInstance(false);

                        this->AddVariable(newvardef);
                        
                        (*j)->SetSrcLayer(layer);
                        (*j)->SetSrcDef(vardef);
                        (*j)->SetDstDef(newvardef);
                        
                        if(pos++==0)
                        {
                                this->ClosureVarStartIndex = newvardef->GetVarIndex();
                        }
                        
                }
        }
        
        return ContainerNode::Provision();
}

// Assembly:
subq $0x1c8, %rsp            # imm = 0x1C8
movq %rdi, 0x1b8(%rsp)
movq 0x1b8(%rsp), %rax
movq %rax, 0x68(%rsp)
leaq 0x1b0(%rsp), %rdi
callq 0x116a0
movq 0x68(%rsp), %rax
movq 0x98(%rax), %rdi
callq 0x116c0
movq %rax, 0x1a8(%rsp)
movq 0x1a8(%rsp), %rax
movq %rax, 0x1b0(%rsp)
movq 0x68(%rsp), %rax
movq 0x98(%rax), %rdi
callq 0x11710
movq %rax, 0x1a0(%rsp)
leaq 0x1b0(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x116f0
testb $0x1, %al
jne 0x13999
jmp 0x13b47
leaq 0x1b0(%rsp), %rdi
movq %rdi, 0x58(%rsp)
callq 0x11740
movq (%rax), %rsi
leaq 0x180(%rsp), %rdi
callq 0x13500
movq 0x58(%rsp), %rdi
callq 0x11740
movq (%rax), %rdi
callq 0x13530
movl %eax, 0x17c(%rsp)
movl $0x40, %edi
callq 0x62f0
movq %rax, 0x60(%rsp)
jmp 0x139e5
movb $0x1, 0x13f(%rsp)
leaq 0x140(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0x6160
jmp 0x13a04
movq 0x60(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x30e90
jmp 0x13a18
movb $0x0, 0x13f(%rsp)
leaq 0x140(%rsp), %rdi
callq 0x61e0
movq 0x60(%rsp), %rax
movq %rax, 0x170(%rsp)
movq 0x170(%rsp), %rdi
movl 0x17c(%rsp), %esi
callq 0x31000
jmp 0x13a50
movq 0x68(%rsp), %rdi
movq 0x170(%rsp), %rsi
callq 0x141b0
jmp 0x13a64
movq 0x170(%rsp), %rdi
callq 0x310b0
movq %rax, 0x50(%rsp)
jmp 0x13a78
movq 0x50(%rsp), %rax
movq %rax, 0x130(%rsp)
leaq 0x1b0(%rsp), %rdi
callq 0x11740
movq (%rax), %rdi
movq 0x130(%rsp), %rsi
callq 0x13570
leaq 0x180(%rsp), %rdi
callq 0x61e0
leaq 0x1b0(%rsp), %rdi
xorl %esi, %esi
callq 0x11770
movq %rax, 0x128(%rsp)
jmp 0x13962
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
jmp 0x13b35
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
jmp 0x13b18
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
leaq 0x140(%rsp), %rdi
callq 0x61e0
testb $0x1, 0x13f(%rsp)
jne 0x13b24
jmp 0x13b33
movq 0x60(%rsp), %rdi
movl $0x40, %esi
callq 0x6300
jmp 0x13b35
leaq 0x180(%rsp), %rdi
callq 0x61e0
jmp 0x13f7d
movq 0x68(%rsp), %rdi
callq 0x14170
movq %rax, 0x120(%rsp)
cmpq $0x0, 0x120(%rsp)
jne 0x13b93
movq 0x62485(%rip), %rdi     # 0x75ff0
leaq 0x4ba55(%rip), %rsi     # 0x5f5c7
callq 0x62d0
movq %rax, %rdi
movq 0x62437(%rip), %rsi     # 0x75fb8
callq 0x6320
movb $0x0, 0x1c7(%rsp)
jmp 0x13f6c
leaq 0x118(%rsp), %rdi
callq 0x11830
movq 0x68(%rsp), %rax
cmpq $0x0, 0xa0(%rax)
je 0x13f59
movq 0x68(%rsp), %rax
movl $0x0, 0x114(%rsp)
movq 0xa0(%rax), %rdi
callq 0x11850
movq %rax, 0x108(%rsp)
movq 0x108(%rsp), %rax
movq %rax, 0x118(%rsp)
movq 0x68(%rsp), %rax
movq 0xa0(%rax), %rdi
callq 0x118a0
movq %rax, 0x100(%rsp)
leaq 0x118(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x11880
testb $0x1, %al
jne 0x13c1e
jmp 0x13f57
movq $0x0, 0xf8(%rsp)
leaq 0x118(%rsp), %rdi
callq 0x118d0
movq (%rax), %rsi
leaq 0xd8(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x13640
movq 0x40(%rsp), %rsi
movq 0x120(%rsp), %rax
movq %rax, 0x48(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x6160
jmp 0x13c6d
movq 0x48(%rsp), %rdi
leaq 0xb0(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
callq 0x143e0
movq %rax, 0x38(%rsp)
jmp 0x13c8e
leaq 0xb0(%rsp), %rdi
callq 0x61e0
movq 0x38(%rsp), %rax
movq %rax, 0xd0(%rsp)
cmpq $0x0, 0xd0(%rsp)
jne 0x13d6c
movq 0x62332(%rip), %rdi     # 0x75ff0
leaq 0x4b515(%rip), %rsi     # 0x5f1da
callq 0x62d0
movq %rax, 0x30(%rsp)
jmp 0x13cd1
movq 0x30(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x62a0
movq %rax, 0x28(%rsp)
jmp 0x13cea
movq 0x28(%rsp), %rdi
leaq 0x4b504(%rip), %rsi     # 0x5f1fa
callq 0x62d0
movq %rax, 0x20(%rsp)
jmp 0x13d02
movq 0x20(%rsp), %rdi
movq 0x622aa(%rip), %rsi     # 0x75fb8
callq 0x6320
jmp 0x13d15
movb $0x0, 0x1c7(%rsp)
movl $0x1, 0xac(%rsp)
jmp 0x13f11
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
jmp 0x13f48
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
leaq 0xb0(%rsp), %rdi
callq 0x61e0
jmp 0x13f48
movl $0x40, %edi
callq 0x62f0
movq %rax, 0x18(%rsp)
jmp 0x13d7d
movb $0x1, 0x7f(%rsp)
leaq 0x80(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x6160
jmp 0x13d99
movq 0x18(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x30e90
jmp 0x13dad
movb $0x0, 0x7f(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x61e0
movq 0x18(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0xd0(%rsp), %rdi
callq 0x31020
movl %eax, 0x14(%rsp)
jmp 0x13dec
movl 0x14(%rsp), %esi
movq 0x8(%rsp), %rdi
callq 0x31000
jmp 0x13dfc
movq 0xa0(%rsp), %rdi
xorl %esi, %esi
callq 0x310d0
jmp 0x13e0d
movq 0x68(%rsp), %rdi
movq 0xa0(%rsp), %rsi
callq 0x141b0
jmp 0x13e21
leaq 0x118(%rsp), %rdi
callq 0x118d0
movq (%rax), %rdi
movq 0xf8(%rsp), %rsi
callq 0x13680
leaq 0x118(%rsp), %rdi
callq 0x118d0
movq (%rax), %rdi
movq 0xd0(%rsp), %rsi
callq 0x136a0
leaq 0x118(%rsp), %rdi
callq 0x118d0
movq (%rax), %rdi
movq 0xa0(%rsp), %rsi
callq 0x136c0
movl 0x114(%rsp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, 0x114(%rsp)
cmpl $0x0, %eax
jne 0x13f06
movq 0xa0(%rsp), %rdi
callq 0x310b0
movq %rax, (%rsp)
jmp 0x13ea3
movq 0x68(%rsp), %rax
movq (%rsp), %rcx
movq %rcx, 0xa8(%rax)
jmp 0x13f06
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
jmp 0x13eec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x168(%rsp)
movl %eax, 0x164(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x61e0
testb $0x1, 0x7f(%rsp)
jne 0x13ef5
jmp 0x13f04
movq 0x18(%rsp), %rdi
movl $0x40, %esi
callq 0x6300
jmp 0x13f48
movl $0x0, 0xac(%rsp)
leaq 0xd8(%rsp), %rdi
callq 0x61e0
movl 0xac(%rsp), %eax
testl %eax, %eax
je 0x13f2d
jmp 0x13f2b
jmp 0x13f6c
jmp 0x13f2f
leaq 0x118(%rsp), %rdi
xorl %esi, %esi
callq 0x11980
movq %rax, 0x70(%rsp)
jmp 0x13be7
leaq 0xd8(%rsp), %rdi
callq 0x61e0
jmp 0x13f7d
jmp 0x13f59
movq 0x68(%rsp), %rdi
callq 0xd330
andb $0x1, %al
movb %al, 0x1c7(%rsp)
movb 0x1c7(%rsp), %al
andb $0x1, %al
addq $0x1c8, %rsp            # imm = 0x1C8
retq
movq 0x168(%rsp), %rdi
callq 0x6550
nopw (%rax,%rax)