| /* |
| * Copyright (C) 2014, 2015 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #pragma once |
| |
| #include "ObjectPropertyConditionSet.h" |
| #include "PropertyOffset.h" |
| |
| namespace JSC { |
| |
| class CodeBlock; |
| class StructureChain; |
| |
| // This class is useful for figuring out how to inline a cached get-like access. We |
| // say "get-like" because this is appropriate for loading the GetterSetter object in |
| // a put_by_id that hits a setter. Notably, this doesn't figure out how to call |
| // accessors, or even whether they should be called. What it gives us, is a way of |
| // determining how to load the value from the requested property (identified by a |
| // StringImpl* uid) from an object of the given structure in the given CodeBlock, |
| // assuming that such an access had already been cached by Repatch (and so Repatch had |
| // already done a bunch of safety checks). This doesn't reexecute any checks that |
| // Repatch would have executed, and for prototype chain accesses, it doesn't ask the |
| // objects in the prototype chain whether their getOwnPropertySlot would attempt to |
| // intercept the access - so this really is only appropriate if you already know that |
| // one of the JITOperations had OK'd this for caching and that Repatch concurred. |
| // |
| // The typical use pattern is something like: |
| // |
| // ComplexGetStatus status = ComplexGetStatus::computeFor(...); |
| // switch (status.kind()) { |
| // case ComplexGetStatus::ShouldSkip: |
| // // Handle the case where this kind of access is possibly safe but wouldn't |
| // // pass the required safety checks. For example, if an IC gives us a list of |
| // // accesses and one of them is ShouldSkip, then we should pretend as if it |
| // // wasn't even there. |
| // break; |
| // case ComplexGetStatus::TakesSlowPath: |
| // // This kind of access is not safe to inline. Bail out of any attempst to |
| // // inline. |
| // break; |
| // case ComplexGetStatus::Inlineable: |
| // // The good stuff goes here. If it's Inlineable then the other properties of |
| // // the 'status' object will tell you everything you need to know about how |
| // // to execute the get-like operation. |
| // break; |
| // } |
| |
| class ComplexGetStatus final { |
| public: |
| enum Kind { |
| ShouldSkip, |
| TakesSlowPath, |
| Inlineable |
| }; |
| |
| ComplexGetStatus() |
| : m_kind(ShouldSkip) |
| , m_offset(invalidOffset) |
| { |
| } |
| |
| static ComplexGetStatus skip() |
| { |
| return ComplexGetStatus(); |
| } |
| |
| static ComplexGetStatus takesSlowPath() |
| { |
| ComplexGetStatus result; |
| result.m_kind = TakesSlowPath; |
| return result; |
| } |
| |
| static ComplexGetStatus computeFor( |
| Structure* headStructure, const ObjectPropertyConditionSet&, UniquedStringImpl* uid); |
| |
| Kind kind() const { return m_kind; } |
| PropertyOffset offset() const { return m_offset; } |
| const ObjectPropertyConditionSet& conditionSet() const { return m_conditionSet; } |
| |
| private: |
| Kind m_kind; |
| PropertyOffset m_offset; |
| ObjectPropertyConditionSet m_conditionSet; |
| }; |
| |
| } // namespace JSC |