⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 txtmgr.asm

📁 Microsoft MS-DOS6.0 完整源代码
💻 ASM
📖 第 1 页 / 共 5 页
字号:
;
; When all pcode references to a prs have been deleted,
; and the prs has no text table, PrsFree is called to remove the entry.
;
; The management of "defining" references happens in two stages during
; an edit.  When a "defining" reference is deleted, prs.otxDef is set
; to undefined by UndefPrs.  At the end of the edit operation, RedefOrDelPrs
; is called to search for a new "defining" reference, or free the prs.
;
; This is done in two stages as a speed optimization for text edits.
; This will help speed up the cases where you are discarding text
; tables, or terminating ASCII load because of an out of memory error.
; This way we accumulate and process all prs defining reference changes
; at one time.
;
;			Call Trees
;			==========
;
; Deleting a defining reference
; -----------------------------
; MrsDiscard   PrsDiscard
;	  \    /
;          \  /
;       TxtDiscard                     ParseLine
;           |                             |
;       TxtDelete             ParseUndo MakeProc (when renaming a sub/function)
;           |                        |    |
;   ForEachPrsInPlaceCP(UpdatePrs)   |	  |
;			      |      |	  |
;			      +------+----+
;				     |
;				  UndefPrs
;
; End of edit - find new defining reference
; -----------------------------------------
;    TxtChange	    LoadFile
;	 |	       |
;	 |	       |
;	 |	       |
;	 |	      MrsDiscard   PrsDiscard
;	 |	       |      \     /	  |
;	 |	       |     PrsDiscard1  |
;	 |	       |		  |
;	 +-------------+------------------+
;		  |
;	   ChkAllUndefPrs		 
;		  |			 
;		  --------
;		  |	 |
;	          | 	 
;	   ForEachCP(TryToDefPrs)
;
;--------------------------------------------------------------------

sBegin	DATA

;** the static structure uPrs is defined in SetPrsDefn header
DPRS_ST	STRUC
DPRS_oRs		DW 1 DUP (?)
DPRS_oMrs		DW 1 DUP (?)
DPRS_otx		DW 1 DUP (?)
DPRS_flags		DB 1 DUP (?)
DPRS_ST	ENDS

dprs	DB size DPRS_ST DUP (?)

;** the static structure uPrs is defined in UpdatePrs's header
UPRS_ST	STRUC
UPRS_oRsEdit		DW 1 DUP(?)
UPRS_otxEdit		DW 1 DUP(?)
UPRS_cbDel		DW 1 DUP(?)
UPRS_cbIns		DW 1 DUP(?)
UPRS_oPrsDel		DW 1 DUP (?)
UPRS_fPrsDelFound	DW 1 DUP (?)
UPRS_fNoRefSameMod	DW 1 DUP (?)
UPRS_oMrsRefDel		DW 1 DUP (?)
UPRS_ST	ENDS

uprs	DB size UPRS_ST DUP (?)

sEnd	DATA

sBegin	CP
assumes	cs,CP

;**************************************************************
; void SetPrsDefn
; Purpose:
;	Called when a prs reference is inserted in pcode.  If this is the
;	"most powerful" definition we've seen so far for the current prs,
;	the the prs entry is changed to remember this text offset
;	as the "defining" reference.
;
; Entry:
;	dprs.DPRS_oRs,oMrs,otx identify where in the pcode
;	  the reference lives.
;	dprs.DPRS_flags = FP_DEFINED if this is for a SUB/FUNCTION/DEF FN stmt.
;	                = FP_DECLARED if this is for a DECLARE stmt.
;	                = 0 if this is for a CALL stmt.
;	grs.oPrsCur identifies the prs being referenced.
;
;**************************************************************
SetPrsDefn PROC NEAR
	test	[dprs.DPRS_flags],FP_DEFINED
	jne	SpNewDef		;brif reference is SUB,FUNC,DEF FN stmt
	test	[prsCur.PRS_flags],FP_DEFINED
	jne	SpNoNewDef		;brif prs is already defined by SUB,...
	test	[dprs.DPRS_flags],FP_DECLARED
	jne	SpNewDef		;brif reference is DECLARE
	test	[prsCur.PRS_flags],FP_DECLARED
	jne	SpNoNewDef		;brif prs is already declared
SpNewDef:
	;Got a SUB, FUNCTION or DEF FN   OR
	;    a DECLARE for prs with no definition  OR
	;    a CALL to an as yet undeclared, undefined SUB.
	; This is the "most powerful" reference seen so far,
	; make this text reference the new owner of the prs entry.
	
	; We need to set prsCur.oMrs even though in most cases, it
	; is redundant given prsCur.oRsDef.  The case where it is
	; valuable info is for DECLAREd prs's with no text tables.
	; If it were not set here, there would be cases when ForEachPrsInMrs
	; would not pick up this prs
	
	mov	ax,[dprs.DPRS_oRs]
	mov	[prsCur.PRS_oRsDef],ax
	mov	ax,[dprs.DPRS_otx]
	mov	[prsCur.PRS_otxDef],ax
	mov	al,[dprs.DPRS_flags]
	or	[prsCur.PRS_flags],al
	test	[txdCur.TXD_flags],FTX_mrs
	je	SpNoNewDef		;brif prs has text table
					;If we didn't, commenting out
					;a SUB stmt would move the prs to
					;another module.
	mov	ax,[dprs.DPRS_oMrs]
	mov	[prsCur.PRS_oMrs],ax
	cmp	[prsCur.PRS_procType],PT_DEFFN
	jne	SpNoNewDef		;brif not a DEF FN
	mov	[prsCur.PRS_oRsDef],ax	;for DEF FNs, the oRsDef is the
					; module's text table.
SpNoNewDef:
	ret
SetPrsDefn ENDP

;**************************************************************
; boolean TryToDefPrs()
; Purpose:
;	Called to see if current text table contains any references
;	to prs uprs.UPRS_oPrsDel.
;
; Entry:
;	uprs.UPRS_oPrsDel is the prs whose reference has been deleted
;uprs.UPRS_oMrsRefDel is the mrs from which the reference was deleted
;uprs.UPRS_fNoRefSameMod: if TRUE then TryToDefPrs must search for
;	a reference to oPrsDel in text tables of module oMrsDel.
;dprs.DPRS_flags: if set to 0 then TryToDefPrs must search for any
;	ref's to oPrsDel. 
; Exit:
;uprs.UPRD_fNoRefSameMod is set to FALSE if it is TRUE on entry and 
;	the text table being searched is in module uprs.UPRS_oMrsRefDel
;	and a ref to procedure uprs.UPRS_oPrsDel is found.
;	uprs.UPRS_fPrsDelFound = TRUE if any other references were found
;	if a "defining" reference is found (i.e. anything but a CALL),
;	   dprs.DPRS_oRs,otx are set to identify the text table and text
;	   offset for the new "defining" reference.
;dprs.DPRS_flags is set to FP_DECLARED if a DECLARE for the deleted
;	Prs is found.
;FALSE is returned when no more searching is required, i.e. when
;	dprs.DPRS_flags = FP_DECLARED and uprs.UPRS_fNoRefSameMod
;	is FALSE.
;	
; 
;**************************************************************
TryToDefPrs PROC NEAR
	push	si			;save caller's si,di
	push	di			
	cmp	[txdCur.TXD_ScanState],SS_SUBRUDE 
	je	JE_TryDone		;	
	mov	di,[uprs.UPRS_fNoRefSameMod] 
	or	di,di			
	jz	TrySearch		;brif already found another ref
					; to the proc in the module with 
					; the deleted reference
	mov	di,[uprs.UPRS_oMrsRefDel] ;di = oMrs of module from which
					; a reference was deleted
	sub	di,[grs.GRS_oMrsCur]	;di = 0 iff the text table is in
					; the same module as the text tbl
					; from which a ref was deleted
	jz	TrySearch		;brif in same module as deleted ref
	test	[dprs.DPRS_flags],FP_DECLARED 
	jnz	TryDone			;exit if we don't need to search
					; this text table for a declare
TrySearch:	 			
	call	TxtDescanCP		;descan current txt tbl to SS_PARSE
	sub	ax,ax
	push	ax
	PUSHI	ax,<CODEOFFSET tOpPrsDef>
	call	TxtFindOp		;ax = offset to 1st opcode in cur text
					; table with prs operand
					;dl = [txtFindIndex]
TryLoop:
	mov	si,ax			;si = otxCur
	cmp	dl,PRSDEF_opEot
JE_TryDone:				
	je	TryDone			;brif done with text table
	add	ax,4			;advance to oPrs operand
	cmp	dl,PRSDEF_opStDefFn
	jne	TryNotDefFn		;brif ref is not a DEF FN
	inc	ax			;skip DEF FN's link field
	inc	ax
TryNotDefFn:
	call	GetWOtx			;ax = oPrs of reference (ax)
	cmp	ax,[uprs.UPRS_oPrsDel]
	jne	TryNext			;brif not ref to prs of interest
	mov	[uprs.UPRS_fNoRefSameMod],di  ;set flag indicating whether
					      ; or not another ref was found
					      ; in module of deleted ref
	test	[dprs.DPRS_flags],FP_DECLARED 
	jnz	TryExit1		;brif not searching for defining ref
	mov	[uprs.UPRS_fPrsDelFound],sp
					;tell caller we found a reference
	;remember where new reference is in static dprs struct
	mov	ax,[grs.GRS_oRsCur]
	mov	[dprs.DPRS_oRs],ax
	mov	ax,[grs.GRS_oMrsCur]
	mov	[dprs.DPRS_oMrs],ax
	mov	[dprs.DPRS_otx],si	;save otxCur
	cmp	[txtFindIndex],PRSDEF_DefineMax
	ja	TryNext			;brif reference was a CALL

	;Since this is only called when the current "defining"
	;reference has been deleted, we know we're never going
	;to find a SUB or FUNCTION pcode.  A DECLARE is the
	;strongest definition we can hope to find, so there's
	;no need to search any further
	
	test	[mrsCur.MRS_flags2],FM2_INCLUDE ;is this an INCLUDE mrs?
	jne	TryNext 		;force it to a "weak" owner

	mov	[dprs.DPRS_flags],FP_DECLARED
TryExit1:
	xchg	ax,di			;ax = 0 iff no longer need to search
	jmp	SHORT TryExit

TryNext:
;if we've just seen a CALL ref, keep searching for DECLARE
	push	si
	PUSHI	ax,<CODEOFFSET tOpPrsDef>
	call	TxtFindNextOp
	jmp	SHORT TryLoop

TryDone:
	mov	ax,sp			;return TRUE (non zero)
TryExit:
	pop	di			;restore caller's di
	pop	si			;restore caller's si
	ret	
TryToDefPrs ENDP

;**************************************************************
; FreeAllUndefinedPrs, ChkAllUndefPrs, ChkAllUndefPrsSaveRs
; Purpose:
;	FreeAllUndefinedPrs has two purposes:
;	(1) It is called to check all prs's to see
;	if the the "defining" text reference to a prs has
;	been marked as deleted. If so, it calls RedefOrDelPrs
;	to search for a new "definition" if none are found, then
;	the Prs is released via PrsFree.
;	(2) It is called to check all prs's to see
;	if the last reference to the prs has been deleted from the
;	module being editted. 
;	ChkAllUndefPrs differs from FreeAllUndefPrs in that it 
;	knows that searching only needs to be performed when a 
;	reference is deleted.
;
;	FreeAllUndefinedPrs is called to Free prs entries created
;	by undefined direct mode references.
;
;	The FTM_PrsDefDeleted bit of flagsTm is used to
;	to determine if we need to search for a new "defining"
;	reference for the prs.
;
; Entry:
;	flagsTm.FTM_PrsDefDeleted set if we need to search
;	  for a new "defining" reference.
;
; Exit:
;	Deleted prs entries with no new definitions are freed
;	Deleted prs entries with new definitions have otxDef
;	  and oRsDef set to the new definition.
;**************************************************************
PUBLIC	ChkAllUndefPrsSaveRs
ChkAllUndefPrsSaveRs PROC NEAR
	push	[grs.GRS_oRsCur]	;preserve current oRs
	call	ChkAllUndefPrs		;check all undefed prs entries
	call	RsActivateCP		;Reactivate current oRs
	ret
ChkAllUndefPrsSaveRs ENDP

PUBLIC	ChkAllUndefPrs
ChkAllUndefPrs	PROC NEAR
	test	WORD PTR [flagsTm],FTM_PrsDefDeleted OR FTM2_PrsRefDeleted*100h
					;have any definitions been deleted?
	jne	FreeAllUndefinedPrs	;brif so - Redef or Del all UNDEFINED
					; prs entries
	ret
ChkAllUndefPrs	ENDP

PUBLIC	FreeAllUndefinedPrs
FreeAllUndefinedPrs PROC NEAR
	push	si			
	push	di			
	mov	ax,[grs.GRS_oMrsCur]	
	mov	[uprs.UPRS_oMrsRefDel],ax	;store mrs of deleted text
	mov	si,UNDEFINED		
FreeAllUndef_Cont:			
	cCall	PrsDeActivate		; ensure all proc.s are in Rs table
FreeAllUndef_Cont1:			
	mov	di,si			
FreeAllUndef_Cont2:			
	mov	ax,di			
	call	GetNextPrs		; PTRRS:ax points to first prs
					;	ax == UNDEFINED ==> no prs's
	inc	ax			
	jnz	FAU_DontExit		
	jmp	FreeAllUndef_Exit	
FAU_DontExit:				

	dec	ax			
	mov	si,ax			; cache, so we don't end up starting
					; from the beginning of the prs
					; chain each time we free a prs
	mov	bx,ax			
	RS_BASE add,bx			; bx = oPrs

; assign cx = 0 if no reference to the Prs has been deleted otw non-zero
	xor	cx,cx			
	test	PTRRS[bx.PRS_flags2],FP_RefDeleted ;[38]
	jz	NoRefDeleted		;brif no reference has been deleted
	and	PTRRS[bx.PRS_flags2],NOT FP_RefDeleted ;[38]clear flag
	not	cx			;set cx = non-0 since ref was deleted
NoRefDeleted:				
	mov	[uprs.UPRS_fNoRefSameMod],cx ;initialize fNoRefSameMod
					;     to TRUE if we must search for
					;     a ref to the Prs in the module

; assign ax = 0 if otxDef is defined otw non-zero
	mov	al,1			;assume otxDef is undefined
	cmp	PTRRS[bx.PRS_otxDef],UNDEFINED
	je	otxDefUnDefined		;brif otxDef is UnDefined
	jcxz	FreeAllUndef_Cont1	;brif otxDef is Defined and 
					; no ref to the prs has been
					; deleted -- nothing to do
	xor	ax,ax			;set ax = 0 since otxDef is defined
otxDefUnDefined:
	push	cx			;preserve condition flag
	push	ax			;preserve condition flag

	push	si			; pass to PrsActivateCP
	call	PrsActivateCP		;activate prs which may be freed

	pop	cx			;cx = 0 iff otxDef is defined
	pop	ax			;ax = 0 iff no ref to proc was del'd
	jcxz	DontSearchForDeclare	;brif otxDef of proc is defined
	xor	dx,dx			;assume that we will need to search
					; for a new defining ref
	test	[flagsTm],FTM_PrsDefDeleted 
	jnz	SearchForRef		;brif a defining ref has been del'd
	or	ax,ax			;ax = 0 if no ref to proc was del'd
	jz	ChkDeletePrs		;This branch is taken if no ref to
					; this proc has been deleted and
					; no defining ref has been deleted
DontSearchForDeclare:	     		
	mov	dl,FP_DECLARED		
SearchForRef:				
	mov	[dprs.DPRS_flags],dl	;set dprs.flags to FP_DECLARED
					; if we don't need to search for

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -