1
/* This implements a little bit of support for serialization contexts.
2
* At the moment, its main role is to just be a global lookup table for
3
* serialization contexts; it'll need to get much smarter. */
5
#define PARROT_IN_EXTENSION
6
#include "parrot/parrot.h"
7
#include "parrot/extend.h"
8
#include "serialization_context.h"
9
#include "pmc_serializationcontext.h"
11
/* Hash of serialization context objects */
12
static PMC *scs = NULL;
14
/* Initializes the store and register with the GC. */
15
static void setup_sc_stores(PARROT_INTERP) {
16
scs = Parrot_pmc_new(interp, enum_class_Hash);
17
Parrot_pmc_gc_register(interp, scs);
20
/* Gets the serialization context - if any - associated with the
21
* specified handle. */
22
PMC * SC_get_sc(PARROT_INTERP, STRING *handle) {
24
setup_sc_stores(interp);
25
return VTABLE_get_pmc_keyed_str(interp, scs, handle);
28
/* Stashes a serialization context with the specified handle. */
29
void SC_set_sc(PARROT_INTERP, STRING *handle, PMC *sc) {
31
setup_sc_stores(interp);
32
VTABLE_set_pmc_keyed_str(interp, scs, handle, sc);
35
/* Given an SC, returns its unique handle. */
36
STRING * SC_get_handle(PARROT_INTERP, PMC *sc) {
38
GETATTR_SerializationContext_handle(interp, sc, handle);
42
/* Given an SC, returns its description. */
43
STRING * SC_get_description(PARROT_INTERP, PMC *sc) {
45
GETATTR_SerializationContext_description(interp, sc, description);
49
/* Given an SC, looks up the index of an STable that is in its root set. */
50
INTVAL SC_find_stable_idx(PARROT_INTERP, PMC *sc, PMC *st) {
53
GETATTR_SerializationContext_root_stables(interp, sc, to_search);
54
count = VTABLE_elements(interp, to_search);
55
for (i = 0; i < count; i++)
56
if (VTABLE_get_pmc_keyed_int(interp, to_search, i) == st)
58
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
59
"STable does not exist in serialization context");
62
/* Given an SC, looks up the index of an object that is in its root set. */
63
INTVAL SC_find_object_idx(PARROT_INTERP, PMC *sc, PMC *obj) {
66
GETATTR_SerializationContext_root_objects(interp, sc, to_search);
67
count = VTABLE_elements(interp, to_search);
68
for (i = 0; i < count; i++)
69
if (VTABLE_get_pmc_keyed_int(interp, to_search, i) == obj)
71
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
72
"Object does not exist in serialization context");
75
/* Given an SC, looks up the index of a code ref that is in its root set. */
76
INTVAL SC_find_code_idx(PARROT_INTERP, PMC *sc, PMC *obj) {
79
GETATTR_SerializationContext_root_codes(interp, sc, to_search);
80
count = VTABLE_elements(interp, to_search);
81
for (i = 0; i < count; i++)
82
if (VTABLE_get_pmc_keyed_int(interp, to_search, i) == obj)
84
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
85
"Code ref '%Ss' does not exist in serialization context",
86
VTABLE_get_string(interp, obj));
89
/* Given an SC and an index, fetch the STable stored there. */
90
PMC * SC_get_stable(PARROT_INTERP, PMC *sc, INTVAL idx) {
92
GETATTR_SerializationContext_root_stables(interp, sc, stables);
93
if (idx >= VTABLE_elements(interp, stables))
94
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
95
"No STable at index %d", idx);
96
return VTABLE_get_pmc_keyed_int(interp, stables, idx);
99
/* Given an SC and an index, fetch the object stored there. */
100
PMC * SC_get_object(PARROT_INTERP, PMC *sc, INTVAL idx) {
102
GETATTR_SerializationContext_root_objects(interp, sc, objects);
103
if (idx >= VTABLE_elements(interp, objects))
104
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
105
"No object at index %d", idx);
106
return VTABLE_get_pmc_keyed_int(interp, objects, idx);
109
/* Given an SC and an index, fetch the code ref stored there. */
110
PMC * SC_get_code(PARROT_INTERP, PMC *sc, INTVAL idx) {
112
GETATTR_SerializationContext_root_codes(interp, sc, codes);
113
if (idx >= VTABLE_elements(interp, codes))
114
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
115
"No code ref at index %d", idx);
116
return VTABLE_get_pmc_keyed_int(interp, codes, idx);
119
/* Adds a code ref to an SC. */
120
void SC_set_code(PARROT_INTERP, PMC *sc, INTVAL idx, PMC *code) {
122
GETATTR_SerializationContext_root_codes(interp, sc, codes);
123
VTABLE_set_pmc_keyed_int(interp, codes, idx, code);
126
/* Takes an object and adds it to this SC's root set, and installs a
127
* reposession entry. */
128
void SC_repossess_object(PARROT_INTERP, PMC *target_sc, PMC *orig_sc, PMC *object) {
129
PMC *rep_indexes, *rep_scs;
131
/* Add to root set. */
134
GETATTR_SerializationContext_root_objects(interp, target_sc, objects);
135
new_slot = VTABLE_elements(interp, objects);
136
VTABLE_set_pmc_keyed_int(interp, objects, new_slot, object);
138
/* Add repossession entry. */
139
GETATTR_SerializationContext_rep_indexes(interp, target_sc, rep_indexes);
140
GETATTR_SerializationContext_rep_scs(interp, target_sc, rep_scs);
141
VTABLE_push_integer(interp, rep_indexes, new_slot << 1);
142
VTABLE_push_pmc(interp, rep_scs, orig_sc);
145
/* Takes an STable and adds it to this SC's root set, and installs a
146
* reposession entry. */
147
void SC_repossess_stable(PARROT_INTERP, PMC *target_sc, PMC *orig_sc, PMC *st_pmc) {
148
PMC *rep_indexes, *rep_scs;
150
/* Add to root set. */
153
GETATTR_SerializationContext_root_stables(interp, target_sc, stables);
154
new_slot = VTABLE_elements(interp, stables);
155
VTABLE_set_pmc_keyed_int(interp, stables, new_slot, st_pmc);
157
/* Add repossession entry. */
158
GETATTR_SerializationContext_rep_indexes(interp, target_sc, rep_indexes);
159
GETATTR_SerializationContext_rep_scs(interp, target_sc, rep_scs);
160
VTABLE_push_integer(interp, rep_indexes, (new_slot << 1) | 1);
161
VTABLE_push_pmc(interp, rep_scs, orig_sc);