Changeset 6557


Ignore:
Timestamp:
May 16, 2007, 7:23:04 AM (15 years ago)
Author:
gb
Message:

finish_function_entry: there's a return address on the top of the
stack when this is entered (#-of-arguments traps). Put it in the
right place when building the frame.

create_exception_callback_frame: look for tra on top of lisp stack,
not in register (usually.)

handle_error(): if we return after calling out for int #xc7 (call
to undefined function), fix up the stack and other registers so
that we can return the value(s) returned by the lisp-side handler.
(It's hard for the lisp-side handler to do the stack manipulation,
because of the xcf on the stack and because of the need to deal
with the return address on the stack.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/ccl/lisp-kernel/x86-exceptions.c

    r6540 r6557  
    274274  natural nargs = (xpGPR(xp,Inargs)&0xffff)>> fixnumshift;
    275275  signed_natural disp = nargs-3;
    276   LispObj *vsp =  (LispObj *) xpGPR(xp,Isp);
     276  LispObj *vsp =  (LispObj *) xpGPR(xp,Isp), ra = *vsp++;
    277277   
    278278 
    279279  if (disp > 0) {               /* implies that nargs > 3 */
    280280    vsp[disp] = xpGPR(xp,Irbp);
    281     vsp[disp+1] = xpGPR(xp,Ira0);
     281    vsp[disp+1] = ra;
    282282    xpGPR(xp,Irbp) = (LispObj)(vsp+disp);
     283    xpGPR(xp,Isp) = (LispObj)vsp;
    283284    push_on_lisp_stack(xp,xpGPR(xp,Iarg_x));
    284285    push_on_lisp_stack(xp,xpGPR(xp,Iarg_y));
    285286    push_on_lisp_stack(xp,xpGPR(xp,Iarg_z));
    286287  } else {
    287     push_on_lisp_stack(xp,xpGPR(xp,Ira0));
     288    push_on_lisp_stack(xp,ra);
    288289    push_on_lisp_stack(xp,xpGPR(xp,Irbp));
    289290    xpGPR(xp,Irbp) = xpGPR(xp,Isp);
     
    322323
    323324  f = xpGPR(xp,Ifn);
    324   tra = xpGPR(xp,Ira0);
     325  tra = *(LispObj*)(xpGPR(xp,Isp));
    325326  if (tag_of(tra) == tag_tra) {
    326327    if ((*((unsigned short *)tra) == RECOVER_FN_FROM_RIP_WORD0) &&
     
    332333      tra_f = 0;
    333334    }
     335  } else {
     336    tra = 0;
    334337  }
    335338
     
    484487    xpGPR(xp,Irbp) = save_rbp;
    485488    xpGPR(xp,Isp) = save_vsp;
    486     xpPC(xp) += skip;
     489    if ((op0 == 0xcd) && (op1 == 0xc7)) {
     490      /* Continue after an undefined function call. The function
     491         that had been undefined has already been called (in the
     492         break loop), and a list of the values that it returned
     493         in in the xp's %arg_z.  A function that returns those
     494         values in in the xp's %fn; we just have to adjust the
     495         stack (keeping the return address in the right place
     496         and discarding any stack args/reserved stack frame),
     497         then set nargs and the PC so that that function's
     498         called when we resume.
     499      */
     500      LispObj *vsp =(LispObj *)save_vsp, ra = *vsp;
     501      int nargs = (xpGPR(xp, Inargs) & 0xffff)>>fixnumshift;
     502     
     503      if (nargs > 3) {
     504        xpGPR(xp,Isp)=(LispObj) (vsp + (1 + 2 + (nargs - 3)));
     505        push_on_lisp_stack(xp,ra);
     506      }
     507      xpPC(xp) = xpGPR(xp,Ifn);
     508      xpGPR(xp,Inargs) = 1<<fixnumshift;
     509    } else {
     510      xpPC(xp) += skip;
     511    }
    487512    return true;
    488513  } else {
Note: See TracChangeset for help on using the changeset viewer.