Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base: master
...
compare: pasm-serializer
Checking mergeability… Don't worry, you can still create the pull request.
  • 4 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Showing with 313 additions and 0 deletions.
  1. +2 −0  MANIFEST
  2. +243 −0 src/pmc/pasmserializer.pmc
  3. +68 −0 t/pmc/pasmserializer.t
View
2  MANIFEST
@@ -1401,6 +1401,7 @@ src/pmc/packfilesegment.pmc []
src/pmc/parrotinterpreter.pmc []
src/pmc/parrotlibrary.pmc []
src/pmc/parrotthread.pmc []
+src/pmc/pasmserializer.pmc []
src/pmc/pmc.num []
src/pmc/pmcproxy.pmc []
src/pmc/pointer.pmc []
@@ -1905,6 +1906,7 @@ t/pmc/parrotio.t [test]
t/pmc/parrotlibrary.t [test]
t/pmc/parrotobject.t [test]
t/pmc/parrotthread.t [test]
+t/pmc/pasmserializer.t [test]
t/pmc/pmc.t [test]
t/pmc/pmcproxy.t [test]
t/pmc/pointer.t [test]
View
243 src/pmc/pasmserializer.pmc
@@ -0,0 +1,243 @@
+/*
+Copyright (C) 2010, Parrot Foundation.
+$Id$
+
+=head1
+
+src/pmc/pasmserializer - PASM Object Serializer
+
+=head1 DESCRIPTION
+
+Freezes and thaws PMCs using a text format suitable for use in PASM.
+
+=head2 Vtables
+
+=over 4
+
+=cut
+
+*/
+
+static void
+push_sep(PARROT_INTERP, PMC *self)
+{
+ PMC *buf = PARROT_PASMSERIALIZER(self)->buffer;
+ VTABLE_push_string(interp, buf, CONST_STRING(interp, " "));
+}
+
+/* HEADERIZER HFILE: none */
+
+pmclass PASMSerializer auto_attrs {
+ ATTR PMC *buffer;
+ ATTR PMC *seen;
+ ATTR PMC *todo;
+ ATTR UINTVAL id;
+ ATTR INTVAL action;
+
+/*
+
+=item C<void init()>
+
+Initialize the serializer.
+
+=cut
+
+*/
+
+ VTABLE void init() {
+ PARROT_PASMSERIALIZER(SELF)->buffer = PMCNULL;
+ PARROT_PASMSERIALIZER(SELF)->todo = Parrot_pmc_new(INTERP, enum_class_ResizablePMCArray);
+ PARROT_PASMSERIALIZER(SELF)->seen = PMCNULL;
+ PARROT_PASMSERIALIZER(SELF)->id = 0;
+
+ PObj_custom_mark_SET(SELF);
+ }
+
+/*
+
+=item C<void mark()>
+
+Mark the PMC as alive.
+
+=cut
+
+*/
+
+ VTABLE void mark() {
+ Parrot_gc_mark_PMC_alive(INTERP, PARROT_PASMSERIALIZER(SELF)->buffer);
+ Parrot_gc_mark_PMC_alive(INTERP, PARROT_PASMSERIALIZER(SELF)->todo);
+ Parrot_gc_mark_PMC_alive(INTERP, PARROT_PASMSERIALIZER(SELF)->seen);
+ }
+
+/*
+
+=item C<PMC *get_iter()>
+
+Get the C<todo> list for this freeze/thaw for iterating over.
+
+=cut
+
+*/
+
+ VTABLE PMC *get_iter() {
+ return PARROT_PASMSERIALIZER(SELF)->todo;
+ }
+
+/*
+
+=item C<INTVAL get_integer()>
+
+Get the flags describing this visit action
+
+=cut
+
+*/
+
+ VTABLE INTVAL get_integer() {
+ return PARROT_PASMSERIALIZER(SELF)->action;
+ }
+
+/*
+
+=item C<void push_integer(INTVAL v)>
+
+=item C<void push_float(FLOATVAL v)>
+
+=item C<void push_string(STRING *v)>
+
+=item C<void push_pmc(PMC *v)>
+
+Push data item C<v> onto the end of the image being frozen.
+
+=cut
+
+*/
+
+ VTABLE void push_integer(INTVAL v) {
+ PMC *buf = PARROT_PASMSERIALIZER(SELF)->buffer;
+ push_sep(INTERP, SELF);
+ VTABLE_push_string(INTERP, buf, Parrot_str_from_int(INTERP, v));
+ }
+
+ VTABLE void push_float(FLOATVAL v) {
+ PMC *buf = PARROT_PASMSERIALIZER(SELF)->buffer;
+ push_sep(INTERP, SELF);
+ VTABLE_push_string(INTERP, buf, Parrot_str_from_num(INTERP, v));
+ }
+
+ VTABLE void push_string(STRING *v) {
+ PMC *buf = PARROT_PASMSERIALIZER(SELF)->buffer;
+ push_sep(INTERP, SELF);
+ if (STRING_IS_NULL(v)) {
+ VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "STRINGNULL"));
+ }
+ else {
+ VTABLE_push_string(INTERP, buf,
+ Parrot_encoding_name(INTERP, Parrot_encoding_number_of_str(INTERP, v)));
+ VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, ":\""));
+ VTABLE_push_string(INTERP, buf, Parrot_str_escape(INTERP, v));
+ VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "\""));
+ }
+ }
+
+ VTABLE void push_pmc(PMC *v) {
+ PMC *buf = PARROT_PASMSERIALIZER(SELF)->buffer;
+ PMC *seen = PARROT_PASMSERIALIZER(SELF)->seen;
+ INTVAL id;
+ INTVAL was_seen;
+
+ if (PARROT_PASMSERIALIZER(SELF)->id)
+ push_sep(INTERP, SELF);
+
+ if (PMC_IS_NULL(v)) {
+ id = 0;
+ was_seen = 1;
+ }
+ else {
+ was_seen = VTABLE_exists_keyed(INTERP, seen, v);
+ if (was_seen)
+ id = VTABLE_get_integer_keyed(INTERP, seen, v);
+ else
+ id = ++PARROT_PASMSERIALIZER(SELF)->id;
+ }
+
+ VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "$"));
+ VTABLE_push_string(INTERP, buf, Parrot_str_from_int(INTERP, id));
+
+ if (!was_seen) {
+ VTABLE_set_integer_keyed(INTERP, seen, v, id);
+ VTABLE_push_pmc(INTERP, PARROT_PASMSERIALIZER(SELF)->todo, v);
+
+ VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, ":"));
+ VTABLE_push_string(INTERP, buf, VTABLE_name(INTERP, v));
+ }
+ }
+
+/*
+
+=item C<STRING *get_string()>
+
+Get the serialized image as a string (after freezing).
+
+=cut
+
+*/
+
+ VTABLE STRING *get_string() {
+ return VTABLE_get_string(INTERP, PARROT_PASMSERIALIZER(SELF)->buffer);
+ }
+
+/*
+
+=item C<void set_pmc(PMC *p)>
+
+Freeze the PMC C<p> into the buffer.
+
+=cut
+
+*/
+
+ VTABLE void set_pmc(PMC *p) {
+ PARROT_PASMSERIALIZER(SELF)->action = VISIT_FREEZE_NORMAL;
+ PARROT_PASMSERIALIZER(SELF)->buffer = Parrot_pmc_new(INTERP, enum_class_StringBuilder);
+ PARROT_PASMSERIALIZER(SELF)->seen = Parrot_pmc_new(INTERP, enum_class_Hash);
+ VTABLE_set_pointer(INTERP, PARROT_PASMSERIALIZER(SELF)->seen,
+ parrot_new_intval_hash(INTERP));
+ SELF.push_pmc(p);
+
+ // Parrot_visit_loop_visit(INTERP, SELF);
+ {
+ INTVAL i;
+ PMC *buf = PARROT_PASMSERIALIZER(SELF)->buffer;
+ PMC *todo = VTABLE_get_iter(INTERP, SELF);
+ for (i = 0; i < VTABLE_elements(INTERP, todo); i++) {
+ PMC *current = VTABLE_get_pmc_keyed_int(INTERP, todo, i);
+
+ VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, "\n$"));
+ VTABLE_push_string(INTERP, buf, Parrot_str_from_int(INTERP, i + 1));
+ VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, ":["));
+
+ VTABLE_freeze(INTERP, current, SELF);
+ VTABLE_visit(INTERP, current, SELF);
+ VISIT_PMC(INTERP, SELF, PMC_metadata(current));
+
+ VTABLE_push_string(INTERP, buf, CONST_STRING(INTERP, " ]"));
+ }
+ }
+ }
+}
+
+/*
+
+=back
+
+=cut
+
+*/
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
View
68 t/pmc/pasmserializer.t
@@ -0,0 +1,68 @@
+#!perl
+# Copyright (C) 2011, Parrot Foundation.
+
+use strict;
+use warnings;
+use lib qw[ . lib ../lib ../../lib ];
+use Test::More;
+use Parrot::Test tests => 2;
+
+
+pir_output_like(<<'CODE', <<'OUT', 'PASMSerialize(FIA)');
+.sub 'main' :main
+ $P0 = new ['FixedIntegerArray']
+ $P0 = 5
+ $P0[0] = 1
+ $P0[1] = 2
+ $P0[2] = 3
+ $P0[3] = 4
+ $P0[4] = 5
+
+ $P1 = new ['PASMSerializer']
+ setref $P1, $P0
+ $S0 = $P1
+ say $S0
+.end
+CODE
+/
+ [$]1: FixedIntegerArray \n
+ [$]1: \[ \s (?: \d+ \s )+ [$]0 \s \] \n
+/mx
+OUT
+
+pir_output_like(<<'CODE', <<'OUT', 'PASMSerialize(RPA)');
+.sub 'main' :main
+ $P0 = new ['ResizablePMCArray']
+ $P0[0] = $P0
+ $P1 = box 42
+ $P2 = new ['Hash']
+ $P2['Hello World'] = $P1
+ $P2['Circular Ref'] = $P0
+ $P0[1] = $P1
+ $P0[2] = $P2
+
+ $P1 = new ['PASMSerializer']
+ setref $P1, $P0
+ $S0 = $P1
+ say $S0
+.end
+CODE
+/
+ [$]1: ResizablePMCArray \n
+ (?:
+ [$]\d+: \[ \s (?: (?: -? \d+ (?: [.] \d+ )? (?: e \d+ )?
+ | \w+:"(?: [^"] | \\ ")*"
+ | STRINGNULL
+ | [$]\d+ (?: : \w+)?
+ )
+ \s )+ [$]0 \s \] \n
+ ){3}
+/mx
+OUT
+
+# Local Variables:
+# mode: cperl
+# cperl-indent-level: 4
+# fill-column: 100
+# End:
+# vim: expandtab shiftwidth=4:

No commit comments for this range

Something went wrong with that request. Please try again.