Module: dfmc-application Synopsis: environment protocols from the application Author: Paul Howard 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 // Note: // The application proxy for is // , defined in this library. It holds the // value of the variable as either a or a tracked // . ///// // The superclass of all application local variable proxies. define sealed abstract class () constant slot local-lexical-name :: , required-init-keyword: name:; constant slot is-argument? :: = #f, init-keyword: argument?:; end class; ///// // An application local variable that is not from Dylan. define class () constant slot local-foreign-value :: , required-init-keyword: foreign-value:; end class; ///// // An application local variable that _is_ from Dylan. define class () constant slot dm-compiler-model :: = #f, init-keyword: model-object:; constant slot local-dylan-location :: , init-keyword: location:; end class; ///// GET-LOCAL-VARIABLE-VALUE // An internal function. Callers must already have ensured that a // debugger transaction is in effect before calling this function. // Returns the corresponding to any lexical variable. define method get-local-variable-value (application :: , v :: ) => (val :: ) v.local-foreign-value end method; define method get-local-variable-value (application :: , v :: ) => (val :: ) let target = application.application-target-app; read-dylan-value(target, v.local-dylan-location) | $stale-remote-value end method; ///// ALL-FRAME-LOCAL-VARIABLES // An internal function. Callers must already have ensured that a // debugger transaction is in effect before calling this function. // Constructs objects for all of the // live variables in a stack frame. define method all-frame-local-variables (application :: , frame :: ) => (var-seq :: ) // This default method returns an empty sequence. If the frame is not // a call frame, then there are no local variables. #[] end method; define method all-frame-local-variables (application :: , frame :: ) => (var-seq :: ) let target = application.application-target-app; // We know that a debugger transaction is in effect. If this method is // being called, then the stack frame must be a foreign call frame. // We get a list of all live lexical variables from the DM, and // build a wrapper around each one. if (dylan-call-frame?(target, frame)) let (names, types, models, vals, locations) = active-dylan-lexical-variables(target, frame); let var-seq = make(, size: size(names)); for (i from 0 below size(names)) var-seq[i] := make(, name: names[i], location: locations[i], argument?: types[i] == #"function-argument", model-object: models[i]); ignore(var-seq[i].dm-compiler-model); end for; var-seq; else let (vars, vals) = live-frame-lexical-variables(target, frame); let var-seq = make(, size: size(vars)); for (i from 0 below size(vars)) var-seq[i] := make(, name: vars[i].lexical-variable-name, foreign-value: vals[i]) end for; var-seq; end if; end method; ///// COUNT-FRAME-LOCAL-VARIABLES // An internal function. Callers must already have ensured that a // debugger transaction is in effect before calling this function. // Returns an integer for the number of live lexical variables in a // stack frame. define method count-frame-local-variables (application :: , frame :: ) => (var-count :: ) // This default method returns an empty sequence. If the frame is not // a call frame, then there are no local variables. 0 end method; define method count-frame-local-variables (application :: , frame :: ) => (var-count :: ) let target = application.application-target-app; if (dylan-call-frame?(target, frame)) number-of-active-dylan-variables(target, frame); else number-of-lexical-variables(target, frame); end if; end method; ///// VARIABLE-VALUE (Environment Protocol Method) // Returns an environment object being the value of a local // variable. define method variable-value (application :: , variable :: , #key thread) => (value :: ); ignore(thread); let target = application.application-target-app; let val = #f; // Ensuring a debugger transaction, get the for the // local variable, and construct the right kind of environment object // for it. perform-debugger-transaction (target, method () ignore(variable.application-object-proxy.is-argument?); val := make-environment-object-for-runtime-value (application, get-local-variable-value (application, variable.application-object-proxy)); end method); val; end method;