-asm_check_clinit:
- mov 0(%rsp),itmp1
- mov offclassinit(itmp1),itmp1l /* get initialized flag (int) */
- test itmp1,itmp1
- jnz L_is_initialized
-
- sub $(14*8),%rsp /* keep stack 16-byte aligned */
-
- mov a0,0*8(%rsp) /* save argument registers */
- mov a1,1*8(%rsp)
- mov a2,2*8(%rsp)
- mov a3,3*8(%rsp)
- mov a4,4*8(%rsp)
- mov a5,5*8(%rsp)
-
- movq fa0,6*8(%rsp) /* maybe cacao does not use all 8 */
- movq fa1,7*8(%rsp) /* argument register, but who knows */
- movq fa2,8*8(%rsp)
- movq fa3,9*8(%rsp)
- movq fa4,10*8(%rsp)
- movq fa5,11*8(%rsp)
- movq fa6,12*8(%rsp)
- movq fa7,13*8(%rsp)
-
- mov 14*8(%rsp),%rdi /* pass classinfo pointer */
- call initialize_class /* call class initialize function */
-
- mov 0*8(%rsp),a0 /* restore argument registers */
- mov 1*8(%rsp),a1
- mov 2*8(%rsp),a2
- mov 3*8(%rsp),a3
- mov 4*8(%rsp),a4
- mov 5*8(%rsp),a5
-
- movq 6*8(%rsp),fa0
- movq 7*8(%rsp),fa1
- movq 8*8(%rsp),fa2
- movq 9*8(%rsp),fa3
- movq 10*8(%rsp),fa4
- movq 11*8(%rsp),fa5
- movq 12*8(%rsp),fa6
- movq 13*8(%rsp),fa7
-
- add $(14*8),%rsp /* remove stack frame */
-
- test v0,v0 /* we had an exception */
- je L_initializererror
-
-L_is_initialized:
- mov 24(%rsp),itmp1 /* get return address */
- sub $5,itmp1 /* remove size of `call rel32' */
-
- mov 16(%rsp),itmp2 /* get xmcode machine code */
- movb itmp2b,(itmp1) /* patch back in 1 byte */
- mov 8(%rsp),itmp2 /* get mcode machine code */
- movl itmp2l,1(itmp1) /* patch back in 4 bytes */
-
- add $((3+1)*8),%rsp /* remove stub stack frame incl. ra */
-
- jmp *itmp1 /* jump to patched code an execute it */
-
-L_initializererror:
+asm_wrapper_patcher:
+ push bp /* save base pointer */
+ mov sp,bp /* move actual sp to bp */
+ sub $((3+ARG_CNT+TMP_CNT)*8+sizestackframeinfo),sp
+ and $0xfffffffffffffff0,sp /* align sp to 16-byte (this is for */
+ /* leaf functions) */
+
+ SAVE_ARGUMENT_REGISTERS(3)
+ SAVE_TEMPORARY_REGISTERS(3+ARG_CNT)
+
+ mov itmp1,0*8(sp) /* save itmp1 and itmp2 */
+ mov itmp2,1*8(sp) /* can be used by some instructions */
+
+ mov sp,a0 /* create stackframe info */
+ add $((3+ARG_CNT+TMP_CNT)*8),a0
+ xor a1,a1 /* if pv is NULL, use findmethod */
+ mov bp,a2 /* pass java sp */
+ add $((6+1)*8),a2
+ mov ((5+1)*8)(bp),a3 /* pass ra to java function */
+ mov a3,a4 /* xpc is equal to ra */
+ call stacktrace_create_extern_stackframeinfo
+
+ mov bp,a0 /* pass stack pointer */
+ add $((1+1)*8),a0 /* skip function pointer */
+ mov 1*8(bp),itmp3 /* get function pointer */
+ call *itmp3 /* call the patcher function */
+ mov v0,2*8(sp) /* save return value */
+
+ mov sp,a0 /* remove stackframe info */
+ add $((3+ARG_CNT+TMP_CNT)*8),a0
+ call stacktrace_remove_stackframeinfo
+
+ RESTORE_ARGUMENT_REGISTERS(3)
+ RESTORE_TEMPORARY_REGISTERS(3+ARG_CNT)
+
+ mov 0*8(sp),itmp1 /* restore itmp1 and itmp2 */
+ mov 1*8(sp),itmp2 /* can be used by some instructions */
+ mov 2*8(sp),itmp3 /* restore return value */
+
+ mov bp,sp /* restore original sp */
+ pop bp /* restore bp */
+ add $(5*8),sp /* remove patcher stackframe, keep ra */
+
+ test itmp3,itmp3 /* exception thrown? */
+ jz L_asm_wrapper_patcher_exception
+ ret /* call new patched code */
+
+L_asm_wrapper_patcher_exception: