July 2000 Draft
JavaScript 2.0
Libraries
Machine Types
previousupnext

Wednesday, February 16, 2000

Purpose

The machine types library is an optional library that provides additional low-level types for use in JavaScript 2.0 programs. On implementations that support this library, these types provide faster, Java-style integer operations that are useful for communicating between JavaScript 2.0 and other programming languages and for performance-critical code. These types are not intended to replace Number and Integer for general-purpose scripting.

Contents

When the machine types library is imported via an import of MachineTypes version 1, the following types become available:

Type

Unit 

Values

byte B Machine integers between -128 and 127 inclusive
ubyte UB Machine integers between 0 and 255 inclusive
short S Machine integers between -32768 and 32767 inclusive
ushort  US Machine integers between 0 and 65535 inclusive
int I Machine integers between -2147483648 and 2147483647 inclusive
uint UI Machine integers between 0 and 4294967295 inclusive
long L Machine integers between -9223372036854775808 and 9223372036854775807 inclusive
ulong UL Machine integers between 0 and 18446744073709551615 inclusive
float F Single-precision IEEE floating-point numbers, including positive and negative zeroes, infinities, and NaN

Values belonging to the nine machine types above are distinct from each other and from values of type integer. A literal may be written by using one of the units provided: 7B is the same as byte(7), which is distinct from 7I, which in turn is distinct from the plain integer 7. A float NaN is distinct from the regular Number NaN. However, the coercions listed below often hide these distinctions.

No subtype relations hold between the machine types.

The above type names are not reserved words.

The units are defined using the standard unit facility. They may be overridden by the user.

Coercions

The following coercions take place:

Casts

The following casts can be used:

Of course, any coercion can also be used as a cast.

Operations

When applied to a value with machine type M, the unary negation operator - always returns a value of the same type M. If the result is not within range of type M, it is treated modulo |M|.

Machine integers support the binary arithmetic operators +, -, *, /, % and bitwise logical operations ~, &, |, ^. If supplied two operands of different machine integer types M1 and M2, all of these binary operators first coerce both operands to the same type M. If M1 appears before M2 in the list byte, ubyte, short, ushort, int, uint, long, ulong, then M is M2; otherwise M is M1. Then these operators perform the operation and finally return the result as a value of type M. If the result is not within range of the target type M, it is treated modulo |M|.

If one of the operands of +, -, *, /, % is a machine integer m of type M and the other is a Number or float value, then m is first coerced to type Number or float. Next, if both operands are floats, then the result is a float; otherwise the result is a Number.

Machine integers also support bitwise shifts <<, >>, and >>>. The result has the same as the first operand. The second operand's type can be Number or any machine type and does not affect the type of the result. Right shifts using >> are signed if the first operand has type byte, short, int, or long, and unsigned if it has type ubyte, ushort, uint, or ulong. Right shifts using >>> are always unsigned.

If passed a float argument, the bitwise logical operations ~, &, |, ^ first coerce the float to a Number. If passed a float as the first argument, the bitwise shifts <<, >>, >>> first coerce the float to a Number.

The comparison operators ==, !=, <, >, <=, => allow any combination of machine type or Number operands. They always compare the exact mathematical values without first converting one operand's type to the other's. Comparisons involving NaNs are always false, and positive and negative zeros compare equal.

The identity comparisons === and !== treat all nine machine type values as disjoint from each other and from regular Number values. Thus, 7B !== 7.

The unary operator !v behaves the same as v!=0 when v has any machine type.

Discussion

These rules are designed to permit machine integer operations to be implemented as single instructions on most processor architectures yet give predictable results. Overflows wrap around instead of signaling errors because such behavior is useful for many bit-manipulation algorithms and permits much better optimization of performance-critical code. Code that is concerned about overflows should be using regular Integer instead of the machine integer types.

Disjointness of Machine Types

Why are values of the eight machine integer types distinct? This was done because of a desire to allow arithmetic operators to only support 32 bits when operating on int values. Let's take a look at the alternative:

Suppose we unify the values of all eight machine types so that 2000000000I is indistinguishable from 2000000000L. To what precision should an operator like + calculate its results? Clearly, if we're adding two long values and the result is within the range of long values, then we'd expect to get the right result. In particular, 2000000000L + 2000000000L should yield 4000000000L. However, we assumed that 2000000000L is indistinguishable from 2000000000I, so 2000000000I + 2000000000I should also yield 4000000000L, which is not representable as an int value. Thus, even if both operands are known to be int values, the + operator has to use 64-bit arithmetic.

If a has type int and we compute a+1I, then we have to use 64-bit arithmetic because the result could be 2147483648. However, if we compute var r:int = a+1I instead, then a smart compiler could make do with 32-bit arithmetic because the result is treated modulo 232. However, this trick would not work with an expression such as if (a+1I > 0).

The alternative is viable but it leads to more demand for 64-bit arithmetic. It does have the advantage that one does not need to worry about intermediate overflows as long as the values don't approach 264.


Waldemar Horwat
Last modified Wednesday, February 16, 2000
previousupnext