indexing description: "Creation type like an argument." date: "$Date$" revision: "$Revision$" class CREATE_ARG inherit CREATE_INFO redefine generate_cid, make_gen_type_byte_code, generate_cid_array, generate_cid_init end SHARED_GENERATION export {NONE} all end SHARED_GEN_CONF_LEVEL export {NONE} all end feature -- Access position: INTEGER -- Position of the argument type to create in the argument -- list of the current treated feature feature -- Settings set_position (i: INTEGER) is -- Assign `i' to `position'. do position := i end feature -- C code generation analyze is do if is_generic then context.mark_current_used context.add_dftype_current elseif is_formal then context.mark_current_used end end generate_type_id (buffer: GENERATION_BUFFER; final_mode: BOOLEAN) is -- Generate creation type. Take the dynamic type of the argument -- if possible, otherwise take its static type. local cl_type_i: CL_TYPE_I gen_type_i: GEN_TYPE_I do cl_type_i := type_to_create gen_type_i ?= cl_type_i buffer.put_string ("RTCA(arg") buffer.put_integer (position) buffer.put_string (gc_comma) if gen_type_i /= Void then buffer.put_string ("typres") elseif is_formal then create_formal_type.generate_type_id (buffer, final_mode) else if context.workbench_mode then buffer.put_string ("RTUD(") buffer.put_static_type_id (cl_type_i.associated_class_type.static_type_id) buffer.put_character (')') else buffer.put_type_id (cl_type_i.type_id) end end buffer.put_character (')') end feature -- IL code generation generate_il is -- Generate creation type. Take the dynamic type of the argument -- if possible, otherwise take its static type. do internal_generate_il (False) end generate_il_type is -- Generate IL code to load type of argument creation type. -- Take the dynamic type of the argument if possible, -- otherwise take its static type. do internal_generate_il (True) end feature {NONE} -- IL code generation internal_generate_il (a_is_for_type: BOOLEAN) is local l_type: TYPE_I creation_label, end_label: IL_LABEL l_is_formal: BOOLEAN l_formal_info: CREATE_FORMAL_TYPE do l_is_formal := is_formal if l_is_formal then l_formal_info := create_formal_type l_type := l_formal_info.type else l_type := type_to_create end creation_label := Il_label_factory.new_label end_label := Il_label_factory.new_label il_generator.generate_argument (position) il_generator.put_default_value (l_type) il_generator.generate_binary_operator ({IL_CONST}.il_eq) il_generator.branch_on_false (creation_label) -- Object is null, we are therefore creating an object of -- the declared type. if a_is_for_type then if l_is_formal then l_formal_info.generate_il_type else (create {CREATE_TYPE}.make (l_type)).generate_il_type end else if l_is_formal then l_formal_info.generate_il else (create {CREATE_TYPE}.make (l_type)).generate_il end end il_generator.branch_to (end_label) il_generator.mark_label (creation_label) -- Object is not null, so we put it on top of stack and call -- the runtime feature that knows how to create an object -- of the same type as another object. il_generator.generate_argument (position) if a_is_for_type then il_generator.load_type else il_generator.create_like_object end il_generator.mark_label (end_label) if not a_is_for_type then il_generator.generate_check_cast (Void, l_type) end end feature -- Byte code generation make_byte_code (ba: BYTE_ARRAY) is -- Generate byte code for an argument anchored type. local cl_type_i : CL_TYPE_I gen_type : GEN_TYPE_I do ba.append (Bc_carg) cl_type_i := type_to_create gen_type ?= cl_type_i if is_formal then create_formal_type.make_byte_code (ba) else ba.append ('%U') -- Default creation type ba.append_short_integer (cl_type_i.type_id - 1) -- Generics (if any) if gen_type /= Void then ba.append_short_integer (context.current_type.generated_id (False)) gen_type.make_gen_type_byte_code (ba, True) end ba.append_short_integer (-1) end -- Argument position ba.append_short_integer (position) end feature -- Generic conformance generate_gen_type_conversion (node : BYTE_NODE) is local gen_type : GEN_TYPE_I do gen_type ?= type_to_create if gen_type /= Void then node.generate_gen_type_conversion (gen_type) end end generate_cid (buffer: GENERATION_BUFFER; final_mode : BOOLEAN) is do buffer.put_string ("RTCA(arg") buffer.put_integer (position) buffer.put_character (',') buffer.put_integer (None_type) buffer.put_character (')') buffer.put_character (',') end make_gen_type_byte_code (ba : BYTE_ARRAY) is do ba.append_short_integer (Like_arg_type) ba.append_short_integer (position) end generate_cid_array (buffer : GENERATION_BUFFER; final_mode : BOOLEAN; idx_cnt : COUNTER) is local dummy : INTEGER do buffer.put_string ("0,") dummy := idx_cnt.next end generate_cid_init (buffer : GENERATION_BUFFER; final_mode : BOOLEAN; idx_cnt : COUNTER) is local dummy : INTEGER do buffer.put_string ("typarr[") buffer.put_integer (idx_cnt.value) buffer.put_string ("] = RTID(RTCA(arg") buffer.put_integer (position) buffer.put_character (',') buffer.put_integer (None_type) buffer.put_string ("));") buffer.put_new_line dummy := idx_cnt.next end type_to_create : CL_TYPE_I is local type_i : TYPE_I do type_i := context.byte_code.arguments.item (position) Result ?= context.creation_type (type_i) end is_formal: BOOLEAN is local l_formal: FORMAL_I do l_formal ?= context.creation_type (context.byte_code.arguments.item (position)) Result := l_formal /= Void end create_formal_type: CREATE_FORMAL_TYPE is require is_formal: is_formal local l_formal: FORMAL_I do l_formal ?= context.creation_type (context.byte_code.arguments.item (position)) create Result.make (l_formal) end end -- class CREATE_ARG