1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block/*
2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2009 Apple Inc. All rights reserved.
3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Redistribution and use in source and binary forms, with or without
5643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * modification, are permitted provided that the following conditions
6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * are met:
7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 1.  Redistributions of source code must retain the above copyright
8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     notice, this list of conditions and the following disclaimer.
9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 2.  Redistributions in binary form must reproduce the above copyright
10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     notice, this list of conditions and the following disclaimer in the
11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     documentation and/or other materials provided with the distribution.
12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */
24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "config.h"
26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebKitDLL.h"
27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebScriptWorld.h"
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
29d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <JavaScriptCore/APICast.h>
30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <WebCore/JSDOMBinding.h>
31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <WebCore/ScriptController.h>
32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
33643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace WebCore;
34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
35643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocktypedef HashMap<DOMWrapperWorld*, WebScriptWorld*> WorldMap;
36643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic WorldMap& allWorlds()
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    static WorldMap& map = *new WorldMap;
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return map;
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockinline WebScriptWorld::WebScriptWorld(PassRefPtr<DOMWrapperWorld> world)
43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    : m_refCount(0)
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    , m_world(world)
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT_ARG(world, m_world);
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT_ARG(world, !allWorlds().contains(m_world.get()));
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    allWorlds().add(m_world.get(), this);
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ++gClassCount;
52643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    gClassNameCount.add("WebScriptWorld");
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
55643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebScriptWorld::~WebScriptWorld()
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(allWorlds().contains(m_world.get()));
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    allWorlds().remove(m_world.get());
59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    --gClassCount;
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    gClassNameCount.remove("WebScriptWorld");
62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
64643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebScriptWorld* WebScriptWorld::standardWorld()
65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    static WebScriptWorld* standardWorld = createInstance(mainThreadNormalWorld()).releaseRef();
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return standardWorld;
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
70643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockCOMPtr<WebScriptWorld> WebScriptWorld::createInstance()
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return createInstance(ScriptController::createWorld());
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
75643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockCOMPtr<WebScriptWorld> WebScriptWorld::createInstance(PassRefPtr<DOMWrapperWorld> world)
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return new WebScriptWorld(world);
78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
80643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockCOMPtr<WebScriptWorld> WebScriptWorld::findOrCreateWorld(DOMWrapperWorld* world)
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (world == mainThreadNormalWorld())
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return standardWorld();
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (WebScriptWorld* existingWorld = allWorlds().get(world))
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return existingWorld;
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return createInstance(world);
89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
91643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockULONG WebScriptWorld::AddRef()
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return ++m_refCount;
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
96643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockULONG WebScriptWorld::Release()
97643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
98643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ULONG newRefCount = --m_refCount;
99643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!newRefCount)
100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        delete this;
101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return newRefCount;
102643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
104643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockHRESULT WebScriptWorld::QueryInterface(REFIID riid, void** ppvObject)
105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!ppvObject)
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return E_POINTER;
108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    *ppvObject = 0;
109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (IsEqualIID(riid, __uuidof(WebScriptWorld)))
111643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        *ppvObject = this;
112643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else if (IsEqualIID(riid, __uuidof(IWebScriptWorld)))
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        *ppvObject = static_cast<IWebScriptWorld*>(this);
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else if (IsEqualIID(riid, IID_IUnknown))
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        *ppvObject = static_cast<IUnknown*>(this);
116643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    else
117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return E_NOINTERFACE;
118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    AddRef();
120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return S_OK;
121643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
123643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockHRESULT WebScriptWorld::standardWorld(IWebScriptWorld** outWorld)
124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
125643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (!outWorld)
126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        return E_POINTER;
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    *outWorld = standardWorld();
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    (*outWorld)->AddRef();
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return S_OK;
131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
132d0825bca7fe65beaee391d30da42e937db621564Steve Block
133d0825bca7fe65beaee391d30da42e937db621564Steve BlockHRESULT WebScriptWorld::scriptWorldForGlobalContext(JSGlobalContextRef context, IWebScriptWorld** outWorld)
134d0825bca7fe65beaee391d30da42e937db621564Steve Block{
135d0825bca7fe65beaee391d30da42e937db621564Steve Block    if (!outWorld)
136d0825bca7fe65beaee391d30da42e937db621564Steve Block        return E_POINTER;
137d0825bca7fe65beaee391d30da42e937db621564Steve Block    return findOrCreateWorld(currentWorld(toJS(context))).copyRefTo(outWorld);
138d0825bca7fe65beaee391d30da42e937db621564Steve Block}
139dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block
140dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve BlockHRESULT WebScriptWorld::unregisterWorld()
141dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block{
142cad810f21b803229eb11403f9209855525a25d57Steve Block    m_world->clearWrappers();
143dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    return S_OK;
144dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block}
145