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