Paste: claude crap basis/

Author: erg
Mode: factor
Date: Fri, 25 Jul 2025 00:33:51
Plain Text |
c9f4313b-2bf9-4c70-8fc7-1764c36ab4e1% cat basis-out
diff --git a/basis/bootstrap/assembler/arm.64.factor b/basis/bootstrap/assembler/arm.64.factor
index f9d04f842e..85ea149a9d 100644
--- a/basis/bootstrap/assembler/arm.64.factor
+++ b/basis/bootstrap/assembler/arm.64.factor
@@ -199,7 +199,7 @@ big-endian off
     X10 X11 SP 16 [post] LDP
     X8 X9 SP 16 [post] LDP
     X6 X7 SP 16 [post] LDP
-    X4 X6 SP 16 [post] LDP
+    X4 X5 SP 16 [post] LDP
     X2 X3 SP 16 [post] LDP
     X0 X1 SP 16 [post] LDP ;

@@ -349,7 +349,7 @@ big-endian off

 [
     ! class = ...
-    type obj tag-bits get dup UBFIZ
+    type obj tag-bits get UBFIZ
     type tuple type-number tag-fixnum CMP
     [ BNE ] [
         type obj tuple-class-offset [+] LDR
@@ -588,7 +588,7 @@ big-endian off

     { drop-locals [
         ds-0 DS -8 [post] LDR
-        RS dup ds-0 tag-bits get 3 - <ASR> SUB
+        RS dup ds-0 tag-bits get 3 - ASR SUB
     ] }
     { get-local [
         ds-0 DS [] LDR
@@ -607,14 +607,14 @@ big-endian off
     ] }
     { string-nth-fast [
         ds-1 ds-0 DS -8 [pre] LDP
-        ds-0 dup ds-1 tag-bits get <ASR> ADD
+        ds-0 dup ds-1 tag-bits get ASR ADD
         ds-0 dup string-offset [+] LDRB
         ds-0 dup tag-bits get LSL
         ds-0 DS [] STR
     ] }
     { tag [
         ds-0 DS [] LDR
-        ds-0 dup tag-bits get dup UBFIZ
+        ds-0 dup tag-bits get UBFIZ
         ds-0 DS [] STR
     ] }

diff --git a/basis/bootstrap/compiler/compiler.factor b/basis/bootstrap/compiler/compiler.factor
index e892d2216a..804b72a593 100644
--- a/basis/bootstrap/compiler/compiler.factor
+++ b/basis/bootstrap/compiler/compiler.factor
@@ -61,6 +61,7 @@ gc

         layout-of
     } compile-unoptimized
+    "omg1" write flush

     "." write flush

@@ -68,24 +69,28 @@ gc
         bitand bitor bitxor bitnot
     } compile-unoptimized

+    "omg2" write flush
     "." write flush

     {
         + * 2/ < <= > >= shift
     } compile-unoptimized

+    "omg3" write flush
     "." write flush

     {
         new-sequence nth push pop last flip
     } compile-unoptimized

+    "omg4" write flush
     "." write flush

     {
         hashcode* = equal? assoc-stack assoc-stack-from get set
     } compile-unoptimized

+    "omg5" write flush
     "." write flush

     {
@@ -94,6 +99,7 @@ gc
         like clone-like
     } compile-unoptimized

+    "omg6" write flush
     "." write flush

     {
@@ -101,6 +107,7 @@ gc
         word-prop set-word-prop 1array 2array 3array ?nth
     } compile-unoptimized

+    "omg7" write flush
     "." write flush

     os windows? [
@@ -118,13 +125,16 @@ gc
         malloc calloc free memcpy
     } compile-unoptimized

+    "omg8" write flush
     "." write flush

     loaded-vocab-names [ vocab-words compile-unoptimized "." write flush ] each

+    "omg9" write flush
     " done" print flush

     "alien.syntax" require
     "io.streams.byte-array.fast" require

+    "omg10" write flush
 ] unless
diff --git a/basis/cpu/arm/64/assembler/assembler.factor b/basis/cpu/arm/64/assembler/assembler.factor
index 8441d245b7..baf93cba6f 100644
--- a/basis/cpu/arm/64/assembler/assembler.factor
+++ b/basis/cpu/arm/64/assembler/assembler.factor
@@ -31,7 +31,7 @@ TUPLE: stack-register < general-register ;
 TUPLE: vector-register < register ;
 32 <iota> [
     [ [ "V" % # ] "" make create-word-in ]
-    [ 64 vector-register boa define-constant ] bi
+    [ 128 vector-register boa define-constant ] bi
 ] each

 TUPLE: fp-register < register ;
@@ -420,7 +420,7 @@ MACRO: encode ( bitspec -- quot ) '[ _ bitfield* 4 >le % ] ;
     } encode ;

 : ADR  ( Xd imm -- )        0 (ADR) ;
-: ADRP ( Xd imm -- ) 12 ?>> 1 (ADR) ;
+: ADRP ( Xd imm -- ) 12 align -12 shift 1 (ADR) ;


 : unsigned-immediate? ( n bits -- ? ) dupd bits = ;
@@ -553,22 +553,22 @@ ERROR: immediate-error n ;
 :: UBFIZ ( Rd Rn lsb width -- )
     Rn encode-width 5 + :> max-width
     lsb max-width check-unsigned-immediate drop
-    width dup 1 max-width 2^ lsb - between? [ immediate-error ] unless drop
+    lsb width + max-width 2^ <= [ immediate-error ] unless
     Rd Rn lsb neg max-width bits width 1 - UBFM ;

 M:: integer LSL ( Rd Rn shift -- )
     Rn encode-width 5 + :> max-width
-    shift max-width check-unsigned-immediate drop
+    shift max-width 1 - check-unsigned-immediate drop
     Rd Rn shift bitnot max-width bits [ 1 + ] keep UBFM ;

 M:: integer LSR ( Rd Rn shift -- )
     Rn encode-width 5 + :> max-width
-    shift max-width check-unsigned-immediate drop
+    shift max-width 1 - check-unsigned-immediate drop
     Rd Rn shift max-width on-bits UBFM ;

 M:: integer ASR ( Rd Rn shift -- )
     Rn encode-width 5 + :> max-width
-    shift max-width check-unsigned-immediate drop
+    shift max-width 1 - check-unsigned-immediate drop
     Rd Rn shift max-width on-bits SBFM ;


c9f4313b-2bf9-4c70-8fc7-1764c36ab4e1%

Annotation: gemini audit of basis/bootstrap/assembler/arm.64.factor

Author: erg
Mode: factor
Date: Fri, 25 Jul 2025 00:41:05
Plain Text |
Based on a static analysis of the provided ARM64 assembly code for the Factor bootstrap, here are several sections that appear to contain obvious or highly probable bugs.

It's important to preface this by saying that without the full context of the Factor Virtual Machine, some of these might be intentional due to a convention not visible in this file. However, based on standard practices for JIT compilers and tagged integer representations, these are significant red flags.

1. Critical Bug: Incorrect Multiplication Logic

Both the fast and slow versions of fixnum* have what appears to be the same critical bug.

In fixnum*fast:

Generated factor
[
    ds-1 ds-0 DS -8 [pre] LDP
    ds-0 dup tag-bits get ASR   ! Untags ds-0 (one of the numbers)
    ds-0 dup ds-1 MUL            ! Multiplies untagged ds-0 by TAGGED ds-1
    ds-0 DS [] STR
]


The Bug: The code untags one of the operands (ds-0) by shifting it right, but it then multiplies this untagged integer by the original, still tagged second operand (ds-1).

Why it's wrong: Multiplying (number_A) by (number_B << 3) + tag will produce a completely incorrect mathematical result. The tag bits of ds-1 will be treated as part of its numerical value during the multiplication.

The Fix: The second operand (ds-1) must also be untagged before the MUL instruction. The result would then need to be re-tagged.

In fixnum* (slower, with overflow check):

Generated factor
[
    arg1 arg2 DS -8 [pre] LDP
    jit-save-context
    arg1 dup tag-bits get ASR   ! Untags arg1
    ds-0 arg1 arg2 MUL           ! Multiplies untagged arg1 by TAGGED arg2
    ...
]
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Factor
IGNORE_WHEN_COPYING_END

The Bug: This is the exact same logical flaw as in the fast version. It multiplies an untagged value (arg1) with a tagged value (arg2). The subsequent overflow check is therefore also operating on incorrect data.

2. Critical Bug: Incorrect Shift Logic

In fixnum-shift-fast:

Generated factor
[
    ds-1 ds-0 DS -8 [pre] LDP
    ds-0 dup tag-bits get ASR      ! Untags the shift amount (ds-0)
    ! compute positive shift value in temp1
    temp1 ds-1 ds-0 LSL            ! Shifts TAGGED value ds-1
    ! compute negative shift value in temp2
    ds-0 dup NEGS
    temp2 ds-1 ds-0 ASR            ! Shifts TAGGED value ds-1
    ...
]
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Factor
IGNORE_WHEN_COPYING_END

The Bug: The code correctly untags the shift amount (ds-0). However, it then proceeds to apply the shift (LSL or ASR) directly to the tagged integer value (ds-1).

Why it's wrong: Shifting a tagged pointer is incorrect. For example, a left shift will move the most significant bits of the number into the tag bits, corrupting the value and its type information.

The Fix: The value to be shifted (ds-1) must be untagged before the shift operation, and the result must be re-tagged before being pushed back to the stack.

3. Critical Bug: Flawed Address Calculation

In string-nth-fast:

Generated factor
[
    ds-1 ds-0 DS -8 [pre] LDP
    ds-0 dup ds-1 tag-bits get <ASR> ADD  ! Incorrect calculation
    ds-0 dup string-offset [+] LDRB      ! Loads from a likely wrong address
    ds-0 dup tag-bits get LSL
    ds-0 DS [] STR
]```
*   **The Bug:** This code is meant to get the n-th character of a string. `ds-1` is the string object pointer and `ds-0` is the integer index. The line `ds-0 dup ds-1 tag-bits get <ASR> ADD` performs the calculation `index = index + (string_pointer >> tag_bits)`.
*   **Why it's wrong:** This calculation corrupts the index by adding a shifted version of the string's base address to it. The correct logic to find the address of the character should be `address = string_base_pointer + string_data_offset + (index >> tag_bits)`. The instruction shown mixes the operands in a way that makes no sense for address calculation.
*   **The Fix:** The calculation needs to be completely rewritten to correctly compute the target address using the string base pointer, the untagged index, and the offset to the character data within the string object.

### 4. Suspicious Code: Conditional Branch Logic

**In `JIT-IF`:**
```factor
[
    ds-0 DS -8 [post] LDR
    ds-0 \ f type-number CMP       ! Compares the value with 'false'
    ! skip over true branch if equal
    [ BEQ ] [
        ! jump to true branch
        LDR=BR rel-word
    ] jit-conditional*
    ! jump to false branch
    LDR=BR rel-word
]
IGNORE_WHEN_COPYING_START
content_copy
download
Use code with caution.
Factor
IGNORE_WHEN_COPYING_END

The Issue: The comments and the code logic appear to contradict each other.

The code compares the popped value with f (Factor's canonical false object).

The BEQ condition means the branch is taken if the value is false.

The comment says ! jump to true branch.

If the value is false (BEQ is true), the code should execute the "false" branch of the if-statement. The code as written appears to jump to the "true" branch when the condition is false. This seems logically inverted. While this could be a quirk of how jit-conditional* is implemented, it's highly suspect and goes against the principle of least surprise.

Conclusion

The code contains several critical, show-stopping bugs in its core arithmetic and memory access primitives (fixnum*, fixnum-shift-fast, string-nth-fast). These bugs would lead to incorrect calculations and memory corruption, causing the program to crash or produce garbage results. The logic in JIT-IF is also highly questionable.

This code requires significant debugging and correction before it could function properly. The issues identified are not subtle edge cases but fundamental flaws in the implementation of these common operations.

New Annotation

Summary:
Author:
Mode:
Body: