AutoHotkey Community

It is currently May 26th, 2012, 12:45 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 173 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 12  Next
Author Message
 Post subject:
PostPosted: December 11th, 2007, 8:27 am 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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 December 12th, 2007, 12:31 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 9:40 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Can we delete variables, as currently that is not possible.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 10:09 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 10:39 am 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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.


:shock:

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.

:)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 10:48 am 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
Well, that is clearly out of way SKAN ....

You should anylise composite storage for your thing. You can also use resources.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 11:46 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 11th, 2007, 12:17 pm 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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 December 12th, 2007, 12:34 pm, edited 2 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 12th, 2007, 7:36 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
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...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 12th, 2007, 7:49 am 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject: something more on-topic
PostPosted: December 12th, 2007, 8:36 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
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. :)


Report this post
Top
 Profile  
Reply with quote  
PostPosted: December 12th, 2007, 12:45 pm 
Offline
User avatar

Joined: December 26th, 2005, 4:40 pm
Posts: 8775
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. :)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 12th, 2007, 1:15 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
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.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 12th, 2007, 2:52 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 17th, 2007, 10:09 pm 
Offline

Joined: March 21st, 2006, 8:31 pm
Posts: 49
Location: Slovakia, Europe :)
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 :D

EDIT2: I've just checked the discussion closer and saw you already thought about something like that :P

_________________
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")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: December 19th, 2007, 4:50 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7501
Location: Australia
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. :lol:
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:
Code:
000: ˜i% 

There is one way I know of to prevent this, but I don't like it...
Code:
Loop, 200
{}

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...


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 173 posts ]  Go to page Previous  1, 2, 3, 4, 5, 6 ... 12  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: Yahoo [Bot] and 69 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group