/* * Copyright (C) 2013 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import #import "CurrentThisInsideBlockGetterTest.h" extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef); extern "C" bool _Block_has_signature(id); extern "C" const char * _Block_signature(id); extern int failed; extern "C" void testObjectiveCAPI(void); #if JSC_OBJC_API_ENABLED @protocol ParentObject @end @interface ParentObject : NSObject + (NSString *)parentTest; @end @implementation ParentObject + (NSString *)parentTest { return [self description]; } @end @protocol TestObject - (id)init; @property int variable; @property (readonly) int six; @property CGPoint point; + (NSString *)classTest; + (NSString *)parentTest; - (NSString *)getString; JSExportAs(testArgumentTypes, - (NSString *)testArgumentTypesWithInt:(int)i double:(double)d boolean:(BOOL)b string:(NSString *)s number:(NSNumber *)n array:(NSArray *)a dictionary:(NSDictionary *)o ); - (void)callback:(JSValue *)function; - (void)bogusCallback:(void(^)(int))function; @end @interface TestObject : ParentObject @property int six; + (id)testObject; @end @implementation TestObject @synthesize variable; @synthesize six; @synthesize point; + (id)testObject { return [[TestObject alloc] init]; } + (NSString *)classTest { return @"classTest - okay"; } - (NSString *)getString { return @"42"; } - (NSString *)testArgumentTypesWithInt:(int)i double:(double)d boolean:(BOOL)b string:(NSString *)s number:(NSNumber *)n array:(NSArray *)a dictionary:(NSDictionary *)o { return [NSString stringWithFormat:@"%d,%g,%d,%@,%d,%@,%@", i, d, b==YES?true:false,s,[n intValue],a[1],o[@"x"]]; } - (void)callback:(JSValue *)function { [function callWithArguments:[NSArray arrayWithObject:[NSNumber numberWithInt:42]]]; } - (void)bogusCallback:(void(^)(int))function { function(42); } @end bool testXYZTested = false; @protocol TextXYZ - (id)initWithString:(NSString*)string; @property int x; @property (readonly) int y; @property (assign) JSValue *onclick; @property (assign) JSValue *weakOnclick; - (void)test:(NSString *)message; @end @interface TextXYZ : NSObject @property int x; @property int y; @property int z; - (void)click; @end @implementation TextXYZ { JSManagedValue *m_weakOnclickHandler; JSManagedValue *m_onclickHandler; } @synthesize x; @synthesize y; @synthesize z; - (id)initWithString:(NSString*)string { self = [super init]; if (!self) return nil; NSLog(@"%@", string); return self; } - (void)test:(NSString *)message { testXYZTested = [message isEqual:@"test"] && x == 13 & y == 4 && z == 5; } - (void)setWeakOnclick:(JSValue *)value { m_weakOnclickHandler = [JSManagedValue managedValueWithValue:value]; } - (void)setOnclick:(JSValue *)value { m_onclickHandler = [JSManagedValue managedValueWithValue:value]; [value.context.virtualMachine addManagedReference:m_onclickHandler withOwner:self]; } - (JSValue *)weakOnclick { return [m_weakOnclickHandler value]; } - (JSValue *)onclick { return [m_onclickHandler value]; } - (void)click { if (!m_onclickHandler) return; JSValue *function = [m_onclickHandler value]; [function callWithArguments:[NSArray array]]; } - (void)dealloc { [[m_onclickHandler value].context.virtualMachine removeManagedReference:m_onclickHandler withOwner:self]; #if !__has_feature(objc_arc) [super dealloc]; #endif } @end @class TinyDOMNode; @protocol TinyDOMNode - (void)appendChild:(TinyDOMNode *)child; - (NSUInteger)numberOfChildren; - (TinyDOMNode *)childAtIndex:(NSUInteger)index; - (void)removeChildAtIndex:(NSUInteger)index; @end @interface TinyDOMNode : NSObject @end @implementation TinyDOMNode { NSMutableArray *m_children; JSVirtualMachine *m_sharedVirtualMachine; } - (id)initWithVirtualMachine:(JSVirtualMachine *)virtualMachine { self = [super init]; if (!self) return nil; m_children = [[NSMutableArray alloc] initWithCapacity:0]; m_sharedVirtualMachine = virtualMachine; #if !__has_feature(objc_arc) [m_sharedVirtualMachine retain]; #endif return self; } - (void)dealloc { for (TinyDOMNode *child in m_children) [m_sharedVirtualMachine removeManagedReference:child withOwner:self]; #if !__has_feature(objc_arc) [m_children release]; [m_sharedVirtualMachine release]; [super dealloc]; #endif } - (void)appendChild:(TinyDOMNode *)child { [m_sharedVirtualMachine addManagedReference:child withOwner:self]; [m_children addObject:child]; } - (NSUInteger)numberOfChildren { return [m_children count]; } - (TinyDOMNode *)childAtIndex:(NSUInteger)index { if (index >= [m_children count]) return nil; return [m_children objectAtIndex:index]; } - (void)removeChildAtIndex:(NSUInteger)index { if (index >= [m_children count]) return; [m_sharedVirtualMachine removeManagedReference:[m_children objectAtIndex:index] withOwner:self]; [m_children removeObjectAtIndex:index]; } @end @interface JSCollection : NSObject - (void)setValue:(JSValue *)value forKey:(NSString *)key; - (JSValue *)valueForKey:(NSString *)key; @end @implementation JSCollection { NSMutableDictionary *_dict; } - (id)init { self = [super init]; if (!self) return nil; _dict = [[NSMutableDictionary alloc] init]; return self; } - (void)setValue:(JSValue *)value forKey:(NSString *)key { JSManagedValue *oldManagedValue = [_dict objectForKey:key]; if (oldManagedValue) { JSValue* oldValue = [oldManagedValue value]; if (oldValue) [oldValue.context.virtualMachine removeManagedReference:oldManagedValue withOwner:self]; } JSManagedValue *managedValue = [JSManagedValue managedValueWithValue:value]; [value.context.virtualMachine addManagedReference:managedValue withOwner:self]; [_dict setObject:managedValue forKey:key]; } - (JSValue *)valueForKey:(NSString *)key { JSManagedValue *managedValue = [_dict objectForKey:key]; if (!managedValue) return nil; return [managedValue value]; } @end @protocol InitA - (id)initWithA:(int)a; - (int)initialize; @end @protocol InitB - (id)initWithA:(int)a b:(int)b; @end @protocol InitC - (id)_init; @end @interface ClassA : NSObject @end @interface ClassB : ClassA @end @interface ClassC : ClassB @end @interface ClassCPrime : ClassB @end @interface ClassD : NSObject - (id)initWithA:(int)a; @end @interface ClassE : ClassD - (id)initWithA:(int)a; @end @implementation ClassA { int _a; } - (id)initWithA:(int)a { self = [super init]; if (!self) return nil; _a = a; return self; } - (int)initialize { return 42; } @end @implementation ClassB { int _b; } - (id)initWithA:(int)a b:(int)b { self = [super initWithA:a]; if (!self) return nil; _b = b; return self; } @end @implementation ClassC { int _c; } - (id)initWithA:(int)a { return [self initWithA:a b:0]; } - (id)initWithA:(int)a b:(int)b { self = [super initWithA:a b:b]; if (!self) return nil; _c = a + b; return self; } @end @implementation ClassCPrime - (id)initWithA:(int)a { self = [super initWithA:a b:0]; if (!self) return nil; return self; } - (id)_init { return [self initWithA:42]; } @end @implementation ClassD - (id)initWithA:(int)a { self = nil; return [[ClassE alloc] initWithA:a]; } - (int)initialize { return 0; } @end @implementation ClassE { int _a; } - (id)initWithA:(int)a { self = [super init]; if (!self) return nil; _a = a; return self; } @end static bool evilAllocationObjectWasDealloced = false; @interface EvilAllocationObject : NSObject - (JSValue *)doEvilThingsWithContext:(JSContext *)context; @end @implementation EvilAllocationObject { JSContext *m_context; } - (id)initWithContext:(JSContext *)context { self = [super init]; if (!self) return nil; m_context = context; return self; } - (void)dealloc { [self doEvilThingsWithContext:m_context]; evilAllocationObjectWasDealloced = true; #if !__has_feature(objc_arc) [super dealloc]; #endif } - (JSValue *)doEvilThingsWithContext:(JSContext *)context { return [context evaluateScript:@" \ (function() { \ var a = []; \ var sum = 0; \ for (var i = 0; i