00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00059 #ifdef ASSERT
00060 if (format == UNDEF) {
00061
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
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
00074
00075 }
00076
00077 if (argument_spec != no_args) {
00078
00079 assert(send_type != no_send, "inconsistency between argument_spec and send_type");
00080 }
00081
00082 if (code_type == control_struc) {
00083
00084 assert(!single_step, "control structures cannot be single stepped");
00085 }
00086
00087 if (code_type == float_operation) {
00088
00089 for (int i = 0; i < 6; i++) {
00090 assert(name[i] == "float_"[i], "inconsistency with naming convention");
00091 }
00092 }
00093 #endif
00094
00095
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
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
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
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
00413
00414 Bytecodes::LoopType Bytecodes::loop_type(Code code) {
00415 switch(code) {
00416 case Bytecodes::jump_loop_byte :
00417 case Bytecodes::jump_loop_word : return loop_start;
00418 case Bytecodes::whileTrue_byte :
00419 case Bytecodes::whileFalse_byte :
00420 case Bytecodes::whileTrue_word :
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 :
00520 case compiled_send_self :
00521 case polymorphic_send_self :
00522 case megamorphic_send_self :
00523 case interpreted_send_self_pop :
00524 case compiled_send_self_pop :
00525 case polymorphic_send_self_pop :
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 :
00537 case compiled_send_super :
00538 case polymorphic_send_super :
00539 case megamorphic_send_super :
00540 case interpreted_send_super_pop :
00541 case compiled_send_super_pop :
00542 case polymorphic_send_super_pop :
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 :
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 :
00575 case smi_sub :
00576 case smi_mult :
00577 case smi_div :
00578 case smi_mod :
00579 case smi_create_point :
00580 case smi_equal :
00581 case smi_not_equal :
00582 case smi_less :
00583 case smi_less_equal :
00584 case smi_greater :
00585 case smi_greater_equal :
00586 case smi_and :
00587 case smi_or :
00588 case smi_xor :
00589 case smi_shift :
00590 case objArray_at :
00591 case objArray_at_put :
00592 case double_equal :
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 :
00604 case compiled_send_0 :
00605 case primitive_send_0 :
00606 case polymorphic_send_0 :
00607 case megamorphic_send_0 : return interpreted_send_0;
00608
00609 case interpreted_send_0_pop :
00610 case compiled_send_0_pop :
00611 case primitive_send_0_pop :
00612 case polymorphic_send_0_pop :
00613 case megamorphic_send_0_pop : return interpreted_send_0_pop;
00614
00615 case interpreted_send_1 :
00616 case compiled_send_1 :
00617 case primitive_send_1 :
00618 case polymorphic_send_1 :
00619 case megamorphic_send_1 : return interpreted_send_1;
00620
00621 case interpreted_send_1_pop :
00622 case compiled_send_1_pop :
00623 case primitive_send_1_pop :
00624 case polymorphic_send_1_pop :
00625 case megamorphic_send_1_pop : return interpreted_send_1_pop;
00626
00627 case interpreted_send_2 :
00628 case compiled_send_2 :
00629 case primitive_send_2 :
00630 case polymorphic_send_2 :
00631 case megamorphic_send_2 : return interpreted_send_2;
00632
00633 case interpreted_send_2_pop :
00634 case compiled_send_2_pop :
00635 case primitive_send_2_pop :
00636 case polymorphic_send_2_pop :
00637 case megamorphic_send_2_pop : return interpreted_send_2_pop;
00638
00639 case interpreted_send_n :
00640 case compiled_send_n :
00641 case primitive_send_n :
00642 case polymorphic_send_n :
00643 case megamorphic_send_n : return interpreted_send_n;
00644
00645 case interpreted_send_n_pop :
00646 case compiled_send_n_pop :
00647 case primitive_send_n_pop :
00648 case polymorphic_send_n_pop :
00649 case megamorphic_send_n_pop : return interpreted_send_n_pop;
00650
00651 case interpreted_send_self :
00652 case compiled_send_self :
00653 case primitive_send_self :
00654 case polymorphic_send_self :
00655 case megamorphic_send_self : return interpreted_send_self;
00656
00657 case interpreted_send_self_pop :
00658 case compiled_send_self_pop :
00659 case primitive_send_self_pop :
00660 case polymorphic_send_self_pop :
00661 case megamorphic_send_self_pop : return interpreted_send_self_pop;
00662
00663 case interpreted_send_super :
00664 case compiled_send_super :
00665 case primitive_send_super :
00666 case polymorphic_send_super :
00667 case megamorphic_send_super : return interpreted_send_super;
00668
00669 case interpreted_send_super_pop :
00670 case compiled_send_super_pop :
00671 case primitive_send_super_pop :
00672 case polymorphic_send_super_pop :
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 :
00679 case smi_sub :
00680 case smi_mult :
00681 case smi_div :
00682 case smi_mod :
00683 case smi_create_point :
00684 case smi_equal :
00685 case smi_not_equal :
00686 case smi_less :
00687 case smi_less_equal :
00688 case smi_greater :
00689 case smi_greater_equal :
00690 case smi_and :
00691 case smi_or :
00692 case smi_xor :
00693 case smi_shift :
00694 case double_equal :
00695 case double_tilde :
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
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
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
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 }