KTF (Korea Telecom Freetel) is a carrier, and KTF devices shipped with their own WIPI implementation.
A KTF app consists of:
- A JAR containing:
client.bin{bss_size}— a raw ARM binary with all AOT-compiled Java classes- App resources
- An ADF file (separate from the JAR) — app descriptor (AID, PID, MClass)
There are no .class files in the JAR. All Java classes are AOT-compiled and exist only inside client.bin as ARM code + metadata.
Java source is compiled to bytecode, then AOT-compiled into ARM native code by the KTF toolchain. The resulting client.bin contains:
- AOT-compiled method bodies (ARM machine code)
- Java class/method metadata structures (platform-specific binary format)
Both pure Java apps and Clets (C native apps) share the same binary format. Clets are Java apps that call C native functions through JNI — the native code is included in the same client.bin.
The platform provides two kinds of integration points to the app binary during initialization:
Passed directly as function pointers for operations such as:
- throwing a Java exception
- allocating Java objects and arrays
- loading Java classes by name
- checking type relationships
- obtaining additional interface tables
- allocating memory
Obtained through the platform's interface lookup. This table provides helpers for:
- calling Java methods from AOT-generated ARM code
- calling JNI native methods
- resolving methods by class and signature
- registering classes with the runtime
- registering Java string constants
Obtained through the same interface lookup mechanism. This is the KTF-side WIPI C surface providing kernel, graphics, database, input, and timer functions.
- Platform loads
client.bininto memory - Calls the binary's entrypoint with the BSS size and gets back a top-level executable descriptor
- Calls the executable's initialization function with a set of platform-owned context blocks, including:
- exception handling state
- JVM context storage
- primitive type descriptors
- Java support callbacks (see above)
- Calls the app-level initialization function
- Calls
Main.main()to start the app
AOT-compiled methods live in the ARM binary. When one method calls another:
- The caller uses a platform-provided Java-call trampoline with the target method address and arguments
- The trampoline calls the target method in a new execution frame
- The target method runs as ARM code and returns its result
For JNI native methods, a separate native-call trampoline is used instead, passing arguments through a data pointer.
KTF uses a setjmp/longjmp mechanism:
- Each try block saves registers (r4-lr) into an exception handler record
- The
current_java_exception_handlerpointer in the exception context tracks the active handler - On exception, the runtime restores the saved registers and jumps to the catch target
- ARM execution:
wie_core_arm::ArmCoreemulates ARM instructions. Rust callbacks are registered at sentinel addresses; when the ARM engine hits one, therun_functionloop dispatches to Rust. - JVM:
KtfJvmImplementationreads class/method metadata directly from ARM memory. The Rust JVM delegates to ARM code for AOT-compiled method bodies viacore.run_function(). - Class loading:
KtfClassLoadercalls the nativefn_get_classto discover classes defined in the ARM binary. - Trampolines:
java_jump_1/2/3andcall_nativeeach callcore.run_function(), creating nested execution frames. - Exception unwind: When
handle_exceptionfinds a catch handler, it returnsWieError::JavaExceptionUnwindinstead of a normal result. This error propagates through nestedrun_functionframes (skipping their context restore), and the trampoline converts it back into aJavaMethodResultthat resumes execution through the restore helper.