module: dfmc-flow-graph Author: Jonathan Bachrach Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND //// DFM COPYING POLICY define compiler-open class () end class; define dont-copy-object using ; define dont-copy-object using ; define dont-copy-object <&top> using ; define dont-copy-object <&primitive> using ; define dont-copy-object <&definition> using ; define dont-copy-object using ; define dont-copy-object using ; define dont-copy-object using ; define dont-copy-object using ; define dont-copy-object <&namespace> using ; define dont-copy-object <&mm-wrapper> using ; define dont-copy-object <&singular-terminal-engine-node> using ; // define dont-copy-slots using = // { dood-pointer => #f }; define dont-copy-slots using = { object-dood => #f }; define dont-copy-slots using = { item-status => $queueable-item-absent }; define dont-copy-slots using = { computation-source-location => parent-source-location(), computation-type => #f }; define dont-copy-slots using = { %label => #f }; define dont-copy-slots using = { %label => #f }; define dont-copy-slots using = { private-model-creator => (*current-dependent* | error("Attempt to copy a model outside of proper compilation-context")) }; define dont-copy-slots using = { emitted-name => #f, emitted-type-name => #f }; define dont-copy-slots <&lambda> using = { lambda-heap => #f, // private-signature-spec => #f, // private-body-spec => #f }; define dont-copy-slots <&iep> using = { code => #f }; // If a call checked incompatible out of line, it might still become // compatible inline (and so amenable to upgrading and inlining), so // we reset its state in the inline copy. define method do-deep-copy (copier :: , object :: ) => (value) let copy = next-method(); copy.item-status := $queueable-item-absent; copy end method; define method do-deep-copy (copier :: , object :: ) => (value) let copy = next-method(); if (copy.compatibility-state == $compatibility-checked-incompatible) copy.compatibility-state := $compatibility-unchecked; end; copy end method; define method do-deep-copy (copier :: , object :: ) => (value) let copy = next-method(); copy.call-inlining-depth := *inlining-depth*; copy end method; define method do-deep-copy (copier :: , object :: ) => (value) let copy = next-method(); referenced-binding(copy) := local-binding-in-requesting-library(referenced-binding(copy)); copy end method; define method do-deep-copy (copier :: , object :: ) => (value) let copy = next-method(); remove-closure!(copy); copy end method; define method do-deep-copy (copier :: , object :: <&profiling-call-site-cache-header-engine-node>) => (value) let copy = next-method(); let ld = model-library(copy); ^profiling-call-site-cache-header-engine-node-id(copy) := library-generate-call-site-id(ld); ^profiling-call-site-cache-header-engine-node-library(copy) := namespace-model(language-definition(ld)); copy end method; define method deep-copy (copier :: , object :: ) => (value) deep-copy(copier, dood-force-slot-value-proxy(object)) end method; define method deep-copy (copier :: , object :: <&object>) => (value) if (model-has-definition?(object)) object // reference by name else maybe-do-deep-copy(copier, object) end if end method; define method deep-copy (copier :: , object :: <&lambda>) => (value) let m = next-method(); if (m == object) // maybe in process of being inline-only copied? element(walker-walked(copier), object, default: #f) | m else m end if end method; define thread variable *dfm-copier-environment-context* = #f; define macro with-dfm-copier-environment { with-dfm-copier-environment (?:expression) ?:body end } => { dynamic-bind (*dfm-copier-environment-context* = ?expression) ?body end dynamic-bind } end macro; define method do-deep-copy (copier :: , object :: ) => (value) let copy = next-method(); if (*dfm-copier-environment-context*) let state = entry-state(object); exits(state) := add-new!(exits(state), copy); add-user!(state, copy); end if; copy end method; define method deep-copy (copier :: , object :: ) => (value) let copying-environment = *dfm-copier-environment-context*; if (~copying-environment | (copying-environment & inner-environment?(object, copying-environment))) maybe-do-deep-copy(copier, object); else object end if; end method; define method deep-copy (copier :: , object :: ) => (value) let copying-environment = *dfm-copier-environment-context*; if (~copying-environment | (copying-environment & inner-environment?(environment(object), copying-environment))) maybe-do-deep-copy(copier, object); else object end if; end method; define method deep-copy (copier :: , object :: ) => (value) let copying-environment = *dfm-copier-environment-context*; if (~copying-environment | (copying-environment & inner-environment?(environment(object), copying-environment))) maybe-do-deep-copy(copier, object); else object end if; end method; // TODO: This is very bad because of the number of non-modeled vectors // in the DFM representation. /* define method deep-copy (copier :: , object :: ) => (copy :: ) if (model-has-definition?(object)) object else let copy = next-method(); copy end; end method; */ // TODO: We have to do this for real at some point, on all model vectors. // For now, this handles manually mapping the type vectors in the // signatures of non-key methods (enough for the FFI). define method do-deep-copy (copier :: , object :: <&signature>) => (value :: <&signature>) let copy = next-method(); let copy-required = ^signature-required(copy); if (copy-required ~== ^signature-required(object)) mapped-model(copy-required); end; let copy-values = ^signature-values(copy); if (copy-values ~== ^signature-values(object)) mapped-model(copy-values); end; copy end method; define method do-deep-copy (copier :: , object :: <&keyword-signature>) => (value :: <&signature>) let copy = next-method(); let copy-keys = ^signature-keys(copy); if (copy-keys ~== ^signature-keys(object)) mapped-model(copy-keys); end; let copy-key-types = ^signature-key-types(copy); if (copy-key-types ~== ^signature-key-types(object)) mapped-model(copy-key-types); end; copy end method; // Unlike primitves, of which they're a slightly suspect subclass, // raw c-function objects don't have definitions of their own and // must be copied. define method deep-copy (copier :: , object :: <&c-function>) => (value) maybe-do-deep-copy(copier, object) end method; define method deep-copy (copier :: , object :: <&raw-object>) => (value) maybe-do-deep-copy(copier, object) end method; define method deep-copy (copier :: , object :: <&code>) => (value) if (model-has-definition?(function(object))) object // reference by name else maybe-do-deep-copy(copier, object) end if end method; define method number-temporaries (f :: <&lambda>) => (res :: ) number-temporaries(environment(f)) end method; define function estimated-copier-table-size (f :: <&lambda>) => (res :: ) number-temporaries(f) * 15 end function; define function current-dfm-copier (capacity :: ) => (res :: ) copier-reset (library-description-dfm-copier(dylan-library-description()) | (library-description-dfm-copier(dylan-library-description()) := make()), capacity: capacity); end function; // eof