Module: dfmc-flow-graph Author: Jonathan Bachrach and Keith Playford 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 define abstract class () end class; define method generator (ref :: ) => (object) #f end method; // Like a value continuation define dood-class () weak slot generator :: false-or() = #f, reinit-expression: #f, init-keyword: generator:; weak slot environment :: false-or(), reinit-expression: #f, required-init-keyword: environment:; slot temporary-properties :: = 0; end dood-class; // Seal construction over the world. define sealed domain make (subclass()); define sealed domain initialize (); define sealed domain initialize-packed-slots (); define method assignments (t :: ) => (res) #() end method; define method name (o :: ) => (res :: ) #f end method; define inline function pack-false-or-field (x :: false-or()) => (z :: ) if (x) x else 0 end end function; define inline function unpack-false-or-field (x :: ) => (z :: false-or()) if (x = 0) #f else x end end function; define constant $max-frame-offset-field-size = 12; define constant $max-frame-offset = ash(1, $max-frame-offset-field-size) - 1; define packed-slots temporary-properties (, ) eval slot closed-over? = #f, field-size: 2, pack-function: pack-false-or-field, unpack-function: unpack-false-or-field; field slot frame-offset = 0, field-size: $max-frame-offset-field-size; quadstate slot dynamic-extent? = #"unknown"; end packed-slots; define method initialize (temporary :: , #rest all-keys, #key environment) next-method(); apply(initialize-packed-slots, temporary, all-keys); add-temporary!(environment, temporary); temporary.frame-offset := min(next-frame-offset(environment), $max-frame-offset); temporary end method; define class (, ) end class; define class (, ) end class; define class () slot assignments :: = #(); slot cell-type :: <&type>, init-keyword: cell-type:; end class; define method cell? (t :: ) #f end; define method cell? (t :: ) #t end; define class () slot me-block :: false-or(), init-keyword: block:; slot exits :: = #(); end class; define leaf packed-slots temporary-properties (, ) boolean slot local-entry-state? = #f; end packed-slots; // a temporary for %stack-vector computation define class () slot number-values :: = 0, init-keyword: number-values:; end class; // define constant = type-union(, singleton(#"not-computed")); // a temporary for computations that produce multiple values. define constant $max-number-values-field-size = 8; define constant $max-number-values = ash(1, $max-number-values-field-size); define class () end class ; // The required-values and rest-values? slots of mv-temps are intended to be // set during conversion. They record the in which the // mv-temp was created. If set, we can assume that the dfm is doing its best // to satisfy the signature of the mv-temp. For ex., if the mv-temp has a // required-values = 2 and is generated by a function call with a #rest values // signature, there will be an ADJ-MV done if necessary to guarantee that at // least two values are available from the MV area. Of course, the back-end may // ignore ADJ-MV computations, if it has other ways of insuring that accesses // to the MV area will yield correct results. define leaf packed-slots temporary-properties (, ) boolean slot mvt-required-initialized? = #f; field slot %required-values = 0, field-size: $max-number-values-field-size; tristate slot %rest-values? = #"unknown"; end packed-slots; // handle initialization, where required-vals and rest-vals? are being set. define method initialize (tmp :: , #rest all-keys, #key environment, required-values, rest-values? = #"unknown") next-method(); if (required-values) tmp.required-values := required-values; end if; if (rest-values? ~== #"unknown") tmp.rest-values? := rest-values?; end if; end method; /* define function mvt-debug-name (o :: ) if (named?(o)) format-to-string("%s/%=", o.name, o.frame-offset); else if (o.frame-offset) format-to-string("*t%d", o.frame-offset - o.environment.lambda.parameters.size); else "*t?" end if; end if; end function; */ define method required-values (tmp :: ) => (n :: ) if (mvt-required-initialized?(tmp)) %required-values(tmp); else 0; end if; end method; define method required-values-setter (new-val :: , tmp :: ) => (n :: ) mvt-required-initialized?(tmp) := #t; tmp.%required-values := new-val end method; define method rest-values? (tmp :: ) => (b :: ) if (%rest-values?(tmp) ~== #"unknown") %rest-values?(tmp); else #t; end if; end method; define method rest-values?-setter (new-val :: , tmp :: ) => (n :: ) tmp.%rest-values? := new-val end method; define method mvt-transfer-values! (from, to) => () if (instance?(from, ) & instance?(to, ) & mvt-required-initialized?(from)) required-values(to) := required-values(from); rest-values?(to) := rest-values?(from); end if; end method; define generic multiple-values? (t :: ) => (boolean :: ); define method multiple-values? (t :: ) => (boolean :: ); #f end method multiple-values?; define method multiple-values? (t :: ) => (boolean :: ); #t end method multiple-values?;