[OpenBIOS] [PATCH] Adds local variable support to OpenBIOS.
Programmingkid
programmingkidx at gmail.com
Tue Aug 28 01:23:47 CEST 2012
On Aug 27, 2012, at 4:44 PM, openbios-request at openbios.org wrote:
> Message: 4
> Date: Mon, 27 Aug 2012 22:35:40 +0200
> From: Segher Boessenkool <segher at kernel.crashing.org>
> To: The OpenBIOS Mailinglist <openbios at openbios.org>
> Subject: Re: [OpenBIOS] [PATCH] Adds local variable support to
> OpenBIOS.
> Message-ID: <F74BFA60-0824-49A9-B592-D6862E0ACFB7 at kernel.crashing.org>
> Content-Type: text/plain; charset=US-ASCII; delsp=yes; format=flowed
>
> Let me comment on the code, independently of if I think using local
> var names is a good idea at all.
>
>> + DEPTH 0= IF
>> + CR ." Please specify an array size." CR
>> + EXIT
>> + THEN
>
> You shouldn't blindly continue when you detect an error; use ABORT
> instead, or ABORT" since you want to print something.
Thanks for catching this. It has been corrected.
>
> Don't check stack depth, it is useless. It doesn't work when you
> forgot to pass a parameter but there is other stuff on the stack
> already (the common case). Your check also doesn't work if there
> is a negative number of parameters on the stack (the next most
> common case...)
>
> Just kill this part.
I don't think ignoring all possible error situations is better than handing a few of them.
>
>> + CREATE CELL * ALLOT \ creates and initializes the instance
>
> CELL * is CELLS (which is a standard Forth word, CELL is not).
Thanks for letting me know about CELL. I have changed them all to CELLS
>
>> + DEPTH 2 < IF
>> + CR ." Please specify an index number." CR
>> + drop \ removes the address of the array instance
>> + -1 throw \ stop normal execution after error
>> + THEN
>
> -1 THROW is ABORT
> Same thing here, just kill this code.
The error handling makes the word more user friendly. Having it fail and leaving the user clueless why doesn't sound right.
>
>> +; immediate
>
> Defining words should not be immediate in most cases, including here.
>
>> +\ Declare the local-base-address VALUE
>> +0 VALUE local-base-address
>> +
>> +\ returns the base address used for the local words
>> +: getBaseAddress ( - addr )
>> + local-base-address
>> +;
>
> : really-get-base-address getBaseAddress ;
> : really-really-get-base-address really-get-base-address ;
>
> And don't use CamelCase.
Is this some official naming convention, or your own taste?
>
>> +\ Sets the first local variable's value
>> +: Local0! ( x - )
>> + 0 CELL * getBaseAddress + !
>> +;
>
> You can do something smarter than this...
>
>> +\ Sets the twelfth local variable's value
>> +: Local11! ( x - )
>> + 11 CELL * getBaseAddress + !
>> +;
>
> ...why stop at 11?
As far as I know, Apple's code only uses two local variables at most. I figured 12 local variables per word should be enough.
>
>> +: calculateNeededMemory ( "char" - n )
>> + 0 TO variableCount
>> + >in @ \ keep track of where the pointer was
>> +
>> + begin
>> + parse-word
>> + 0= if \ if there is no more text to parse
>> + drop
>> + true
>> + else
>> + dup " ;" comp
>> + 0= if \ if the semicolon is encountered
>> + drop \ drop the duplicated address
>> + false
>> + else
>> + " }" comp
>> + 0= if \ if '}' character is encountered
>> + true \ end loop because '}' marks end of local variables
>> + else
>> + variableCount 1 + TO variableCount
>> + false
>> + then
>> + then
>> + then
>> + until
>> +
>> + >in ! \ reset the pointer
>> + variableCount CELL *
>> +;
>
> Factor this? You shouldn't ever use a variable that is used as a temp
> inside a word.
I'm not sure why you suggest this. It is just such a pain having to deal with the stack.
>
>> +: allocateMemory ( n - addr )
>> + alloc-mem dup 0= if
>> + drop
>> + cr cr 10 spaces abort" Failed to allocate memory for local
>> variables!" cr cr
>> + then
>> +;
>
> alloc-mem is way too slow to be used on every function call. Statically
> allocate a locals stack, or put it on an existing stack, or something
> like that.
I agree. That is why it is only used at compile time.
>
>> +\ Declares the size of the local variable table
>> +48 CONSTANT localTableSize
>> +
>> +\ Declare the local variable table
>> +localTableSize ARRAY localVariableTable
>
> You have 48 but can only access 12?
That is four fields per local variable: 48 / 4 = 12.
>
>> +: getLocalRecordCount
>> + arrayCount 4 /
>> +;
>
> Oh. Use a struct?
The little documentation on struct I found did not indicate it was a better replacement for Array.
>
> I'll stop here. There are two good ways to implement locals (or
> anything else, really): 1) Make it _simple_: you can do locals
> in about 20 or 30 lines of code. 60 is fine, too. 2) Make it
> efficient: don't allocate from a heap, don't run much code on
> the hot paths. This will be much smaller code as well, but
> perhaps trickier to understand.
What is a hot path?
>
> Segher
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.openbios.org/pipermail/openbios/attachments/20120827/45495747/attachment-0001.html>
More information about the OpenBIOS
mailing list