1/*
2 * Copyright (C) 2008-2018 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 "JSCJSValue.h"
29#include "PropertySlot.h"
30#include <wtf/Assertions.h>
31
32namespace JSC {
33
34class JSObject;
35class JSFunction;
36
37class PutPropertySlot {
38public:
39 enum Type : uint8_t { Uncachable, ExistingProperty, NewProperty, SetterProperty, CustomValue, CustomAccessor };
40 enum Context { UnknownContext, PutById, PutByIdEval };
41 typedef bool (*PutValueFunc)(JSGlobalObject*, EncodedJSValue thisObject, EncodedJSValue value);
42
43 PutPropertySlot(JSValue thisValue, bool isStrictMode = false, Context context = UnknownContext, bool isInitialization = false)
44 : m_base(0)
45 , m_thisValue(thisValue)
46 , m_offset(invalidOffset)
47 , m_isStrictMode(isStrictMode)
48 , m_isInitialization(isInitialization)
49 , m_type(Uncachable)
50 , m_context(context)
51 , m_cacheability(CachingAllowed)
52 {
53 }
54
55 void setExistingProperty(JSObject* base, PropertyOffset offset)
56 {
57 m_type = ExistingProperty;
58 m_base = base;
59 m_offset = offset;
60 }
61
62 void setNewProperty(JSObject* base, PropertyOffset offset)
63 {
64 m_type = NewProperty;
65 m_base = base;
66 m_offset = offset;
67 }
68
69 void setCustomValue(JSObject* base, FunctionPtr<OperationPtrTag> function)
70 {
71 m_type = CustomValue;
72 m_base = base;
73 m_putFunction = function;
74 }
75
76 void setCustomAccessor(JSObject* base, FunctionPtr<OperationPtrTag> function)
77 {
78 m_type = CustomAccessor;
79 m_base = base;
80 m_putFunction = function;
81 }
82
83 void setCacheableSetter(JSObject* base, PropertyOffset offset)
84 {
85 m_type = SetterProperty;
86 m_base = base;
87 m_offset = offset;
88 }
89
90 void setThisValue(JSValue thisValue)
91 {
92 m_thisValue = thisValue;
93 }
94
95 void setStrictMode(bool value)
96 {
97 m_isStrictMode = value;
98 }
99
100 FunctionPtr<OperationPtrTag> customSetter() const
101 {
102 ASSERT(isCacheableCustom());
103 return m_putFunction;
104 }
105
106 Context context() const { return static_cast<Context>(m_context); }
107
108 Type type() const { return m_type; }
109 JSObject* base() const { return m_base; }
110 JSValue thisValue() const { return m_thisValue; }
111
112 bool isStrictMode() const { return m_isStrictMode; }
113 bool isCacheablePut() const { return isCacheable() && (m_type == NewProperty || m_type == ExistingProperty); }
114 bool isCacheableSetter() const { return isCacheable() && m_type == SetterProperty; }
115 bool isCacheableCustom() const { return isCacheable() && (m_type == CustomValue || m_type == CustomAccessor); }
116 bool isCustomAccessor() const { return isCacheable() && m_type == CustomAccessor; }
117 bool isInitialization() const { return m_isInitialization; }
118
119 PropertyOffset cachedOffset() const
120 {
121 return m_offset;
122 }
123
124 void disableCaching()
125 {
126 m_cacheability = CachingDisallowed;
127 }
128
129private:
130 bool isCacheable() const { return m_cacheability == CachingAllowed; }
131
132 JSObject* m_base;
133 JSValue m_thisValue;
134 PropertyOffset m_offset;
135 bool m_isStrictMode : 1;
136 bool m_isInitialization : 1;
137 Type m_type;
138 uint8_t m_context;
139 CacheabilityType m_cacheability;
140 FunctionPtr<OperationPtrTag> m_putFunction;
141};
142
143} // namespace JSC
144