]> git.saurik.com Git - apple/javascriptcore.git/blame - bytecode/ComplexGetStatus.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / bytecode / ComplexGetStatus.h
CommitLineData
ed1e77d3
A
1/*
2 * Copyright (C) 2014 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#ifndef ComplexGetStatus_h
27#define ComplexGetStatus_h
28
29#include "IntendedStructureChain.h"
30#include "JSCJSValue.h"
31#include "PropertyOffset.h"
32
33namespace JSC {
34
35class CodeBlock;
36class StructureChain;
37
38// This class is useful for figuring out how to inline a cached get-like access. We
39// say "get-like" because this is appropriate for loading the GetterSetter object in
40// a put_by_id that hits a setter. Notably, this doesn't figure out how to call
41// accessors, or even whether they should be called. What it gives us, is a way of
42// determining how to load the value from the requested property (identified by a
43// StringImpl* uid) from an object of the given structure in the given CodeBlock,
44// assuming that such an access had already been cached by Repatch (and so Repatch had
45// already done a bunch of safety checks). This doesn't reexecute any checks that
46// Repatch would have executed, and for prototype chain accesses, it doesn't ask the
47// objects in the prototype chain whether their getOwnPropertySlot would attempt to
48// intercept the access - so this really is only appropriate if you already know that
49// one of the JITOperations had OK'd this for caching and that Repatch concurred.
50//
51// The typical use pattern is something like:
52//
53// ComplexGetStatus status = ComplexGetStatus::computeFor(...);
54// switch (status.kind()) {
55// case ComplexGetStatus::ShouldSkip:
56// // Handle the case where this kind of access is possibly safe but wouldn't
57// // pass the required safety checks. For example, if an IC gives us a list of
58// // accesses and one of them is ShouldSkip, then we should pretend as if it
59// // wasn't even there.
60// break;
61// case ComplexGetStatus::TakesSlowPath:
62// // This kind of access is not safe to inline. Bail out of any attempst to
63// // inline.
64// break;
65// case ComplexGetStatus::Inlineable:
66// // The good stuff goes here. If it's Inlineable then the other properties of
67// // the 'status' object will tell you everything you need to know about how
68// // to execute the get-like operation.
69// break;
70// }
71
72class ComplexGetStatus {
73public:
74 enum Kind {
75 ShouldSkip,
76 TakesSlowPath,
77 Inlineable
78 };
79
80 ComplexGetStatus()
81 : m_kind(ShouldSkip)
82 , m_offset(invalidOffset)
83 , m_attributes(UINT_MAX)
84 {
85 }
86
87 static ComplexGetStatus skip()
88 {
89 return ComplexGetStatus();
90 }
91
92 static ComplexGetStatus takesSlowPath()
93 {
94 ComplexGetStatus result;
95 result.m_kind = TakesSlowPath;
96 return result;
97 }
98
99 static ComplexGetStatus computeFor(
100 CodeBlock* profiledBlock, Structure* headStructure, StructureChain* chain,
101 unsigned chainCount, UniquedStringImpl* uid);
102
103 Kind kind() const { return m_kind; }
104 unsigned attributes() const { return m_attributes; }
105 JSValue specificValue() const { return m_specificValue; }
106 PropertyOffset offset() const { return m_offset; }
107 IntendedStructureChain* chain() const { return m_chain.get(); }
108
109private:
110 Kind m_kind;
111 PropertyOffset m_offset;
112 unsigned m_attributes;
113 JSValue m_specificValue;
114 RefPtr<IntendedStructureChain> m_chain;
115};
116
117} // namespace JSC
118
119#endif // ComplexGetStatus_h
120