AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

LowLevel & dynamic code
Goto page Previous  1, 2, 3, 4, 5  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
SKAN



Joined: 26 Dec 2005
Posts: 5880

PostPosted: Tue Dec 11, 2007 8:27 am    Post subject: Reply with quote

Thanks lexikos. Smile

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 ?!

Smile


Last edited by SKAN on Wed Dec 12, 2007 12:31 pm; edited 1 time in total
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Tue Dec 11, 2007 9:40 am    Post subject: Reply with quote

Can we delete variables, as currently that is not possible.
_________________
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Tue Dec 11, 2007 10:09 am    Post subject: Reply with quote

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
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5880

PostPosted: Tue Dec 11, 2007 10:39 am    Post subject: Reply with quote

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.


Shocked

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.

Smile
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Tue Dec 11, 2007 10:48 am    Post subject: Reply with quote

Well, that is clearly out of way SKAN ....

You should anylise composite storage for your thing. You can also use resources.
_________________
Back to top
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Tue Dec 11, 2007 11:46 am    Post subject: Reply with quote

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
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5880

PostPosted: Tue Dec 11, 2007 12:17 pm    Post subject: Reply with quote

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.

Smile


Last edited by SKAN on Wed Dec 12, 2007 12:34 pm; edited 2 times in total
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Wed Dec 12, 2007 7:36 am    Post subject: Reply with quote

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
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5880

PostPosted: Wed Dec 12, 2007 7:49 am    Post subject: Reply with quote

lexikos wrote:
I feel that any further discussion is off-topic...


I understand. Sad
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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Wed Dec 12, 2007 8:36 am    Post subject: something more on-topic Reply with quote

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. Smile
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5880

PostPosted: Wed Dec 12, 2007 12:45 pm    Post subject: Re: something more on-topic Reply with quote

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. Smile
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3626
Location: Belgrade

PostPosted: Wed Dec 12, 2007 1:15 pm    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Wed Dec 12, 2007 2:52 pm    Post subject: Reply with quote

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
View user's profile Send private message
Fuco



Joined: 21 Mar 2006
Posts: 49
Location: Slovakia, Europe :)

PostPosted: Mon Dec 17, 2007 10:09 pm    Post subject: Reply with quote

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 Very Happy

EDIT2: I've just checked the discussion closer and saw you already thought about something like that Razz
_________________
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
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 2558
Location: Australia, Qld

PostPosted: Wed Dec 19, 2007 4:50 am    Post subject: Reply with quote

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. Laughing
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...
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3, 4, 5  Next
Page 3 of 5

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group