2620405a96f97985013413806c6c4251ee4d3d28
[WebKit-https.git] / Source / JavaScriptCore / bytecode / ComplexGetStatus.h
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
33 namespace JSC {
34
35 class CodeBlock;
36 class 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
72 class ComplexGetStatus {
73 public:
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     
109 private:
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