03 April 2009

Pointer and Gfa_Var object

I wasn't finished discussing the Pointer [To] data type. Maybe I should summarize the things I figured out until now:
  • GFA-BASIC 32 is capable of generating two types of code to access data; directly and indirectly using C-like pointer code.
  • A Pointer [To] type variable is 32-bits variable without a VarPtr address. The data memory address is set using Pointer=. Other than this, GFA-BASIC 32 treats the pointer as a normal data type.
  • All ByRef subroutine arguments are Pointer To variables, whose VarPtr-address is set by the caller (instruction that executes the subroutine).

Because of the duality, GFA-BASIC 32 needs to handle a Pointer To variable differently from normal variables. A normal variable has a name and memory location, in fact the variable-name is an alias for a data location. As such a variable name is not known after compiling, all references to the variable name are removed and replaced by assembler instruction theat memory loaction. Therefor a normal variable has only one 'address', either returned by VarPtr (V:) or ArrPtr. A Pointer (32-bits wide) on the other hand is split in two separate units. The address the pointer is stored and the VarPtr address it is pointing to. A Pointer variable has two addresses. This is refelected in the Gfa_Var object. A Gfa_Var object is an item of Gfa_Vars collection, a collection of variables of a certain subroutine. The Gfa_Var has two properties that illustrate this concept:

Gfa_Var.VarPtr Gfa_Var.Addr

In case of a normal variable both properties return the VarPtr address, In case of a pointer the .Addr property returns the address of the Pointer variable and the .VarPtr property the address set using Pointer()=. To help investigate I wrote a small procedure to show the Gfa_Var properties in the Debug Output window. A call to ShowVar is done by including a copy of a Gfa_Vars collection item. In case of the example below, I inspected a global user-defined-type declared as Foo. To obtain a collection of global variables you either use Gfa_Globals or Gfa_Vars(""). To inspect a local variable, execute ShowVar from inside a procedure and use Gfa_Vars0!varname.

ShowVar Gfa_Vars("")!Foo, V:foo, ArrPtr(foo), _
 "- Global Foo As Tfoo:"

Proc ShowVar(vGfaVar As Gfa_Var, vp%, ap%, comment$)
  Debug comment$

  Debug "Variable: "#39 & vGfaVar.Name & #39 & _
    ", TypeName: "#39 & vGfaVar.TypeName & #39 & _
    ", Sub: "#39 & vGfaVar.PName & #39
  Trace Hex(vGfaVar.Type)
  Trace vGfaVar.Addr
  Debug "ArrPtr(" & vGfaVar.Name & ") = " ap
  Debug "VarPtr(" & vGfaVar.Name & ") = " vp
  Trace vGfaVar.VarPtr
  Trace vGfaVar.Size
  Trace vGfaVar.Len
  Trace vGfaVar.IsTyped
  Debug
EndProc

3 comments:

  1. Anonymous6/4/09

    Silly question: How to get the prog started? The first line already gives various error messages.

    By the way, variables are not declared.

    Kindly regards ys geko

    ReplyDelete
  2. Hi Gerd,

    It won't run, you are correct. The foo variable and the TFoo user-defined type aren't declared. Insert the following code above these lines and it will work:

    Debug.Show
    Type Tfoo
    d As Double
    EndType
    Global foo As Tfoo

    ReplyDelete
  3. Anonymous7/4/09

    Thank you Sjouke, now it works. With foo I'm at daggers drawn.

    Regards geko

    ReplyDelete