1. WM_COPYDATA memory leak. loop 100000, uses 37M of memory
2. '=>' function memory leak. In the example, using pin_call() => () uses 37M of memory, which is modified to pin_call() {}, which will use 23M of memory. I cannot understand the reason for this difference.
It takes about 20 seconds to run this example
Code: Select all
global A_src:=CriticalObject(),A_pin:=CriticalObject(),A_air:=CriticalObject(),A_base:=CriticalObject({id:0}),a_pug:=[],A_Name:='moss',A_Self,a_dllRes
,A_drive:=SubStr(A_ScriptDir,1,2),A_dir:=SubStr(A_ScriptDir,1, (InStr(A_ScriptDir,"\",,,2) or 3)-1),A_disk,A_Id:=0,A_Time,A_Path,A_SelfDir,A_Freelist,A_type,a_ahktime
#NoTrayIcon
#Persistent
#MaxThreads 255
#SingleInstance force
DetectHiddenWindows("on"),ProcessSetPriority("high")
main()
ahkdll({code:"#Persistent`ntt:=[1,2,3,4]`nreturn`nMsgBox a_type ahktime(" ahktime() ")`nToolTip 1,1,1`nreturn"})
sleep 100
th:=a_pin.1
ti:=ahktime()
loop 100000
{
t:=th.ahkgetvar("tt")
}
MsgBox ahktime(ti) "`n" ov(t)
t:=ahksethex(th.func("ahkgethex","tt"))
t:=th.c.tt
t:=th.c.ahkgetvar("tt")
t:=th.ahkgetvar("tt")
main(){
UnZipRawMemory(LockResource(hr:=LoadResource(0,s:=FindResource(0,"F903E44B8A904483A1732BA84EA6191F",10))),SizeofResource(0,s),a_dllRes),FreeResource(hr)
QueryPerformanceFrequency(getvar(a_ahktime:=0))
a_type:=substr(a_type,instr(a_type,";`!")+4)
RegExMatch(a_type,"s)(.*)A_type:=fileread\(A_LineFile\)(.*)",t)
A_base.__pin_1:="`nExitApp`n#NoTrayIcon`n#Persistent`n#MaxThreads 255`nglobal A_src,A_pin,A_air,A_base,a_pug,A_Name,A_Self,A_drive,A_dir,A_disk,A_Id,A_Time,A_Path,A_SelfDir,A_type`n"
. t.1 "A_src:=CriticalObject(" (&a_src) "),A_pin:=CriticalObject(" (&A_pin) "),A_air:=CriticalObject(" (&A_air) "),A_base:=CriticalObject(" (&A_base) "),a_pug:=[],A_drive:='" a_drive "',A_dir:='" a_dir "',A_disk:='" A_disk "'"
a_base.__pin_2:=strReplace(strReplace(strReplace(t.2,"&a_dllRes",(&a_dllRes)),"a_ahktime",a_ahktime),"NewThread(","a_pin.0.post('NewThread',")
a_type:="e"
as_tls_exe()
}
as_tls_exe(){
f:={lib:lib:=GetModuleHandle(),Function:GetProcAddress(lib,"ahkFunction"),PostFunction:GetProcAddress(lib,"ahkPostFunction"),addScript:GetProcAddress(lib,"addScript")
,Exec:GetProcAddress(lib,"ahkExec"),ExecuteLine:GetProcAddress(lib,"ahkExecuteLine"),getvar:GetProcAddress(lib,"ahkgetvar"),assign:GetProcAddress(lib,"ahkassign")
,Label:GetProcAddress(lib,"ahkLabel"),Pause:GetProcAddress(lib,"ahkPause"),Ready:GetProcAddress(lib,"ahkReady")}
A_base.__pin_tls:= "`na_type:='t',a_pin.%a_id%:=A_Self:=CriticalObject({ThreadID:i:=GetcurrentThreadID(),name:a_name,hwnd:A_ScriptHwnd,id:a_id})
,A_Self.DefineMethod('func',DynaCall(" f.Function ",'s==sssssssssssui','','','','','','','','','','','',i))
,A_Self.DefineMethod('post',DynaCall(" f.PostFunction ",'i==sssssssssssui','','','','','','','','','','','',i))
,A_Self.DefineMethod('add',DynaCall(" f.addScript ",'ut==siui','',0,i))
,A_Self.DefineMethod('exec',DynaCall(" f.Exec ",'ut==sui','',i))
,A_Self.DefineMethod('get',DynaCall(" f.getvar ",'s==suiui','',0,i))
,A_Self.DefineMethod('set',DynaCall(" f.assign ",'s==ssui','','',i))
,A_Self.DefineMethod('sub',DynaCall(" f.Label ",'ui==suiui','',0,i))
,A_Self.DefineMethod('pause',DynaCall(" f.Pause ",'ui==sui','',i))
,A_Self.DefineMethod('ready',DynaCall(" f.Ready ",'ui==ui',i)),a_self.DefineMethod('__Call', func('pin_call'))"
a_pin.0:=a_pin.moss:=a_pin.host:=A_Self:=CriticalObject({ThreadID:i:=GetcurrentThreadID(),name:"moss",hwnd:A_ScriptHwnd,module:"moss",id:a_id})
,A_Self.DefineMethod("func",DynaCall(f.Function,"s==sssssssssssui","","","","","","","","","","","",i))
,A_Self.DefineMethod("post",DynaCall(f.PostFunction,"i==sssssssssssui","","","","","","","","","","","",i))
,A_Self.DefineMethod("add",DynaCall(f.addScript,"ut==siui","",0,i))
,A_Self.DefineMethod("exec",DynaCall(f.Exec,"ut==sui","",i))
,A_Self.DefineMethod("get",DynaCall(f.getvar,"s==suiui","",0,i))
,A_Self.DefineMethod("set",DynaCall(f.assign,"s==ssui","","",i))
,A_Self.DefineMethod("sub",DynaCall(f.Label,"ui==suiui","",0,i))
,A_Self.DefineMethod("pause",DynaCall(f.Pause,"ui==sui","",i))
,A_Self.DefineMethod("ready",DynaCall(f.Ready,"ui==ui",i)),a_self.DefineMethod('__Call', func("pin_call"))
}
/*
m 1,a_pin.1.ahkgetlist("tt","a_id","a_name")
M a_pin.1.ahkgetvar("tt")
t:=so(a_ahkdir "\conf.so")
m t
Loop Files,t["src"] "\*","FR"
{
if A_LoopFileExt="ahk"
read_ahk(A_LoopFilePath,substr(A_LoopFileName,1,-4))
else if A_LoopFileExt="ss"
read_ss(A_LoopFilePath)
}
read_ahk(path,name){
if ObjRawGet(a_src,name)
return
str:=trim(fileread(path),"`n`r`t ")
it:={},ObjRawSet(a_src,name,it)
static to:={"key":"1","alias":"1","code":"1"}
if RegExMatch(str,"SsU)^;\?(.*)\r\n(.*)",f)
{
loop parse, f.1,",","`t "
if (r:=instr(k:=a_loopfield,"=")) and n:=LTrim(substr(k,r+1)," `t")
{
i:=RTrim(substr(k,1,r-1)," `t")
ObjRawSet(it,i,n)
}
for i,n in it.OwnProps()
if ObjRawGet(to,i)
gosub(i)
}
return
read:
if n!=1
it["s"]:=trim(f.2,"`r`t`n ")
return
key:
return
alias:
Loop Parse,n,"|", "`t "
ObjRawGet(a_src,a_loopfield)?'':ObjRawSet(a_src,a_loopfield,it)
return
}
read_ss(path){
pi:=so(path,,"amo_object")
m pi
MsgBox "ss"
}
M ov(t) "`n`n" ov(a_pug)
*/
;!
ahkpin(w,l,m,h){
static _:=(ListLines("off"),onmessage(0x12340,A_ScriptHwnd,(w,l,m,h) => (%object(w)%(), objrelease(w)),250),onmessage(0x4a,A_ScriptHwnd,"ahkpin",250),A_type:=fileread(A_LineFile),'')
Critical
t:=ObjLoad(NumGet(l+2*A_PtrSize),NumGet(l+A_PtrSize))
if ""!=(s:=t.HasOwnProp("ps")?%t.func%(t.ps*):%t.func%()) and w
pin_send({func:"ahkAliasSet",ps:[w,s]},t.from,0)
return true
}
pin_send(ByRef it,ByRef hwnd,ByRef reply){
sz:=ObjDump(it,bin),VarSetCapacity(c,3*A_PtrSize,0),NumPut(sz,c,A_PtrSize),NumPut(&bin,c,2*A_PtrSize),SendMessage_(hwnd,0x4a,reply,&c),VarSetCapacity(c,0)
}
pin_call(this,ByRef func,ByRef ps*)=>(it:={from:A_ScriptHwnd,func:func},ps.length?ObjRawSet(it,"ps",ps[1]):"",pin_send(it,this.hwnd,getvar(out)),out)
pin_call2(this,ByRef func,ByRef ps*){
it:={from:A_ScriptHwnd,func:func},ps.length?ObjRawSet(it,"ps",ps[1]):"",pin_send(it,this.hwnd,getvar(out))
return out
}
ov(f,t:="",r:=""){
if !r
{
if !isobject(f)
return
r:={&f:1}
}
else if ObjRawGet(r,&f)
Return "*"
else r.%&f%:=1
if RegExMatch(p:=type(f),"(RegExMatch)",m)
_%m.1%()
else if p~="i)array"
arr(),d:="[",b:="]"
else
map(),d:="{",b:="}"
Return jk?jk:(t?("`n" t):"") d "`n" t rtrim(s,"`n`t,") "`t`n" t b
arr(){
for i,n in f
s.="`t" ltrim(k(n),"`n`t") ",`n" t
}
map(){
for i,n in p~="i)Object"?f.OwnProps():f
s.="`t" k(i) "`t:`t" k(n) ",`n" t
}
k(ByRef k) => isobject(k) ? ov(k,t "`t",r) : k is "number" ? k : "`"" (instr(k,"`n")? StrReplace(k,"`n","`n`t" t):k) "`""
_RegExMatch(){
for i,n in f
jk.="[ " i "`t,`tP-" f.pos(i) "`t,`t(L-" f.len(i) ")`t,`t`"" f.value(i) "`" ]`n"
jk:=trim(jk,"`n,")
}
}
ahkload(){
return (t:=CriticalObject({"":r:=MemoryLoadLibrary(&a_dllRes)}),
t.DefineMethod("func",DynaCall(MemoryGetProcAddress(r,"ahkFunction"),"s==sssssssssss")),
t.DefineMethod("post",DynaCall(MemoryGetProcAddress(r,"ahkPostFunction"),"i==sssssssssss")),
t.DefineMethod("new",DynaCall(MemoryGetProcAddress(r,"ahkTextDll"),"ut==sss")),
t.DefineMethod("add",DynaCall(MemoryGetProcAddress(r,"addScript"),"ut==si")),
t.DefineMethod("exec",DynaCall(MemoryGetProcAddress(r,"ahkExec"),"ut==sui")),
t.DefineMethod("get",DynaCall(MemoryGetProcAddress(r,"ahkGetVar"),"s==sui")),
t.DefineMethod("set",DynaCall(MemoryGetProcAddress(r,"ahkAssign"),"ui==ss")),
t.DefineMethod("sub",DynaCall(MemoryGetProcAddress(r,"ahkLabel"),"ui==sui")),
t.DefineMethod("pause",DynaCall(MemoryGetProcAddress(r,"ahkPause"),"i==s")),
t.DefineMethod("exit",DynaCall(MemoryGetProcAddress(r,"ahkTerminate"),"i==i")),
t.DefineMethod("ready",DynaCall(MemoryGetProcAddress(r,"ahkReady"),"")),
t.DefineMethod("reload",DynaCall(MemoryGetProcAddress(r,"ahkReload"),"i==i")),t)
}
ahkTime(s:=0){
QueryPerformanceCounter(getvar(n:=0))
Return (s ? Round((n-s)/a_ahktime, 6) : n)
}
apg(t){
a_pug.push(t)
}
ahkgetvar(byref r){
global
return %r%
}
ahkSetlist(p){
global
local i,n
for i,n in p.OwnProps()
%i%:=n
}
ahkgetlist(p*){
global
t:={}
for i,n in p
ObjRawSet(t,n,%n%)
return t
}
ahksetvar(ByRef k,ByRef v){
global
%k%:=v
}
ahkAliasSet(ByRef i,ByRef v){
alias(r,i+0),r:=v
}
ahksetobj(o,p){
global
local i,n
o:=%o%
if type(o)="map"
{
for i,n in p.OwnProps()
o[i]:=n
} else
{
for i,n in p.OwnProps()
ObjRawSet(o,i,n)
}
}
ahkgetobj(o,p){
global
local i,n,t
{
o:=%o%,t:={}
for i,n in p
ObjRawSet(t,n,ObjRawGet(o,n))
return t
}
}
go(t,p*){
critical
ObjAddRef(t:=&func(t).bind(p*)),PostMessage_(A_ScriptHwnd,0x12340,t)
}
to(t,p*){
SetTimer Func(t).Bind(p*),-1
}
pin_post(w,l,s,h){
t:=object(l),ObjRelease(l),r:=t.RemoveAt(1),%r%(t*)
}
pin_new(ByRef name){
i:=A_DetectHiddenWindows,n:=A_TitleMatchMode,DetectHiddenWindows("On"),SetTitleMatchMode(2)
if r:=WinExist(s:="[" name "] ahk_class AutoHotkey") or WinExist((Sleep(15),s)) or WinExist((Sleep(30),s))
out:={name:name,hwnd:r},out.DefineMethod('__Call', func("pin_call"))
DetectHiddenWindows(i),SetTitleMatchMode(n)
return out
}
ahkgethex(t){
global
t:=%t%
if isobject(t)
return (sz:=ObjDump(t,v), BinToHex(&v,sz))
else
return t
}
ahksethex(ByRef hex){
HexToBin(bin,hex)
return ObjLoad(&bin)
}
/*
ahktls(it){
it.id:=++a_base.id
it.HasOwnProp("name")?'':it.name:="Nix"
head:=",a_name:='" it.name "',a_id:=" it.id ",A_Parent:=" A_id ",A_ParentHwnd:=" A_ScriptHwnd ",A_ParentName:='" A_name "',SetWindowText(A_ScriptHwnd,'[' a_name ']')," A_base.__pin_tls ",a_self.c:=self_base.new()"
NewThread(it.code A_base.__pin_1 head A_base.__pin_2,, it.name " ." it.id)
return it.id
}
*/
ahkexe(it){
it.id:=++a_base.id
}
ahkdll(it){
it.id:=++a_base.id
a_pin.%it.id%:=t:=ahkload()
it.HasOwnProp("name")?'':it.name:="Nix"
head:=",a_name:='" ObjRawGet(it,"name") "',a_id:=" it.id ",A_Parent:=" A_id ",A_ParentHwnd:=" A_ScriptHwnd ",A_ParentName:='" A_name "',SetWindowText(A_ScriptHwnd,'[' a_name ']'),A_Self:=CriticalObject(" (&t) "),a_self.hwnd:=A_ScriptHwnd,a_self.c:=self_base.new()"
t.DefineMethod('__Call', func("pin_call"))
t.new it.code A_base.__pin_1 head A_base.__pin_2,, it.name " ." it.id
return it.id
}
Class self_base {
__item[p*] {
set {
global
%p[1]%:=value
}
get {
global
return %p[1]%
}
}
__Get(k,p) {
global
return %k%
}
__Set(k,r,v) {
global
%k%:=v
}
__call(a,b){
return %a%(b*)
}
}