Skip to content

Commit 11b1430

Browse files
committed
Start replacing container spec approach.
This is the minimum needed to get NQP to build and pass its tests again with the data structure updates. Still needs some more infrastructure before we can start updating Rakudo to use this new approach.
1 parent 3c65140 commit 11b1430

File tree

6 files changed

+88
-114
lines changed

6 files changed

+88
-114
lines changed

src/6model/serialization.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
/* Version of the serialization format that we are currently at and lowest
2121
* version we support. */
22-
#define CURRENT_VERSION 3
22+
#define CURRENT_VERSION 4
2323
#define MIN_VERSION 1
2424

2525
/* Various sizes (in bytes). */
@@ -748,10 +748,11 @@ static void serialize_stable(PARROT_INTERP, SerializationWriter *writer, PMC *st
748748
/* Container spec. */
749749
write_int_func(interp, writer, st->container_spec != NULL);
750750
if (st->container_spec) {
751-
write_ref_func(interp, writer, st->container_spec->value_slot.class_handle);
752-
write_str_func(interp, writer, st->container_spec->value_slot.attr_name);
753-
write_int_func(interp, writer, st->container_spec->value_slot.hint);
754-
write_ref_func(interp, writer, st->container_spec->fetch_method);
751+
/* Write container spec name. */
752+
write_str_func(interp, writer, st->container_spec->name);
753+
754+
/* Give container spec a chance to serialize any data it wishes. */
755+
st->container_spec->serialize(interp, st, writer);
755756
}
756757

757758
/* If the REPR has a function to serialize representation data, call it. */
@@ -1617,11 +1618,15 @@ static void deserialize_stable(PARROT_INTERP, SerializationReader *reader, INTVA
16171618

16181619
/* Container spec. */
16191620
if (read_int_func(interp, reader)) {
1620-
st->container_spec = (ContainerSpec *)mem_sys_allocate(sizeof(ContainerSpec));
1621-
st->container_spec->value_slot.class_handle = read_ref_func(interp, reader);
1622-
st->container_spec->value_slot.attr_name = read_str_func(interp, reader);
1623-
st->container_spec->value_slot.hint = read_int_func(interp, reader);
1624-
st->container_spec->fetch_method = read_ref_func(interp, reader);
1621+
/* Depends on version. If before 4, we don't try to read it. */
1622+
if (reader->root.version < 4)
1623+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
1624+
"Unable to deserialize old container spec format");
1625+
1626+
/* Otherwise, resolve the container spec by name and get it
1627+
* set up. */
1628+
read_str_func(interp, reader);
1629+
/* XXX TODO: The rest of this. */
16251630
}
16261631

16271632
/* Mark it as being in the SC we're currently deserializing. */

src/6model/sixmodelobject.c

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -183,26 +183,7 @@ PMC * create_stable(PARROT_INTERP, REPROps *REPR, PMC *HOW) {
183183
/* Performs a decontainerizing operation on the passed variable, using
184184
* the 6model container API. */
185185
PMC * decontainerize(PARROT_INTERP, PMC *var) {
186-
if (var->vtable->base_type == smo_id) {
187-
ContainerSpec *spec = STABLE(var)->container_spec;
188-
if (spec && IS_CONCRETE(var)) {
189-
if (!PMC_IS_NULL(spec->value_slot.class_handle)) {
190-
/* Just get slot. */
191-
return VTABLE_get_attr_keyed(interp, var, spec->value_slot.class_handle,
192-
spec->value_slot.attr_name);
193-
}
194-
else {
195-
/* Invoke FETCH method. */
196-
PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
197-
PMC *meth = spec->fetch_method;
198-
PMC *cappy = Parrot_pmc_new(interp, enum_class_CallContext);
199-
VTABLE_push_pmc(interp, cappy, var);
200-
Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
201-
cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
202-
Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
203-
return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
204-
}
205-
}
206-
}
186+
if (var->vtable->base_type == smo_id)
187+
var = DECONT(interp, var);
207188
return var;
208189
}

src/6model/sixmodelobject.h

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,32 @@ typedef struct {
2929
INTVAL hint; /* Hint for use in static/gradual typing. */
3030
} AttributeIdentifier;
3131

32-
/* Language interop information that we hold if the type is declaring a
33-
* container of some sort. */
32+
/* Container specification information, for types that serve as containers.
33+
* A container is something that can be assigned into. It may be some kind
34+
* of container object (like Perl 6's Scalar) or it may be a reference to a
35+
* native lexical or object field. The function table determines the way it
36+
* behaves. */
3437
typedef struct {
35-
AttributeIdentifier value_slot;
36-
PMC *fetch_method;
38+
/* Fetches a value out of a container. Used for decontainerization. */
39+
PMC * (*fetch) (PARROT_INTERP, PMC *cont);
40+
41+
/* Stores a value in a container. Used for assignment. */
42+
void (*store) (PARROT_INTERP, PMC *cont, PMC *obj);
43+
44+
/* Name of this container specification. */
45+
STRING *name;
46+
47+
/* Marks container data, if any. */
48+
void (*gc_mark_data) (PARROT_INTERP, STable *st);
49+
50+
/* Frees container data, if any. */
51+
void (*gc_free_data) (PARROT_INTERP, STable *st);
52+
53+
/* Serializes the container data, if any. */
54+
void (*serialize) (PARROT_INTERP, STable *st, SerializationWriter *writer);
55+
56+
/* Deserializes the container data, if any. */
57+
void (*deserialize) (PARROT_INTERP, STable *st, SerializationReader *reader);
3758
} ContainerSpec;
3859

3960
/* How do we invoke this thing? Specifies either an attribute to look at for
@@ -138,10 +159,14 @@ struct SixModel_STable {
138159
INTVAL type_cache_id;
139160

140161
/* If this is a container, then this contains information needed in
141-
* order to fetch the value in it. If not, it'll be null, which can
142-
* be taken as a "not a container" indication. */
162+
* order to fetch the value in it or assign a value to it. If not,
163+
* it'll be null, which can be taken as a "not a container" indication. */
143164
ContainerSpec *container_spec;
144165

166+
/* Data that the container spec may need to function. */
167+
/* Any data specific to this type that the REPR wants to keep. */
168+
void *container_data;
169+
145170
/* If this is invokable, then this contains information needed to
146171
* figure out how to invoke it. If not, it'll be null. */
147172
InvocationSpec *invocation_spec;
@@ -394,6 +419,11 @@ struct SixModel_REPROps {
394419
#define IS_CONCRETE(o) (!PObj_flag_TEST(private0, (o)))
395420
#define MARK_AS_TYPE_OBJECT(o) PObj_flag_SET(private0, (o))
396421

422+
/* Macro for decontainerization. */
423+
#define DECONT(interp, o) (STABLE(o)->container_spec ? \
424+
STABLE(o)->container_spec->fetch(interp, o) : \
425+
o)
426+
397427
/* Write barriers for noticing changes to objects or STables with an SC. */
398428
typedef void (* obj_sc_barrier_func) (PARROT_INTERP, PMC *obj);
399429
typedef void (* st_sc_barrier_func) (PARROT_INTERP, STable *st);

src/ops/nqp_dyncall.ops

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -545,27 +545,8 @@ unmarshal_callback(PARROT_INTERP, PMC *value, PMC *info) {
545545
}
546546

547547
PMC * decontainerize(PARROT_INTERP, PMC *var) {
548-
if (var->vtable->base_type == smo_id) {
549-
ContainerSpec *spec = STABLE(var)->container_spec;
550-
if (spec && IS_CONCRETE(var)) {
551-
if (!PMC_IS_NULL(spec->value_slot.class_handle)) {
552-
/* Just get slot. */
553-
return VTABLE_get_attr_keyed(interp, var, spec->value_slot.class_handle,
554-
spec->value_slot.attr_name);
555-
}
556-
else {
557-
/* Invoke FETCH method. */
558-
PMC *old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
559-
PMC *meth = spec->fetch_method;
560-
PMC *cappy = Parrot_pmc_new(interp, enum_class_CallContext);
561-
VTABLE_push_pmc(interp, cappy, var);
562-
Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
563-
cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
564-
Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
565-
return VTABLE_get_pmc_keyed_int(interp, cappy, 0);
566-
}
567-
}
568-
}
548+
if (var->vtable->base_type == smo_id)
549+
var = DECONT(interp, var);
569550
return var;
570551
}
571552

0 commit comments

Comments
 (0)