Javatrans - Java bytecode to other languages - notes

Chris Greenhalgh, 2006-02-06, last updated 2006-08-04


Some of my own think-aloud implementation/design notes... at your own risk.


C++ general

C++ arrays do have an intrinsic length, c.f. Java. Options:
So, i'll need to autogenerate or have template-based array classes, which extend java.lang.Object equivalent.


Java byte code creates a new initialised object in memory separately from calling the constructor. This can be compared with Symbian's 2-phase construction. Why not?!


In the initial prototype i just used "char*" but this would require proper heap-sweeping GC, since java strings are immutable and so get copied all over the place...

so now i have put in a java_lang_String replacement.

Also, what about unicode?!

Garbage collection

Of course, Java (and C#) has it. As does managed C++, but not symbian or ansi c++.
I coud use someones cunning GC library, but i'm not sure this will work well/at all on a phone.
so for now i will do simple reference counting GC on java_lang_Object...
Like COM IUnknown AddRef():int & Release():int



MSVC++ has support for ANSI exceptions, which are rather similar to Java exceptions:
try {
throw <somevalue>;
catch ( <sometype> [<var>] ) {
/* ... */
catch ( ... ) {
/* any exception */
Optionally a function may declare that it throws exceptions:
void func() throw(...) { /* ... */ }

Note that catch variable is assigned by copy.

Catching an exception in a constructor assignment requires special syntax:

C::C(int ii)
try   // function-try block
: i(f(ii))
{   /* body of function goes in try block */ }
catch (...) {
/* any exception incl. constructor initializer */

Destructors of stack variables in the completed try scope are called when an exception is thrown.


Symbian C++ has a non-standard exception mechanism, presumably based directly on longjmp.
The analog of throw is User::Leave(TInt reason).
The analog of try is the TRAP or TRAPD (TRAP/Declare) macros (here from series 60 fp2):
TRAP(_r,_s) {TTrap __t;if (__t.Trap(_r)==0){_s;TTrap::UnTrap();}}
TRAPD(_r,_s) TInt _r;{TTrap __t;if (__t.Trap(_r)==0){_s;TTrap::UnTrap();}}

_r is the TInt-typed variable which will receive the Leave reason value, _s is the C++ statement to be executed as the try body.

Exception handling is performed by subsequent testing of the _r variable.

I don't think that destructors of stack variables are called, but the current thread cleanup stack is unwound to the point at which the TRAP harness was entered.

The cleanup stack is access via the CleanupStack class, and has operations:

static void PushL(TAny* aPtr); // freed by User::free 
static void PushL(CBase* aPtr); // freed by delete - has virtual destructor
static void PushL(TCleanupItem anItem); // freed by calling
// typedef void (*TCleanupOperation)(TAny*);
static void Pop();
static void Pop(TInt aCount); // aCount items
static void Pop(TAny* aExpectedItem); // panic if top doesn't match in debug build
static void Pop(TInt aCount, TAny* aLastExpectedItem); // panic if aCount-1 item doesn't match in debug build
static void PopAndDestroy();
static void PopAndDestroy(TInt aCount);
static void PopAndDestroy(TAny* aExpectedItem);
static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem);
static void Check(TAny* aExpectedItem); // else panic

Symbian also has thread panics which are comparable to a number of Java VM exceptions, but I don't think these are trappable in any way.

Symbian semantics using ANSI exceptions

Could be achieved by code of the form:
int _r;
try {
} catch (int ex) {
_r = ex;
to implement TRAPD, where 'User::Leave(val)' maps to 'throw val'.


Java uses the Exceptions attribute of the class file method_info structure to describe which exceptions are declared to be thrown by a method.

Java uses the exception_table of the Code attribute to describe the try/catch organisation of the code, specifying a table of start_pc (inclusive) to end_pc (exclusive) of the try scope, handler_pc of the catch code, and the catch_type, where 0 is any exception, else index of exception CONSTANT_Class_info in the constant pool.

Strictly there is nothing to stop exception scopes being overlapping, etc. But presumably most simple compilers will directly reflect the nested structure of the source program.


Change log