fix codetest failure - trailing whitespace
[parrot.git] / src / pmc / opcode.pmc
blob1d06f26a8348342bb10fa99bd932144d7db097aa
1 /*
2 Copyright (C) 2010, Parrot Foundation.
3 $Id$
5 =head1 NAME
7 src/pmc/opcode.pmc
9 =head1 DESCRIPTION
11 Implements opcode VTABLEs.
13 =cut
17 #include "parrot/parrot.h"
19 pmclass Opcode auto_attrs {
20     ATTR op_info_t *info;
21     ATTR INTVAL op_number;
22     ATTR STRING *full_name_cache;
24     VTABLE void init() {
25         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
26             "Opcode must be created from OpLib.");
27     }
29     VTABLE void mark() {
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);
33     }
35     VTABLE void set_pointer(void *i) {
36         Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
37         if (attrs->info)
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;
41     }
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);
47         if (num == -1)
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);
51     }
53     VTABLE INTVAL get_integer() {
54         Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
55         if (!attrs->info)
56             return -1;
57         return attrs->op_number;
58     }
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);
63         if (attrs->info)
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;
71     }
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;
80         }
81         return attrs->full_name_cache;
82     }
84     VTABLE INTVAL elements() {
85         Parrot_Opcode_attributes * const attrs = PARROT_OPCODE(SELF);
86         if (!attrs->info)
87             return -1;
88         return attrs->info->op_count - 1;
89     }
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]
95                : -1;
96     }
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);
103     }
105     METHOD jump() {
106         const op_info_t * const info = PARROT_OPCODE(SELF)->info;
107         const INTVAL jump = info->jump;
108         RETURN(INTVAL jump);
109     }
111     METHOD dirs() {
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;
115         if (arg_count > 0) {
116             INTVAL i;
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]);
120         }
121         RETURN(PMC *result);
122     }
124     METHOD labels() {
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;
128         if (arg_count > 0) {
129             INTVAL i;
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]);
133         }
134         RETURN(PMC *result);
135     }
140  * Local variables:
141  *   c-file-style: "parrot"
142  * End:
143  * vim: expandtab shiftwidth=4:
144  */