f167908a127dc579d634f1fc42570a26f91b7660
[WebKit-https.git] / Source / JavaScriptCore / runtime / JSArrayBuffer.cpp
1 /*
2  * Copyright (C) 2013, 2016 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 #include "config.h"
27 #include "JSArrayBuffer.h"
28
29 #include "JSCInlines.h"
30 #include "Reject.h"
31
32 namespace JSC {
33
34 const ClassInfo JSArrayBuffer::s_info = {
35     "ArrayBuffer", &Base::s_info, 0, CREATE_METHOD_TABLE(JSArrayBuffer)};
36
37 JSArrayBuffer::JSArrayBuffer(VM& vm, Structure* structure, PassRefPtr<ArrayBuffer> arrayBuffer)
38     : Base(vm, structure)
39     , m_impl(arrayBuffer.get())
40 {
41 }
42
43 void JSArrayBuffer::finishCreation(VM& vm, JSGlobalObject* globalObject)
44 {
45     Base::finishCreation(vm);
46     vm.heap.addReference(this, m_impl);
47     vm.m_typedArrayController->registerWrapper(globalObject, m_impl, this);
48 }
49
50 JSArrayBuffer* JSArrayBuffer::create(
51     VM& vm, Structure* structure, PassRefPtr<ArrayBuffer> passedBuffer)
52 {
53     RefPtr<ArrayBuffer> buffer = passedBuffer;
54     JSArrayBuffer* result =
55         new (NotNull, allocateCell<JSArrayBuffer>(vm.heap))
56         JSArrayBuffer(vm, structure, buffer);
57     result->finishCreation(vm, structure->globalObject());
58     return result;
59 }
60
61 Structure* JSArrayBuffer::createStructure(
62     VM& vm, JSGlobalObject* globalObject, JSValue prototype)
63 {
64     return Structure::create(
65         vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info(),
66         NonArray);
67 }
68
69 size_t JSArrayBuffer::estimatedSize(JSCell* cell)
70 {
71     JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(cell);
72     size_t bufferEstimatedSize = thisObject->impl()->gcSizeEstimateInBytes();
73     return Base::estimatedSize(cell) + bufferEstimatedSize;
74 }
75
76 bool JSArrayBuffer::getOwnPropertySlot(
77     JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
78 {
79     JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(object);
80     
81     if (propertyName == exec->propertyNames().byteLength) {
82         slot.setValue(thisObject, DontDelete | ReadOnly, jsNumber(thisObject->impl()->byteLength()));
83         return true;
84     }
85     
86     return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
87 }
88
89 bool JSArrayBuffer::put(
90     JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value,
91     PutPropertySlot& slot)
92 {
93     VM& vm = exec->vm();
94     auto scope = DECLARE_THROW_SCOPE(vm);
95     JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(cell);
96
97     if (UNLIKELY(isThisValueAltered(slot, thisObject)))
98         return ordinarySetSlow(exec, thisObject, propertyName, value, slot.thisValue(), slot.isStrictMode());
99     
100     if (propertyName == vm.propertyNames->byteLength)
101         return reject(exec, scope, slot.isStrictMode(), ASCIILiteral("Attempting to write to a read-only array buffer property."));
102     
103     return Base::put(thisObject, exec, propertyName, value, slot);
104 }
105
106 bool JSArrayBuffer::defineOwnProperty(
107     JSObject* object, ExecState* exec, PropertyName propertyName,
108     const PropertyDescriptor& descriptor, bool shouldThrow)
109 {
110     VM& vm = exec->vm();
111     auto scope = DECLARE_THROW_SCOPE(vm);
112     JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(object);
113     
114     if (propertyName == vm.propertyNames->byteLength)
115         return reject(exec, scope, shouldThrow, ASCIILiteral("Attempting to define read-only array buffer property."));
116     
117     return Base::defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow);
118 }
119
120 bool JSArrayBuffer::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
121 {
122     JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(cell);
123     
124     if (propertyName == exec->propertyNames().byteLength)
125         return false;
126     
127     return Base::deleteProperty(thisObject, exec, propertyName);
128 }
129
130 void JSArrayBuffer::getOwnNonIndexPropertyNames(
131     JSObject* object, ExecState* exec, PropertyNameArray& array, EnumerationMode mode)
132 {
133     JSArrayBuffer* thisObject = jsCast<JSArrayBuffer*>(object);
134     
135     if (mode.includeDontEnumProperties())
136         array.add(exec->propertyNames().byteLength);
137     
138     Base::getOwnNonIndexPropertyNames(thisObject, exec, array, mode);
139 }
140
141 } // namespace JSC
142