1/* 2 * Copyright (C) 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY 17 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 */ 24 25#import "WebScriptWorld.h" 26 27#import "WebScriptWorldInternal.h" 28#import <WebCore/JSDOMBinding.h> 29#import <WebCore/ScriptController.h> 30#import <JavaScriptCore/APICast.h> 31 32#import <wtf/RefPtr.h> 33 34using namespace WebCore; 35 36@interface WebScriptWorldPrivate : NSObject { 37@public 38 RefPtr<DOMWrapperWorld> world; 39} 40@end 41 42@implementation WebScriptWorldPrivate 43@end 44 45typedef HashMap<DOMWrapperWorld*, WebScriptWorld*> WorldMap; 46static WorldMap& allWorlds() 47{ 48 static WorldMap& map = *new WorldMap; 49 return map; 50} 51 52@implementation WebScriptWorld 53 54- (id)initWithWorld:(PassRefPtr<DOMWrapperWorld>)world 55{ 56 ASSERT_ARG(world, world); 57 if (!world) 58 return nil; 59 60 self = [super init]; 61 if (!self) 62 return nil; 63 64 _private = [[WebScriptWorldPrivate alloc] init]; 65 _private->world = world; 66 67 ASSERT_ARG(world, !allWorlds().contains(_private->world.get())); 68 allWorlds().add(_private->world.get(), self); 69 70 return self; 71} 72 73- (id)init 74{ 75 return [self initWithWorld:ScriptController::createWorld()]; 76} 77 78- (void)unregisterWorld 79{ 80 _private->world->clearWrappers(); 81} 82 83- (void)dealloc 84{ 85 ASSERT(allWorlds().contains(_private->world.get())); 86 allWorlds().remove(_private->world.get()); 87 88 [_private release]; 89 _private = nil; 90 [super dealloc]; 91} 92 93+ (WebScriptWorld *)standardWorld 94{ 95 static WebScriptWorld *world = [[WebScriptWorld alloc] initWithWorld:mainThreadNormalWorld()]; 96 return world; 97} 98 99+ (WebScriptWorld *)world 100{ 101 return [[[self alloc] init] autorelease]; 102} 103 104+ (WebScriptWorld *)scriptWorldForGlobalContext:(JSGlobalContextRef)context 105{ 106 return [self findOrCreateWorld:currentWorld(toJS(context))]; 107} 108 109@end 110 111@implementation WebScriptWorld (WebInternal) 112 113DOMWrapperWorld* core(WebScriptWorld *world) 114{ 115 return world ? world->_private->world.get() : 0; 116} 117 118+ (WebScriptWorld *)findOrCreateWorld:(DOMWrapperWorld*) world 119{ 120 ASSERT_ARG(world, world); 121 122 if (world == mainThreadNormalWorld()) 123 return [self standardWorld]; 124 125 if (WebScriptWorld *existingWorld = allWorlds().get(world)) 126 return existingWorld; 127 128 return [[[self alloc] initWithWorld:world] autorelease]; 129} 130 131@end 132