rastroobossc@violet.waterloo.edu (Rick Stroobosscher) (11/23/87)
I am currently developing a run-time memory manager for the Action programming language. This run-time manager will serve two functions. First, it will allow for dynamic memory allocation and disposal. The function New () takes as input the size of a requested block and returns an address to this block. The procedure Dispose takes as input the address of a block and returns it to the internal heap. Second, the memory manager will allow the user to call procs and funcs recursively. This is accomplished by pushing parameters and local variables onto the internal stack via the procedures PushStack () and ShoveStack (). Similiarly, the user can pop items off the stack with the function PopStack () and procedure HeaveStack (). If you are interested in using some of these programming aids, feel free to contact me via the net or via electronic mail. Lastly, I have one question for you knowledgeable Action! programmers. While developing this run-time manager, I have frequently used TYPEs and POINTERs to records of TYPEs. I have found a error in the way Action! compiles code with respect to record TYPEs. At least I think that it does, on my cartridge at least. Let me provide an example, and then I will explain how Action! compiles this. MODULE TYPE BlockNode=[CARD data CARD next] BlockNode POINTER FrontNode DEFINE True="1" DEFINE Nil="$FFFF" PROC Test () BlockNode POINTER CurrNode CurrNode=FrontNode WHILE CurrNode <> NIL DO IF CurrNode.data = PrevNode.data THEN RETURN (True) ELSE CurrNode=CurrNode.next FI OD RETURN The problem lies in the execution of the statements after the ELSE clause. I have reviewed the object code that the Action! compiler produces and have discovered these things. Action! accesses fields of records by using indirect indexed addressing, ie. (addr),Y. As it compiles the IF clause it produces code that uses indirect indexed addressing to retrieve the values for CurrNode.data and PrevNode.data. This code includes LDY #1 and DEY, since the data field in the record is located in two bytes, that are offset by 0 and 1 respectively from the start of the record. That's easy you say, and I agree, but the problem occurs when Action! compiles the line, CurrNode=CurrNode.next. In an attempt to optimize the code, the object code produced does not explicitly LDY #3 and DEY to access the next field. Rather, it expects the code produced by the IF clause to have set the Y register to 1, and simply INYs the Y-register. However, the IF clause does not leave the Y register as 1, but as 0, and then when trying to access the next field in CurrNode.next, we access 1 byte away from it, which really screws up tree traversals and linked list traversals. So far, I have been fixing this by including explicit LDY #1 [$A0 $01] instructiions in my code. But I am wondering, has anyone else had this problem, or can they verify it on their cartidges? Thanks for your time, if my essay has been too confusing, reply and ask more questions. If the above example I gave does work, (it shouldn't) I will post the original problem from my micro (when I get a modem for Christmas) including the source code and object code in assembly language form. Rick Stroobosscher University of Waterloo
john1233@csd4.milw.wisc.edu (Thomas M Johnson) (11/24/87)
In article <4204@watdragon.waterloo.edu> rastroobossc@violet.waterloo.edu (Rick Stroobosscher) writes: > > I am currently developing a run-time memory manager for the Action >programming language. This run-time manager will serve two functions. >First, it will allow for dynamic memory allocation and disposal. The function >New () takes as input the size of a requested block and returns an address >to this block. The procedure Dispose takes as input the address of a block >and returns it to the internal heap. The Action! toolkit contains an include file called ALLOCATE.ACT and it allows dynamic memory usage. I don't know if it is as nice as yours though, I never tried using it. Tom