<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr">Hi all!<div> I need some advice to solve a problem for the Live Typing functionality I'm working on (Live Typing, previously called Dynamic Type Information, saves the class of the object every time it is assigned to a variable, used as return/etc. That info is accesible from the image and helps having better tools. More info at: <a href="https://github.com/hernanwilkinson/Cuis-Smalltalk-DynamicTypeInformation">https://github.com/hernanwilkinson/Cuis-Smalltalk-DynamicTypeInformation</a></div><div>For the shake of simplicity I use class and type indistinctly)</div><div><br></div><div> The problem is related to saving the type of parameters and temporaries of closures (BlockClosure). Parameters and temporaries (locals from now on) of methods work well (with some minor issues not important now) </div><div> To save classes of method locals I added an array in AdditionalMethodState whose size is equals to locals size. Each element of that array points to another array that holds the classes of the objects assigned to a variable (the local var index is used as index in the first array).<br><div> Saving the types of closure's locals is not that simple, but I solved the "structural" part  adding a new indirection (as usual). So now AdditionalMethodState has an array whose size equals "1 + the number of closures the method has", that is one element per "closure". Each element of that array will point the array used to point the arrays of types per variable. I think an example will help:</div><div><br></div><div>m1: p1</div><div>   | t1 |</div><div><br></div><div>   t1 := 0.   "<-- it will save SmallInteger in (method additionalState contextTypesAt: 1) at: 2."</div><div>   [ | t2 | t2 := 'hello' ] value. "<-- it will save String in (method additionalState contextTypesAt: 2) at: 1"</div><div><br></div><div>   [ | t3 | t3 := 3.14 ] value. "<-- it will save Float in (method additionalState contextTypesAt: 3) at: 1"</div><div><br></div><div>As we can see, index 1 is used for the method's context when 0 is assigned to t1. Because it is the second local (the first one is p1), the index 2 is used to save the type of 0 (SmallInteger). </div><div> Index 2 is used when 'hello' is assigned to t2 because t2 is defined in the first closure. Because it is the first block local, index 1 is used to access t2 types array, and so on.</div><div><br></div><div> I did not mentioned it, but the problem resides in the fact that the same bytecode is used to assign an object to a var, no matter if it is inside a closure or not.</div><div> So the problem I have to solve is how can the bytecode's code know at witch context types array save the assigned object's class. That is, for the same bytecode, for example "<69> popIntoTemp: 1" I have to decide the array to use.</div><div> I hope I've been clear, it is a difficult to explain...</div><div><br></div><div> After a lot of ideas and possibilities, I found that the method/closure start pc could be use to decide the array's index to use (based on something similar to what CompiledMethod>>#startpcsToBlockExtents returns). </div><div> So, every time a new activation context is created (for example StackInterpreter>>#activateNewClosure:outer:method:numArgs:mayContextSwitch:, StackInterpreter>>#internalActivateNewMethod and so on) I can use the start pc to calculate the array's index.</div><div> So, let's say I have that solved too, now the problem is how can I access that index from the bytecode's code?. I have the following ideas:</div><div>1) Add an inst. var. to MethodContext that will have the index (or even better, the local's types array). So every time a new context is created, I calculate the index based on the PC and set that inst. var. </div><div>2) Do the same as in 1) but adding an inst. var. to BlockClosure (better than 1 because the closure is created once while the method context could be created more than once for the same closure)</div><div>3) Push the calculated index in the stack (as the IP, SP, etc. are pushed). Based on the num. args + num. temps., calculate the position in the stack of that index every time a type has to be saved.</div><div>4) Have an interpreter variable as 'method' but called, let's say, 'contextVarsTypes' that is set every time a new activation is created. The previous contextVarsTypes value is pushed in the stack and restore from it when exiting a context.</div><div><br></div><div>The problem with 1) and 2) is that MethodContext and BlockClosure can not be modified (at least not easily, a new image format would be needed, etc), but the advantage is that I don't have to worry about that value when a context is leaved. </div><div>Between 3) and 4) and think 4) is faster but I'm not sure that if a GC is executed and the array moved (let's say contextVarsTypes points directly to the types array), that contextVarsTypes will point to the new arrays position in memory (will that happen? how is 'method' changed if a GC is executed?)</div><div><br></div><div>Which one do you think is better/faster/possible?</div><div>Any advice/comment on this matter will be appreciated. </div><div>If there is an easier/different way to solve this problem, please help me :-)</div><div><br></div><div>Thanks!</div><div>Hernan </div><div><br></div><div><br></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><span style="font-family:tahoma,sans-serif;font-size:xx-small;border-collapse:collapse"><strong><span style="font-size:8pt"><span><span style="font-size:small"><font size="2"><span style="font-weight:normal"><span style="font-weight:bold">Hernán Wilkinson</span><br>Agile Software Development, Teaching & Coaching</span></font></span></span></span></strong></span></div><div><span style="font-family:tahoma,sans-serif;font-size:xx-small;border-collapse:collapse"><strong><span style="font-size:8pt"><span><span style="font-size:small"><font size="2"><span style="font-weight:normal">Phone: +54-011</span></font></span></span></span></strong></span><font face="tahoma, sans-serif" size="2">-4893-2057</font></div><div><strong style="font-family:tahoma,sans-serif;font-size:xx-small"><span style="font-size:8pt"><span style="font-size:small"><font size="2"><span style="font-weight:normal">Twitter: @HernanWilkinson</span></font></span></span></strong></div><div><span style="font-family:tahoma,sans-serif;font-size:xx-small;border-collapse:collapse"><strong><span style="font-size:8pt"><span><span style="font-size:small"><font size="2"><span style="font-weight:normal">site: <a href="http://www.10pines.com/" style="color:rgb(17,65,112)" target="_blank">http://www.10Pines.com</a></span></font></span></span></span></strong></span></div><div><font face="tahoma, sans-serif"><span style="border-collapse:collapse">Address: Alem 896</span></font>, Floor 6, Buenos Aires, Argentina</div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div></div>