Skip to content

Commit

Permalink
TIMOB-6688 Do not convert pure-JS modules to proxies, but wrapper the…
Browse files Browse the repository at this point in the history
…m, to avoid TIMOB-2392.
  • Loading branch information
WhichKatieDid committed Dec 15, 2011
1 parent 21968ea commit 34d406c
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 48 deletions.
46 changes: 25 additions & 21 deletions iphone/Classes/KrollBridge.mm
Original file line number Diff line number Diff line change
Expand Up @@ -705,30 +705,34 @@ - (id)krollObjectForProxy:(id)proxy
-(id)loadCommonJSModule:(NSString*)code withPath:(NSString*)path
{
NSString *js = [[NSString alloc] initWithFormat:TitaniumModuleRequireFormat,code];

id result = [self evalJSAndWait:js];
[js release];
bool resultIsArray = [result isKindOfClass:[NSArray class]];
bool resultIsDict = [result isKindOfClass:[NSDictionary class]];

if (resultIsArray || resultIsDict) {
TiProxy *proxy = [[TiProxy alloc] _initWithPageContext:self];
int keyIndex = 0;
for (id currentObject in result)
{
if (resultIsDict)
{
[proxy setValue:[result objectForKey:currentObject] forUndefinedKey:currentObject];
}
else
{
[proxy setValue:currentObject forKey:[NSString stringWithFormat:@"%d",keyIndex++]];
}
}
result = [proxy autorelease];
/* This most likely should be integrated with normal code flow, but to
* minimize impact until a in-depth reconsideration of KrollContext can be
* done, we should have as little footprint
*/
KrollEval *eval = [[[KrollEval alloc] initWithCode:js] autorelease];
TiValueRef exception = NULL;
TiValueRef resultRef = [eval jsInvokeInContext:context exception:&exception];
[js release];
[eval release];

if (exception != NULL) {
id excm = [KrollObject toID:context value:exception];
NSLog(@"[ERROR] Script Error = %@",[TiUtils exceptionMessage:excm]);
fflush(stderr);
throw excm;
}
/*
* In order to work around the underlying issue of TIMOB-2392, we must
* use KrollFunction as a JS wrapper instead of converting it to a proxy
*/

KrollFunction * result = [[KrollFunction alloc] init];
[result setRemoteBridge:self];
[result setRemoteFunction:(TiObjectRef)resultRef];
[result protectJsobject];

return result;
return [result autorelease];
}

-(NSString*)pathToModuleClassName:(NSString*)path
Expand Down
10 changes: 10 additions & 0 deletions iphone/Classes/KrollCallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,25 @@
// KrollCallbacks and KrollObjectProperties will be converted into functions (or TiObjectRefs at
// any rate)

/*
* TODO: KrollFunction should be made a base class, renamed something akin to
* KrollWrapper, to reflect its larger use as of TIMOB-6688 and for future
* designs where we consolidate various KrollObjects, KrollCallbacks, etc.
*/

@class KrollBridge;

@interface KrollFunction : NSObject
{
TiObjectRef remoteFunction;
KrollBridge * remoteBridge;
BOOL protecting;
}

@property (nonatomic,readwrite,assign) TiObjectRef remoteFunction;
@property (nonatomic,readwrite,assign) KrollBridge * remoteBridge;

-(void)protectJsobject;
-(void)unprotectJsobject;

@end
73 changes: 60 additions & 13 deletions iphone/Classes/KrollCallback.m
Original file line number Diff line number Diff line change
Expand Up @@ -158,19 +158,6 @@ -(id)call:(NSArray*)args thisObject:(id)thisObject_
return val;
}

- (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.
*/

TiValueRef valueRef = [KrollObject toValue:context value:value];
TiStringRef keyRef = TiStringCreateWithCFString((CFStringRef) key);
TiObjectSetProperty(jsContext, function, keyRef, valueRef, kTiPropertyAttributeReadOnly, NULL);
TiStringRelease(keyRef);
}

-(TiObjectRef)function
{
return function;
Expand All @@ -193,4 +180,64 @@ -(void)setContext:(KrollContext*)context_
@implementation KrollFunction
@synthesize remoteFunction, remoteBridge;

/* NOTE:
* Until KrollFunction 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, KrollFunction does not have the infrastructure to
* handle being called outside the JS.
*/

- (void)dealloc {
if (protecting) {
[self unprotectJsobject];
}
[super dealloc];
}

-(void)protectJsobject
{
if (protecting || ![KrollBridge krollBridgeExists:remoteBridge])
{
return;
}

if (![[remoteBridge krollContext] isKJSThread])
{
NSLog(@"[WARN] KrollFunction trying to protect in the wrong thread.%@",CODELOCATION);
return;
}
protecting = YES;
TiValueProtect([[remoteBridge krollContext] context],remoteFunction);
}

-(void)unprotectJsobject
{
if (!protecting || ![KrollBridge krollBridgeExists:remoteBridge])
{
return;
}

if (![[remoteBridge krollContext] isKJSThread])
{
NSLog(@"[WARN] KrollFunction trying to unprotect in the wrong thread.%@",CODELOCATION);
return;
}
protecting = NO;
TiValueUnprotect([[remoteBridge krollContext] context],remoteFunction);
}

- (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 = [remoteBridge krollContext];
TiValueRef valueRef = [KrollObject toValue:context value:value];
TiStringRef keyRef = TiStringCreateWithCFString((CFStringRef) key);
TiObjectSetProperty([context context], remoteFunction, keyRef, valueRef, kTiPropertyAttributeReadOnly, NULL);
TiStringRelease(keyRef);
}

@end
1 change: 1 addition & 0 deletions iphone/Classes/KrollContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
NSString *code;
}
-(id)initWithCode:(NSString*)code;
-(TiValueRef) jsInvokeInContext: (KrollContext*)context exception: (TiValueRef *)exceptionPointer;
-(void)invoke:(KrollContext*)context;
-(id)invokeWithResult:(KrollContext*)context;
@end
Expand Down
26 changes: 12 additions & 14 deletions iphone/Classes/KrollContext.mm
Original file line number Diff line number Diff line change
Expand Up @@ -539,45 +539,43 @@ -(void)dealloc
[super dealloc];
}

-(void)invoke:(KrollContext*)context
-(TiValueRef) jsInvokeInContext: (KrollContext*)context exception: (TiValueRef *)exceptionPointer
{
TiStringRef js = TiStringCreateWithCFString((CFStringRef) code);
TiObjectRef global = TiContextGetGlobalObject([context context]);

TiValueRef exception = NULL;
TiValueRef result = TiEvalScript([context context], js, global, NULL, 1, exceptionPointer);

TiStringRelease(js);

TiEvalScript([context context], js, global, NULL, 1, &exception);
return result;
}

-(void)invoke:(KrollContext*)context
{
TiValueRef exception = NULL;
[self jsInvokeInContext:context exception:&exception];

if (exception!=NULL)
{
id excm = [KrollObject toID:context value:exception];
NSLog(@"[ERROR] Script Error = %@",[TiUtils exceptionMessage:excm]);
fflush(stderr);
}

TiStringRelease(js);
}

-(id)invokeWithResult:(KrollContext*)context
{
TiStringRef js = TiStringCreateWithCFString((CFStringRef) code);
TiObjectRef global = TiContextGetGlobalObject([context context]);

TiValueRef exception = NULL;

TiValueRef result = TiEvalScript([context context], js, global, NULL, 1, &exception);
TiValueRef result = [self jsInvokeInContext:context exception:&exception];

if (exception!=NULL)
{
id excm = [KrollObject toID:context value:exception];
NSLog(@"[ERROR] Script Error = %@",[TiUtils exceptionMessage:excm]);
fflush(stderr);
TiStringRelease(js);
throw excm;
}

TiStringRelease(js);

return [KrollObject toID:context value:result];
}

Expand Down

0 comments on commit 34d406c

Please sign in to comment.