 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
SKAN
Joined: 26 Dec 2005 Posts: 5880
|
Posted: Tue Dec 11, 2007 8:27 am Post subject: |
|
|
Thanks lexikos.
If we had a way to save and restore the whole memory structure,
including the binary content any vars may contain,
Would not that be great ?!

Last edited by SKAN on Wed Dec 12, 2007 12:31 pm; edited 1 time in total |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Tue Dec 11, 2007 9:40 am Post subject: |
|
|
Can we delete variables, as currently that is not possible. _________________
 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2558 Location: Australia, Qld
|
Posted: Tue Dec 11, 2007 10:09 am Post subject: |
|
|
All Var structures (i.e. variables, excluding their contents) created by AutoHotkey use memory from SimpleHeap, which does not allow the memory to be freed. The same is true for script structures, like Line, ArgStruct, DerefType, etc.
If we created the Vars manually, we could delete them. It could be useful for "sandboxed" dynamic scripts (where the entire script and its variables could be deleted), but more typically not so useful. Manually creating global variables (accessible by regular double-derefs) would not be possible.
As for saving and restoring "the whole memory structure", it could be done, but you'd have to use ListVars. It would have fairly limited uses. |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5880
|
Posted: Tue Dec 11, 2007 10:39 am Post subject: |
|
|
| lexikos wrote: | | As for saving and restoring "the whole memory structure", it could be done, but you'd have to use ListVars. It would have fairly limited uses. |
I can already create a bin file which would be a super structure for many tiny bmps, ttf and vars and load them with a UDF. This way my script would be less cluttered and the resource would be reduced to a single file.
What I request you is:
propose/suggest/convince Mr.Chris on changes to AutoHotkey.exe itself which would allow us more flexible low-level access.
 |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Tue Dec 11, 2007 10:48 am Post subject: |
|
|
Well, that is clearly out of way SKAN ....
You should anylise composite storage for your thing. You can also use resources. _________________
 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2558 Location: Australia, Qld
|
Posted: Tue Dec 11, 2007 11:46 am Post subject: |
|
|
Skan, what capability are you suggesting be added to LowLevel?
| Skan wrote: | | propose/suggest/convince Mr.Chris on changes to AutoHotkey.exe itself which would allow us more flexible low-level access. | LowLevel came about because I wanted to see what was possible without modifying AutoHotkey.
Having access to the global Script structure (g_script) would allow a script to enumerate global variables in the script. It would also remove the need for __getFirstLine, __getFirstFunc and __getFirstLabel. However, I think it would be much more appropriate to add the desired functionality to AutoHotkey. The same is true for any application of LowLevel.
One thing I am not sure of is what functionality is worthy of built-in status. |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5880
|
Posted: Tue Dec 11, 2007 12:17 pm Post subject: |
|
|
| majkinetor wrote: | | You should anylise composite storage for your thing. You can also use resources. |
No. I am not requesting anything for personal needs and this is nothing about distribution. I was just trying to give an example.
| lexikos wrote: | | Skan, what capability are you suggesting be added to LowLevel? |
Functionality that provides manipulation of memory variables including wildcard search / listing of variable names, relevant pointers, sizes etc.

Last edited by SKAN on Wed Dec 12, 2007 12:34 pm; edited 2 times in total |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2558 Location: Australia, Qld
|
Posted: Wed Dec 12, 2007 7:36 am Post subject: |
|
|
| Skan wrote: | | Functionality that provides manipulation of memory variables including wildcard search / listing of variable names, relevant pointers, sizes etc. |
You can use ListGlobalVars to get the global var list (text.) LowLevel is not required at all, and I feel that any further discussion is off-topic... |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5880
|
Posted: Wed Dec 12, 2007 7:49 am Post subject: |
|
|
| lexikos wrote: | | I feel that any further discussion is off-topic... |
I understand.
Maybe I should have just asked it like: "Any way to retrieve the size of a variable that contain binary data ?"
I can edit out/delete my posts if you want to.
Thanks. |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2558 Location: Australia, Qld
|
Posted: Wed Dec 12, 2007 8:36 am Post subject: something more on-topic |
|
|
| Skan wrote: | | Maybe I should have just asked it like: "Any way to retrieve the size of a variable that contain binary data ?" |
Since I had thought it obvious, I hadn't posted:
| Code: | size_a := VarSetCapacity(var)
| or the less obvious | Code: | | size_b := NumGet(__getVar(var)+8) | size_b will always be size_a+1, since VarSetCapacity does not include the byte reserved for a null-terminator. Also, the following are equivalent:
| Code: | addr_a := &var
addr_b := NumGet(__getVar(var)) ; implied offset +0 | In theory, you could change var to refer to existing memory:
| Code: | | NumPut(pointer, __getVar(var)) | but you'd need to ensure:
- mHowAllocated is ALLOC_MALLOC (2) and the memory was allocated with msvcrt\malloc(); or
- mHowAllocated is ALLOC_SIMPLE (1), so AutoHotkey never tries to free() the memory
| Code: | | NumPut(1, __getVar(var), 12, "char") |
and the memory is never freed while the variable is using it.
Again in theory, mHowAllocated shouldn't matter as long as var is not local and you don't treat it as a string. (Assigning a string to the var would potentially cause AutoHotkey to "expand" it, by allocating new memory and attempting to free what you assigned.)
If mHowAllocated is 0, the variable has never been allocated memory. Knowing this, you can determine whether a variable has ever had a capacity higher than 0.
| Skan wrote: | | I can edit out/delete my posts if you want to. | Perhaps just edit them to be more concise, with less off-topic background information.  |
|
| Back to top |
|
 |
SKAN
Joined: 26 Dec 2005 Posts: 5880
|
Posted: Wed Dec 12, 2007 12:45 pm Post subject: Re: something more on-topic |
|
|
| lexikos wrote: | | Since I had thought it obvious, I hadn't posted: size_a := VarSetCapacity(var) |
Thanks for being patient. In future, I will post with sanity.  |
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 3626 Location: Belgrade
|
Posted: Wed Dec 12, 2007 1:15 pm Post subject: |
|
|
| Quote: | | In theory, you could change var to refer to existing memory: |
So we can delete variables then ?
I can just create one variable, name it TRASH and then I can delete entire array (so it is not visible in ListVars) by redirecting its pointers to TRASH. _________________
 |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2558 Location: Australia, Qld
|
Posted: Wed Dec 12, 2007 2:52 pm Post subject: |
|
|
No, you can delete a variable's contents, but not the variable itself. By "refer to existing memory", I meant the variable's contents. In the following example, var2 and var3 point to the same memory as var1. Var3 is assigned a longer string to show that it causes new memory to be allocated. Var4 is turned into a proper ByRef alias for var1.
| Code: | LowLevel_init()
var1 = abc
NumPut( VarSetCapacity(var1)+1, NumPut(&var1, __getVar(var2)), 4)
NumPut( VarSetCapacity(var1)+1, NumPut(&var1, __getVar(var3)), 4)
NumPut( __getVar(var1), __getVar(var4), 4), NumPut(0, __getVar(var4), 15, "char")
ListVars
MsgBox % var1 "`n" var2 "`n" var3 "`n" var4
VarSetCapacity(var2, -1)
VarSetCapacity(var3, -1)
ListVars
MsgBox % var1 "`n" var2 "`n" var3 "`n" var4
var2 = 123
var3 = Too long.
ListVars
MsgBox % var1 "`n" var2 "`n" var3 "`n" var4
var4 = var4 is a true alias for var1, ByRef-style.
ListVars
MsgBox % var1 "`n" var2 "`n" var3 "`n" var4
|
|
|
| Back to top |
|
 |
Fuco
Joined: 21 Mar 2006 Posts: 49 Location: Slovakia, Europe :)
|
Posted: Mon Dec 17, 2007 10:09 pm Post subject: |
|
|
I just want to say you BIG THANX ;P you surely deserve it, __expr is so awesome thing... ( im used to double evaluation from other languages, and this is the last thing i missed in AHK )
Keep on working on this!!
EDIT:
i was wondering, if its possible to make something like "shell" in ahk script. I mean, i have some edit, i write here "msgbox hello world" and press RUN, and it run the script in editbox ( so script can run other scripts, it may be useful for some stuff like "plugins" and so on ). >< crazy idea but if its possible i can find use for it for sure
EDIT2: I've just checked the discussion closer and saw you already thought about something like that  _________________ RegExReplace("C:\Program Files\AutoHotkey", "(^C)(?=\W).{4}((?i)[GOD])\w{1,4}\s(\D)(?:\w+)*\\(?3)(u|o).*?(k).*" , "$3$4$l1$5$2") |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 2558 Location: Australia, Qld
|
Posted: Wed Dec 19, 2007 4:50 am Post subject: |
|
|
A preview of things to come:
| Code: | SetTimer, % CreateSub("func('timer1')"), 1000
sub2 := CreateSub("func(A_ThisHotkey)")
Hotkey, ^1, %sub2%
Hotkey, ^2, %sub2% |
...
And here it is.
| Code: | #NoTrayIcon
DllCall("AllocConsole")
LowLevel_init()
SetTimer, % CreateSub("func('timer1')"), 1000
sub2 := CreateSub("func(A_ThisHotkey)")
Hotkey, ^1, %sub2%
Hotkey, ^2, %sub2%
; gosub % sub3:=CreateSub("func('sub')")
; DeleteSub(sub)
; ListLines
; Pause
func(param)
{
FileAppend, %param%`n, CON
}
CreateSub(expr, name="", pScopeFunc=0)
{
if __findLabel(name)
return 0, ErrorLevel:="Label already exists."
if ! pArg := __MakeExpressionArg(expr, pScopeFunc)
return 0 ; ErrorLevel set by __MakeExpressionArg.
pSub := DllCall("GlobalAlloc","uint",0x40,"uint",80 + (name ? StrLen(name)+1 : 15))
if name =
name := pSub
DllCall("lstrcpy","uint",pSub+80,"str",name)
; Build expression line.
NumPut(pArg, NumPut(1, NumPut(3, pSub+16,0,"char"), 0,"char"), 2)
NumPut(pSub+48, NumPut(pSub+16, pSub+32))
; Build return line.
NumPut(102, pSub+48,0,"char")
NumPut(pSub+48, NumPut(pSub+16, pSub+64))
; Build label and insert into list.
pFirstLabel := __getFirstLabel()
NumPut(NumGet(pFirstLabel+12), NumPut(pFirstLabel, NumPut(pSub+16, NumPut(pSub+80, pSub+0))))
NumPut(pSub, NumGet(pFirstLabel+12)+8), NumPut(pSub, pFirstLabel+12)
return pSub
}
; For use ONLY with subs created by CreateSub.
DeleteSub(pSub) {
NumPut(NumGet(pSub+12), NumGet(pSub+8)+12) ; pSub->mPrevLabel->mNextLabel = pSub->mNextLabel;
NumPut(NumGet(pSub+8), NumGet(pSub+12)+8) ; pSub->mNextLabel->mPrevLabel = pSub->mPrevLabel;
DllCall("GlobalFree","uint",NumGet(pSub+20)), DllCall("GlobalFree","uint",pSub)
} |
I plan on adding full command-parsing before including CreateSub in LowLevel.
I'm still contemplating what to do about one major issue: ListLines.
ListLines is not safe to use after DeleteSub if the sub has executed, since it tries to display Lines that were deleted. It may crash AutoHotkey or display garbage like the following:
There is one way I know of to prevent this, but I don't like it...
An alternative I am considering is to maintain a "pool" of unused Line structures. Rather than deleting Lines, they would be "reclaimed" by the script and reused later. (Only the 32-byte Line structure needs to be persistent - the text, arg and deref structures may be deleted.)
Of course, once a Line is "reclaimed", ListLines won't be entirely accurate (since it will display a blank line.) If a Line is reused, ListLines may be confusing... |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|