[Vm-dev] bitten by & and |

Nicolas Cellier nicolas.cellier.aka.nice at gmail.com
Tue Jan 11 21:11:37 UTC 2011


2011/1/11 Igor Stasenko <siguctua at gmail.com>:
>
> On 11 January 2011 21:15, Andreas Raab <andreas.raab at gmx.de> wrote:
>>
>> I would vote for option
>>
>> d) Disallow it altogether since it's completely ambiguous and *require* the
>> use of #or:/bitOr: or #and:/bitAnd:. I.e.,
>>
>> CCodeGenerator>>generateAmbigousOr: msgNode on: aStream indent: level
>>
>>        self error: 'Usage of | is ambiguous - use #or: or #bitOr: instead'.
>>
>> There are only a handful of uses that need to be fixed and the above would
>> find them very quickly.
>>
>
> +1
>
> rather than trying to find less painful workaround, it is better to
> simply bark at each use of it,
> and don't generate code until all uses of it will be examined and
> replaced with aproppriate or/bitOr/and/bitAnd
>
> Also, for clarity i would even introduce
>
> #define bitAnd(x,y)  ((x) & (y))
> #define and(x,y)  ((x) && (y))
> #define or(x,y)  ((x) || (y))
> #define bitOr(x,y)  ((x) | (y))
>
> and let generate to use these macros instead of &&/&/|/|| . So,in this
> way, C code could be more readable :)
>

With differences in signed/unsigned promotion to a longer int, I don't
think you'll ever get a readable C ;).

Nicolas

>
>> Cheers,
>>  - Andreas
>>
>>
>> On 1/11/2011 12:00 PM, Eliot Miranda wrote:
>>>
>>>
>>>
>>>
>>> Hi All,
>>>
>>>     I just got bittenhard (not for the first time) by & and |
>>> (implemented both by integers and booleans) being translated into && (==
>>> and:) and || (== or:).  So the following in constant folding in the
>>> StackToRegisterMappingCogit
>>>
>>> (argIsInt and: [rcvrIsInt]) ifTrue:
>>> [rcvrInt := objectMemory integerValueOf: rcvrInt.
>>> argInt := objectMemory integerValueOf: argInt.
>>> primDescriptor opcode caseOf: {
>>> [AddRR]-> [result := rcvrInt + argInt].
>>> [SubRR]-> [result := rcvrInt - argInt].
>>> [AndRR]-> [result := rcvrInt &: argInt].
>>> [OrRR]-> [result := rcvrInt | argInt] }.
>>> (objectMemory isIntegerValue: result) ifTrue:
>>> ["Must annotate the bytecode for correct pc mapping."
>>> self annotateBytecode: self Label.
>>> ^self ssPop: 2; ssPushConstant: (objectMemory integerObjectOf: result)].
>>> ^self genSpecialSelectorSend].
>>>
>>> produced valid results in the simulator, but was translated to
>>>
>>>     if (argIsInt
>>> && (rcvrIsInt)) {
>>>         rcvrInt = (rcvrInt >> 1);
>>>         argInt = (argInt >> 1);
>>>
>>>         switch ((primDescriptor->opcode)) {
>>>         case AddRR:
>>>                         result = rcvrInt + argInt;
>>>             break;
>>>         case SubRR:
>>>                         result = rcvrInt - argInt;
>>>             break;
>>>         case AndRR:
>>>                         result = rcvrInt && argInt;
>>>             break;
>>>         case OrRR:
>>>                         result = rcvrInt || argInt;
>>>             break;
>>>         default:
>>>             error("Case not found and no otherwise clause");
>>>         }
>>>         if (isIntegerValue(result)) {
>>>             annotateBytecode(gLabel());
>>>             return ssPop(2),ssPushConstant(((result << 1) | 1));
>>>         }
>>>         return genSpecialSelectorSend();
>>>     }
>>>
>>> and so e.g. 16r4000 bitOr: 16r8000 evaluated to 1, not 49152.
>>>
>>> Three approaches come to mind,
>>> a) emit a warning when & and | are used with variables and/or literals
>>> as opposed to message sends, e.g. warn for 1 | 2, var | var et al, but
>>> not for (a > b) | (b > c) et al
>>> b) translate | to | and & to &
>>> c) translate expr | expr to expr || expr and expr & expr to expr &&
>>> expr, but translate varOrLiteral | anything to varOrLiteral | anything
>>> and varOrLiteral & anything to varOrLiteral & anything, and vice verse.
>>>
>>> I'm for b) since a relational expression such as a > 1 is defined in C
>>> to be either 1 or 0, and so in C (oneOrZero | oneOrZero) == (oneOrZero
>>> || oneOrZero) and (oneOrZero & oneOrZero) == (oneOrZero && oneOrZero).
>>>
>>> Thoughts, opinions?
>>>
>>> best (hurting),
>>> Eliot
>>
>
>
>
> --
> Best regards,
> Igor Stasenko AKA sig.
>


More information about the Vm-dev mailing list