2 Copyright (C) 2010, Parrot Foundation.
11 Implements opcode VTABLEs.
17 #include "parrot/parrot.h"
19 pmclass Opcode auto_attrs {
21 ATTR INTVAL op_number;
22 ATTR STRING *full_name_cache;
25 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
26 "Opcode must be created from OpLib.");
30 Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
31 if (attrs->full_name_cache)
32 Parrot_gc_mark_STRING_alive(INTERP, attrs->full_name_cache);
35 VTABLE void set_pointer(void *i) {
36 Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
38 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
39 "Opcode has already been initialized");
40 attrs->info = (op_info_t *)i;
43 VTABLE void set_string_native(STRING *name) {
44 char * cstr = Parrot_str_to_cstring(INTERP, name);
45 const INTVAL num = INTERP->op_lib->op_code(INTERP, cstr, 1);
46 Parrot_str_free_cstring(cstr);
48 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
49 "Opcode: Opcode %S not found", name);
50 VTABLE_set_integer_native(INTERP, SELF, num);
53 VTABLE INTVAL get_integer() {
54 Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
57 return attrs->op_number;
60 VTABLE void set_integer_native(INTVAL value) {
61 const INTVAL opcount = INTERP->op_lib->op_count;
62 Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
64 Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
65 "Opcode has already been initialized");
66 if (value >= opcount || value < 0)
67 Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_OUT_OF_BOUNDS,
68 "Opcode: Opcode index %d out of bounds", value);
69 attrs->info = &(INTERP->op_info_table[value]);
70 attrs->op_number = value;
73 VTABLE STRING* get_string() {
74 Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
75 if (attrs->full_name_cache == NULL) {
76 const char * const name = attrs->info->full_name;
77 const INTVAL len = strlen(name);
78 STRING * const newstr = Parrot_str_new(INTERP, name, len);
79 attrs->full_name_cache = newstr;
81 return attrs->full_name_cache;
84 VTABLE INTVAL elements() {
85 Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
88 return attrs->info->op_count - 1;
91 VTABLE INTVAL get_integer_keyed_int(INTVAL i) {
92 Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
93 return i < attrs->info->op_count - 1
94 ? (INTVAL)attrs->info->types[i]
98 METHOD family_name() {
99 const char * const name = PARROT_OPCODE(SELF)->info->name;
100 const INTVAL len = strlen(name);
101 STRING * result = Parrot_str_new(INTERP, name, len);
102 RETURN(STRING *result);
106 const op_info_t * const info = PARROT_OPCODE(SELF)->info;
107 const INTVAL jump = info->jump;
112 const op_info_t * const info = PARROT_OPCODE(SELF)->info;
113 PMC *result = Parrot_pmc_new(INTERP, enum_class_FixedIntegerArray);
114 INTVAL arg_count = info->op_count - 1;
117 VTABLE_set_integer_native(INTERP, result, arg_count);
118 for (i = 0; i < arg_count; ++i)
119 VTABLE_set_integer_keyed_int(INTERP, result, i, (INTVAL) info->dirs[i]);
125 const op_info_t * const info = PARROT_OPCODE(SELF)->info;
126 PMC *result = Parrot_pmc_new(INTERP, enum_class_FixedIntegerArray);
127 INTVAL arg_count = info->op_count - 1;
130 VTABLE_set_integer_native(INTERP, result, arg_count);
131 for (i = 0; i < arg_count; ++i)
132 VTABLE_set_integer_keyed_int(INTERP, result, i, (INTVAL) info->labels[i]);
141 * c-file-style: "parrot"
143 * vim: expandtab shiftwidth=4: