MonoTouch JIT Error in Release mode on Linq Method - ios

I currently have some code as shown below that uses Linq to organize some IEnumerables for me. When executing this code on the device in release mode (iOS 5.0.1, MonoTouch 5.0.1, Mono 2.10.6.1) I get the exception
Attempting to JIT compile method 'System.Linq.OrderedEnumerable`1:GetEnumerator()' while running with --aot-only.
The code that generates this error is
// List<IncidentDocument> documents is passed in
List<LibraryTableViewItemGroup> groups = new List<LibraryTableViewItemGroup>();
List<DocumentObjectType> categories = documents.Select(d=>d.Type).Distinct().OrderBy(s=>s.ToString()).ToList();
foreach(DocumentObjectType cat in categories)
{
List<IncidentDocument> catDocs = documents.Where(d => d.Type == cat).OrderBy(d => d.Name).ToList();
List<LibraryTableViewItem> catDocsTableItems = catDocs.ConvertAll(d => { return new LibraryTableViewItem{ Image = GetImageForDocument(d.Type), Title = d.Name, SubTitle = d.Description}; });
LibraryTableViewItemGroup catGroup = new LibraryTableViewItemGroup{ Name = GetCatName(cat), Footer = null, Items = catDocsTableItems };
groups.Add (catGroup);
}
This error doesn't happen in the simulator for Release|Debug configurations, or on the device for the Debug configuration. I've seen a couple of similar threads on SO here and here, but I'm not sure I understand how they apply to me on this particular issue.

It could be a few things.
There are some limitations when using full AOT to build iOS applications, i.e. ensuring that nothing will be JITted at runtime (an Apple restriction). Each one is different even if the message looks identical (i.e. many causes will lead to this). However there are generally easy workarounds we can suggest for them;
It could also be a (known) regression in 5.0.1 (which is fixed in 5.0.2). This produced a few extra AOT failures that are normally not issues (or already fixed issues).
I suggest you to update to MonoTouch 5.0.2 to see if it compiles correctly your application. If not then please fill a bug report on http;//bugzilla.xamarin.com and include a small, self-contained, test case to duplicate the issue (the above is not complete enough). It seems an interesting test case if it works when debugging is enabled.

Related

How to log a large object or primitive to the console in NativeScript core on iOS?

Currently, both console.log and console.dir truncate their output. Here's a pull request that explicitly limited, by default, the size of the console output for the NativeScript Android runtime. I couldn't find a similar pull request for the iOS runtime. The pull request for Android added a configuration option that can be set to change the limit but no such option seems to exist for iOS.
Here's a (closed) issue for the main NativeScript project with a comment mentioning that no configuration option seems to be available (or at least known) to change the apparent limit:
console.dir not showing full object · Issue #6041 · NativeScript/NativeScript
I checked the NativeScript, NativeScript iOS runtime, and even WebKit sources (on which the NativeScript iOS runtime depends for its JavaScript runtime from what I could tell) and I couldn't find any obvious limit on the size of console messages.
In the interim, I've opted to use this function in my code:
function logBigStringToConsole(string) {
const maxConsoleStringLength = 900; // The actual max length isn't clear.
const length = string.length;
if (length < maxConsoleStringLength) {
console.log(string);
} else {
console.log(string.substring(0, maxConsoleStringLength));
logBigStringToConsole(string.substring(maxConsoleStringLength));
}
}
and I use it like this:
logBigStringToConsole(JSON.stringify(bigObject));

Configuring multiple devices in PortAudio: Invalid device error

This query is regarding the Portaudio framework. A little background before I ask the question:I am working on an application in PortAudio to output audio through a multichannel(=8) device. However, the device I am using does not expose itself as a single 8-channel device but instead shows up in my device-list as 4 stereo devices. On searching for an approach to handle this, I got to know that WinMME in PortAudio supports multiple devices.
Now, I went through the appropriate header file("pa_win_wmme.h") and followed the suggestions present. But I get the 'Invalid device' error (error number -9996) after calling PA_OpenStream(). In the above mentioned header file, they have in fact specified the right parameter(s) to use when configuring multiple devices to avoid this error, but in-spite of following them, I still get the error.
So I wanted to know if anybody has faced a similar issue and whether I have missed/wrongly configured anything.
I am pasting the required snippets of code below for reference:
PaStreamParameters outputParameters;
PaWinMmeStreamInfo wmmeStreamInfo;
PaWinMmeDeviceAndChannelCount wmmeDeviceAndNumChannels;**
...
...
outputParameters.device = paUseHostApiSpecificDeviceSpecification;
outputParameters.channelCount = 8;
outputParameters.sampleFormat = paFloat32; /* 32 bit floating point processing */
outputParameters.hostApiSpecificStreamInfo = NULL;
wmmeStreamInfo.size = sizeof(PaWinMmeStreamInfo);
wmmeStreamInfo.hostApiType = paMME;
wmmeStreamInfo.version = 1;
wmmeStreamInfo.flags = paWinMmeUseMultipleDevices;
wmmeDeviceAndNumChannels.channelCount = 2;
wmmeDeviceAndNumChannels.device = 3;
wmmeStreamInfo.devices = &wmmeDeviceAndNumChannels;
wmmeStreamInfo.deviceCount = 4;
outputParameters.hostApiSpecificStreamInfo = &wmmeStreamInfo;
The device id = 3 was obtained through
Pa_GetHostApiInfo( Pa_HostApiTypeIdToHostApiIndex( paMME ) )->defaultOutputDevice
I hope I have made the query clear enough. Will be happy to provide more details if required.
Thanks.
I finally figured out the mistake :-)
The configuration for multiple devices must be made as an array. For instance, in the above case
wmmeDeviceAndNumChannels must be an array of 4, with each individual device field containing the corresponding device index of each of the 4 stereo devices. The channelCount remains 2. The outputParameters.channelCount still has to be the aggregate number of channels, i.e. 8. With this I was able to run the application with a single stream, and of course, without any errors related to invalid device or invalid number of channels.:-)
Thanks.
Based on the code pasted above, it looks like you are trying to call open on a single 8-channel device. Instead you will have to get the Pa index of all four devices and call open 4 times. Once for each stereo device. You will then have 4 interleaved stereo streams to maintain. My guess is that changing channelCount = 8 to channelCount = 2 will allow the first stream to open.

App used to work with AIR 3.2, doesn't work with AIR 3.5

I'm getting this error when I press a button in a flash/air app that used to work in the AIR 3.2 SDK - now upgraded to the AIR 3.5 SDK. Any help much appreciated.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at seed_template_fla::MainTimeline/frame7()[seed_template_fla.MainTimeline::frame7:31]
at flash.display::MovieClip/gotoAndPlay()
at seed_template_fla::MainTimeline/gotoPage() [seed_template_fla.MainTimeline::frame1:20]
at seed_template_fla::MainTimeline/gotoRepro() [seed_template_fla.MainTimeline::frame1:12]
I'm creating an app for iPhone using Flash CS6 on Mac and exporting using the Air 3.5 SDK. I also have the AIR 3.5 runtime installed.
The app is very simple at the moment. It basically moves from frame to frame when you press a button using the gotoAndPlay(frameNr) function. There are some hexes on the frames that update an array of numbers when clicked. They are also toggled visible/not visible.
This used to work perfectly using the AIR 3.2 SDK, but I recently downloaded the AIR 3.5 SDK from adobe and added it through flash (Help>Manage Air SDK) and set it as the build target in File>Publish Settings>Target.
When I switch back to AIR 3.2 SDK, the app works perfectly again.
Also, when I upload the app to my iPhone 4S running IOS 5.1 using AIR 3.5 SDK, I just see a black screen with 5 loading dots flashing. This also works fine with AIR 3.2 SDK.
This is the code for frame 7
The last line is line 31.
stop();
techtitle.text = "Select Trait";
techdesc.text = "Spend points to change core stats and other special abilities";
points.visible = false;
techpoints.visible=false;
pointsbalance.text = myPoints.toString();
btn_tech.visible = false;
curTechSelected = null;
trace("set hexes invisible");
for (var j:int = 0; j <= 67; j++) {
if (hexStatusb[j] == 1) {
this["btn_hex_"+j+"b"].visible = false;
}
}
function onBtnHex37bClick(event:MouseEvent):void
{
techtitle.text = "tech1";
techdesc.text = "tech1 description"
techpoints.text = "-2";
points.visible = true;
techpoints.visible=true;
btn_tech.visible = true;
curTechSelected = btn_hex_37b;
curTechSelectedNr = 37;
curTechPoints = 2;
}
trace(this["btn_hex_37b"]);
btn_hex_37b.addEventListener(MouseEvent.CLICK, onBtnHex37bClick);
OK - so, after trying out lots of things, I figured out why this is happening.
Solution: get rid of all TFL text objects when running AIR 3.5 SDK
It seems that the TFL Text library wasn't being loaded properly at runtime. Something crucial that I neglected to mention was that I was getting this warning message (similar here http://forums.adobe.com/thread/825637)
Content will not stream... The runtime shared libraries being preloaded are textLayout_1.0.0.05... TFLText
and this warning message in the output
Warning: Ignoring 'secure' attribute in policy file from http://fpdownload.adobe.com/pub/swz/crossdomain.xml. The 'secure' attribute is only permitted in HTTPS and socket policy files.
Simply removing all TFLText objects and changing them to classic text makes the app work fine again.
#csomakk Great news. I have found the answer. You can publish in 3.5 and 3.6 and have your TLF Text too. I posted a write-up on my blog that shows exactly how to do it.
To get started: the error message states that something is null.. it means, that the program doesn't know, where to look for it. It can happen, when you didn't create the object (btn_hex_37b = new MovieClip()); or you haven't even created a variable for it.
on the given line (btn_hex_37b.addEventListener(MouseEvent.CLICK, onBtnHex37bClick);) only btn_hex_37b can be null, because onBtnHex37bClick exists, and if it wouldn't, the program wouldn't compile.
The reason it came up when switching to AIR 3.5 is probably that it calls some creation functions in different order. Go to the line where you define the btn_hex_37b variable. Search for that functions calling.. Make sure, that btn_hex_37b is created before going to frame7.
Also, if its not a vital, to have onBtn_hex_37bClick, you can do the following:
if(btn_hex_37b){
btn_hex_37b.addEventListener(MouseEvent.CLICK, onBtnHex37bClick);
}
the if will check if btn_hex_37b is not null.
On the else method, you can give a timeouted method(but that is ugly), or give the eventlistener right after the creation of the object.
Hope this helped.
For Flash CS6, copy this swc:
/Applications/Adobe Flash CS6/Common/Configuration/ActionScript 3.0/libs/flash.swc
Into my Flash Builder project using these steps:
http://interactivesection.files.wordpress.com/2009/06/include_fl_packages_in_flex_builder-1.jpg
and then use this link
http://curtismorley.com/2013/03/05/app-used-to-work-with-air-3-2-or-3-4-doesnt-work-with-air-3-5-or-3-6/#comment-241102

Backbone on BlackBerry OS5 - is it possible?

I'm developing a mobile application using Backbone, jQueryMobile and Phonegap. The app works great on Android, iOS and BB >= 6, but on BB5 as expected there are countless issues coming up.
I'm now facing problems with Backbone itself. I'm debugging it and looks like the problem is in the routes definition. The application crashes on start time due to something related to it (still investigating, but debugging is painful for BB5...).
Also, I read that BB5 won't play nice with hash listening, which Backbone relies on to do the navigation, so I am wondering if somebody has been able to create a backbone app on OS5, or is it simply not possible?
I'm updating this question just in case someone faces the same issue:
Short story: it's not possible to run Backbone on OS5. I debugged into backbone and some instructions with regular expressions were causing a crash. Even if these are fixed in the future, we determined that the js support was simply not good enough and finally discarded the OS5 version.
It is probably not worth it in most cases but this is doable.
I managed to get an app running after quite a bit of work - the javascript support is really not great in OS 5.0 and debugging is very very slow as suggested in bfcapell's answer.
To get backbone to work you need to comment out the code that uses the hashchange event to handle url changes (this is assuming that the router is being used). THere is a fallback in backbone which uses setinterval to poll for changes.
// Depending on whether we're using pushState or hashes, and whether
// 'onhashchange' is supported, determine how we check the URL state.
/*if (this._hasPushState)
{
alert('pushstate');
$(window).bind('popstate', this.checkUrl);
} else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE)
{
alert('hashchange');
$(window).bind('hashchange', this.checkUrl);
} else if (this._wantsHashChange)
{*/
this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
//}
The foreach method in underscore also needs to be modified to not use the native foreach method. This is needed for collections to be rendered correctly.
var each = _.each = _.forEach = function (obj, iterator, context)
{
if (obj == null) return;
/*if (nativeForEach && obj.forEach === nativeForEach)
{
obj.forEach(iterator, context);
}
else*/
if (obj.length === +obj.length)
The above should get at least backbone mostly working. (I say mostly because I have a completely working app but I suspect to find a couple more OS5 specific issues in time).

Catching java.lang.Error

I'm developing a Javame framework for J2me and Blackberry. I read the type(bb or j2me) from the device, and then I load the right classes depending on the detected device.
Only I get a java.lang.error when executing the following code. I think that's because I use a blackberry package in the KuixCanvasBB that j2me doesn't support. But is there a way to catch this error?
KuixCanvas canvas;
if(Settings.j2me) {
System.out.println("j2me");
canvas = new KuixCanvasJ2me(this, isFullscreen());
}
else {
System.out.println("BB");
try {
canvas = new KuixCanvasBB(this, isFullscreen());
//canvas = new KuixCanvasJ2me(this, isFullscreen());
}
catch (java.lang.Error e) {
canvas=null;
}
}
I still get an Error when executing the above code:
java.lang.Error: ClassFormatError: 154
- java.lang.Class.invoke_verify(), bci=0
- java.lang.Class.initialize(), bci=117
- java.lang.Class.initialize(), bci=139
- java.lang.Class.forName(), bci=0
Can I catch this error without the app shutting down?
Since many J2ME VMs will verify all code before running anything such code could easily be rejected from even installing on many devices.
A safer solution would probably be to make this a build-time decision, since you'll need separate .jar files for the final build anyway.
The reason you get the error is probably because references to other classes get resolved as soon as the method is entered on the JVM.

Resources