00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 class Bytecodes: AllStatic {
00055 public:
00056
00057
00058 static int version() { return 2; }
00059
00060 enum Format {
00061 B,
00062 BB,
00063 BBB,
00064 BBBB,
00065 BBO,
00066 BBL,
00067 BO,
00068 BOO,
00069 BLO,
00070 BOL,
00071 BLL,
00072 BL,
00073 BLB,
00074 BBOO,
00075 BBLO,
00076 BOOLB,
00077 BBS,
00078 UNDEF,
00079
00080 number_of_formats
00081 };
00082
00083 enum CodeType {
00084 local_access,
00085 instVar_access,
00086 context_access,
00087 classVar_access,
00088 global_access,
00089 new_closure,
00090 new_context,
00091 control_struc,
00092 message_send,
00093 nonlocal_return,
00094 primitive_call,
00095 dll_call,
00096 float_operation,
00097 miscellaneous,
00098
00099 number_of_code_types
00100 };
00101
00102 enum ArgumentSpec {
00103 recv_0_args,
00104 recv_1_args,
00105 recv_2_args,
00106 recv_n_args,
00107 args_only,
00108 no_args,
00109
00110 number_of_argument_specs
00111 };
00112
00113 enum SendType {
00114 interpreted_send,
00115 compiled_send,
00116 polymorphic_send,
00117 megamorphic_send,
00118 predicted_send,
00119 accessor_send,
00120 primitive_send,
00121 no_send,
00122
00123 number_of_send_types
00124 };
00125
00126 enum LoopType {
00127 loop_start,
00128 loop_end,
00129 no_loop,
00130
00131 number_of_loop_types
00132 };
00133
00134 enum Code {
00135
00136 push_temp_0 = 0x00,
00137 push_temp_1 = 0x01,
00138 push_temp_2 = 0x02,
00139 push_temp_3 = 0x03,
00140 push_temp_4 = 0x04,
00141 push_temp_5 = 0x05,
00142 unimplemented_06 = 0x06,
00143 push_temp_n = 0x07,
00144 push_arg_1 = 0x08,
00145 push_arg_2 = 0x09,
00146 push_arg_3 = 0x0a,
00147 push_arg_n = 0x0b,
00148 allocate_temp_1 = 0x0c,
00149 allocate_temp_2 = 0x0d,
00150 allocate_temp_3 = 0x0e,
00151 allocate_temp_n = 0x0f,
00152
00153
00154 store_temp_0_pop = 0x10,
00155 store_temp_1_pop = 0x11,
00156 store_temp_2_pop = 0x12,
00157 store_temp_3_pop = 0x13,
00158 store_temp_4_pop = 0x14,
00159 store_temp_5_pop = 0x15,
00160 store_temp_n = 0x16,
00161 store_temp_n_pop = 0x17,
00162 push_neg_n = 0x18,
00163 push_succ_n = 0x19,
00164 push_literal = 0x1a,
00165 push_tos = 0x1b,
00166 push_self = 0x1c,
00167 push_nil = 0x1d,
00168 push_true = 0x1e,
00169 push_false = 0x1f,
00170
00171
00172 unimplemented_20 = 0x20,
00173 unimplemented_21 = 0x21,
00174 unimplemented_22 = 0x22,
00175 unimplemented_23 = 0x23,
00176 unimplemented_24 = 0x24,
00177 unimplemented_25 = 0x25,
00178 unimplemented_26 = 0x26,
00179 unimplemented_27 = 0x27,
00180 return_instVar_name = 0x28,
00181 push_classVar = 0x29,
00182 store_classVar_pop = 0x2a,
00183 store_classVar = 0x2b,
00184 return_instVar = 0x2c,
00185 push_instVar = 0x2d,
00186 store_instVar_pop = 0x2e,
00187 store_instVar = 0x2f,
00188
00189
00190 float_allocate = 0x30,
00191 float_floatify_pop = 0x31,
00192 float_move = 0x32,
00193 float_set = 0x33,
00194 float_nullary_op = 0x34,
00195 float_unary_op = 0x35,
00196 float_binary_op = 0x36,
00197 float_unary_op_to_oop = 0x37,
00198 float_binary_op_to_oop = 0x38,
00199 unimplemented_39 = 0x39,
00200 unimplemented_3a = 0x3a,
00201 unimplemented_3b = 0x3b,
00202 unimplemented_3c = 0x3c,
00203 push_instVar_name = 0x3d,
00204 store_instVar_pop_name = 0x3e,
00205 store_instVar_name = 0x3f,
00206
00207
00208 push_temp_0_context_0 = 0x40,
00209 push_temp_1_context_0 = 0x41,
00210 push_temp_2_context_0 = 0x42,
00211 push_temp_n_context_0 = 0x43,
00212 store_temp_0_context_0_pop = 0x44,
00213 store_temp_1_context_0_pop = 0x45,
00214 store_temp_2_context_0_pop = 0x46,
00215 store_temp_n_context_0_pop = 0x47,
00216 push_new_closure_context_0 = 0x48,
00217 push_new_closure_context_1 = 0x49,
00218 push_new_closure_context_2 = 0x4a,
00219 push_new_closure_context_n = 0x4b,
00220 install_new_context_method_0 = 0x4c,
00221 install_new_context_method_1 = 0x4d,
00222 install_new_context_method_2 = 0x4e,
00223 install_new_context_method_n = 0x4f,
00224
00225
00226 push_temp_0_context_1 = 0x50,
00227 push_temp_1_context_1 = 0x51,
00228 push_temp_2_context_1 = 0x52,
00229 push_temp_n_context_1 = 0x53,
00230 store_temp_0_context_1_pop = 0x54,
00231 store_temp_1_context_1_pop = 0x55,
00232 store_temp_2_context_1_pop = 0x56,
00233 store_temp_n_context_1_pop = 0x57,
00234 push_new_closure_tos_0 = 0x58,
00235 push_new_closure_tos_1 = 0x59,
00236 push_new_closure_tos_2 = 0x5a,
00237 push_new_closure_tos_n = 0x5b,
00238 only_pop = 0x5c,
00239 install_new_context_block_1 = 0x5d,
00240 install_new_context_block_2 = 0x5e,
00241 install_new_context_block_n = 0x5f,
00242
00243
00244 push_temp_0_context_n = 0x60,
00245 push_temp_1_context_n = 0x61,
00246 push_temp_2_context_n = 0x62,
00247 push_temp_n_context_n = 0x63,
00248 store_temp_0_context_n_pop = 0x64,
00249 store_temp_1_context_n_pop = 0x65,
00250 store_temp_2_context_n_pop = 0x66,
00251 store_temp_n_context_n_pop = 0x67,
00252 set_self_via_context = 0x68,
00253 copy_1_into_context = 0x69,
00254 copy_2_into_context = 0x6a,
00255 copy_n_into_context = 0x6b,
00256 copy_self_into_context = 0x6c,
00257 copy_self_1_into_context = 0x6d,
00258 copy_self_2_into_context = 0x6e,
00259 copy_self_n_into_context = 0x6f,
00260
00261
00262 ifTrue_byte = 0x70,
00263 ifFalse_byte = 0x71,
00264 and_byte = 0x72,
00265 or_byte = 0x73,
00266 whileTrue_byte = 0x74,
00267 whileFalse_byte = 0x75,
00268 jump_else_byte = 0x76,
00269 jump_loop_byte = 0x77,
00270 ifTrue_word = 0x78,
00271 ifFalse_word = 0x79,
00272 and_word = 0x7a,
00273 or_word = 0x7b,
00274 whileTrue_word = 0x7c,
00275 whileFalse_word = 0x7d,
00276 jump_else_word = 0x7e,
00277 jump_loop_word = 0x7f,
00278
00279
00280 interpreted_send_0 = 0x80,
00281 interpreted_send_1 = 0x81,
00282 interpreted_send_2 = 0x82,
00283 interpreted_send_n = 0x83,
00284 interpreted_send_0_pop = 0x84,
00285 interpreted_send_1_pop = 0x85,
00286 interpreted_send_2_pop = 0x86,
00287 interpreted_send_n_pop = 0x87,
00288 interpreted_send_self = 0x88,
00289 interpreted_send_self_pop = 0x89,
00290 interpreted_send_super = 0x8a,
00291 interpreted_send_super_pop = 0x8b,
00292 return_tos_pop_0 = 0x8c,
00293 return_tos_pop_1 = 0x8d,
00294 return_tos_pop_2 = 0x8e,
00295 return_tos_pop_n = 0x8f,
00296
00297
00298 polymorphic_send_0 = 0x90,
00299 polymorphic_send_1 = 0x91,
00300 polymorphic_send_2 = 0x92,
00301 polymorphic_send_n = 0x93,
00302 polymorphic_send_0_pop = 0x94,
00303 polymorphic_send_1_pop = 0x95,
00304 polymorphic_send_2_pop = 0x96,
00305 polymorphic_send_n_pop = 0x97,
00306 polymorphic_send_self = 0x98,
00307 polymorphic_send_self_pop = 0x99,
00308 polymorphic_send_super = 0x9a,
00309 polymorphic_send_super_pop = 0x9b,
00310 return_self_pop_0 = 0x9c,
00311 return_self_pop_1 = 0x9d,
00312 return_self_pop_2 = 0x9e,
00313 return_self_pop_n = 0x9f,
00314
00315
00316 compiled_send_0 = 0xa0,
00317 compiled_send_1 = 0xa1,
00318 compiled_send_2 = 0xa2,
00319 compiled_send_n = 0xa3,
00320 compiled_send_0_pop = 0xa4,
00321 compiled_send_1_pop = 0xa5,
00322 compiled_send_2_pop = 0xa6,
00323 compiled_send_n_pop = 0xa7,
00324 compiled_send_self = 0xa8,
00325 compiled_send_self_pop = 0xa9,
00326 compiled_send_super = 0xaa,
00327 compiled_send_super_pop = 0xab,
00328 return_tos_zap_pop_n = 0xac,
00329 return_self_zap_pop_n = 0xad,
00330 non_local_return_tos_pop_n = 0xae,
00331 non_local_return_self_pop_n = 0xaf,
00332
00333
00334 prim_call = 0xb0,
00335 predict_prim_call = 0xb1,
00336 prim_call_failure = 0xb2,
00337 predict_prim_call_failure = 0xb3,
00338 dll_call_sync = 0xb4,
00339 prim_call_self = 0xb5,
00340 prim_call_self_failure = 0xb6,
00341 unimplemented_b7 = 0xb7,
00342 access_send_self = 0xb8,
00343 primitive_send_0 = 0xb9,
00344 primitive_send_super = 0xba,
00345 primitive_send_super_pop = 0xbb,
00346 unimplemented_bc = 0xbc,
00347 primitive_send_1 = 0xbd,
00348 primitive_send_2 = 0xbe,
00349 primitive_send_n = 0xbf,
00350
00351
00352 prim_call_lookup = 0xc0,
00353 predict_prim_call_lookup = 0xc1,
00354 prim_call_failure_lookup = 0xc2,
00355 predict_prim_call_failure_lookup = 0xc3,
00356 dll_call_async = 0xc4,
00357 prim_call_self_lookup = 0xc5,
00358 prim_call_self_failure_lookup = 0xc6,
00359 unimplemented_c7 = 0xc7,
00360 access_send_0 = 0xc8,
00361 primitive_send_0_pop = 0xc9,
00362 primitive_send_self = 0xca,
00363 primitive_send_self_pop = 0xcb,
00364 unimplemented_cc = 0xcc,
00365 primitive_send_1_pop = 0xcd,
00366 primitive_send_2_pop = 0xce,
00367 primitive_send_n_pop = 0xcf,
00368
00369
00370 megamorphic_send_0 = 0xd0,
00371 megamorphic_send_1 = 0xd1,
00372 megamorphic_send_2 = 0xd2,
00373 megamorphic_send_n = 0xd3,
00374 megamorphic_send_0_pop = 0xd4,
00375 megamorphic_send_1_pop = 0xd5,
00376 megamorphic_send_2_pop = 0xd6,
00377 megamorphic_send_n_pop = 0xd7,
00378 megamorphic_send_self = 0xd8,
00379 megamorphic_send_self_pop = 0xd9,
00380 megamorphic_send_super = 0xda,
00381 megamorphic_send_super_pop = 0xdb,
00382 unimplemented_dc = 0xdc,
00383 special_primitive_send_1_hint = 0xdd,
00384 unimplemented_de = 0xde,
00385 unimplemented_df = 0xdf,
00386
00387
00388 smi_add = 0xe0,
00389 smi_sub = 0xe1,
00390 smi_mult = 0xe2,
00391 smi_div = 0xe3,
00392 smi_mod = 0xe4,
00393 smi_create_point = 0xe5,
00394 smi_equal = 0xe6,
00395 smi_not_equal = 0xe7,
00396 smi_less = 0xe8,
00397 smi_less_equal = 0xe9,
00398 smi_greater = 0xea,
00399 smi_greater_equal = 0xeb,
00400 objArray_at = 0xec,
00401 objArray_at_put = 0xed,
00402 double_equal = 0xee,
00403 double_tilde = 0xef,
00404
00405
00406 push_global = 0xf0,
00407 store_global_pop = 0xf1,
00408 store_global = 0xf2,
00409 push_classVar_name = 0xf3,
00410 store_classVar_pop_name = 0xf4,
00411 store_classVar_name = 0xf5,
00412 smi_and = 0xf6,
00413 smi_or = 0xf7,
00414 smi_xor = 0xf8,
00415 smi_shift = 0xf9,
00416 unimplemented_fa = 0xfa,
00417 unimplemented_fb = 0xfb,
00418 unimplemented_fc = 0xfc,
00419 unimplemented_fd = 0xfd,
00420 unimplemented_fe = 0xfe,
00421 halt = 0xff,
00422
00423 number_of_codes = 0x100
00424 };
00425
00426 private:
00427 static char* _entry_point[number_of_codes];
00428 static char* _name[number_of_codes];
00429 static Format _format[number_of_codes];
00430 static CodeType _code_type[number_of_codes];
00431 static ArgumentSpec _argument_spec[number_of_codes];
00432 static SendType _send_type[number_of_codes];
00433 static bool _single_step[number_of_codes];
00434 static bool _pop_tos[number_of_codes];
00435
00436 static void def(Code code);
00437 static void def(Code code, char* name, Format format, CodeType code_type, bool single_step, bool pop_tos = false);
00438 static void def(Code code, char* name, Format format, ArgumentSpec argument_spec, SendType send_type, bool pop_tos = false);
00439 static void def(Code code, char* name, Format format, CodeType code_type, bool single_step, ArgumentSpec argument_spec, SendType send_type, bool pop_tos);
00440
00441 public:
00442
00443 static void set_entry_point(Code code, char* entry_point);
00444
00445
00446
00447 static bool is_defined(Code code) { return 0 <= code && code < number_of_codes && _format[code] != UNDEF; }
00448 static bool is_self_send(Code code);
00449 static bool is_super_send(Code code);
00450 static bool has_access_send_code(Code code);
00451 static bool has_predicted_send_code(Code code);
00452 static bool is_send_code(Code code) { return send_type(code) != no_send; }
00453
00454
00455
00456 static char* entry_point (Code code) { return _entry_point[code]; }
00457 static char* name (Code code) { return _name[code]; }
00458 static Format format (Code code) { return _format[code]; }
00459 static CodeType code_type (Code code) { return _code_type[code]; }
00460 static ArgumentSpec argument_spec (Code code) { return _argument_spec[code]; }
00461 static SendType send_type (Code code) { return _send_type[code]; }
00462 static bool single_step (Code code) { return _single_step[code]; }
00463 static bool pop_tos (Code code) { return _pop_tos[code]; }
00464 static LoopType loop_type (Code code);
00465
00466
00467
00468 static char* format_as_string (Format format);
00469 static char* code_type_as_string (CodeType code_type);
00470 static char* argument_spec_as_string (ArgumentSpec argument_spec);
00471 static char* send_type_as_string (SendType send_type);
00472 static char* loop_type_as_string (LoopType loop_type);
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 static Code original_send_code_for (Code code);
00483 static Code interpreted_send_code_for (Code code);
00484 static Code compiled_send_code_for (Code code);
00485 static Code access_send_code_for (Code code);
00486 static Code primitive_send_code_for (Code code);
00487 static Code polymorphic_send_code_for (Code code);
00488 static Code megamorphic_send_code_for (Code code);
00489
00490
00491
00492
00493
00494
00495
00496
00497 static Code original_primitive_call_code_for (Code code);
00498 static Code primitive_call_code_for (Code code);
00499
00500
00501
00502 static void init();
00503 static void print();
00504 };