Just wanted to point out, that although frowned upon, Java still allows
free interpretation/modification of the (typically 4K) memory page under
control by the JVM. I.e. if you declare a "uniony type" via an array:
byte[] a = new byte[] {1, 2, 3, 4, 5, 6, 7, 8};
...and enter the realm of java.util.Unsafe:
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe $ = (Unsafe) field.get(null);
...one may interpret individual bytes without any bounds check:
long offset = $.arrayBaseOffset(byte[].class);
out.println( $.getByte(a, offset) ); // 1
out.println( $.getByte(a, offset + 1) ); // 2
out.println( $.getByte(a, offset + 2) ); // 3
out.println( $.getByte(a, offset + 3) ); // 4
out.println( $.getByte(a, offset + 4) ); // 5
out.println( $.getByte(a, offset + 5) ); // 6
out.println( $.getByte(a, offset + 6) ); // 7
out.println( $.getByte(a, offset + 7) ); // 8
...or as 4 Bahama shorts:
out.println( $.getShort(a, offset) ); // 513
out.println( $.getShort(a, offset + 2) ); // 1027
out.println( $.getShort(a, offset + 4) ); // 1541
out.println( $.getShort(a, offset + 6) ); // 2055
...or 2 integers:
out.println( $.getInt(a, offset) ); // 67305985
out.println( $.getInt(a, offset + 4) ); // 134678021
...or 1 long:
System.out.println( $.getLong(a, offset) ); // 578437695752307201
So although Sun made it very hard to escape the playpen, it is possible and
indeed NIO's DirectByteBuffer etc. takes advantage of this. It's also
possible to step beyond a types memory and access memory belonging to
another type, although this feels safer to do on the stack than on the heap.
On Wednesday, October 31, 2012 3:25:40 AM UTC+1, Cédric Beust ♔ wrote:
>
> Bouncing off another topic mentioned in the latest podcast: union types.
> Yes, C had them but the first time I was exposed to them was in Pascal, and
> the discussion on the podcast reminded me of an awesome hack that blew my
> mind a very long time ago.
>
> Pascal was well known to be very strict and safe. Among other things, it
> didn't let you access the memory directly, which was a big deal in the 8
> bit era where memory protection was a distant dream and PEEK and POKE were
> how you wrote games.
>
> And then, one day, somebody found a way to address the memory using
> standard Pascal. Here is the trick (from memory, so it's probably not quite
> correct):
>
> type
> b = record
> x : array[1..65536] of ^integer;
> y : integer;
> end;
>
> This declares a union type that is made of either an array of 65k pointers
> to integers or a single integer. Then you initialize this record in its "x"
> side with the memory address you want to peek and you access it by using
> the "x" side of the record.
>
> It took me months to understand what this code did, but what a revelation
> it was when it finally clicked...
>
> By the way, these types are formally known as "sum types" (Either is one
> of them).
>
> --
> Cédric
>
>
>
--
You received this message because you are subscribed to the Google Groups "Java
Posse" group.
To view this discussion on the web visit
https://groups.google.com/d/msg/javaposse/-/1YN7LvLYuGsJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/javaposse?hl=en.