Home | History | Annotate | Download | only in objc
      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 
     38 static NSMapTable* DOMWrapperCache;
     39 
     40 NSMapTable* 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 
     52 NSObject* getDOMWrapper(DOMObjectInternal* impl)
     53 {
     54     if (!DOMWrapperCache)
     55         return nil;
     56     return static_cast<NSObject*>(NSMapGet(DOMWrapperCache, impl));
     57 }
     58 
     59 void addDOMWrapper(NSObject* wrapper, DOMObjectInternal* impl)
     60 {
     61     if (!DOMWrapperCache)
     62         DOMWrapperCache = createWrapperCache();
     63     NSMapInsert(DOMWrapperCache, impl, wrapper);
     64 }
     65 
     66 void removeDOMWrapper(DOMObjectInternal* impl)
     67 {
     68     if (!DOMWrapperCache)
     69         return;
     70     NSMapRemove(DOMWrapperCache, impl);
     71 }
     72 
     73 //------------------------------------------------------------------------------------------
     74 
     75 @implementation WebScriptObject (WebScriptObjectInternal)
     76 
     77 // Only called by DOMObject subclass.
     78 - (id)_init
     79 {
     80     self = [super init];
     81 
     82     if (![self isKindOfClass:[DOMObject class]]) {
     83         [NSException raise:NSGenericException format:@"+%@: _init is an internal initializer", [self class]];
     84         return nil;
     85     }
     86 
     87     _private = [[WebScriptObjectPrivate alloc] init];
     88     _private->isCreatedByDOMWrapper = YES;
     89 
     90     return self;
     91 }
     92 
     93 - (void)_initializeScriptDOMNodeImp
     94 {
     95     ASSERT(_private->isCreatedByDOMWrapper);
     96 
     97     if (![self isKindOfClass:[DOMNode class]]) {
     98         // DOMObject can't map back to a document, and thus an interpreter,
     99         // so for now only create wrappers for DOMNodes.
    100         NSLog(@"%s:%d:  We don't know how to create ObjC JS wrappers from DOMObjects yet.", __FILE__, __LINE__);
    101         return;
    102     }
    103 
    104     // Extract the WebCore::Node from the ObjectiveC wrapper.
    105     DOMNode *n = (DOMNode *)self;
    106     WebCore::Node *nodeImpl = core(n);
    107 
    108     // Dig up Interpreter and ExecState.
    109     WebCore::Frame *frame = 0;
    110     if (WebCore::Document* document = nodeImpl->document())
    111         frame = document->frame();
    112     if (!frame)
    113         return;
    114 
    115     // The global object which should own this node - FIXME: does this need to be isolated-world aware?
    116     WebCore::JSDOMGlobalObject* globalObject = frame->script()->globalObject(WebCore::mainThreadNormalWorld());
    117     JSC::ExecState *exec = globalObject->globalExec();
    118 
    119     // Get (or create) a cached JS object for the DOM node.
    120     JSC::JSObject *scriptImp = asObject(WebCore::toJS(exec, globalObject, nodeImpl));
    121 
    122     JSC::Bindings::RootObject* rootObject = frame->script()->bindingRootObject();
    123 
    124     [self _setImp:scriptImp originRootObject:rootObject rootObject:rootObject];
    125 }
    126 
    127 @end
    128