1/*
2 * Copyright (C) 2019 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. ``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 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#pragma once
27
28#include "JSProxy.h"
29
30namespace JSC {
31
32 class JSNonDestructibleProxy : public JSProxy {
33 public:
34 using Base = JSProxy;
35 static const unsigned StructureFlags = Base::StructureFlags;
36 static const bool needsDestruction = false;
37
38 template<typename CellType, SubspaceAccess mode>
39 static CompleteSubspace* subspaceFor(VM& vm)
40 {
41 // JSProxy is JSDestrucitbleObject, but we make this JSNonDestructibleProxy non-destructible by using non-destructible subspace.
42 // The motivation behind this is (1) except for JSWindowProxy JSProxy does not need to be destructible, and (2) subspace of destructible
43 // and non-destructible objects are separated and JSProxy is using one MarkedBlock only for JSProxy class in the JSC framework and wasting memory.
44 // Basically, to make objects destructible, objects need to inherit JSDestructibleObject. It holds a classInfo at a specific offset
45 // so that Heap can get methodTable::destroy even if structures held by objects are destroyed before objects' destructions. But this
46 // requirement forces JSProxy to inherit JSDestructibleObject for JSWindowProxy even while the other JSProxy does not need to be
47 // destructible. We create JSNonDestructibleProxy, which is a subclass of JSProxy, and make it non-destructible so that we still keep
48 // JSWindowProxy destructible while making JSNonDestructibleProxy non-destructible.
49 return JSNonFinalObject::subspaceFor<CellType, mode>(vm);
50 }
51
52 static JSNonDestructibleProxy* create(VM& vm, Structure* structure, JSObject* target)
53 {
54 JSNonDestructibleProxy* proxy = new (NotNull, allocateCell<JSNonDestructibleProxy>(vm.heap)) JSNonDestructibleProxy(vm, structure);
55 proxy->finishCreation(vm, target);
56 return proxy;
57 }
58
59 static JSNonDestructibleProxy* create(VM& vm, Structure* structure)
60 {
61 JSNonDestructibleProxy* proxy = new (NotNull, allocateCell<JSNonDestructibleProxy>(vm.heap)) JSNonDestructibleProxy(vm, structure);
62 proxy->finishCreation(vm);
63 return proxy;
64 }
65
66 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, JSType proxyType)
67 {
68 ASSERT(proxyType == ImpureProxyType || proxyType == PureForwardingProxyType);
69 return Structure::create(vm, globalObject, prototype, TypeInfo(proxyType, StructureFlags), info());
70 }
71
72 DECLARE_EXPORT_INFO;
73
74 protected:
75 JSNonDestructibleProxy(VM& vm, Structure* structure)
76 : Base(vm, structure)
77 {
78 }
79 };
80
81} // namespace JSC
82