| /* |
| * 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. AND ITS CONTRIBUTORS ``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 ITS 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 "config.h" |
| #import "CurrentThisInsideBlockGetterTest.h" |
| |
| #if JSC_OBJC_API_ENABLED |
| |
| #import <Foundation/Foundation.h> |
| #import <JavaScriptCore/JavaScriptCore.h> |
| |
| static JSObjectRef CallAsConstructor(JSContextRef ctx, JSObjectRef constructor, size_t, const JSValueRef[], JSValueRef*) |
| { |
| JSObjectRef newObjectRef = NULL; |
| NSMutableDictionary *constructorPrivateProperties = (__bridge NSMutableDictionary *)(JSObjectGetPrivate(constructor)); |
| NSDictionary *constructorDescriptor = constructorPrivateProperties[@"constructorDescriptor"]; |
| newObjectRef = JSObjectMake(ctx, NULL, NULL); |
| NSDictionary *objectProperties = constructorDescriptor[@"objectProperties"]; |
| |
| if (objectProperties) { |
| JSValue *newObject = [JSValue valueWithJSValueRef:newObjectRef inContext:[JSContext contextWithJSGlobalContextRef:JSContextGetGlobalContext(ctx)]]; |
| for (NSString *objectProperty in objectProperties) { |
| [newObject defineProperty:objectProperty descriptor:objectProperties[objectProperty]]; |
| } |
| } |
| |
| return newObjectRef; |
| } |
| |
| static void ConstructorFinalize(JSObjectRef object) |
| { |
| NSMutableDictionary *privateProperties = (__bridge NSMutableDictionary *)(JSObjectGetPrivate(object)); |
| CFBridgingRelease((__bridge CFTypeRef)(privateProperties)); |
| JSObjectSetPrivate(object, NULL); |
| } |
| |
| static JSClassRef ConstructorClass(void) |
| { |
| static JSClassRef constructorClass = NULL; |
| |
| if (constructorClass == NULL) { |
| JSClassDefinition classDefinition = kJSClassDefinitionEmpty; |
| classDefinition.className = "Constructor"; |
| classDefinition.callAsConstructor = CallAsConstructor; |
| classDefinition.finalize = ConstructorFinalize; |
| constructorClass = JSClassCreate(&classDefinition); |
| } |
| |
| return constructorClass; |
| } |
| |
| @interface JSValue (ConstructorCreation) |
| |
| + (JSValue *)valueWithConstructorDescriptor:(NSDictionary *)constructorDescriptor inContext:(JSContext *)context; |
| |
| @end |
| |
| @implementation JSValue (ConstructorCreation) |
| |
| + (JSValue *)valueWithConstructorDescriptor:(id)constructorDescriptor inContext:(JSContext *)context |
| { |
| NSMutableDictionary *privateProperties = [@{ @"constructorDescriptor" : constructorDescriptor } mutableCopy]; |
| JSGlobalContextRef ctx = [context JSGlobalContextRef]; |
| JSObjectRef constructorRef = JSObjectMake(ctx, ConstructorClass(), const_cast<void*>(CFBridgingRetain(privateProperties))); |
| JSValue *constructor = [JSValue valueWithJSValueRef:constructorRef inContext:context]; |
| return constructor; |
| } |
| |
| @end |
| |
| @interface JSContext (ConstructorCreation) |
| |
| - (JSValue *)valueWithConstructorDescriptor:(NSDictionary *)constructorDescriptor; |
| |
| @end |
| |
| @implementation JSContext (ConstructorCreation) |
| |
| - (JSValue *)valueWithConstructorDescriptor:(id)constructorDescriptor |
| { |
| return [JSValue valueWithConstructorDescriptor:constructorDescriptor inContext:self]; |
| } |
| |
| @end |
| |
| void currentThisInsideBlockGetterTest() |
| { |
| @autoreleasepool { |
| JSContext *context = [[JSContext alloc] init]; |
| |
| JSValue *myConstructor = [context valueWithConstructorDescriptor:@{ |
| @"objectProperties" : @{ |
| @"currentThis" : @{ JSPropertyDescriptorGetKey : ^{ return JSContext.currentThis; } }, |
| }, |
| }]; |
| |
| JSValue *myObj1 = [myConstructor constructWithArguments:nil]; |
| NSLog(@"myObj1.currentThis: %@", myObj1[@"currentThis"]); |
| JSValue *myObj2 = [myConstructor constructWithArguments:@[ @"bar" ]]; |
| NSLog(@"myObj2.currentThis: %@", myObj2[@"currentThis"]); |
| } |
| } |
| |
| #endif // JSC_OBJC_API_ENABLED |