Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial import - not yet working, but shows basic premise

  • Loading branch information...
commit a5d28df634b797e0c3e884595e9c22b02646baa1 0 parents
Peter Lobsinger authored
30 setup.json
@@ -0,0 +1,30 @@
+{
+ "name": "deepclone",
+ "version": "0.001",
+
+ "abstract": "deep clone library",
+ "description": "Deep cloning library operating on arbitrary Parrot PMCs",
+ "keywords": [ "deep clone", "clone", "copy" ],
+
+ "copyright_holder": "Peter Lobsinger",
+ "license_type": "Artistic License 2.0",
+ "license_uri": "http://www.perlfoundation.org/artistic_license_2_0",
+
+ "checkout_uri": "git://github.com/plobsing/parrot-deepclone.git",
+ "browser_uri": "http://github.com/plobsing/parrot-deepclone",
+ "project_uri": "http://github.com/plobsing/parrot-deepclone",
+
+ "pir_winxed": {
+ "src/deepclone.pir": "src/deepclone.winxed"
+ },
+
+ "pbc_pir": {
+ "src/deepclone.pbc": "src/deepclone.pir"
+ },
+
+ "c_dynext": {
+ "deepclonehelper": {
+ "src": [ "src/deepclonehelper.c" ]
+ }
+ }
+}
287 setup.winxed
@@ -0,0 +1,287 @@
+#! winxed
+
+/*
+
+=head1 NAME
+
+setup.winxed - Python distutils style
+
+=head1 DESCRIPTION
+
+=head2 Functions
+
+=over 4
+
+=item C<main>
+
+run distutils
+
+=cut
+
+ */
+
+function main(var argv) {
+ using extern distutils;
+
+ /* ignore first element in argv (program name) */
+ argv.shift();
+
+ using build_pir_winxed;
+ using build_c_dynext;
+ register_step_before('build', build_pir_winxed);
+ register_step_after('build', build_c_dynext);
+
+ using clean_pir_winxed;
+ using clean_c_dynext;
+ register_steb_after('clean', clean_pir_winxed);
+ register_step_before('clean', clean_c_dynext);
+
+ var conf = load_setup_json();
+ setup(argv:[flat], conf:[flat,named]);
+}
+
+
+/*
+
+=item C<load_setup_json>
+
+read setup.json
+
+=cut
+
+*/
+
+function load_setup_json() {
+ var file = open('setup.json');
+ string json_str = file.readall();
+ file.close();
+ var json = load_language('data_json');
+ var promise = json.compile(json_str);
+ return promise();
+}
+
+
+/*
+
+=item C<build_pir_winxed()>
+
+compile Winxed files to PIR
+
+=cut
+
+*/
+
+function build_pir_winxed(var kv[named, slurpy]) {
+ var hash = kv['pir_winxed'];
+
+ if (!hash) return;
+
+ string flags = get_value('pir_winxed_flags', '':[named('default')], kv:[flat,named]);
+
+ var jobs = new 'ResizableStringArray'();
+ for (string pir in hash) {
+ string winxed = hash[pir];
+
+ if (newer(pir, winxed)) continue;
+
+ mkpath(dirname(pir), 1:[named('verbose')]);
+
+ string cmd = sprintf("%s --target=pir --output=%s %s %s", [
+ get_winxed(), pir, flags, winxed
+ ]);
+
+ jobs.push(cmd);
+ }
+
+ run_jobs(jobs);
+}
+
+
+/*
+
+=item C<clean_pir_winxed()>
+
+cleanup PIR files generated from Winxed files
+
+=cut
+
+*/
+
+function clean_pir_winxed(var kv[named, slurpy]) {
+ var hash = kv['pir_winxed'];
+
+ if (!hash) return;
+
+ for (string pir in hash)
+ unlink(pir, 1:[named('verbose')]);
+}
+
+
+/*
+
+=item C<build_c_dynext>
+
+=cut
+
+*/
+
+function build_c_dynext(kv[named, slurpy]) {
+ var hash = kv['c_dynext'];
+
+ if (!hash) return;
+
+ var config = get_config();
+ mkpath('dynext', 1:[named('verbose')]);
+
+ for (string dyn_name in hash) {
+ var opts = hash[dyn_name];
+ string dyn_file = dyn_filename(dyn_name);
+
+ string ccflags = opts['ccflags'] + get_cflags();
+
+ // mostly taken from distutils.pir '__build_dynpmc_alone'
+ string ldflags = join(' ', [
+ opts['ldflags'], config['ld_load_flags'],
+ config['parrot_is_shared'] ? config['inst_libparrot_ldflags'] : ''
+ ]);
+
+ var jobs = new 'ResizableStringArray'();
+ var o_files = new 'ResizableStringArray'();
+ for (string src in opts['src']) {
+ var obj = c_to_o_file(src);
+ o_files.push(obj);
+
+ if (newer(obj, src)) continue;
+
+ // mostly stolen from distutils.pir '__compile_cc'
+ string cmd = join(' ', [
+ config['cc'], '-c', config['cc_o_out'], obj,
+ '-I', get_incdir(), '-I', get_incdir() + '/pmc', '-I', cwd(),
+ ccflags, src
+ ]);
+
+ jobs.push(cmd);
+ }
+
+ run_jobs(jobs);
+
+ string cmd = join(' ', [
+ config['ld'], config['ld_out'], dyn_file, ldflags, join(' ', o_files)
+ ]);
+
+ system(cmd, 1:[named('verbose')]);
+
+ /* XXX don't have access to has_strip outside of distutils.pir */
+ }
+}
+
+
+/*
+
+=item C<clean_c_dynext()>
+
+=cut
+
+*/
+
+function clean_c_dynext(kv[named, slurpy]) {
+ var hash = kv['c_dynext'];
+
+ if (!hash) return;
+
+ for (string dyn_name in hash) {
+ var opts = hash[dyn_name];
+
+ for (string src in opts['src'])
+ unlink(c_to_o_file(src), 1:[named('verbose')]);
+
+ unlink(dyn_filename(dyn_name), 1:[named('verbose')]);
+ }
+}
+
+
+/*
+
+=item C<c_to_o_file()>
+
+=cut
+
+*/
+
+function c_to_o_file(string cfile) {
+ int strlen = length(cfile);
+ string obj_ext = get_config()['o'];
+ string ofile = substr(cfile, strlen - 2, 2) == '.c' ?
+ substr(cfile, 0, strlen - 2) + obj_ext :
+ cfile + obj_ext;
+ return ofile;
+}
+
+
+/*
+
+=item C<dyn_filename()>
+
+=cut
+
+*/
+
+function dyn_filename(string dyn) {
+ string load_ext = get_load_ext();
+ return 'dynext/lib' + dyn + load_ext;
+}
+
+
+/*
+
+=item C<compile_dynlib>
+
+compile a Parrot dynlib from a set of C source files using (optional) flags
+
+mostly stolen from C<distutils.pir>
+
+=cut
+
+*/
+
+function compile_dynlib(string name, var sources, string cflags, string ldflags) {
+ cflags = join(' ', [cflags, get_cflags()]);
+ ldflags = join(' ', [ldflags, get_ldflags()]);
+
+ mkpath('dynext', 1:[named('verbose')]);
+
+ string obj_ext = get_obj();
+ var objects = new 'ResizableStringArray'();
+ for (string src in sources) {
+ int strlen = length(src);
+ var obj = substr(src, strlen - 2, 2) == '.c' ?
+ substr(src, 0, strlen - 2) + obj_ext :
+ src + obj_ext;
+ __compile_cc(obj, src, cflags);
+ objects.push(obj);
+ }
+
+ var config = get_config();
+ string load_ext = get_load_ext();
+ string dynext = 'dynext/' + name + load_ext;
+ string cmd = join( ' ', [ config['ld'], config['ld_out'], dynext, ldflags,
+ config['ld_load_flags'], config['parrot_is_shared'] ?
+ config['inst_libparrot_ldflags'] : '' ] )
+ + join(' ', objects);
+ system(cmd, 1:[named('verbose')]);
+
+ // XXX no access to _has_strip outside of distutils.pir
+ // if (_has_strip(cflags))
+ // system('strip ' + dynext, 1:[named(verbose)]);
+}
+
+
+/*
+
+=back
+
+=cut
+
+vim: expandtab shiftwidth=4 ft=javascript:
+
+*/
167 src/deepclone.winxed
@@ -0,0 +1,167 @@
+#! winxed
+
+const int VISIT_FREEZE_NORMAL = 0x04; // 0x00 | 0x04;
+const int VISIT_THAW_NORMAL = 0x05; // 0x01 | 0x04;
+
+const int Hash_key_type_pointer = 4;
+
+function onload[anon, load] () {
+ var core_nci_funcs = {
+ "Parrot_pmc_new_noinit" : "PJI",
+ "Parrot_PMC_visit" : "vJPP",
+ "Parrot_PMC_freeze" : "vJPP",
+ "Parrot_PMC_thaw" : "vJPP",
+ "Parrot_PMC_thawfinish" : "vJPP"
+ };
+ var lib = null;
+ for (string name in core_nci_funcs) {
+ string sig = core_nci_funcs[name];
+ var nci = dlfunc(lib, name, sig);
+ ${ set_hll_global name, nci };
+ }
+
+ /*
+ * Use a helper library to get at data Parrot wisely
+ * encapsulates away from the programmer.
+ *
+ * XXX Don't do this at home!
+ */
+ var my_lib = loadlib("deepclonehelper");
+ var my_nci_funcs = {
+ "pmc_addr" : "IJP",
+ "pmc_get_meta" : "PJP",
+ "pmc_set_meta" : "vJPP",
+ "pmc_typenum" : "IJP"
+ };
+ for (string name in my_nci_funcs) {
+ string sig = my_nci_funcs[name];
+ var nci = dlfunc(my_lib, name, sig);
+ ${ set_hll_global name, nci };
+ }
+}
+
+class DeepClone {
+ var todo;
+ var seen;
+ var state;
+
+ var int_queue;
+ var num_queue;
+ var str_queue;
+ var pmc_queue;
+
+ function init_pmc[vtable] (var orig) {
+ self.todo = new 'ResizablePMCArray'();
+ // XXX winxed constant expansion bug
+ // self.seen = new 'Hash'(Hash_key_type_pointer);
+ self.seen = new 'Hash'(4);
+ self.state = new 'Integer'();
+
+ self.int_queue = new 'ResizableIntegerArray'();
+ self.num_queue = new 'ResizableFloatArray'();
+ self.str_queue = new 'ResizableStringArray'();
+ self.pmc_queue = new 'ResizablePMCArray'();
+
+ ${ push self.todo, orig };
+ }
+
+ function get_pmc[vtable] () {
+ using Parrot_PMC_visit;
+ using Parrot_PMC_freeze;
+ using Parrot_PMC_thaw;
+ using Parrot_PMC_thawfinish;
+ using pmc_get_meta;
+ using pmc_set_meta;
+ using pmc_addr;
+
+ for (int i = 0; i < self.todo; i++) {
+ var orig = self.todo[i];
+ var meta = pmc_get_meta(orig);
+ self.state = VISIT_FREEZE_NORMAL;
+ Parrot_PMC_visit(orig, self);
+ Parrot_PMC_freeze(orig, self);
+ self.push_pmc(meta);
+
+ int addr = pmc_addr(orig);
+ var dup = self.seen[addr];
+ self.state = VISIT_THAW_NORMAL;
+ Parrot_PMC_visit(dup, self);
+ Parrot_PMC_thaw(dup, self);
+ pmc_set_meta(dup, self.shift_pmc());
+ }
+
+ for (int i = 0; i < self.todo; i++) {
+ var dup = self.seen[pmc_addr(self.todo[i])];
+ Parrot_PMC_thawfinish(dup, self);
+ }
+
+ return self.todo[0];
+ }
+
+ function get_integer[vtable] () {
+ int i = self.state;
+ return i;
+ }
+
+ function push_pmc[vtable] (var v) {
+ using pmc_addr;
+ int addr = pmc_addr(v);
+
+ var dup;
+ int i;
+ ${ isnull i, v };
+ if (i) {
+ dup = null;
+ }
+ else if (exists(self.seen[addr])) {
+ dup = self.seen[addr];
+ }
+ else {
+ using pmc_typenum;
+ using Parrot_pmc_new_noinit;
+ int i = pmc_typenum(v);
+ dup = Parrot_pmc_new_noinit(i);
+ self.seen[addr] = dup;
+ ${ push self.todo, v };
+ }
+
+ ${ push self.pmc_queue, dup };
+ }
+
+ function shift_pmc[vtable] () {
+ var v;
+ ${ shift v, self.pmc_queue };
+ return v;
+ }
+
+ function push_integer[vtable] (int v) {
+ ${ push self.int_queue, v };
+ }
+
+ function shift_integer[vtable] () {
+ int v;
+ ${ shift v, self.int_queue };
+ return v;
+ }
+
+ function push_float[vtable] (float v) {
+ ${ push self.num_queue, v };
+ }
+
+ function shift_float[vtable] () {
+ float v;
+ ${ shift v, self.num_queue };
+ return v;
+ }
+
+ function push_string[vtable] (string v) {
+ ${ push self.str_queue, v };
+ }
+
+ function shift_string[vtable] () {
+ string v;
+ ${ shift v, self.str_queue };
+ return v;
+ }
+}
+
41 src/deepclonehelper.c
@@ -0,0 +1,41 @@
+/*
+ * deepclonehelper.c - helper functions for DeepClone
+ */
+
+/*
+ * These functions horribly break encapsulation on PMCs. Yes, I'm a horrible person.
+ *
+ * P.S.: HORRIBLE!!!
+ */
+#include <parrot/parrot.h>
+
+PARROT_DYNEXT_EXPORT
+INTVAL
+pmc_addr(PARROT_INTERP, PMC *obj) {
+ return (INTVAL)obj;
+}
+
+PARROT_DYNEXT_EXPORT
+PMC *
+pmc_get_meta(PARROT_INTERP, PMC *obj) {
+ return PMC_metadata(obj);
+}
+
+PARROT_DYNEXT_EXPORT
+void
+pmc_set_meta(PARROT_INTERP, PMC *obj, PMC *meta) {
+ PMC_metadata(obj) = meta;
+}
+
+PARROT_DYNEXT_EXPORT
+INTVAL
+pmc_typenum(PARROT_INTERP, PMC *obj) {
+ return obj->vtable->base_type;
+}
+
+/*
+ * Local variables:
+ * c-file-style: "parrot"
+ * End:
+ * vim: expandtab shiftwidth=4:
+ */
Please sign in to comment.
Something went wrong with that request. Please try again.