We should support CreateThis in the FTL
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSProxy.cpp
1 /*
2  * Copyright (C) 2011-2012, 2016-2017 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 #include "config.h"
27 #include "JSProxy.h"
28
29 #include "JSGlobalObject.h"
30 #include "JSCInlines.h"
31
32 namespace JSC {
33
34 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSProxy);
35
36 const ClassInfo JSProxy::s_info = { "JSProxy", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSProxy) };
37
38 void JSProxy::visitChildren(JSCell* cell, SlotVisitor& visitor)
39 {
40     JSProxy* thisObject = jsCast<JSProxy*>(cell);
41     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
42     Base::visitChildren(thisObject, visitor);
43     visitor.append(thisObject->m_target);
44 }
45
46 void JSProxy::setTarget(VM& vm, JSGlobalObject* globalObject)
47 {
48     m_target.set(vm, this, globalObject);
49     setPrototypeDirect(vm, globalObject->getPrototypeDirect(vm));
50 }
51
52 String JSProxy::className(const JSObject* object, VM& vm)
53 {
54     const JSProxy* thisObject = jsCast<const JSProxy*>(object);
55     return thisObject->target()->methodTable(vm)->className(thisObject->target(), vm);
56 }
57
58 String JSProxy::toStringName(const JSObject* object, ExecState* exec)
59 {
60     const JSProxy* thisObject = jsCast<const JSProxy*>(object);
61     return thisObject->target()->methodTable(exec->vm())->toStringName(thisObject->target(), exec);
62 }
63
64 bool JSProxy::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
65 {
66     JSProxy* thisObject = jsCast<JSProxy*>(object);
67     return thisObject->target()->methodTable(exec->vm())->getOwnPropertySlot(thisObject->target(), exec, propertyName, slot);
68 }
69
70 bool JSProxy::getOwnPropertySlotByIndex(JSObject* object, ExecState* exec, unsigned propertyName, PropertySlot& slot)
71 {
72     JSProxy* thisObject = jsCast<JSProxy*>(object);
73     return thisObject->target()->methodTable(exec->vm())->getOwnPropertySlotByIndex(thisObject->target(), exec, propertyName, slot);
74 }
75
76 bool JSProxy::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
77 {
78     JSProxy* thisObject = jsCast<JSProxy*>(cell);
79     return thisObject->target()->methodTable(exec->vm())->put(thisObject->target(), exec, propertyName, value, slot);
80 }
81
82 bool JSProxy::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
83 {
84     JSProxy* thisObject = jsCast<JSProxy*>(cell);
85     return thisObject->target()->methodTable(exec->vm())->putByIndex(thisObject->target(), exec, propertyName, value, shouldThrow);
86 }
87
88 bool JSProxy::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow)
89 {
90     JSProxy* thisObject = jsCast<JSProxy*>(object);
91     return thisObject->target()->methodTable(exec->vm())->defineOwnProperty(thisObject->target(), exec, propertyName, descriptor, shouldThrow);
92 }
93
94 bool JSProxy::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
95 {
96     JSProxy* thisObject = jsCast<JSProxy*>(cell);
97     return thisObject->target()->methodTable(exec->vm())->deleteProperty(thisObject->target(), exec, propertyName);
98 }
99
100 bool JSProxy::isExtensible(JSObject* object, ExecState* exec)
101 {
102     JSProxy* thisObject = jsCast<JSProxy*>(object);
103     return thisObject->target()->methodTable(exec->vm())->isExtensible(thisObject->target(), exec);
104 }
105
106 bool JSProxy::preventExtensions(JSObject* object, ExecState* exec)
107 {
108     JSProxy* thisObject = jsCast<JSProxy*>(object);
109     return thisObject->target()->methodTable(exec->vm())->preventExtensions(thisObject->target(), exec);
110 }
111
112 bool JSProxy::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned propertyName)
113 {
114     JSProxy* thisObject = jsCast<JSProxy*>(cell);
115     return thisObject->target()->methodTable(exec->vm())->deletePropertyByIndex(thisObject->target(), exec, propertyName);
116 }
117
118 void JSProxy::getPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
119 {
120     JSProxy* thisObject = jsCast<JSProxy*>(object);
121     thisObject->target()->methodTable(exec->vm())->getPropertyNames(thisObject->target(), exec, propertyNames, mode);
122 }
123
124 uint32_t JSProxy::getEnumerableLength(ExecState* exec, JSObject* object)
125 {
126     JSProxy* thisObject = jsCast<JSProxy*>(object);
127     return thisObject->target()->methodTable(exec->vm())->getEnumerableLength(exec, thisObject->target());
128 }
129
130 void JSProxy::getStructurePropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode)
131 {
132     // Skip the structure loop, since it is invalid for proxies.
133 }
134
135 void JSProxy::getGenericPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
136 {
137     JSProxy* thisObject = jsCast<JSProxy*>(object);
138     // Get *all* of the property names, not just the generic ones, since we skipped the structure
139     // ones above.
140     thisObject->target()->methodTable(exec->vm())->getPropertyNames(thisObject->target(), exec, propertyNames, mode);
141 }
142
143 void JSProxy::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
144 {
145     JSProxy* thisObject = jsCast<JSProxy*>(object);
146     thisObject->target()->methodTable(exec->vm())->getOwnPropertyNames(thisObject->target(), exec, propertyNames, mode);
147 }
148
149 bool JSProxy::setPrototype(JSObject* object, ExecState* exec, JSValue prototype, bool shouldThrowIfCantSet)
150 {
151     JSProxy* thisObject = jsCast<JSProxy*>(object);
152     return thisObject->target()->methodTable(exec->vm())->setPrototype(thisObject->target(), exec, prototype, shouldThrowIfCantSet);
153 }
154
155 JSValue JSProxy::getPrototype(JSObject* object, ExecState* exec)
156 {
157     JSProxy* thisObject = jsCast<JSProxy*>(object);
158     return thisObject->target()->methodTable(exec->vm())->getPrototype(thisObject->target(), exec);
159 }
160
161 } // namespace JSC