flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > eqtype. A bug or not a bug?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
Well. This topic is more for fun, than a bug report. However I assume, the author could consider some improvements to this directive's operation.

How good do you actually know fasm? Smile If you think, you're a fasm guru, try to predict (without compiling it!) the output of the following tests:
Code:
;Test 1
if not x eqtype rva near
     display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 2
if repeat '' eqtype times ''
  display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 3
if repeat + 5 eqtype times dword
  display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 4
if [+rva dword + x] eqtype ptr *
  display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 5
if [-rva dword + x] eqtype ptr *
  display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 6
if defined eqtype used
    display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 7
if err eqtype rb
  display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 8
if and eqtype neg
 display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 9
if and eqtype not
 display 'equals',13,10
else
    display 'differs',13,10
end if
;Test 10
if not eqtype and
        display 'equals',13,10
else
    display 'differs',13,10
end if    

You're welcome to test yourself by compiling the code and post your score here. Smile
Post 11 Feb 2012, 01:12
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17637
Location: In your JS exploiting you and your system
revolution
That last one was tricky to predict. I predicted "invalid expression" but I was wrong. Now I see why. Sneaky. Mr. Green
Post 11 Feb 2012, 01:58
View user's profile Send private message Visit poster's website Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 619
cod3b453
Most of this I've never even seen before Laughing Got 1 right plus 3 guesses, everything else wrong and also mostly guesses Embarassed
Post 11 Feb 2012, 08:40
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7782
Location: Kraków, Poland
Tomasz Grysztar
"eqtype" distinguises the types of lexical phrases as seen by parser. It means complete phrases, like numerical expression or address (you find the list here or in the manual. It will not work on the chunks of the expression - the "eqtype" operator may then not be recognized at all, as parser will try to interpret it as a missing part of the expression (since parser tries to complete the lexical phrase before it goes to another one). So if you try to apply "eqtype" to incomplete lexical phrases, the result is at least undefined. In the last one, for example, note that "not" in place other than instruction initial is interpreted as unary operator, so seeing "not" parser again tries to complete lexical phrase, eating "eqtype" in the way.

In general: avoid using "eqtype" with incomplete expressions, because such usage is incomplete from the language specification point of view and the result you get will be highly dependent on algorithms used by parser (and may even vary wildly from version to version). Using the "eqtype" in an undocumented way should be on your own risk.
Post 11 Feb 2012, 11:06
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
Tomasz Grysztar
Incomplete expressions should return an error like "expected expression". If you specify a subset of possible language constructions, then there should be an error when working with constructions outside of this subset. Why does "if repeat" (Tests 2 and 3) compile at all? "repeat" is here an unexpected token under any conditions.

Now to the tests with "not" (Tests 9 and 10). Your list specifies instruction mnemonics as comparable tokens. So I expect also "not" to be comparable. But here you treat "not" as a beginning of a numeric expression and at the same time "and" (which can also be a numeric expression part) as an instruction. If you say, that that's because "and" is invalid at the beginning of a numeric expression, than why even parenthesizing "not" does not allow it to be compared as an instruction mnemonic? "not" would be in the same way invalid at the end of a numeric expression. For this reason also 9 should either return an error ("expected expression") or treat "not" as an instruction mnemonic.

And the last comment to complete expressions. Tests 4 and 5 are not quite good examples, but their only difference should show, there's a flaw with unary operators. For example, "[+not x]" is not considered as a valid address expression (in this case at least comparing it should return an error), but "[-not x]" is a valid expression.
Post 11 Feb 2012, 13:08
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7782
Location: Kraków, Poland
Tomasz Grysztar
l_inc wrote:
If you specify a subset of possible language constructions, then there should be an error when working with constructions outside of this subset.
There is no such rule. If you use constructions whose behavior is not defined by specification, it is exactly as it is: undefined behavior.

l_inc wrote:
Why does "if repeat" (Tests 2 and 3) compile at all? "repeat" is here an unexpected token under any conditions.
Assembler directives count among the "instruction mnemonic" category, so it is valid to use them in "eqtype" expression. Perhaps the documentation is not specific enough here. You can even do "if if eqtype while" and it is valid.

l_inc wrote:
Now to the tests with "not" (Tests 9 and 10). Your list specifies instruction mnemonics as comparable tokens. So I expect also "not" to be comparable. But here you treat "not" as a beginning of a numeric expression and at the same time "and" (which can also be a numeric expression part) as an instruction. If you say, that that's because "and" is invalid at the beginning of a numeric expression, than why even parenthesizing "not" does not allow it to be compared as an instruction mnemonic? "not" would be in the same way invalid at the end of a numeric expression. For this reason also 9 should either return an error ("expected expression") or treat "not" as an instruction mnemonic.
I believe you answered your own question. "and" cannot occur at the beginning of a numeric expression, so when parser sees alone "and", it interprets it as instruction, while "not", even in parentheses, can start the numeric expression, and parser tries to get an expression if only it sees a chance. The ambiguity is a problem here - perhaps some special handling could be added to make parser more willing to see the instruction mnemonic if the expression seems obviously wrong - but I cannot promise anything.

l_inc wrote:
And the last comment to complete expressions. Tests 4 and 5 are not quite good examples, but their only difference should show, there's a flaw with unary operators. For example, "[+not x]" is not considered as a valid address expression (in this case at least comparing it should return an error), but "[-not x]" is a valid expression.
Yes, it seems that there is a bug, but it's not related to "eqtype" operation. For example "dq + not 1" should assemble, but it does not - I will look into it.
Post 11 Feb 2012, 15:49
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
Quote:
There is no such rule. If you use constructions whose behavior is not defined by specification, it is exactly as it is: undefined behavior.

That's a very comfortable viewpoint, but there is such rule. Otherwise any typo should result in undefined behaviour. E.g., unintentional miv eax,ebx and you get a sysenter instead. That would be a horrible language.
Quote:
Assembler directives count among the "instruction mnemonic" category, so it is valid to use them in "eqtype" expression.

Oh. Then it would be a problem to document, what "instruction mnemonics" can be compared with eqtype and what can not. That's cool I can do if if eqtype while, but why is this better, than if times eqtype while?
Quote:
Yes, it seems that there is a bug, but it's not related to "eqtype" operation.

It's not, but getting a compilation error is anyway better, than hours and days of debugging resulting from undefined behaviour which appears only in context of eqtype.

And I'd like to ask one more question about eqtype which is however a little bit offtopic. Are relocatable labels also of the same type as other numeric expressions? I assume, you say yes. But my humble opinion, they should be a separate type. Because otherwise we don't have any way in fasm to determine, whether a label (or a numeric constant or even an expression) is relocatable, and usage rules for relocatable expressions are a lot more restrictive, than for other numeric expressions. Well... I could show situations, where it's absolutely necessary to distinguish relocatable expressions.
Post 11 Feb 2012, 18:52
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7782
Location: Kraków, Poland
Tomasz Grysztar
l_inc wrote:
Quote:
There is no such rule. If you use constructions whose behavior is not defined by specification, it is exactly as it is: undefined behavior.

That's a very comfortable viewpoint, but there is such rule. Otherwise any typo should result in undefined behaviour. E.g., unintentional miv eax,ebx and you get a sysenter instead. That would be a horrible language.
It may be defined that if unknown instruction name is encountered, then the error will be signalized, or that if the label of data of inconsistent size is provided then the error will be signalized, those are very useful features (well, not all of them are documented in case of fasm, my fault - when you design language specification, such things should usually be defined precisely). But then if you use some construction whose meaning is not obvious from the specification, then the behavior is simply - undefined, undocumented, you cannot assume anything about it. This happens with specifications of many languages, there is nothing unusual about it.

And then there are also undocumented features, like "loadall286"/"loadall386" instructions in fasm. If we assumed than any construction that is not defined should signalize an error, the undocumented features would become the same as bugs. Which they are not.

l_inc wrote:
And I'd like to ask one more question about eqtype which is however a little bit offtopic. Are relocatable labels also of the same type as other numeric expressions? I assume, you say yes. But my humble opinion, they should be a separate type. Because otherwise we don't have any way in fasm to determine, whether a label (or a numeric constant or even an expression) is relocatable, and usage rules for relocatable expressions are a lot more restrictive, than for other numeric expressions. Well... I could show situations, where it's absolutely necessary to distinguish relocatable expressions.
The "eqtype" operates on parser level and parser does not yet know about relocatable labels, because they are lexically no different from other labels (it is only determined at assembly stage, and may even vary from pass to pass). So it is not possible to implement such test into "eqtype". But it is possible to add another logical expression operator for such purpose. Can you propose a name for it?
Post 11 Feb 2012, 19:01
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7782
Location: Kraków, Poland
Tomasz Grysztar
The "+ not x" bug has been fixed in 1.69.36 release.
Post 11 Feb 2012, 19:02
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
Quote:
This happens with specifications of many languages, there is nothing unusual about it.

You're right. But are you sure this should also be the case for the expressions compared with eqtype? Normally an invalid address expression or an incomplete expression results in an error in fasm, but not in case of eqtype.
Quote:
If we assumed than any construction that is not defined should signalize an error, the undocumented features would become the same as bugs.

Well. I don't think there is a clear difference between a bug and an undocumented feature. That's why we can very often hear (or say Smile) the statement "That's not a bug. That's a feature!"
Btw., I never heard about those instructions. Thank you for the information.
Quote:
But it is possible to add another logical expression operator for such purpose. Can you propose a name for it?

This is a fast decision. I hoped I'm wrong regarding the impossibility of determining whether a label is relocatable. A name? Like "defined" or "used" (well, rather like "defined" because it should accept expressions)? I'm not sure, I'm aware of name requirements. "relocatable" is probably too long. The shorter options could be "volatile" or "moveable". However it would be equivalent to check the opposite with a "fixed" directive. Anyway it's up to you to decide.

P.S. Btw., there were requests for directives, more important on my opinion. For example, a directive to specify the file and section alignment in a PE.

Quote:
The "+ not x" bug has been fixed in 1.69.36 release.

Oh. Thank you. That was quite fast.
Post 11 Feb 2012, 20:27
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
The use of "relocatable" should be avoided since it could be confused with "Could this address be relocatable if I wanted to?". "relocated", although not so nice would be a better candidate (e.g. "if relocated address").

Other ideas:
final: As in "the compile-time address is the final address used at run-time"
abs: Absolute address (in the sense of not relocated). But not a good option since it could be thought as "Which form this address is, [number], or [reg+offset]?".

fixed looks good and is the one I like the most, but I'm a little bit worried about how near to fix preprocessor directive is (or how could some people may attempt to test for fixed symbols ignoring that both belong to different stages and they don't know of each other).
Post 12 Feb 2012, 00:54
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7782
Location: Kraków, Poland
Tomasz Grysztar
LocoDelAssembly wrote:
fixed looks good and is the one I like the most, but I'm a little bit worried about how near to fix preprocessor directive is (or how could some people may attempt to test for fixed symbols ignoring that both belong to different stages and they don't know of each other).
So maybe something like "settled" or "established"?
Post 12 Feb 2012, 01:26
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17637
Location: In your JS exploiting you and your system
revolution
Options:

relative
relocatable
movable
changeable
alterable
variable
unknown
unknowable
unsure
uncertain
unfixed
liquid
malleable
updateable
notfinal
isrelative
isrva


I like the first one the best.
Post 12 Feb 2012, 01:37
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7782
Location: Kraków, Poland
Tomasz Grysztar
"relative" is nice, but there already is such named constant in GDI32.INC
Post 12 Feb 2012, 01:55
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17637
Location: In your JS exploiting you and your system
revolution
My second choice: isrva
Code:
if isRVA myAddress
  do something
else if not isRVA myAddress
  do something else
else
  WTF!
end if    
Post 12 Feb 2012, 03:17
View user's profile Send private message Visit poster's website Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4633
Location: Argentina
LocoDelAssembly
"relative" suffers of the same problems "abs" does. "isrva" may be confused as "Was the address passed to my macro of the form rva something?" Also, would this be the first time fasm introduces a keyword composed of more than one word?

Another one: definitive.

From revolution's list I like uncertain.

BTW, would be possible (and acceptable for the language) to introduce the "is" operator? I mean something that could let you do things like "if address is definitive", but with the possibility of extending it in the future to test for much more things (e.g. "if value is dword" to test if it the value fits in a dword, "if address is rel8" to test if value/address is rel8 encodable, "if value is float/double/extended", etc., etc., etc.).

PS: And after the keyword "is" it wouldn't be necessary to be followed by exactly a single symbol (but would be desirable that most of the attributes be a single symbol).
Post 12 Feb 2012, 05:27
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
LocoDelAssembly wrote:
fixed looks good and is the one I like the most, but I'm a little bit worried about how near to fix preprocessor directive is (or how could some people may attempt to test for fixed symbols ignoring that both belong to different stages and they don't know of each other).

Don't we have the same situation with "define" and "defined"?

Everything like "relative" or "isrva" has nothing to do with the actual meaning of relocatability. A relocatable address referred by the PE fixups directory is always absolute, not relative. Again the relative addresses never need fixups (e.g., "$-$$" is always a not-relocatable expression).

One more option is "stable". However I still prefer "fixed" (shorter, keeps the "-ed"-ending like the other directives of this type, and sounds similar to the related data identifier "fixups").
Post 12 Feb 2012, 12:40
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
Tomasz Grysztar
What about this example?
Code:
if : eqtype ''
     display 'equals',13,10
else
    display 'differs',13,10
end if
    

The colon is interpreted here as a label definition. Shouldn't if have more priority because it precedes the colon? For example, the documentation states, the colon is a comparable (with eqtype) symbol. But it seem, it can't be compared, if the colon is the second symbol on a line.

There's however a problem with inconsistent preprocessor behaviour, because fixing this would not prevent the preprocessor from trying to expand macros following the colon.
Post 12 Feb 2012, 18:48
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7782
Location: Kraków, Poland
Tomasz Grysztar
Yes, currently parser is consistent with preprocessor in that a symbol followed by colon in the initial position is always interpreted as label. You can override this problem with constructs like:
Code:
if <:> eqtype <''>    
Post 12 Feb 2012, 18:53
View user's profile Send private message Visit poster's website Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc
Tomasz Grysztar
Thank you. But that's not a problem to workaround the situation (e.g.,
Code:
if <: eqtype <''    
would also work). The actual question is, whether you think this behaviour is a flaw and whether you could decide to add special processing for this case.
Post 12 Feb 2012, 19:07
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.