1/*
2 * Copyright (C) 2014-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#if ENABLE(DFG_JIT)
29
30#include "DFGValueStrength.h"
31#include "JSCJSValue.h"
32#include "JSCast.h"
33#include "Structure.h"
34
35namespace JSC { namespace DFG {
36
37class Graph;
38
39class FrozenValue {
40public:
41 FrozenValue()
42 : m_structure(nullptr)
43 , m_strength(WeakValue)
44 {
45 }
46
47 FrozenValue(JSValue value)
48 : m_value(value)
49 , m_structure(nullptr)
50 , m_strength(WeakValue)
51 {
52 RELEASE_ASSERT(!value || !value.isCell());
53 }
54
55 FrozenValue(JSValue value, Structure* structure, ValueStrength strength)
56 : m_value(value)
57 , m_structure(structure)
58 , m_strength(strength)
59 {
60 ASSERT((!!value && value.isCell()) == !!structure);
61 ASSERT(!value || !value.isCell() || value.asCell()->classInfo(value.asCell()->vm()) == structure->classInfo());
62 ASSERT(!!structure || (strength == WeakValue));
63 }
64
65 static FrozenValue* emptySingleton();
66
67 bool operator!() const { return !m_value; }
68
69 JSValue value() const { return m_value; }
70 JSCell* cell() const { return m_value.asCell(); }
71
72 template<typename T>
73 T dynamicCast(VM& vm)
74 {
75 JSValue theValue = value();
76 if (!theValue)
77 return nullptr;
78 return jsDynamicCast<T>(vm, theValue);
79 }
80 template<typename T>
81 T cast()
82 {
83 return jsCast<T>(value());
84 }
85
86 Structure* structure() const { return m_structure; }
87
88 void strengthenTo(ValueStrength strength)
89 {
90 if (!!m_value && m_value.isCell())
91 m_strength = merge(m_strength, strength);
92 }
93
94 bool pointsToHeap() const { return !!value() && value().isCell(); }
95
96 // The strength of the value itself. The structure is almost always weak.
97 ValueStrength strength() const { return m_strength; }
98
99 String tryGetString(Graph&);
100
101 void dumpInContext(PrintStream& out, DumpContext* context) const;
102 void dump(PrintStream& out) const;
103
104private:
105 friend class Graph;
106
107 // This is a utility method for DFG::Graph::freeze(). You should almost always call
108 // Graph::freeze() directly. Calling this instead of Graph::freeze() can result in
109 // the same constant being viewed as having different structures during the course
110 // of compilation, which can sometimes cause bad things to happen. For example, we
111 // may observe that one version of the constant has an unwatchable structure but
112 // then a later version may start to have a watchable structure due to a transition.
113 // The point of freezing is to ensure that we generally only see one version of
114 // constants, but that requires freezing through the Graph.
115 static FrozenValue freeze(JSValue value)
116 {
117 return FrozenValue(
118 value,
119 (!!value && value.isCell()) ? value.asCell()->structure() : nullptr,
120 WeakValue);
121 }
122
123 JSValue m_value;
124 Structure* m_structure;
125 ValueStrength m_strength;
126};
127
128} } // namespace JSC::DFG
129
130#endif // ENABLE(DFG_JIT)
131