-- Byte code for reverse assignment class REVERSE_B inherit ASSIGN_B redefine enlarged, make_byte_code, generate_il end feature -- Access info: CREATE_INFO -- Keep info about `target' type. -- Never Void. feature -- Settings set_info (a_info: like info) is -- Set `info' to `a_info'. require a_info_not_void: a_info /= Void do info := a_info ensure info_set: info = a_info end feature -- Enlarging enlarged: REVERSE_BL is -- Enlarge current node. do create Result Result.set_target (target.enlarged) Result.set_source (source.enlarged) Result.set_line_number (line_number) Result.set_info (info) end feature -- IL code generation generate_il is -- Generate IL code for a reverse assignment. local target_type, source_type: TYPE_I success_label, failure_label: IL_LABEL do generate_il_line_info (True) -- Code that needs to be generated when performing -- assignment to an attribute. target.generate_il_start_assignment -- Get types target_type := context.creation_type (target.type) source_type := context.real_type (source.type) check target_type_not_void: target_type /= Void source_type_not_void: source_type /= Void end -- FIXME: At the moment we don't know how to -- find out the real type of the generic -- parameter, so we cheat. if target_type.has_formal then target_type ?= real_type (target_type) end -- Generate expression byte code source.generate_il if source_type.is_expanded then if target_type.is_expanded then source.generate_il_metamorphose (source_type, Void, True) else source.generate_il_metamorphose (source_type, target_type, False) end end -- Generate Test on type il_generator.generate_is_instance_of (target_type) if target_type.is_expanded then il_generator.duplicate_top success_label := il_label_factory.new_label il_generator.branch_on_true (success_label) -- Assignment attempt faild. -- Remove duplicate obtained from call to `isinst'. il_generator.pop -- Assignment attempt failed, we simply load previous -- value of `target'. It is ok to regenerate `target' as -- it can only be a creatable entity: local, attribute, result. target.generate_il failure_label := il_label_factory.new_label il_generator.branch_to (failure_label) il_generator.mark_label (success_label) il_generator.generate_unmetamorphose (target_type) il_generator.mark_label (failure_label) end -- Generate assignment header depending of the type -- of the target (local, attribute or result). target.generate_il_reverse_assignment (source_type) end feature -- Byte code generation make_byte_code (ba: BYTE_ARRAY) is -- Generate byte code for a reverse assignment local source_type: TYPE_I do generate_melted_debugger_hook (ba) -- Generate expression byte code source.make_byte_code (ba) source_type := context.real_type (source.type) make_reverse_code (ba, source_type) end feature {NONE} -- Implementation make_reverse_code (ba: BYTE_ARRAY; source_type: TYPE_I) is -- Generate source reverse assignment byte code require target.is_creatable ba_not_void: ba /= Void good_argument: source_type /= Void consistency: not source_type.is_void local basic_type: BASIC_I target_type: TYPE_I do target_type := context.creation_type (target.type) check not_expanded: not target_type.is_true_expanded not_basic: not target_type.is_basic end if target_type.is_none then ba.append (Bc_none_assign) else -- Target is a reference if source_type.is_basic then -- Source is basic and target is a reference: -- metamorphose and simple attachment basic_type ?= source_type ba.append (Bc_metamorphose) elseif source_type.is_true_expanded then -- Source is expanded and target is a reference: clone -- and simple attachment ba.append (Bc_clone) end ba.append (target.reverse_code) target.make_end_reverse_assignment (ba) -- Generate type of target info.make_byte_code (ba) end end end