Fix EXPT type contagion, MAP result-type dispatch on OR, and TRACE of…#747
Open
blakemcbride wants to merge 1 commit intoarmedbear:masterfrom
Open
Fix EXPT type contagion, MAP result-type dispatch on OR, and TRACE of…#747blakemcbride wants to merge 1 commit intoarmedbear:masterfrom
blakemcbride wants to merge 1 commit intoarmedbear:masterfrom
Conversation
Author
|
With this final patch, ABCL passes the entire ANSI conformance suite. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fix EXPT type contagion, MAP result-type dispatch on OR, and TRACE of (SETF name)
Summary
Repairs three unrelated ANSI conformance failures:
EXPT.29MAP.48MAKE-SEQUENCEwith anORof vector typesTRACE.8(SETF foo)calls bypassed the trace wrapperEach test passes and no previously-passing test regresses.
Root causes and fixes
1.
EXPT.29—(expt 0 y)ignored the type ofyMathFunctions.EXPThandled a zero base with a barereturn base;:That returned the exact base object, which meant
(expt 0 2.0f0)producedthe integer
0rather than the single-float0.0f0. The ANSI test walks(x, y)over zero bases (0,0.0f0,0.0d0, various complex zeros) andnon-zero powers and requires
(eql (* x y) (expt x y)). The old behaviorviolated that for every case where
ywas a float or complex-float.Fix (
MathFunctions.java): Delegate to the existing multiplicationcontagion machinery.
base.multiplyBy(power)produces zero of the correct contagious type(single-float, double-float, complex single, complex double, etc.) — the
same value the test expects from
(* x y).2.
MAP.48—(make-sequence '(or ...) size)errored unconditionallyMAPdefers toMAKE-SEQUENCEfor the result-type.MAKE-SEQUENCErejected any compound type whose operator was not one of the known
vector/array names and signalled
"(OR ...) is not a sequence type."— even when the branches of the
ORall shared a single element type.MAP.48's result type is(or (vector t 10) (vector t 5)); bothbranches have element type
t, and one of them ((vector t 5)) matchesthe input length of 5. CLHS 17.3 says the element type of the result
array is determined by the type specifier when the implementation can
determine it, so this case is legal and well-defined.
The opposite case matters too:
MAP.ERROR.10,MAKE-SEQUENCE.ERROR.15,COERCE.ERROR.10, andCONCATENATE.ERROR.6all pass anORwhosebranches have conflicting element types (e.g.
(or (vector bit) (vector t))) and require an error. So the fix must accept unambiguousORtypes and reject ambiguous ones.Fix (
make-sequence.lisp): Before the existing type dispatch, peeloff an
ORby extracting each branch's element type. If all branchesagree, iterate over the branches and return the first one that
MAKE-SEQUENCEcan satisfy at the requested size. If the element typesconflict (or any branch is not a recognized vector type), signal the
existing
simple-type-error:%vector-type-element-typerecognizes the standard vector-shaped typespecifiers (
VECTOR,SIMPLE-VECTOR,(VECTOR et),STRING,BIT-VECTOR,ARRAY, etc.) and returns the declared element type or:UNKNOWN.3.
TRACE.8— compiled(SETF foo)bypassed the trace wrapper(trace (setf foo))installs a wrapper by replacing(fdefinition '(setf foo)). A compiled caller only sees that wrapper ifthe call site resolves through the symbol's setf-function slot at
runtime. For ordinary symbols, compiled
(foo …)calls go throughSymbol.execute, which dispatches to the current fdefinition, sotraced regular functions emit output correctly (TRACE.1–TRACE.7).
For
(setf foo)the name is a two-element list.p2-functionincompiler-pass2.lisphandles this with:The third clause (flagged with a pre-existing
FIXME Need to check for NOTINLINE declaration!comment) fires whenever(compile 'f)isinvoked on a function that references
#'(setf foo), including thecompile*call rt.lsp makes when*compile-tests* = T. The branchbakes the current
fdefinitioninto the generated class as a staticfield — so the wrapper installed by
TRACElater is never called.Fix (
compiler-pass2.lisp): Add the missingnotinline-pguard sothe compiled form falls through to the final clause, which loads the
symbol and calls
getSymbolSetfFunctionOrDie()(a runtime lookup):TRACE.8's test file declares
(declaim (notinline function-to-trace (setf function-to-trace)))atthe top, so the user's explicit
NOTINLINEnow propagates into thegenerated bytecode. This mirrors how the regular-symbol branch already
routes notinline calls through
Symbol.executerather than caching thefunction object.
Files changed
src/org/armedbear/lisp/MathFunctions.javasrc/org/armedbear/lisp/make-sequence.lispsrc/org/armedbear/lisp/compiler-pass2.lispTest plan
ant abclbuilds cleanly.ant test.ansi.compiled:EXPT.29,MAP.48, andTRACE.8leave the failure list. The OR-type error tests
(
COERCE.ERROR.10,CONCATENATE.ERROR.6,MAKE-SEQUENCE.ERROR.15,MAP.ERROR.10) continue to pass — they were first regressed by anearlier, over-permissive
MAKE-SEQUENCEchange and required theelement-type-coherence check described above.
-
(expt 0 2.0f0)→0.0f0;(expt 0 #C(2.0 0.5))→#C(0.0 0.0).-
(map '(or (vector t 10) (vector t 5)) #'identity '(1 2 3 4 5))→
#(1 2 3 4 5).-
(map '(or (vector bit) (vector t)) #'identity '(1 0 1))signalssimple-type-error.- After
(compile 'f)wherefdoes(setf (traced-setf-name x) v), the compiledfhonours(trace (setf traced-setf-name)).Compatibility
EXPTnow returns a float/complex zero rather than an integer zerowhen the base is zero and the power has a float/complex type. This
matches CLHS 12.1 type-contagion rules and what
(* 0 y)alreadyproduced.
MAKE-SEQUENCEnow accepts(or T1 T2 …)when all branches share asingle element type. Ambiguous
ORresult types (conflicting elementtypes or unrecognized branches) continue to signal
simple-type-error.(SETF foo)calls in code compiled withCOMPILE(notCOMPILE-FILE)now honour
(declaim (notinline (SETF foo))). Code that declaredNOTINLINEalready intended runtime dispatch, so no caller shouldneed to change.