Module: dfmc-c-back-end Author: Jonathan Bachrach, 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 constant $initial-string-stream-contents-size = 10000; define class () constant slot lambda-stream = make(, direction: #"output", contents: make(, size: $initial-string-stream-contents-size)); end; register-back-end(, #"c", #f, #f); define method initialize (back-end :: , #key, #all-keys) => () next-method(); stream-contents(back-end.lambda-stream, clear-contents?: #t); end method; define method back-end-record-repeated-object-sizes? (back-end :: ) => (well? :: ) #t end method; define constant $xep-string = "xep"; define constant $rest-xep-string = "rest_xep"; define constant $rest-key-xep-string = "rest_key_xep"; define constant $gf-xep-string = "gf_xep"; define constant $key-mep-string = "key_mep"; define constant $gf-optional-xep-string = "gf_optional_xep"; define constant $dylan-type-string = "D"; define constant $initialize-closure-string = "INIT_CLOSURE"; define constant $make-closure-string = "MAKE_CLOSURE"; define constant $make-closure-with-signature-string = "MAKE_CLOSURE_SIG"; define constant $make-closure-initd-string = "MAKE_CLOSURE_INITD"; define constant $make-closure-initd-with-signature-string = "MAKE_CLOSURE_INITD_SIG"; define constant $make-method-with-signature-string = "MAKE_METHOD_SIG"; define constant $set-method-signature-string = "SET_METHOD_SIG"; define constant $initialize-keyword-closure-string = "INIT_KEYWORD_CLOSURE"; define constant $make-keyword-closure-string = "MAKE_KEYWORD_CLOSURE"; define constant $make-keyword-closure-with-signature-string = "MAKE_KEYWORD_CLOSURE_SIG"; define constant $make-keyword-closure-initd-string = "MAKE_KEYWORD_CLOSURE_INITD"; define constant $make-keyword-closure-initd-with-signature-string = "MAKE_KEYWORD_CLOSURE_INITD_SIG"; define constant $make-keyword-method-with-signature-string = "MAKE_KEYWORD_METHOD_SIG"; define constant $set-keyword-method-signature-string = "SET_KEYWORD_METHOD_SIG"; // define constant $box-string // = "BOX"; define constant $closure-reference-string = "CREF"; define constant $method-reference-string = "MREF"; define constant $function-register-string = c-local-mangle("%function"); // define constant $next-methods-register-string // = c-local-mangle("%next-methods"); define constant $capture-environment-string = "CAPTURE_ENVIRONMENT"; define constant $capture-keyword-environment-string = "CAPTURE_KEYWORD_ENVIRONMENT"; // define constant $closure-string // = "CLOSURE"; // define constant $true-string // = "DTRUE"; // define constant $false-string // = "DFALSE"; define class () constant slot ref-temp :: , required-init-keyword: ref-temp:; constant slot ref-index :: = 0, init-keyword: ref-index:; constant slot lhs? :: = #f, init-keyword: lhs?:; end class; define method mv-temp-ref(tmp :: , i :: ) make(, ref-temp: tmp, ref-index: i) end method; define method mv-temp-ref(tmp , i :: ) tmp; end method; define method mv-temp-lhs(tmp :: , i :: ) make(, ref-temp: tmp, ref-index: i, lhs?: #t) end method; define method mv-temp-lhs(tmp, i :: ) tmp; end method; define class () constant slot addr-temporary, required-init-keyword: temporary:; end class; define method make-address-of(o) make(, temporary: o); end method; define method emit-reference (b :: , s :: , o :: ) => () format(s, "&"); emit-reference(b, s, o.addr-temporary); end method; define method back-end-word-size (object :: ) => (size :: ) if (current-processor-name() == #"alpha") 8 else 4 end; end method; define function format-emit (b :: , s :: , d :: , format-string :: , #rest arguments) let i :: = 0; for (c in format-string) select (c) '~' => print-message(arguments[i], s); i := i + 1; '%' => emit-object(b, s, arguments[i]); i := i + 1; '@' => emit-reference(b, s, arguments[i]); i := i + 1; '?' => emit-indirect-reference(b, s, arguments[i]); i := i + 1; '^' => emit-name(b, s, arguments[i]); i := i + 1; '#' => if (arg-used?(arguments[i])) format-emit*(b, s, "@ = ", arguments[i]); end if; i := i + 1; '\t' => for (i from 0 below d) write(s, " "); end; otherwise => write-element(s, c); end select; end for; end function; define method arg-used?(o :: ) (o ~== #f) & o.ref-temp.used? end method; define method arg-used?(o) (o ~== #f) & o.used? end method; define inline function format-emit* (b :: , s :: , format-string :: , #rest arguments) apply(format-emit, b, s, 1, format-string, arguments) end function; //// TOP-LEVEL define method emit-all (back-end :: , cr :: , #rest flags, #key dfm-output? = #f, #all-keys) with-simple-abort-retry-restart ("Abort the emission phase", "Restart the emission phase") /* // Hack!!! Displaced. register-object(unit, unit.top-level-lambda); // Some references are inserted by the back-end itself. These are they: register-object(unit, &false); register-object(unit, &true); // Descend the roots locating all internal and external objects. trace-objects(unit); */ let heap = cr.compilation-record-model-heap; let literals = heap.heap-defined-object-sequence; when (dfm-output?) with-build-area-output (stream = current-library-description(), name: concatenate(cr.compilation-record-name, ".dfm")) for (literal in literals) apply(emit-dfm, back-end, stream, literal, flags); end for; end with-build-area-output; end when; for (literal in literals) emit-code(back-end, literal); end for; with-labeling-from-dynamic for (code in heap.heap-root-system-init-code, count from 0) emit-init-code(back-end, code.^iep); end for; for (code in heap.heap-root-init-code, count from 0) emit-init-code(back-end, code.^iep); end for; end; retract-local-methods-in-heap(heap); end; end method; // Must retract local methods only after code generation of compilation-record define method retract-local-methods-in-heap(heap) => () if (*retract-dfm?*) for (literal in heap.heap-defined-object-sequence) if (instance?(literal, <&iep>) & ~lambda-top-level?(literal)) // format-out?("\nRETRACTING %=\n", literal); retract-method-dfm(literal); retract-method-dfm(literal.function); end if; end for; end if; end method; define method emit-dfm (back-end :: , stream :: , o :: <&iep>, #rest flags, #key form?, force-emit?, #all-keys) => () print-method(stream, o.function); format(stream, "\n"); end method emit-dfm; define method emit-dfm (back-end :: , stream :: , o, #rest flags, #key, #all-keys) => () end method emit-dfm; // eof