Line data Source code
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/. */
6 :
7 : #ifndef jsopcodeinlines_h
8 : #define jsopcodeinlines_h
9 :
10 : #include "jsopcode.h"
11 :
12 : #include "jsscript.h"
13 :
14 : namespace js {
15 :
16 : static inline unsigned
17 105154 : GetDefCount(JSScript* script, unsigned offset)
18 : {
19 105154 : jsbytecode* pc = script->offsetToPC(offset);
20 :
21 : /*
22 : * Add an extra pushed value for OR/AND opcodes, so that they are included
23 : * in the pushed array of stack values for type inference.
24 : */
25 105154 : switch (JSOp(*pc)) {
26 : case JSOP_OR:
27 : case JSOP_AND:
28 468 : return 1;
29 : case JSOP_PICK:
30 : case JSOP_UNPICK:
31 : /*
32 : * Pick pops and pushes how deep it looks in the stack + 1
33 : * items. i.e. if the stack were |a b[2] c[1] d[0]|, pick 2
34 : * would pop b, c, and d to rearrange the stack to |a c[0]
35 : * d[1] b[2]|.
36 : */
37 324 : return pc[1] + 1;
38 : default:
39 104362 : return StackDefs(script, pc);
40 : }
41 : }
42 :
43 : static inline unsigned
44 124276 : GetUseCount(JSScript* script, unsigned offset)
45 : {
46 124276 : jsbytecode* pc = script->offsetToPC(offset);
47 :
48 124276 : if (JSOp(*pc) == JSOP_PICK || JSOp(*pc) == JSOP_UNPICK)
49 333 : return pc[1] + 1;
50 123943 : if (CodeSpec[*pc].nuses == -1)
51 7279 : return StackUses(script, pc);
52 116664 : return CodeSpec[*pc].nuses;
53 : }
54 :
55 : static inline JSOp
56 3 : ReverseCompareOp(JSOp op)
57 : {
58 3 : switch (op) {
59 : case JSOP_GT:
60 0 : return JSOP_LT;
61 : case JSOP_GE:
62 2 : return JSOP_LE;
63 : case JSOP_LT:
64 1 : return JSOP_GT;
65 : case JSOP_LE:
66 0 : return JSOP_GE;
67 : case JSOP_EQ:
68 : case JSOP_NE:
69 : case JSOP_STRICTEQ:
70 : case JSOP_STRICTNE:
71 0 : return op;
72 : default:
73 0 : MOZ_CRASH("unrecognized op");
74 : }
75 : }
76 :
77 : static inline JSOp
78 43 : NegateCompareOp(JSOp op)
79 : {
80 43 : switch (op) {
81 : case JSOP_GT:
82 1 : return JSOP_LE;
83 : case JSOP_GE:
84 4 : return JSOP_LT;
85 : case JSOP_LT:
86 9 : return JSOP_GE;
87 : case JSOP_LE:
88 0 : return JSOP_GT;
89 : case JSOP_EQ:
90 0 : return JSOP_NE;
91 : case JSOP_NE:
92 0 : return JSOP_EQ;
93 : case JSOP_STRICTNE:
94 2 : return JSOP_STRICTEQ;
95 : case JSOP_STRICTEQ:
96 27 : return JSOP_STRICTNE;
97 : default:
98 0 : MOZ_CRASH("unrecognized op");
99 : }
100 : }
101 :
102 0 : class BytecodeRange {
103 : public:
104 0 : BytecodeRange(JSContext* cx, JSScript* script)
105 0 : : script(cx, script), pc(script->code()), end(pc + script->length())
106 0 : {}
107 0 : bool empty() const { return pc == end; }
108 0 : jsbytecode* frontPC() const { return pc; }
109 0 : JSOp frontOpcode() const { return JSOp(*pc); }
110 0 : size_t frontOffset() const { return script->pcToOffset(pc); }
111 0 : void popFront() { pc += GetBytecodeLength(pc); }
112 :
113 : private:
114 : RootedScript script;
115 : jsbytecode* pc;
116 : jsbytecode* end;
117 : };
118 :
119 : } // namespace js
120 :
121 : #endif /* jsopcodeinlines_h */
|