-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d52c52f
commit 2fa56c5
Showing
5 changed files
with
177 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollWrapper.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* Appcelerator Titanium Mobile | ||
* Copyright (c) 2009-2018 by Appcelerator, Inc. All Rights Reserved. | ||
* Licensed under the terms of the Apache Public License | ||
* Please see the LICENSE included with this distribution for details. | ||
*/ | ||
|
||
#import "KrollContext.h" | ||
#import <Foundation/Foundation.h> | ||
|
||
@class KrollBridge; | ||
|
||
/* | ||
* For functions and other objects that need to be held by proxies without | ||
* conversion or possible retain cycles, KrollWrapper passively refers to a | ||
* JS Object. In the future, this should become the base class, instead of a | ||
* collection of Kroll wrappers all based off of NSObject despite common | ||
* functionality. | ||
* | ||
* NOTE: This is an object that is never made explicitly by TiIdToValue; | ||
* instead, all JS functions become KrollCallbacks, and both KrollCallbacks | ||
* and KrollObjectProperties will be converted into functions. | ||
* (or TiObjectRefs at any rate) | ||
* Instead, KrollWrapper is used in two places currently: When a function is | ||
* retained as a property by a proxy (to avoid the above retain loop), | ||
* and for JS-based modules which do not need proxy properties but do need to | ||
* be first-class JS object citizens. | ||
* TODO: Consolidate various KrollObjects, KrollCallbacks, etc to be | ||
* KrollWrappers. | ||
*/ | ||
@interface KrollWrapper : NSObject { | ||
JSObjectRef jsobject; | ||
KrollBridge *bridge; | ||
BOOL protecting; | ||
} | ||
|
||
// Access the native JSCore object | ||
@property (nonatomic, readwrite, assign) JSObjectRef jsobject; | ||
|
||
// Access the kroll bridge (e.g. for the kroll context) | ||
@property (nonatomic, readwrite, assign) KrollBridge *bridge; | ||
|
||
// Protects a JSObject from being GC'd | ||
- (void)protectJsobject; | ||
|
||
// Unprotects a JSObject from being GC'd | ||
- (void)unprotectJsobject; | ||
|
||
// Replaces a value for a given key in it's underlaying JSContext | ||
- (void)replaceValue:(id)value forKey:(NSString *)key notification:(BOOL)notify; | ||
|
||
// Executes an async JavaScript function and returns the resulting JSCore value if any | ||
- (JSValueRef)executeWithArguments:(NSArray<id> *)arguments; | ||
|
||
@end |
110 changes: 110 additions & 0 deletions
110
iphone/TitaniumKit/TitaniumKit/Sources/Kroll/KrollWrapper.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
/** | ||
* Appcelerator Titanium Mobile | ||
* Copyright (c) 2009-2018 by Appcelerator, Inc. All Rights Reserved. | ||
* Licensed under the terms of the Apache Public License | ||
* Please see the LICENSE included with this distribution for details. | ||
*/ | ||
|
||
#import "KrollWrapper.h" | ||
#import "KrollBridge.h" | ||
#import "KrollCallback.h" | ||
#import "KrollObject.h" | ||
#import "TiExceptionHandler.h" | ||
|
||
@implementation KrollWrapper | ||
@synthesize jsobject, bridge; | ||
|
||
/* NOTE: | ||
* Until KrollWrapper takes a more expanded role as a general purpose wrapper, | ||
* protectJsobject is to be used during commonJS inclusion ONLY. | ||
* For example, KrollBridge ensures that this is only done in the JS thread, | ||
* and unlike KrollObject, KrollWrapper does not have the infrastructure to | ||
* handle being called outside the JS. | ||
* Furthermore, KrollWrapper does not get notified of JSObject finalization, | ||
* etc, etc. The specific cases where KrollWrapper is currently used do not | ||
* make this an issue, but KrollWrapper needs hardening if it is to be a base | ||
* class. | ||
*/ | ||
|
||
- (void)dealloc | ||
{ | ||
if (protecting) { | ||
[self unprotectJsobject]; | ||
} | ||
[super dealloc]; | ||
} | ||
|
||
- (void)protectJsobject | ||
{ | ||
if (protecting || ![KrollBridge krollBridgeExists:bridge]) { | ||
return; | ||
} | ||
|
||
if (![[bridge krollContext] isKJSThread]) { | ||
DeveloperLog(@"[WARN] KrollWrapper trying to protect in the wrong thread.%@", CODELOCATION); | ||
return; | ||
} | ||
protecting = YES; | ||
JSValueProtect([[bridge krollContext] context], jsobject); | ||
} | ||
|
||
- (void)unprotectJsobject | ||
{ | ||
if (!protecting || ![KrollBridge krollBridgeExists:bridge]) { | ||
return; | ||
} | ||
|
||
if (![[bridge krollContext] isKJSThread]) { | ||
DeveloperLog(@"[WARN] KrollWrapper trying to unprotect in the wrong thread.%@", CODELOCATION); | ||
return; | ||
} | ||
protecting = NO; | ||
JSValueUnprotect([[bridge krollContext] context], jsobject); | ||
} | ||
|
||
- (void)replaceValue:(id)value forKey:(NSString *)key notification:(BOOL)notify | ||
{ /* | ||
* This is to be used ONLY from KrollBridge's require call, due to some | ||
* JS files assigning exports to a function instead of a standard | ||
* JS object. | ||
*/ | ||
KrollContext *context = [bridge krollContext]; | ||
JSValueRef valueRef = [KrollObject toValue:context value:value]; | ||
|
||
/* | ||
* Properties can only be added to objects | ||
*/ | ||
if (JSValueIsObject([context context], jsobject)) { | ||
JSStringRef keyRef = JSStringCreateWithCFString((CFStringRef)key); | ||
JSObjectSetProperty([context context], jsobject, keyRef, valueRef, kJSPropertyAttributeReadOnly, NULL); | ||
JSStringRelease(keyRef); | ||
} | ||
} | ||
|
||
- (JSValueRef)executeWithArguments:(NSArray<id> *)arguments | ||
{ | ||
if (![KrollBridge krollBridgeExists:[self bridge]]) { | ||
return NULL; | ||
} | ||
|
||
JSObjectRef value = [self jsobject]; | ||
JSContextRef context = [self.bridge.krollContext context]; | ||
|
||
JSValueRef callException = NULL; | ||
JSValueRef callArgs[arguments.count]; | ||
|
||
for (NSUInteger i = 0; i < arguments.count; i++) { | ||
callArgs[i] = [KrollObject toValue:self.bridge.krollContext value:[arguments objectAtIndex:i]]; | ||
} | ||
|
||
JSValueRef functionResult = JSObjectCallAsFunction(context, value, NULL, 1, callArgs, &callException); | ||
|
||
if (callException != NULL) { | ||
id exceptionPayload = [KrollObject toID:self.bridge.krollContext value:callException]; | ||
[[TiExceptionHandler defaultExceptionHandler] reportScriptError:[TiUtils scriptErrorValue:exceptionPayload]]; | ||
} | ||
|
||
return functionResult; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters