note
	description: "[
		Accessor to an object. Useful to manipulate fields of an object, or
		an expanded field of an object without causing any copying.
		If applied to an expanded type, a copy will be manipulated.
	]"
	implementation_details: "[
		The GC might be moving objects, some of the routines are actually builtin.
	]"
	date: "$Date: 2017-03-23 19:18:26 +0000 (Thu, 23 Mar 2017) $"
	revision: "$Revision: 100033 $"

class 
	REFLECTED_REFERENCE_OBJECT

inherit
	REFLECTED_OBJECT

	REFLECTOR_CONSTANTS

create 
	make


create {REFLECTED_REFERENCE_OBJECT, RT_DBG_INTERNAL}
	make_for_expanded_field,
	make_for_expanded_field_at

feature {NONE} -- Initialization

	make (a_object: ANY)
			-- Setup a proxy to a_object.
		require
			not_expanded_object: True
		do
			enclosing_object := a_object
			dynamic_type := {ISE_RUNTIME}.dynamic_type (a_object)
			physical_offset := 0
		ensure
			enclosing_object_set: enclosing_object = a_object
			no_physical_offset: physical_offset = 0
		end

	make_for_expanded_field (a_enclosing_object: REFLECTED_REFERENCE_OBJECT; i: INTEGER_32)
			-- Setup a proxy to expanded field located at the i-th field of a_enclosing_object.
		require
			i_th_field_is_expanded: a_enclosing_object.is_field_statically_expanded (i)
		do
			enclosing_object := a_enclosing_object.enclosing_object
			physical_offset := a_enclosing_object.physical_offset + a_enclosing_object.field_offset (i)
			dynamic_type := {ISE_RUNTIME}.dynamic_type_at_offset ($enclosing_object.to_pointer, physical_offset)
		ensure
			enclosing_object_set: enclosing_object = a_enclosing_object.enclosing_object
		end

	make_for_expanded_field_at (a_enclosing_object: ANY; a_physical_offset: INTEGER_32)
			-- Setup a proxy to expanded field located at the a_physical_offset of a_enclosing_object.
		require
			not_dotnet: not {PLATFORM}.is_dotnet
		do
			enclosing_object := a_enclosing_object
			physical_offset := a_physical_offset
			dynamic_type := {ISE_RUNTIME}.dynamic_type_at_offset ($a_enclosing_object.to_pointer, a_physical_offset)
		ensure
			enclosing_object_set: enclosing_object = a_enclosing_object
		end
	
feature -- Access

	object: ANY
			-- Associated object for Current.
			-- It might be a copy if Current is expanded.
		do
			Result := {ISE_RUNTIME}.reference_field_at_offset ($enclosing_object.to_pointer, physical_offset)
		end

	object_address: POINTER
			-- Unprotected reference to object.
		do
			Result := {ISE_RUNTIME}.raw_reference_field_at_offset ($enclosing_object.to_pointer, physical_offset)
		end

	enclosing_object: separate ANY
			-- Enclosing object containing object or a reference to `object.

	physical_offset: INTEGER_32
			-- Actual offset in bytes of object in enclosing_object.

	copy_semantics_field (i: INTEGER_32): REFLECTED_COPY_SEMANTICS_OBJECT
			-- Object attached to the i-th field of object
			-- (directly or through a reference)
		do
			create Result.make (twin, i)
		end

	expanded_field (i: INTEGER_32): REFLECTED_REFERENCE_OBJECT
			-- Object representation of the i-th field of object
			-- which is expanded. We provide a wrapper that enables
			-- direct editing of the field without duplicating
			-- the expanded object.
		do
			create Result.make_for_expanded_field (Current, i)
		end
	
feature -- Settings

	set_object (a_obj: separate ANY)
			-- Update Current to represent a new reflected object.
		require
			physical_offset_not_set: physical_offset = 0
		do
			enclosing_object := a_obj
			physical_offset := 0
			dynamic_type := {ISE_RUNTIME}.dynamic_type (a_obj)
		ensure
			enclosing_object_set: enclosing_object = a_obj
			no_physical_offset: physical_offset = 0
		end
	
note
	copyright: "Copyright (c) 1984-2017, Eiffel Software and others"
	license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
	source: "[
		Eiffel Software
		5949 Hollister Ave., Goleta, CA 93117 USA
		Telephone 805-685-1006, Fax 805-685-6869
		Website http://www.eiffel.com
		Customer support http://support.eiffel.com
	]"

end -- class REFLECTED_REFERENCE_OBJECT

Generated by ISE EiffelStudio