| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright 2013 the V8 project authors. All rights reserved. | 
 |    2 // Use of this source code is governed by a BSD-style license that can be | 
 |    3 // found in the LICENSE file. | 
 |    4  | 
 |    5 #ifndef V8_COMPILER_JS_OPERATOR_H_ | 
 |    6 #define V8_COMPILER_JS_OPERATOR_H_ | 
 |    7  | 
 |    8 #include "src/compiler/opcodes.h" | 
 |    9 #include "src/compiler/operator.h" | 
 |   10 #include "src/unique.h" | 
 |   11 #include "src/zone.h" | 
 |   12  | 
 |   13 namespace v8 { | 
 |   14 namespace internal { | 
 |   15 namespace compiler { | 
 |   16  | 
 |   17 // Defines the location of a context slot relative to a specific scope. This is | 
 |   18 // used as a parameter by JSLoadContext and JSStoreContext operators and allows | 
 |   19 // accessing a context-allocated variable without keeping track of the scope. | 
 |   20 class ContextAccess { | 
 |   21  public: | 
 |   22   ContextAccess(int depth, int index, bool immutable) | 
 |   23       : immutable_(immutable), depth_(depth), index_(index) { | 
 |   24     ASSERT(0 <= depth && depth <= kMaxUInt16); | 
 |   25     ASSERT(0 <= index && static_cast<uint32_t>(index) <= kMaxUInt32); | 
 |   26   } | 
 |   27   int depth() const { return depth_; } | 
 |   28   int index() const { return index_; } | 
 |   29   bool immutable() const { return immutable_; } | 
 |   30  | 
 |   31  private: | 
 |   32   // For space reasons, we keep this tightly packed, otherwise we could just use | 
 |   33   // a simple int/int/bool POD. | 
 |   34   const bool immutable_; | 
 |   35   const uint16_t depth_; | 
 |   36   const uint32_t index_; | 
 |   37 }; | 
 |   38  | 
 |   39 // Defines the arity and the call flags for a JavaScript function call. This is | 
 |   40 // used as a parameter by JSCall operators. | 
 |   41 struct CallParameters { | 
 |   42   int arity; | 
 |   43   CallFunctionFlags flags; | 
 |   44 }; | 
 |   45  | 
 |   46 // Interface for building JavaScript-level operators, e.g. directly from the | 
 |   47 // AST. Most operators have no parameters, thus can be globally shared for all | 
 |   48 // graphs. | 
 |   49 class JSOperatorBuilder { | 
 |   50  public: | 
 |   51   explicit JSOperatorBuilder(Zone* zone) : zone_(zone) {} | 
 |   52  | 
 |   53 #define SIMPLE(name, properties, inputs, outputs) \ | 
 |   54   return new (zone_)                              \ | 
 |   55       SimpleOperator(IrOpcode::k##name, properties, inputs, outputs, #name); | 
 |   56  | 
 |   57 #define NOPROPS(name, inputs, outputs) \ | 
 |   58   SIMPLE(name, Operator::kNoProperties, inputs, outputs) | 
 |   59  | 
 |   60 #define OP1(name, ptype, pname, properties, inputs, outputs)                 \ | 
 |   61   return new (zone_) Operator1<ptype>(IrOpcode::k##name, properties, inputs, \ | 
 |   62                                       outputs, #name, pname) | 
 |   63  | 
 |   64 #define BINOP(name) NOPROPS(name, 2, 1) | 
 |   65 #define UNOP(name) NOPROPS(name, 1, 1) | 
 |   66  | 
 |   67 #define PURE_BINOP(name) SIMPLE(name, Operator::kPure, 2, 1) | 
 |   68  | 
 |   69   Operator* Equal() { BINOP(JSEqual); } | 
 |   70   Operator* NotEqual() { BINOP(JSNotEqual); } | 
 |   71   Operator* StrictEqual() { PURE_BINOP(JSStrictEqual); } | 
 |   72   Operator* StrictNotEqual() { PURE_BINOP(JSStrictNotEqual); } | 
 |   73   Operator* LessThan() { BINOP(JSLessThan); } | 
 |   74   Operator* GreaterThan() { BINOP(JSGreaterThan); } | 
 |   75   Operator* LessThanOrEqual() { BINOP(JSLessThanOrEqual); } | 
 |   76   Operator* GreaterThanOrEqual() { BINOP(JSGreaterThanOrEqual); } | 
 |   77   Operator* BitwiseOr() { BINOP(JSBitwiseOr); } | 
 |   78   Operator* BitwiseXor() { BINOP(JSBitwiseXor); } | 
 |   79   Operator* BitwiseAnd() { BINOP(JSBitwiseAnd); } | 
 |   80   Operator* ShiftLeft() { BINOP(JSShiftLeft); } | 
 |   81   Operator* ShiftRight() { BINOP(JSShiftRight); } | 
 |   82   Operator* ShiftRightLogical() { BINOP(JSShiftRightLogical); } | 
 |   83   Operator* Add() { BINOP(JSAdd); } | 
 |   84   Operator* Subtract() { BINOP(JSSubtract); } | 
 |   85   Operator* Multiply() { BINOP(JSMultiply); } | 
 |   86   Operator* Divide() { BINOP(JSDivide); } | 
 |   87   Operator* Modulus() { BINOP(JSModulus); } | 
 |   88  | 
 |   89   Operator* UnaryNot() { UNOP(JSUnaryNot); } | 
 |   90   Operator* ToBoolean() { UNOP(JSToBoolean); } | 
 |   91   Operator* ToNumber() { UNOP(JSToNumber); } | 
 |   92   Operator* ToString() { UNOP(JSToString); } | 
 |   93   Operator* ToName() { UNOP(JSToName); } | 
 |   94   Operator* ToObject() { UNOP(JSToObject); } | 
 |   95   Operator* Yield() { UNOP(JSYield); } | 
 |   96  | 
 |   97   Operator* Create() { SIMPLE(JSCreate, Operator::kEliminatable, 0, 1); } | 
 |   98  | 
 |   99   Operator* Call(int arguments, CallFunctionFlags flags) { | 
 |  100     CallParameters parameters = {arguments, flags}; | 
 |  101     OP1(JSCallFunction, CallParameters, parameters, Operator::kNoProperties, | 
 |  102         arguments, 1); | 
 |  103   } | 
 |  104  | 
 |  105   Operator* CallNew(int arguments) { | 
 |  106     return new (zone_) | 
 |  107         Operator1<int>(IrOpcode::kJSCallConstruct, Operator::kNoProperties, | 
 |  108                        arguments, 1, "JSCallConstruct", arguments); | 
 |  109   } | 
 |  110  | 
 |  111   Operator* LoadProperty() { BINOP(JSLoadProperty); } | 
 |  112   Operator* LoadNamed(PrintableUnique<Name> name) { | 
 |  113     OP1(JSLoadNamed, PrintableUnique<Name>, name, Operator::kNoProperties, 1, | 
 |  114         1); | 
 |  115   } | 
 |  116  | 
 |  117   Operator* StoreProperty() { NOPROPS(JSStoreProperty, 3, 0); } | 
 |  118   Operator* StoreNamed(PrintableUnique<Name> name) { | 
 |  119     OP1(JSStoreNamed, PrintableUnique<Name>, name, Operator::kNoProperties, 2, | 
 |  120         0); | 
 |  121   } | 
 |  122  | 
 |  123   Operator* DeleteProperty(StrictMode strict_mode) { | 
 |  124     OP1(JSDeleteProperty, StrictMode, strict_mode, Operator::kNoProperties, 2, | 
 |  125         1); | 
 |  126   } | 
 |  127  | 
 |  128   Operator* HasProperty() { NOPROPS(JSHasProperty, 2, 1); } | 
 |  129  | 
 |  130   Operator* LoadContext(uint16_t depth, uint32_t index, bool immutable) { | 
 |  131     ContextAccess access(depth, index, immutable); | 
 |  132     OP1(JSLoadContext, ContextAccess, access, | 
 |  133         Operator::kEliminatable | Operator::kNoWrite, 1, 1); | 
 |  134   } | 
 |  135   Operator* StoreContext(uint16_t depth, uint32_t index) { | 
 |  136     ContextAccess access(depth, index, false); | 
 |  137     OP1(JSStoreContext, ContextAccess, access, Operator::kNoProperties, 2, 1); | 
 |  138   } | 
 |  139  | 
 |  140   Operator* TypeOf() { SIMPLE(JSTypeOf, Operator::kPure, 1, 1); } | 
 |  141   Operator* InstanceOf() { NOPROPS(JSInstanceOf, 2, 1); } | 
 |  142   Operator* Debugger() { NOPROPS(JSDebugger, 0, 0); } | 
 |  143  | 
 |  144   // TODO(titzer): nail down the static parts of each of these context flavors. | 
 |  145   Operator* CreateFunctionContext() { NOPROPS(JSCreateFunctionContext, 1, 1); } | 
 |  146   Operator* CreateCatchContext(PrintableUnique<String> name) { | 
 |  147     OP1(JSCreateCatchContext, PrintableUnique<String>, name, | 
 |  148         Operator::kNoProperties, 1, 1); | 
 |  149   } | 
 |  150   Operator* CreateWithContext() { NOPROPS(JSCreateWithContext, 2, 1); } | 
 |  151   Operator* CreateBlockContext() { NOPROPS(JSCreateBlockContext, 2, 1); } | 
 |  152   Operator* CreateModuleContext() { NOPROPS(JSCreateModuleContext, 2, 1); } | 
 |  153   Operator* CreateGlobalContext() { NOPROPS(JSCreateGlobalContext, 2, 1); } | 
 |  154  | 
 |  155   Operator* Runtime(Runtime::FunctionId function, int arguments) { | 
 |  156     const Runtime::Function* f = Runtime::FunctionForId(function); | 
 |  157     ASSERT(f->nargs == -1 || f->nargs == arguments); | 
 |  158     OP1(JSCallRuntime, Runtime::FunctionId, function, Operator::kNoProperties, | 
 |  159         arguments, f->result_size); | 
 |  160   } | 
 |  161  | 
 |  162 #undef SIMPLE | 
 |  163 #undef NOPROPS | 
 |  164 #undef OP1 | 
 |  165 #undef BINOP | 
 |  166 #undef UNOP | 
 |  167  | 
 |  168  private: | 
 |  169   Zone* zone_; | 
 |  170 }; | 
 |  171  | 
 |  172 // Specialization for static parameters of type {ContextAccess}. | 
 |  173 template <> | 
 |  174 struct StaticParameterTraits<ContextAccess> { | 
 |  175   static OStream& PrintTo(OStream& os, ContextAccess val) {  // NOLINT | 
 |  176     return os << val.depth() << "," << val.index() | 
 |  177               << (val.immutable() ? ",imm" : ""); | 
 |  178   } | 
 |  179   static int HashCode(ContextAccess val) { | 
 |  180     return (val.depth() << 16) | (val.index() & 0xffff); | 
 |  181   } | 
 |  182   static bool Equals(ContextAccess a, ContextAccess b) { | 
 |  183     return a.immutable() == b.immutable() && a.depth() == b.depth() && | 
 |  184            a.index() == b.index(); | 
 |  185   } | 
 |  186 }; | 
 |  187  | 
 |  188 // Specialization for static parameters of type {Runtime::FunctionId}. | 
 |  189 template <> | 
 |  190 struct StaticParameterTraits<Runtime::FunctionId> { | 
 |  191   static OStream& PrintTo(OStream& os, Runtime::FunctionId val) {  // NOLINT | 
 |  192     const Runtime::Function* f = Runtime::FunctionForId(val); | 
 |  193     return os << (f->name ? f->name : "?Runtime?"); | 
 |  194   } | 
 |  195   static int HashCode(Runtime::FunctionId val) { return static_cast<int>(val); } | 
 |  196   static bool Equals(Runtime::FunctionId a, Runtime::FunctionId b) { | 
 |  197     return a == b; | 
 |  198   } | 
 |  199 }; | 
 |  200 } | 
 |  201 } | 
 |  202 }  // namespace v8::internal::compiler | 
 |  203  | 
 |  204 #endif  // V8_COMPILER_JS_OPERATOR_H_ | 
| OLD | NEW |