js/src/jsanalyze.h

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 /* Definitions for javascript analysis. */
     9 #ifndef jsanalyze_h
    10 #define jsanalyze_h
    12 #include "jscompartment.h"
    14 namespace js {
    15 namespace analyze {
    17 class Bytecode;
    18 struct LifetimeVariable;
    19 class SlotValue;
    20 class SSAValue;
    21 struct SSAValueInfo;
    22 class SSAUseChain;
    24 // Common representation of slots between ScriptAnalysis, TypeScript, and in the
    25 // case of TotalSlots, Ion.
    26 static inline uint32_t ThisSlot() {
    27     return 0;
    28 }
    29 static inline uint32_t ArgSlot(uint32_t arg) {
    30     return 1 + arg;
    31 }
    32 static inline uint32_t LocalSlot(JSScript *script, uint32_t local) {
    33     return 1 + local +
    34            (script->functionNonDelazifying() ? script->functionNonDelazifying()->nargs() : 0);
    35 }
    36 static inline uint32_t TotalSlots(JSScript *script) {
    37     return LocalSlot(script, 0) + script->nfixed();
    38 }
    40 // Analysis information about a script.  FIXME: At this point, the entire
    41 // purpose of this class is to compute JSScript::needsArgsObj, and to support
    42 // isReachable() in order for jsinfer.cpp:FindPreviousInnerInitializer to get
    43 // the previous opcode.  For that purpose, it is completely overkill.
    44 class ScriptAnalysis
    45 {
    46     friend class Bytecode;
    48     JSScript *script_;
    50     Bytecode **codeArray;
    52     uint32_t numSlots;
    54     bool *escapedSlots;
    56 #ifdef DEBUG
    57     /* Whether the compartment was in debug mode when we performed the analysis. */
    58     bool originalDebugMode_: 1;
    59 #endif
    61     /* --------- Bytecode analysis --------- */
    63     bool canTrackVars:1;
    64     bool argumentsContentsObserved_:1;
    66     /* --------- Lifetime analysis --------- */
    68     LifetimeVariable *lifetimes;
    70   public:
    71     ScriptAnalysis(JSScript *script) {
    72         mozilla::PodZero(this);
    73         this->script_ = script;
    74 #ifdef DEBUG
    75         this->originalDebugMode_ = script_->compartment()->debugMode();
    76 #endif
    77     }
    79     MOZ_WARN_UNUSED_RESULT
    80     bool analyzeBytecode(JSContext *cx);
    82     bool isReachable(const jsbytecode *pc) { return maybeCode(pc); }
    84   private:
    85     MOZ_WARN_UNUSED_RESULT
    86     bool analyzeSSA(JSContext *cx);
    87     MOZ_WARN_UNUSED_RESULT
    88     bool analyzeLifetimes(JSContext *cx);
    90     /* Accessors for bytecode information. */
    91     Bytecode& getCode(uint32_t offset) {
    92         JS_ASSERT(offset < script_->length());
    93         JS_ASSERT(codeArray[offset]);
    94         return *codeArray[offset];
    95     }
    96     Bytecode& getCode(const jsbytecode *pc) { return getCode(script_->pcToOffset(pc)); }
    98     Bytecode* maybeCode(uint32_t offset) {
    99         JS_ASSERT(offset < script_->length());
   100         return codeArray[offset];
   101     }
   102     Bytecode* maybeCode(const jsbytecode *pc) { return maybeCode(script_->pcToOffset(pc)); }
   104     inline bool jumpTarget(uint32_t offset);
   105     inline bool jumpTarget(const jsbytecode *pc);
   107     inline const SSAValue &poppedValue(uint32_t offset, uint32_t which);
   108     inline const SSAValue &poppedValue(const jsbytecode *pc, uint32_t which);
   110     inline const SlotValue *newValues(uint32_t offset);
   111     inline const SlotValue *newValues(const jsbytecode *pc);
   113     inline bool trackUseChain(const SSAValue &v);
   115     /*
   116      * Get the use chain for an SSA value.
   117      */
   118     inline SSAUseChain *& useChain(const SSAValue &v);
   121     /* For a JSOP_CALL* op, get the pc of the corresponding JSOP_CALL/NEW/etc. */
   122     inline jsbytecode *getCallPC(jsbytecode *pc);
   124     /* Accessors for local variable information. */
   126     /*
   127      * Escaping slots include all slots that can be accessed in ways other than
   128      * through the corresponding LOCAL/ARG opcode. This includes all closed
   129      * slots in the script, all slots in scripts which use eval or are in debug
   130      * mode, and slots which are aliased by NAME or similar opcodes in the
   131      * containing script (which does not imply the variable is closed).
   132      */
   133     inline bool slotEscapes(uint32_t slot);
   135     /*
   136      * Whether we distinguish different writes of this variable while doing
   137      * SSA analysis. Escaping locals can be written in other scripts, and the
   138      * presence of NAME opcodes which could alias local variables or arguments
   139      * keeps us from tracking variable values at each point.
   140      */
   141     inline bool trackSlot(uint32_t slot);
   143     inline const LifetimeVariable & liveness(uint32_t slot);
   145     void printSSA(JSContext *cx);
   146     void printTypes(JSContext *cx);
   148     /* Bytecode helpers */
   149     MOZ_WARN_UNUSED_RESULT
   150     inline bool addJump(JSContext *cx, unsigned offset,
   151                         unsigned *currentOffset, unsigned *forwardJump, unsigned *forwardLoop,
   152                         unsigned stackDepth);
   154     /* Lifetime helpers */
   155     MOZ_WARN_UNUSED_RESULT
   156     inline bool addVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
   157                             LifetimeVariable **&saved, unsigned &savedCount);
   158     MOZ_WARN_UNUSED_RESULT
   159     inline bool killVariable(JSContext *cx, LifetimeVariable &var, unsigned offset,
   160                              LifetimeVariable **&saved, unsigned &savedCount);
   161     MOZ_WARN_UNUSED_RESULT
   162     inline bool extendVariable(JSContext *cx, LifetimeVariable &var, unsigned start, unsigned end);
   164     inline void ensureVariable(LifetimeVariable &var, unsigned until);
   166     /* SSA helpers */
   167     MOZ_WARN_UNUSED_RESULT
   168     bool makePhi(JSContext *cx, uint32_t slot, uint32_t offset, SSAValue *pv);
   169     MOZ_WARN_UNUSED_RESULT
   170     bool insertPhi(JSContext *cx, SSAValue &phi, const SSAValue &v);
   171     MOZ_WARN_UNUSED_RESULT
   172     bool mergeValue(JSContext *cx, uint32_t offset, const SSAValue &v, SlotValue *pv);
   173     MOZ_WARN_UNUSED_RESULT
   174     bool checkPendingValue(JSContext *cx, const SSAValue &v, uint32_t slot,
   175                            Vector<SlotValue> *pending);
   176     MOZ_WARN_UNUSED_RESULT
   177     bool checkBranchTarget(JSContext *cx, uint32_t targetOffset, Vector<uint32_t> &branchTargets,
   178                            SSAValueInfo *values, uint32_t stackDepth);
   179     MOZ_WARN_UNUSED_RESULT
   180     bool checkExceptionTarget(JSContext *cx, uint32_t catchOffset,
   181                               Vector<uint32_t> &exceptionTargets);
   182     MOZ_WARN_UNUSED_RESULT
   183     bool mergeBranchTarget(JSContext *cx, SSAValueInfo &value, uint32_t slot,
   184                            const Vector<uint32_t> &branchTargets, uint32_t currentOffset);
   185     MOZ_WARN_UNUSED_RESULT
   186     bool mergeExceptionTarget(JSContext *cx, const SSAValue &value, uint32_t slot,
   187                               const Vector<uint32_t> &exceptionTargets);
   188     MOZ_WARN_UNUSED_RESULT
   189     bool mergeAllExceptionTargets(JSContext *cx, SSAValueInfo *values,
   190                                   const Vector<uint32_t> &exceptionTargets);
   191     MOZ_WARN_UNUSED_RESULT
   192     bool freezeNewValues(JSContext *cx, uint32_t offset);
   194     typedef Vector<SSAValue, 16> SeenVector;
   195     bool needsArgsObj(JSContext *cx, SeenVector &seen, const SSAValue &v);
   196     bool needsArgsObj(JSContext *cx, SeenVector &seen, SSAUseChain *use);
   197     bool needsArgsObj(JSContext *cx);
   199   public:
   200 #ifdef DEBUG
   201     void assertMatchingDebugMode();
   202     void assertMatchingStackDepthAtOffset(uint32_t offset, uint32_t stackDepth);
   203 #else
   204     void assertMatchingDebugMode() { }
   205     void assertMatchingStackDepthAtOffset(uint32_t offset, uint32_t stackDepth) { }
   206 #endif
   207 };
   209 #ifdef DEBUG
   210 void PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc);
   211 #endif
   213 } /* namespace analyze */
   214 } /* namespace js */
   216 #endif /* jsanalyze_h */

mercurial