-- This file is part of SmartEiffel The GNU Eiffel Compiler. -- Copyright (C) 1994-2002 LORIA - INRIA - U.H.P. Nancy 1 - FRANCE -- Dominique COLNET and Suzanne COLLIN - SmartEiffel@loria.fr -- http://SmartEiffel.loria.fr -- SmartEiffel is free software; you can redistribute it and/or modify it -- under the terms of the GNU General Public License as published by the Free -- Software Foundation; either version 2, or (at your option) any later -- version. SmartEiffel is distributed in the hope that it will be useful,but -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -- for more details. You should have received a copy of the GNU General -- Public License along with SmartEiffel; see the file COPYING. If not, -- write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -- Boston, MA 02111-1307, USA. -- class AGENT_INSTRUCTION -- -- Some agent is called using the `foo.call([bar]);' notation. -- inherit CALL_PROC_CALL; INSTRUCTION creation {PROC_CALL_1} make feature pretty_print is do creator.pretty_print end to_runnable(ct: E_TYPE): INSTRUCTION is do Result := creator.to_runnable(ct) end arg_count: INTEGER is 1 compile_to_c is do agent_args.c_agent_definition_call(target) cpp.put_character(';') cpp.put_character('%N') end end_mark_comment: BOOLEAN is false stupid_switch(run_time_set: RUN_TIME_SET): BOOLEAN is do check false end end is_pre_computable: BOOLEAN is false compile_to_jvm is local idx: INTEGER space: INTEGER fcn: STRING i_argument: INTEGER ft: FACE_TUPLE tt: TYPE_TUPLE tp: TYPE_OF_AGENT point1: INTEGER point2: INTEGER point3: INTEGER point4: INTEGER index_local: INTEGER count_local: INTEGER target_local: INTEGER do -- target t -- open_arguments o -- open_arguments_count c -- open_arguments_index x -- open_argument_indices d -- arguments a -- base b -- integer i -- minus_1 m -- object j -- method e index_local := code_attribute.extra_local_size1 count_local := code_attribute.extra_local_size1 target_local := code_attribute.extra_local_size1 -- set up target local target.compile_to_jvm fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) code_attribute.opcode_checkcast(idx) code_attribute.opcode_astore( target_local ) -- put open arguments into open_arguments -- , code_attribute.opcode_aload( target_local ) -- ,t idx := constant_pool.idx_fieldref3( fcn, as_open_arguments, fz_c2 ) space := target.result_type.jvm_stack_space ft ?= arguments.expression(1) tp ?= target.result_type tt := tp.open if tt.count > 0 then code_attribute.opcode_dup -- ,tt code_attribute.opcode_getfield(idx,space + 1); -- get open_arguments -- ,to end from i_argument := 1 until i_argument > ft.count loop code_attribute.opcode_dup -- ,too code_attribute.opcode_push_integer( i_argument - 1 ) -- ,tooi if ft.expression(i_argument).result_type.is_basic_eiffel_expanded then push_jvm_expanded_argument_to_object_wrapper( ft.expression(i_argument), tt.type(i_argument) ) else space := ft.expression(i_argument).standard_compile_to_jvm_into( tt.type(i_argument) ) end -- ,tooij code_attribute.opcode_aastore -- ,to i_argument := i_argument + 1 end if tt.count > 0 then code_attribute.opcode_pop -- ,t end -- fill in open arguments in arguments -- set up index local code_attribute.opcode_push_integer( 0 ) code_attribute.opcode_istore( index_local ) -- ,t -- set up count local code_attribute.opcode_dup -- ,tt fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_open_argument_indices, fz_d3 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get open_arguments_indices -- ,td code_attribute.opcode_arraylength; -- get length of open_arguments_indices -- ,tc code_attribute.opcode_istore( count_local ) -- ,t code_attribute.opcode_iload( count_local ) -- ,tc code_attribute.opcode_iconst_0 -- ,tc0 point1 := code_attribute.opcode_if_icmpeq -- jump if open_argument_count empty -- ,t -- if open_argument_count > 0, see if open_argument_indices[0] = -1 code_attribute.opcode_dup -- ,tt fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_open_argument_indices, fz_d3 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get open_arguments_indices -- ,td code_attribute.opcode_iconst_0 -- ,td0 code_attribute.opcode_iaload -- ,ti code_attribute.opcode_iconst_m1 -- ,tim point2 := code_attribute.opcode_if_icmpne -- jump if open_argument_indices[0] /= -1 -- ,t -- get open_arguments[0] and put it in target code_attribute.opcode_dup -- ,tt code_attribute.opcode_dup -- to get open_arguments -- ,ttt fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_open_arguments, fz_c2 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get open_arguments -- ,tto code_attribute.opcode_iconst_0 -- index 0 of open_arguments -- ,tto0 code_attribute.opcode_aaload -- get open_arguments[0] -- ,ttj fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_target, fz_21 ) space := target.result_type.jvm_stack_space code_attribute.opcode_putfield(idx,space + 1); -- set target -- ,t -- set open_argument_index to 1 code_attribute.opcode_push_integer( 1 ) code_attribute.opcode_istore( index_local ) -- ,t code_attribute.resolve_u2_branch( point2 ) -- jumped to here if open_argument_indices[0] /= -1 -- ,t -- test to see if open_argument_index >= open_argument_count point4 := code_attribute.program_counter; -- jumped to here from end of "loop" to copy open arguments -- code_attribute.opcode_iload( index_local ) -- ,tx -- ,tx code_attribute.opcode_iload( count_local ) -- ,txc point3 := code_attribute.opcode_if_icmpge -- jump if open_argument_index >= open_argument_count -- ,t -- put open_argument[open_argument_index] into -- arguments[ open_argument_indices[open_argument_index] ] code_attribute.opcode_dup -- ,tt code_attribute.opcode_dup -- ,ttt fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_arguments, fz_c2 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get arguments -- ,tta --target.compile_to_jvm code_attribute.opcode_swap -- ,tat fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_open_argument_indices, fz_d3 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get open_arguments_indices -- ,tad code_attribute.opcode_iload( index_local ) -- ,tadx code_attribute.opcode_iaload -- get open_argument_indices[open_argument_index] -- ,tai code_attribute.opcode_aload( target_local ) -- ,tait fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_open_arguments, fz_c2 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get open_arguments -- ,taio code_attribute.opcode_iload( index_local ) -- ,taiox code_attribute.opcode_aaload -- get open_argument[open_argument_index] -- ,taij code_attribute.opcode_aastore -- store argument[open_argument_indices[open_argument_index]] = open_argument[open_argument_index] -- ,t -- increment open_argument_index -- ,t code_attribute.opcode_iload( index_local ) -- ,tx code_attribute.opcode_iconst_1 -- ,tx1 code_attribute.opcode_iadd -- ,ti code_attribute.opcode_istore( index_local ) -- ,t code_attribute.opcode_goto_backward(point4); -- jump back to top of loop to iterate through open_arguments code_attribute.resolve_u2_branch( point3 ) -- jumped to here if open_argument_index >= open_argument_count code_attribute.resolve_u2_branch( point1 ) -- jumped to here if open_argument_count empty -- ,t fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_fieldref3( fcn, as_method, fz_21 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get method -- ,e idx := constant_pool.idx_class2(fz_java_lang_reflect_method) code_attribute.opcode_checkcast(idx) -- ,e idx := constant_pool.idx_class2(fz_java_lang_reflect_method) code_attribute.opcode_aload( target_local ) -- ,et fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_target, fz_21 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get target -- ,eb code_attribute.opcode_aload( target_local ) -- ,ebt fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_arguments, fz_c2 ) space := target.result_type.jvm_stack_space code_attribute.opcode_getfield(idx,space + 1); -- get arguments -- ,eba idx := constant_pool.idx_methodref3( fz_java_lang_reflect_method, fz_c8, fz_c9 ); -- invoke code_attribute.opcode_invokevirtual( idx, -1 ) -- ,j code_attribute.opcode_aload( target_local ) -- ,jt code_attribute.opcode_swap -- ,tj fcn := target.result_type.run_class.fully_qualified_name idx := constant_pool.idx_class2(fcn) idx := constant_pool.idx_fieldref3( fcn, as_last_result, fz_21 ) space := target.result_type.jvm_stack_space code_attribute.opcode_putfield(idx,space + 1); -- set last_result -- , end push_jvm_expanded_argument_to_object_wrapper( arg_expression: EXPRESSION; f_type: E_TYPE ) is local idx: INTEGER space: INTEGER do if f_type.is_boolean then idx := constant_pool.idx_class2(fz_java_lang_boolean) code_attribute.opcode_new(idx) code_attribute.opcode_dup space := arg_expression.standard_compile_to_jvm_into( f_type ) idx := constant_pool.idx_methodref3( fz_java_lang_boolean, fz_35, fz_cb ); -- code_attribute.opcode_invokespecial( idx, -1 ) elseif f_type.is_character then idx := constant_pool.idx_class2(fz_java_lang_byte) code_attribute.opcode_new(idx) code_attribute.opcode_dup space := arg_expression.standard_compile_to_jvm_into( f_type ) idx := constant_pool.idx_methodref3( fz_java_lang_byte, fz_35, fz_cc1 ); -- code_attribute.opcode_invokespecial( idx, -1 ) elseif f_type.is_integer then idx := constant_pool.idx_class2(fz_java_lang_integer) code_attribute.opcode_new(idx) code_attribute.opcode_dup space := arg_expression.standard_compile_to_jvm_into( f_type ) idx := constant_pool.idx_methodref3( fz_java_lang_integer, fz_35, fz_27 ); -- code_attribute.opcode_invokespecial( idx, -1 ) elseif f_type.is_real then idx := constant_pool.idx_class2(fz_java_lang_float) code_attribute.opcode_new(idx) code_attribute.opcode_dup space := arg_expression.standard_compile_to_jvm_into( f_type ) idx := constant_pool.idx_methodref3( fz_java_lang_float, fz_35, fz_ce ); -- code_attribute.opcode_invokespecial( idx, -1 ) elseif f_type.is_double then idx := constant_pool.idx_class2(fz_java_lang_double) code_attribute.opcode_new(idx) code_attribute.opcode_dup space := arg_expression.standard_compile_to_jvm_into( f_type ) idx := constant_pool.idx_methodref3( fz_java_lang_double, fz_35, fz_cf ); -- code_attribute.opcode_invokespecial( idx, -1 ) elseif f_type.is_pointer then arg_expression.compile_to_jvm end end feature {COMPOUND,INSTRUCTION_WITH_COMMENT} verify_scoop(allowed: FORMAL_ARG_LIST) is local dummy: BOOLEAN do if not target.is_current and then target.result_type.is_separate then if allowed /= Void then dummy := allowed.verify_scoop(creator.target) else target.scoop_error end end end feature {NONE} creator: PROC_CALL -- The `creator' of `Current'. arguments: EFFECTIVE_ARG_LIST agent_args: AGENT_ARGS -- Computed using `feature_name' and `aguments'. make(c: like creator) is require c.target /= Void c.feature_name.to_string = as_call c.run_feature.result_type = Void do creator := c target := creator.target feature_name := creator.feature_name arguments := creator.arguments run_feature := creator.run_feature agent_args := agent_pool.register_agent_call(arguments,run_feature) ensure creator = c target = creator.target feature_name = creator.feature_name arguments = creator.arguments run_feature = creator.run_feature end afd_check_hook is do end invariant target /= Void feature_name /= Void run_feature /= Void end -- AGENT_INSTRUCTION