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