1/* 2 * Copyright (C) 2004, 2006, 2007, 2008, 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 COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#import "config.h" 27#import "DOMInternal.h" 28 29#import "DOMNodeInternal.h" 30#import "Frame.h" 31#import "JSNode.h" 32#import "WebScriptObjectPrivate.h" 33#import "runtime_root.h" 34 35//------------------------------------------------------------------------------------------ 36// Wrapping WebCore implementation objects 37 38static NSMapTable* DOMWrapperCache; 39 40NSMapTable* createWrapperCache() 41{ 42#ifdef BUILDING_ON_TIGER 43 return NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, NSNonRetainedObjectMapValueCallBacks, 0); 44#else 45 // NSMapTable with zeroing weak pointers is the recommended way to build caches like this under garbage collection. 46 NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsOpaquePersonality; 47 NSPointerFunctionsOptions valueOptions = NSPointerFunctionsZeroingWeakMemory | NSPointerFunctionsObjectPersonality; 48 return [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0]; 49#endif 50} 51 52NSMapTable* createWrapperCacheWithIntegerKeys() 53{ 54#ifdef BUILDING_ON_TIGER 55 return NSCreateMapTable(NSIntMapKeyCallBacks, NSNonRetainedObjectMapValueCallBacks, 0); 56#else 57 // NSMapTable with zeroing weak pointers is the recommended way to build caches like this under garbage collection. 58 NSPointerFunctionsOptions keyOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsIntegerPersonality; 59 NSPointerFunctionsOptions valueOptions = NSPointerFunctionsZeroingWeakMemory | NSPointerFunctionsObjectPersonality; 60 return [[NSMapTable alloc] initWithKeyOptions:keyOptions valueOptions:valueOptions capacity:0]; 61#endif 62} 63 64NSObject* getDOMWrapper(DOMObjectInternal* impl) 65{ 66 if (!DOMWrapperCache) 67 return nil; 68 return static_cast<NSObject*>(NSMapGet(DOMWrapperCache, impl)); 69} 70 71void addDOMWrapper(NSObject* wrapper, DOMObjectInternal* impl) 72{ 73 if (!DOMWrapperCache) 74 DOMWrapperCache = createWrapperCache(); 75 NSMapInsert(DOMWrapperCache, impl, wrapper); 76} 77 78void removeDOMWrapper(DOMObjectInternal* impl) 79{ 80 if (!DOMWrapperCache) 81 return; 82 NSMapRemove(DOMWrapperCache, impl); 83} 84 85//------------------------------------------------------------------------------------------ 86 87@implementation WebScriptObject (WebScriptObjectInternal) 88 89// Only called by DOMObject subclass. 90- (id)_init 91{ 92 self = [super init]; 93 94 if (![self isKindOfClass:[DOMObject class]]) { 95 [NSException raise:NSGenericException format:@"+%@: _init is an internal initializer", [self class]]; 96 return nil; 97 } 98 99 _private = [[WebScriptObjectPrivate alloc] init]; 100 _private->isCreatedByDOMWrapper = YES; 101 102 return self; 103} 104 105- (void)_initializeScriptDOMNodeImp 106{ 107 ASSERT(_private->isCreatedByDOMWrapper); 108 109 if (![self isKindOfClass:[DOMNode class]]) { 110 // DOMObject can't map back to a document, and thus an interpreter, 111 // so for now only create wrappers for DOMNodes. 112 NSLog(@"%s:%d: We don't know how to create ObjC JS wrappers from DOMObjects yet.", __FILE__, __LINE__); 113 return; 114 } 115 116 // Extract the WebCore::Node from the ObjectiveC wrapper. 117 DOMNode *n = (DOMNode *)self; 118 WebCore::Node *nodeImpl = core(n); 119 120 // Dig up Interpreter and ExecState. 121 WebCore::Frame *frame = 0; 122 if (WebCore::Document* document = nodeImpl->document()) 123 frame = document->frame(); 124 if (!frame) 125 return; 126 127 // The global object which should own this node. 128 WebCore::JSDOMGlobalObject* globalObject = frame->script()->globalObject(); 129 JSC::ExecState *exec = globalObject->globalExec(); 130 131 // Get (or create) a cached JS object for the DOM node. 132 JSC::JSObject *scriptImp = asObject(WebCore::toJS(exec, globalObject, nodeImpl)); 133 134 JSC::Bindings::RootObject* rootObject = frame->script()->bindingRootObject(); 135 136 [self _setImp:scriptImp originRootObject:rootObject rootObject:rootObject]; 137} 138 139@end 140