]>
Commit | Line | Data |
---|---|---|
b37bf2e1 A |
1 | /* |
2 | * Copyright (C) 2006, 2007 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 | #include "config.h" | |
27 | #include "JSContextRef.h" | |
f9bf01c6 | 28 | #include "JSContextRefPrivate.h" |
b37bf2e1 A |
29 | |
30 | #include "APICast.h" | |
9dae56ea | 31 | #include "InitializeThreading.h" |
b37bf2e1 A |
32 | #include "JSCallbackObject.h" |
33 | #include "JSClassRef.h" | |
34 | #include "JSGlobalObject.h" | |
9dae56ea | 35 | #include "JSObject.h" |
4e4e5a6f | 36 | #include <wtf/text/StringHash.h> |
b37bf2e1 | 37 | |
f9bf01c6 | 38 | #if OS(DARWIN) |
9dae56ea A |
39 | #include <mach-o/dyld.h> |
40 | ||
41 | static const int32_t webkitFirstVersionWithConcurrentGlobalContexts = 0x2100500; // 528.5.0 | |
42 | #endif | |
43 | ||
44 | using namespace JSC; | |
45 | ||
46 | JSContextGroupRef JSContextGroupCreate() | |
47 | { | |
48 | initializeThreading(); | |
4e4e5a6f | 49 | return toRef(JSGlobalData::createContextGroup(ThreadStackTypeSmall).releaseRef()); |
9dae56ea A |
50 | } |
51 | ||
52 | JSContextGroupRef JSContextGroupRetain(JSContextGroupRef group) | |
53 | { | |
54 | toJS(group)->ref(); | |
55 | return group; | |
56 | } | |
57 | ||
58 | void JSContextGroupRelease(JSContextGroupRef group) | |
59 | { | |
60 | toJS(group)->deref(); | |
61 | } | |
b37bf2e1 A |
62 | |
63 | JSGlobalContextRef JSGlobalContextCreate(JSClassRef globalObjectClass) | |
64 | { | |
9dae56ea | 65 | initializeThreading(); |
f9bf01c6 | 66 | #if OS(DARWIN) |
9dae56ea A |
67 | // When running on Tiger or Leopard, or if the application was linked before JSGlobalContextCreate was changed |
68 | // to use a unique JSGlobalData, we use a shared one for compatibility. | |
69 | #if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) | |
70 | if (NSVersionOfLinkTimeLibrary("JavaScriptCore") <= webkitFirstVersionWithConcurrentGlobalContexts) { | |
71 | #else | |
72 | { | |
73 | #endif | |
f9bf01c6 | 74 | JSLock lock(LockForReal); |
9dae56ea A |
75 | return JSGlobalContextCreateInGroup(toRef(&JSGlobalData::sharedInstance()), globalObjectClass); |
76 | } | |
f9bf01c6 | 77 | #endif // OS(DARWIN) |
9dae56ea A |
78 | |
79 | return JSGlobalContextCreateInGroup(0, globalObjectClass); | |
80 | } | |
81 | ||
82 | JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClassRef globalObjectClass) | |
83 | { | |
84 | initializeThreading(); | |
85 | ||
f9bf01c6 | 86 | JSLock lock(LockForReal); |
4e4e5a6f | 87 | RefPtr<JSGlobalData> globalData = group ? PassRefPtr<JSGlobalData>(toJS(group)) : JSGlobalData::createContextGroup(ThreadStackTypeSmall); |
9dae56ea | 88 | |
f9bf01c6 | 89 | APIEntryShim entryShim(globalData.get(), false); |
9dae56ea A |
90 | |
91 | #if ENABLE(JSC_MULTIPLE_THREADS) | |
92 | globalData->makeUsableFromMultipleThreads(); | |
93 | #endif | |
b37bf2e1 A |
94 | |
95 | if (!globalObjectClass) { | |
9dae56ea | 96 | JSGlobalObject* globalObject = new (globalData.get()) JSGlobalObject; |
b37bf2e1 A |
97 | return JSGlobalContextRetain(toGlobalRef(globalObject->globalExec())); |
98 | } | |
99 | ||
9dae56ea A |
100 | JSGlobalObject* globalObject = new (globalData.get()) JSCallbackObject<JSGlobalObject>(globalObjectClass); |
101 | ExecState* exec = globalObject->globalExec(); | |
ba379fdc | 102 | JSValue prototype = globalObjectClass->prototype(exec); |
b37bf2e1 A |
103 | if (!prototype) |
104 | prototype = jsNull(); | |
9dae56ea A |
105 | globalObject->resetPrototype(prototype); |
106 | return JSGlobalContextRetain(toGlobalRef(exec)); | |
b37bf2e1 A |
107 | } |
108 | ||
109 | JSGlobalContextRef JSGlobalContextRetain(JSGlobalContextRef ctx) | |
110 | { | |
b37bf2e1 | 111 | ExecState* exec = toJS(ctx); |
f9bf01c6 | 112 | APIEntryShim entryShim(exec); |
9dae56ea A |
113 | |
114 | JSGlobalData& globalData = exec->globalData(); | |
b37bf2e1 | 115 | gcProtect(exec->dynamicGlobalObject()); |
9dae56ea | 116 | globalData.ref(); |
b37bf2e1 A |
117 | return ctx; |
118 | } | |
119 | ||
120 | void JSGlobalContextRelease(JSGlobalContextRef ctx) | |
121 | { | |
b37bf2e1 | 122 | ExecState* exec = toJS(ctx); |
9dae56ea A |
123 | JSLock lock(exec); |
124 | ||
f9bf01c6 | 125 | JSGlobalData& globalData = exec->globalData(); |
4e4e5a6f A |
126 | JSGlobalObject* dgo = exec->dynamicGlobalObject(); |
127 | IdentifierTable* savedIdentifierTable = wtfThreadData().setCurrentIdentifierTable(globalData.identifierTable); | |
128 | ||
129 | // One reference is held by JSGlobalObject, another added by JSGlobalContextRetain(). | |
130 | bool releasingContextGroup = globalData.refCount() == 2; | |
131 | bool releasingGlobalObject = Heap::heap(dgo)->unprotect(dgo); | |
132 | // If this is the last reference to a global data, it should also | |
133 | // be the only remaining reference to the global object too! | |
134 | ASSERT(!releasingContextGroup || releasingGlobalObject); | |
135 | ||
136 | // An API 'JSGlobalContextRef' retains two things - a global object and a | |
137 | // global data (or context group, in API terminology). | |
138 | // * If this is the last reference to any contexts in the given context group, | |
139 | // call destroy on the heap (the global data is being freed). | |
140 | // * If this was the last reference to the global object, then unprotecting | |
141 | // it may release a lot of GC memory - run the garbage collector now. | |
142 | // * If there are more references remaining the the global object, then do nothing | |
143 | // (specifically that is more protects, which we assume come from other JSGlobalContextRefs). | |
144 | if (releasingContextGroup) | |
9dae56ea | 145 | globalData.heap.destroy(); |
4e4e5a6f | 146 | else if (releasingGlobalObject) |
f9bf01c6 | 147 | globalData.heap.collectAllGarbage(); |
9dae56ea A |
148 | |
149 | globalData.deref(); | |
f9bf01c6 | 150 | |
4e4e5a6f | 151 | wtfThreadData().setCurrentIdentifierTable(savedIdentifierTable); |
b37bf2e1 A |
152 | } |
153 | ||
154 | JSObjectRef JSContextGetGlobalObject(JSContextRef ctx) | |
155 | { | |
156 | ExecState* exec = toJS(ctx); | |
f9bf01c6 | 157 | APIEntryShim entryShim(exec); |
9dae56ea A |
158 | |
159 | // It is necessary to call toThisObject to get the wrapper object when used with WebCore. | |
160 | return toRef(exec->lexicalGlobalObject()->toThisObject(exec)); | |
161 | } | |
162 | ||
163 | JSContextGroupRef JSContextGetGroup(JSContextRef ctx) | |
164 | { | |
165 | ExecState* exec = toJS(ctx); | |
166 | return toRef(&exec->globalData()); | |
b37bf2e1 | 167 | } |
f9bf01c6 A |
168 | |
169 | JSGlobalContextRef JSContextGetGlobalContext(JSContextRef ctx) | |
170 | { | |
171 | ExecState* exec = toJS(ctx); | |
172 | APIEntryShim entryShim(exec); | |
173 | ||
174 | return toGlobalRef(exec->lexicalGlobalObject()->globalExec()); | |
175 | } |