Skip to content

Commit

Permalink
Fix OCallMethod on HVirtual, when obj is in args (#701)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuxiaomao authored Aug 8, 2024
1 parent 703d29d commit 5e2b6f4
Showing 1 changed file with 28 additions and 9 deletions.
37 changes: 28 additions & 9 deletions src/jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -3631,6 +3631,7 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
int paramsSize;
int jhasfield, jend;
bool need_dyn;
bool obj_in_args = false;
vreg *obj = R(o->extra[0]);
preg *v = alloc_cpu_call(ctx,obj);
preg *r = alloc_reg(ctx,RCPU_CALL);
Expand All @@ -3655,7 +3656,10 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
vreg *a = R(o->extra[i+1]);
if( hl_is_ptr(a->t) ) {
op64(ctx,MOV,pmem(&p,r->id,i*HL_WSIZE),alloc_cpu(ctx,a,true));
if( a->current != v ) RUNLOCK(a->current);
if( a->current != v ) {
RUNLOCK(a->current);
} else
obj_in_args = true;
} else {
preg *r2 = alloc_reg(ctx,RCPU);
op64(ctx,LEA,r2,&a->stack);
Expand Down Expand Up @@ -3692,15 +3696,30 @@ int hl_jit_function( jit_ctx *ctx, hl_module *m, hl_function *f ) {
patch_jump(ctx,jhasfield);
restore_regs(ctx);

/*
o = o->value hack
*/
if( v->holds ) v->holds->current = NULL;
obj->current = v;
v->holds = obj;
op64(ctx,MOV,v,pmem(&p,v->id,HL_WSIZE));
if( !obj_in_args ) {
// o = o->value hack
if( v->holds ) v->holds->current = NULL;
obj->current = v;
v->holds = obj;
op64(ctx,MOV,v,pmem(&p,v->id,HL_WSIZE));
size = prepare_call_args(ctx,o->p3,o->extra,ctx->vregs,0);
} else {
// keep o->value in R(f->nregs)
int regids[64];
preg *pc = alloc_reg(ctx,RCPU_CALL);
vreg *sc = R(f->nregs); // scratch register that we temporary rebind
if( o->p3 >= 63 ) jit_error("assert");
memcpy(regids, o->extra, o->p3 * sizeof(int));
regids[0] = f->nregs;
sc->size = HL_WSIZE;
sc->t = &hlt_dyn;
op64(ctx, MOV, pc, pmem(&p,v->id,HL_WSIZE));
scratch(pc);
sc->current = pc;
pc->holds = sc;
size = prepare_call_args(ctx,o->p3,regids,ctx->vregs,0);
}

size = prepare_call_args(ctx,o->p3,o->extra,ctx->vregs,0);
op_call(ctx,r,size);
discard_regs(ctx, false);
store_result(ctx, dst);
Expand Down

0 comments on commit 5e2b6f4

Please sign in to comment.