-------------------------------------------------------------------------------------------
                      [ENHANCED] VFP 9.0 FIX - THE VARIABLE BEHAVIOR FOR THE VARIABLE NAME WITHOUT MDOT
                               January 2024
                 -------------------------------------------------------------------------------------------
                                     CCB



1. BUG:

     In vfp9 (and vfp6, vfp7, vfp8), when we run the code:
     x2=x1
     it will run slower than the code:
     x2=m.x1

     The bug was reported by Mike Yearwood.


2. CAUSE:

     In vfp9 (and vfp6, vfp7, vfp8), when we run the code:
     x2=x1
     vfp will check the field x1 first, if there is the field x1 in the current work area, it will store the field x1 to the variable x2,
     if there is no the field x1 in the current work area, it will store the variable x1 to the variable x2.
     So it will run slower.

     In Visual FoxPro Advanced, if we set SYS(9062,0), when we run the code:
     x2=x1
     vfp will not check the field x1, it will check the variable x1 only, it will store the variable x1 to the variable x2.
     So it will run faster.
     But for some code, for example,
     REPLACE fld2 WITH fld1
     it will cause an error, because there is no the variable fld1.


3. RESOLUTION:

     We can write some code to fix the BUG.

     Fun421386 :: ; proc near
             push ebp                                                        ;0x00421386 :        55
             mov ebp , esp                                                   ;0x00421387 :        8bec
             sub esp , 064h                                                  ;0x00421389 :        83ec64
             mov  ecx , dword ptr [ Data9370f0 ]                             ;0x0042138c :        8b0df0709300
             mov eax ,  dword ptr [ Data9393ac ]                             ;0x00421392 :        a1ac939300
             add ecx , 02Ch                                                  ;0x00421397 :        83c12c
             push ebx                                                        ;0x0042139a :        53
             mov ebx , ecx                                                   ;0x0042139b :        8bd9
             mov  dword ptr [ Data9370f0 ] , ecx                             ;0x0042139d :        890df0709300
             movzx ecx ,word ptr [eax]                                       ;0x004213a3 :        0fb708
             add eax , 02h                                                   ;0x004213a6 :        83c002
             mov dword ptr [ Data9393ac ] ,  eax                             ;0x004213a9 :        a3ac939300
             mov al ,  byte ptr [ Data936f10 ]                               ;0x004213ae :        a0106f9300
             test al , al                                                    ;0x004213b3 :        84c0
             push esi                                                        ;0x004213b5 :        56
             push edi                                                        ;0x004213b6 :        57
             mov  dword ptr [ ebp - 4 ] , ebx                                ;0x004213b7 :        895dfc
             mov  dword ptr [ ebp - 8 ] , ecx                                ;0x004213ba :        894df8
             js Label58f640                                                  ;0x004213bd :        0f887de21600
             mov eax ,  dword ptr [ Data936dec ]                             ;0x004213c3 :        a1ec6d9300
             test eax , eax                                                  ;0x004213c8 :        85c0
             mov  edx , dword ptr [ Data9370f8 ]                             ;0x004213ca :        8b15f8709300
             jne Label58f66c                                                 ;0x004213d0 :        0f8596e21600

     Label4213d6 ::
             mov  edi , dword ptr [edx]                                      ;0x004213d6 :        8b3a
             mov  eax , dword ptr [ edi + 0158h ]                            ;0x004213d8 :        8b8758010000
             test eax , eax                                                  ;0x004213de :        85c0
             jne Label58f6d6                                                 ;0x004213e0 :        0f85f0e21600

     Label4213e6 ::
             mov  edx , dword ptr [ Data9370f8 ]                             ;0x004213e6 :        8b15f8709300
             mov  eax , dword ptr [edx]                                      ;0x004213ec :        8b02
             mov  dword ptr [ ebp - 12 ] , eax                               ;0x004213ee :        8945f4
             mov  eax , dword ptr [ eax + 32 ]                               ;0x004213f1 :        8b4020
             xor edi , edi                                                   ;0x004213f4 :        33ff
             test eax , eax                                                  ;0x004213f6 :        85c0
             je Label421432                                                  ;0x004213f8 :        7438
             test  byte ptr [ eax + 16 ] , 020h                              ;0x004213fa :        f6401020
             je Label421432                                                  ;0x004213fe :        7432


     ;
     ;                 --------------------------------------------------------------------------------
     ;                      VFP 9.0 FIX - THE VARIABLE BEHAVIOR FOR THE VARIABLE NAME WITHOUT MDOT
     ;                                  June 2021
     ;                 --------------------------------------------------------------------------------
     ;                                     CCB
     ;
     ; The variable behavior for the variable name without mdot.
     ;
     ; 2021/6/26, by ccb
     ;

             mov  edx , dword ptr [ Data9370f8 ]
             mov  edx , dword ptr [edx]
             cmp dword ptr [edx] , 00h
             je Label421400
             cmp dword ptr vfpa_sys9062_data,00h
             je Label421432
             cmp dword ptr vfpa_sys9062_data,02h
             je Label4213ff
             jmp Label421400
     Label4213ff ::
             mov  esi , dword ptr [ ebp - 8 ]
             mov  edx , dword ptr [ Data9388e4 ]
             lea ecx ,  dword ptr [ esi + 4 * esi ]
             movzx ecx ,word ptr [ edx + 4 * ecx + 14 ]
             pushd 00h
             dec ecx
             call Fun53c57a
             cmp eax , 0FFFFFFFFh
             jne Label421432
             mov  edx , dword ptr [ Data9370f8 ]
             mov  eax , dword ptr [edx]
             mov  eax , dword ptr [ eax + 32 ]
             jmp Label421400


     Label421400 ::
             mov  eax , dword ptr [eax]                                      ;0x00421400 :        8b00
             mov  ecx , dword ptr [ eax + 52 ]                               ;0x00421402 :        8b4834
             xor esi , esi                                                   ;0x00421405 :        33f6
             test ecx , ecx                                                  ;0x00421407 :        85c9
             jle Label421432                                                 ;0x00421409 :        7e27
             xor ecx , ecx                                                   ;0x0042140b :        33c9
             lea esp ,  dword ptr [ esp ]                                    ;0x0042140d :        8d2424

     Label421410 ::
             mov  edx , dword ptr [ eax + 76 ]                               ;0x00421410 :        8b504c
             mov  edx , dword ptr [edx]                                      ;0x00421413 :        8b12
             mov  bx , word ptr [ ebp - 8 ]                                  ;0x00421415 :        668b5df8
             cmp  word ptr [ ecx + edx ] , bx                                ;0x00421419 :        66391c11
             je Label42142c                                                  ;0x0042141d :        740d
             mov  edx , dword ptr [ eax + 52 ]                               ;0x0042141f :        8b5034
             inc esi                                                         ;0x00421422 :        46
             add ecx , 034h                                                  ;0x00421423 :        83c134
             cmp esi , edx                                                   ;0x00421426 :        3bf2
             jnl Label42142f                                                 ;0x00421428 :        7d05
             jmp Label421410                                                 ;0x0042142a :        ebe4

     Label42142c ::
             lea edi ,  dword ptr [ esi + 1 ]                                ;0x0042142c :        8d7e01

     Label42142f ::
             mov  ebx , dword ptr [ ebp - 4 ]                                ;0x0042142f :        8b5dfc

     Label421432 ::
             test edi , edi                                                  ;0x00421432 :        85ff
             je Label53c8bc                                                  ;0x00421434 :        0f8482b41100
             lea eax ,  dword ptr [ edi - 1 ]                                ;0x0042143a :        8d47ff
             push eax                                                        ;0x0042143d :        50
             mov  eax , dword ptr [ ebp - 12 ]                               ;0x0042143e :        8b45f4
             mov  ecx , dword ptr [ eax + 32 ]                               ;0x00421441 :        8b4820
             push ecx                                                        ;0x00421444 :        51
             push ebx                                                        ;0x00421445 :        53
             call Fun421694                                                  ;0x00421446 :        e849020000
             test eax , eax                                                  ;0x0042144b :        85c0
             je Label53c8bc                                                  ;0x0042144d :        0f8469b41100

     Label421453 ::
             pop edi                                                         ;0x00421453 :        5f
             pop esi                                                         ;0x00421454 :        5e
             pop ebx                                                         ;0x00421455 :        5b
             mov esp , ebp                                                   ;0x00421456 :        8be5
             pop ebp                                                         ;0x00421458 :        5d
             ret                                                             ;0x00421459 :        c3


4. APPLIES TO:

     VFP 6.0.8167.0
     VFP 6.0.8961.0 (SP5)

     VFP 7.0.0.9262
     VFP 7.0.0.9465 (SP1)

     VFP 8.0.0.2521
     VFP 8.0.0.3117 (SP1)

     VFP 9.0.0.2412
     VFP 9.0.0.3504 (SP1)
     VFP 9.0.0.4611 (SP2)
     VFP 9.0.0.5015 (SP2)
     VFP 9.0.0.5411 (SP2)
     VFP 9.0.0.5721 (SP2)
     VFP 9.0.0.5815 (SP2)
     VFP 9.0.0.6303 (SP2)
     VFP 9.0.0.6602 (SP2)
     VFP 9.0.0.7423 (SP2)

     The bug has been fixed in VFP Advanced.

     IMPORTANT NOTE:
     Recommend to only use SYS(9062,0) for some code, for example,
     PRIVATE m.q_oldsys9062
     m.q_oldsys9062=VAL(SYS(9062))
     =SYS(9062,0) && For the variable name without mdot, vfp will not check the field name, it will check the variable name only.
     * the code block start...
     * ...
     * the code block end.
     =SYS(9062,m.q_oldsys9062)

     It is similar to the following code:
     PRIVATE m.q_oldsele
     m.q_oldsele=SELE()
     SELE 0
     * the code block start...
     * ...
     * the code block end.
     SELE (m.q_oldsele)

     There is only a little difference for some statements, for example,

     1, x2=x1 and m.x2=x1

     the vfp source code:
     x2=x1
     the compiled p-code:
     0D 00 54 F7 00 00 10 FC F7 01 00 FD FE
     --------------------------------------
     the length of the compiled p-code is 0x0D (13) bytes.

     the vfp source code:
     m.x2=x1
     the compiled p-code:
     0F 00 54 F5 0D F7 00 00 10 FC F7 01 00 FD FE
     --------------------------------------------
     the length of the compiled p-code is 0x0F (15) bytes.

     F5 0D : it's M., and then it's the same as x2=x1.

     2, PUBLIC x2 and PUBLIC m.x2

     the vfp source code:
     PUBLIC x2
     the compiled p-code:
     07 00 37 F7 00 00 FE
     --------------------
     the length of the compiled p-code is 0x07 (7) bytes.

     the vfp source code:
     PUBLIC m.x2
     the compiled p-code:
     09 00 37 F5 0D F7 00 00 FE
     --------------------------
     the length of the compiled p-code is 0x09 (9) bytes.

     F5 0D : it's M., and then it's the same as PUBLIC x2.

     3, x2=m.x1 and STORE m.x1 TO x2

     the vfp source code:
     x2=m.x1
     get nti (an integer) of the var x2, save to tmp2 (an integer),
     calculate the expression m.x1, save the result to a Value structure val1,
     set the var x2 (its nti is tmp2) from val1.

     the vfp source code:
     STORE m.x1 TO x2
     calculate the expression m.x1, save the result to a Value structure val1,
     get nti (an integer) of the var x2,
     set the var x2 (its nti is eax) from val1.


5. REFERENCE WEBSITES:

     1, baiyujia.com:
     http://www.baiyujia.com
     http://www.baiyujia.com/vfpdocuments/f_vfp9fix180.asp

     2, foxite.com:
     https://www.foxite.com/archives/memory-variable-0000292846.htm
     https://www.foxite.com/archives/mdot-0000322640.htm
     https://www.foxite.com/archives/it-is-not-wise-not-to-use-mdot-0000219998.htm
     https://www.foxite.com/archives/magical-m-0000180204.htm
     https://www.foxite.com/archives/m-prefix-of-local-variables-0000079314.htm
     https://www.foxite.com/archives/a-confession-0000382571.htm
     https://www.foxite.com/archives/another-thread-on-mdot-0000237222.htm
     https://www.foxite.com/archives/best-coding-practices-for-newbies-0000160033.htm
     https://www.foxite.com/archives/best-practice-to-declare-variables-0000369623.htm
     https://www.foxite.com/archives/debugruntime-differences-and-mdot-0000431500.htm
     https://www.foxite.com/archives/for-statement-variable-0000447907.htm
     https://www.foxite.com/archives/foxypreviewer-v279-and-mdots-0000323617.htm

     3, microsoft.com:
     https://docs.microsoft.com/en-us/archive/blogs/calvin_hsia/foxpro-performance-tip-field-name-lookup-for-tables
     https://social.msdn.microsoft.com/Forums/en-US/cc859679-4c22-4410-addd-7d013d91ca67/question-on-mem

     4, blogspot.com:
     https://sandstorm36.blogspot.com/2011/09/learning-mdot-usage-repost.html


6. OTHER:

     For reference only, there is no guarantees.

     Any questions or suggestions, please send me an email at ccb2000@163.com.