Project: titanium
Issue TIMOB-17351: iOS - Hyperloop modules might crash when accessing native objects
Using the current version of Hyperloop for iOS. When accessing a variable that holds a native object wrapped by a Hyperloop JS object, the app will crash with this stack trace: h4. EXC_BAD_ACCESS (code=2,address=0xc) {code} #0	0x03fac0b2 in objc_msgSend () #1	0x0027c674 in TiBindingTiValueToNSObject at /Users/penrique/Documents/Titanium_Studio_Workspace/TestClassic/build/iphone/Classes/TiBindingTiValue.m:112 #2	0x0002fe4c in TiValueToId at /Users/penrique/Documents/Titanium_Studio_Workspace/TestClassic/build/iphone/Classes/KrollObject.m:86 #3	0x00031cd1 in +[KrollObject toID:value:] at /Users/penrique/Documents/Titanium_Studio_Workspace/TestClassic/build/iphone/Classes/KrollObject.m:515 #4	0x0002aebc in KrollCallAsFunction at /Users/penrique/Documents/Titanium_Studio_Workspace/TestClassic/build/iphone/Classes/KrollMethod.m:37 #5	0x002d1b03 in TI::TiCallbackObject::call(TI::TiExcState*) at /Users/max/dev/titanium/tijscore/TiCore/API/TiCallbackObjectFunctions.h:397 #6	0x0031483a in TI::Interpreter::privateExecute(TI::Interpreter::ExecutionFlag, TI::RegisterFile*, TI::TiExcState*) at /Users/max/dev/titanium/tijscore/TiCore/interpreter/Interpreter.cpp:4073 #7	0x00319a5b in TI::Interpreter::executeCall(TI::TiExcState*, TI::TiObject*, TI::CallType, TI::CallData const&, TI::TiValue, TI::ArgList const&) at /Users/max/dev/titanium/tijscore/TiCore/interpreter/Interpreter.cpp:965 #8	0x0035c963 in TI::call(TI::TiExcState*, TI::TiValue, TI::CallType, TI::CallData const&, TI::TiValue, TI::ArgList const&) at /Users/max/dev/titanium/tijscore/TiCore/runtime/CallData.cpp:45 #9	0x002cc9dc in TiObjectCallAsFunction at /Users/max/dev/titanium/tijscore/TiCore/API/TiObjectRef.cpp:449 #10	0x0027bcd6 in TiBindingEventProcess at /Users/penrique/Documents/Titanium_Studio_Workspace/TestClassic/build/iphone/Classes/TiBindingEvent.m:278 #11	0x0027bfd3 in -[TiBindingCallbackInvoke invoke:] at /Users/penrique/Documents/Titanium_Studio_Workspace/TestClassic/build/iphone/Classes/TiBindingRunLoop.m:53 #12	0x00025c05 in -[KrollContext invoke:] at /Users/penrique/Documents/Titanium_Studio_Workspace/TestClassic/build/iphone/Classes/KrollContext.m:958 #13	0x0002768c in -[KrollContext main] at /Users/penrique/Documents/Titanium_Studio_Workspace/TestClassic/build/iphone/Classes/KrollContext.m:1315 #14	0x010fda07 in -[NSThread main] () {code} Note: the line numbers might vary deepening on the SDK version, but they're close enough The reason for this is very simple. When using Titanium Mobile we have two types of JS object: A normal JS object, and a JS object containing an Objective-C object. When using a Hyperloop module, there's another JS object added to the equation, a JS object containing a Hyperloop object. In JavaScriptCore every JS object has a place for a void*. In Titanium Mobile we store an Objective-C "id" directly there. In Hyperloop, in the other hand, we store a c++ class in that same void* property, and that class has a void* property (called "data") and there we sore an objective-c "id". This is why it crashes. Titanium Mobile: JS Object -> void* -> id Hyperloop JSObject -> void* -> c++ class -> void* -> id {code} id privateObject = (id)TiObjectGetPrivate(obj); if ([privateObject isKindOfClass:[KrollObject class]]) {	return [privateObject target]; } {code} In the first line of code we get the void* from the JS object and cast it as an "id". Then we call an Objective-C method on it - "isKindOfClass:". This is fine in Titanium mobile, but in Hyperloop, that void* is a c++ class, and on that second line, we call an objective-c method on that c++ class, and then the app crashes hard.
Story points: 13