// File: rofl0r[P]ascc/cs_parser.cpp
// Function: call_property_func(ccCompiledScript*, int, int)
int call_property_func(ccCompiledScript *scrip, int propSym, int isWrite) {
  // a Property Get
  int numargs = 0;

  // AX contains the struct address

  // Always a struct member -- set OP = AX
  if ((sym.entries[propSym].flags & SFLG_STATIC) == 0) {
    scrip->push_reg(SREG_OP);
    scrip->write_cmd1(SCMD_CALLOBJ, SREG_AX);
  }

  if (isWrite) {
    // BX contains the new value
    if (sym.entries[propSym].flags & SFLG_IMPORTED)
      scrip->write_cmd1(SCMD_PUSHREAL, SREG_BX);
    else {
      cc_error("internal error: prop is not import");
      return -1;
    }

    numargs++;
  }

  if (sym.entries[propSym].flags & SFLG_ARRAY) {
    // array indexer is in DX
    if (sym.entries[propSym].flags & SFLG_IMPORTED)
      scrip->write_cmd1(SCMD_PUSHREAL, SREG_DX);
    else {
      cc_error("internal error: prop is not import");
      return -1;
    }

    numargs++;
  }

  if (sym.entries[propSym].flags & SFLG_IMPORTED) {
    // tell it how many args for this call (nested imported functions
    // causes stack problems otherwise)
    scrip->write_cmd1(SCMD_NUMFUNCARGS, numargs);
  }

  int propFunc;
  if (isWrite)
    propFunc = sym.entries[propSym].get_propset();
  else
    propFunc = sym.entries[propSym].get_propget();

  if (propFunc < 0) {
    cc_error("Internal error: property in use but not set");
    return -1;
  }

  // AX = Func Address
  scrip->write_cmd2(SCMD_LITTOREG, SREG_AX, propFunc);

  if (sym.entries[propSym].flags & SFLG_IMPORTED) {
    scrip->fixup_previous(FIXUP_IMPORT);
    // do the call
    scrip->write_cmd1(SCMD_CALLEXT, SREG_AX);
    if (numargs > 0)
      scrip->write_cmd1(SCMD_SUBREALSTACK,numargs);
  }
  else {
    scrip->fixup_previous(FIXUP_FUNCTION);
    scrip->write_cmd1(SCMD_CALL, SREG_AX);

    // restore the stack
    if (numargs > 0) {
      scrip->cur_sp -= numargs*4;
      scrip->write_cmd2(SCMD_SUB,SREG_SP,numargs*4);
    }
  }

  if (!isWrite) {
    // function return type
    scrip->ax_val_type = sym.entries[propSym].vartype;
    scrip->ax_val_scope = SYM_LOCALVAR;
    if (sym.entries[propSym].flags & SFLG_DYNAMICARRAY)
      scrip->ax_val_type |= STYPE_DYNARRAY;
    if (sym.entries[propSym].flags & SFLG_POINTER)
      scrip->ax_val_type |= STYPE_POINTER;
    if (sym.entries[propSym].flags & SFLG_CONST)
      scrip->ax_val_type |= STYPE_CONST;
  }

  if ((sym.entries[propSym].flags & SFLG_STATIC) == 0) {
    scrip->pop_reg(SREG_OP);
  }

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movslq -0x14(%rbp), %rsi
leaq 0x34bfc(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x2000, %rax           # imm = 0x2000
cmpq $0x0, %rax
jne 0xdcae
movq -0x10(%rbp), %rdi
movl $0x6, %esi
callq 0x252f0
movq -0x10(%rbp), %rdi
movl $0x2d, %esi
movl $0x3, %edx
callq 0x25200
cmpl $0x0, -0x18(%rbp)
je 0xdd0e
movslq -0x14(%rbp), %rsi
leaq 0x34bb1(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x4, %rax
cmpq $0x0, %rax
je 0xdceb
movq -0x10(%rbp), %rdi
movl $0x22, %esi
movl $0x4, %edx
callq 0x25200
jmp 0xdd05
leaq 0x244ff(%rip), %rdi     # 0x321f1
movb $0x0, %al
callq 0x1bac0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xe018
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
movslq -0x14(%rbp), %rsi
leaq 0x34b57(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x2, %rax
cmpq $0x0, %rax
je 0xdd8a
movslq -0x14(%rbp), %rsi
leaq 0x34b35(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x4, %rax
cmpq $0x0, %rax
je 0xdd67
movq -0x10(%rbp), %rdi
movl $0x22, %esi
movl $0x7, %edx
callq 0x25200
jmp 0xdd81
leaq 0x24483(%rip), %rdi     # 0x321f1
movb $0x0, %al
callq 0x1bac0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xe018
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
movslq -0x14(%rbp), %rsi
leaq 0x34adb(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x4, %rax
cmpq $0x0, %rax
je 0xddbd
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %edx
movl $0x27, %esi
callq 0x25200
cmpl $0x0, -0x18(%rbp)
je 0xdde4
movslq -0x14(%rbp), %rsi
leaq 0x34aa2(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq %rax, %rdi
callq 0x1e320
movl %eax, -0x20(%rbp)
jmp 0xde03
movslq -0x14(%rbp), %rsi
leaq 0x34a81(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq %rax, %rdi
callq 0x1e2e0
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jge 0xde23
leaq 0x24404(%rip), %rdi     # 0x32214
movb $0x0, %al
callq 0x1bac0
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0xe018
movq -0x10(%rbp), %rdi
movl -0x20(%rbp), %ecx
movl $0x6, %esi
movl $0x3, %edx
callq 0x25240
movslq -0x14(%rbp), %rsi
leaq 0x34a2c(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x4, %rax
cmpq $0x0, %rax
je 0xde95
movq -0x10(%rbp), %rdi
movl $0x4, %esi
callq 0x25820
movq -0x10(%rbp), %rdi
movl $0x21, %esi
movl $0x3, %edx
callq 0x25200
cmpl $0x0, -0x1c(%rbp)
jle 0xde93
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %edx
movl $0x23, %esi
callq 0x25200
jmp 0xdef5
movq -0x10(%rbp), %rdi
movl $0x2, %esi
callq 0x25820
movq -0x10(%rbp), %rdi
movl $0x17, %esi
movl $0x3, %edx
callq 0x25200
cmpl $0x0, -0x1c(%rbp)
jle 0xdef3
movl -0x1c(%rbp), %eax
shll $0x2, %eax
movslq %eax, %rdx
movq -0x10(%rbp), %rax
movq 0x8d40(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x8d40(%rax)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %ecx
shll $0x2, %ecx
movl $0x2, %esi
movl $0x1, %edx
callq 0x25240
jmp 0xdef5
cmpl $0x0, -0x18(%rbp)
jne 0xdfdf
movslq -0x14(%rbp), %rsi
leaq 0x34966(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movswl 0x30(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8d4c(%rax)
movq -0x10(%rbp), %rax
movl $0x2, 0x8d50(%rax)
movslq -0x14(%rbp), %rsi
leaq 0x34936(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x40000, %rax          # imm = 0x40000
cmpq $0x0, %rax
je 0xdf69
movq -0x10(%rbp), %rax
movl 0x8d4c(%rax), %ecx
orl $0x10000000, %ecx       # imm = 0x10000000
movl %ecx, 0x8d4c(%rax)
movslq -0x14(%rbp), %rsi
leaq 0x348fc(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x100, %rax            # imm = 0x100
cmpq $0x0, %rax
je 0xdfa3
movq -0x10(%rbp), %rax
movl 0x8d4c(%rax), %ecx
orl $0x40000000, %ecx       # imm = 0x40000000
movl %ecx, 0x8d4c(%rax)
movslq -0x14(%rbp), %rsi
leaq 0x348c2(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x10000, %rax          # imm = 0x10000
cmpq $0x0, %rax
je 0xdfdd
movq -0x10(%rbp), %rax
movl 0x8d4c(%rax), %ecx
orl $0x20000000, %ecx       # imm = 0x20000000
movl %ecx, 0x8d4c(%rax)
jmp 0xdfdf
movslq -0x14(%rbp), %rsi
leaq 0x34886(%rip), %rdi     # 0x42870
addq $0x28, %rdi
callq 0x17e60
movq 0x28(%rax), %rax
andq $0x2000, %rax           # imm = 0x2000
cmpq $0x0, %rax
jne 0xe011
movq -0x10(%rbp), %rdi
movl $0x6, %esi
callq 0x25330
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x20, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)