COMMENT @----------------------------------------------------------------------

	Copyright (c) GeoWorks 1989 -- All Rights Reserved

PROJECT:	PC GEOS
FILE:		object.def

DECLARER:	Kernel

DESCRIPTION:
	This file defines object management structures and routines.

	$Id: object.def,v 1.1 97/04/04 14:23:10 newdeal Exp $

------------------------------------------------------------------------------@

SetDef	__OBJECT

include lmem.def

StartKernel

global ObjMessage:far
global ObjProcBroadcastMessage:far
global ObjCallInstanceNoLock:far
global ObjCallInstanceNoLockES:far
global ObjCallClassNoLock:far
global ObjCallSuperNoLock:far
global ObjGotoSuperTailRecurse:far
global ObjGotoInstanceTailRecurse:far
global ObjInstantiate:far
global ObjInstantiateForThread:far
global ObjLockObjBlock:far
global ObjDuplicateResource:far
global ObjFreeDuplicate:far
global ObjFreeChunk:far
global ObjIncInUseCount:far
global ObjDecInUseCount:far
global ObjIncInteractibleCount:far
global ObjDecInteractibleCount:far

global ObjDoRelocation:far
global ObjDoUnRelocation:far
global ObjResizeMaster:far
global ObjInitializeMaster:far
global ObjInitializePart:far
global ObjGetFlags:far
global ObjSetFlags:far
global ObjMarkDirty:far
global ObjSwapLock:far
global ObjSwapUnlock:far
global ObjSwapLockParent:far
global ObjTestIfObjBlockRunByCurThread:far
global ObjSaveBlock:far
global ObjMapSavedToState:far
global ObjMapStateToSaved:far
global ObjIsObjectInClass:far
global ObjFreeObjBlock:far
global ObjFreeMessage:far
global ObjGetMessageInfo:far
global ObjGetMessageData:far
global MessageSetDestination:far
global MessageDispatch:far
global MessageProcess:far
global ObjDuplicateMessage:far

global ObjVarAddData:far
global ObjVarDeleteData:far
global ObjVarDeleteDataAt:far
global ObjVarScanData:far
global ObjVarFindData:far
global ObjVarDerefData:far
global ObjVarDeleteDataRange:far
global ObjVarCopyDataRange:far

global ObjBlockSetOutput:far
global ObjBlockGetOutput:far
global ObjRelocOrUnRelocSuper:far
global ObjIsClassADescendant:far

;-

global OBJLOCKOBJBLOCK:far
global OBJDUPLICATERESOURCE:far
global OBJFREEDUPLICATE:far
global OBJFREECHUNK:far
global OBJGETFLAGS:far
global OBJSETFLAGS:far
global OBJMARKDIRTY:far
global OBJISOBJECTINCLASS:far
global OBJINCINUSECOUNT:far
global OBJDECINUSECOUNT:far
global OBJINCINTERACTIBLECOUNT:far
global OBJDECINTERACTIBLECOUNT:far
global OBJDORELOCATION:far
global OBJDOUNRELOCATION:far
global OBJRESIZEMASTER:far
global OBJINITIALIZEMASTER:far
global OBJINITIALIZEPART:far
global OBJASSOCVMFILE:far
global OBJDISASSOCVMFILE:far
global OBJTESTIFOBJBLOCKRUNBYCURTHREAD:far
global OBJSAVEBLOCK:far
global OBJMAPSAVEDTOSTATE:far
global OBJMAPSTATETOSAVED:far
global COBJMESSAGE:far
global COBJCALLSUPER:far
global OBJFREEMESSAGE:far
global OBJGETMESSAGEINFO:far
global OBJGETMESSAGEDATA:far
global MESSAGESETDESTINATION:far
global CMESSAGEDISPATCH:far
global COBJSENDTOCHILDREN:far
global OBJDEREF:far
global OBJDEREF1:far
global OBJDEREF2:far
global OBJINSTANTIATE:far
global OBJINSTANTIATEFORTHREAD:far
global OBJPROCBROADCASTMESSAGE:far
global OBJFREEOBJBLOCK:far
global OBJRELOCATEENTRYPOINT:far
global OBJUNRELOCATEENTRYPOINT:far
ObjRelocateEntryPoint equ OBJRELOCATEENTRYPOINT
ObjUnRelocateEntryPoint equ OBJUNRELOCATEENTRYPOINT

global OBJVARADDDATA:far
global OBJVARDELETEDATA:far
global OBJVARDELETEDATAAT:far
global OBJVARSCANDATA:far
global OBJVARFINDDATA:far
global OBJVARDEREFDATA:far
global OBJVARDELETEDATARANGE:far
global OBJVARCOPYDATARANGE:far

global OBJBLOCKSETOUTPUT:far
global OBJBLOCKGETOUTPUT:far
global OBJDUPLICATEMESSAGE:far
global OBJISCLASSADESCENDANT:far
global OBJRELOCORUNRELOCSUPER:far

;--------------------------------------------------------------------------
;	Flags sent to ObjMessage
;--------------------------------------------------------------------------

MessageFlags	record
    MF_CALL:1
    MF_FORCE_QUEUE:1
    MF_STACK:1
    :1
    MF_CHECK_DUPLICATE:1
    MF_CHECK_LAST_ONLY:1
    MF_REPLACE:1
    MF_CUSTOM:1
    MF_FIXUP_DS:1
    MF_FIXUP_ES:1
    MF_DISCARD_IF_NO_MATCH:1
    MF_MATCH_ALL:1
    MF_INSERT_AT_FRONT:1
    MF_CAN_DISCARD_IF_DESPERATE:1
    MF_RECORD:1
    :1
MessageFlags	end

MessageError 		etype word
MESSAGE_NO_ERROR 	enum MessageError
MESSAGE_NO_HANDLES	enum MessageError	; short on handles and
						;  MF_CAN_DISCARD_IF_DESPERATE
						;  was passed.

;	Return values for custom compare routine called when sending events

PROC_SE_EXIT		=	8000h
PROC_SE_STORE_AT_BACK	=	1
PROC_SE_CONTINUE	=	0

;------------------------------------------------------------------------------
;		Action Descriptor
;------------------------------------------------------------------------------

	; Structure of an action descriptor

ActionDescriptor	struct
    AD_OD		optr
    AD_message		word
ActionDescriptor	ends

;------------------------------------------------------------------------------
;		Object Structures
;------------------------------------------------------------------------------


ObjLMemBlockHeader	struct
    OLMBH_header	LMemBlockHeader <>

    OLMBH_inUseCount	word
    ; "In Use" count for this block.  If non-zero, it is not safe for this
    ; block to be freed, for any number of reasons including:
    ;		- References to other system resources (memory handles,
    ;		  windows, semaphores) which must be released before the
    ;		  object may be destroyed.
    ;		- The existence (or possibility thereof) of messages in
    ;		  queues somewhere destined for an object or objects within
    ;		  the block.
    ; Tested by internal death mechanism to know when the block's memory
    ; handle may actually be freed.  Transitions of this value from 0->1 & 
    ; 1->0 are reported to the ObjBlock output, via the messages
    ; MSG_META_NOTIFY_OBJ_BLOCK_IN_USE and
    ; MSG_META_NOTIFY_OBJ_BLOCK_NOT_IN_USE.  Inc/Dec pairs may be found
    ; around queue flushes within the kernel's block freeing mechanism, as well
    ; as in object methods whereever system resources are grabbed or released.
    ; The default VisClass handlers provide such pairs at the opening/closing
    ; of Windows.

    OLMBH_interactibleCount	word
    ; "Interactible" count for this block.  If non-zero, then one or more
    ; objects within the block are either visible to the user, or possibly
    ; about to be activated by the user (for example, via a keyboard
    ; shortcut).  Is incremented by the default handler for MSG_VIS_OPEN,
    ; decremented by MSG_VIS_CLOSE.   Specific UI's may provide other
    ; inc/dec pairs as needed.  Transitions of this value from 0->1 & 
    ; 1->0 are reported to the ObjBlock output, via the messages
    ; MSG_META_NOTIFY_OBJ_BLOCK_INTERACTIBLE and
    ; MSG_META_NOTIFY_OBJ_BLOCK_NOT_INTERACTIBLE.  GenControlClass uses such
    ; notifications to know when objects must be updated to reflect current
    ; state, & when built out object trees are no longer needed.  Note
    ; that ObjInc/DecInteractibleCount automatically Inc/Dec the "In-Use"
    ; count on transitions from 0->1 & 1->0, so it is unecessary call
    ; ObjInc/DecInUseCount in addition to ObjInc/DecInteractibleCount.

    OLMBH_output	optr
    ; ObjBlock output -- optr to be notified about changes in resource status,
    ; such as in-use count going zero, non-zero.  Messages may also be sent
    ; to this optr by objects using the TravelOption "TO_OBJ_BLOCK_OUTPUT".

    OLMBH_resourceSize	word
    ; Size of resource

ObjLMemBlockHeader	ends

;	Flags kept for each chunk in an object block
;	If you add flags, consider changes to LibProcessCopyChunkIn and friends

ObjChunkFlags	record
    :3
    OCF_VARDATA_RELOC:1
    OCF_DIRTY:1
    OCF_IGNORE_DIRTY:1
    OCF_IN_RESOURCE:1
    OCF_IS_OBJECT:1
ObjChunkFlags	end

	; Class structure
	; DO NOT CHANGE THIS WITHOUT ALSO CHANGING THE DEFINITION IN Esp!

ClassFlags	record
    CLASSF_HAS_DEFAULT:1	; Set if dword before the class record
				; contains an fptr of a default method
				; handler to deal with any unrecognized
				; method send to an object of the class
    CLASSF_MASTER_CLASS:1	; Set if class is a master class
    CLASSF_VARIANT_CLASS:1	; Set if superclass varies
    CLASSF_DISCARD_ON_SAVE:1	; Set if class data can be discarded
				; when object is saved
    CLASSF_NEVER_SAVED:1	; Set if objects of this class
				; are never saved. This is a signal
				; to Esp that it needn't build up
				; a relocation table for the class
    CLASSF_HAS_RELOC:1		; Set if dword after method table is
				; routine to call to relocate or
				; unrelocate an object. Routine is
				; passed MSG_META_RELOCATE or
				; MSG_META_UNRELOCATE in AX.
    CLASSF_C_HANDLERS:1		; Handlers are written in C and must
				; be called with the C convention
    :1
ClassFlags	end

ClassStruct		struct
    Class_superClass	fptr.ClassStruct	;Class's superclass
    Class_masterOffset	word		;Offset to master class data
    Class_methodCount	word		;Number of methods defined
    Class_instanceSize	word		;Size to allocate instance
    Class_vdRelocTable	nptr.VarObjRelocation	;Ptr to vardata relocation info
    Class_relocTable	nptr.ObjRelocation	;Ptr to relocation info
    Class_flags		ClassFlags	;Flags for the class
    Class_masterMethods	byte		;Bits set by Esp to indicate the
					; presence of method handlers for a
					; given master level.
    Class_methodTable	label	word	;Start of method table
ClassStruct		ends

;------------------------------------------------------------------------------
; 	Constants and Structures for Object Variable Storage Mechanism
;------------------------------------------------------------------------------

;
; structure of a variable data entry
;
VarDataEntry	struct
	VDE_dataType		word		; data type
	;
	; if the data type include extra data, then the following fields
	; exist
	;
	VDE_entrySize		word		; size of extra data (INCLUDES
						;	VDE_dataType and
						;	VDE_entrySize)
	VDE_extraData		label	byte	; start of extra data
VarDataEntry	ends

;	Offset from a pointer to extra data to the data type
;	THIS SHOULD ONLY BE USED IN EXCEPTIONAL CIRCUMSTANCES.
;
VEDP_dataType	=	-4	; offset to data type
VEDP_entrySize	=	-2	; offset to data size (valid only if 
				; VDF_EXTRA_DATA bit set in data type)
;
; these bits are stored in the low part of the data type word
;
VarDataFlags	record
	:14
	VDF_EXTRA_DATA:1		; set if data entry has extra data
	VDF_SAVE_TO_STATE:1		; set if this data entry should be
					;	saved to state file
VarDataFlags	end


; Macro for fetching the type of a variable data entry given a pointer to
; the extra data stored in it.
;
; VarDataTypePtr( segment, ptr, result );
;
VarDataTypePtr	macro	varDataSegment, varDataPtr, result
	mov	result, varDataSegment:[varDataPtr].VEDP_dataType
	and	result, not mask VarDataFlags
endm

; Macro for fetching the VarDataFlags for a variable data entry given a 
; pointer to the extra data stored in it.
;
; VarDataFlagsPtr( segment, ptr, result );
;
VarDataFlagsPtr	macro	varDataSegment, varDataPtr, result
	mov	result, varDataSegment:[varDataPtr].VEDP_dataType
	and	result, mask VarDataFlags
endm

; Macro for fetching the size of the extra data stored in a variable
; data entry, given a pointer to the extra data
;
; VarDataSizePtr( segment, ptr, result );
;
VarDataSizePtr	macro	varDataSegment, varDataPtr, result
	local	gotIt

	clr	result
	test	{byte} varDataSegment:[varDataPtr].VEDP_dataType, mask VDF_EXTRA_DATA
	jz	gotIt
	mov	result, varDataSegment:[varDataPtr].VEDP_entrySize
	sub	result, size VarDataEntry
gotIt:
endm


;
; structure of a handler in VarDataHandlerTable
;
VarDataHandler	struct
	VDH_dataType	word		; data type for this handler
	VDH_handler	nptr.far	; handler routine
VarDataHandler	ends

;
; for C, we have a slightly different handler table format
;
VarDataCHandler	struct
	VDCH_dataType	word
	VDCH_handler	fptr.far
VarDataCHandler	ends

;------------------------------------------------------------------------------
;		Method Types & Structures
;------------------------------------------------------------------------------

DEFAULT_MASTER_MESSAGES		=	8192	;Methods per master class level
FIRST_MASTER_MESSAGE		=	16384	;Message # for first master 
						; level below Meta.


DEFAULT_CLASS_MESSAGES		=	512	;Methods per class level

DEFAULT_EXPORTED_MESSAGES	=	48

;------------------------------------------------------------------------------
;		Structures used when relocating objects
;------------------------------------------------------------------------------

;	If objects of a particular class can be saved, the class must have
;	a relocation table.  This table specifies that pieces of the classes
;	instance data must be relocated and the type of relocation to use.

;	The relocation table consists of an array of ObjRelocation structures,
;	with the end of the list marked by a RELOC_END_OF_LIST.

ObjRelocationType etype byte
RELOC_END_OF_LIST 	enum ObjRelocationType

	; Relocation from resource ID to handle.  The target contains the
	; resource identification (described below)
RELOC_HANDLE 		enum ObjRelocationType	;resource ID to handle

	; Relocation from resource ID to segment.  The target contains the
	; resource identification (described below)
RELOC_SEGMENT 		enum ObjRelocationType	;resource ID to segment

	; Relocation from resource ID/entry point number to a far pointer.
	; The low word of the target contains the resource identification
	; and the high word of the target contains the entry point number
RELOC_ENTRY_POINT 	enum ObjRelocationType	;resource ID/entry #

RELOC_LAST_LEGAL	=	RELOC_ENTRY_POINT

;
; Structure of an object relocation table entry (for instance data)
;
ObjRelocation	struct
    OR_type	ObjRelocationType	;Type of relocation
    OR_offset	word			;Offset to relocation
ObjRelocation	ends

; Structure passed to ObjRelocateEntryPoint

EntryPointRelocation	struct
    EPR_geodeName	char GEODE_NAME_SIZE dup (?)
    EPR_entryNumber	word
EntryPointRelocation	ends

;
; Structure of a vardata object relocation
;
VarObjRelocationType	record
    VORT_DATA_TYPE:14		; high 14 bits of VarData type constant
    VORT_RELOC_TYPE ObjRelocationType:2
VarObjRelocationType	end

VarObjRelocation	struct
    VOR_type	VarObjRelocationType
    VOR_offset	word
VarObjRelocation	ends

;-----------

;	All object relocations occur in place.  When a block is read in, it is
;	relocated (an ObjRelocationID is replaced with the real data).  When a
;	block is written out, it is unrelocated (the real data is replaced with
;	an ObjRelocationID)

ObjRelocationSource etype byte
ORS_NULL 		enum ObjRelocationSource	;ObjRelocation to 0
ORS_OWNING_GEODE 	enum ObjRelocationSource	;Resource of geode
							;index = resource ID
ORS_KERNEL 		enum ObjRelocationSource	;kernel entry point
ORS_LIBRARY 		enum ObjRelocationSource	;index = imported lib #
ORS_CURRENT_BLOCK	enum ObjRelocationSource	;handle of block
ORS_VM_HANDLE 		enum ObjRelocationSource	;reloc to handle of
							; block saved on the
							; saved list -- index
							; a VM iD
ORS_OWNING_GEODE_ENTRY_POINT enum ObjRelocationSource	;entry point of owner
ORS_NON_STATE_VM	enum ObjRelocationSource	;index = VM index, vm
							; file handle stored
							; in block header
ORS_UNKNOWN_BLOCK	enum ObjRelocationSource	;index = handle>>4
ORS_EXTERNAL 		enum ObjRelocationSource	;??? index = offset into
							;state space's table
							; NOT IMPLEMENTED


ObjRelocationID	record
	RID_SOURCE ObjRelocationSource:4
	RID_INDEX:12
ObjRelocationID	end

;------------------------------------------------------------------------------
;		Macros
;------------------------------------------------------------------------------


COMMENT @%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		CallSuper
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

SYNOPSIS:	Pass a method on to the superclass. Registers should be
		set up as for a regular no-lock super call.

PASS:		method - Name of method being sent (may not be a register)

PSEUDO CODE/STRATEGY:

KNOWN BUGS/SIDE EFFECTS/IDEAS:

REVISION HISTORY:
	Name	Date		Description
	----	----		-----------
	ardeb	11/15/89	Initial version

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%@
CallSuper	macro	method
ifb @CurClass
ErrMessage <Current class unknown. Use class directive to set one>
else
		;
		; Issue the static call anyway -- let the linker figure it
		; out.
		;
		call	method, super @CurClass
endif
		endm

;------------------------------------------------------------------------

; Object relocation to a resource
GetResourceIDObj	macro	resource
    ifnb <reg>
	mov	reg, (ORS_OWNING_GEODE shl offset RID_SOURCE) + resid resource
    else
	word	(ORS_OWNING_GEODE shl offset RID_SOURCE) + resid resource
    endif
endm

; Unrelocated doubleword pointer
UN_DD		macro	name, biff
ifidn	<name>,<0>
	dword	0
else
    ; the TYPE operator applied to a segment yields a constant for the segment
    ; type (0 = private, 1 = common, 2 = stack, 3 = library, 4 = resource,
    ; 5 = lmem, 6 = public, 7 = absolute, 8 = global)
    if type (seg name) eq 3
	; "resid" of a library entry point yields the library number in which
	; the entry point resides
	word	(ORS_LIBRARY shl offset RID_SOURCE) + resid name
    else
	ifdef DefVMFile
		.err <far pointer to something in a vm file makes no sense>
	endif
	; "resid" of a geode's entry point yields the resource ID, as usual
	word	(ORS_OWNING_GEODE_ENTRY_POINT shl offset RID_SOURCE)+resid name
    endif
    	; "enum" of any symbol, in a library or the geode, yields the entry-
	; point number of the symbol in that geode's exported entry-point table
	word	enum name
endif
endm


; Handle pointer
D_HPTR		macro	name
ifidn	<name>,<0>
	word	0
else
	word	handle name	
endif
endm


; Object pointer
D_OPTR		macro	name, extra
ifidn	<name>,<0>
	dword	0
else
	ifidn	<name>,<process>
		word	extra
		word	handle 0
	else
		ifidn	<extra>, <parent>
			word	offset	&name + 1
		else
			word	offset	&name
		endif
		word	handle name
	endif
endif
endm


; Unrelocated handle pointer
UN_HPTR		macro	name
ifidn	<name>,<0>
	word	0
else
	ifidn	<name>,<process>
		word	(ORS_OWNING_GEODE shl offset RID_SOURCE); use RESID 0
	else
	    ifdef DefVMFile
	    	word	(ORS_NON_STATE_VM shl offset RID_SOURCE) + resid name
	    else
		word	(ORS_OWNING_GEODE shl offset RID_SOURCE) + resid name
	    endif
	endif
endif
endm


; Unrelocated object pointer
UN_OPTR		macro	name, extra
ifidn	<name>,<0>
	dword	0
else
	ifidn	<name>,<process>
		word	extra
		word	(ORS_OWNING_GEODE shl offset RID_SOURCE) ; Use RESID 0
	else
	    ifidn	<extra>, <parent>
		    word	offset	&name + 1
	    else
		    word	offset	&name
	    endif
	    ifdef DefVMFile
		word	(ORS_NON_STATE_VM shl offset RID_SOURCE) + resid name
	    else
		word	(ORS_OWNING_GEODE shl offset RID_SOURCE) + resid name
	    endif
	endif
endif
endm


; Next two allow blocks to be duplicated in their entirety by not referring
; to any specific resource.
; XXX: should have an assertion that the macro argument is in the same block,
; but Esp can't handle it, currently (segment <chunksym> yields the @Heap
; segment, which doesn't compare equal to the group symbol that's in @CurSeg)

; Internal handle pointer (for current block)
I_HPTR		macro	name
ifidn	<name>,<0>
	word	0
else
	word	ORS_CURRENT_BLOCK shl offset RID_SOURCE
endif
endm


; Internal object pointer (to something in current block)
I_OPTR		macro	name, extra
ifidn	<name>,<0>
	dword	0
else
	ifidn	<extra>, <parent>
		word	offset	&name + 1
	else
		word	offset	&name
	endif
	word	ORS_CURRENT_BLOCK shl offset RID_SOURCE
endif
endm

EndKernel
