// File: /workspace/github_cpp_makefile_star2_O2/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 0x1c91e(%rip), %r12     # 0x256f0
movq 0x28(%r12), %rax
imulq $0xb0, %rcx, %r15
testb $0x20, 0x29(%rax,%r15)
jne 0x8e04
pushq $0x6
popq %rsi
movq %rbx, %rdi
callq 0x11ed2
pushq $0x2d
popq %rsi
pushq $0x3
popq %rdx
movq %rbx, %rdi
callq 0x11e4a
movq 0x28(%r12), %rax
testl %ebp, %ebp
je 0x8e29
testb $0x4, 0x28(%rax,%r15)
je 0x8e39
pushq $0x22
popq %rsi
pushq $0x4
popq %rdx
movq %rbx, %rdi
callq 0x11e4a
movq 0x28(%r12), %rax
pushq $0x1
popq %r14
jmp 0x8e2c
xorl %r14d, %r14d
movq 0x28(%rax,%r15), %rax
testb $0x2, %al
je 0x8e60
testb $0x4, %al
jne 0x8e45
leaq 0x103fd(%rip), %rdi     # 0x1923d
jmp 0x8eee
pushq $0x22
popq %rsi
pushq $0x7
popq %rdx
movq %rbx, %rdi
callq 0x11e4a
incl %r14d
movq 0x28(%r12), %rax
movq 0x28(%rax,%r15), %rax
testb $0x4, %al
je 0x8e72
pushq $0x27
popq %rsi
movq %rbx, %rdi
movl %r14d, %edx
callq 0x11e4a
movq 0x28(%r12), %rdi
addq %r15, %rdi
testl %ebp, %ebp
je 0x8e85
callq 0xfece
jmp 0x8e8a
callq 0xfeba
testl %eax, %eax
js 0x8ee7
pushq $0x6
popq %rsi
pushq $0x3
popq %rdx
movq %rbx, %rdi
movl %eax, %ecx
callq 0x11e6a
movq 0x28(%r12), %rax
testb $0x4, 0x28(%rax,%r15)
jne 0x8f03
pushq $0x2
popq %rsi
movq %rbx, %rdi
callq 0x120e4
pushq $0x17
popq %rsi
pushq $0x3
popq %rdx
movq %rbx, %rdi
callq 0x11e4a
testl %r14d, %r14d
je 0x8f2f
shll $0x2, %r14d
subq %r14, 0x8d40(%rbx)
pushq $0x2
popq %rsi
pushq $0x1
popq %rdx
movq %rbx, %rdi
movl %r14d, %ecx
callq 0x11e6a
jmp 0x8f2f
leaq 0x10372(%rip), %rdi     # 0x19260
xorl %eax, %eax
callq 0xf258
pushq $-0x1
popq %rbp
movl %ebp, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
pushq $0x4
popq %rsi
movq %rbx, %rdi
callq 0x120e4
pushq $0x21
popq %rsi
pushq $0x3
popq %rdx
movq %rbx, %rdi
callq 0x11e4a
testl %r14d, %r14d
je 0x8f2f
pushq $0x23
popq %rsi
movq %rbx, %rdi
movl %r14d, %edx
callq 0x11e4a
movq 0x28(%r12), %rax
testl %ebp, %ebp
je 0x8f3f
movq 0x28(%rax,%r15), %rax
jmp 0x8f8e
movswl 0x30(%rax,%r15), %ecx
movl %ecx, 0x8d4c(%rbx)
movl $0x2, 0x8d50(%rbx)
movq 0x28(%rax,%r15), %rax
testl $0x50100, %eax          # imm = 0x50100
je 0x8f8e
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 0x8ef8
pushq $0x6
popq %rsi
movq %rbx, %rdi
callq 0x11eea
jmp 0x8ef8