Author Topic: Difference between x32 and x64  (Read 2084 times)

0 Members and 1 Guest are viewing this topic.

Brian Alvarez

  • Guest
Difference between x32 and x64
« on: November 19, 2018, 11:47:28 AM »
 IM trying to create the REPLACE feature in oxygen, i have this function:

Code: [Select]
// replaces parts of a string with specified replacements.
SUB REPLACE(boolean a, string ocu, string rep, string trg)

if len(rep) = 0 then
    exit function
end if

int r, i

if a then ' ANY
    if len(ocu) <> len(rep) then
        trg = ""
        exit sub
    end if
    byte bocu at strptr(ocu)
    byte brep at strptr(rep)
    byte btrg at strptr(trg)
    for r = 1 to len(ocu)
        if len(rep) < r then exit for       
        for i = 1 to len(trg)       
            if bocu[r] = btrg[i] then
                btrg[i] = brep[r]                     
            end if
        next i
    next r
else  ' by word (Code by Charles)

    do
        i = instr(i+1, trg, ocu)
        if i then
            trg = left(trg, i-1) + rep + mid(trg, i + len(rep))
        else
            exit do 
        end if
        i = len(rep) + i - 1
    loop
end if

END SUB

The function compiles (it doesnt work yet) but crashes on 64 bit mode, but in 32 bit mode it doesnt compile, it says:

Code: [Select]
ERROR: Must not assign to a direct string param
 Its the exact same code for invocation in both modes:

Code: [Select]
FUNCTION PBMAIN() AS LONG
   STRING st
   st = "Hello Mom"
   Replace(0, "Mom", "World", st)
   print st
END FUNCTION

Thanks!
« Last Edit: November 19, 2018, 12:58:58 PM by Brian Alvarez »

Brian Alvarez

  • Guest
Re: Difference between x32 and x64
« Reply #1 on: November 19, 2018, 12:59:56 PM »

Adding the byref switch to the target string parameter fixed it:
I thought that since byval is not yet supported, BYREF was instrinsic.

Code: [Select]
// replaces parts of a string with specified replacements.
SUB REPLACE(boolean a, string ocu, string rep, byref string trg)

if len(rep) = 0 then
    exit function
end if

int r, i

if a then ' ANY
    if len(ocu) <> len(rep) then
        trg = ""
        exit sub
    end if
    byte bocu at strptr(ocu)
    byte brep at strptr(rep)
    byte btrg at strptr(trg)
    for r = 1 to len(ocu)
        if len(rep) < r then exit for       
        for i = 1 to len(trg)       
            if bocu[r] = btrg[i] then
                btrg[i] = brep[r]                     
            end if
        next i
    next r
else  ' by word (Code by Charles)

    do
        i = instr(i+1, trg, ocu)
        if i then
            trg = left(trg, i-1) + rep + mid(trg, i + len(rep))
        else
            exit do 
        end if
        i = len(rep) + i - 1
    loop
end if

END SUB

Charles Pegge

  • Guest
Re: Difference between x32 and x64
« Reply #2 on: November 19, 2018, 07:46:08 PM »
Hi Brian,

It could also be:

SUB REPLACE(bool a, string ocu, string rep, string ptr trg)

ptr / byref / * are alternatives


Or the compacted form:

SUB REPLACE(bool a, string ocu, rep, *trg)


Brian Alvarez

  • Guest
Re: Difference between x32 and x64
« Reply #3 on: November 26, 2018, 04:43:26 PM »
Since this is also a problem between 32 bit and 64 bit, im going to post it here instead of opening a new thread...
feel free to move it to it's own thread if it is worthy of such promotion.

 The following is code that PluriBASIC generates. When using rtl32, it works fine,
but when using rtl64, the app crashes when sending the string pointer as a parameter for
"BYREFPAR". Somehow the engine does not like the pointer. Maybe i am sending a pointer not big enough to
hold the 64bit string address.

 Please ignore the fact that the class is not freeing strings properly. I simplified the generated code by hand
to make it easier to follow.

 What can i be doing wrong?
 

Code: [Select]
'Generated with PluriBASIC 6.0.74371.0

$ filename "array_system.exe"

uses rtl64

Declare Function PluriBASICMessageBox  Lib "user32.dll" Alias "MessageBoxA"

FUNCTION MSGBOX(string sText, sys mOptions = 0, string sCaption = "PluriBASIC") AS LONG
   FUNCTION = PluriBASICMessageBox(null, sText, sCaption, mOptions)
END FUNCTION

#def __dim1 (d1-bnd[1])
#def __dim2 (d2-bnd[3])
#def __dim3 (d3-bnd[5])

#def __class_nam_def class _arr_%1

macro __declare_array_type(dtype)
__class_nam_def(dtype)

    int dims      ' Number of dimensions
    int elems     ' Number of elements.
    int slength   ' length of strings.
    int ispointer ' is pointer flag.
    sys hBuffer   ' Address of the buffer
    sys hCustAddr ' Address provided by the inline code.
    int BuffLen   ' length of the buffer in bytes
    int bnd[10]   ' bounds.   
 
    function redim(int p, int * d, n)
        int i
        elems = 0
        for i = 1 to n step 2
            bnd[i+0] = d[i+0]
            bnd[i+1] = d[i+1]
            elems   += (d[i+1]-d[i+0])
        next
        int nBufLen = (elems * sizeof(sys)) + 32
        sys nBuffer = getmemory(nBufLen)
        int eBfCopy = BuffLen
        if BuffLen
          if BuffLen>nBufLen then
              eBfCopy = nBufLen
          end if
          copy nBufLen, BuffLen, eBfCopy
          freememory hBuffer
        endif
        hBuffer = nBuffer
        BuffLen = nBufLen       
    end function 
 
    method constructor(int * d, n, isptr, slen, sys hAddr)
        ispointer = isptr
        slength   = slen
        hCustAddr = hAddr
        dims = n / 2
        this.redim(0, d, n)
    end method
   
    function destructor()
        freememory(hBuffer)
        hBuffer = 0
        BuffLen = 0
    end function
   
    '======================================================================
    function c(int d1, d2, d3, dtype v)
        dtype dt at (hBuffer + 32)
        dt(__dim1 * __dim2 + __dim3) = v
    end function

     function c(int d1, d2, d3) as dtype
        dtype dt at (hBuffer + 32)
        return dt(__dim1 * __dim2 + __dim3)
    end function
    '======================================================================
    function p(int d1, d2, d3) as dtype*
        dtype dt at (hBuffer + 32)
        return @dt(__dim1 * __dim2 + __dim3)
    end function
 
end class

end macro

__declare_array_type(bstring)

SUB BYREFPAR(BYREF ss AS STRING, BYVAL _ByValue_s2 AS STRING)
   STRING s2 = _ByValue_s2
   ss = "Changed in the SUB"
   s2 = "Changed in the SUB"
END SUB

FUNCTION PBMAIN() AS INT
   new _arr_bstring sss(int{-10, 100, 0, 100, 0, 100}, countof, 0, 0, 0)
   sss.c(5,5,5) = "Original contents 1"
   sss.c(5,5,6) = "Original contents 2"
   BYREFPAR(sss.p(5,5,5), sss.c(5,5,6))
   MSGBOX(sss.c(5,5,5), 0, sss.c(5,5,6)) ' should display one modified and one unmodified.
END FUNCTION

PBMAIN() ' invoke entry point

Brian Alvarez

  • Guest
Re: Difference between x32 and x64
« Reply #4 on: November 26, 2018, 06:26:27 PM »
By casting the address to a sys it doesnt crash:

Code: [Select]
BYREFPAR(cast(sys) sss.p(5,5,5), sss.c(5,5,6))
 But the "variable" remains "byval".

Maybe it is somewhere converting it to an int or something,
it should be an easy internal fix, right? :)

Brian Alvarez

  • Guest
Re: Difference between x32 and x64
« Reply #5 on: November 26, 2018, 10:39:41 PM »
 The 64bit address being passed differs from the address that @ss is displaying.

 For the 32bit mode, the address is correct.

Charles Pegge

  • Guest
Re: Difference between x32 and x64
« Reply #6 on: November 26, 2018, 10:43:15 PM »
Brian.

I see one problem:

copy nBufLen, BuffLen, eBfCopy

copy is a low-level procedure and its prototype is

copy(DestAddress, SourceAddress, ByteCount)

Brian Alvarez

  • Guest
Re: Difference between x32 and x64
« Reply #7 on: November 26, 2018, 11:30:21 PM »
Hello charles :)

 That is a direct copy of the source code you kindly provided me, only the variable names have changed.

https://www.oxygenbasic.org/forum/index.php?topic=1811.msg19715#msg19715

Did you see the other problem i was talking about?
« Last Edit: November 27, 2018, 12:23:10 AM by Brian Alvarez »

Charles Pegge

  • Guest
Re: Difference between x32 and x64
« Reply #8 on: November 27, 2018, 04:48:32 AM »
Well, tell the author to check his code more diligently.  :)
I'm surprised it worked at all.

I think this is the only mod required:

 copy nBuffer, hBuffer, eBfCopy

Brian Alvarez

  • Guest
Re: Difference between x32 and x64
« Reply #9 on: November 27, 2018, 11:53:16 AM »

 Thanks Charles, i made the change. The 64 bit Pointer problem still remains. :)