No announcement yet.

Instance variables

  • Filter
  • Time
  • Show
Clear All
new posts

  • Instance variables

    I'm in one of those 'Can't see the wood for the trees' situations.

    I ported some asm over to a Class Method and the results were as if I hadn't ported anything.

    The following otherwise meaningless snippet best describes my problem.

    On the face of it, it seems that Instance Variables are not keen on asm but I feel sure they would be if I knew what I was doing.

    The first two asm lines are not doing what I thought they would do. Anothervariable remains at 123 instead of 999; which is what I'm after with this snippet.

    The assigning of local temporary variables in the monstrosity solves the problem but I cannot believe that's what I need to do otherwise a lot of asm work is going to get throttled.

    Just out of curiosity changing Anothervariable to 456 gave 456 as the outcome and that is local.

    I've been reading the Help file but it doesn't give much away and Googling Instance Variables leaves a lot to be desired. Slipping an analogy twix two gobbledygook statements seems to be a lost art.

    #Compile Exe
    #Dim All
    #Register None
    Class CAffair
      Instance Avariable, Anothervariable As Dword
      Class Method Create
        Avariable = 999
        Anothervariable = 123
      End Method
      Class Method AsmBit()
        ' These two lines have no effect on Anothervariable
        ! mov eax, Avariable
        ! mov Anothervariable, eax
        ' This monstrosity works ie Anothervariable becomes 999
    '    Local TAvariable,TAnothervariable As Dword
    '    TAvariable = Avariable
    '    ! mov eax, TAvariable
    '    ! mov TAnothervariable, eax
    '    Anothervariable = TAnothervariable
        ' Anothervariable becomes 456
    '    Anothervariable = 456
      End Method
      Interface IAffair
        Inherit IUnknown
        Method Test As Double
          Method = AnotherVariable
        End Method
      End Interface
    End Class
    Function PBMain
    Local Whatever As IAffair
    Let Whatever = Class "CAffair"
    Print Whatever.Test ' Should be Anothervariable
    End Function
    Last edited by David Roberts; 4 Sep 2008, 07:08 AM. Reason: Misspelling in a comment - be nice if Dim All checked them as well <grin>

  • #2

    I tried a few combinations and my conclusion is that this must be a bug. It seems that the variable AnotherVariable retains its value iow, the stack isn't updated with value coming from the asm instruction which should copy the value to AnotherVariable.

    What works is this

        Method Test As Long
    '      Method = Me.AsmBit
          Local AVariable As Dword
          Local AnotherVariable As DWord
        Avariable = 999
        Anothervariable = 123
          ! mov eax, Avariable
          ! mov Anothervariable, eax
          Method = AnotherVariable
        End Method
    So there is something going on with Instance variables and Class Methods combined or one or the other, I don't know.


    So here we are, this is the end.
    But all that dies, is born again.
    - From The Ashes (In This Moment)


    • #3
      Thanks Steven.

      Oh dear.

      The idea that I am working on will be getting information from the registry in 'Class Method Create'. Getting that information at any other time will involve some 'first pass' type code with wasted CPU time on the second and subsequent passes.

      I'd like a few more opinions before reporting a potential bug - I find that hard to believe given my decidedly beginning status with regard objects.


      • #4
        Daft thing is the following works

            ' These two lines have no effect on Anothervariable
        '    ! mov eax, Avariable
        '    ! mov Anothervariable, eax
            Local temp As Dword
            temp = Avariable
            Anothervariable = temp
        but what I have in mind has to be written in asm.


        • #5
          This one works too:

          CLASS METHOD AsmBit()
          LOCAL pDword1, pDword2 AS DWORD
          pDword1 = varptr(Avariable)
          pDword2 = varptr(Anothervariable)
          !  mov   eax,  pDword1
          !  mov   edx,  pDword2
          !  mov   eax,  [eax]
          !  mov   [edx],  eax
          END METHOD


          • #6
            Thanks Greg.

            Varptr had crossed my mind.

            This is where the trouble is:

            Local x,y As Dword Ptr
            x = VarPtr(Avariable)
            Print x;@x
            ! lea eax, Avariable
            ! mov y, eax
            Print y;@y
            I'm getting
            1419084 999
            4210740 0

            That's why Anothervariable isn't getting overwritten - another address is being clobbered. We're pushing our luck on a GPF here.

            I need one more person to have a look and if no joy then I'll put a bug report in.


            • #7
              I think that my monstrosity is the fastest so far, two Basic assignments and two 'simple' asm instructions.

              I'm getting more trouble now.

              Poke Long, eqp, rndl

              fails in an Interface Method where both eqp and rndl are Instance variables.

              If eqp is declared Locally and a local variable Trndl is assigned to rndl then I'm out of trouble. I should add that eqp declared locally failed and the solution was only got with the Trndl assignment.

              In other words the same 'trick' as my monstrosity.

              There is something very wrong here. How can rndl's address be causing trouble but Trndl gets the correct contents of rndl?


              • #8
                As a last resort I decided to read the manual - online that is.

                * 2^32.

                Most variables in a PowerBASIC module are visible to Inline Assembler code created with the ASM statement. You can reference LOCAL, STATIC, and GLOBAL variables by name by simply using the name as an operand of the assembler opcode. That isn't possible with INSTANCE and THREADED variables, as their access requires multiple operations best handled by higher level PowerBASIC code.
                My hard copy of PBWin 8 says yes for Threaded variables.

                Anyway, gentlemen, there it is.

                So, assign an Instance variable to a local variable, kick it around and assign it back unless someone comes up with a better idea.


                • #9
                  I could just knock myself on the head ... reading the manual sometimes can be very helpful. So, no bug whatsoever. It's by design !
                  So here we are, this is the end.
                  But all that dies, is born again.
                  - From The Ashes (In This Moment)