|
@@ -74,6 +74,7 @@ type
|
|
var
|
|
var
|
|
WrapperBlockList : PWrapperBlock;
|
|
WrapperBlockList : PWrapperBlock;
|
|
TrampolineFreeList : PMethodWrapperTrampoline;
|
|
TrampolineFreeList : PMethodWrapperTrampoline;
|
|
|
|
+ CritObjectInstance : TCriticalSection;
|
|
|
|
|
|
function TrampolineWndProc(Window: HWND; Message, WParam: WPARAM;LParam: LPARAM): HRESULT; stdcall; assembler;
|
|
function TrampolineWndProc(Window: HWND; Message, WParam: WPARAM;LParam: LPARAM): HRESULT; stdcall; assembler;
|
|
asm
|
|
asm
|
|
@@ -111,75 +112,92 @@ function MakeObjectInstance(Method: TWndMethod): Pointer;
|
|
NewBlock : PWrapperBlock;
|
|
NewBlock : PWrapperBlock;
|
|
Trampoline : PMethodWrapperTrampoline;
|
|
Trampoline : PMethodWrapperTrampoline;
|
|
begin
|
|
begin
|
|
- if not(assigned(TrampolineFreeList)) then
|
|
|
|
- begin
|
|
|
|
- NewBlock:=VirtualAlloc(nil,SizeOfPage,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
|
|
|
|
- NewBlock^.UsageCount:=0;
|
|
|
|
- NewBlock^.Next:=WrapperBlockList;
|
|
|
|
- WrapperBlockList:=NewBlock;
|
|
|
|
- Trampoline:=@NewBlock^.Trampolines;
|
|
|
|
- while pointer(Trampoline)+sizeof(Trampoline)<pointer(NewBlock)+SizeOfPage do
|
|
|
|
- begin
|
|
|
|
- Trampoline^.Next:=TrampolineFreeList;
|
|
|
|
- Trampoline^.Block:=NewBlock;
|
|
|
|
- TrampolineFreeList:=Trampoline;
|
|
|
|
- inc(Trampoline);
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
- Trampoline:=TrampolineFreeList;
|
|
|
|
- TrampolineFreeList:=TrampolineFreeList^.Next;
|
|
|
|
- inc(Trampoline^.Block^.UsageCount);
|
|
|
|
- Trampoline^.Call:=$e8;
|
|
|
|
- Trampoline^.CallOffset:=pointer(@get_method_offset)-pointer(@Trampoline^.Call)-5;
|
|
|
|
- Trampoline^.Jmp:=$e9;
|
|
|
|
- Trampoline^.JmpOffset:=pointer(@TrampolineWndProc)-pointer(@Trampoline^.Jmp)-5;
|
|
|
|
- Trampoline^.Method:=Method;
|
|
|
|
- Result:=Trampoline;
|
|
|
|
|
|
+ EnterCriticalSection(CritObjectInstance);
|
|
|
|
+ try
|
|
|
|
+ if not(assigned(TrampolineFreeList)) then
|
|
|
|
+ begin
|
|
|
|
+ NewBlock:=VirtualAlloc(nil,SizeOfPage,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
|
|
|
|
+ NewBlock^.UsageCount:=0;
|
|
|
|
+ NewBlock^.Next:=WrapperBlockList;
|
|
|
|
+ WrapperBlockList:=NewBlock;
|
|
|
|
+ Trampoline:=@NewBlock^.Trampolines;
|
|
|
|
+ while pointer(Trampoline)+sizeof(Trampoline)<pointer(NewBlock)+SizeOfPage do
|
|
|
|
+ begin
|
|
|
|
+ Trampoline^.Next:=TrampolineFreeList;
|
|
|
|
+ Trampoline^.Block:=NewBlock;
|
|
|
|
+ TrampolineFreeList:=Trampoline;
|
|
|
|
+ inc(Trampoline);
|
|
|
|
+ end;
|
|
|
|
+ end;
|
|
|
|
+ Trampoline:=TrampolineFreeList;
|
|
|
|
+ TrampolineFreeList:=TrampolineFreeList^.Next;
|
|
|
|
+ inc(Trampoline^.Block^.UsageCount);
|
|
|
|
+ Trampoline^.Call:=$e8;
|
|
|
|
+ Trampoline^.CallOffset:=pointer(@get_method_offset)-pointer(@Trampoline^.Call)-5;
|
|
|
|
+ Trampoline^.Jmp:=$e9;
|
|
|
|
+ Trampoline^.JmpOffset:=pointer(@TrampolineWndProc)-pointer(@Trampoline^.Jmp)-5;
|
|
|
|
+ Trampoline^.Method:=Method;
|
|
|
|
+ Result:=Trampoline;
|
|
|
|
+ finally
|
|
|
|
+ LeaveCriticalSection(CritObjectInstance);
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
procedure FreeObjectInstance(ObjectInstance: Pointer);
|
|
procedure FreeObjectInstance(ObjectInstance: Pointer);
|
|
begin
|
|
begin
|
|
- dec(PMethodWrapperTrampoline(ObjectInstance)^.Block^.UsageCount);
|
|
|
|
- PMethodWrapperTrampoline(ObjectInstance)^.Next:=TrampolineFreeList;
|
|
|
|
- TrampolineFreeList:=PMethodWrapperTrampoline(ObjectInstance);
|
|
|
|
|
|
+ EnterCriticalSection(CritObjectInstance);
|
|
|
|
+ try
|
|
|
|
+ // block gets overwritten by method dec(PMethodWrapperTrampoline(ObjectInstance)^.Block^.UsageCount);
|
|
|
|
+ PMethodWrapperTrampoline(ObjectInstance)^.Next:=TrampolineFreeList;
|
|
|
|
+ TrampolineFreeList:=PMethodWrapperTrampoline(ObjectInstance);
|
|
|
|
+ finally
|
|
|
|
+ LeaveCriticalSection(CritObjectInstance);
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
-function AllocateHWnd(Method: TWndMethod): HWND;
|
|
|
|
|
|
+procedure DeleteInstBlockList;
|
|
|
|
+ var
|
|
|
|
+ hp : PWrapperBlock;
|
|
begin
|
|
begin
|
|
- { dummy }
|
|
|
|
- runerror(217);
|
|
|
|
|
|
+ EnterCriticalSection(CritObjectInstance);
|
|
|
|
+ try
|
|
|
|
+ while assigned(WrapperBlockList) do
|
|
|
|
+ begin
|
|
|
|
+ hp:=WrapperBlockList^.Next;
|
|
|
|
+ if VirtualFree(WrapperBlockList,4096,MEM_DECOMMIT) then
|
|
|
|
+ VirtualFree(WrapperBlockList,0,MEM_RELEASE);
|
|
|
|
+ WrapperBlockList:=hp;
|
|
|
|
+ end;
|
|
|
|
+ finally
|
|
|
|
+ LeaveCriticalSection(CritObjectInstance);
|
|
|
|
+ end;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
-procedure DeallocateHWnd(Wnd: HWND);
|
|
|
|
|
|
+function AllocateHWnd(Method: TWndMethod): HWND;
|
|
begin
|
|
begin
|
|
{ dummy }
|
|
{ dummy }
|
|
runerror(217);
|
|
runerror(217);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
-procedure DeleteInstBlockList;
|
|
|
|
- var
|
|
|
|
- hp : PWrapperBlock;
|
|
|
|
|
|
+procedure DeallocateHWnd(Wnd: HWND);
|
|
begin
|
|
begin
|
|
- while assigned(WrapperBlockList) do
|
|
|
|
- begin
|
|
|
|
- hp:=WrapperBlockList^.Next;
|
|
|
|
- if VirtualFree(WrapperBlockList,4096,MEM_DECOMMIT) then
|
|
|
|
- VirtualFree(WrapperBlockList,0,MEM_RELEASE);
|
|
|
|
- WrapperBlockList:=hp;
|
|
|
|
- end;
|
|
|
|
|
|
+ { dummy }
|
|
|
|
+ runerror(217);
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
|
|
initialization
|
|
initialization
|
|
WrapperBlockList:=nil;
|
|
WrapperBlockList:=nil;
|
|
TrampolineFreeList:=nil;
|
|
TrampolineFreeList:=nil;
|
|
|
|
+ InitCriticalSection(CritObjectInstance);
|
|
CommonInit;
|
|
CommonInit;
|
|
|
|
|
|
finalization
|
|
finalization
|
|
CommonCleanup;
|
|
CommonCleanup;
|
|
DeleteInstBlockList;
|
|
DeleteInstBlockList;
|
|
|
|
+ DoneCriticalSection(CritObjectInstance);
|
|
end.
|
|
end.
|