Few cents about my commits

iOS13 PostFix #9: experimental and formal bitcode support

|

Bitcode was considered as big question once Apple introduced support for it. Mostly it was seen as danger for RoboVM project as Apple might use it as a blocking requirement and not allow application to be submitted without bitcode. While today lot of people think bitcode is not deliver significant benefits (if apple re-compiles apps on own servers) having it might be good idea due:

  • developers need it due fear;
  • it is required when producing Framework target with RoboVM and including framework in bitcode-enabled project;
  • it was a part of commercial RoboVm 1.14 compier.

How support works

There is nice post Embedded Bitcode by Jonas Delieghere that covers basics. In case of RoboVM getting bitcode is not big deal as its an optimized form of LLVM IR that RoboVM compiler produces while building native code. The question is how to get it emited to object file. From post there are two option to mark object file as having bitcode:

  • Full support: a section __LLVM, __bitcode for storing the (optimized) bitcode. This is plain, binary bitcode, not wrapped in an archive as there’s only one file for each object;
  • Formal support: an empty section __LLVM, __asm to differentiate objects without bitcode from those built from assembly.

This post fix implemented formal support due following moment:

  • to add bitcode as section to obj file would require implementing functionality similar to clang’s -fembed-bitcode as LLVM either produces bitcode, object or assemble file;
  • RoboVM compiler does produce object file from assember file (it produces it from LLVM IR to hack method size fields in info object);
  • genereting bitcode and allowing Apple to re-compile app will break line number and method information. As it being received from DWARF debug one, once recompiled by apple – offsets might not match anymore. And it would require to disable line number information in stack traces.

What was done

  • native libraries were re-compiled with -fembed-bitcode flags;
  • each object file generated from Java class now gets __LLVM, __asm section;
  • linker is being instructed to use -fembed-bitcode;
  • as runtime libraries are huge now due included bitcode – it being stripped of if not enabled to minimize debug footprint;

How to use

Bitcode support can be enabled:

  • in robovm.xml with <enableBitcode>true</enableBitcode>;
  • in robovm setion of build.gradle with enableBitcode = true;
  • in enableBitcode parameter to maven plugin;

Code is delivered as PR443

Other postfixes:

iOS13 PostFix #8: workaround for missing objc classes(ObjCClassNotFoundException)

|

Apple altogether with introducing new APIs also keeps refactoring existing one. In this case it results in part of API being extracted from class and moved to newly introduced class. And this class is being used as new super. Result class will have schema when super class introduced later than child. This makes problem when running code on iOS older than super was introduced. Bright example:

// since ios 4.1
@interface GKPlayer : GKBasePlayer

// but

// since ios 10.0
@interface GKBasePlayer : NSObject

Root case

iOS13 PostFix #7: bindings for ios13.2

|

This post continues the series of fixes discovered during compilation of CocoaTouch library and improvements to compiler.

PostFix #7: iOS 13.2 bindings

While things being fixes iOS 13.2 is already in wild. This postfix delivers:

  • changes to support new api;
  • fixes in javadoc;
  • fixes to structures that have to be annotated as packed.

Code is delivered as PR441

Other postfixes:

iOS13 PostFix #6: Fixes to Network framework bindings

|

This post continues the series of fixes discovered during compilation of CocoaTouch library and improvements to compiler.

PostFix #6: Fixes to Network framework bindings

As metntioned in gitter channel a try to use NWPathMonitor fails with ObjCClassNotFoundException: OS_nw_path_monitor. The binding of Network framework differs from common approach in way it is completely functional interface. Most of API might be simply grouped into two groups:

  • creators: CLASS INST = function_Create()
  • usage: function_Usage(CLASS INST, other params) RoboVM bro compiler allow to use such functions as class memebers, e.g.:
    function_Usage(CLASS INST, other params)
    to
    class CLASS {
      @Bridge
      function_Usage( other params)
    }
    

Same time bro-gen extracts types defined in framework as protocols (like NWPathMonitor is defined as OS_nw_path_monitor) and closes binding for it is a NativeProtocolProxy. Which shall work in general case but not this.

RoboVM 2.3.8 released, what's new

|

What’s new

  • [fixed] #408 Cannot compile AUMIDIEvent;
  • [fixed] #414 Deployment to ios13 device, updated libimobiledevice lib’s bindings;
  • [fixed] swiched to simctl to support Xcode11 simulator PR#410;
  • [improvement] kotlin improvements: debugger and compilation PR#349
  • [fixed] #387 CGBitmapContext.create fails on real device for big sizes;
  • [added] support for packed structures PR#378;
  • [fixed] Broken enum marshallers cleanup PR#377;
  • [fixed] Debugger crashed when native thread exited while paused on breakpoint PR#384;

What’s in progress

Meanwhile work in progress happening in support for JDK12 tools on host branch, it contains following changes:

  • all builds scripts reworked to allow building RoboVM using JDK9+ (works with JDK13) PR#400;
  • ios13 bindings PR#406;
  • Idea plugin workaround for long-going android gradle faset #242, PR#401;
  • On-going series of Cocoa13-postfixes

Happy coding!
Please report any issue to tracker.

iOS13 PostFix #5: implementation of missing Struct.offsetOf

|

This post continues the series of fixes discovered during compilation of CocoaTouch library and improvements to compiler.

PostFix #5: Struct.offsetOf always returns zero

Other postfixes:

Struct.offsetOf is required to proper implement initialization of variable size structs with flexible array member such as:

struct vectord {
    size_t len;
    double arr[]; // the flexible array member must be last
};

Root case and fix

Struct has offsetOf definition and it returns always zero similar to sizeOf method. `` its implemenation is being synthesized by RoboVM compiler and invocation of sizeOf being fixed during trampoline phase from Struct.sizeOf to DestStruct.sizeOf (DestStruct – an example struct implementation). Root case – compiler doesn’t not synthesize offsetOf.

AltPods: pods updated - 1.4.0-SNAPSHOT

|

AltPods were update to v1.4.0-SNAPSHOTS to sync with recent releases. Part of list didn’t receive any API update hovewer bindings were re-generated against recent version of frameworks. Update list look as bellow:

Updated pod

Unchanged pod

These pods were pushed to https://oss.sonatype.org/content/repositories/snapshots maven repo under 1.4.0-SNAPSHOTS version.
Source code @github

Updates are not fullty tested, please open issue if bug found.

NB: AltPods – are robopods kept at my personal standalone repo. This is done to prevent main robopods repo from turning into code graveyard. As these pods have low interest of community and low chances to be updated.

iOS13 PostFix #4: Compilation failed on @Bridge annotate covariant return synthetic method

|

This post continues the series of fixes discovered during compilation of CocoaTouch library.

PostFix #4: @Bridge annotated covatiant return bridget methods

Other postfixes:

Issue was discovered while compiling NWTxtRecord:

java.lang.IllegalArgumentException: @Bridge annotated method <org.robovm.apple.network.NWTxtRecord: org.robovm.apple.foundation.NSObject copy()> must be native
	at org.robovm.compiler.BridgeMethodCompiler.validateBridgeMethod(BridgeMethodCompiler.java:87)
	at org.robovm.compiler.BridgeMethodCompiler.doCompile(BridgeMethodCompiler.java:233)

Root case and fix

In source code NWTxtRecord doesn’t contain NSObject copy() method but containts NWTxtRecord copy(). Hovewer once class file is decompiled following methods can be found there:

iOS13 PostFix #3: Support for @Block member in structs

|

This post continues the series of fixes discovered during compilation of CocoaTouch library.

PostFix #3: Adding support @Block members in structs

Other postfixes:

Issue was discovered while compiling CMBufferHandlers:

java.lang.IllegalArgumentException: No @Marshaler found for return type of @StructMember method <org.robovm.apple.coremedia.CMBufferHandlers: org.robovm.objc.block.Block1 getGetDecodeTimeStamp()>
	at org.robovm.compiler.MarshalerLookup.findMarshalerMethod(MarshalerLookup.java:169)
	at org.robovm.compiler.BroMethodCompiler.getStructMemberType(BroMethodCompiler.java:977)
	at org.robovm.compiler.BroMethodCompiler.getStructType(BroMethodCompiler.java:677)
	at org.robovm.compiler.BroMethodCompiler.getStructType(BroMethodCompiler.java:568)
	at org.robovm.compiler.StructMemberMethodCompiler.reset(StructMemberMethodCompiler.java:63)

Root case and fix

Root case and fix is clear from exception: there is no @Marshaller for @Block return type at moment StructMemberMethodCompiler performs reset. And the fix is to provide such. In details there are several moments and fixes:

  • Marshallers for @Block affected methods are generated by ObjCBlockPlugin in ObjCBlockPlugin.Before class run. The problem here is that ClassCompiler invokes it after StructMemberMethodCompiler.reset where this marshaller is required (and where exception is happening). The fix is to move reset section of method compilers below invocation of plugins Before. This makes marshallers generated at moment StructMemberMethodCompiler.reset needs it.
  • Second moment is that ObjCBlockPlugin.Before was not considering @StructMember annotated methods as subject for method transformation and the fix is trivial – extending condition to include the case.

The fix is delivered as PR421

iOS13 PostFix #2: Non static @Bridge method in enums

|

This post continues series of fixes discovered during compilation of CocoaTouch library.

PostFix #2: Adding support for non-static @Bridge method in enums classes

Other postfixes:

Issue was discovered during compiling of UIImageSymbolWeight class:

java.lang.IllegalArgumentException: Receiver of non static @Bridge method <org.robovm.apple.uikit.UIImageSymbolWeight: double toFontWeight()> must either be a Struct or a NativeObject
	at org.robovm.compiler.BroMethodCompiler.getBridgeOrCallbackFunctionType(BroMethodCompiler.java:554)
	at org.robovm.compiler.BroMethodCompiler.getBridgeFunctionType(BroMethodCompiler.java:526)

What is wrong