:TITLE[Fncall.0mc...February 21, 1985 3:44 PM, van Melle]; * Fn0, op 010, Call function of 0 args whose name is in first 2 bytes @Fn0: lspNargs _ 0c, goto[FnxTail], opcode[010]; * Fn1, op 011, Call function of 1 args whose name is in first 2 bytes @Fn1: lspNargs _ 1c, goto[FnxTail], opcode[011]; * Fn2, op 012, Call function of 2 args whose name is in first 2 bytes @Fn2: lspNargs _ 2c, goto[FnxTail], opcode[012]; * Fn3, op 013, Call function of 3 args whose name is in first 2 bytes @Fn3: lspNargs _ 3c, goto[FnxTail], opcode[013]; * Fn4, op 014, Call function of 4 args whose name is in first 2 bytes @Fn4: lspNargs _ 4c, goto[FnxTail], opcode[014]; * Fnx, op 015, Fully general function call, first byte is number of args, next 2 bytes are atom @Fnx: T _ NextData[IBuf], opcode[015]; lspNargs _ T, goto[FnxTail]; * Get number of args FnxTail: T _ NextData[IBuf]; lspDefx1 _ T; T _ NextData[IBuf]; loadpage[pgFrame]; lspDefx1 _ (lsh[lspDefx1, 10]) or T, gotop[lspCallFn0]; * CheckApply*, op 017: Punt if TOS is not ccodep or is NLAMBDA* @CheckApply: T _ lsh[Stack&-1, 1], skip[R<0], opcode[17]; lspGenBrHi _ (DEFspace), skip; * use first seg of def space lspGenBrHi _ (DEFspace2); * use second seg of def space lu _ Stack&+1; lspGenBr _ (DEFbase), skip[alu=0]; lspUFN _ 17c, goto[ufnLBL]; * TOS not atom nop; * Wait for base to be written because fetch can fault PFetch2[lspGenBr, lspL0]; * fetch function definition cell lspL0 _ (lspL0) and (10000c), goto[ApplyStarUfn, R>=0]; * Ufn if codep bit off skip[alu#0]; NextOpCode; lspUFN _ 17c, goto[ufnLBL]; ApplyStarUfn: lspUFN _ 17c, goto[ufnLBL]; * Applyfn, op 016: * apply function whose name is TOS and number of args is TOS-2 * This checks for 3 elements on stack because StkState cannot * indicate no elements on stack @Applyfn: nop, opcode[016]; ApplyFn: loadpage[pgHStack], call[CheckElt3P4]; T _ Stack&-1; lspDefx1 _ T; T _ Stack&-1; lspDefx0 _ T; T _ Stack&-2; lspNargs _ T, loadpage[pgFrame]; StkState _ rsh[StkState, 2], gotop[lspCallfn]; onpage[opPage0]; lspUfnxP4: T _ SStkp; lspL4 _ T, loadpage[pgUfnxA]; T _ (PcxReg); onpage[pgUfnxA]; Stkp _ lspL4, lspL4 _ T, NoRegILockOk, task; * Stkp backed up to as of start of opcode * LspL4 = PCF as of start of opcode T _ (PCFReg); lu _ (lspL4) - T; * has PCF changed (i.e. more bytes fetched)? lspGenBrHi _ STATSspace, skip[alu=0]; PCF _ lspL4; * yes, restore it. Can't be unconditional * because only low 3 bits of PCF can be loaded lspGenBr _ UFNTableBase; T _ lsh[lspUFN, 1]; * index into double-word ufn table PFetch2[lspGenBr, lspL2]; * fetch function definition T _ rhmask[lspL3]; * get number of args lspL3 _ rsh[lspL3, 10]; * number of extra bytes (0-2) lspNargs _ T, goto[lspUfnx4a, alu=0]; * skip much if no extra bytes T _ NextData[IBuf]; lu _ lspL3, goto[lspUfnx4b, R Odd]; lspL1 _ T; T _ NextData[IBuf]; T _ (lsh[lspL1, 10]) or T; lspUfnx4b: Stack&+1 _ (smallpl); Stack&+1 _ T; * Push extra byte(s) as smallp StkState _ lsh[StkState, 1]; lspUfnx4a: T _ lspL2, loadpage[pgFrame]; * Ufn atom lspDefx1 _ T, gotop[lspCallfn0]; * call the function :END[Fncall];