00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "inst-priv.h"
00021
00024 enum {
00025 P_ARG_NONE,
00026 P_ARG_X,
00027 P_ARG_Y,
00028 P_ARG_X_X,
00029 P_ARG_Y_X,
00030 P_ARG_X_Y,
00031 P_ARG_X_X_LARGE,
00032 P_ARG_Y_X_LARGE,
00033 P_ARG_X_Y_LARGE,
00034 P_ARG_FUNCTOR,
00035 P_ARG_FUNCTOR_LARGE,
00036 P_ARG_CONSTANT,
00037 P_ARG_CONSTANT_X,
00038 P_ARG_MEMBER,
00039 P_ARG_MEMBER_LARGE,
00040 P_ARG_RESET,
00041 P_ARG_RESET_LARGE,
00042 P_ARG_LABEL
00043 };
00044
00045 enum {
00046 P_TYPE_GET,
00047 P_TYPE_STOP,
00048 P_TYPE_SKIP
00049 };
00050
00051 typedef struct p_inst_info p_inst_info;
00052 struct p_inst_info
00053 {
00054 const char *name;
00055 #if defined(P_TERM_64BIT)
00056 int arg_types;
00057 int get_put_type;
00058 #else
00059 short arg_types;
00060 short get_put_type;
00061 #endif
00062 };
00063 static p_inst_info const instructions[] = {
00064 {"put_variable", P_ARG_X, P_TYPE_SKIP},
00065 {"put_variable2", P_ARG_X_X, P_TYPE_SKIP},
00066 {"put_variable2_large", P_ARG_X_X_LARGE, P_TYPE_SKIP},
00067 {"put_variable2", P_ARG_Y_X, P_TYPE_SKIP},
00068 {"put_variable2_large", P_ARG_Y_X_LARGE, P_TYPE_SKIP},
00069 {"put_value", P_ARG_X_X, P_TYPE_GET},
00070 {"put_value_large", P_ARG_X_X_LARGE, P_TYPE_GET},
00071 {"put_value", P_ARG_Y_X, P_TYPE_SKIP},
00072 {"put_value_large", P_ARG_Y_X_LARGE, P_TYPE_SKIP},
00073 {"put_functor", P_ARG_FUNCTOR, P_TYPE_STOP},
00074 {"put_functor_large", P_ARG_FUNCTOR_LARGE, P_TYPE_STOP},
00075 {"put_list", P_ARG_X, P_TYPE_STOP},
00076 {"put_constant", P_ARG_CONSTANT_X, P_TYPE_STOP},
00077 {"put_member_variable", P_ARG_MEMBER, P_TYPE_SKIP},
00078 {"put_member_variable_large", P_ARG_MEMBER_LARGE, P_TYPE_SKIP},
00079 {"put_member_variable_auto", P_ARG_MEMBER, P_TYPE_SKIP},
00080 {"put_member_variable_auto_large", P_ARG_MEMBER_LARGE, P_TYPE_SKIP},
00081
00082 {"set_variable", P_ARG_X, P_TYPE_STOP},
00083 {"set_variable", P_ARG_Y, P_TYPE_STOP},
00084 {"set_value", P_ARG_X, P_TYPE_STOP},
00085 {"set_value", P_ARG_Y, P_TYPE_STOP},
00086 {"set_functor", P_ARG_FUNCTOR, P_TYPE_STOP},
00087 {"set_functor_large", P_ARG_FUNCTOR_LARGE, P_TYPE_STOP},
00088 {"set_list", P_ARG_X, P_TYPE_STOP},
00089 {"set_list_tail", P_ARG_X, P_TYPE_STOP},
00090 {"set_nil_tail", P_ARG_X, P_TYPE_STOP},
00091 {"set_constant", P_ARG_CONSTANT, P_TYPE_STOP},
00092 {"set_void", P_ARG_NONE, P_TYPE_STOP},
00093
00094 {"get_variable", P_ARG_X_Y, P_TYPE_GET},
00095 {"get_variable_large", P_ARG_X_Y_LARGE, P_TYPE_GET},
00096 {"get_value", P_ARG_X_X, P_TYPE_GET},
00097 {"get_value_large", P_ARG_X_X_LARGE, P_TYPE_GET},
00098 {"get_value", P_ARG_Y_X, P_TYPE_GET},
00099 {"get_value_large", P_ARG_Y_X_LARGE, P_TYPE_GET},
00100 {"get_functor", P_ARG_FUNCTOR, P_TYPE_GET},
00101 {"get_functor_large", P_ARG_FUNCTOR_LARGE, P_TYPE_GET},
00102 {"get_list", P_ARG_X_X, P_TYPE_GET},
00103 {"get_list_large", P_ARG_X_X_LARGE, P_TYPE_GET},
00104 {"get_atom", P_ARG_CONSTANT_X, P_TYPE_GET},
00105 {"get_constant", P_ARG_CONSTANT_X, P_TYPE_GET},
00106
00107 {"get_in_value", P_ARG_X_X, P_TYPE_GET},
00108 {"get_in_value_large", P_ARG_X_X_LARGE, P_TYPE_GET},
00109 {"get_in_value", P_ARG_Y_X, P_TYPE_GET},
00110 {"get_in_value_large", P_ARG_Y_X_LARGE, P_TYPE_GET},
00111 {"get_in_functor", P_ARG_FUNCTOR, P_TYPE_GET},
00112 {"get_in_functor_large", P_ARG_FUNCTOR_LARGE, P_TYPE_GET},
00113 {"get_in_list", P_ARG_X_X, P_TYPE_GET},
00114 {"get_in_list_large", P_ARG_X_X_LARGE, P_TYPE_GET},
00115 {"get_in_atom", P_ARG_CONSTANT_X, P_TYPE_GET},
00116 {"get_in_constant", P_ARG_CONSTANT_X, P_TYPE_GET},
00117
00118 {"unify_variable", P_ARG_X, P_TYPE_SKIP},
00119 {"unify_variable", P_ARG_Y, P_TYPE_SKIP},
00120 {"unify_value", P_ARG_X, P_TYPE_SKIP},
00121 {"unify_value", P_ARG_Y, P_TYPE_SKIP},
00122 {"unify_functor", P_ARG_FUNCTOR, P_TYPE_SKIP},
00123 {"unify_functor_large", P_ARG_FUNCTOR_LARGE, P_TYPE_SKIP},
00124 {"unify_list", P_ARG_X, P_TYPE_SKIP},
00125 {"unify_list_tail", P_ARG_X, P_TYPE_SKIP},
00126 {"unify_nil_tail", P_ARG_X, P_TYPE_SKIP},
00127 {"unify_atom", P_ARG_CONSTANT, P_TYPE_SKIP},
00128 {"unify_constant", P_ARG_CONSTANT, P_TYPE_SKIP},
00129 {"unify_void", P_ARG_NONE, P_TYPE_SKIP},
00130
00131 {"unify_in_value", P_ARG_X, P_TYPE_SKIP},
00132 {"unify_in_value", P_ARG_Y, P_TYPE_SKIP},
00133 {"unify_in_functor", P_ARG_FUNCTOR, P_TYPE_SKIP},
00134 {"unify_in_functor_large", P_ARG_FUNCTOR_LARGE, P_TYPE_SKIP},
00135 {"unify_in_list", P_ARG_X, P_TYPE_SKIP},
00136 {"unify_in_list_tail", P_ARG_X, P_TYPE_SKIP},
00137 {"unify_in_nil_tail", P_ARG_X, P_TYPE_SKIP},
00138 {"unify_in_atom", P_ARG_CONSTANT, P_TYPE_SKIP},
00139 {"unify_in_constant", P_ARG_CONSTANT, P_TYPE_SKIP},
00140 {"unify_in_void", P_ARG_NONE, P_TYPE_SKIP},
00141
00142 {"reset_argument", P_ARG_RESET, P_TYPE_SKIP},
00143 {"reset_argument_large", P_ARG_RESET_LARGE, P_TYPE_SKIP},
00144 {"reset_tail", P_ARG_X, P_TYPE_SKIP},
00145
00146 {"jump", P_ARG_LABEL, P_TYPE_SKIP},
00147
00148 {"proceed", P_ARG_NONE, P_TYPE_STOP},
00149 {"fail", P_ARG_NONE, P_TYPE_STOP},
00150 {"return", P_ARG_X, P_TYPE_STOP},
00151 {"return_true", P_ARG_NONE, P_TYPE_STOP},
00152 {"throw", P_ARG_X, P_TYPE_STOP},
00153
00154 #if 0
00155 P_OP_CALL,
00156 P_OP_EXECUTE,
00157
00158 P_OP_TRY_ME_ELSE,
00159 P_OP_RETRY_ME_ELSE,
00160 P_OP_TRUST_ME,
00161
00162 P_OP_NECK_CUT,
00163 P_OP_GET_LEVEL,
00164 P_OP_CUT,
00165 #endif
00166
00167 {"end", P_ARG_NONE, P_TYPE_STOP}
00168 };
00169
00170 void _p_code_disassemble
00171 (FILE *output, p_context *context, const p_code_clause *clause)
00172 {
00173 p_opcode opcode;
00174 size_t size;
00175 const p_inst *inst = (p_inst *)(clause->code->inst);
00176 for (;;) {
00177 opcode = (p_opcode)(inst->header.opcode);
00178 if (opcode == P_OP_JUMP) {
00179
00180 inst = inst->label.label;
00181 continue;
00182 } else if (opcode == P_OP_END) {
00183
00184 break;
00185 }
00186 fprintf(output, "%08lx: %s", (long)inst,
00187 instructions[opcode].name);
00188 switch (instructions[opcode].arg_types) {
00189 case P_ARG_NONE:
00190 default:
00191 size = sizeof(inst->header);
00192 break;
00193 case P_ARG_X:
00194 fprintf(output, " X%u", inst->one_reg.reg1);
00195 size = sizeof(inst->one_reg);
00196 break;
00197 case P_ARG_Y:
00198 fprintf(output, " Y%u", inst->one_reg.reg1);
00199 size = sizeof(inst->one_reg);
00200 break;
00201 case P_ARG_X_X:
00202 fprintf(output, " X%u, X%u", inst->two_reg.reg1,
00203 inst->two_reg.reg2);
00204 size = sizeof(inst->two_reg);
00205 break;
00206 case P_ARG_Y_X:
00207 fprintf(output, " Y%u, X%u", inst->two_reg.reg1,
00208 inst->two_reg.reg2);
00209 size = sizeof(inst->two_reg);
00210 break;
00211 case P_ARG_X_Y:
00212 fprintf(output, " X%u, Y%u", inst->two_reg.reg1,
00213 inst->two_reg.reg2);
00214 size = sizeof(inst->two_reg);
00215 break;
00216 case P_ARG_X_X_LARGE:
00217 fprintf(output, " X%u, X%u", inst->large_two_reg.reg1,
00218 inst->large_two_reg.reg2);
00219 size = sizeof(inst->large_two_reg);
00220 break;
00221 case P_ARG_Y_X_LARGE:
00222 fprintf(output, " Y%u, X%u", inst->large_two_reg.reg1,
00223 inst->large_two_reg.reg2);
00224 size = sizeof(inst->large_two_reg);
00225 break;
00226 case P_ARG_X_Y_LARGE:
00227 fprintf(output, " X%u, Y%u", inst->large_two_reg.reg1,
00228 inst->large_two_reg.reg2);
00229 size = sizeof(inst->large_two_reg);
00230 break;
00231 case P_ARG_FUNCTOR:
00232 putc(' ', output);
00233 p_term_print(context, inst->functor.name,
00234 p_term_stdio_print_func, output);
00235 fprintf(output, "/%u, X%u",
00236 inst->functor.arity, inst->functor.reg1);
00237 size = sizeof(inst->functor);
00238 break;
00239 case P_ARG_FUNCTOR_LARGE:
00240 putc(' ', output);
00241 p_term_print(context, inst->large_functor.name,
00242 p_term_stdio_print_func, output);
00243 fprintf(output, "/%u, X%u",
00244 inst->large_functor.arity,
00245 inst->large_functor.reg1);
00246 size = sizeof(inst->large_functor);
00247 break;
00248 case P_ARG_CONSTANT:
00249 putc(' ', output);
00250 p_term_print(context, inst->constant.value,
00251 p_term_stdio_print_func, output);
00252 size = sizeof(inst->constant);
00253 break;
00254 case P_ARG_CONSTANT_X:
00255 putc(' ', output);
00256 p_term_print(context, inst->constant.value,
00257 p_term_stdio_print_func, output);
00258 fprintf(output, ", X%u", inst->constant.reg1);
00259 size = sizeof(inst->constant);
00260 break;
00261 case P_ARG_MEMBER:
00262 fprintf(output, " X%u, ", inst->functor.reg1);
00263 p_term_print(context, inst->functor.name,
00264 p_term_stdio_print_func, output);
00265 fprintf(output, ", X%u", inst->functor.arity);
00266 size = sizeof(inst->functor);
00267 break;
00268 case P_ARG_MEMBER_LARGE:
00269 fprintf(output, " X%u, ", inst->large_functor.reg1);
00270 p_term_print(context, inst->large_functor.name,
00271 p_term_stdio_print_func, output);
00272 fprintf(output, ", X%u", inst->large_functor.arity);
00273 size = sizeof(inst->large_functor);
00274 break;
00275 case P_ARG_RESET:
00276 fprintf(output, " X%u, %u", inst->two_reg.reg1,
00277 inst->two_reg.reg2);
00278 size = sizeof(inst->two_reg);
00279 break;
00280 case P_ARG_RESET_LARGE:
00281 fprintf(output, " X%u, %u", inst->large_two_reg.reg1,
00282 inst->large_two_reg.reg2);
00283 size = sizeof(inst->large_two_reg);
00284 break;
00285 case P_ARG_LABEL:
00286 fprintf(output, " %08lx", (long)(inst->label.label));
00287 size = sizeof(inst->label);
00288 break;
00289 }
00290 putc('\n', output);
00291 inst = (p_inst *)(((char *)inst) + size);
00292 }
00293 }
00294
00295
00296 int _p_code_argument_key
00297 (p_rbkey *key, const p_code_clause *clause, unsigned int arg)
00298 {
00299 p_opcode opcode;
00300 size_t size;
00301 const p_inst *inst = (p_inst *)(clause->code->inst);
00302 for (;;) {
00303 opcode = (p_opcode)(inst->header.opcode);
00304 if (opcode == P_OP_JUMP) {
00305
00306 inst = inst->label.label;
00307 continue;
00308 } else if (opcode == P_OP_END) {
00309
00310 break;
00311 }
00312 switch (instructions[opcode].get_put_type) {
00313 case P_TYPE_GET:
00314 switch (opcode) {
00315
00316
00317 case P_OP_PUT_X_VALUE:
00318 case P_OP_GET_Y_VARIABLE:
00319 if (inst->two_reg.reg1 == arg)
00320 return 0;
00321 break;
00322 case P_OP_PUT_X_VALUE_LARGE:
00323 case P_OP_GET_Y_VARIABLE_LARGE:
00324 if (inst->large_two_reg.reg1 == arg)
00325 return 0;
00326 break;
00327 case P_OP_GET_X_VALUE:
00328 case P_OP_GET_Y_VALUE:
00329 case P_OP_GET_IN_X_VALUE:
00330 case P_OP_GET_IN_Y_VALUE:
00331 if (inst->two_reg.reg2 == arg)
00332 return 0;
00333 break;
00334 case P_OP_GET_X_VALUE_LARGE:
00335 case P_OP_GET_Y_VALUE_LARGE:
00336 case P_OP_GET_IN_X_VALUE_LARGE:
00337 case P_OP_GET_IN_Y_VALUE_LARGE:
00338 if (inst->large_two_reg.reg2 == arg)
00339 return 0;
00340 break;
00341
00342 case P_OP_GET_FUNCTOR:
00343 case P_OP_GET_IN_FUNCTOR:
00344 if (inst->functor.reg1 != arg)
00345 break;
00346 key->type = P_TERM_FUNCTOR;
00347 key->size = inst->functor.arity;
00348 key->name = inst->functor.name;
00349 return 1;
00350 case P_OP_GET_FUNCTOR_LARGE:
00351 case P_OP_GET_IN_FUNCTOR_LARGE:
00352 if (inst->large_functor.reg1 != arg)
00353 break;
00354 key->type = P_TERM_FUNCTOR;
00355 key->size = inst->large_functor.arity;
00356 key->name = inst->large_functor.name;
00357 return 1;
00358 case P_OP_GET_LIST:
00359 case P_OP_GET_IN_LIST:
00360 if (inst->two_reg.reg1 != arg)
00361 break;
00362 key->type = P_TERM_LIST;
00363 key->size = 0;
00364 key->name = 0;
00365 return 1;
00366 case P_OP_GET_LIST_LARGE:
00367 case P_OP_GET_IN_LIST_LARGE:
00368 if (inst->large_two_reg.reg1 != arg)
00369 break;
00370 key->type = P_TERM_LIST;
00371 key->size = 0;
00372 key->name = 0;
00373 return 1;
00374 case P_OP_GET_ATOM:
00375 case P_OP_GET_IN_ATOM:
00376 if (inst->constant.reg1 != arg)
00377 break;
00378 key->type = P_TERM_ATOM;
00379 key->size = 0;
00380 key->name = inst->constant.value;
00381 return 1;
00382 case P_OP_GET_CONSTANT:
00383 case P_OP_GET_IN_CONSTANT:
00384 if (inst->constant.reg1 != arg)
00385 break;
00386 key->type = inst->constant.value->header.type;
00387 if (key->type == P_TERM_INTEGER) {
00388 key->size = p_term_integer_value
00389 (inst->constant.value);
00390 key->name = 0;
00391 } else {
00392 key->size = 0;
00393 key->name = inst->constant.value;
00394 }
00395 return 1;
00396 default: break;
00397 }
00398 break;
00399
00400 case P_TYPE_STOP:
00401
00402 return 0;
00403
00404 case P_TYPE_SKIP: break;
00405 }
00406 switch (instructions[opcode].arg_types) {
00407 case P_ARG_NONE:
00408 default:
00409 size = sizeof(inst->header);
00410 break;
00411 case P_ARG_X:
00412 size = sizeof(inst->one_reg);
00413 break;
00414 case P_ARG_Y:
00415 size = sizeof(inst->one_reg);
00416 break;
00417 case P_ARG_X_X:
00418 size = sizeof(inst->two_reg);
00419 break;
00420 case P_ARG_Y_X:
00421 size = sizeof(inst->two_reg);
00422 break;
00423 case P_ARG_X_Y:
00424 size = sizeof(inst->two_reg);
00425 break;
00426 case P_ARG_X_X_LARGE:
00427 size = sizeof(inst->large_two_reg);
00428 break;
00429 case P_ARG_Y_X_LARGE:
00430 size = sizeof(inst->large_two_reg);
00431 break;
00432 case P_ARG_X_Y_LARGE:
00433 size = sizeof(inst->large_two_reg);
00434 break;
00435 case P_ARG_FUNCTOR:
00436 size = sizeof(inst->functor);
00437 break;
00438 case P_ARG_FUNCTOR_LARGE:
00439 size = sizeof(inst->large_functor);
00440 break;
00441 case P_ARG_CONSTANT:
00442 size = sizeof(inst->constant);
00443 break;
00444 case P_ARG_CONSTANT_X:
00445 size = sizeof(inst->constant);
00446 break;
00447 case P_ARG_MEMBER:
00448 size = sizeof(inst->functor);
00449 break;
00450 case P_ARG_MEMBER_LARGE:
00451 size = sizeof(inst->large_functor);
00452 break;
00453 case P_ARG_RESET:
00454 size = sizeof(inst->two_reg);
00455 break;
00456 case P_ARG_RESET_LARGE:
00457 size = sizeof(inst->large_two_reg);
00458 break;
00459 case P_ARG_LABEL:
00460 size = sizeof(inst->label);
00461 break;
00462 }
00463 inst = (p_inst *)(((char *)inst) + size);
00464 }
00465 return 0;
00466 }
00467