Running:
- Fuse v0.35.0 (build 10867)
- macOS Sierra v10.12.3
- XCode 8.3 beta
- iOS 10.3
I can add a bit more detail regarding the crash I am getting above. I’ve whittled down my code to as minimal as possible and still get the crash.
I feel like I’m doing something trivially stupid or perhaps it has something to do with which thread it’s running on (I’m certainly not trying to do anything funny with respect to threading, but the stack trace has some suspicious posix_thread stuff.
Here’s my UX:
<App>
<JavaScript>
var test = require("Test");
var getStatus = () => {
test.getStatus(
function(result) { debug_log(JSON.parse(result)); }
);
};
module.exports = {
getStatus: getStatus
};
</JavaScript>
<Button Text="Get Status" Clicked="{getStatus}" />
</App>
Here’s the native module:
using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using Uno.UX;
using Uno.Compiler.ExportTargetInterop;
using Uno;
using Uno.Collections;
[Require("Xcode.Framework","Foundation.framework")]
[UXGlobalModule]
public class TestModule : NativeModule
{
static readonly TestModule _instance;
public TestModule()
{
if(_instance != null)
return;
_instance = this;
Resource.SetGlobalKey(_instance, "Test");
AddMember(new NativeFunction("getStatus", (NativeCallback)getStatus));
}
class SuccessClosure
{
Function _callback;
public SuccessClosure(Function callback)
{
_callback = callback;
}
public void Call(string arg)
{
_callback.Call(arg);
}
}
object getStatus(Context c, object[] args)
{
if defined(iOS) {
Function successCb = args[0] as Function;
_getStatus(new SuccessClosure(successCb).Call);
return null;
} else {
debug_log "getStatus is only implemented for iOS";
return null;
}
}
[Foreign(Language.ObjC)]
public extern(iOS) void _getStatus(Action<string> success)
@{
success(@"Hello");
@}
}
When I tap “Get Status”, it gets to the extern(iOS) line success(@"Hello");
and then enters JavaScriptCore-land and crashes with the following stack trace:
libc++abi.dylib: terminating with uncaught exception of type uThrowable: Uno.Exception
(lldb) bt
warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.
* thread #12, stop reason = signal SIGABRT
frame #0: 0x0000000182659014 libsystem_kernel.dylib`__pthread_kill + 8
frame #1: 0x0000000182723334 libsystem_pthread.dylib`pthread_kill + 112
frame #2: 0x00000001825cd9c4 libsystem_c.dylib`abort + 140
frame #3: 0x00000001820991b0 libc++abi.dylib`abort_message + 132
frame #4: 0x00000001820b2bec libc++abi.dylib`default_terminate_handler() + 280
frame #5: 0x00000001820c0830 libobjc.A.dylib`_objc_terminate() + 140
frame #6: 0x00000001820af5d4 libc++abi.dylib`std::__terminate(void (*)()) + 16
frame #7: 0x00000001820aeef8 libc++abi.dylib`__cxa_throw + 136
* frame #8: fuse-test`g::Fuse::Scripting::JavaScriptCore::Context__CallbackWrapper::Call(this=0x0000000170265480, args=0x000000017027eec0, exception=0x000000016e4c22d0) at Fuse.Scripting.JavaScriptCore.g.cpp:239
frame #9: fuse-test`g::Fuse::Scripting::JavaScriptCore::Context__CallbackWrapper__Call_fn(__this=0x0000000170265480, args=0x000000017027eec0, exception=0x000000016e4c22d0, __retval=0x000000016e4c2120) at Fuse.Scripting.JavaScriptCore.g.cpp:207
frame #10: fuse-test`uInvoke(func=0x00000001002757b0, args=0x000000016e4c2090, count=4) at _invoke.cpp:20
frame #11: fuse-test`uDelegate::Invoke(this=0x000000017029fbd0, retval=(_address = 0x000000016e4c2120), args=0x000000016e4c2130, count=4) at ObjectModel.cpp:1440
frame #12: fuse-test`uDelegate::Invoke(this=0x000000017029fbd0, count=2) at ObjectModel.cpp:1531
frame #13: fuse-test`g::Fuse::Scripting::JavaScriptCore::JSClassRef::CreateUnoCallback(this=0x0000000000000002, ctx=0x000000016e4c2460, function=0x00000001077989a0, thisObject=0x00000001077c12e0, argumentCount=1, arguments=0x000000016e4c22e8, exception=0x000000016e4c22d0)::$_1::operator()(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) const at Fuse.Scripting.JavaScriptCore.g.cpp:887
frame #14: fuse-test`g::Fuse::Scripting::JavaScriptCore::JSClassRef::CreateUnoCallback(ctx=0x000000016e4c2460, function=0x00000001077989a0, thisObject=0x00000001077c12e0, argumentCount=1, arguments=0x000000016e4c22e8, exception=0x000000016e4c22d0)::$_1::__invoke(OpaqueJSContext const*, OpaqueJSValue*, OpaqueJSValue*, unsigned long, OpaqueJSValue const* const*, OpaqueJSValue const**) at Fuse.Scripting.JavaScriptCore.g.cpp:872
frame #15: 0x0000000187c1be7c JavaScriptCore`JSC::JSCallbackObject<JSC::JSDestructibleObject>::call(JSC::ExecState*) + 456
frame #16: 0x000000018756aba8 JavaScriptCore`JSC::LLInt::setUpCall(JSC::ExecState*, JSC::Instruction*, JSC::CodeSpecializationKind, JSC::JSValue, JSC::LLIntCallLinkInfo*) + 456
frame #17: 0x0000000187cfeb88 JavaScriptCore`llint_entry + 26392
frame #18: 0x0000000187cf82a8 JavaScriptCore`vmEntryToJavaScript + 264
frame #19: 0x0000000187be25b8 JavaScriptCore`JSC::JITCode::execute(JSC::VM*, JSC::ProtoCallFrame*) + 164
frame #20: 0x000000018756efe8 JavaScriptCore`JSC::Interpreter::executeCall(JSC::ExecState*, JSC::JSObject*, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 416
frame #21: 0x000000018787b5ec JavaScriptCore`JSC::profiledCall(JSC::ExecState*, JSC::ProfilingReason, JSC::JSValue, JSC::CallType, JSC::CallData const&, JSC::JSValue, JSC::ArgList const&) + 164
frame #22: 0x000000018756ed5c JavaScriptCore`JSObjectCallAsFunction + 636
frame #23: fuse-test`g::Fuse::Scripting::JavaScriptCore::JSObjectRef::CallAsFunction(__this=0x000000010775ece0, ctx=0x00000001077d80e0, thisObject=0x0000000000000000, arguments=0x000000017027ee40, onException=0x000000017029a220) at Fuse.Scripting.JavaScriptCore.g.cpp:1220
frame #24: fuse-test`g::Fuse::Scripting::JavaScriptCore::Function__Call_fn(__this=0x0000000170075f40, args=0x000000017027ee00, __retval=0x000000016e4c2918) at Fuse.Scripting.JavaScriptCore.g.cpp:754
frame #25: fuse-test`g::Fuse::Scripting::Function::Call(this=0x0000000170075f40, args=0x000000017027ee00) at Fuse.Scripting.Function.h:30
frame #26: fuse-test`g::Fuse::Reactive::EventBinding__CallClosure::Call(this=0x000000017428bcc0) at Fuse.Reactive.g.cpp:841
frame #27: fuse-test`g::Fuse::Reactive::EventBinding__CallClosure__Call_fn(__this=0x000000017428bcc0) at Fuse.Reactive.g.cpp:757
frame #28: fuse-test`uDelegate::InvokeVoid(this=0x00000001742813b0) at ObjectModel.cpp:1382
frame #29: fuse-test`g::Fuse::Reactive::ThreadWorker::RunInner(this=0x00000001740a8820) at Fuse.Reactive.g.cpp:3658
frame #30: fuse-test`g::Fuse::Reactive::ThreadWorker::Run(this=0x00000001740a8820) at Fuse.Reactive.g.cpp:3563
frame #31: fuse-test`g::Fuse::Reactive::ThreadWorker__Run_fn(__this=0x00000001740a8820) at Fuse.Reactive.g.cpp:3472
frame #32: fuse-test`uDelegate::InvokeVoid(this=0x0000000174287620) at ObjectModel.cpp:1382
frame #33: fuse-test`ThreadStartup(arg=0x0000000174261880) at posix_thread.cpp:43
frame #34: 0x000000018272175c libsystem_pthread.dylib`_pthread_body + 240
frame #35: 0x000000018272166c libsystem_pthread.dylib`_pthread_start + 284
frame #36: 0x000000018271ed84 libsystem_pthread.dylib`thread_start + 4