bytecodes.cpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996 LongView Technologies L.L.C. $Revision: 1.29 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 # include "incls/_precompiled.incl"
00025 # include "incls/_bytecodes.cpp.incl"
00026 
00027 
00028 char*                   Bytecodes::_entry_point[number_of_codes];
00029 char*                   Bytecodes::_name[number_of_codes];
00030 Bytecodes::Format       Bytecodes::_format[number_of_codes];
00031 Bytecodes::CodeType     Bytecodes::_code_type[number_of_codes];
00032 Bytecodes::ArgumentSpec Bytecodes::_argument_spec[number_of_codes];
00033 Bytecodes::SendType     Bytecodes::_send_type[number_of_codes];
00034 bool                    Bytecodes::_single_step[number_of_codes];
00035 bool                    Bytecodes::_pop_tos[number_of_codes];
00036 
00037 
00038 void Bytecodes::def(Code code) {
00039   def(code, "undefined", UNDEF, miscellaneous, false, no_args, no_send, false);
00040 }
00041 
00042   
00043 void Bytecodes::def(Code code, char* name, Format format, CodeType code_type, bool single_step, bool pop_tos) {
00044   def(code, name, format, code_type, single_step, no_args, no_send, pop_tos);
00045 }
00046 
00047 
00048 void Bytecodes::def(Code code, char* name, Format format, ArgumentSpec argument_spec, SendType send_type, bool pop_tos) {
00049   assert(send_type != no_send, "must be a send");
00050   def(code, name, format, message_send, true, argument_spec, send_type, pop_tos);
00051 }
00052 
00053 
00054 void Bytecodes::def(Code code, char* name, Format format, CodeType code_type, bool single_step, ArgumentSpec argument_spec, SendType send_type, bool pop_tos) {
00055   assert(0 <= code && code < number_of_codes, "out of bounds");
00056   assert(_name[code] == NULL, "bytecode defined twice");
00057 
00058   // plausibility checks for arguments (compare with naming convention)
00059   #ifdef ASSERT
00060   if (format == UNDEF) {
00061     // bytecode name should be "undefined"
00062     for (int i = 0; i < 9; i++) {
00063       assert(name[i] == "undefined"[i], "inconsistency with naming convention");
00064     }
00065   }
00066 
00067   if (pop_tos) {
00068     // bytecode name unlikely to start with "push_"... and should end with ..."_pop"
00069     assert(name[0] != 'p' || name[1] != 'u' || name[2] != 's' || name[3] != 'h' || name[4] != '_', "unlikely naming");
00070 
00071     int i = 0;
00072     while (name[i] != '\00') i++;
00073     // Fix this lars
00074     // assert(name[i-4] == '_' && name[i-3] == 'p' && name[i-2] == 'o' && name[i-1] == 'p', "inconsistency with naming convention");
00075   }
00076 
00077   if (argument_spec != no_args) {
00078     // must be a send
00079     assert(send_type != no_send, "inconsistency between argument_spec and send_type");
00080   }
00081 
00082   if (code_type == control_struc) {
00083     // not intercepted on single step
00084     assert(!single_step, "control structures cannot be single stepped");
00085   }
00086 
00087   if (code_type == float_operation) {
00088     // bytecode name should start with "float_"
00089     for (int i = 0; i < 6; i++) {
00090       assert(name[i] == "float_"[i], "inconsistency with naming convention");
00091     }
00092   }
00093   #endif
00094 
00095   // set table entries
00096   _entry_point[code]   = NULL;
00097   _name[code]          = name;
00098   _format[code]        = format;
00099   _code_type[code]     = code_type;
00100   _argument_spec[code] = argument_spec;
00101   _send_type[code]     = send_type;
00102   _single_step[code]   = single_step;
00103   _pop_tos[code]       = pop_tos;
00104 }
00105 
00106 
00107 extern "C" doFn original_table[Bytecodes::number_of_codes];
00108 
00109 void Bytecodes::set_entry_point(Code code, char* entry_point) {
00110   assert(is_defined(code), "undefined byte code");
00111   assert(entry_point != NULL, "not a valid entry_point");
00112   _entry_point[code] = entry_point;
00113   original_table[code] = (doFn)entry_point;
00114 }
00115 
00116 
00117 void Bytecodes::init() {
00118   // to allow check for complete initialization at end of init
00119   #ifdef ASSERT
00120   int i;
00121   for (i = 0; i < number_of_codes; i++) {
00122     _name[Code(i)] = NULL;
00123   }
00124   #endif
00125 
00126   // for better readability
00127   const bool do_sst = true;
00128   const bool no_sst = false;
00129   const bool pop    = true;
00130 
00131   def(push_temp_0,                      "push_temp_0",                          B,      local_access,   no_sst);
00132   def(push_temp_1,                      "push_temp_1",                          B,      local_access,   no_sst);
00133   def(push_temp_2,                      "push_temp_2",                          B,      local_access,   no_sst);
00134   def(push_temp_3,                      "push_temp_3",                          B,      local_access,   no_sst);
00135   def(push_temp_4,                      "push_temp_4",                          B,      local_access,   no_sst);
00136   def(push_temp_5,                      "push_temp_5",                          B,      local_access,   no_sst);
00137   def(unimplemented_06);
00138   def(push_temp_n,                      "push_temp_n",                          BB,     local_access,   no_sst);
00139   def(push_arg_1,                       "push_arg_1",                           B,      local_access,   no_sst);
00140   def(push_arg_2,                       "push_arg_2",                           B,      local_access,   no_sst);
00141   def(push_arg_3,                       "push_arg_3",                           B,      local_access,   no_sst);
00142   def(push_arg_n,                       "push_arg_n",                           BB,     local_access,   no_sst);
00143   def(allocate_temp_1,                  "allocate_temp_1",                      B,      miscellaneous,  no_sst);
00144   def(allocate_temp_2,                  "allocate_temp_2",                      B,      miscellaneous,  no_sst);
00145   def(allocate_temp_3,                  "allocate_temp_3",                      B,      miscellaneous,  no_sst);
00146   def(allocate_temp_n,                  "allocate_temp_n",                      BB,     miscellaneous,  no_sst);
00147 
00148   def(store_temp_0_pop,                 "store_temp_0_pop",                     B,      local_access,   do_sst, pop);
00149   def(store_temp_1_pop,                 "store_temp_1_pop",                     B,      local_access,   do_sst, pop);
00150   def(store_temp_2_pop,                 "store_temp_2_pop",                     B,      local_access,   do_sst, pop);
00151   def(store_temp_3_pop,                 "store_temp_3_pop",                     B,      local_access,   do_sst, pop);
00152   def(store_temp_4_pop,                 "store_temp_4_pop",                     B,      local_access,   do_sst, pop);
00153   def(store_temp_5_pop,                 "store_temp_5_pop",                     B,      local_access,   do_sst, pop);
00154   def(store_temp_n,                     "store_temp_n",                         BB,     local_access,   do_sst);
00155   def(store_temp_n_pop,                 "store_temp_n_pop",                     BB,     local_access,   do_sst, pop);
00156   def(push_neg_n,                       "push_neg_n",                           BB,     miscellaneous,  no_sst);
00157   def(push_succ_n,                      "push_succ_n",                          BB,     miscellaneous,  no_sst);
00158   def(push_literal,                     "push_literal",                         BO,     miscellaneous,  no_sst);
00159   def(push_tos,                         "push_tos",                             B,      miscellaneous,  no_sst);
00160   def(push_self,                        "push_self",                            B,      miscellaneous,  no_sst);
00161   def(push_nil,                         "push_nil",                             B,      miscellaneous,  no_sst);
00162   def(push_true,                        "push_true",                            B,      miscellaneous,  no_sst);
00163   def(push_false,                       "push_false",                           B,      miscellaneous,  no_sst);
00164 
00165   def(unimplemented_20);
00166   def(unimplemented_21);
00167   def(unimplemented_22);
00168   def(unimplemented_23);
00169   def(unimplemented_24);
00170   def(unimplemented_25);
00171   def(unimplemented_26);
00172   def(unimplemented_27);
00173   def(return_instVar_name,              "return_instVar_name",                  BO,     instVar_access, no_sst);
00174   def(push_classVar,                    "push_classVar",                        BO,     classVar_access,no_sst);
00175   def(store_classVar_pop,               "store_classVar_pop",                   BO,     classVar_access,do_sst, pop);
00176   def(store_classVar,                   "store_classVar",                       BO,     classVar_access,do_sst);
00177   def(return_instVar,                   "return_instVar",                       BL,     instVar_access, do_sst);
00178   def(push_instVar,                     "push_instVar",                         BL,     instVar_access, no_sst);
00179   def(store_instVar_pop,                "store_instVar_pop",                    BL,     instVar_access, do_sst, pop);
00180   def(store_instVar,                    "store_instVar",                        BL,     instVar_access, do_sst);
00181 
00182   def(float_allocate,                   "float_allocate",                       BBBB,   float_operation,no_sst);
00183   def(float_floatify_pop,               "float_floatify_pop",                   BB,     float_operation,no_sst, pop);
00184   def(float_move,                       "float_move",                           BBB,    float_operation,no_sst);
00185   def(float_set,                        "float_set",                            BBO,    float_operation,no_sst);
00186   def(float_nullary_op,                 "float_nullary_op",                     BBB,    float_operation,no_sst);
00187   def(float_unary_op,                   "float_unary_op",                       BBB,    float_operation,no_sst);
00188   def(float_binary_op,                  "float_binary_op",                      BBB,    float_operation,no_sst);
00189   def(float_unary_op_to_oop,            "float_unary_op_to_oop",                BBB,    float_operation,no_sst);
00190   def(float_binary_op_to_oop,           "float_binary_op_to_oop",               BBB,    float_operation,no_sst);
00191   def(unimplemented_39);
00192   def(unimplemented_3a);
00193   def(unimplemented_3b);
00194   def(unimplemented_3c);
00195   def(push_instVar_name,                "push_instVar_name",                    BO,     instVar_access, no_sst);
00196   def(store_instVar_pop_name,           "store_instVar_pop_name",               BO,     instVar_access, no_sst, pop);
00197   def(store_instVar_name,               "store_instVar_name",                   BO,     instVar_access, no_sst);
00198 
00199   def(push_temp_0_context_0,            "push_temp_0_context_0",                B,      context_access, no_sst);
00200   def(push_temp_1_context_0,            "push_temp_1_context_0",                B,      context_access, no_sst);
00201   def(push_temp_2_context_0,            "push_temp_2_context_0",                B,      context_access, no_sst);
00202   def(push_temp_n_context_0,            "push_temp_n_context_0",                BB,     context_access, no_sst);
00203   def(store_temp_0_context_0_pop,       "store_temp_0_context_0_pop",           B,      context_access, do_sst, pop);
00204   def(store_temp_1_context_0_pop,       "store_temp_1_context_0_pop",           B,      context_access, do_sst, pop);
00205   def(store_temp_2_context_0_pop,       "store_temp_2_context_0_pop",           B,      context_access, do_sst, pop);
00206   def(store_temp_n_context_0_pop,       "store_temp_n_context_0_pop",           BB,     context_access, do_sst, pop);
00207   def(push_new_closure_context_0,       "push_new_closure_context_0",           BO,     new_closure,    no_sst);
00208   def(push_new_closure_context_1,       "push_new_closure_context_1",           BO,     new_closure,    no_sst);
00209   def(push_new_closure_context_2,       "push_new_closure_context_2",           BO,     new_closure,    no_sst);
00210   def(push_new_closure_context_n,       "push_new_closure_context_n",           BBO,    new_closure,    no_sst);
00211   def(install_new_context_method_0,     "install_new_context_method_0",         B,      new_context,    no_sst);
00212   def(install_new_context_method_1,     "install_new_context_method_1",         B,      new_context,    no_sst);
00213   def(install_new_context_method_2,     "install_new_context_method_2",         B,      new_context,    no_sst);
00214   def(install_new_context_method_n,     "install_new_context_method_n",         BB,     new_context,    no_sst);
00215 
00216   def(push_temp_0_context_1,            "push_temp_0_context_1",                B,      context_access, no_sst);
00217   def(push_temp_1_context_1,            "push_temp_1_context_1",                B,      context_access, no_sst);
00218   def(push_temp_2_context_1,            "push_temp_2_context_1",                B,      context_access, no_sst);
00219   def(push_temp_n_context_1,            "push_temp_n_context_1",                BB,     context_access, no_sst);
00220   def(store_temp_0_context_1_pop,       "store_temp_0_context_1_pop",           B,      context_access, do_sst, pop);
00221   def(store_temp_1_context_1_pop,       "store_temp_1_context_1_pop",           B,      context_access, do_sst, pop);
00222   def(store_temp_2_context_1_pop,       "store_temp_2_context_1_pop",           B,      context_access, do_sst, pop);
00223   def(store_temp_n_context_1_pop,       "store_temp_n_context_1_pop",           BB,     context_access, do_sst, pop);
00224   def(push_new_closure_tos_0,           "push_new_closure_tos_0",               BO,     new_closure,    no_sst);
00225   def(push_new_closure_tos_1,           "push_new_closure_tos_1",               BO,     new_closure,    no_sst);
00226   def(push_new_closure_tos_2,           "push_new_closure_tos_2",               BO,     new_closure,    no_sst);
00227   def(push_new_closure_tos_n,           "push_new_closure_tos_n",               BBO,    new_closure,    no_sst);
00228   def(only_pop,                         "only_pop",                             B,      new_context,    no_sst, pop);
00229   def(install_new_context_block_1,      "install_new_context_block_1",          B,      new_context,    no_sst);
00230   def(install_new_context_block_2,      "install_new_context_block_2",          B,      new_context,    no_sst);
00231   def(install_new_context_block_n,      "install_new_context_block_n",          BB,     new_context,    no_sst);
00232 
00233   def(push_temp_0_context_n,            "push_temp_0_context_n",                BB,     context_access, no_sst);
00234   def(push_temp_1_context_n,            "push_temp_1_context_n",                BB,     context_access, no_sst);
00235   def(push_temp_2_context_n,            "push_temp_2_context_n",                BB,     context_access, no_sst);
00236   def(push_temp_n_context_n,            "push_temp_n_context_n",                BBB,    context_access, no_sst);
00237   def(store_temp_0_context_n_pop,       "store_temp_0_context_n_pop",           BB,     context_access, do_sst, pop);
00238   def(store_temp_1_context_n_pop,       "store_temp_1_context_n_pop",           BB,     context_access, do_sst, pop);
00239   def(store_temp_2_context_n_pop,       "store_temp_2_context_n_pop",           BB,     context_access, do_sst, pop);
00240   def(store_temp_n_context_n_pop,       "store_temp_n_context_n_pop",           BBB,    context_access, do_sst, pop);
00241   def(set_self_via_context,             "set_self_via_context",                 B,      context_access, no_sst);
00242   def(copy_1_into_context,              "copy_1_into_context",                  BB,     context_access, no_sst);
00243   def(copy_2_into_context,              "copy_2_into_context",                  BBB,    context_access, no_sst);
00244   def(copy_n_into_context,              "copy_n_into_context",                  BBS,    context_access, no_sst);
00245   def(copy_self_into_context,           "copy_self_into_context",               B,      context_access, no_sst);
00246   def(copy_self_1_into_context,         "copy_self_1_into_context",             BB,     context_access, no_sst);
00247   def(copy_self_2_into_context,         "copy_self_2_into_context",             BBB,    context_access, no_sst);
00248   def(copy_self_n_into_context,         "copy_self_n_into_context",             BBS,    context_access, no_sst);
00249 
00250   def(ifTrue_byte,                      "ifTrue_byte",                          BBB,    control_struc,  no_sst);
00251   def(ifFalse_byte,                     "ifFalse_byte",                         BBB,    control_struc,  no_sst);
00252   def(and_byte,                         "and_byte",                             BB,     control_struc,  no_sst);
00253   def(or_byte,                          "or_byte",                              BB,     control_struc,  no_sst);
00254   def(whileTrue_byte,                   "whileTrue_byte",                       BB,     control_struc,  no_sst);
00255   def(whileFalse_byte,                  "whileFalse_byte",                      BB,     control_struc,  no_sst);
00256   def(jump_else_byte,                   "jump_else_byte",                       BB,     control_struc,  no_sst);
00257   def(jump_loop_byte,                   "jump_loop_byte",                       BBB,    control_struc,  no_sst);
00258   def(ifTrue_word,                      "ifTrue_word",                          BBL,    control_struc,  no_sst);
00259   def(ifFalse_word,                     "ifFalse_word",                         BBL,    control_struc,  no_sst);
00260   def(and_word,                         "and_word",                             BL,     control_struc,  no_sst);
00261   def(or_word,                          "or_word",                              BL,     control_struc,  no_sst);
00262   def(whileTrue_word,                   "whileTrue_word",                       BL,     control_struc,  no_sst);
00263   def(whileFalse_word,                  "whileFalse_word",                      BL,     control_struc,  no_sst);
00264   def(jump_else_word,                   "jump_else_word",                       BL,     control_struc,  no_sst);
00265   def(jump_loop_word,                   "jump_loop_word",                       BLL,    control_struc,  no_sst);
00266 
00267   def(interpreted_send_0,               "interpreted_send_0",                   BOO,    recv_0_args,    interpreted_send);
00268   def(interpreted_send_1,               "interpreted_send_1",                   BOO,    recv_1_args,    interpreted_send);
00269   def(interpreted_send_2,               "interpreted_send_2",                   BOO,    recv_2_args,    interpreted_send);
00270   def(interpreted_send_n,               "interpreted_send_n",                   BBOO,   recv_n_args,    interpreted_send);
00271   def(interpreted_send_0_pop,           "interpreted_send_0_pop",               BOO,    recv_0_args,    interpreted_send,       pop);
00272   def(interpreted_send_1_pop,           "interpreted_send_1_pop",               BOO,    recv_1_args,    interpreted_send,       pop);
00273   def(interpreted_send_2_pop,           "interpreted_send_2_pop",               BOO,    recv_2_args,    interpreted_send,       pop);
00274   def(interpreted_send_n_pop,           "interpreted_send_n_pop",               BBOO,   recv_n_args,    interpreted_send,       pop);
00275   def(interpreted_send_self,            "interpreted_send_self",                BOO,    args_only,      interpreted_send);
00276   def(interpreted_send_self_pop,        "interpreted_send_self_pop",            BOO,    args_only,      interpreted_send,       pop);
00277   def(interpreted_send_super,           "interpreted_send_super",               BOO,    args_only,      interpreted_send);
00278   def(interpreted_send_super_pop,       "interpreted_send_super_pop",           BOO,    args_only,      interpreted_send,       pop);
00279   def(return_tos_pop_0,                 "return_tos_pop_0",                     B,      miscellaneous,  do_sst);
00280   def(return_tos_pop_1,                 "return_tos_pop_1",                     B,      miscellaneous,  do_sst);
00281   def(return_tos_pop_2,                 "return_tos_pop_2",                     B,      miscellaneous,  do_sst);
00282   def(return_tos_pop_n,                 "return_tos_pop_n",                     BB,     miscellaneous,  do_sst);
00283 
00284   def(polymorphic_send_0,               "polymorphic_send_0",                   BOO,    recv_0_args,    polymorphic_send);
00285   def(polymorphic_send_1,               "polymorphic_send_1",                   BOO,    recv_1_args,    polymorphic_send);
00286   def(polymorphic_send_2,               "polymorphic_send_2",                   BOO,    recv_2_args,    polymorphic_send);
00287   def(polymorphic_send_n,               "polymorphic_send_n",                   BBOO,   recv_n_args,    polymorphic_send);
00288   def(polymorphic_send_0_pop,           "polymorphic_send_0_pop",               BOO,    recv_0_args,    polymorphic_send,       pop);
00289   def(polymorphic_send_1_pop,           "polymorphic_send_1_pop",               BOO,    recv_1_args,    polymorphic_send,       pop);
00290   def(polymorphic_send_2_pop,           "polymorphic_send_2_pop",               BOO,    recv_2_args,    polymorphic_send,       pop);
00291   def(polymorphic_send_n_pop,           "polymorphic_send_n_pop",               BBOO,   recv_n_args,    polymorphic_send,       pop);
00292   def(polymorphic_send_self,            "polymorphic_send_self",                BOO,    args_only,      polymorphic_send);
00293   def(polymorphic_send_self_pop,        "polymorphic_send_self_pop",            BOO,    args_only,      polymorphic_send,       pop);
00294   def(polymorphic_send_super,           "polymorphic_send_super",               BOO,    args_only,      polymorphic_send);
00295   def(polymorphic_send_super_pop,       "polymorphic_send_super_pop",           BOO,    args_only,      polymorphic_send,       pop);
00296   def(return_self_pop_0,                "return_self_pop_0",                    B,      miscellaneous,  do_sst);
00297   def(return_self_pop_1,                "return_self_pop_1",                    B,      miscellaneous,  do_sst);
00298   def(return_self_pop_2,                "return_self_pop_2",                    B,      miscellaneous,  do_sst);
00299   def(return_self_pop_n,                "return_self_pop_n",                    BB,     miscellaneous,  do_sst);
00300 
00301   def(compiled_send_0,                  "compiled_send_0",                      BLO,    recv_0_args,    compiled_send);
00302   def(compiled_send_1,                  "compiled_send_1",                      BLO,    recv_1_args,    compiled_send);
00303   def(compiled_send_2,                  "compiled_send_2",                      BLO,    recv_2_args,    compiled_send);
00304   def(compiled_send_n,                  "compiled_send_n",                      BBLO,   recv_n_args,    compiled_send);
00305   def(compiled_send_0_pop,              "compiled_send_0_pop",                  BLO,    recv_0_args,    compiled_send,          pop);
00306   def(compiled_send_1_pop,              "compiled_send_1_pop",                  BLO,    recv_1_args,    compiled_send,          pop);
00307   def(compiled_send_2_pop,              "compiled_send_2_pop",                  BLO,    recv_2_args,    compiled_send,          pop);
00308   def(compiled_send_n_pop,              "compiled_send_n_pop",                  BBLO,   recv_n_args,    compiled_send,          pop);
00309   def(compiled_send_self,               "compiled_send_self",                   BLO,    args_only,      compiled_send);
00310   def(compiled_send_self_pop,           "compiled_send_self_pop",               BLO,    args_only,      compiled_send,          pop);
00311   def(compiled_send_super,              "compiled_send_super",                  BLO,    args_only,      compiled_send);
00312   def(compiled_send_super_pop,          "compiled_send_super_pop",              BLO,    args_only,      compiled_send,          pop);
00313   def(return_tos_zap_pop_n,             "return_tos_zap_pop_n",                 BB,     miscellaneous,  do_sst);
00314   def(return_self_zap_pop_n,            "return_self_zap_pop_n",                BB,     miscellaneous,  do_sst);
00315   def(non_local_return_tos_pop_n,       "non_local_return_tos_pop_n",           BB,     nonlocal_return,do_sst);
00316   def(non_local_return_self_pop_n,      "non_local_return_self_pop_n",          BB,     nonlocal_return,do_sst);
00317 
00318   def(prim_call,                        "prim_call",                            BL,     primitive_call, do_sst);
00319   def(predict_prim_call,                "predict_prim_call",                    BL,     primitive_call, do_sst);
00320   def(prim_call_failure,                "prim_call_failure",                    BLL,    primitive_call, do_sst);
00321   def(predict_prim_call_failure,        "predict_prim_call_failure",            BLL,    primitive_call, do_sst);
00322   def(dll_call_sync,                    "dll_call_sync",                        BOOLB,  dll_call,       do_sst);
00323   def(prim_call_self,                   "prim_call_self",                       BL,     primitive_call, do_sst);
00324   def(prim_call_self_failure,           "prim_call_self_failure",               BLL,    primitive_call, do_sst);
00325   def(unimplemented_b7);
00326   def(access_send_self,                 "access_send_self",                     BOO,    args_only,      accessor_send);
00327   def(primitive_send_0,                 "primitive_send_0",                     BOO,    recv_0_args,    primitive_send);
00328   def(primitive_send_super,             "primitive_send_super",                 BOO,    args_only,      primitive_send);
00329   def(primitive_send_super_pop,         "primitive_send_super_pop",             BOO,    args_only,      primitive_send,         pop);
00330   def(unimplemented_bc);
00331   def(primitive_send_1,                 "primitive_send_1",                     BOO,    recv_1_args,    primitive_send);
00332   def(primitive_send_2,                 "primitive_send_2",                     BOO,    recv_2_args,    primitive_send);
00333   def(primitive_send_n,                 "primitive_send_n",                     BBOO,   recv_n_args,    primitive_send);
00334 
00335   def(prim_call_lookup,                 "prim_call_lookup",                     BO,     primitive_call, no_sst);
00336   def(predict_prim_call_lookup,         "predict_prim_call_lookup",             BO,     primitive_call, no_sst);
00337   def(prim_call_failure_lookup,         "prim_call_failure_lookup",             BOL,    primitive_call, no_sst);
00338   def(predict_prim_call_failure_lookup, "predict_prim_call_failure_lookup",     BOL,    primitive_call, no_sst);
00339   def(dll_call_async,                   "dll_call_async",                       BOOLB,  dll_call,       do_sst);
00340   def(prim_call_self_lookup,            "prim_call_self_lookup",                BO,     primitive_call, no_sst);
00341   def(prim_call_self_failure_lookup,    "prim_call_self_failure_lookup",        BOL,    primitive_call, no_sst);
00342   def(unimplemented_c7);
00343   def(access_send_0,                    "access_send_0",                        BOO,    recv_0_args,    accessor_send);
00344   def(primitive_send_0_pop,             "primitive_send_0_pop",                 BOO,    recv_0_args,    primitive_send,         pop);
00345   def(primitive_send_self,              "primitive_send_self",                  BOO,    args_only,      primitive_send);
00346   def(primitive_send_self_pop,          "primitive_send_self_pop",              BOO,    args_only,      primitive_send,         pop);
00347   def(unimplemented_cc);
00348   def(primitive_send_1_pop,             "primitive_send_1_pop",                 BOO,    recv_1_args,    primitive_send,         pop);
00349   def(primitive_send_2_pop,             "primitive_send_2_pop",                 BOO,    recv_2_args,    primitive_send,         pop);
00350   def(primitive_send_n_pop,             "primitive_send_n_pop",                 BBOO,   recv_n_args,    primitive_send,         pop);
00351 
00352   def(megamorphic_send_0,               "megamorphic_send_0",                   BOO,    recv_0_args,    megamorphic_send);
00353   def(megamorphic_send_1,               "megamorphic_send_1",                   BOO,    recv_1_args,    megamorphic_send);
00354   def(megamorphic_send_2,               "megamorphic_send_2",                   BOO,    recv_2_args,    megamorphic_send);
00355   def(megamorphic_send_n,               "megamorphic_send_n",                   BBOO,   recv_n_args,    megamorphic_send);
00356   def(megamorphic_send_0_pop,           "megamorphic_send_0_pop",               BOO,    recv_0_args,    megamorphic_send,       pop);
00357   def(megamorphic_send_1_pop,           "megamorphic_send_1_pop",               BOO,    recv_1_args,    megamorphic_send,       pop);
00358   def(megamorphic_send_2_pop,           "megamorphic_send_2_pop",               BOO,    recv_2_args,    megamorphic_send,       pop);
00359   def(megamorphic_send_n_pop,           "megamorphic_send_n_pop",               BBOO,   recv_n_args,    megamorphic_send,       pop);
00360   def(megamorphic_send_self,            "megamorphic_send_self",                BOO,    args_only,      megamorphic_send);
00361   def(megamorphic_send_self_pop,        "megamorphic_send_self_pop",            BOO,    args_only,      megamorphic_send,       pop);
00362   def(megamorphic_send_super,           "megamorphic_send_super",               BOO,    args_only,      megamorphic_send);
00363   def(megamorphic_send_super_pop,       "megamorphic_send_super_pop",           BOO,    args_only,      megamorphic_send,       pop);
00364   def(unimplemented_dc);
00365   def(special_primitive_send_1_hint,    "special_primitive_send_1_hint",        BB,     miscellaneous,  no_sst);
00366   def(unimplemented_de);
00367   def(unimplemented_df);
00368 
00369   def(smi_add,                          "smi_add",                              BOO,    recv_1_args,    predicted_send);
00370   def(smi_sub,                          "smi_sub",                              BOO,    recv_1_args,    predicted_send);
00371   def(smi_mult,                         "smi_mult",                             BOO,    recv_1_args,    predicted_send);
00372   def(smi_div,                          "smi_div",                              BOO,    recv_1_args,    predicted_send);
00373   def(smi_mod,                          "smi_mod",                              BOO,    recv_1_args,    predicted_send);
00374   def(smi_create_point,                 "smi_create_point",                     BOO,    recv_1_args,    predicted_send);
00375   def(smi_equal,                        "smi_equal",                            BOO,    recv_1_args,    predicted_send);
00376   def(smi_not_equal,                    "smi_not_equal",                        BOO,    recv_1_args,    predicted_send);
00377   def(smi_less,                         "smi_less",                             BOO,    recv_1_args,    predicted_send);
00378   def(smi_less_equal,                   "smi_less_equal",                       BOO,    recv_1_args,    predicted_send);
00379   def(smi_greater,                      "smi_greater",                          BOO,    recv_1_args,    predicted_send);
00380   def(smi_greater_equal,                "smi_greater_equal",                    BOO,    recv_1_args,    predicted_send);
00381   def(objArray_at,                      "objArray_at",                          BOO,    recv_1_args,    predicted_send);
00382   def(objArray_at_put,                  "objArray_at_put",                      BOO,    recv_1_args,    predicted_send);
00383   def(double_equal,                     "double_equal",                         B,      miscellaneous,  do_sst);
00384   def(double_tilde,                     "double_tilde",                         B,      miscellaneous,  do_sst);
00385 
00386   def(push_global,                      "push_global",                          BO,     global_access,  no_sst);
00387   def(store_global_pop,                 "store_global_pop",                     BO,     global_access,  do_sst, pop);
00388   def(store_global,                     "store_global",                         BO,     global_access,  do_sst);
00389   def(push_classVar_name,               "push_classVar_name",                   BO,     classVar_access,no_sst);
00390   def(store_classVar_pop_name,          "store_classVar_pop_name",              BO,     classVar_access,no_sst, pop);
00391   def(store_classVar_name,              "store_classVar_name",                  BO,     classVar_access,no_sst);
00392   def(smi_and,                          "smi_and",                              BOO,    recv_1_args,    predicted_send);
00393   def(smi_or,                           "smi_or",                               BOO,    recv_1_args,    predicted_send);
00394   def(smi_xor,                          "smi_xor",                              BOO,    recv_1_args,    predicted_send);
00395   def(smi_shift,                        "smi_shift",                            BOO,    recv_1_args,    predicted_send);
00396   def(unimplemented_fa);
00397   def(unimplemented_fb);
00398   def(unimplemented_fc);
00399   def(unimplemented_fd);
00400   def(unimplemented_fe);
00401   def(halt,                             "halt",                                 B,      control_struc,  no_sst);
00402 
00403   // check if all bytecodes have been initialized
00404   #ifdef ASSERT
00405   for (i = 0; i < number_of_codes; i++) {
00406     assert(_name[Code(i)] != NULL, "bytecode table not fully initialized");
00407   }
00408   #endif
00409 }
00410 
00411 
00412 // The dispatchTable controls the dispatch of byte codes
00413 
00414 Bytecodes::LoopType Bytecodes::loop_type(Code code) {
00415   switch(code) {
00416     case Bytecodes::jump_loop_byte      : // fall through
00417     case Bytecodes::jump_loop_word      : return loop_start;
00418     case Bytecodes::whileTrue_byte      : // fall through
00419     case Bytecodes::whileFalse_byte     : // fall through
00420     case Bytecodes::whileTrue_word      : // fall through
00421     case Bytecodes::whileFalse_word     : return loop_end;
00422     default                             : return no_loop;
00423   }
00424   ShouldNotReachHere();
00425 }
00426 
00427 
00428 char* Bytecodes::format_as_string(Format format) {
00429   switch (format) {
00430     case B    : return "B";
00431     case BB   : return "BB";
00432     case BBB  : return "BBB";
00433     case BBBB : return "BBBB";
00434     case BBO  : return "BBO";
00435     case BBL  : return "BBL";
00436     case BO   : return "BO";
00437     case BOO  : return "BOO";
00438     case BLO  : return "BLO";
00439     case BOL  : return "BOL";
00440     case BLL  : return "BLL";
00441     case BL   : return "BL";
00442     case BLB  : return "BLB";
00443     case BBOO : return "BBOO";
00444     case BBLO : return "BBLO";
00445     case BOOLB: return "BOOLB";
00446     case BBS  : return "BBS";
00447     case UNDEF: return "UNDEF";
00448   }
00449   ShouldNotReachHere();
00450   return NULL;
00451 }
00452 
00453 
00454 char* Bytecodes::send_type_as_string(SendType send_type) {
00455   switch (send_type) {
00456     case interpreted_send: return "interpreted_send";
00457     case compiled_send   : return "compiled_send";
00458     case polymorphic_send: return "polymorphic_send";
00459     case megamorphic_send: return "megamorphic_send";
00460     case predicted_send  : return "predicted_send";
00461     case accessor_send   : return "accessor send";
00462     case primitive_send  : return "primitive_send";
00463     case no_send         : return "no_send";
00464   }
00465   ShouldNotReachHere();
00466   return NULL;
00467 }
00468 
00469 
00470 char* Bytecodes::code_type_as_string(CodeType code_type) {
00471   switch (code_type) {
00472     case local_access   : return "local_access";
00473     case instVar_access : return "instVar_access";
00474     case context_access : return "context_access";
00475     case classVar_access: return "classVar_access";
00476     case global_access  : return "global_access";
00477     case new_closure    : return "new_closure";
00478     case new_context    : return "new_context";
00479     case control_struc  : return "control_struc";
00480     case message_send   : return "message_send";
00481     case nonlocal_return: return "nonlocal_return";
00482     case primitive_call : return "primitive_call";
00483     case dll_call       : return "dll_call";
00484     case float_operation: return "float_operation";
00485     case miscellaneous  : return "miscellaneous";
00486   }
00487   ShouldNotReachHere();
00488   return NULL;
00489 }
00490 
00491 
00492 char* Bytecodes::argument_spec_as_string(ArgumentSpec argument_spec) {
00493   switch (argument_spec) {
00494     case recv_0_args: return "recv_0_args";
00495     case recv_1_args: return "recv_1_args";
00496     case recv_2_args: return "recv_2_args";
00497     case recv_n_args: return "recv_n_args";
00498     case args_only  : return "args_only";
00499     case no_args    : return "no_args";
00500   }
00501   ShouldNotReachHere();
00502   return NULL;
00503 }
00504 
00505 
00506 char* Bytecodes::loop_type_as_string(LoopType loop_type) {
00507   switch (loop_type) {
00508     case loop_start: return "loop_start";
00509     case loop_end  : return "loop_end";
00510     case no_loop   : return "no_loop";
00511   }
00512   ShouldNotReachHere();
00513   return NULL;
00514 }
00515 
00516 
00517 bool Bytecodes::is_self_send(Bytecodes::Code code) {
00518   switch (code) {
00519     case interpreted_send_self          : // fall through
00520     case compiled_send_self             : // fall through
00521     case polymorphic_send_self          : // fall through
00522     case megamorphic_send_self          : // fall through
00523     case interpreted_send_self_pop      : // fall through
00524     case compiled_send_self_pop         : // fall through
00525     case polymorphic_send_self_pop      : // fall through
00526     case megamorphic_send_self_pop      : return true;
00527     default                             : return false;
00528   }
00529   ShouldNotReachHere();
00530   return false;
00531 }
00532 
00533 
00534 bool Bytecodes::is_super_send(Bytecodes::Code code) {
00535   switch (code) {
00536     case interpreted_send_super         : // fall through
00537     case compiled_send_super            : // fall through
00538     case polymorphic_send_super         : // fall through
00539     case megamorphic_send_super         : // fall through
00540     case interpreted_send_super_pop     : // fall through
00541     case compiled_send_super_pop        : // fall through
00542     case polymorphic_send_super_pop     : // fall through
00543     case megamorphic_send_super_pop     : return true;
00544     default                             : return false;
00545   }
00546   ShouldNotReachHere();
00547   return false;
00548 }
00549 
00550 
00551 bool Bytecodes::has_access_send_code(Bytecodes::Code code) {
00552   switch (code) {
00553     case interpreted_send_0             : // fall through
00554     case interpreted_send_self          : return true;
00555     default                             : return false;
00556   }
00557   ShouldNotReachHere();
00558   return false;
00559 }
00560 
00561 
00562 bool Bytecodes::has_predicted_send_code(Bytecodes::Code code) {
00563   switch (code) {
00564     case interpreted_send_1             : return true;
00565     default                             : return false;
00566   }
00567   ShouldNotReachHere();
00568   return false;
00569 }
00570 
00571 
00572 Bytecodes::Code Bytecodes::original_send_code_for(Bytecodes::Code code) {
00573   switch (code) {
00574     case smi_add                        : // fall through
00575     case smi_sub                        : // fall through
00576     case smi_mult                       : // fall through
00577     case smi_div                        : // fall through
00578     case smi_mod                        : // fall through
00579     case smi_create_point               : // fall through
00580     case smi_equal                      : // fall through
00581     case smi_not_equal                  : // fall through
00582     case smi_less                       : // fall through
00583     case smi_less_equal                 : // fall through
00584     case smi_greater                    : // fall through
00585     case smi_greater_equal              : // fall through
00586     case smi_and                        : // fall through
00587     case smi_or                         : // fall through
00588     case smi_xor                        : // fall through
00589     case smi_shift                      : // fall through
00590     case objArray_at                    : // fall through
00591     case objArray_at_put                : // fall through
00592     case double_equal                   : // fall through
00593     case double_tilde                   : return code;
00594     default                             : return interpreted_send_code_for(code);
00595   }
00596   ShouldNotReachHere();
00597   return halt;
00598 }
00599 
00600 
00601 Bytecodes::Code Bytecodes::interpreted_send_code_for(Bytecodes::Code code) {
00602   switch (code) {
00603     case interpreted_send_0             : // fall through
00604     case compiled_send_0                : // fall through
00605     case primitive_send_0               : // fall through
00606     case polymorphic_send_0             : // fall through
00607     case megamorphic_send_0             : return interpreted_send_0;
00608 
00609     case interpreted_send_0_pop         : // fall through
00610     case compiled_send_0_pop            : // fall through
00611     case primitive_send_0_pop           : // fall through
00612     case polymorphic_send_0_pop         : // fall through
00613     case megamorphic_send_0_pop         : return interpreted_send_0_pop;
00614 
00615     case interpreted_send_1             : // fall through
00616     case compiled_send_1                : // fall through
00617     case primitive_send_1               : // fall through
00618     case polymorphic_send_1             : // fall through
00619     case megamorphic_send_1             : return interpreted_send_1;
00620 
00621     case interpreted_send_1_pop         : // fall through
00622     case compiled_send_1_pop            : // fall through
00623     case primitive_send_1_pop           : // fall through
00624     case polymorphic_send_1_pop         : // fall through
00625     case megamorphic_send_1_pop         : return interpreted_send_1_pop;
00626 
00627     case interpreted_send_2             : // fall through
00628     case compiled_send_2                : // fall through
00629     case primitive_send_2               : // fall through
00630     case polymorphic_send_2             : // fall through
00631     case megamorphic_send_2             : return interpreted_send_2;
00632 
00633     case interpreted_send_2_pop         : // fall through
00634     case compiled_send_2_pop            : // fall through
00635     case primitive_send_2_pop           : // fall through
00636     case polymorphic_send_2_pop         : // fall through
00637     case megamorphic_send_2_pop         : return interpreted_send_2_pop;
00638 
00639     case interpreted_send_n             : // fall through
00640     case compiled_send_n                : // fall through
00641     case primitive_send_n               : // fall through
00642     case polymorphic_send_n             : // fall through
00643     case megamorphic_send_n             : return interpreted_send_n;
00644 
00645     case interpreted_send_n_pop         : // fall through
00646     case compiled_send_n_pop            : // fall through
00647     case primitive_send_n_pop           : // fall through
00648     case polymorphic_send_n_pop         : // fall through
00649     case megamorphic_send_n_pop         : return interpreted_send_n_pop;
00650 
00651     case interpreted_send_self          : // fall through
00652     case compiled_send_self             : // fall through
00653     case primitive_send_self            : // fall through
00654     case polymorphic_send_self          : // fall through
00655     case megamorphic_send_self          : return interpreted_send_self;
00656 
00657     case interpreted_send_self_pop      : // fall through
00658     case compiled_send_self_pop         : // fall through
00659     case primitive_send_self_pop        : // fall through
00660     case polymorphic_send_self_pop      : // fall through
00661     case megamorphic_send_self_pop      : return interpreted_send_self_pop;
00662 
00663     case interpreted_send_super         : // fall through
00664     case compiled_send_super            : // fall through
00665     case primitive_send_super           : // fall through
00666     case polymorphic_send_super         : // fall through
00667     case megamorphic_send_super         : return interpreted_send_super;
00668 
00669     case interpreted_send_super_pop     : // fall through
00670     case compiled_send_super_pop        : // fall through
00671     case primitive_send_super_pop       : // fall through
00672     case polymorphic_send_super_pop     : // fall through
00673     case megamorphic_send_super_pop     : return interpreted_send_super_pop;
00674 
00675     case access_send_0                  : return interpreted_send_0;
00676     case access_send_self               : return interpreted_send_self;
00677 
00678     case smi_add                        : // fall through
00679     case smi_sub                        : // fall through
00680     case smi_mult                       : // fall through
00681     case smi_div                        : // fall through
00682     case smi_mod                        : // fall through
00683     case smi_create_point               : // fall through
00684     case smi_equal                      : // fall through
00685     case smi_not_equal                  : // fall through
00686     case smi_less                       : // fall through
00687     case smi_less_equal                 : // fall through
00688     case smi_greater                    : // fall through
00689     case smi_greater_equal              : // fall through
00690     case smi_and                        : // fall through
00691     case smi_or                         : // fall through
00692     case smi_xor                        : // fall through
00693     case smi_shift                      : // fall through
00694     case double_equal                   : // fall through
00695     case double_tilde                   : // fall through
00696     case objArray_at                    : return interpreted_send_1;
00697     case objArray_at_put                : return interpreted_send_2;
00698 
00699     default                             : fatal("not a send bytecode");
00700   }
00701   ShouldNotReachHere();
00702   return halt;
00703 }
00704 
00705 
00706 Bytecodes::Code Bytecodes::compiled_send_code_for(Bytecodes::Code code) {
00707   switch (interpreted_send_code_for(code)) {
00708     case interpreted_send_0             : return compiled_send_0;
00709     case interpreted_send_1             : return compiled_send_1;
00710     case interpreted_send_2             : return compiled_send_2;
00711     case interpreted_send_n             : return compiled_send_n;
00712     case interpreted_send_self          : return compiled_send_self;
00713     case interpreted_send_super         : return compiled_send_super;
00714 
00715     case interpreted_send_0_pop         : return compiled_send_0_pop;
00716     case interpreted_send_1_pop         : return compiled_send_1_pop;
00717     case interpreted_send_2_pop         : return compiled_send_2_pop;
00718     case interpreted_send_n_pop         : return compiled_send_n_pop;
00719     case interpreted_send_self_pop      : return compiled_send_self_pop;
00720     case interpreted_send_super_pop     : return compiled_send_super_pop;
00721 
00722     default                             : fatal("no corresponding compiled send code");
00723   }
00724   ShouldNotReachHere();
00725   return halt;
00726 }
00727 
00728 
00729 Bytecodes::Code Bytecodes::access_send_code_for(Bytecodes::Code code) {
00730   switch (interpreted_send_code_for(code)) {
00731     case interpreted_send_0             : return access_send_0;
00732     case interpreted_send_self          : return access_send_self;
00733     default                             : fatal("no corresponding access send code");
00734   }
00735   ShouldNotReachHere();
00736   return halt;
00737 }
00738 
00739 
00740 Bytecodes::Code Bytecodes::primitive_send_code_for(Bytecodes::Code code) {
00741   switch (interpreted_send_code_for(code)) {
00742     case interpreted_send_0             : return primitive_send_0;
00743     case interpreted_send_1             : return primitive_send_1;
00744     case interpreted_send_2             : return primitive_send_2;
00745     case interpreted_send_n             : return primitive_send_n;
00746     case interpreted_send_self          : return primitive_send_self;
00747     case interpreted_send_super         : return primitive_send_super;
00748 
00749     case interpreted_send_0_pop         : return primitive_send_0_pop;
00750     case interpreted_send_1_pop         : return primitive_send_1_pop;
00751     case interpreted_send_2_pop         : return primitive_send_2_pop;
00752     case interpreted_send_n_pop         : return primitive_send_n_pop;
00753     case interpreted_send_self_pop      : return primitive_send_self_pop;
00754     case interpreted_send_super_pop     : return primitive_send_super_pop;
00755 
00756     default                             : fatal("no corresponding primitive send code");
00757   }
00758   ShouldNotReachHere();
00759   return halt;
00760 }
00761 
00762 
00763 Bytecodes::Code Bytecodes::polymorphic_send_code_for(Bytecodes::Code code) {
00764   switch (interpreted_send_code_for(code)) {
00765     case interpreted_send_0             : return polymorphic_send_0;
00766     case interpreted_send_1             : return polymorphic_send_1;
00767     case interpreted_send_2             : return polymorphic_send_2;
00768     case interpreted_send_n             : return polymorphic_send_n;
00769     case interpreted_send_self          : return polymorphic_send_self;
00770     case interpreted_send_super         : return polymorphic_send_super;
00771 
00772     case interpreted_send_0_pop         : return polymorphic_send_0_pop;
00773     case interpreted_send_1_pop         : return polymorphic_send_1_pop;
00774     case interpreted_send_2_pop         : return polymorphic_send_2_pop;
00775     case interpreted_send_n_pop         : return polymorphic_send_n_pop;
00776     case interpreted_send_self_pop      : return polymorphic_send_self_pop;
00777     case interpreted_send_super_pop     : return polymorphic_send_super_pop;
00778 
00779     default                             : fatal("no corresponding polymorphic send code");
00780   }
00781   ShouldNotReachHere();
00782   return halt;
00783 }
00784 
00785 
00786 Bytecodes::Code Bytecodes::megamorphic_send_code_for(Bytecodes::Code code) {
00787   switch (interpreted_send_code_for(code)) {
00788     case interpreted_send_0             : return megamorphic_send_0;
00789     case interpreted_send_1             : return megamorphic_send_1;
00790     case interpreted_send_2             : return megamorphic_send_2;
00791     case interpreted_send_n             : return megamorphic_send_n;
00792     case interpreted_send_self          : return megamorphic_send_self;
00793     case interpreted_send_super         : return megamorphic_send_super;
00794 
00795     case interpreted_send_0_pop         : return megamorphic_send_0_pop;
00796     case interpreted_send_1_pop         : return megamorphic_send_1_pop;
00797     case interpreted_send_2_pop         : return megamorphic_send_2_pop;
00798     case interpreted_send_n_pop         : return megamorphic_send_n_pop;
00799     case interpreted_send_self_pop      : return megamorphic_send_self_pop;
00800     case interpreted_send_super_pop     : return megamorphic_send_super_pop;
00801 
00802     default                             : fatal("no corresponding megamorphic send code");
00803   }
00804   ShouldNotReachHere();
00805   return halt;
00806 }
00807 
00808 
00809 Bytecodes::Code Bytecodes::original_primitive_call_code_for(Code code) {
00810   switch (code) {
00811     case prim_call:                     
00812     case prim_call_lookup:              return prim_call_lookup;
00813     case prim_call_self:
00814     case prim_call_self_lookup:         return prim_call_self_lookup;
00815     case prim_call_failure:
00816     case prim_call_failure_lookup:      return prim_call_failure_lookup;
00817     case prim_call_self_failure:
00818     case prim_call_self_failure_lookup: return prim_call_self_failure_lookup;
00819     default: fatal("no corresponding primitive call code");
00820   }
00821   ShouldNotReachHere();
00822   return halt;
00823 }
00824 
00825 
00826 Bytecodes::Code Bytecodes::primitive_call_code_for(Code code) {
00827   switch (code) {
00828     case prim_call_lookup               : return prim_call;
00829     case prim_call_self_lookup          : return prim_call_self;
00830     case prim_call_failure_lookup       : return prim_call_failure;
00831     case prim_call_self_failure_lookup  : return prim_call_self_failure;
00832     default                             : fatal("no corresponding primitive call code");
00833   }
00834   ShouldNotReachHere();
00835   return halt;
00836 }
00837 
00838 
00839 void Bytecodes::print() {
00840   for (int i = 0; i < number_of_codes; i++) {
00841     Code code = Code(i);
00842     if (is_defined(code)) {
00843       std->print("%s\n", name(code));
00844       std->print("  %s\n", code_type_as_string(code_type(code)));
00845       std->print("  %s\n", send_type_as_string(send_type(code)));
00846       std->cr();
00847     }
00848   }
00849 }
00850 
00851 
00852 // Smalltalk generation
00853 
00854 #ifndef PRODUCT
00855 
00856 static void generate_comment() {
00857   std->print("\t\"\n");
00858   std->print("\tGenerated method - do not modify manually\n");
00859   std->print("\t(use delta +GenerateSmalltalk to generate).\n");
00860   std->print("\t\"\n");
00861 }
00862 
00863 
00864 static bool actually_generated(Bytecodes::Code code) {
00865   return
00866     Bytecodes::is_defined(code) &&
00867     ( Bytecodes::send_type(code) == Bytecodes::no_send          ||
00868       Bytecodes::send_type(code) == Bytecodes::interpreted_send ||
00869       Bytecodes::send_type(code) == Bytecodes::predicted_send
00870     );
00871 }
00872 
00873 
00874 static void generate_instr_method() {
00875   std->print("instr: i\n");
00876   generate_comment();
00877   std->print("\t| h l |\n");
00878   std->print("\th := i // 16r10.\n");
00879   std->print("\tl := i \\\\ 16r10.\n\n");
00880   for (int h = 0; h < 0x10; h++) {
00881     std->print("\th = 16r%X ifTrue: [\n", h);
00882     for (int l = 0; l < 0x10; l++) {
00883       Bytecodes::Code code = Bytecodes::Code(h*0x10 + l);
00884       if (actually_generated(code)) {
00885         std->print("\t\tl = 16r%X\tifTrue:\t[ ^ '%s' ].\n", l, Bytecodes::name(code));
00886       }
00887     }
00888     std->print("\t\t^ ''\n");
00889     std->print("\t].\n\n");
00890   }
00891   std->print("\tself halt\n");
00892   std->print("!\n\n");
00893 }
00894 
00895 
00896 static void print_table_entry_for(char* selector, int code) {
00897   std->print("\tselector = #%s\t\tifTrue: [ ^ 16r%02X ].\n", selector, code);
00898 }
00899 
00900 
00901 static void generate_codeForPrimitive_method() {
00902   std->print("codeForPrimitive: selector\n");
00903   generate_comment();
00904   print_table_entry_for("primitiveAdd:ifFail:",                 Bytecodes::smi_add              );
00905   print_table_entry_for("primitiveSubtract:ifFail:",            Bytecodes::smi_sub              );
00906   print_table_entry_for("primitiveMultiply:ifFail:",            Bytecodes::smi_mult             );
00907 
00908   print_table_entry_for("primitiveSmallIntegerEqual:ifFail:",   Bytecodes::smi_equal            );
00909   print_table_entry_for("primitiveSmallIntegerNotEqual:ifFail:",Bytecodes::smi_not_equal        );
00910   print_table_entry_for("primitiveLessThan:ifFail:",            Bytecodes::smi_less             );
00911   print_table_entry_for("primitiveLessThanOrEqual:ifFail:",     Bytecodes::smi_less_equal       );
00912   print_table_entry_for("primitiveGreaterThan:ifFail:",         Bytecodes::smi_greater          );
00913   print_table_entry_for("primitiveGreaterThanOrEqual:ifFail:",  Bytecodes::smi_greater_equal    );
00914   
00915   print_table_entry_for("primitiveBitAnd:ifFail:",              Bytecodes::smi_and              );
00916   print_table_entry_for("primitiveBitOr:ifFail:",               Bytecodes::smi_or               );
00917   print_table_entry_for("primitiveBitXor:ifFail:",              Bytecodes::smi_xor              );
00918   print_table_entry_for("primitiveRawBitShift:ifFail:",         Bytecodes::smi_shift            );
00919   std->print("\t^ nil\n");
00920   std->print("!\n\n");
00921 }
00922 
00923 
00924 static void generate_signature(char* sig, char separator) {
00925   int i = 1;
00926   int b_cnt = 1;
00927   int w_cnt = 1;
00928   int o_cnt = 1;
00929   int s_cnt = 1;
00930   while (sig[i] != '\0') {
00931     std->put(separator);
00932     switch (sig[i]) {
00933       case 'B': std->print("byte: b%d", b_cnt++); break;
00934       case 'L': std->print("word: w%d", w_cnt++); break;
00935       case 'O': std->print("oop: o%d", o_cnt++); break;
00936       case 'S': std->print("bytes: s%d", s_cnt++); break;
00937       default : ShouldNotReachHere();
00938     }
00939     separator = ' ';
00940     i++;
00941   }
00942 }
00943 
00944 
00945 static bool has_instVar_access(Bytecodes::Code code) {
00946   return Bytecodes::code_type(code) == Bytecodes::instVar_access;
00947 }
00948 
00949 
00950 static bool has_classVar_access(Bytecodes::Code code) {
00951   return Bytecodes::code_type(code) == Bytecodes::classVar_access;
00952 }
00953 
00954 
00955 static bool has_inline_cache(Bytecodes::Code code) {
00956   return Bytecodes::send_type(code) != Bytecodes::no_send;
00957 }
00958 
00959 
00960 static void generate_gen_method(Bytecodes::Code code) {
00961   char* sig = Bytecodes::format_as_string(Bytecodes::format(code));
00962   std->print(Bytecodes::name(code));
00963   generate_signature(sig, '_');
00964   std->cr();
00965   generate_comment();
00966   std->print("\tself byte: 16r%02X", code);
00967   generate_signature(sig, ' ');
00968   std->print(".\n");
00969   if (has_instVar_access (code)) std->print("\tself has_instVar_access.\n");
00970   if (has_classVar_access(code)) std->print("\tself has_classVar_access.\n");
00971   if (has_inline_cache   (code)) std->print("\tself has_inline_cache.\n");
00972   std->print("!\n\n");
00973 }
00974 
00975 
00976 static void generate_float_function_constant_method(Floats::Function f) {
00977   std->print("float_%s\n", Floats::function_name_for(f));
00978   generate_comment();
00979   std->print("\t^ %d\n", f);
00980   std->print("!\n\n");
00981 }
00982 
00983 
00984 static void generate_HCode_methods() {
00985   std->print("!DeltaHCode methods !\n\n");
00986 
00987   generate_instr_method();
00988   generate_codeForPrimitive_method();
00989 
00990   int i;
00991   for (i = 0; i < Bytecodes::number_of_codes; i++) {
00992     Bytecodes::Code code = Bytecodes::Code(i);
00993     if (actually_generated(code)) generate_gen_method(code);
00994   }
00995 
00996   // assert(Floats::is_initialized(), "Floats must be initialized");
00997   for (i = 0; i < Floats::number_of_functions; i++) {
00998     Floats::Function f = Floats::Function(i);
00999     generate_float_function_constant_method(f);
01000   }
01001 
01002   std->print("!\n\n");
01003 }
01004 
01005 
01006 // HTML generation
01007 
01008 class Markup: StackObj {
01009  private:
01010   char* _tag;
01011  public:
01012   Markup(char* tag)     { _tag = tag; std->print("<%s>\n", _tag); }
01013   ~Markup()             { std->print("</%s>\n", _tag); }
01014 };
01015 
01016 
01017 static void markup(char* tag, char* text) {
01018   std->print("<%s>%s</%s>\n", tag, text, tag);
01019 }
01020 
01021 
01022 static void print_format(Bytecodes::Format format) {
01023   char* f = Bytecodes::format_as_string(format);
01024   while (*f) {
01025     switch (*f) {
01026       case 'B': std->print(" byte");    break;
01027       case 'L': std->print(" long");    break;
01028       case 'O': std->print(" oop");     break;
01029       case 'S': std->print(" {byte}");  break;
01030       default : ShouldNotReachHere();   break;
01031     }
01032     f++;
01033   }
01034 }
01035 
01036 
01037 static char* arguments_as_string(Bytecodes::ArgumentSpec spec) {
01038   switch (spec) {
01039     case Bytecodes::recv_0_args: return "receiver";
01040     case Bytecodes::recv_1_args: return "receiver argument_1";
01041     case Bytecodes::recv_2_args: return "receiver argument_1 argument_2";
01042     case Bytecodes::recv_n_args: return "receiver argument_1 argument_2 ... argument_n";
01043     case Bytecodes::args_only  : return "argument_1 argument_2 ... argument_n";
01044     default                    : ShouldNotReachHere();
01045   }
01046   return NULL;
01047 }
01048 
01049 
01050 static void generate_HTML_for(Bytecodes::Code code) {
01051   std->print("<TD>%02X<SUB>H</SUB><TD><B>%s</B><TD>", int(code), Bytecodes::name(code));
01052   print_format(Bytecodes::format(code));
01053   std->print("<TD>%s", Bytecodes::single_step(code) ? "intercepted" : "");
01054   if (Bytecodes::code_type(code) == Bytecodes::message_send) {
01055     std->print("<TD>%s", Bytecodes::send_type_as_string(Bytecodes::send_type(code)));
01056     std->print("<TD>%s", arguments_as_string(Bytecodes::argument_spec(code)));
01057   }
01058   std->print("<TR>\n");
01059 }
01060 
01061 
01062 static void generate_HTML_for(Bytecodes::CodeType type) {
01063   { Markup tag("H3");
01064     std->print("%s bytecodes\n", Bytecodes::code_type_as_string(type));
01065   }
01066   { Markup tag("TABLE");
01067     std->print("<TH>Code<TH>Name<TH>Format<TH>Single step");
01068     if (type == Bytecodes::message_send) std->print("<TH>Send type<TH>Arguments");
01069     std->print("<TR>\n");
01070     for (int i = 0; i < Bytecodes::number_of_codes; i++) {
01071       Bytecodes::Code code = Bytecodes::Code(i);
01072       if (Bytecodes::is_defined(code) && Bytecodes::code_type(code) == type) generate_HTML_for(code);
01073     }
01074   }
01075   std->print("<HR>\n");
01076 }
01077 
01078 
01079 static void generate_HTML_docu() {
01080   Markup tag("HTML");
01081   std->print("<!-- do not modify - use delta +GenerateHTML to generate -->\n");
01082   { Markup tag("HEAD");
01083     markup("TITLE", "Delta Bytecodes");
01084   }
01085   { Markup tag("BODY");
01086     { Markup tag("H2");
01087       std->print("Delta Bytecodes (Version %d)\n", Bytecodes::version());
01088     }
01089     for (int i = 0; i < Bytecodes::number_of_code_types; i++) generate_HTML_for(Bytecodes::CodeType(i));
01090   }
01091 }
01092 
01093 #endif
01094 
01095 
01096 void bytecodes_init() {
01097   Bytecodes::init();
01098 #ifndef PRODUCT
01099   if (GenerateSmalltalk) {
01100     generate_HCode_methods();
01101     exit(0);
01102   }
01103   if (GenerateHTML) {
01104     generate_HTML_docu();
01105     exit(0);
01106   }
01107 #endif
01108 }

Generated on Mon Oct 9 13:37:05 2006 for Strongtalk VM by  doxygen 1.4.7