Represent a standalone class implements a hash table, which in many cases can be a substitute for the dictionary (Dictionary) of Scripting runtime. Implements all the same methods as in the dictionary, and add new ones. Includes support transfer through the For Each, you can also set the mode of transfer of keys/values, as compared to the previous version fixes bugs departure from the environment during your stay in the loop For Each, and there are no restrictions on the nested loops. Run fast enough on my computer about as well (even a bit faster) as a dictionary with binary comparison, when the text comparison works almost 2 times faster than the dictionary. As keys are allowed Variant variables with types of vbEmpty to vbDecimal inclusive. Numeric keys must be unique, ie -1, True, -1e0 - the same key as in the dictionary. New method EnumMode - determines the current mode of transfer. Valid values ENUM_BY_KEY, ENUM_BY_VALUE. Upon entering the For Each loop starts listing the parameter that is set this property. For example, you can list the keys in the main loop, the attached values or keys first and then the value. Also setting this property in windows Locals or Watch You can toggle the display with keys to values and vice versa.
Code is generated only when the first object, and is used by all subsequent objects. The address is stored in the environment variable, as I did in subclassing.
Image may be NSFW.
Clik here to view.
Implementation itself is an array of doubly-linked lists, where the array indexes - the hash values of the corresponding keys. To support enumeration is used enumerator object. Implementing an interface IEnumVariant and IUnknown for the enumerator is written in assembly language:Clik here to view.

Code:
[BITS 32]
QueryInterface:
mov eax,[esp+4] ; ObjPtr
inc dword [eax+4] ; Counter++
mov ecx, [esp+0xc]
mov [ecx],eax ; ppvObject = ObjPtr
xor eax,eax ; Success
ret 0xc
AddRef:
mov eax,[esp+4] ; ObjPtr
inc dword [eax+4] ; Counter++
mov eax, [eax+4] ; Counter return
ret 0x4
Release:
mov eax,[esp+4] ; ObjPtr
dec dword [eax+4] ; Counter--
jz RemoveObject ; if (Counter == 0)
mov eax, [eax+4] ; Counter return
ret 0x4
RemoveObject:
push eax ; lpMem
push 0x00000001 ; HEAP_NO_SERIALIZE
call 0x12345678 ; GetProcessHeap
push eax ; hHeap
call 0x12345678 ; HeapFree
xor eax,eax ; Counter = 0
ret 0x4
IEnumVariant_Next:
push ebx
push edi
push esi
mov esi, [esp+0x10] ; ObjPtr
mov ebx, [esp+0x14] ; ebx = celt
mov edi, [esp+0x18] ; rgVar
NextItem:
movsx eax, word [esi+0x8] ; Pointer.Hash
inc eax
jz ExitCycle ; if (Pointer.Hash == -1)
dec eax
mov ecx, [esi+0xc] ; DataPtr
mov ecx, [ecx+eax*8+4] ; ecx = tItem.tElement
movzx eax, word [esi+0xA] ; Pointer.Index
imul ax, ax, 0x28 ;
movzx eax, ax ; eax = Pointer.Index * sizeof(tElement)
mov ecx, [ecx+0xc] ; ecx = *tElement(0)
lea ecx, [ecx+eax] ; *tElement(Pointer.Index)
mov eax, [ecx+0x20]
add ecx, [esi+0x14] ; ecx += OffsetVarinat
mov [esi+0x8], eax ; Pointer = tElement(Pointer.Index).Next
push ecx ; pvargSrc
push edi ; pvargDest == rgVar
call 0x12345678 ; VariantCopy
add edi, 0x10
dec ebx
jne NextItem
ExitCycle:
test ebx, ebx
setne dl ; if (ebx = 0) dl = 0 else dl = 1
movzx esi, dl ; edx = dl
mov edi, [esp+0x1c] ; pCeltFetched
test edi, edi
je ExitFunction
mov eax, [esp+0x14] ; eax = celt
sub eax, ebx
mov [edi], eax ; pCeltFetched = count
ExitFunction:
mov eax, esi
pop esi
pop edi
pop ebx
ret 0x10
IEnumVariant_Skip:
mov edx, [esp+0x04] ; ObjPtr
mov eax, [edx+0x8] ; Pointer.Hash
mov edx, [edx+0xc] ; DataPtr
NextItem_2:
inc ax
jz ExitCycle_2 ; if (Pointer.Hash == -1)
dec ax
movzx ecx, ax ; ecx = Pointer.Hash
mov ecx, [edx+ecx*8+4] ; ecx = tItem.tElement
shr eax, 0x10 ; eax = Pointer.Index
imul ax, ax, 0x28 ;
mov ecx, [ecx+0xc] ; ecx = *tElement(0)
mov eax, [ecx+eax+0x20] ; eax = tElement(Pointer.Index).Next
dec dword [esp+0x08] ; celt--
jne NextItem_2
xor edx, edx
ExitCycle_2:
test edx, edx
setne dl ; if (edx = 0) dl = 0 else dl = 1
mov eax, edx
ret 0x08
IEnumVariant_Reset:
mov eax, [esp+0x04] ; ObjPtr
mov edx, [eax+0x10] ; First
mov [eax+0x08], edx ; Pointer = First
xor eax, eax
ret 0x4