[Cocoa] Adapt more WebKit code to be ARC-compatible
[WebKit-https.git] / Source / WebKit / Shared / Cocoa / APIObject.mm
1 /*
2  * Copyright (C) 2013 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''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27 #import "APIObject.h"
28
29 #if WK_API_ENABLED
30
31 #import "WKBackForwardListInternal.h"
32 #import "WKBackForwardListItemInternal.h"
33 #import "WKBrowsingContextControllerInternal.h"
34 #import "WKBrowsingContextGroupInternal.h"
35 #import "WKConnectionInternal.h"
36 #import "WKContentRuleListInternal.h"
37 #import "WKContentRuleListStoreInternal.h"
38 #import "WKFrameInfoInternal.h"
39 #import "WKHTTPCookieStoreInternal.h"
40 #import "WKNSArray.h"
41 #import "WKNSData.h"
42 #import "WKNSDictionary.h"
43 #import "WKNSError.h"
44 #import "WKNSNumber.h"
45 #import "WKNSString.h"
46 #import "WKNSURL.h"
47 #import "WKNSURLAuthenticationChallenge.h"
48 #import "WKNSURLRequest.h"
49 #import "WKNavigationActionInternal.h"
50 #import "WKNavigationDataInternal.h"
51 #import "WKNavigationInternal.h"
52 #import "WKNavigationResponseInternal.h"
53 #import "WKOpenPanelParametersInternal.h"
54 #import "WKPreferencesInternal.h"
55 #import "WKProcessPoolInternal.h"
56 #import "WKSecurityOriginInternal.h"
57 #import "WKURLSchemeTaskInternal.h"
58 #import "WKUserContentControllerInternal.h"
59 #import "WKUserScriptInternal.h"
60 #import "WKWebProcessPlugInBrowserContextControllerInternal.h"
61 #import "WKWebProcessPlugInFrameInternal.h"
62 #import "WKWebProcessPlugInHitTestResultInternal.h"
63 #import "WKWebProcessPlugInInternal.h"
64 #import "WKWebProcessPlugInNodeHandleInternal.h"
65 #import "WKWebProcessPlugInPageGroupInternal.h"
66 #import "WKWebProcessPlugInRangeHandleInternal.h"
67 #import "WKWebProcessPlugInScriptWorldInternal.h"
68 #import "WKWebsiteDataRecordInternal.h"
69 #import "WKWebsiteDataStoreInternal.h"
70 #import "WKWindowFeaturesInternal.h"
71 #import "_WKAttachmentInternal.h"
72 #import "_WKAutomationSessionInternal.h"
73 #import "_WKDownloadInternal.h"
74 #import "_WKExperimentalFeatureInternal.h"
75 #import "_WKFrameHandleInternal.h"
76 #import "_WKGeolocationPositionInternal.h"
77 #import "_WKHitTestResultInternal.h"
78 #import "_WKInspectorInternal.h"
79 #import "_WKProcessPoolConfigurationInternal.h"
80 #import "_WKUserContentWorldInternal.h"
81 #import "_WKUserInitiatedActionInternal.h"
82 #import "_WKUserStyleSheetInternal.h"
83 #import "_WKVisitedLinkStoreInternal.h"
84 #import "_WKWebsitePoliciesInternal.h"
85
86 #if ENABLE(APPLICATION_MANIFEST)
87 #import "_WKApplicationManifestInternal.h"
88 #endif
89
90 static const size_t minimumObjectAlignment = 8;
91 static_assert(minimumObjectAlignment >= alignof(void*), "Objects should always be at least pointer-aligned.");
92 static const size_t maximumExtraSpaceForAlignment = minimumObjectAlignment - alignof(void*);
93
94 namespace API {
95
96 void Object::ref()
97 {
98     CFRetain((__bridge CFTypeRef)wrapper());
99 }
100
101 void Object::deref()
102 {
103     CFRelease((__bridge CFTypeRef)wrapper());
104 }
105
106 static id <WKObject> allocateWKObject(Class cls, size_t size)
107 {
108     return class_createInstance(cls, size + maximumExtraSpaceForAlignment);
109 }
110
111 API::Object& Object::fromWKObjectExtraSpace(id <WKObject> obj)
112 {
113     size_t size = sizeof(API::Object);
114     size_t spaceAvailable = size + maximumExtraSpaceForAlignment;
115     void* indexedIvars = object_getIndexedIvars(obj);
116     return *static_cast<API::Object*>(std::align(minimumObjectAlignment, size, indexedIvars, spaceAvailable));
117 }
118
119 void* Object::newObject(size_t size, Type type)
120 {
121     id <WKObject> wrapper;
122
123     // Wrappers that inherit from WKObject store the API::Object in their extra bytes, so they are
124     // allocated using NSAllocatedObject. The other wrapper classes contain inline storage for the
125     // API::Object, so they are allocated using +alloc.
126
127     switch (type) {
128 #if ENABLE(APPLICATION_MANIFEST)
129     case Type::ApplicationManifest:
130         wrapper = [_WKApplicationManifest alloc];
131         break;
132 #endif
133
134     case Type::Array:
135         wrapper = [WKNSArray alloc];
136         break;
137
138 #if ENABLE(ATTACHMENT_ELEMENT)
139     case Type::Attachment:
140         wrapper = [_WKAttachment alloc];
141         break;
142 #endif
143
144     case Type::AuthenticationChallenge:
145         wrapper = allocateWKObject([WKNSURLAuthenticationChallenge self], size);
146         break;
147
148     case Type::AutomationSession:
149         wrapper = [_WKAutomationSession alloc];
150         break;
151
152     case Type::BackForwardList:
153         wrapper = [WKBackForwardList alloc];
154         break;
155
156     case Type::BackForwardListItem:
157         wrapper = [WKBackForwardListItem alloc];
158         break;
159
160     case Type::Boolean:
161     case Type::Double:
162     case Type::UInt64:
163         wrapper = [WKNSNumber alloc];
164         ((WKNSNumber *)wrapper)->_type = type;
165         break;
166
167     case Type::Bundle:
168         wrapper = [WKWebProcessPlugInController alloc];
169         break;
170
171     case Type::BundlePage:
172         wrapper = [WKWebProcessPlugInBrowserContextController alloc];
173         break;
174
175     case Type::Connection:
176         // While not actually a WKObject instance, WKConnection uses allocateWKObject to allocate extra space
177         // instead of using ObjectStorage because the wrapped C++ object is a subclass of WebConnection.
178         wrapper = allocateWKObject([WKConnection self], size);
179         break;
180
181     case Type::Preferences:
182         wrapper = [WKPreferences alloc];
183         break;
184
185     case Type::ProcessPool:
186         wrapper = [WKProcessPool alloc];
187         break;
188
189     case Type::ProcessPoolConfiguration:
190         wrapper = [_WKProcessPoolConfiguration alloc];
191         break;
192
193     case Type::Data:
194         wrapper = [WKNSData alloc];
195         break;
196
197     case Type::Dictionary:
198         wrapper = [WKNSDictionary alloc];
199         break;
200
201     case Type::Download:
202         wrapper = [_WKDownload alloc];
203         break;
204
205     case Type::ExperimentalFeature:
206         wrapper = [_WKExperimentalFeature alloc];
207         break;
208
209     case Type::Error:
210         wrapper = allocateWKObject([WKNSError self], size);
211         break;
212
213     case Type::FrameHandle:
214         wrapper = [_WKFrameHandle alloc];
215         break;
216
217     case Type::FrameInfo:
218         wrapper = [WKFrameInfo alloc];
219         break;
220
221 #if PLATFORM(IOS)
222     case Type::GeolocationPosition:
223         wrapper = [_WKGeolocationPosition alloc];
224         break;
225 #endif
226
227     case Type::HTTPCookieStore:
228         wrapper = [WKHTTPCookieStore alloc];
229         break;
230
231 #if PLATFORM(MAC)
232     case Type::HitTestResult:
233         wrapper = [_WKHitTestResult alloc];
234         break;
235 #endif
236
237     case Type::Inspector:
238         wrapper = [_WKInspector alloc];
239         break;
240         
241     case Type::Navigation:
242         wrapper = [WKNavigation alloc];
243         break;
244
245     case Type::NavigationAction:
246         wrapper = [WKNavigationAction alloc];
247         break;
248
249     case Type::NavigationData:
250         wrapper = [WKNavigationData alloc];
251         break;
252
253     case Type::NavigationResponse:
254         wrapper = [WKNavigationResponse alloc];
255         break;
256
257 #if PLATFORM(MAC)
258     case Type::OpenPanelParameters:
259         wrapper = [WKOpenPanelParameters alloc];
260         break;
261 #endif
262
263     case Type::PageGroup:
264         wrapper = [WKBrowsingContextGroup alloc];
265         break;
266
267     case Type::SecurityOrigin:
268         wrapper = [WKSecurityOrigin alloc];
269         break;
270
271     case Type::String:
272         wrapper = allocateWKObject([WKNSString self], size);
273         break;
274
275     case Type::URL:
276         wrapper = allocateWKObject([WKNSURL self], size);
277         break;
278
279     case Type::URLRequest:
280         wrapper = allocateWKObject([WKNSURLRequest self], size);
281         break;
282
283     case Type::URLSchemeTask:
284         wrapper = [WKURLSchemeTaskImpl alloc];
285         break;
286
287     case Type::UserContentController:
288         wrapper = [WKUserContentController alloc];
289         break;
290
291     case Type::ContentRuleList:
292         wrapper = [WKContentRuleList alloc];
293         break;
294
295     case Type::ContentRuleListStore:
296         wrapper = [WKContentRuleListStore alloc];
297         break;
298
299     case Type::UserContentWorld:
300         wrapper = [_WKUserContentWorld alloc];
301         break;
302
303     case Type::UserInitiatedAction:
304         wrapper = [_WKUserInitiatedAction alloc];
305         break;
306
307     case Type::UserScript:
308         wrapper = [WKUserScript alloc];
309         break;
310
311     case Type::UserStyleSheet:
312         wrapper = [_WKUserStyleSheet alloc];
313         break;
314
315     case Type::VisitedLinkStore:
316         wrapper = [_WKVisitedLinkStore alloc];
317         break;
318
319     case Type::WebsiteDataRecord:
320         wrapper = [WKWebsiteDataRecord alloc];
321         break;
322
323     case Type::WebsiteDataStore:
324         wrapper = [WKWebsiteDataStore alloc];
325         break;
326
327     case Type::WebsitePolicies:
328         wrapper = [_WKWebsitePolicies alloc];
329         break;
330
331     case Type::WindowFeatures:
332         wrapper = [WKWindowFeatures alloc];
333         break;
334
335     case Type::BundleFrame:
336         wrapper = [WKWebProcessPlugInFrame alloc];
337         break;
338
339     case Type::BundleHitTestResult:
340         wrapper = [WKWebProcessPlugInHitTestResult alloc];
341         break;
342
343     case Type::BundleNodeHandle:
344         wrapper = [WKWebProcessPlugInNodeHandle alloc];
345         break;
346
347     case Type::BundlePageGroup:
348         wrapper = [WKWebProcessPlugInPageGroup alloc];
349         break;
350
351     case Type::BundleRangeHandle:
352         wrapper = [WKWebProcessPlugInRangeHandle alloc];
353         break;
354
355     case Type::BundleScriptWorld:
356         wrapper = [WKWebProcessPlugInScriptWorld alloc];
357         break;
358
359     default:
360         wrapper = allocateWKObject([WKObject self], size);
361         break;
362     }
363
364     Object& object = wrapper._apiObject;
365     object.m_wrapper = wrapper;
366
367     return &object;
368 }
369
370 void* Object::wrap(API::Object* object)
371 {
372     if (!object)
373         return nullptr;
374
375     return (__bridge void*)object->wrapper();
376 }
377
378 API::Object* Object::unwrap(void* object)
379 {
380     if (!object)
381         return nullptr;
382
383     return &((__bridge id <WKObject>)object)._apiObject;
384 }
385
386 } // namespace API
387
388 #endif // WK_API_ENABLED