// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, %ebp
movq %rdi, %rbx
movslq %esi, %rcx
leaq 0x1bf94(%rip), %r12     # 0x256e0
movq 0x28(%r12), %rax
imulq $0xb0, %rcx, %r15
testb $0x20, 0x29(%rax,%r15)
jne 0x9784
movq %rbx, %rdi
movl $0x6, %esi
callq 0x134f6
movq %rbx, %rdi
movl $0x2d, %esi
movl $0x3, %edx
callq 0x1346e
movq 0x28(%r12), %rax
testl %ebp, %ebp
je 0x97af
testb $0x4, 0x28(%rax,%r15)
je 0x97bf
movq %rbx, %rdi
movl $0x22, %esi
movl $0x4, %edx
callq 0x1346e
movq 0x28(%r12), %rax
movl $0x1, %r14d
jmp 0x97b2
xorl %r14d, %r14d
movq 0x28(%rax,%r15), %rax
testb $0x2, %al
je 0x97ea
testb $0x4, %al
jne 0x97cb
leaq 0x11a97(%rip), %rdi     # 0x1b25d
jmp 0x9888
movq %rbx, %rdi
movl $0x22, %esi
movl $0x7, %edx
callq 0x1346e
incl %r14d
movq 0x28(%r12), %rax
movq 0x28(%rax,%r15), %rax
testb $0x4, %al
je 0x97fe
movq %rbx, %rdi
movl $0x27, %esi
movl %r14d, %edx
callq 0x1346e
movq 0x28(%r12), %rdi
addq %r15, %rdi
testl %ebp, %ebp
je 0x9811
callq 0x110e6
jmp 0x9816
callq 0x110d0
testl %eax, %eax
js 0x9881
movq %rbx, %rdi
movl $0x6, %esi
movl $0x3, %edx
movl %eax, %ecx
callq 0x1348e
movq 0x28(%r12), %rax
testb $0x4, 0x28(%rax,%r15)
jne 0x989f
movq %rbx, %rdi
movl $0x2, %esi
callq 0x137c6
movq %rbx, %rdi
movl $0x17, %esi
movl $0x3, %edx
callq 0x1346e
testl %r14d, %r14d
je 0x98d3
shll $0x2, %r14d
subq %r14, 0x8d40(%rbx)
movq %rbx, %rdi
movl $0x2, %esi
movl $0x1, %edx
movl %r14d, %ecx
callq 0x1348e
jmp 0x98d3
leaq 0x119f8(%rip), %rdi     # 0x1b280
xorl %eax, %eax
callq 0x102f4
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movl %ebp, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq %rbx, %rdi
movl $0x4, %esi
callq 0x137c6
movq %rbx, %rdi
movl $0x21, %esi
movl $0x3, %edx
callq 0x1346e
testl %r14d, %r14d
je 0x98d3
movq %rbx, %rdi
movl $0x23, %esi
movl %r14d, %edx
callq 0x1346e
movq 0x28(%r12), %rax
testl %ebp, %ebp
je 0x98e3
movq 0x28(%rax,%r15), %rax
jmp 0x9932
movswl 0x30(%rax,%r15), %ecx
movl %ecx, 0x8d4c(%rbx)
movl $0x2, 0x8d50(%rbx)
movq 0x28(%rax,%r15), %rax
testl $0x50100, %eax          # imm = 0x50100
je 0x9932
movl %eax, %edx
shll $0xa, %edx
andl $0x10000000, %edx       # imm = 0x10000000
movl %eax, %esi
shll $0x16, %esi
andl $0x40000000, %esi       # imm = 0x40000000
orl %edx, %esi
movl %eax, %edx
shll $0xd, %edx
andl $0x20000000, %edx       # imm = 0x20000000
orl %esi, %edx
orl %ecx, %edx
movl %edx, 0x8d4c(%rbx)
xorl %ebp, %ebp
btl $0xd, %eax
jb 0x9894
movq %rbx, %rdi
movl $0x6, %esi
callq 0x13524
jmp 0x9894