4.3BSD/usr/contrib/icon/lib/coact.s
/*
* coact(coexpr,value) - suspend current co-expression and activate
* coexpr with value.
*
* Outline:
* create procedure frame
* save sp and boundary in current co-expression stack header
* dereference result if it is local to co-expression
* change current stack to coexpr
* set activator in new co-expression stack header
* get sp and boundary from new co-expression stack header
* return value in new stack
*/
Global(_boundary) /* Icon/C boundary */
Global(_current) /* current co-expression */
Global(_file) /* current file name */
Global(_line) /* current line number */
Global(_deref) /* dereference */
Global(_runerr) /* runtime error */
Global(_coact)
#ifdef VAX
_coact:
Mask STDSV
calls $0,_setbound
subl2 $8,sp # Make room on stack for line and file
movl _line,-4(fp) # and put them in the frame
movl _file,-8(fp)
movl _current+4,r2 # r2 <- pointer to current stack header
movl sp,16(r2) # save the stack pointer,
movl ap,20(r2) # address pointer,
movl _boundary,24(r2)# and boundary for the current co-expression
# in its stack header
moval 8(ap),r4 # point r4 at coexp argument on stack
pushl r4 # and
calls $1,_deref # dereference the co-expression
cmpl $D_ESTACK,(r4)+ # see if we indeed have a co-expression
# and if we don't, it's runnerr 118,
# "co-expression expected"
jeql f1
tstl -(r4) # back up to point at bogus co-expression
pushl r4 # and call runerr with the bogon as
pushl $118 # its argument
calls $2,_runerr
f1:
movl (r4)+,r3 # point r3 at the co-expression stack header
movl $D_ESTACK,4(r3) # create the descriptor for the activator
movl r2,8(r3) # (r2 has pointer to previously current
# co-expression, which is the activator)
movl r3,_current+4 # make the new co-expression current
movl 16(r3),sp # get stack pointer,
movl 20(r3),ap # address pointer,
movl 24(r3),fp # and frame pointer/boundary from header
movl fp,_boundary
movl 4(ap),r1 # get nargs in r1
movaq 8(ap)[r1],r0 # point r0 at target for result on stack,
movl r0,r1 # and save the pointer
movq (r4),(r1) # copy value from old stack to new
movl r1,r4 # point r4 at address of result on new stack
movl (r4),r1 # get type field of new result
bitl $F_NQUAL,r1 # if return value points into the old
jeql f11 # co-expression, then it needs
bitl $F_VAR,r1 # dereferencing
jeql f11
bitl $F_TVAR,r1
jneq f2
movl 4(r4),r1 # get pointer field of result into r1
jbr f3
f2:
bicl2 $~TYPEMASK,r1 # isolate type bits by turning off others
cmpl $T_TVSUBS,r1 # if we have a substring t.v., we have
jneq f11 # to dereference it.
movl 4(r4),r1 # point r1 at the string of the
movl 16(r1),r1 # trapped variable (cmt??)
f3:
cmpl r1,16(r2) # if pointer is between old sp and sbase,
jlss f11 # it needs dereferencing
cmpl r1,12(r2)
jgtr f11
pushl r4
calls $1,_deref # so, dereference it
f11:
movl -4(fp),_line # restore line number
movl -8(fp),_file # and file name
calls $0,_clrbound
ret # return. This return will use the dummy
# frame built above and we should land in
# first frame built above
#endif VAX
#ifdef PORT
DummyFcn(_coact)
#endif PORT
#ifdef PDP11
/ coact(coexpr,value) - suspend current co-expression and activate
/ coexpr with value.
/ NOTE: this code is highly dependent on stack frame layout.
/ Outline:
/ create procedure frame
/ save sp and boundary in current co-expression stack header
/ dereference result if it is local to co-expression
/ change current stack to coexpr
/ set activator in new co-expression stack header
/ get sp and boundary from new co-expression stack header
/ return value in new stack
/ Register usage:
/ r2: pointer to current co-expression stack header
/ r3: pointer to new co-expression stack header
/ r4: pointer to arguments to activate
/ r5: procedure frame pointer
Global(csv) / save registers
Global(cret) / return as from C
_coact:
jsr r5,csv / create procedure frame
mov _line,(sp) / save current line number
mov _file,-(sp) / and file name
mov _current+2,r2 / r2 <- pointer to current stack header
mov sp,8.(r2) / save sp
mov _boundary,12.(r2) / save boundary
mov r5,r4 / r4 <- pointer to coexpr
add $6,r4
mov r4,-(sp) / dereference coexpr
jsr pc,_deref
tst (sp)+
cmp $D_ESTACK,(r4)+ / check type field of coexpr
beq 1f
tst -(r4)
mov r4,-(sp)
mov $118.,-(sp) / runerr 118 - co-expression expected
jsr pc,_runerr
1:
mov (r4)+,r3 / r3 <- pointer to new stack header
mov $D_ESTACK,2(r3) / set activator field of new stack header
mov r2,4(r3)
mov r3,_current+2 / make new stack header current
mov 8.(r3),sp / get new sp
mov 12.(r3),r5 / get new r5 and
mov r5,_boundary / new boundary
mov 4(r5),r0 / r0 <- location of result on new stack
asl r0 / (r0 <- 6 + 4*nargs)
asl r0
add r5,r0
add $6,r0
mov r0,r1 / remember address of result on new stack
mov (r4)+,(r0)+ / copy value from old stack
mov (r4)+,(r0)
mov r1,r4 / r4 <- address of result on new stack
mov (r4), r1 / get type field of return value into r1
bit $F_NQUAL,r1 / if return value points into the old
beq 1f / co-expression, then it needs
bit $F_VAR,r1 / dereferencing
beq 1f
bit $F_TVAR,r1
bne 2f
mov 2(r4),r1 / get pointer field into r1
br 3f
2:
bic $!TYPEMASK,r1 / check type code for substring t.v.
cmp $T_TVSUBS,r1 / if not, it doesn't need
bne 1f / dereferencing
mov 2(r4),r1 / get pointer field from b_tvsubs
mov 8.(r1),r1 / block into r1
3:
cmp r1,8.(r2) / if pointer is between old
blo 1f / sp and sbase it needs
cmp r1,6.(r2) / dereferencing
bhi 1f
mov r4,(sp) / dereference it
jsr pc,_deref
tst (sp)+
1:
mov -8.(r5),_line / restore line number
mov -10.(r5),_file / and file name
jmp cret / return in new stack
#endif PDP11