1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/src/jit/LIR-Common.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,6124 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: set ts=8 sts=4 et sw=4 tw=99: 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#ifndef jit_LIR_Common_h 1.11 +#define jit_LIR_Common_h 1.12 + 1.13 +#include "jit/shared/Assembler-shared.h" 1.14 + 1.15 +// This file declares LIR instructions that are common to every platform. 1.16 + 1.17 +namespace js { 1.18 +namespace jit { 1.19 + 1.20 +class Range; 1.21 + 1.22 +template <size_t Temps, size_t ExtraUses = 0> 1.23 +class LBinaryMath : public LInstructionHelper<1, 2 + ExtraUses, Temps> 1.24 +{ 1.25 + public: 1.26 + const LAllocation *lhs() { 1.27 + return this->getOperand(0); 1.28 + } 1.29 + const LAllocation *rhs() { 1.30 + return this->getOperand(1); 1.31 + } 1.32 +}; 1.33 + 1.34 +// Simplifies register allocation since the first instruction of a block is 1.35 +// guaranteed to have no uses. 1.36 +class LLabel : public LInstructionHelper<0, 0, 0> 1.37 +{ 1.38 + public: 1.39 + LIR_HEADER(Label) 1.40 +}; 1.41 + 1.42 +class LNop : public LInstructionHelper<0, 0, 0> 1.43 +{ 1.44 + public: 1.45 + LIR_HEADER(Nop) 1.46 +}; 1.47 + 1.48 +// An LOsiPoint captures a snapshot after a call and ensures enough space to 1.49 +// patch in a call to the invalidation mechanism. 1.50 +// 1.51 +// Note: LSafepoints are 1:1 with LOsiPoints, so it holds a reference to the 1.52 +// corresponding LSafepoint to inform it of the LOsiPoint's masm offset when it 1.53 +// gets CG'd. 1.54 +class LOsiPoint : public LInstructionHelper<0, 0, 0> 1.55 +{ 1.56 + LSafepoint *safepoint_; 1.57 + 1.58 + public: 1.59 + LOsiPoint(LSafepoint *safepoint, LSnapshot *snapshot) 1.60 + : safepoint_(safepoint) 1.61 + { 1.62 + JS_ASSERT(safepoint && snapshot); 1.63 + assignSnapshot(snapshot); 1.64 + } 1.65 + 1.66 + LSafepoint *associatedSafepoint() { 1.67 + return safepoint_; 1.68 + } 1.69 + 1.70 + LIR_HEADER(OsiPoint) 1.71 +}; 1.72 + 1.73 +class LMove 1.74 +{ 1.75 + LAllocation *from_; 1.76 + LAllocation *to_; 1.77 + LDefinition::Type type_; 1.78 + 1.79 + public: 1.80 + LMove(LAllocation *from, LAllocation *to, LDefinition::Type type) 1.81 + : from_(from), 1.82 + to_(to), 1.83 + type_(type) 1.84 + { } 1.85 + 1.86 + LAllocation *from() { 1.87 + return from_; 1.88 + } 1.89 + const LAllocation *from() const { 1.90 + return from_; 1.91 + } 1.92 + LAllocation *to() { 1.93 + return to_; 1.94 + } 1.95 + const LAllocation *to() const { 1.96 + return to_; 1.97 + } 1.98 + LDefinition::Type type() const { 1.99 + return type_; 1.100 + } 1.101 +}; 1.102 + 1.103 +class LMoveGroup : public LInstructionHelper<0, 0, 0> 1.104 +{ 1.105 + js::Vector<LMove, 2, IonAllocPolicy> moves_; 1.106 + 1.107 + LMoveGroup(TempAllocator &alloc) 1.108 + : moves_(alloc) 1.109 + { } 1.110 + 1.111 + public: 1.112 + LIR_HEADER(MoveGroup) 1.113 + 1.114 + static LMoveGroup *New(TempAllocator &alloc) { 1.115 + return new(alloc) LMoveGroup(alloc); 1.116 + } 1.117 + 1.118 + void printOperands(FILE *fp); 1.119 + 1.120 + // Add a move which takes place simultaneously with all others in the group. 1.121 + bool add(LAllocation *from, LAllocation *to, LDefinition::Type type); 1.122 + 1.123 + // Add a move which takes place after existing moves in the group. 1.124 + bool addAfter(LAllocation *from, LAllocation *to, LDefinition::Type type); 1.125 + 1.126 + size_t numMoves() const { 1.127 + return moves_.length(); 1.128 + } 1.129 + const LMove &getMove(size_t i) const { 1.130 + return moves_[i]; 1.131 + } 1.132 +}; 1.133 + 1.134 +// Constant 32-bit integer. 1.135 +class LInteger : public LInstructionHelper<1, 0, 0> 1.136 +{ 1.137 + int32_t i32_; 1.138 + 1.139 + public: 1.140 + LIR_HEADER(Integer) 1.141 + 1.142 + LInteger(int32_t i32) 1.143 + : i32_(i32) 1.144 + { } 1.145 + 1.146 + int32_t getValue() const { 1.147 + return i32_; 1.148 + } 1.149 +}; 1.150 + 1.151 +// Constant pointer. 1.152 +class LPointer : public LInstructionHelper<1, 0, 0> 1.153 +{ 1.154 + public: 1.155 + enum Kind { 1.156 + GC_THING, 1.157 + NON_GC_THING 1.158 + }; 1.159 + 1.160 + private: 1.161 + void *ptr_; 1.162 + Kind kind_; 1.163 + 1.164 + public: 1.165 + LIR_HEADER(Pointer) 1.166 + 1.167 + LPointer(gc::Cell *ptr) 1.168 + : ptr_(ptr), kind_(GC_THING) 1.169 + { } 1.170 + 1.171 + LPointer(void *ptr, Kind kind) 1.172 + : ptr_(ptr), kind_(kind) 1.173 + { } 1.174 + 1.175 + void *ptr() const { 1.176 + return ptr_; 1.177 + } 1.178 + Kind kind() const { 1.179 + return kind_; 1.180 + } 1.181 + const char *extraName() const { 1.182 + return kind_ == GC_THING ? "GC_THING" : "NON_GC_THING"; 1.183 + } 1.184 + 1.185 + gc::Cell *gcptr() const { 1.186 + JS_ASSERT(kind() == GC_THING); 1.187 + return (gc::Cell *) ptr_; 1.188 + } 1.189 +}; 1.190 + 1.191 +// Constant double. 1.192 +class LDouble : public LInstructionHelper<1, 0, 0> 1.193 +{ 1.194 + double d_; 1.195 + public: 1.196 + LIR_HEADER(Double); 1.197 + 1.198 + LDouble(double d) : d_(d) 1.199 + { } 1.200 + double getDouble() const { 1.201 + return d_; 1.202 + } 1.203 +}; 1.204 + 1.205 +// Constant float32. 1.206 +class LFloat32 : public LInstructionHelper<1, 0, 0> 1.207 +{ 1.208 + float f_; 1.209 + public: 1.210 + LIR_HEADER(Float32); 1.211 + 1.212 + LFloat32(float f) 1.213 + : f_(f) 1.214 + { } 1.215 + 1.216 + float getFloat() const { 1.217 + return f_; 1.218 + } 1.219 +}; 1.220 + 1.221 +// A constant Value. 1.222 +class LValue : public LInstructionHelper<BOX_PIECES, 0, 0> 1.223 +{ 1.224 + Value v_; 1.225 + 1.226 + public: 1.227 + LIR_HEADER(Value) 1.228 + 1.229 + LValue(const Value &v) 1.230 + : v_(v) 1.231 + { } 1.232 + 1.233 + Value value() const { 1.234 + return v_; 1.235 + } 1.236 +}; 1.237 + 1.238 +// Clone an object literal such as we are not modifying the object contained in 1.239 +// the sources. 1.240 +class LCloneLiteral : public LCallInstructionHelper<1, 1, 0> 1.241 +{ 1.242 + public: 1.243 + LIR_HEADER(CloneLiteral) 1.244 + 1.245 + LCloneLiteral(const LAllocation &obj) 1.246 + { 1.247 + setOperand(0, obj); 1.248 + } 1.249 + 1.250 + const LAllocation *getObjectLiteral() { 1.251 + return getOperand(0); 1.252 + } 1.253 + 1.254 + MCloneLiteral *mir() const { 1.255 + return mir_->toCloneLiteral(); 1.256 + } 1.257 +}; 1.258 + 1.259 +// Formal argument for a function, returning a box. Formal arguments are 1.260 +// initially read from the stack. 1.261 +class LParameter : public LInstructionHelper<BOX_PIECES, 0, 0> 1.262 +{ 1.263 + public: 1.264 + LIR_HEADER(Parameter) 1.265 +}; 1.266 + 1.267 +// Stack offset for a word-sized immutable input value to a frame. 1.268 +class LCallee : public LInstructionHelper<1, 0, 0> 1.269 +{ 1.270 + public: 1.271 + LIR_HEADER(Callee) 1.272 +}; 1.273 + 1.274 +// Base class for control instructions (goto, branch, etc.) 1.275 +template <size_t Succs, size_t Operands, size_t Temps> 1.276 +class LControlInstructionHelper : public LInstructionHelper<0, Operands, Temps> { 1.277 + 1.278 + mozilla::Array<MBasicBlock *, Succs> successors_; 1.279 + 1.280 + public: 1.281 + virtual size_t numSuccessors() const MOZ_FINAL MOZ_OVERRIDE { return Succs; } 1.282 + 1.283 + virtual MBasicBlock *getSuccessor(size_t i) const MOZ_FINAL MOZ_OVERRIDE { 1.284 + return successors_[i]; 1.285 + } 1.286 + 1.287 + virtual void setSuccessor(size_t i, MBasicBlock *successor) MOZ_FINAL MOZ_OVERRIDE { 1.288 + successors_[i] = successor; 1.289 + } 1.290 +}; 1.291 + 1.292 +// Jumps to the start of a basic block. 1.293 +class LGoto : public LControlInstructionHelper<1, 0, 0> 1.294 +{ 1.295 + public: 1.296 + LIR_HEADER(Goto) 1.297 + 1.298 + LGoto(MBasicBlock *block) 1.299 + { 1.300 + setSuccessor(0, block); 1.301 + } 1.302 + 1.303 + MBasicBlock *target() const { 1.304 + return getSuccessor(0); 1.305 + } 1.306 +}; 1.307 + 1.308 +class LNewSlots : public LCallInstructionHelper<1, 0, 3> 1.309 +{ 1.310 + public: 1.311 + LIR_HEADER(NewSlots) 1.312 + 1.313 + LNewSlots(const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3) { 1.314 + setTemp(0, temp1); 1.315 + setTemp(1, temp2); 1.316 + setTemp(2, temp3); 1.317 + } 1.318 + 1.319 + const LDefinition *temp1() { 1.320 + return getTemp(0); 1.321 + } 1.322 + const LDefinition *temp2() { 1.323 + return getTemp(1); 1.324 + } 1.325 + const LDefinition *temp3() { 1.326 + return getTemp(2); 1.327 + } 1.328 + 1.329 + MNewSlots *mir() const { 1.330 + return mir_->toNewSlots(); 1.331 + } 1.332 +}; 1.333 + 1.334 +class LNewArray : public LInstructionHelper<1, 0, 1> 1.335 +{ 1.336 + public: 1.337 + LIR_HEADER(NewArray) 1.338 + 1.339 + LNewArray(const LDefinition &temp) { 1.340 + setTemp(0, temp); 1.341 + } 1.342 + 1.343 + const char *extraName() const { 1.344 + return mir()->shouldUseVM() ? "VMCall" : nullptr; 1.345 + } 1.346 + 1.347 + const LDefinition *temp() { 1.348 + return getTemp(0); 1.349 + } 1.350 + 1.351 + MNewArray *mir() const { 1.352 + return mir_->toNewArray(); 1.353 + } 1.354 +}; 1.355 + 1.356 +class LNewObject : public LInstructionHelper<1, 0, 1> 1.357 +{ 1.358 + public: 1.359 + LIR_HEADER(NewObject) 1.360 + 1.361 + LNewObject(const LDefinition &temp) { 1.362 + setTemp(0, temp); 1.363 + } 1.364 + 1.365 + const char *extraName() const { 1.366 + return mir()->shouldUseVM() ? "VMCall" : nullptr; 1.367 + } 1.368 + 1.369 + const LDefinition *temp() { 1.370 + return getTemp(0); 1.371 + } 1.372 + 1.373 + MNewObject *mir() const { 1.374 + return mir_->toNewObject(); 1.375 + } 1.376 +}; 1.377 + 1.378 +class LNewPar : public LInstructionHelper<1, 1, 2> 1.379 +{ 1.380 + public: 1.381 + LIR_HEADER(NewPar); 1.382 + 1.383 + LNewPar(const LAllocation &cx, const LDefinition &temp1, const LDefinition &temp2) { 1.384 + setOperand(0, cx); 1.385 + setTemp(0, temp1); 1.386 + setTemp(1, temp2); 1.387 + } 1.388 + 1.389 + MNewPar *mir() const { 1.390 + return mir_->toNewPar(); 1.391 + } 1.392 + 1.393 + const LAllocation *forkJoinContext() { 1.394 + return getOperand(0); 1.395 + } 1.396 + 1.397 + const LDefinition *getTemp0() { 1.398 + return getTemp(0); 1.399 + } 1.400 + 1.401 + const LDefinition *getTemp1() { 1.402 + return getTemp(1); 1.403 + } 1.404 +}; 1.405 + 1.406 +class LNewDenseArrayPar : public LCallInstructionHelper<1, 2, 3> 1.407 +{ 1.408 + public: 1.409 + LIR_HEADER(NewDenseArrayPar); 1.410 + 1.411 + LNewDenseArrayPar(const LAllocation &cx, const LAllocation &length, 1.412 + const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3) 1.413 + { 1.414 + setOperand(0, cx); 1.415 + setOperand(1, length); 1.416 + setTemp(0, temp1); 1.417 + setTemp(1, temp2); 1.418 + setTemp(2, temp3); 1.419 + } 1.420 + 1.421 + MNewDenseArrayPar *mir() const { 1.422 + return mir_->toNewDenseArrayPar(); 1.423 + } 1.424 + 1.425 + const LAllocation *forkJoinContext() { 1.426 + return getOperand(0); 1.427 + } 1.428 + 1.429 + const LAllocation *length() { 1.430 + return getOperand(1); 1.431 + } 1.432 + 1.433 + const LDefinition *getTemp0() { 1.434 + return getTemp(0); 1.435 + } 1.436 + 1.437 + const LDefinition *getTemp1() { 1.438 + return getTemp(1); 1.439 + } 1.440 + 1.441 + const LDefinition *getTemp2() { 1.442 + return getTemp(2); 1.443 + } 1.444 +}; 1.445 + 1.446 +// Allocates a new DeclEnvObject. 1.447 +// 1.448 +// This instruction generates two possible instruction sets: 1.449 +// (1) An inline allocation of the call object is attempted. 1.450 +// (2) Otherwise, a callVM create a new object. 1.451 +// 1.452 +class LNewDeclEnvObject : public LInstructionHelper<1, 0, 1> 1.453 +{ 1.454 + public: 1.455 + LIR_HEADER(NewDeclEnvObject); 1.456 + 1.457 + LNewDeclEnvObject(const LDefinition &temp) { 1.458 + setTemp(0, temp); 1.459 + } 1.460 + 1.461 + const LDefinition *temp() { 1.462 + return getTemp(0); 1.463 + } 1.464 + 1.465 + MNewDeclEnvObject *mir() const { 1.466 + return mir_->toNewDeclEnvObject(); 1.467 + } 1.468 +}; 1.469 + 1.470 +// Allocates a new CallObject. The inputs are: 1.471 +// slots: either a reg representing a HeapSlot *, or a placeholder 1.472 +// meaning that no slots pointer is needed. 1.473 +// 1.474 +// This instruction generates two possible instruction sets: 1.475 +// (1) If the call object is extensible, this is a callVM to create the 1.476 +// call object. 1.477 +// (2) Otherwise, an inline allocation of the call object is attempted. 1.478 +// 1.479 +class LNewCallObject : public LInstructionHelper<1, 1, 1> 1.480 +{ 1.481 + public: 1.482 + LIR_HEADER(NewCallObject) 1.483 + 1.484 + LNewCallObject(const LAllocation &slots, const LDefinition &temp) { 1.485 + setOperand(0, slots); 1.486 + setTemp(0, temp); 1.487 + } 1.488 + 1.489 + const LDefinition *temp() { 1.490 + return getTemp(0); 1.491 + } 1.492 + 1.493 + const LAllocation *slots() { 1.494 + return getOperand(0); 1.495 + } 1.496 + 1.497 + MNewCallObject *mir() const { 1.498 + return mir_->toNewCallObject(); 1.499 + } 1.500 +}; 1.501 + 1.502 +// Allocates a new CallObject with singleton type through an out-of-line VM 1.503 +// call. The inputs are: 1.504 +// slots: either a reg representing a HeapSlot *, or a placeholder 1.505 +// meaning that no slots pointer is needed. 1.506 +// 1.507 +class LNewSingletonCallObject : public LInstructionHelper<1, 1, 0> 1.508 +{ 1.509 + public: 1.510 + LIR_HEADER(NewSingletonCallObject) 1.511 + 1.512 + LNewSingletonCallObject(const LAllocation &slots) { 1.513 + setOperand(0, slots); 1.514 + } 1.515 + 1.516 + const LAllocation *slots() { 1.517 + return getOperand(0); 1.518 + } 1.519 + 1.520 + MNewCallObjectBase * mir() const { 1.521 + MOZ_ASSERT(mir_->isNewCallObject() || mir_->isNewRunOnceCallObject()); 1.522 + return static_cast<MNewCallObjectBase *>(mir_); 1.523 + } 1.524 +}; 1.525 + 1.526 +class LNewCallObjectPar : public LInstructionHelper<1, 2, 2> 1.527 +{ 1.528 + LNewCallObjectPar(const LAllocation &cx, const LAllocation &slots, 1.529 + const LDefinition &temp1, const LDefinition &temp2) 1.530 + { 1.531 + setOperand(0, cx); 1.532 + setOperand(1, slots); 1.533 + setTemp(0, temp1); 1.534 + setTemp(1, temp2); 1.535 + } 1.536 + 1.537 +public: 1.538 + LIR_HEADER(NewCallObjectPar); 1.539 + 1.540 + static LNewCallObjectPar *NewWithSlots(TempAllocator &alloc, 1.541 + const LAllocation &cx, const LAllocation &slots, 1.542 + const LDefinition &temp1, const LDefinition &temp2) 1.543 + { 1.544 + return new(alloc) LNewCallObjectPar(cx, slots, temp1, temp2); 1.545 + } 1.546 + 1.547 + static LNewCallObjectPar *NewSansSlots(TempAllocator &alloc, 1.548 + const LAllocation &cx, 1.549 + const LDefinition &temp1, const LDefinition &temp2) 1.550 + { 1.551 + LAllocation slots = LConstantIndex::Bogus(); 1.552 + return new(alloc) LNewCallObjectPar(cx, slots, temp1, temp2); 1.553 + } 1.554 + 1.555 + const LAllocation *forkJoinContext() { 1.556 + return getOperand(0); 1.557 + } 1.558 + 1.559 + const LAllocation *slots() { 1.560 + return getOperand(1); 1.561 + } 1.562 + 1.563 + const bool hasDynamicSlots() { 1.564 + // TO INVESTIGATE: Felix tried using isRegister() method here, 1.565 + // but for useFixed(_, CallTempN), isRegister() is false (and 1.566 + // isUse() is true). So for now ignore that and try to match 1.567 + // the LConstantIndex::Bogus() generated above instead. 1.568 + return slots() && ! slots()->isConstant(); 1.569 + } 1.570 + 1.571 + const MNewCallObjectPar *mir() const { 1.572 + return mir_->toNewCallObjectPar(); 1.573 + } 1.574 + 1.575 + const LDefinition *getTemp0() { 1.576 + return getTemp(0); 1.577 + } 1.578 + 1.579 + const LDefinition *getTemp1() { 1.580 + return getTemp(1); 1.581 + } 1.582 +}; 1.583 + 1.584 +class LNewDerivedTypedObject : public LCallInstructionHelper<1, 3, 0> 1.585 +{ 1.586 + public: 1.587 + LIR_HEADER(NewDerivedTypedObject); 1.588 + 1.589 + LNewDerivedTypedObject(const LAllocation &type, 1.590 + const LAllocation &owner, 1.591 + const LAllocation &offset) { 1.592 + setOperand(0, type); 1.593 + setOperand(1, owner); 1.594 + setOperand(2, offset); 1.595 + } 1.596 + 1.597 + const LAllocation *type() { 1.598 + return getOperand(0); 1.599 + } 1.600 + 1.601 + const LAllocation *owner() { 1.602 + return getOperand(1); 1.603 + } 1.604 + 1.605 + const LAllocation *offset() { 1.606 + return getOperand(2); 1.607 + } 1.608 +}; 1.609 + 1.610 +class LNewStringObject : public LInstructionHelper<1, 1, 1> 1.611 +{ 1.612 + public: 1.613 + LIR_HEADER(NewStringObject) 1.614 + 1.615 + LNewStringObject(const LAllocation &input, const LDefinition &temp) { 1.616 + setOperand(0, input); 1.617 + setTemp(0, temp); 1.618 + } 1.619 + 1.620 + const LAllocation *input() { 1.621 + return getOperand(0); 1.622 + } 1.623 + const LDefinition *temp() { 1.624 + return getTemp(0); 1.625 + } 1.626 + MNewStringObject *mir() const { 1.627 + return mir_->toNewStringObject(); 1.628 + } 1.629 +}; 1.630 + 1.631 +class LAbortPar : public LInstructionHelper<0, 0, 0> 1.632 +{ 1.633 + public: 1.634 + LIR_HEADER(AbortPar); 1.635 +}; 1.636 + 1.637 +class LInitElem : public LCallInstructionHelper<0, 1 + 2*BOX_PIECES, 0> 1.638 +{ 1.639 + public: 1.640 + LIR_HEADER(InitElem) 1.641 + 1.642 + LInitElem(const LAllocation &object) { 1.643 + setOperand(0, object); 1.644 + } 1.645 + 1.646 + static const size_t IdIndex = 1; 1.647 + static const size_t ValueIndex = 1 + BOX_PIECES; 1.648 + 1.649 + const LAllocation *getObject() { 1.650 + return getOperand(0); 1.651 + } 1.652 + MInitElem *mir() const { 1.653 + return mir_->toInitElem(); 1.654 + } 1.655 +}; 1.656 + 1.657 +class LInitElemGetterSetter : public LCallInstructionHelper<0, 2 + BOX_PIECES, 0> 1.658 +{ 1.659 + public: 1.660 + LIR_HEADER(InitElemGetterSetter) 1.661 + 1.662 + LInitElemGetterSetter(const LAllocation &object, const LAllocation &value) { 1.663 + setOperand(0, object); 1.664 + setOperand(1, value); 1.665 + } 1.666 + 1.667 + static const size_t IdIndex = 2; 1.668 + 1.669 + const LAllocation *object() { 1.670 + return getOperand(0); 1.671 + } 1.672 + const LAllocation *value() { 1.673 + return getOperand(1); 1.674 + } 1.675 + MInitElemGetterSetter *mir() const { 1.676 + return mir_->toInitElemGetterSetter(); 1.677 + } 1.678 +}; 1.679 + 1.680 +// Takes in an Object and a Value. 1.681 +class LMutateProto : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> 1.682 +{ 1.683 + public: 1.684 + LIR_HEADER(MutateProto) 1.685 + 1.686 + LMutateProto(const LAllocation &object) { 1.687 + setOperand(0, object); 1.688 + } 1.689 + 1.690 + static const size_t ValueIndex = 1; 1.691 + 1.692 + const LAllocation *getObject() { 1.693 + return getOperand(0); 1.694 + } 1.695 + const LAllocation *getValue() { 1.696 + return getOperand(1); 1.697 + } 1.698 +}; 1.699 + 1.700 +// Takes in an Object and a Value. 1.701 +class LInitProp : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> 1.702 +{ 1.703 + public: 1.704 + LIR_HEADER(InitProp) 1.705 + 1.706 + LInitProp(const LAllocation &object) { 1.707 + setOperand(0, object); 1.708 + } 1.709 + 1.710 + static const size_t ValueIndex = 1; 1.711 + 1.712 + const LAllocation *getObject() { 1.713 + return getOperand(0); 1.714 + } 1.715 + const LAllocation *getValue() { 1.716 + return getOperand(1); 1.717 + } 1.718 + 1.719 + MInitProp *mir() const { 1.720 + return mir_->toInitProp(); 1.721 + } 1.722 +}; 1.723 + 1.724 +class LInitPropGetterSetter : public LCallInstructionHelper<0, 2, 0> 1.725 +{ 1.726 + public: 1.727 + LIR_HEADER(InitPropGetterSetter) 1.728 + 1.729 + LInitPropGetterSetter(const LAllocation &object, const LAllocation &value) { 1.730 + setOperand(0, object); 1.731 + setOperand(1, value); 1.732 + } 1.733 + 1.734 + const LAllocation *object() { 1.735 + return getOperand(0); 1.736 + } 1.737 + const LAllocation *value() { 1.738 + return getOperand(1); 1.739 + } 1.740 + 1.741 + MInitPropGetterSetter *mir() const { 1.742 + return mir_->toInitPropGetterSetter(); 1.743 + } 1.744 +}; 1.745 + 1.746 +class LCheckOverRecursed : public LInstructionHelper<0, 0, 0> 1.747 +{ 1.748 + public: 1.749 + LIR_HEADER(CheckOverRecursed) 1.750 + 1.751 + LCheckOverRecursed() 1.752 + { } 1.753 +}; 1.754 + 1.755 +class LCheckOverRecursedPar : public LInstructionHelper<0, 1, 1> 1.756 +{ 1.757 + public: 1.758 + LIR_HEADER(CheckOverRecursedPar); 1.759 + 1.760 + LCheckOverRecursedPar(const LAllocation &cx, const LDefinition &tempReg) { 1.761 + setOperand(0, cx); 1.762 + setTemp(0, tempReg); 1.763 + } 1.764 + 1.765 + const LAllocation *forkJoinContext() { 1.766 + return getOperand(0); 1.767 + } 1.768 + 1.769 + const LDefinition *getTempReg() { 1.770 + return getTemp(0); 1.771 + } 1.772 +}; 1.773 + 1.774 +// Alternative to LInterruptCheck which does not emit an explicit check of the 1.775 +// interrupt flag but relies on the loop backedge being patched via a signal 1.776 +// handler. 1.777 +class LInterruptCheckImplicit : public LInstructionHelper<0, 0, 0> 1.778 +{ 1.779 + Label *oolEntry_; 1.780 + 1.781 + public: 1.782 + LIR_HEADER(InterruptCheckImplicit) 1.783 + 1.784 + LInterruptCheckImplicit() 1.785 + : oolEntry_(nullptr) 1.786 + {} 1.787 + 1.788 + Label *oolEntry() { 1.789 + return oolEntry_; 1.790 + } 1.791 + 1.792 + void setOolEntry(Label *oolEntry) { 1.793 + oolEntry_ = oolEntry; 1.794 + } 1.795 +}; 1.796 + 1.797 +class LInterruptCheckPar : public LInstructionHelper<0, 1, 1> 1.798 +{ 1.799 + public: 1.800 + LIR_HEADER(InterruptCheckPar); 1.801 + 1.802 + LInterruptCheckPar(const LAllocation &cx, const LDefinition &tempReg) { 1.803 + setOperand(0, cx); 1.804 + setTemp(0, tempReg); 1.805 + } 1.806 + 1.807 + const LAllocation *forkJoinContext() { 1.808 + return getOperand(0); 1.809 + } 1.810 + 1.811 + const LDefinition *getTempReg() { 1.812 + return getTemp(0); 1.813 + } 1.814 +}; 1.815 + 1.816 +class LDefVar : public LCallInstructionHelper<0, 1, 0> 1.817 +{ 1.818 + public: 1.819 + LIR_HEADER(DefVar) 1.820 + 1.821 + LDefVar(const LAllocation &scopeChain) 1.822 + { 1.823 + setOperand(0, scopeChain); 1.824 + } 1.825 + 1.826 + const LAllocation *scopeChain() { 1.827 + return getOperand(0); 1.828 + } 1.829 + MDefVar *mir() const { 1.830 + return mir_->toDefVar(); 1.831 + } 1.832 +}; 1.833 + 1.834 +class LDefFun : public LCallInstructionHelper<0, 1, 0> 1.835 +{ 1.836 + public: 1.837 + LIR_HEADER(DefFun) 1.838 + 1.839 + LDefFun(const LAllocation &scopeChain) 1.840 + { 1.841 + setOperand(0, scopeChain); 1.842 + } 1.843 + 1.844 + const LAllocation *scopeChain() { 1.845 + return getOperand(0); 1.846 + } 1.847 + MDefFun *mir() const { 1.848 + return mir_->toDefFun(); 1.849 + } 1.850 +}; 1.851 + 1.852 +class LTypeOfV : public LInstructionHelper<1, BOX_PIECES, 1> 1.853 +{ 1.854 + public: 1.855 + LIR_HEADER(TypeOfV) 1.856 + 1.857 + LTypeOfV(const LDefinition &tempToUnbox) { 1.858 + setTemp(0, tempToUnbox); 1.859 + } 1.860 + 1.861 + static const size_t Input = 0; 1.862 + 1.863 + const LDefinition *tempToUnbox() { 1.864 + return getTemp(0); 1.865 + } 1.866 + 1.867 + MTypeOf *mir() const { 1.868 + return mir_->toTypeOf(); 1.869 + } 1.870 +}; 1.871 + 1.872 +class LToIdV : public LInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 1> 1.873 +{ 1.874 + public: 1.875 + LIR_HEADER(ToIdV) 1.876 + 1.877 + LToIdV(const LDefinition &temp) 1.878 + { 1.879 + setTemp(0, temp); 1.880 + } 1.881 + 1.882 + static const size_t Object = 0; 1.883 + static const size_t Index = BOX_PIECES; 1.884 + 1.885 + MToId *mir() const { 1.886 + return mir_->toToId(); 1.887 + } 1.888 + 1.889 + const LDefinition *tempFloat() { 1.890 + return getTemp(0); 1.891 + } 1.892 +}; 1.893 + 1.894 +// Allocate an object for |new| on the caller-side, 1.895 +// when there is no templateObject or prototype known 1.896 +class LCreateThis : public LCallInstructionHelper<BOX_PIECES, 1, 0> 1.897 +{ 1.898 + public: 1.899 + LIR_HEADER(CreateThis) 1.900 + 1.901 + LCreateThis(const LAllocation &callee) 1.902 + { 1.903 + setOperand(0, callee); 1.904 + } 1.905 + 1.906 + const LAllocation *getCallee() { 1.907 + return getOperand(0); 1.908 + } 1.909 + 1.910 + MCreateThis *mir() const { 1.911 + return mir_->toCreateThis(); 1.912 + } 1.913 +}; 1.914 + 1.915 +// Allocate an object for |new| on the caller-side, 1.916 +// when the prototype is known. 1.917 +class LCreateThisWithProto : public LCallInstructionHelper<1, 2, 0> 1.918 +{ 1.919 + public: 1.920 + LIR_HEADER(CreateThisWithProto) 1.921 + 1.922 + LCreateThisWithProto(const LAllocation &callee, const LAllocation &prototype) 1.923 + { 1.924 + setOperand(0, callee); 1.925 + setOperand(1, prototype); 1.926 + } 1.927 + 1.928 + const LAllocation *getCallee() { 1.929 + return getOperand(0); 1.930 + } 1.931 + const LAllocation *getPrototype() { 1.932 + return getOperand(1); 1.933 + } 1.934 + 1.935 + MCreateThis *mir() const { 1.936 + return mir_->toCreateThis(); 1.937 + } 1.938 +}; 1.939 + 1.940 +// Allocate an object for |new| on the caller-side. 1.941 +// Always performs object initialization with a fast path. 1.942 +class LCreateThisWithTemplate : public LInstructionHelper<1, 0, 1> 1.943 +{ 1.944 + public: 1.945 + LIR_HEADER(CreateThisWithTemplate) 1.946 + 1.947 + LCreateThisWithTemplate(const LDefinition &temp) { 1.948 + setTemp(0, temp); 1.949 + } 1.950 + 1.951 + MCreateThisWithTemplate *mir() const { 1.952 + return mir_->toCreateThisWithTemplate(); 1.953 + } 1.954 + 1.955 + const LDefinition *temp() { 1.956 + return getTemp(0); 1.957 + } 1.958 +}; 1.959 + 1.960 +// Allocate a new arguments object for the frame. 1.961 +class LCreateArgumentsObject : public LCallInstructionHelper<1, 1, 1> 1.962 +{ 1.963 + public: 1.964 + LIR_HEADER(CreateArgumentsObject) 1.965 + 1.966 + LCreateArgumentsObject(const LAllocation &callObj, const LDefinition &temp) 1.967 + { 1.968 + setOperand(0, callObj); 1.969 + setTemp(0, temp); 1.970 + } 1.971 + 1.972 + const LAllocation *getCallObject() { 1.973 + return getOperand(0); 1.974 + } 1.975 + 1.976 + MCreateArgumentsObject *mir() const { 1.977 + return mir_->toCreateArgumentsObject(); 1.978 + } 1.979 +}; 1.980 + 1.981 +// Get argument from arguments object. 1.982 +class LGetArgumentsObjectArg : public LInstructionHelper<BOX_PIECES, 1, 1> 1.983 +{ 1.984 + public: 1.985 + LIR_HEADER(GetArgumentsObjectArg) 1.986 + 1.987 + LGetArgumentsObjectArg(const LAllocation &argsObj, const LDefinition &temp) 1.988 + { 1.989 + setOperand(0, argsObj); 1.990 + setTemp(0, temp); 1.991 + } 1.992 + 1.993 + const LAllocation *getArgsObject() { 1.994 + return getOperand(0); 1.995 + } 1.996 + 1.997 + MGetArgumentsObjectArg *mir() const { 1.998 + return mir_->toGetArgumentsObjectArg(); 1.999 + } 1.1000 +}; 1.1001 + 1.1002 +// Set argument on arguments object. 1.1003 +class LSetArgumentsObjectArg : public LInstructionHelper<0, 1 + BOX_PIECES, 1> 1.1004 +{ 1.1005 + public: 1.1006 + LIR_HEADER(SetArgumentsObjectArg) 1.1007 + 1.1008 + LSetArgumentsObjectArg(const LAllocation &argsObj, const LDefinition &temp) 1.1009 + { 1.1010 + setOperand(0, argsObj); 1.1011 + setTemp(0, temp); 1.1012 + } 1.1013 + 1.1014 + const LAllocation *getArgsObject() { 1.1015 + return getOperand(0); 1.1016 + } 1.1017 + 1.1018 + MSetArgumentsObjectArg *mir() const { 1.1019 + return mir_->toSetArgumentsObjectArg(); 1.1020 + } 1.1021 + 1.1022 + static const size_t ValueIndex = 1; 1.1023 +}; 1.1024 + 1.1025 +// If the Value is an Object, return unbox(Value). 1.1026 +// Otherwise, return the other Object. 1.1027 +class LReturnFromCtor : public LInstructionHelper<1, BOX_PIECES + 1, 0> 1.1028 +{ 1.1029 + public: 1.1030 + LIR_HEADER(ReturnFromCtor) 1.1031 + 1.1032 + LReturnFromCtor(const LAllocation &object) 1.1033 + { 1.1034 + // Value set by useBox() during lowering. 1.1035 + setOperand(LReturnFromCtor::ObjectIndex, object); 1.1036 + } 1.1037 + 1.1038 + const LAllocation *getObject() { 1.1039 + return getOperand(LReturnFromCtor::ObjectIndex); 1.1040 + } 1.1041 + 1.1042 + static const size_t ValueIndex = 0; 1.1043 + static const size_t ObjectIndex = BOX_PIECES; 1.1044 +}; 1.1045 + 1.1046 +class LComputeThis : public LInstructionHelper<1, BOX_PIECES, 0> 1.1047 +{ 1.1048 + public: 1.1049 + LIR_HEADER(ComputeThis) 1.1050 + 1.1051 + static const size_t ValueIndex = 0; 1.1052 + 1.1053 + const LDefinition *output() { 1.1054 + return getDef(0); 1.1055 + } 1.1056 + 1.1057 + MComputeThis *mir() const { 1.1058 + return mir_->toComputeThis(); 1.1059 + } 1.1060 +}; 1.1061 + 1.1062 +class LLoadArrowThis : public LInstructionHelper<BOX_PIECES, 1, 0> 1.1063 +{ 1.1064 + public: 1.1065 + LLoadArrowThis(const LAllocation &callee) { 1.1066 + setOperand(0, callee); 1.1067 + } 1.1068 + 1.1069 + LIR_HEADER(LoadArrowThis) 1.1070 + 1.1071 + const LAllocation *callee() { 1.1072 + return getOperand(0); 1.1073 + } 1.1074 +}; 1.1075 + 1.1076 +// Writes a typed argument for a function call to the frame's argument vector. 1.1077 +class LStackArgT : public LInstructionHelper<0, 1, 0> 1.1078 +{ 1.1079 + uint32_t argslot_; // Index into frame-scope argument vector. 1.1080 + MIRType type_; 1.1081 + 1.1082 + public: 1.1083 + LIR_HEADER(StackArgT) 1.1084 + 1.1085 + LStackArgT(uint32_t argslot, MIRType type, const LAllocation &arg) 1.1086 + : argslot_(argslot), 1.1087 + type_(type) 1.1088 + { 1.1089 + setOperand(0, arg); 1.1090 + } 1.1091 + uint32_t argslot() const { 1.1092 + return argslot_; 1.1093 + } 1.1094 + MIRType type() const { 1.1095 + return type_; 1.1096 + } 1.1097 + const LAllocation *getArgument() { 1.1098 + return getOperand(0); 1.1099 + } 1.1100 +}; 1.1101 + 1.1102 +// Writes an untyped argument for a function call to the frame's argument vector. 1.1103 +class LStackArgV : public LInstructionHelper<0, BOX_PIECES, 0> 1.1104 +{ 1.1105 + uint32_t argslot_; // Index into frame-scope argument vector. 1.1106 + 1.1107 + public: 1.1108 + LIR_HEADER(StackArgV) 1.1109 + 1.1110 + LStackArgV(uint32_t argslot) 1.1111 + : argslot_(argslot) 1.1112 + { } 1.1113 + 1.1114 + uint32_t argslot() const { 1.1115 + return argslot_; 1.1116 + } 1.1117 +}; 1.1118 + 1.1119 +// Common code for LIR descended from MCall. 1.1120 +template <size_t Defs, size_t Operands, size_t Temps> 1.1121 +class LJSCallInstructionHelper : public LCallInstructionHelper<Defs, Operands, Temps> 1.1122 +{ 1.1123 + public: 1.1124 + uint32_t argslot() const { 1.1125 + return mir()->numStackArgs(); 1.1126 + } 1.1127 + MCall *mir() const { 1.1128 + return this->mir_->toCall(); 1.1129 + } 1.1130 + 1.1131 + bool hasSingleTarget() const { 1.1132 + return getSingleTarget() != nullptr; 1.1133 + } 1.1134 + JSFunction *getSingleTarget() const { 1.1135 + return mir()->getSingleTarget(); 1.1136 + } 1.1137 + 1.1138 + // The number of stack arguments is the max between the number of formal 1.1139 + // arguments and the number of actual arguments. The number of stack 1.1140 + // argument includes the |undefined| padding added in case of underflow. 1.1141 + // Does not include |this|. 1.1142 + uint32_t numStackArgs() const { 1.1143 + JS_ASSERT(mir()->numStackArgs() >= 1); 1.1144 + return mir()->numStackArgs() - 1; // |this| is not a formal argument. 1.1145 + } 1.1146 + // Does not include |this|. 1.1147 + uint32_t numActualArgs() const { 1.1148 + return mir()->numActualArgs(); 1.1149 + } 1.1150 +}; 1.1151 + 1.1152 +// Generates a polymorphic callsite, wherein the function being called is 1.1153 +// unknown and anticipated to vary. 1.1154 +class LCallGeneric : public LJSCallInstructionHelper<BOX_PIECES, 1, 2> 1.1155 +{ 1.1156 + public: 1.1157 + LIR_HEADER(CallGeneric) 1.1158 + 1.1159 + LCallGeneric(const LAllocation &func, const LDefinition &nargsreg, 1.1160 + const LDefinition &tmpobjreg) 1.1161 + { 1.1162 + setOperand(0, func); 1.1163 + setTemp(0, nargsreg); 1.1164 + setTemp(1, tmpobjreg); 1.1165 + } 1.1166 + 1.1167 + const LAllocation *getFunction() { 1.1168 + return getOperand(0); 1.1169 + } 1.1170 + const LDefinition *getNargsReg() { 1.1171 + return getTemp(0); 1.1172 + } 1.1173 + const LDefinition *getTempObject() { 1.1174 + return getTemp(1); 1.1175 + } 1.1176 +}; 1.1177 + 1.1178 +// Generates a hardcoded callsite for a known, non-native target. 1.1179 +class LCallKnown : public LJSCallInstructionHelper<BOX_PIECES, 1, 1> 1.1180 +{ 1.1181 + public: 1.1182 + LIR_HEADER(CallKnown) 1.1183 + 1.1184 + LCallKnown(const LAllocation &func, const LDefinition &tmpobjreg) 1.1185 + { 1.1186 + setOperand(0, func); 1.1187 + setTemp(0, tmpobjreg); 1.1188 + } 1.1189 + 1.1190 + const LAllocation *getFunction() { 1.1191 + return getOperand(0); 1.1192 + } 1.1193 + const LDefinition *getTempObject() { 1.1194 + return getTemp(0); 1.1195 + } 1.1196 +}; 1.1197 + 1.1198 +// Generates a hardcoded callsite for a known, native target. 1.1199 +class LCallNative : public LJSCallInstructionHelper<BOX_PIECES, 0, 4> 1.1200 +{ 1.1201 + public: 1.1202 + LIR_HEADER(CallNative) 1.1203 + 1.1204 + LCallNative(const LDefinition &argContext, const LDefinition &argUintN, 1.1205 + const LDefinition &argVp, const LDefinition &tmpreg) 1.1206 + { 1.1207 + // Registers used for callWithABI(). 1.1208 + setTemp(0, argContext); 1.1209 + setTemp(1, argUintN); 1.1210 + setTemp(2, argVp); 1.1211 + 1.1212 + // Temporary registers. 1.1213 + setTemp(3, tmpreg); 1.1214 + } 1.1215 + 1.1216 + const LDefinition *getArgContextReg() { 1.1217 + return getTemp(0); 1.1218 + } 1.1219 + const LDefinition *getArgUintNReg() { 1.1220 + return getTemp(1); 1.1221 + } 1.1222 + const LDefinition *getArgVpReg() { 1.1223 + return getTemp(2); 1.1224 + } 1.1225 + const LDefinition *getTempReg() { 1.1226 + return getTemp(3); 1.1227 + } 1.1228 +}; 1.1229 + 1.1230 +// Generates a hardcoded callsite for a known, DOM-native target. 1.1231 +class LCallDOMNative : public LJSCallInstructionHelper<BOX_PIECES, 0, 4> 1.1232 +{ 1.1233 + public: 1.1234 + LIR_HEADER(CallDOMNative) 1.1235 + 1.1236 + LCallDOMNative(const LDefinition &argJSContext, const LDefinition &argObj, 1.1237 + const LDefinition &argPrivate, const LDefinition &argArgs) 1.1238 + { 1.1239 + setTemp(0, argJSContext); 1.1240 + setTemp(1, argObj); 1.1241 + setTemp(2, argPrivate); 1.1242 + setTemp(3, argArgs); 1.1243 + } 1.1244 + 1.1245 + const LDefinition *getArgJSContext() { 1.1246 + return getTemp(0); 1.1247 + } 1.1248 + const LDefinition *getArgObj() { 1.1249 + return getTemp(1); 1.1250 + } 1.1251 + const LDefinition *getArgPrivate() { 1.1252 + return getTemp(2); 1.1253 + } 1.1254 + const LDefinition *getArgArgs() { 1.1255 + return getTemp(3); 1.1256 + } 1.1257 +}; 1.1258 + 1.1259 +class LBail : public LInstructionHelper<0, 0, 0> 1.1260 +{ 1.1261 + public: 1.1262 + LIR_HEADER(Bail) 1.1263 +}; 1.1264 + 1.1265 +template <size_t defs, size_t ops> 1.1266 +class LDOMPropertyInstructionHelper : public LCallInstructionHelper<defs, 1 + ops, 3> 1.1267 +{ 1.1268 + protected: 1.1269 + LDOMPropertyInstructionHelper(const LDefinition &JSContextReg, const LAllocation &ObjectReg, 1.1270 + const LDefinition &PrivReg, const LDefinition &ValueReg) 1.1271 + { 1.1272 + this->setOperand(0, ObjectReg); 1.1273 + this->setTemp(0, JSContextReg); 1.1274 + this->setTemp(1, PrivReg); 1.1275 + this->setTemp(2, ValueReg); 1.1276 + } 1.1277 + 1.1278 + public: 1.1279 + const LDefinition *getJSContextReg() { 1.1280 + return this->getTemp(0); 1.1281 + } 1.1282 + const LAllocation *getObjectReg() { 1.1283 + return this->getOperand(0); 1.1284 + } 1.1285 + const LDefinition *getPrivReg() { 1.1286 + return this->getTemp(1); 1.1287 + } 1.1288 + const LDefinition *getValueReg() { 1.1289 + return this->getTemp(2); 1.1290 + } 1.1291 +}; 1.1292 + 1.1293 + 1.1294 +class LGetDOMProperty : public LDOMPropertyInstructionHelper<BOX_PIECES, 0> 1.1295 +{ 1.1296 + public: 1.1297 + LIR_HEADER(GetDOMProperty) 1.1298 + 1.1299 + LGetDOMProperty(const LDefinition &JSContextReg, const LAllocation &ObjectReg, 1.1300 + const LDefinition &PrivReg, const LDefinition &ValueReg) 1.1301 + : LDOMPropertyInstructionHelper<BOX_PIECES, 0>(JSContextReg, ObjectReg, 1.1302 + PrivReg, ValueReg) 1.1303 + { } 1.1304 + 1.1305 + MGetDOMProperty *mir() const { 1.1306 + return mir_->toGetDOMProperty(); 1.1307 + } 1.1308 +}; 1.1309 + 1.1310 +class LGetDOMMember : public LInstructionHelper<BOX_PIECES, 1, 0> 1.1311 +{ 1.1312 + public: 1.1313 + LIR_HEADER(GetDOMMember); 1.1314 + LGetDOMMember(const LAllocation &object) { 1.1315 + setOperand(0, object); 1.1316 + } 1.1317 + 1.1318 + const LAllocation *object() { 1.1319 + return getOperand(0); 1.1320 + } 1.1321 + 1.1322 + MGetDOMMember *mir() const { 1.1323 + return mir_->toGetDOMMember(); 1.1324 + } 1.1325 +}; 1.1326 + 1.1327 +class LSetDOMProperty : public LDOMPropertyInstructionHelper<0, BOX_PIECES> 1.1328 +{ 1.1329 + public: 1.1330 + LIR_HEADER(SetDOMProperty) 1.1331 + 1.1332 + LSetDOMProperty(const LDefinition &JSContextReg, const LAllocation &ObjectReg, 1.1333 + const LDefinition &PrivReg, const LDefinition &ValueReg) 1.1334 + : LDOMPropertyInstructionHelper<0, BOX_PIECES>(JSContextReg, ObjectReg, 1.1335 + PrivReg, ValueReg) 1.1336 + { } 1.1337 + 1.1338 + static const size_t Value = 1; 1.1339 + 1.1340 + MSetDOMProperty *mir() const { 1.1341 + return mir_->toSetDOMProperty(); 1.1342 + } 1.1343 +}; 1.1344 + 1.1345 +// Generates a polymorphic callsite, wherein the function being called is 1.1346 +// unknown and anticipated to vary. 1.1347 +class LApplyArgsGeneric : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES + 2, 2> 1.1348 +{ 1.1349 + public: 1.1350 + LIR_HEADER(ApplyArgsGeneric) 1.1351 + 1.1352 + LApplyArgsGeneric(const LAllocation &func, const LAllocation &argc, 1.1353 + const LDefinition &tmpobjreg, const LDefinition &tmpcopy) 1.1354 + { 1.1355 + setOperand(0, func); 1.1356 + setOperand(1, argc); 1.1357 + setTemp(0, tmpobjreg); 1.1358 + setTemp(1, tmpcopy); 1.1359 + } 1.1360 + 1.1361 + MApplyArgs *mir() const { 1.1362 + return mir_->toApplyArgs(); 1.1363 + } 1.1364 + 1.1365 + bool hasSingleTarget() const { 1.1366 + return getSingleTarget() != nullptr; 1.1367 + } 1.1368 + JSFunction *getSingleTarget() const { 1.1369 + return mir()->getSingleTarget(); 1.1370 + } 1.1371 + 1.1372 + const LAllocation *getFunction() { 1.1373 + return getOperand(0); 1.1374 + } 1.1375 + const LAllocation *getArgc() { 1.1376 + return getOperand(1); 1.1377 + } 1.1378 + static const size_t ThisIndex = 2; 1.1379 + 1.1380 + const LDefinition *getTempObject() { 1.1381 + return getTemp(0); 1.1382 + } 1.1383 + const LDefinition *getTempCopy() { 1.1384 + return getTemp(1); 1.1385 + } 1.1386 +}; 1.1387 + 1.1388 +class LArraySplice : public LCallInstructionHelper<0, 3, 0> 1.1389 +{ 1.1390 + public: 1.1391 + LIR_HEADER(ArraySplice) 1.1392 + 1.1393 + LArraySplice(const LAllocation &object, const LAllocation &start, 1.1394 + const LAllocation &deleteCount) 1.1395 + { 1.1396 + setOperand(0, object); 1.1397 + setOperand(1, start); 1.1398 + setOperand(2, deleteCount); 1.1399 + } 1.1400 + 1.1401 + MArraySplice *mir() const { 1.1402 + return mir_->toArraySplice(); 1.1403 + } 1.1404 + 1.1405 + const LAllocation *getObject() { 1.1406 + return getOperand(0); 1.1407 + } 1.1408 + const LAllocation *getStart() { 1.1409 + return getOperand(1); 1.1410 + } 1.1411 + const LAllocation *getDeleteCount() { 1.1412 + return getOperand(2); 1.1413 + } 1.1414 +}; 1.1415 + 1.1416 +class LGetDynamicName : public LCallInstructionHelper<BOX_PIECES, 2, 3> 1.1417 +{ 1.1418 + public: 1.1419 + LIR_HEADER(GetDynamicName) 1.1420 + 1.1421 + LGetDynamicName(const LAllocation &scopeChain, const LAllocation &name, 1.1422 + const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3) 1.1423 + { 1.1424 + setOperand(0, scopeChain); 1.1425 + setOperand(1, name); 1.1426 + setTemp(0, temp1); 1.1427 + setTemp(1, temp2); 1.1428 + setTemp(2, temp3); 1.1429 + } 1.1430 + 1.1431 + MGetDynamicName *mir() const { 1.1432 + return mir_->toGetDynamicName(); 1.1433 + } 1.1434 + 1.1435 + const LAllocation *getScopeChain() { 1.1436 + return getOperand(0); 1.1437 + } 1.1438 + const LAllocation *getName() { 1.1439 + return getOperand(1); 1.1440 + } 1.1441 + 1.1442 + const LDefinition *temp1() { 1.1443 + return getTemp(0); 1.1444 + } 1.1445 + const LDefinition *temp2() { 1.1446 + return getTemp(1); 1.1447 + } 1.1448 + const LDefinition *temp3() { 1.1449 + return getTemp(2); 1.1450 + } 1.1451 +}; 1.1452 + 1.1453 +class LFilterArgumentsOrEvalS : public LCallInstructionHelper<0, 1, 2> 1.1454 +{ 1.1455 + public: 1.1456 + LIR_HEADER(FilterArgumentsOrEvalS) 1.1457 + 1.1458 + LFilterArgumentsOrEvalS(const LAllocation &string, const LDefinition &temp1, 1.1459 + const LDefinition &temp2) 1.1460 + { 1.1461 + setOperand(0, string); 1.1462 + setTemp(0, temp1); 1.1463 + setTemp(1, temp2); 1.1464 + } 1.1465 + 1.1466 + MFilterArgumentsOrEval *mir() const { 1.1467 + return mir_->toFilterArgumentsOrEval(); 1.1468 + } 1.1469 + 1.1470 + const LAllocation *getString() { 1.1471 + return getOperand(0); 1.1472 + } 1.1473 + const LDefinition *temp1() { 1.1474 + return getTemp(0); 1.1475 + } 1.1476 + const LDefinition *temp2() { 1.1477 + return getTemp(1); 1.1478 + } 1.1479 +}; 1.1480 + 1.1481 +class LFilterArgumentsOrEvalV : public LCallInstructionHelper<0, BOX_PIECES, 3> 1.1482 +{ 1.1483 + public: 1.1484 + LIR_HEADER(FilterArgumentsOrEvalV) 1.1485 + 1.1486 + LFilterArgumentsOrEvalV(const LDefinition &temp1, const LDefinition &temp2, 1.1487 + const LDefinition &temp3) 1.1488 + { 1.1489 + setTemp(0, temp1); 1.1490 + setTemp(1, temp2); 1.1491 + setTemp(2, temp3); 1.1492 + } 1.1493 + 1.1494 + static const size_t Input = 0; 1.1495 + 1.1496 + MFilterArgumentsOrEval *mir() const { 1.1497 + return mir_->toFilterArgumentsOrEval(); 1.1498 + } 1.1499 + 1.1500 + const LDefinition *temp1() { 1.1501 + return getTemp(0); 1.1502 + } 1.1503 + const LDefinition *temp2() { 1.1504 + return getTemp(1); 1.1505 + } 1.1506 + const LDefinition *temp3() { 1.1507 + return getTemp(2); 1.1508 + } 1.1509 +}; 1.1510 + 1.1511 +class LCallDirectEvalS : public LCallInstructionHelper<BOX_PIECES, 2 + BOX_PIECES, 0> 1.1512 +{ 1.1513 + public: 1.1514 + LIR_HEADER(CallDirectEvalS) 1.1515 + 1.1516 + LCallDirectEvalS(const LAllocation &scopeChain, const LAllocation &string) 1.1517 + { 1.1518 + setOperand(0, scopeChain); 1.1519 + setOperand(1, string); 1.1520 + } 1.1521 + 1.1522 + static const size_t ThisValue = 2; 1.1523 + 1.1524 + MCallDirectEval *mir() const { 1.1525 + return mir_->toCallDirectEval(); 1.1526 + } 1.1527 + 1.1528 + const LAllocation *getScopeChain() { 1.1529 + return getOperand(0); 1.1530 + } 1.1531 + const LAllocation *getString() { 1.1532 + return getOperand(1); 1.1533 + } 1.1534 +}; 1.1535 + 1.1536 +class LCallDirectEvalV : public LCallInstructionHelper<BOX_PIECES, 1 + (2 * BOX_PIECES), 0> 1.1537 +{ 1.1538 + public: 1.1539 + LIR_HEADER(CallDirectEvalV) 1.1540 + 1.1541 + LCallDirectEvalV(const LAllocation &scopeChain) 1.1542 + { 1.1543 + setOperand(0, scopeChain); 1.1544 + } 1.1545 + 1.1546 + static const size_t Argument = 1; 1.1547 + static const size_t ThisValue = 1 + BOX_PIECES; 1.1548 + 1.1549 + MCallDirectEval *mir() const { 1.1550 + return mir_->toCallDirectEval(); 1.1551 + } 1.1552 + 1.1553 + const LAllocation *getScopeChain() { 1.1554 + return getOperand(0); 1.1555 + } 1.1556 +}; 1.1557 + 1.1558 +// Takes in either an integer or boolean input and tests it for truthiness. 1.1559 +class LTestIAndBranch : public LControlInstructionHelper<2, 1, 0> 1.1560 +{ 1.1561 + public: 1.1562 + LIR_HEADER(TestIAndBranch) 1.1563 + 1.1564 + LTestIAndBranch(const LAllocation &in, MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.1565 + { 1.1566 + setOperand(0, in); 1.1567 + setSuccessor(0, ifTrue); 1.1568 + setSuccessor(1, ifFalse); 1.1569 + } 1.1570 + 1.1571 + MBasicBlock *ifTrue() const { 1.1572 + return getSuccessor(0); 1.1573 + } 1.1574 + MBasicBlock *ifFalse() const { 1.1575 + return getSuccessor(1); 1.1576 + } 1.1577 +}; 1.1578 + 1.1579 +// Takes in either an integer or boolean input and tests it for truthiness. 1.1580 +class LTestDAndBranch : public LControlInstructionHelper<2, 1, 0> 1.1581 +{ 1.1582 + public: 1.1583 + LIR_HEADER(TestDAndBranch) 1.1584 + 1.1585 + LTestDAndBranch(const LAllocation &in, MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.1586 + { 1.1587 + setOperand(0, in); 1.1588 + setSuccessor(0, ifTrue); 1.1589 + setSuccessor(1, ifFalse); 1.1590 + } 1.1591 + 1.1592 + MBasicBlock *ifTrue() const { 1.1593 + return getSuccessor(0); 1.1594 + } 1.1595 + MBasicBlock *ifFalse() const { 1.1596 + return getSuccessor(1); 1.1597 + } 1.1598 +}; 1.1599 + 1.1600 +// Takes in either an integer or boolean input and tests it for truthiness. 1.1601 +class LTestFAndBranch : public LControlInstructionHelper<2, 1, 0> 1.1602 +{ 1.1603 + public: 1.1604 + LIR_HEADER(TestFAndBranch) 1.1605 + 1.1606 + LTestFAndBranch(const LAllocation &in, MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.1607 + { 1.1608 + setOperand(0, in); 1.1609 + setSuccessor(0, ifTrue); 1.1610 + setSuccessor(1, ifFalse); 1.1611 + } 1.1612 + 1.1613 + MBasicBlock *ifTrue() const { 1.1614 + return getSuccessor(0); 1.1615 + } 1.1616 + MBasicBlock *ifFalse() const { 1.1617 + return getSuccessor(1); 1.1618 + } 1.1619 +}; 1.1620 + 1.1621 +// Takes an object and tests it for truthiness. An object is falsy iff it 1.1622 +// emulates |undefined|; see js::EmulatesUndefined. 1.1623 +class LTestOAndBranch : public LControlInstructionHelper<2, 1, 1> 1.1624 +{ 1.1625 + public: 1.1626 + LIR_HEADER(TestOAndBranch) 1.1627 + 1.1628 + LTestOAndBranch(const LAllocation &input, MBasicBlock *ifTruthy, MBasicBlock *ifFalsy, 1.1629 + const LDefinition &temp) 1.1630 + { 1.1631 + setOperand(0, input); 1.1632 + setSuccessor(0, ifTruthy); 1.1633 + setSuccessor(1, ifFalsy); 1.1634 + setTemp(0, temp); 1.1635 + } 1.1636 + 1.1637 + const LDefinition *temp() { 1.1638 + return getTemp(0); 1.1639 + } 1.1640 + 1.1641 + MBasicBlock *ifTruthy() { 1.1642 + return getSuccessor(0); 1.1643 + } 1.1644 + MBasicBlock *ifFalsy() { 1.1645 + return getSuccessor(1); 1.1646 + } 1.1647 + 1.1648 + MTest *mir() { 1.1649 + return mir_->toTest(); 1.1650 + } 1.1651 +}; 1.1652 + 1.1653 +// Takes in a boxed value and tests it for truthiness. 1.1654 +class LTestVAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 3> 1.1655 +{ 1.1656 + public: 1.1657 + LIR_HEADER(TestVAndBranch) 1.1658 + 1.1659 + LTestVAndBranch(MBasicBlock *ifTruthy, MBasicBlock *ifFalsy, const LDefinition &temp0, 1.1660 + const LDefinition &temp1, const LDefinition &temp2) 1.1661 + { 1.1662 + setSuccessor(0, ifTruthy); 1.1663 + setSuccessor(1, ifFalsy); 1.1664 + setTemp(0, temp0); 1.1665 + setTemp(1, temp1); 1.1666 + setTemp(2, temp2); 1.1667 + } 1.1668 + 1.1669 + const char *extraName() const { 1.1670 + return mir()->operandMightEmulateUndefined() ? "MightEmulateUndefined" : nullptr; 1.1671 + } 1.1672 + 1.1673 + static const size_t Input = 0; 1.1674 + 1.1675 + const LDefinition *tempFloat() { 1.1676 + return getTemp(0); 1.1677 + } 1.1678 + 1.1679 + const LDefinition *temp1() { 1.1680 + return getTemp(1); 1.1681 + } 1.1682 + 1.1683 + const LDefinition *temp2() { 1.1684 + return getTemp(2); 1.1685 + } 1.1686 + 1.1687 + MBasicBlock *ifTruthy() { 1.1688 + return getSuccessor(0); 1.1689 + } 1.1690 + MBasicBlock *ifFalsy() { 1.1691 + return getSuccessor(1); 1.1692 + } 1.1693 + 1.1694 + MTest *mir() const { 1.1695 + return mir_->toTest(); 1.1696 + } 1.1697 +}; 1.1698 + 1.1699 +// Dispatches control flow to a successor based on incoming JSFunction*. 1.1700 +// Used to implemenent polymorphic inlining. 1.1701 +class LFunctionDispatch : public LInstructionHelper<0, 1, 0> 1.1702 +{ 1.1703 + // Dispatch is performed based on a function -> block map 1.1704 + // stored in the MIR. 1.1705 + 1.1706 + public: 1.1707 + LIR_HEADER(FunctionDispatch); 1.1708 + 1.1709 + LFunctionDispatch(const LAllocation &in) { 1.1710 + setOperand(0, in); 1.1711 + } 1.1712 + 1.1713 + MFunctionDispatch *mir() { 1.1714 + return mir_->toFunctionDispatch(); 1.1715 + } 1.1716 +}; 1.1717 + 1.1718 +class LTypeObjectDispatch : public LInstructionHelper<0, 1, 1> 1.1719 +{ 1.1720 + // Dispatch is performed based on a TypeObject -> block 1.1721 + // map inferred by the MIR. 1.1722 + 1.1723 + public: 1.1724 + LIR_HEADER(TypeObjectDispatch); 1.1725 + 1.1726 + LTypeObjectDispatch(const LAllocation &in, const LDefinition &temp) { 1.1727 + setOperand(0, in); 1.1728 + setTemp(0, temp); 1.1729 + } 1.1730 + 1.1731 + const LDefinition *temp() { 1.1732 + return getTemp(0); 1.1733 + } 1.1734 + 1.1735 + MTypeObjectDispatch *mir() { 1.1736 + return mir_->toTypeObjectDispatch(); 1.1737 + } 1.1738 +}; 1.1739 + 1.1740 +// Compares two integral values of the same JS type, either integer or object. 1.1741 +// For objects, both operands are in registers. 1.1742 +class LCompare : public LInstructionHelper<1, 2, 0> 1.1743 +{ 1.1744 + JSOp jsop_; 1.1745 + 1.1746 + public: 1.1747 + LIR_HEADER(Compare) 1.1748 + LCompare(JSOp jsop, const LAllocation &left, const LAllocation &right) 1.1749 + : jsop_(jsop) 1.1750 + { 1.1751 + setOperand(0, left); 1.1752 + setOperand(1, right); 1.1753 + } 1.1754 + 1.1755 + JSOp jsop() const { 1.1756 + return jsop_; 1.1757 + } 1.1758 + const LAllocation *left() { 1.1759 + return getOperand(0); 1.1760 + } 1.1761 + const LAllocation *right() { 1.1762 + return getOperand(1); 1.1763 + } 1.1764 + MCompare *mir() { 1.1765 + return mir_->toCompare(); 1.1766 + } 1.1767 + const char *extraName() const { 1.1768 + return js_CodeName[jsop_]; 1.1769 + } 1.1770 +}; 1.1771 + 1.1772 +// Compares two integral values of the same JS type, either integer or object. 1.1773 +// For objects, both operands are in registers. 1.1774 +class LCompareAndBranch : public LControlInstructionHelper<2, 2, 0> 1.1775 +{ 1.1776 + MCompare *cmpMir_; 1.1777 + JSOp jsop_; 1.1778 + 1.1779 + public: 1.1780 + LIR_HEADER(CompareAndBranch) 1.1781 + LCompareAndBranch(MCompare *cmpMir, JSOp jsop, 1.1782 + const LAllocation &left, const LAllocation &right, 1.1783 + MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.1784 + : cmpMir_(cmpMir), jsop_(jsop) 1.1785 + { 1.1786 + setOperand(0, left); 1.1787 + setOperand(1, right); 1.1788 + setSuccessor(0, ifTrue); 1.1789 + setSuccessor(1, ifFalse); 1.1790 + } 1.1791 + 1.1792 + JSOp jsop() const { 1.1793 + return jsop_; 1.1794 + } 1.1795 + MBasicBlock *ifTrue() const { 1.1796 + return getSuccessor(0); 1.1797 + } 1.1798 + MBasicBlock *ifFalse() const { 1.1799 + return getSuccessor(1); 1.1800 + } 1.1801 + const LAllocation *left() { 1.1802 + return getOperand(0); 1.1803 + } 1.1804 + const LAllocation *right() { 1.1805 + return getOperand(1); 1.1806 + } 1.1807 + MTest *mir() const { 1.1808 + return mir_->toTest(); 1.1809 + } 1.1810 + MCompare *cmpMir() const { 1.1811 + return cmpMir_; 1.1812 + } 1.1813 + const char *extraName() const { 1.1814 + return js_CodeName[jsop_]; 1.1815 + } 1.1816 +}; 1.1817 + 1.1818 +class LCompareD : public LInstructionHelper<1, 2, 0> 1.1819 +{ 1.1820 + public: 1.1821 + LIR_HEADER(CompareD) 1.1822 + LCompareD(const LAllocation &left, const LAllocation &right) { 1.1823 + setOperand(0, left); 1.1824 + setOperand(1, right); 1.1825 + } 1.1826 + 1.1827 + const LAllocation *left() { 1.1828 + return getOperand(0); 1.1829 + } 1.1830 + const LAllocation *right() { 1.1831 + return getOperand(1); 1.1832 + } 1.1833 + MCompare *mir() { 1.1834 + return mir_->toCompare(); 1.1835 + } 1.1836 +}; 1.1837 + 1.1838 +class LCompareF : public LInstructionHelper<1, 2, 0> 1.1839 +{ 1.1840 + public: 1.1841 + LIR_HEADER(CompareF) 1.1842 + LCompareF(const LAllocation &left, const LAllocation &right) { 1.1843 + setOperand(0, left); 1.1844 + setOperand(1, right); 1.1845 + } 1.1846 + 1.1847 + const LAllocation *left() { 1.1848 + return getOperand(0); 1.1849 + } 1.1850 + const LAllocation *right() { 1.1851 + return getOperand(1); 1.1852 + } 1.1853 + MCompare *mir() { 1.1854 + return mir_->toCompare(); 1.1855 + } 1.1856 +}; 1.1857 + 1.1858 +class LCompareDAndBranch : public LControlInstructionHelper<2, 2, 0> 1.1859 +{ 1.1860 + MCompare *cmpMir_; 1.1861 + 1.1862 + public: 1.1863 + LIR_HEADER(CompareDAndBranch) 1.1864 + LCompareDAndBranch(MCompare *cmpMir, const LAllocation &left, const LAllocation &right, 1.1865 + MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.1866 + : cmpMir_(cmpMir) 1.1867 + { 1.1868 + setOperand(0, left); 1.1869 + setOperand(1, right); 1.1870 + setSuccessor(0, ifTrue); 1.1871 + setSuccessor(1, ifFalse); 1.1872 + } 1.1873 + 1.1874 + MBasicBlock *ifTrue() const { 1.1875 + return getSuccessor(0); 1.1876 + } 1.1877 + MBasicBlock *ifFalse() const { 1.1878 + return getSuccessor(1); 1.1879 + } 1.1880 + const LAllocation *left() { 1.1881 + return getOperand(0); 1.1882 + } 1.1883 + const LAllocation *right() { 1.1884 + return getOperand(1); 1.1885 + } 1.1886 + MTest *mir() const { 1.1887 + return mir_->toTest(); 1.1888 + } 1.1889 + MCompare *cmpMir() const { 1.1890 + return cmpMir_; 1.1891 + } 1.1892 +}; 1.1893 + 1.1894 +class LCompareFAndBranch : public LControlInstructionHelper<2, 2, 0> 1.1895 +{ 1.1896 + MCompare *cmpMir_; 1.1897 + 1.1898 + public: 1.1899 + LIR_HEADER(CompareFAndBranch) 1.1900 + LCompareFAndBranch(MCompare *cmpMir, const LAllocation &left, const LAllocation &right, 1.1901 + MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.1902 + : cmpMir_(cmpMir) 1.1903 + { 1.1904 + setOperand(0, left); 1.1905 + setOperand(1, right); 1.1906 + setSuccessor(0, ifTrue); 1.1907 + setSuccessor(1, ifFalse); 1.1908 + } 1.1909 + 1.1910 + MBasicBlock *ifTrue() const { 1.1911 + return getSuccessor(0); 1.1912 + } 1.1913 + MBasicBlock *ifFalse() const { 1.1914 + return getSuccessor(1); 1.1915 + } 1.1916 + const LAllocation *left() { 1.1917 + return getOperand(0); 1.1918 + } 1.1919 + const LAllocation *right() { 1.1920 + return getOperand(1); 1.1921 + } 1.1922 + MTest *mir() const { 1.1923 + return mir_->toTest(); 1.1924 + } 1.1925 + MCompare *cmpMir() const { 1.1926 + return cmpMir_; 1.1927 + } 1.1928 +}; 1.1929 + 1.1930 +class LCompareS : public LInstructionHelper<1, 2, 1> 1.1931 +{ 1.1932 + public: 1.1933 + LIR_HEADER(CompareS) 1.1934 + LCompareS(const LAllocation &left, const LAllocation &right, 1.1935 + const LDefinition &temp) { 1.1936 + setOperand(0, left); 1.1937 + setOperand(1, right); 1.1938 + setTemp(0, temp); 1.1939 + } 1.1940 + 1.1941 + const LAllocation *left() { 1.1942 + return getOperand(0); 1.1943 + } 1.1944 + const LAllocation *right() { 1.1945 + return getOperand(1); 1.1946 + } 1.1947 + const LDefinition *temp() { 1.1948 + return getTemp(0); 1.1949 + } 1.1950 + MCompare *mir() { 1.1951 + return mir_->toCompare(); 1.1952 + } 1.1953 +}; 1.1954 + 1.1955 +// strict-equality between value and string. 1.1956 +class LCompareStrictS : public LInstructionHelper<1, BOX_PIECES + 1, 2> 1.1957 +{ 1.1958 + public: 1.1959 + LIR_HEADER(CompareStrictS) 1.1960 + LCompareStrictS(const LAllocation &rhs, const LDefinition &temp0, 1.1961 + const LDefinition &temp1) { 1.1962 + setOperand(BOX_PIECES, rhs); 1.1963 + setTemp(0, temp0); 1.1964 + setTemp(1, temp1); 1.1965 + } 1.1966 + 1.1967 + static const size_t Lhs = 0; 1.1968 + 1.1969 + const LAllocation *right() { 1.1970 + return getOperand(BOX_PIECES); 1.1971 + } 1.1972 + const LDefinition *temp() { 1.1973 + return getTemp(0); 1.1974 + } 1.1975 + const LDefinition *tempToUnbox() { 1.1976 + return getTemp(1); 1.1977 + } 1.1978 + MCompare *mir() { 1.1979 + return mir_->toCompare(); 1.1980 + } 1.1981 +}; 1.1982 + 1.1983 +// Used for strict-equality comparisons where one side is a boolean 1.1984 +// and the other is a value. Note that CompareI is used to compare 1.1985 +// two booleans. 1.1986 +class LCompareB : public LInstructionHelper<1, BOX_PIECES + 1, 0> 1.1987 +{ 1.1988 + public: 1.1989 + LIR_HEADER(CompareB) 1.1990 + 1.1991 + LCompareB(const LAllocation &rhs) { 1.1992 + setOperand(BOX_PIECES, rhs); 1.1993 + } 1.1994 + 1.1995 + static const size_t Lhs = 0; 1.1996 + 1.1997 + const LAllocation *rhs() { 1.1998 + return getOperand(BOX_PIECES); 1.1999 + } 1.2000 + 1.2001 + MCompare *mir() { 1.2002 + return mir_->toCompare(); 1.2003 + } 1.2004 +}; 1.2005 + 1.2006 +class LCompareBAndBranch : public LControlInstructionHelper<2, BOX_PIECES + 1, 0> 1.2007 +{ 1.2008 + MCompare *cmpMir_; 1.2009 + 1.2010 + public: 1.2011 + LIR_HEADER(CompareBAndBranch) 1.2012 + 1.2013 + LCompareBAndBranch(MCompare *cmpMir, const LAllocation &rhs, 1.2014 + MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.2015 + : cmpMir_(cmpMir) 1.2016 + { 1.2017 + setOperand(BOX_PIECES, rhs); 1.2018 + setSuccessor(0, ifTrue); 1.2019 + setSuccessor(1, ifFalse); 1.2020 + } 1.2021 + 1.2022 + static const size_t Lhs = 0; 1.2023 + 1.2024 + const LAllocation *rhs() { 1.2025 + return getOperand(BOX_PIECES); 1.2026 + } 1.2027 + 1.2028 + MBasicBlock *ifTrue() const { 1.2029 + return getSuccessor(0); 1.2030 + } 1.2031 + MBasicBlock *ifFalse() const { 1.2032 + return getSuccessor(1); 1.2033 + } 1.2034 + MTest *mir() const { 1.2035 + return mir_->toTest(); 1.2036 + } 1.2037 + MCompare *cmpMir() const { 1.2038 + return cmpMir_; 1.2039 + } 1.2040 +}; 1.2041 + 1.2042 +class LCompareV : public LInstructionHelper<1, 2 * BOX_PIECES, 0> 1.2043 +{ 1.2044 + public: 1.2045 + LIR_HEADER(CompareV) 1.2046 + 1.2047 + static const size_t LhsInput = 0; 1.2048 + static const size_t RhsInput = BOX_PIECES; 1.2049 + 1.2050 + MCompare *mir() const { 1.2051 + return mir_->toCompare(); 1.2052 + } 1.2053 +}; 1.2054 + 1.2055 +class LCompareVAndBranch : public LControlInstructionHelper<2, 2 * BOX_PIECES, 0> 1.2056 +{ 1.2057 + MCompare *cmpMir_; 1.2058 + 1.2059 + public: 1.2060 + LIR_HEADER(CompareVAndBranch) 1.2061 + 1.2062 + static const size_t LhsInput = 0; 1.2063 + static const size_t RhsInput = BOX_PIECES; 1.2064 + 1.2065 + LCompareVAndBranch(MCompare *cmpMir, MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.2066 + : cmpMir_(cmpMir) 1.2067 + { 1.2068 + setSuccessor(0, ifTrue); 1.2069 + setSuccessor(1, ifFalse); 1.2070 + } 1.2071 + 1.2072 + MBasicBlock *ifTrue() const { 1.2073 + return getSuccessor(0); 1.2074 + } 1.2075 + MBasicBlock *ifFalse() const { 1.2076 + return getSuccessor(1); 1.2077 + } 1.2078 + MTest *mir() const { 1.2079 + return mir_->toTest(); 1.2080 + } 1.2081 + MCompare *cmpMir() const { 1.2082 + return cmpMir_; 1.2083 + } 1.2084 +}; 1.2085 + 1.2086 +class LCompareVM : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0> 1.2087 +{ 1.2088 + public: 1.2089 + LIR_HEADER(CompareVM) 1.2090 + 1.2091 + static const size_t LhsInput = 0; 1.2092 + static const size_t RhsInput = BOX_PIECES; 1.2093 + 1.2094 + MCompare *mir() const { 1.2095 + return mir_->toCompare(); 1.2096 + } 1.2097 +}; 1.2098 + 1.2099 +class LBitAndAndBranch : public LControlInstructionHelper<2, 2, 0> 1.2100 +{ 1.2101 + public: 1.2102 + LIR_HEADER(BitAndAndBranch) 1.2103 + LBitAndAndBranch(MBasicBlock *ifTrue, MBasicBlock *ifFalse) 1.2104 + { 1.2105 + setSuccessor(0, ifTrue); 1.2106 + setSuccessor(1, ifFalse); 1.2107 + } 1.2108 + 1.2109 + MBasicBlock *ifTrue() const { 1.2110 + return getSuccessor(0); 1.2111 + } 1.2112 + MBasicBlock *ifFalse() const { 1.2113 + return getSuccessor(1); 1.2114 + } 1.2115 + const LAllocation *left() { 1.2116 + return getOperand(0); 1.2117 + } 1.2118 + const LAllocation *right() { 1.2119 + return getOperand(1); 1.2120 + } 1.2121 +}; 1.2122 + 1.2123 +class LIsNullOrLikeUndefined : public LInstructionHelper<1, BOX_PIECES, 2> 1.2124 +{ 1.2125 + public: 1.2126 + LIR_HEADER(IsNullOrLikeUndefined) 1.2127 + 1.2128 + LIsNullOrLikeUndefined(const LDefinition &temp, const LDefinition &tempToUnbox) 1.2129 + { 1.2130 + setTemp(0, temp); 1.2131 + setTemp(1, tempToUnbox); 1.2132 + } 1.2133 + 1.2134 + static const size_t Value = 0; 1.2135 + 1.2136 + MCompare *mir() { 1.2137 + return mir_->toCompare(); 1.2138 + } 1.2139 + 1.2140 + const LDefinition *temp() { 1.2141 + return getTemp(0); 1.2142 + } 1.2143 + 1.2144 + const LDefinition *tempToUnbox() { 1.2145 + return getTemp(1); 1.2146 + } 1.2147 +}; 1.2148 + 1.2149 +class LIsNullOrLikeUndefinedAndBranch : public LControlInstructionHelper<2, BOX_PIECES, 2> 1.2150 +{ 1.2151 + MCompare *cmpMir_; 1.2152 + 1.2153 + public: 1.2154 + LIR_HEADER(IsNullOrLikeUndefinedAndBranch) 1.2155 + 1.2156 + LIsNullOrLikeUndefinedAndBranch(MCompare *cmpMir, MBasicBlock *ifTrue, MBasicBlock *ifFalse, 1.2157 + const LDefinition &temp, const LDefinition &tempToUnbox) 1.2158 + : cmpMir_(cmpMir) 1.2159 + { 1.2160 + setSuccessor(0, ifTrue); 1.2161 + setSuccessor(1, ifFalse); 1.2162 + setTemp(0, temp); 1.2163 + setTemp(1, tempToUnbox); 1.2164 + } 1.2165 + 1.2166 + static const size_t Value = 0; 1.2167 + 1.2168 + MBasicBlock *ifTrue() const { 1.2169 + return getSuccessor(0); 1.2170 + } 1.2171 + MBasicBlock *ifFalse() const { 1.2172 + return getSuccessor(1); 1.2173 + } 1.2174 + MTest *mir() const { 1.2175 + return mir_->toTest(); 1.2176 + } 1.2177 + MCompare *cmpMir() const { 1.2178 + return cmpMir_; 1.2179 + } 1.2180 + const LDefinition *temp() { 1.2181 + return getTemp(0); 1.2182 + } 1.2183 + const LDefinition *tempToUnbox() { 1.2184 + return getTemp(1); 1.2185 + } 1.2186 +}; 1.2187 + 1.2188 +// Takes an object and tests whether it emulates |undefined|, as determined by 1.2189 +// the JSCLASS_EMULATES_UNDEFINED class flag on unwrapped objects. See also 1.2190 +// js::EmulatesUndefined. 1.2191 +class LEmulatesUndefined : public LInstructionHelper<1, 1, 0> 1.2192 +{ 1.2193 + public: 1.2194 + LIR_HEADER(EmulatesUndefined) 1.2195 + 1.2196 + LEmulatesUndefined(const LAllocation &input) 1.2197 + { 1.2198 + setOperand(0, input); 1.2199 + } 1.2200 + 1.2201 + MCompare *mir() { 1.2202 + return mir_->toCompare(); 1.2203 + } 1.2204 +}; 1.2205 + 1.2206 +class LEmulatesUndefinedAndBranch : public LControlInstructionHelper<2, 1, 1> 1.2207 +{ 1.2208 + MCompare *cmpMir_; 1.2209 + 1.2210 + public: 1.2211 + LIR_HEADER(EmulatesUndefinedAndBranch) 1.2212 + 1.2213 + LEmulatesUndefinedAndBranch(MCompare *cmpMir, const LAllocation &input, 1.2214 + MBasicBlock *ifTrue, MBasicBlock *ifFalse, 1.2215 + const LDefinition &temp) 1.2216 + : cmpMir_(cmpMir) 1.2217 + { 1.2218 + setOperand(0, input); 1.2219 + setSuccessor(0, ifTrue); 1.2220 + setSuccessor(1, ifFalse); 1.2221 + setTemp(0, temp); 1.2222 + } 1.2223 + 1.2224 + MBasicBlock *ifTrue() const { 1.2225 + return getSuccessor(0); 1.2226 + } 1.2227 + MBasicBlock *ifFalse() const { 1.2228 + return getSuccessor(1); 1.2229 + } 1.2230 + MTest *mir() const { 1.2231 + return mir_->toTest(); 1.2232 + } 1.2233 + MCompare *cmpMir() const { 1.2234 + return cmpMir_; 1.2235 + } 1.2236 + const LDefinition *temp() { 1.2237 + return getTemp(0); 1.2238 + } 1.2239 +}; 1.2240 + 1.2241 +// Not operation on an integer. 1.2242 +class LNotI : public LInstructionHelper<1, 1, 0> 1.2243 +{ 1.2244 + public: 1.2245 + LIR_HEADER(NotI) 1.2246 + 1.2247 + LNotI(const LAllocation &input) { 1.2248 + setOperand(0, input); 1.2249 + } 1.2250 +}; 1.2251 + 1.2252 +// Not operation on a double. 1.2253 +class LNotD : public LInstructionHelper<1, 1, 0> 1.2254 +{ 1.2255 + public: 1.2256 + LIR_HEADER(NotD) 1.2257 + 1.2258 + LNotD(const LAllocation &input) { 1.2259 + setOperand(0, input); 1.2260 + } 1.2261 + 1.2262 + MNot *mir() { 1.2263 + return mir_->toNot(); 1.2264 + } 1.2265 +}; 1.2266 + 1.2267 +// Not operation on a float32. 1.2268 +class LNotF : public LInstructionHelper<1, 1, 0> 1.2269 +{ 1.2270 + public: 1.2271 + LIR_HEADER(NotF) 1.2272 + 1.2273 + LNotF(const LAllocation &input) { 1.2274 + setOperand(0, input); 1.2275 + } 1.2276 + 1.2277 + MNot *mir() { 1.2278 + return mir_->toNot(); 1.2279 + } 1.2280 +}; 1.2281 + 1.2282 +// Boolean complement operation on an object. 1.2283 +class LNotO : public LInstructionHelper<1, 1, 0> 1.2284 +{ 1.2285 + public: 1.2286 + LIR_HEADER(NotO) 1.2287 + 1.2288 + LNotO(const LAllocation &input) 1.2289 + { 1.2290 + setOperand(0, input); 1.2291 + } 1.2292 + 1.2293 + MNot *mir() { 1.2294 + return mir_->toNot(); 1.2295 + } 1.2296 +}; 1.2297 + 1.2298 +// Boolean complement operation on a value. 1.2299 +class LNotV : public LInstructionHelper<1, BOX_PIECES, 3> 1.2300 +{ 1.2301 + public: 1.2302 + LIR_HEADER(NotV) 1.2303 + 1.2304 + static const size_t Input = 0; 1.2305 + LNotV(const LDefinition &temp0, const LDefinition &temp1, const LDefinition &temp2) 1.2306 + { 1.2307 + setTemp(0, temp0); 1.2308 + setTemp(1, temp1); 1.2309 + setTemp(2, temp2); 1.2310 + } 1.2311 + 1.2312 + const LDefinition *tempFloat() { 1.2313 + return getTemp(0); 1.2314 + } 1.2315 + 1.2316 + const LDefinition *temp1() { 1.2317 + return getTemp(1); 1.2318 + } 1.2319 + 1.2320 + const LDefinition *temp2() { 1.2321 + return getTemp(2); 1.2322 + } 1.2323 + 1.2324 + MNot *mir() { 1.2325 + return mir_->toNot(); 1.2326 + } 1.2327 +}; 1.2328 + 1.2329 +// Bitwise not operation, takes a 32-bit integer as input and returning 1.2330 +// a 32-bit integer result as an output. 1.2331 +class LBitNotI : public LInstructionHelper<1, 1, 0> 1.2332 +{ 1.2333 + public: 1.2334 + LIR_HEADER(BitNotI) 1.2335 +}; 1.2336 + 1.2337 +// Call a VM function to perform a BITNOT operation. 1.2338 +class LBitNotV : public LCallInstructionHelper<1, BOX_PIECES, 0> 1.2339 +{ 1.2340 + public: 1.2341 + LIR_HEADER(BitNotV) 1.2342 + 1.2343 + static const size_t Input = 0; 1.2344 +}; 1.2345 + 1.2346 +// Binary bitwise operation, taking two 32-bit integers as inputs and returning 1.2347 +// a 32-bit integer result as an output. 1.2348 +class LBitOpI : public LInstructionHelper<1, 2, 0> 1.2349 +{ 1.2350 + JSOp op_; 1.2351 + 1.2352 + public: 1.2353 + LIR_HEADER(BitOpI) 1.2354 + 1.2355 + LBitOpI(JSOp op) 1.2356 + : op_(op) 1.2357 + { } 1.2358 + 1.2359 + const char *extraName() const { 1.2360 + if (bitop() == JSOP_URSH && mir_->toUrsh()->bailoutsDisabled()) 1.2361 + return "ursh:BailoutsDisabled"; 1.2362 + return js_CodeName[op_]; 1.2363 + } 1.2364 + 1.2365 + JSOp bitop() const { 1.2366 + return op_; 1.2367 + } 1.2368 +}; 1.2369 + 1.2370 +// Call a VM function to perform a bitwise operation. 1.2371 +class LBitOpV : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0> 1.2372 +{ 1.2373 + JSOp jsop_; 1.2374 + 1.2375 + public: 1.2376 + LIR_HEADER(BitOpV) 1.2377 + 1.2378 + LBitOpV(JSOp jsop) 1.2379 + : jsop_(jsop) 1.2380 + { } 1.2381 + 1.2382 + JSOp jsop() const { 1.2383 + return jsop_; 1.2384 + } 1.2385 + 1.2386 + const char *extraName() const { 1.2387 + return js_CodeName[jsop_]; 1.2388 + } 1.2389 + 1.2390 + static const size_t LhsInput = 0; 1.2391 + static const size_t RhsInput = BOX_PIECES; 1.2392 +}; 1.2393 + 1.2394 +// Shift operation, taking two 32-bit integers as inputs and returning 1.2395 +// a 32-bit integer result as an output. 1.2396 +class LShiftI : public LBinaryMath<0> 1.2397 +{ 1.2398 + JSOp op_; 1.2399 + 1.2400 + public: 1.2401 + LIR_HEADER(ShiftI) 1.2402 + 1.2403 + LShiftI(JSOp op) 1.2404 + : op_(op) 1.2405 + { } 1.2406 + 1.2407 + JSOp bitop() { 1.2408 + return op_; 1.2409 + } 1.2410 + 1.2411 + MInstruction *mir() { 1.2412 + return mir_->toInstruction(); 1.2413 + } 1.2414 + 1.2415 + const char *extraName() const { 1.2416 + return js_CodeName[op_]; 1.2417 + } 1.2418 +}; 1.2419 + 1.2420 +class LUrshD : public LBinaryMath<1> 1.2421 +{ 1.2422 + public: 1.2423 + LIR_HEADER(UrshD) 1.2424 + 1.2425 + LUrshD(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) { 1.2426 + setOperand(0, lhs); 1.2427 + setOperand(1, rhs); 1.2428 + setTemp(0, temp); 1.2429 + } 1.2430 + const LDefinition *temp() { 1.2431 + return getTemp(0); 1.2432 + } 1.2433 +}; 1.2434 + 1.2435 +// Returns from the function being compiled (not used in inlined frames). The 1.2436 +// input must be a box. 1.2437 +class LReturn : public LInstructionHelper<0, BOX_PIECES, 0> 1.2438 +{ 1.2439 + public: 1.2440 + LIR_HEADER(Return) 1.2441 +}; 1.2442 + 1.2443 +class LThrow : public LCallInstructionHelper<0, BOX_PIECES, 0> 1.2444 +{ 1.2445 + public: 1.2446 + LIR_HEADER(Throw) 1.2447 + 1.2448 + static const size_t Value = 0; 1.2449 +}; 1.2450 + 1.2451 +class LMinMaxI : public LInstructionHelper<1, 2, 0> 1.2452 +{ 1.2453 + public: 1.2454 + LIR_HEADER(MinMaxI) 1.2455 + LMinMaxI(const LAllocation &first, const LAllocation &second) 1.2456 + { 1.2457 + setOperand(0, first); 1.2458 + setOperand(1, second); 1.2459 + } 1.2460 + 1.2461 + const LAllocation *first() { 1.2462 + return this->getOperand(0); 1.2463 + } 1.2464 + const LAllocation *second() { 1.2465 + return this->getOperand(1); 1.2466 + } 1.2467 + const LDefinition *output() { 1.2468 + return this->getDef(0); 1.2469 + } 1.2470 + MMinMax *mir() const { 1.2471 + return mir_->toMinMax(); 1.2472 + } 1.2473 + const char *extraName() const { 1.2474 + return mir()->isMax() ? "Max" : "Min"; 1.2475 + } 1.2476 +}; 1.2477 + 1.2478 +class LMinMaxD : public LInstructionHelper<1, 2, 0> 1.2479 +{ 1.2480 + public: 1.2481 + LIR_HEADER(MinMaxD) 1.2482 + LMinMaxD(const LAllocation &first, const LAllocation &second) 1.2483 + { 1.2484 + setOperand(0, first); 1.2485 + setOperand(1, second); 1.2486 + } 1.2487 + 1.2488 + const LAllocation *first() { 1.2489 + return this->getOperand(0); 1.2490 + } 1.2491 + const LAllocation *second() { 1.2492 + return this->getOperand(1); 1.2493 + } 1.2494 + const LDefinition *output() { 1.2495 + return this->getDef(0); 1.2496 + } 1.2497 + MMinMax *mir() const { 1.2498 + return mir_->toMinMax(); 1.2499 + } 1.2500 + const char *extraName() const { 1.2501 + return mir()->isMax() ? "Max" : "Min"; 1.2502 + } 1.2503 +}; 1.2504 + 1.2505 +// Negative of an integer 1.2506 +class LNegI : public LInstructionHelper<1, 1, 0> 1.2507 +{ 1.2508 + public: 1.2509 + LIR_HEADER(NegI); 1.2510 + LNegI(const LAllocation &num) { 1.2511 + setOperand(0, num); 1.2512 + } 1.2513 +}; 1.2514 + 1.2515 +// Negative of a double. 1.2516 +class LNegD : public LInstructionHelper<1, 1, 0> 1.2517 +{ 1.2518 + public: 1.2519 + LIR_HEADER(NegD) 1.2520 + LNegD(const LAllocation &num) { 1.2521 + setOperand(0, num); 1.2522 + } 1.2523 +}; 1.2524 + 1.2525 +// Negative of a float32. 1.2526 +class LNegF : public LInstructionHelper<1, 1, 0> 1.2527 +{ 1.2528 + public: 1.2529 + LIR_HEADER(NegF) 1.2530 + LNegF(const LAllocation &num) { 1.2531 + setOperand(0, num); 1.2532 + } 1.2533 +}; 1.2534 + 1.2535 +// Absolute value of an integer. 1.2536 +class LAbsI : public LInstructionHelper<1, 1, 0> 1.2537 +{ 1.2538 + public: 1.2539 + LIR_HEADER(AbsI) 1.2540 + LAbsI(const LAllocation &num) { 1.2541 + setOperand(0, num); 1.2542 + } 1.2543 +}; 1.2544 + 1.2545 +// Absolute value of a double. 1.2546 +class LAbsD : public LInstructionHelper<1, 1, 0> 1.2547 +{ 1.2548 + public: 1.2549 + LIR_HEADER(AbsD) 1.2550 + LAbsD(const LAllocation &num) { 1.2551 + setOperand(0, num); 1.2552 + } 1.2553 +}; 1.2554 + 1.2555 +// Absolute value of a float32. 1.2556 +class LAbsF : public LInstructionHelper<1, 1, 0> 1.2557 +{ 1.2558 + public: 1.2559 + LIR_HEADER(AbsF) 1.2560 + LAbsF(const LAllocation &num) { 1.2561 + setOperand(0, num); 1.2562 + } 1.2563 +}; 1.2564 + 1.2565 +// Square root of a double. 1.2566 +class LSqrtD : public LInstructionHelper<1, 1, 0> 1.2567 +{ 1.2568 + public: 1.2569 + LIR_HEADER(SqrtD) 1.2570 + LSqrtD(const LAllocation &num) { 1.2571 + setOperand(0, num); 1.2572 + } 1.2573 +}; 1.2574 + 1.2575 +// Square root of a float32. 1.2576 +class LSqrtF : public LInstructionHelper<1, 1, 0> 1.2577 +{ 1.2578 + public: 1.2579 + LIR_HEADER(SqrtF) 1.2580 + LSqrtF(const LAllocation &num) { 1.2581 + setOperand(0, num); 1.2582 + } 1.2583 +}; 1.2584 + 1.2585 +class LAtan2D : public LCallInstructionHelper<1, 2, 1> 1.2586 +{ 1.2587 + public: 1.2588 + LIR_HEADER(Atan2D) 1.2589 + LAtan2D(const LAllocation &y, const LAllocation &x, const LDefinition &temp) { 1.2590 + setOperand(0, y); 1.2591 + setOperand(1, x); 1.2592 + setTemp(0, temp); 1.2593 + } 1.2594 + 1.2595 + const LAllocation *y() { 1.2596 + return getOperand(0); 1.2597 + } 1.2598 + 1.2599 + const LAllocation *x() { 1.2600 + return getOperand(1); 1.2601 + } 1.2602 + 1.2603 + const LDefinition *temp() { 1.2604 + return getTemp(0); 1.2605 + } 1.2606 + 1.2607 + const LDefinition *output() { 1.2608 + return getDef(0); 1.2609 + } 1.2610 +}; 1.2611 + 1.2612 +class LHypot : public LCallInstructionHelper<1, 2, 1> 1.2613 +{ 1.2614 + public: 1.2615 + LIR_HEADER(Hypot) 1.2616 + LHypot(const LAllocation &x, const LAllocation &y, const LDefinition &temp) { 1.2617 + setOperand(0, x); 1.2618 + setOperand(1, y); 1.2619 + setTemp(0, temp); 1.2620 + } 1.2621 + 1.2622 + const LAllocation *x() { 1.2623 + return getOperand(0); 1.2624 + } 1.2625 + 1.2626 + const LAllocation *y() { 1.2627 + return getOperand(1); 1.2628 + } 1.2629 + 1.2630 + const LDefinition *temp() { 1.2631 + return getTemp(0); 1.2632 + } 1.2633 + 1.2634 + const LDefinition *output() { 1.2635 + return getDef(0); 1.2636 + } 1.2637 +}; 1.2638 + 1.2639 +// Double raised to an integer power. 1.2640 +class LPowI : public LCallInstructionHelper<1, 2, 1> 1.2641 +{ 1.2642 + public: 1.2643 + LIR_HEADER(PowI) 1.2644 + LPowI(const LAllocation &value, const LAllocation &power, const LDefinition &temp) { 1.2645 + setOperand(0, value); 1.2646 + setOperand(1, power); 1.2647 + setTemp(0, temp); 1.2648 + } 1.2649 + 1.2650 + const LAllocation *value() { 1.2651 + return getOperand(0); 1.2652 + } 1.2653 + const LAllocation *power() { 1.2654 + return getOperand(1); 1.2655 + } 1.2656 + const LDefinition *temp() { 1.2657 + return getTemp(0); 1.2658 + } 1.2659 +}; 1.2660 + 1.2661 +// Double raised to a double power. 1.2662 +class LPowD : public LCallInstructionHelper<1, 2, 1> 1.2663 +{ 1.2664 + public: 1.2665 + LIR_HEADER(PowD) 1.2666 + LPowD(const LAllocation &value, const LAllocation &power, const LDefinition &temp) { 1.2667 + setOperand(0, value); 1.2668 + setOperand(1, power); 1.2669 + setTemp(0, temp); 1.2670 + } 1.2671 + 1.2672 + const LAllocation *value() { 1.2673 + return getOperand(0); 1.2674 + } 1.2675 + const LAllocation *power() { 1.2676 + return getOperand(1); 1.2677 + } 1.2678 + const LDefinition *temp() { 1.2679 + return getTemp(0); 1.2680 + } 1.2681 +}; 1.2682 + 1.2683 +// Math.random(). 1.2684 +class LRandom : public LCallInstructionHelper<1, 0, 2> 1.2685 +{ 1.2686 + public: 1.2687 + LIR_HEADER(Random) 1.2688 + LRandom(const LDefinition &temp, const LDefinition &temp2) { 1.2689 + setTemp(0, temp); 1.2690 + setTemp(1, temp2); 1.2691 + } 1.2692 + const LDefinition *temp() { 1.2693 + return getTemp(0); 1.2694 + } 1.2695 + const LDefinition *temp2() { 1.2696 + return getTemp(1); 1.2697 + } 1.2698 +}; 1.2699 + 1.2700 +class LMathFunctionD : public LCallInstructionHelper<1, 1, 1> 1.2701 +{ 1.2702 + public: 1.2703 + LIR_HEADER(MathFunctionD) 1.2704 + LMathFunctionD(const LAllocation &input, const LDefinition &temp) { 1.2705 + setOperand(0, input); 1.2706 + setTemp(0, temp); 1.2707 + } 1.2708 + 1.2709 + const LDefinition *temp() { 1.2710 + return getTemp(0); 1.2711 + } 1.2712 + MMathFunction *mir() const { 1.2713 + return mir_->toMathFunction(); 1.2714 + } 1.2715 + const char *extraName() const { 1.2716 + return MMathFunction::FunctionName(mir()->function()); 1.2717 + } 1.2718 +}; 1.2719 + 1.2720 +class LMathFunctionF : public LCallInstructionHelper<1, 1, 1> 1.2721 +{ 1.2722 + public: 1.2723 + LIR_HEADER(MathFunctionF) 1.2724 + LMathFunctionF(const LAllocation &input, const LDefinition &temp) { 1.2725 + setOperand(0, input); 1.2726 + setTemp(0, temp); 1.2727 + } 1.2728 + 1.2729 + const LDefinition *temp() { 1.2730 + return getTemp(0); 1.2731 + } 1.2732 + MMathFunction *mir() const { 1.2733 + return mir_->toMathFunction(); 1.2734 + } 1.2735 + const char *extraName() const { 1.2736 + return MMathFunction::FunctionName(mir()->function()); 1.2737 + } 1.2738 +}; 1.2739 + 1.2740 +// Adds two integers, returning an integer value. 1.2741 +class LAddI : public LBinaryMath<0> 1.2742 +{ 1.2743 + bool recoversInput_; 1.2744 + 1.2745 + public: 1.2746 + LIR_HEADER(AddI) 1.2747 + 1.2748 + LAddI() 1.2749 + : recoversInput_(false) 1.2750 + { } 1.2751 + 1.2752 + const char *extraName() const { 1.2753 + return snapshot() ? "OverflowCheck" : nullptr; 1.2754 + } 1.2755 + 1.2756 + virtual bool recoversInput() const { 1.2757 + return recoversInput_; 1.2758 + } 1.2759 + void setRecoversInput() { 1.2760 + recoversInput_ = true; 1.2761 + } 1.2762 +}; 1.2763 + 1.2764 +// Subtracts two integers, returning an integer value. 1.2765 +class LSubI : public LBinaryMath<0> 1.2766 +{ 1.2767 + bool recoversInput_; 1.2768 + 1.2769 + public: 1.2770 + LIR_HEADER(SubI) 1.2771 + 1.2772 + LSubI() 1.2773 + : recoversInput_(false) 1.2774 + { } 1.2775 + 1.2776 + const char *extraName() const { 1.2777 + return snapshot() ? "OverflowCheck" : nullptr; 1.2778 + } 1.2779 + 1.2780 + virtual bool recoversInput() const { 1.2781 + return recoversInput_; 1.2782 + } 1.2783 + void setRecoversInput() { 1.2784 + recoversInput_ = true; 1.2785 + } 1.2786 +}; 1.2787 + 1.2788 +// Performs an add, sub, mul, or div on two double values. 1.2789 +class LMathD : public LBinaryMath<0> 1.2790 +{ 1.2791 + JSOp jsop_; 1.2792 + 1.2793 + public: 1.2794 + LIR_HEADER(MathD) 1.2795 + 1.2796 + LMathD(JSOp jsop) 1.2797 + : jsop_(jsop) 1.2798 + { } 1.2799 + 1.2800 + JSOp jsop() const { 1.2801 + return jsop_; 1.2802 + } 1.2803 + 1.2804 + const char *extraName() const { 1.2805 + return js_CodeName[jsop_]; 1.2806 + } 1.2807 +}; 1.2808 + 1.2809 +// Performs an add, sub, mul, or div on two double values. 1.2810 +class LMathF: public LBinaryMath<0> 1.2811 +{ 1.2812 + JSOp jsop_; 1.2813 + 1.2814 + public: 1.2815 + LIR_HEADER(MathF) 1.2816 + 1.2817 + LMathF(JSOp jsop) 1.2818 + : jsop_(jsop) 1.2819 + { } 1.2820 + 1.2821 + JSOp jsop() const { 1.2822 + return jsop_; 1.2823 + } 1.2824 + 1.2825 + const char *extraName() const { 1.2826 + return js_CodeName[jsop_]; 1.2827 + } 1.2828 +}; 1.2829 + 1.2830 +class LModD : public LBinaryMath<1> 1.2831 +{ 1.2832 + public: 1.2833 + LIR_HEADER(ModD) 1.2834 + 1.2835 + LModD(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp) { 1.2836 + setOperand(0, lhs); 1.2837 + setOperand(1, rhs); 1.2838 + setTemp(0, temp); 1.2839 + } 1.2840 + const LDefinition *temp() { 1.2841 + return getTemp(0); 1.2842 + } 1.2843 + bool isCall() const { 1.2844 + return true; 1.2845 + } 1.2846 +}; 1.2847 + 1.2848 +// Call a VM function to perform a binary operation. 1.2849 +class LBinaryV : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0> 1.2850 +{ 1.2851 + JSOp jsop_; 1.2852 + 1.2853 + public: 1.2854 + LIR_HEADER(BinaryV) 1.2855 + 1.2856 + LBinaryV(JSOp jsop) 1.2857 + : jsop_(jsop) 1.2858 + { } 1.2859 + 1.2860 + JSOp jsop() const { 1.2861 + return jsop_; 1.2862 + } 1.2863 + 1.2864 + const char *extraName() const { 1.2865 + return js_CodeName[jsop_]; 1.2866 + } 1.2867 + 1.2868 + static const size_t LhsInput = 0; 1.2869 + static const size_t RhsInput = BOX_PIECES; 1.2870 +}; 1.2871 + 1.2872 +// Adds two string, returning a string. 1.2873 +class LConcat : public LInstructionHelper<1, 2, 5> 1.2874 +{ 1.2875 + public: 1.2876 + LIR_HEADER(Concat) 1.2877 + 1.2878 + LConcat(const LAllocation &lhs, const LAllocation &rhs, const LDefinition &temp1, 1.2879 + const LDefinition &temp2, const LDefinition &temp3, const LDefinition &temp4, 1.2880 + const LDefinition &temp5) 1.2881 + { 1.2882 + setOperand(0, lhs); 1.2883 + setOperand(1, rhs); 1.2884 + setTemp(0, temp1); 1.2885 + setTemp(1, temp2); 1.2886 + setTemp(2, temp3); 1.2887 + setTemp(3, temp4); 1.2888 + setTemp(4, temp5); 1.2889 + } 1.2890 + 1.2891 + const LAllocation *lhs() { 1.2892 + return this->getOperand(0); 1.2893 + } 1.2894 + const LAllocation *rhs() { 1.2895 + return this->getOperand(1); 1.2896 + } 1.2897 + const LDefinition *temp1() { 1.2898 + return this->getTemp(0); 1.2899 + } 1.2900 + const LDefinition *temp2() { 1.2901 + return this->getTemp(1); 1.2902 + } 1.2903 + const LDefinition *temp3() { 1.2904 + return this->getTemp(2); 1.2905 + } 1.2906 + const LDefinition *temp4() { 1.2907 + return this->getTemp(3); 1.2908 + } 1.2909 + const LDefinition *temp5() { 1.2910 + return this->getTemp(4); 1.2911 + } 1.2912 +}; 1.2913 + 1.2914 +class LConcatPar : public LInstructionHelper<1, 3, 4> 1.2915 +{ 1.2916 + public: 1.2917 + LIR_HEADER(ConcatPar) 1.2918 + 1.2919 + LConcatPar(const LAllocation &cx, const LAllocation &lhs, const LAllocation &rhs, 1.2920 + const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3, 1.2921 + const LDefinition &temp4) 1.2922 + { 1.2923 + setOperand(0, cx); 1.2924 + setOperand(1, lhs); 1.2925 + setOperand(2, rhs); 1.2926 + setTemp(0, temp1); 1.2927 + setTemp(1, temp2); 1.2928 + setTemp(2, temp3); 1.2929 + setTemp(3, temp4); 1.2930 + } 1.2931 + 1.2932 + const LAllocation *forkJoinContext() { 1.2933 + return this->getOperand(0); 1.2934 + } 1.2935 + const LAllocation *lhs() { 1.2936 + return this->getOperand(1); 1.2937 + } 1.2938 + const LAllocation *rhs() { 1.2939 + return this->getOperand(2); 1.2940 + } 1.2941 + const LDefinition *temp1() { 1.2942 + return this->getTemp(0); 1.2943 + } 1.2944 + const LDefinition *temp2() { 1.2945 + return this->getTemp(1); 1.2946 + } 1.2947 + const LDefinition *temp3() { 1.2948 + return this->getTemp(2); 1.2949 + } 1.2950 + const LDefinition *temp4() { 1.2951 + return this->getTemp(3); 1.2952 + } 1.2953 +}; 1.2954 + 1.2955 +// Get uint16 character code from a string. 1.2956 +class LCharCodeAt : public LInstructionHelper<1, 2, 0> 1.2957 +{ 1.2958 + public: 1.2959 + LIR_HEADER(CharCodeAt) 1.2960 + 1.2961 + LCharCodeAt(const LAllocation &str, const LAllocation &index) { 1.2962 + setOperand(0, str); 1.2963 + setOperand(1, index); 1.2964 + } 1.2965 + 1.2966 + const LAllocation *str() { 1.2967 + return this->getOperand(0); 1.2968 + } 1.2969 + const LAllocation *index() { 1.2970 + return this->getOperand(1); 1.2971 + } 1.2972 +}; 1.2973 + 1.2974 +// Convert uint16 character code to a string. 1.2975 +class LFromCharCode : public LInstructionHelper<1, 1, 0> 1.2976 +{ 1.2977 + public: 1.2978 + LIR_HEADER(FromCharCode) 1.2979 + 1.2980 + LFromCharCode(const LAllocation &code) { 1.2981 + setOperand(0, code); 1.2982 + } 1.2983 + 1.2984 + const LAllocation *code() { 1.2985 + return this->getOperand(0); 1.2986 + } 1.2987 +}; 1.2988 + 1.2989 +class LStringSplit : public LCallInstructionHelper<1, 2, 0> 1.2990 +{ 1.2991 + public: 1.2992 + LIR_HEADER(StringSplit) 1.2993 + 1.2994 + LStringSplit(const LAllocation &string, const LAllocation &separator) { 1.2995 + setOperand(0, string); 1.2996 + setOperand(1, separator); 1.2997 + } 1.2998 + const LAllocation *string() { 1.2999 + return getOperand(0); 1.3000 + } 1.3001 + const LAllocation *separator() { 1.3002 + return getOperand(1); 1.3003 + } 1.3004 + const MStringSplit *mir() const { 1.3005 + return mir_->toStringSplit(); 1.3006 + } 1.3007 +}; 1.3008 + 1.3009 +// Convert a 32-bit integer to a double. 1.3010 +class LInt32ToDouble : public LInstructionHelper<1, 1, 0> 1.3011 +{ 1.3012 + public: 1.3013 + LIR_HEADER(Int32ToDouble) 1.3014 + 1.3015 + LInt32ToDouble(const LAllocation &input) { 1.3016 + setOperand(0, input); 1.3017 + } 1.3018 +}; 1.3019 + 1.3020 +// Convert a 32-bit float to a double. 1.3021 +class LFloat32ToDouble : public LInstructionHelper<1, 1, 0> 1.3022 +{ 1.3023 + public: 1.3024 + LIR_HEADER(Float32ToDouble) 1.3025 + 1.3026 + LFloat32ToDouble(const LAllocation &input) { 1.3027 + setOperand(0, input); 1.3028 + } 1.3029 +}; 1.3030 + 1.3031 +// Convert a double to a 32-bit float. 1.3032 +class LDoubleToFloat32 : public LInstructionHelper<1, 1, 0> 1.3033 +{ 1.3034 + public: 1.3035 + LIR_HEADER(DoubleToFloat32) 1.3036 + 1.3037 + LDoubleToFloat32(const LAllocation &input) { 1.3038 + setOperand(0, input); 1.3039 + } 1.3040 +}; 1.3041 + 1.3042 +// Convert a 32-bit integer to a float32. 1.3043 +class LInt32ToFloat32 : public LInstructionHelper<1, 1, 0> 1.3044 +{ 1.3045 + public: 1.3046 + LIR_HEADER(Int32ToFloat32) 1.3047 + 1.3048 + LInt32ToFloat32(const LAllocation &input) { 1.3049 + setOperand(0, input); 1.3050 + } 1.3051 +}; 1.3052 + 1.3053 +// Convert a value to a double. 1.3054 +class LValueToDouble : public LInstructionHelper<1, BOX_PIECES, 0> 1.3055 +{ 1.3056 + public: 1.3057 + LIR_HEADER(ValueToDouble) 1.3058 + static const size_t Input = 0; 1.3059 + 1.3060 + MToDouble *mir() { 1.3061 + return mir_->toToDouble(); 1.3062 + } 1.3063 +}; 1.3064 + 1.3065 +// Convert a value to a float32. 1.3066 +class LValueToFloat32 : public LInstructionHelper<1, BOX_PIECES, 0> 1.3067 +{ 1.3068 + public: 1.3069 + LIR_HEADER(ValueToFloat32) 1.3070 + static const size_t Input = 0; 1.3071 + 1.3072 + MToFloat32 *mir() { 1.3073 + return mir_->toToFloat32(); 1.3074 + } 1.3075 +}; 1.3076 + 1.3077 +// Convert a value to an int32. 1.3078 +// Input: components of a Value 1.3079 +// Output: 32-bit integer 1.3080 +// Bailout: undefined, string, object, or non-int32 double 1.3081 +// Temps: one float register, one GP register 1.3082 +// 1.3083 +// This instruction requires a temporary float register. 1.3084 +class LValueToInt32 : public LInstructionHelper<1, BOX_PIECES, 2> 1.3085 +{ 1.3086 + public: 1.3087 + enum Mode { 1.3088 + NORMAL, 1.3089 + TRUNCATE 1.3090 + }; 1.3091 + 1.3092 + private: 1.3093 + Mode mode_; 1.3094 + 1.3095 + public: 1.3096 + LIR_HEADER(ValueToInt32) 1.3097 + 1.3098 + LValueToInt32(const LDefinition &temp0, const LDefinition &temp1, Mode mode) 1.3099 + : mode_(mode) 1.3100 + { 1.3101 + setTemp(0, temp0); 1.3102 + setTemp(1, temp1); 1.3103 + } 1.3104 + 1.3105 + const char *extraName() const { 1.3106 + return mode() == NORMAL ? "Normal" : "Truncate"; 1.3107 + } 1.3108 + 1.3109 + static const size_t Input = 0; 1.3110 + 1.3111 + Mode mode() const { 1.3112 + return mode_; 1.3113 + } 1.3114 + const LDefinition *tempFloat() { 1.3115 + return getTemp(0); 1.3116 + } 1.3117 + const LDefinition *temp() { 1.3118 + return getTemp(1); 1.3119 + } 1.3120 + MToInt32 *mirNormal() const { 1.3121 + JS_ASSERT(mode_ == NORMAL); 1.3122 + return mir_->toToInt32(); 1.3123 + } 1.3124 + MTruncateToInt32 *mirTruncate() const { 1.3125 + JS_ASSERT(mode_ == TRUNCATE); 1.3126 + return mir_->toTruncateToInt32(); 1.3127 + } 1.3128 +}; 1.3129 + 1.3130 +// Convert a double to an int32. 1.3131 +// Input: floating-point register 1.3132 +// Output: 32-bit integer 1.3133 +// Bailout: if the double cannot be converted to an integer. 1.3134 +class LDoubleToInt32 : public LInstructionHelper<1, 1, 0> 1.3135 +{ 1.3136 + public: 1.3137 + LIR_HEADER(DoubleToInt32) 1.3138 + 1.3139 + LDoubleToInt32(const LAllocation &in) { 1.3140 + setOperand(0, in); 1.3141 + } 1.3142 + 1.3143 + MToInt32 *mir() const { 1.3144 + return mir_->toToInt32(); 1.3145 + } 1.3146 +}; 1.3147 + 1.3148 +// Convert a float32 to an int32. 1.3149 +// Input: floating-point register 1.3150 +// Output: 32-bit integer 1.3151 +// Bailout: if the float32 cannot be converted to an integer. 1.3152 +class LFloat32ToInt32 : public LInstructionHelper<1, 1, 0> 1.3153 +{ 1.3154 + public: 1.3155 + LIR_HEADER(Float32ToInt32) 1.3156 + 1.3157 + LFloat32ToInt32(const LAllocation &in) { 1.3158 + setOperand(0, in); 1.3159 + } 1.3160 + 1.3161 + MToInt32 *mir() const { 1.3162 + return mir_->toToInt32(); 1.3163 + } 1.3164 +}; 1.3165 + 1.3166 +// Convert a double to a truncated int32. 1.3167 +// Input: floating-point register 1.3168 +// Output: 32-bit integer 1.3169 +class LTruncateDToInt32 : public LInstructionHelper<1, 1, 1> 1.3170 +{ 1.3171 + public: 1.3172 + LIR_HEADER(TruncateDToInt32) 1.3173 + 1.3174 + LTruncateDToInt32(const LAllocation &in, const LDefinition &temp) { 1.3175 + setOperand(0, in); 1.3176 + setTemp(0, temp); 1.3177 + } 1.3178 + 1.3179 + const LDefinition *tempFloat() { 1.3180 + return getTemp(0); 1.3181 + } 1.3182 +}; 1.3183 + 1.3184 +// Convert a float32 to a truncated int32. 1.3185 +// Input: floating-point register 1.3186 +// Output: 32-bit integer 1.3187 +class LTruncateFToInt32 : public LInstructionHelper<1, 1, 1> 1.3188 +{ 1.3189 + public: 1.3190 + LIR_HEADER(TruncateFToInt32) 1.3191 + 1.3192 + LTruncateFToInt32(const LAllocation &in, const LDefinition &temp) { 1.3193 + setOperand(0, in); 1.3194 + setTemp(0, temp); 1.3195 + } 1.3196 + 1.3197 + const LDefinition *tempFloat() { 1.3198 + return getTemp(0); 1.3199 + } 1.3200 +}; 1.3201 + 1.3202 +// Convert a boolean value to a string. 1.3203 +class LBooleanToString : public LInstructionHelper<1, 1, 0> 1.3204 +{ 1.3205 + public: 1.3206 + LIR_HEADER(BooleanToString) 1.3207 + 1.3208 + LBooleanToString(const LAllocation &input) { 1.3209 + setOperand(0, input); 1.3210 + } 1.3211 + 1.3212 + const MToString *mir() { 1.3213 + return mir_->toToString(); 1.3214 + } 1.3215 +}; 1.3216 + 1.3217 +// Convert an integer hosted on one definition to a string with a function call. 1.3218 +class LIntToString : public LInstructionHelper<1, 1, 0> 1.3219 +{ 1.3220 + public: 1.3221 + LIR_HEADER(IntToString) 1.3222 + 1.3223 + LIntToString(const LAllocation &input) { 1.3224 + setOperand(0, input); 1.3225 + } 1.3226 + 1.3227 + const MToString *mir() { 1.3228 + return mir_->toToString(); 1.3229 + } 1.3230 +}; 1.3231 + 1.3232 +// Convert a double hosted on one definition to a string with a function call. 1.3233 +class LDoubleToString : public LInstructionHelper<1, 1, 1> 1.3234 +{ 1.3235 + public: 1.3236 + LIR_HEADER(DoubleToString) 1.3237 + 1.3238 + LDoubleToString(const LAllocation &input, const LDefinition &temp) { 1.3239 + setOperand(0, input); 1.3240 + setTemp(0, temp); 1.3241 + } 1.3242 + 1.3243 + const LDefinition *tempInt() { 1.3244 + return getTemp(0); 1.3245 + } 1.3246 + const MToString *mir() { 1.3247 + return mir_->toToString(); 1.3248 + } 1.3249 +}; 1.3250 + 1.3251 +// Convert a primitive to a string with a function call. 1.3252 +class LPrimitiveToString : public LInstructionHelper<1, BOX_PIECES, 1> 1.3253 +{ 1.3254 + public: 1.3255 + LIR_HEADER(PrimitiveToString) 1.3256 + 1.3257 + LPrimitiveToString(const LDefinition &tempToUnbox) 1.3258 + { 1.3259 + setTemp(0, tempToUnbox); 1.3260 + } 1.3261 + 1.3262 + static const size_t Input = 0; 1.3263 + 1.3264 + const MToString *mir() { 1.3265 + return mir_->toToString(); 1.3266 + } 1.3267 + 1.3268 + const LDefinition *tempToUnbox() { 1.3269 + return getTemp(0); 1.3270 + } 1.3271 +}; 1.3272 + 1.3273 +// No-op instruction that is used to hold the entry snapshot. This simplifies 1.3274 +// register allocation as it doesn't need to sniff the snapshot out of the 1.3275 +// LIRGraph. 1.3276 +class LStart : public LInstructionHelper<0, 0, 0> 1.3277 +{ 1.3278 + public: 1.3279 + LIR_HEADER(Start) 1.3280 +}; 1.3281 + 1.3282 +// Passed the BaselineFrame address in the OsrFrameReg by SideCannon(). 1.3283 +// Forwards this object to the LOsrValues for Value materialization. 1.3284 +class LOsrEntry : public LInstructionHelper<1, 0, 0> 1.3285 +{ 1.3286 + protected: 1.3287 + Label label_; 1.3288 + uint32_t frameDepth_; 1.3289 + 1.3290 + public: 1.3291 + LIR_HEADER(OsrEntry) 1.3292 + 1.3293 + LOsrEntry() 1.3294 + : frameDepth_(0) 1.3295 + { } 1.3296 + 1.3297 + void setFrameDepth(uint32_t depth) { 1.3298 + frameDepth_ = depth; 1.3299 + } 1.3300 + uint32_t getFrameDepth() { 1.3301 + return frameDepth_; 1.3302 + } 1.3303 + Label *label() { 1.3304 + return &label_; 1.3305 + } 1.3306 + 1.3307 +}; 1.3308 + 1.3309 +// Materialize a Value stored in an interpreter frame for OSR. 1.3310 +class LOsrValue : public LInstructionHelper<BOX_PIECES, 1, 0> 1.3311 +{ 1.3312 + public: 1.3313 + LIR_HEADER(OsrValue) 1.3314 + 1.3315 + LOsrValue(const LAllocation &entry) 1.3316 + { 1.3317 + setOperand(0, entry); 1.3318 + } 1.3319 + 1.3320 + const MOsrValue *mir() { 1.3321 + return mir_->toOsrValue(); 1.3322 + } 1.3323 +}; 1.3324 + 1.3325 +// Materialize a JSObject scope chain stored in an interpreter frame for OSR. 1.3326 +class LOsrScopeChain : public LInstructionHelper<1, 1, 0> 1.3327 +{ 1.3328 + public: 1.3329 + LIR_HEADER(OsrScopeChain) 1.3330 + 1.3331 + LOsrScopeChain(const LAllocation &entry) 1.3332 + { 1.3333 + setOperand(0, entry); 1.3334 + } 1.3335 + 1.3336 + const MOsrScopeChain *mir() { 1.3337 + return mir_->toOsrScopeChain(); 1.3338 + } 1.3339 +}; 1.3340 + 1.3341 +// Materialize a JSObject scope chain stored in an interpreter frame for OSR. 1.3342 +class LOsrReturnValue : public LInstructionHelper<BOX_PIECES, 1, 0> 1.3343 +{ 1.3344 + public: 1.3345 + LIR_HEADER(OsrReturnValue) 1.3346 + 1.3347 + LOsrReturnValue(const LAllocation &entry) 1.3348 + { 1.3349 + setOperand(0, entry); 1.3350 + } 1.3351 + 1.3352 + const MOsrReturnValue *mir() { 1.3353 + return mir_->toOsrReturnValue(); 1.3354 + } 1.3355 +}; 1.3356 + 1.3357 +// Materialize a JSObject ArgumentsObject stored in an interpreter frame for OSR. 1.3358 +class LOsrArgumentsObject : public LInstructionHelper<1, 1, 0> 1.3359 +{ 1.3360 + public: 1.3361 + LIR_HEADER(OsrArgumentsObject) 1.3362 + 1.3363 + LOsrArgumentsObject(const LAllocation &entry) 1.3364 + { 1.3365 + setOperand(0, entry); 1.3366 + } 1.3367 + 1.3368 + const MOsrArgumentsObject *mir() { 1.3369 + return mir_->toOsrArgumentsObject(); 1.3370 + } 1.3371 +}; 1.3372 + 1.3373 +class LRegExp : public LCallInstructionHelper<1, 0, 0> 1.3374 +{ 1.3375 + public: 1.3376 + LIR_HEADER(RegExp) 1.3377 + 1.3378 + const MRegExp *mir() const { 1.3379 + return mir_->toRegExp(); 1.3380 + } 1.3381 +}; 1.3382 + 1.3383 +class LRegExpExec : public LCallInstructionHelper<BOX_PIECES, 2, 0> 1.3384 +{ 1.3385 + public: 1.3386 + LIR_HEADER(RegExpExec) 1.3387 + 1.3388 + LRegExpExec(const LAllocation ®exp, const LAllocation &string) 1.3389 + { 1.3390 + setOperand(0, regexp); 1.3391 + setOperand(1, string); 1.3392 + } 1.3393 + 1.3394 + const LAllocation *regexp() { 1.3395 + return getOperand(0); 1.3396 + } 1.3397 + const LAllocation *string() { 1.3398 + return getOperand(1); 1.3399 + } 1.3400 + 1.3401 + const MRegExpExec *mir() const { 1.3402 + return mir_->toRegExpExec(); 1.3403 + } 1.3404 +}; 1.3405 + 1.3406 +class LRegExpTest : public LCallInstructionHelper<1, 2, 0> 1.3407 +{ 1.3408 + public: 1.3409 + LIR_HEADER(RegExpTest) 1.3410 + 1.3411 + LRegExpTest(const LAllocation ®exp, const LAllocation &string) 1.3412 + { 1.3413 + setOperand(0, regexp); 1.3414 + setOperand(1, string); 1.3415 + } 1.3416 + 1.3417 + const LAllocation *regexp() { 1.3418 + return getOperand(0); 1.3419 + } 1.3420 + const LAllocation *string() { 1.3421 + return getOperand(1); 1.3422 + } 1.3423 + 1.3424 + const MRegExpTest *mir() const { 1.3425 + return mir_->toRegExpTest(); 1.3426 + } 1.3427 +}; 1.3428 + 1.3429 + 1.3430 +class LStrReplace : public LCallInstructionHelper<1, 3, 0> 1.3431 +{ 1.3432 + public: 1.3433 + LStrReplace(const LAllocation &string, const LAllocation &pattern, 1.3434 + const LAllocation &replacement) 1.3435 + { 1.3436 + setOperand(0, string); 1.3437 + setOperand(1, pattern); 1.3438 + setOperand(2, replacement); 1.3439 + } 1.3440 + 1.3441 + const LAllocation *string() { 1.3442 + return getOperand(0); 1.3443 + } 1.3444 + const LAllocation *pattern() { 1.3445 + return getOperand(1); 1.3446 + } 1.3447 + const LAllocation *replacement() { 1.3448 + return getOperand(2); 1.3449 + } 1.3450 +}; 1.3451 + 1.3452 +class LRegExpReplace: public LStrReplace 1.3453 +{ 1.3454 + public: 1.3455 + LIR_HEADER(RegExpReplace); 1.3456 + 1.3457 + LRegExpReplace(const LAllocation &string, const LAllocation &pattern, 1.3458 + const LAllocation &replacement) 1.3459 + : LStrReplace(string, pattern, replacement) 1.3460 + { 1.3461 + } 1.3462 + 1.3463 + const MRegExpReplace *mir() const { 1.3464 + return mir_->toRegExpReplace(); 1.3465 + } 1.3466 +}; 1.3467 + 1.3468 +class LStringReplace: public LStrReplace 1.3469 +{ 1.3470 + public: 1.3471 + LIR_HEADER(StringReplace); 1.3472 + 1.3473 + LStringReplace(const LAllocation &string, const LAllocation &pattern, 1.3474 + const LAllocation &replacement) 1.3475 + : LStrReplace(string, pattern, replacement) 1.3476 + { 1.3477 + } 1.3478 + 1.3479 + const MStringReplace *mir() const { 1.3480 + return mir_->toStringReplace(); 1.3481 + } 1.3482 +}; 1.3483 + 1.3484 +class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0> 1.3485 +{ 1.3486 + public: 1.3487 + LIR_HEADER(LambdaForSingleton) 1.3488 + 1.3489 + LLambdaForSingleton(const LAllocation &scopeChain) 1.3490 + { 1.3491 + setOperand(0, scopeChain); 1.3492 + } 1.3493 + const LAllocation *scopeChain() { 1.3494 + return getOperand(0); 1.3495 + } 1.3496 + const MLambda *mir() const { 1.3497 + return mir_->toLambda(); 1.3498 + } 1.3499 +}; 1.3500 + 1.3501 +class LLambda : public LInstructionHelper<1, 1, 1> 1.3502 +{ 1.3503 + public: 1.3504 + LIR_HEADER(Lambda) 1.3505 + 1.3506 + LLambda(const LAllocation &scopeChain, const LDefinition &temp) { 1.3507 + setOperand(0, scopeChain); 1.3508 + setTemp(0, temp); 1.3509 + } 1.3510 + const LAllocation *scopeChain() { 1.3511 + return getOperand(0); 1.3512 + } 1.3513 + const LDefinition *temp() { 1.3514 + return getTemp(0); 1.3515 + } 1.3516 + const MLambda *mir() const { 1.3517 + return mir_->toLambda(); 1.3518 + } 1.3519 +}; 1.3520 + 1.3521 +class LLambdaArrow : public LInstructionHelper<1, 1 + BOX_PIECES, 1> 1.3522 +{ 1.3523 + public: 1.3524 + LIR_HEADER(LambdaArrow) 1.3525 + 1.3526 + static const size_t ThisValue = 1; 1.3527 + 1.3528 + LLambdaArrow(const LAllocation &scopeChain, const LDefinition &temp) { 1.3529 + setOperand(0, scopeChain); 1.3530 + setTemp(0, temp); 1.3531 + } 1.3532 + const LAllocation *scopeChain() { 1.3533 + return getOperand(0); 1.3534 + } 1.3535 + const LDefinition *temp() { 1.3536 + return getTemp(0); 1.3537 + } 1.3538 + const MLambdaArrow *mir() const { 1.3539 + return mir_->toLambdaArrow(); 1.3540 + } 1.3541 +}; 1.3542 + 1.3543 +class LLambdaPar : public LInstructionHelper<1, 2, 2> 1.3544 +{ 1.3545 + public: 1.3546 + LIR_HEADER(LambdaPar); 1.3547 + 1.3548 + LLambdaPar(const LAllocation &cx, const LAllocation &scopeChain, 1.3549 + const LDefinition &temp1, const LDefinition &temp2) 1.3550 + { 1.3551 + setOperand(0, cx); 1.3552 + setOperand(1, scopeChain); 1.3553 + setTemp(0, temp1); 1.3554 + setTemp(1, temp2); 1.3555 + } 1.3556 + const LAllocation *forkJoinContext() { 1.3557 + return getOperand(0); 1.3558 + } 1.3559 + const LAllocation *scopeChain() { 1.3560 + return getOperand(1); 1.3561 + } 1.3562 + const MLambdaPar *mir() const { 1.3563 + return mir_->toLambdaPar(); 1.3564 + } 1.3565 + const LDefinition *getTemp0() { 1.3566 + return getTemp(0); 1.3567 + } 1.3568 + const LDefinition *getTemp1() { 1.3569 + return getTemp(1); 1.3570 + } 1.3571 +}; 1.3572 + 1.3573 +// Determines the implicit |this| value for function calls. 1.3574 +class LImplicitThis : public LInstructionHelper<BOX_PIECES, 1, 0> 1.3575 +{ 1.3576 + public: 1.3577 + LIR_HEADER(ImplicitThis) 1.3578 + 1.3579 + LImplicitThis(const LAllocation &callee) { 1.3580 + setOperand(0, callee); 1.3581 + } 1.3582 + 1.3583 + const MImplicitThis *mir() const { 1.3584 + return mir_->toImplicitThis(); 1.3585 + } 1.3586 + const LAllocation *callee() { 1.3587 + return getOperand(0); 1.3588 + } 1.3589 +}; 1.3590 + 1.3591 +// Load the "slots" member out of a JSObject. 1.3592 +// Input: JSObject pointer 1.3593 +// Output: slots pointer 1.3594 +class LSlots : public LInstructionHelper<1, 1, 0> 1.3595 +{ 1.3596 + public: 1.3597 + LIR_HEADER(Slots) 1.3598 + 1.3599 + LSlots(const LAllocation &object) { 1.3600 + setOperand(0, object); 1.3601 + } 1.3602 + 1.3603 + const LAllocation *object() { 1.3604 + return getOperand(0); 1.3605 + } 1.3606 +}; 1.3607 + 1.3608 +// Load the "elements" member out of a JSObject. 1.3609 +// Input: JSObject pointer 1.3610 +// Output: elements pointer 1.3611 +class LElements : public LInstructionHelper<1, 1, 0> 1.3612 +{ 1.3613 + public: 1.3614 + LIR_HEADER(Elements) 1.3615 + 1.3616 + LElements(const LAllocation &object) { 1.3617 + setOperand(0, object); 1.3618 + } 1.3619 + 1.3620 + const LAllocation *object() { 1.3621 + return getOperand(0); 1.3622 + } 1.3623 +}; 1.3624 + 1.3625 +// If necessary, convert any int32 elements in a vector into doubles. 1.3626 +class LConvertElementsToDoubles : public LInstructionHelper<0, 1, 0> 1.3627 +{ 1.3628 + public: 1.3629 + LIR_HEADER(ConvertElementsToDoubles) 1.3630 + 1.3631 + LConvertElementsToDoubles(const LAllocation &elements) { 1.3632 + setOperand(0, elements); 1.3633 + } 1.3634 + 1.3635 + const LAllocation *elements() { 1.3636 + return getOperand(0); 1.3637 + } 1.3638 +}; 1.3639 + 1.3640 +// If |elements| has the CONVERT_DOUBLE_ELEMENTS flag, convert int32 value to 1.3641 +// double. Else return the original value. 1.3642 +class LMaybeToDoubleElement : public LInstructionHelper<BOX_PIECES, 2, 1> 1.3643 +{ 1.3644 + public: 1.3645 + LIR_HEADER(MaybeToDoubleElement) 1.3646 + 1.3647 + LMaybeToDoubleElement(const LAllocation &elements, const LAllocation &value, 1.3648 + const LDefinition &tempFloat) { 1.3649 + setOperand(0, elements); 1.3650 + setOperand(1, value); 1.3651 + setTemp(0, tempFloat); 1.3652 + } 1.3653 + 1.3654 + const LAllocation *elements() { 1.3655 + return getOperand(0); 1.3656 + } 1.3657 + const LAllocation *value() { 1.3658 + return getOperand(1); 1.3659 + } 1.3660 + const LDefinition *tempFloat() { 1.3661 + return getTemp(0); 1.3662 + } 1.3663 +}; 1.3664 + 1.3665 +// Load the initialized length from an elements header. 1.3666 +class LInitializedLength : public LInstructionHelper<1, 1, 0> 1.3667 +{ 1.3668 + public: 1.3669 + LIR_HEADER(InitializedLength) 1.3670 + 1.3671 + LInitializedLength(const LAllocation &elements) { 1.3672 + setOperand(0, elements); 1.3673 + } 1.3674 + 1.3675 + const LAllocation *elements() { 1.3676 + return getOperand(0); 1.3677 + } 1.3678 +}; 1.3679 + 1.3680 +// Store to the initialized length in an elements header. Note the input is an 1.3681 +// *index*, one less than the desired initialized length. 1.3682 +class LSetInitializedLength : public LInstructionHelper<0, 2, 0> 1.3683 +{ 1.3684 + public: 1.3685 + LIR_HEADER(SetInitializedLength) 1.3686 + 1.3687 + LSetInitializedLength(const LAllocation &elements, const LAllocation &index) { 1.3688 + setOperand(0, elements); 1.3689 + setOperand(1, index); 1.3690 + } 1.3691 + 1.3692 + const LAllocation *elements() { 1.3693 + return getOperand(0); 1.3694 + } 1.3695 + const LAllocation *index() { 1.3696 + return getOperand(1); 1.3697 + } 1.3698 +}; 1.3699 + 1.3700 +// Load the length from an elements header. 1.3701 +class LArrayLength : public LInstructionHelper<1, 1, 0> 1.3702 +{ 1.3703 + public: 1.3704 + LIR_HEADER(ArrayLength) 1.3705 + 1.3706 + LArrayLength(const LAllocation &elements) { 1.3707 + setOperand(0, elements); 1.3708 + } 1.3709 + 1.3710 + const LAllocation *elements() { 1.3711 + return getOperand(0); 1.3712 + } 1.3713 +}; 1.3714 + 1.3715 +// Store to the length in an elements header. Note the input is an *index*, 1.3716 +// one less than the desired length. 1.3717 +class LSetArrayLength : public LInstructionHelper<0, 2, 0> 1.3718 +{ 1.3719 + public: 1.3720 + LIR_HEADER(SetArrayLength) 1.3721 + 1.3722 + LSetArrayLength(const LAllocation &elements, const LAllocation &index) { 1.3723 + setOperand(0, elements); 1.3724 + setOperand(1, index); 1.3725 + } 1.3726 + 1.3727 + const LAllocation *elements() { 1.3728 + return getOperand(0); 1.3729 + } 1.3730 + const LAllocation *index() { 1.3731 + return getOperand(1); 1.3732 + } 1.3733 +}; 1.3734 + 1.3735 +// Read the length of a typed array. 1.3736 +class LTypedArrayLength : public LInstructionHelper<1, 1, 0> 1.3737 +{ 1.3738 + public: 1.3739 + LIR_HEADER(TypedArrayLength) 1.3740 + 1.3741 + LTypedArrayLength(const LAllocation &obj) { 1.3742 + setOperand(0, obj); 1.3743 + } 1.3744 + 1.3745 + const LAllocation *object() { 1.3746 + return getOperand(0); 1.3747 + } 1.3748 +}; 1.3749 + 1.3750 +// Load a typed array's elements vector. 1.3751 +class LTypedArrayElements : public LInstructionHelper<1, 1, 0> 1.3752 +{ 1.3753 + public: 1.3754 + LIR_HEADER(TypedArrayElements) 1.3755 + 1.3756 + LTypedArrayElements(const LAllocation &object) { 1.3757 + setOperand(0, object); 1.3758 + } 1.3759 + const LAllocation *object() { 1.3760 + return getOperand(0); 1.3761 + } 1.3762 +}; 1.3763 + 1.3764 +// Load a typed array's elements vector. 1.3765 +class LTypedObjectElements : public LInstructionHelper<1, 1, 0> 1.3766 +{ 1.3767 + public: 1.3768 + LIR_HEADER(TypedObjectElements) 1.3769 + 1.3770 + LTypedObjectElements(const LAllocation &object) { 1.3771 + setOperand(0, object); 1.3772 + } 1.3773 + const LAllocation *object() { 1.3774 + return getOperand(0); 1.3775 + } 1.3776 + const MTypedObjectElements *mir() const { 1.3777 + return mir_->toTypedObjectElements(); 1.3778 + } 1.3779 +}; 1.3780 + 1.3781 +// Load a typed array's elements vector. 1.3782 +class LSetTypedObjectOffset : public LInstructionHelper<0, 2, 1> 1.3783 +{ 1.3784 + public: 1.3785 + LIR_HEADER(SetTypedObjectOffset) 1.3786 + 1.3787 + LSetTypedObjectOffset(const LAllocation &object, 1.3788 + const LAllocation &offset, 1.3789 + const LDefinition &temp0) 1.3790 + { 1.3791 + setOperand(0, object); 1.3792 + setOperand(1, offset); 1.3793 + setTemp(0, temp0); 1.3794 + } 1.3795 + const LAllocation *object() { 1.3796 + return getOperand(0); 1.3797 + } 1.3798 + const LAllocation *offset() { 1.3799 + return getOperand(1); 1.3800 + } 1.3801 + const LDefinition *temp0() { 1.3802 + return getTemp(0); 1.3803 + } 1.3804 +}; 1.3805 + 1.3806 +// Check whether a typed object has a neutered owner buffer. 1.3807 +class LNeuterCheck : public LInstructionHelper<0, 1, 1> 1.3808 +{ 1.3809 + public: 1.3810 + LIR_HEADER(NeuterCheck) 1.3811 + 1.3812 + LNeuterCheck(const LAllocation &object, const LDefinition &temp) { 1.3813 + setOperand(0, object); 1.3814 + setTemp(0, temp); 1.3815 + } 1.3816 + const LAllocation *object() { 1.3817 + return getOperand(0); 1.3818 + } 1.3819 + const LDefinition *temp() { 1.3820 + return getTemp(0); 1.3821 + } 1.3822 +}; 1.3823 + 1.3824 +// Bailout if index >= length. 1.3825 +class LBoundsCheck : public LInstructionHelper<0, 2, 0> 1.3826 +{ 1.3827 + public: 1.3828 + LIR_HEADER(BoundsCheck) 1.3829 + 1.3830 + LBoundsCheck(const LAllocation &index, const LAllocation &length) { 1.3831 + setOperand(0, index); 1.3832 + setOperand(1, length); 1.3833 + } 1.3834 + const MBoundsCheck *mir() const { 1.3835 + return mir_->toBoundsCheck(); 1.3836 + } 1.3837 + const LAllocation *index() { 1.3838 + return getOperand(0); 1.3839 + } 1.3840 + const LAllocation *length() { 1.3841 + return getOperand(1); 1.3842 + } 1.3843 +}; 1.3844 + 1.3845 +// Bailout if index + minimum < 0 or index + maximum >= length. 1.3846 +class LBoundsCheckRange : public LInstructionHelper<0, 2, 1> 1.3847 +{ 1.3848 + public: 1.3849 + LIR_HEADER(BoundsCheckRange) 1.3850 + 1.3851 + LBoundsCheckRange(const LAllocation &index, const LAllocation &length, 1.3852 + const LDefinition &temp) 1.3853 + { 1.3854 + setOperand(0, index); 1.3855 + setOperand(1, length); 1.3856 + setTemp(0, temp); 1.3857 + } 1.3858 + const MBoundsCheck *mir() const { 1.3859 + return mir_->toBoundsCheck(); 1.3860 + } 1.3861 + const LAllocation *index() { 1.3862 + return getOperand(0); 1.3863 + } 1.3864 + const LAllocation *length() { 1.3865 + return getOperand(1); 1.3866 + } 1.3867 +}; 1.3868 + 1.3869 +// Bailout if index < minimum. 1.3870 +class LBoundsCheckLower : public LInstructionHelper<0, 1, 0> 1.3871 +{ 1.3872 + public: 1.3873 + LIR_HEADER(BoundsCheckLower) 1.3874 + 1.3875 + LBoundsCheckLower(const LAllocation &index) 1.3876 + { 1.3877 + setOperand(0, index); 1.3878 + } 1.3879 + MBoundsCheckLower *mir() const { 1.3880 + return mir_->toBoundsCheckLower(); 1.3881 + } 1.3882 + const LAllocation *index() { 1.3883 + return getOperand(0); 1.3884 + } 1.3885 +}; 1.3886 + 1.3887 +// Load a value from a dense array's elements vector. Bail out if it's the hole value. 1.3888 +class LLoadElementV : public LInstructionHelper<BOX_PIECES, 2, 0> 1.3889 +{ 1.3890 + public: 1.3891 + LIR_HEADER(LoadElementV) 1.3892 + 1.3893 + LLoadElementV(const LAllocation &elements, const LAllocation &index) { 1.3894 + setOperand(0, elements); 1.3895 + setOperand(1, index); 1.3896 + } 1.3897 + 1.3898 + const char *extraName() const { 1.3899 + return mir()->needsHoleCheck() ? "HoleCheck" : nullptr; 1.3900 + } 1.3901 + 1.3902 + const MLoadElement *mir() const { 1.3903 + return mir_->toLoadElement(); 1.3904 + } 1.3905 + const LAllocation *elements() { 1.3906 + return getOperand(0); 1.3907 + } 1.3908 + const LAllocation *index() { 1.3909 + return getOperand(1); 1.3910 + } 1.3911 +}; 1.3912 + 1.3913 +class LInArray : public LInstructionHelper<1, 4, 0> 1.3914 +{ 1.3915 + public: 1.3916 + LIR_HEADER(InArray) 1.3917 + 1.3918 + LInArray(const LAllocation &elements, const LAllocation &index, 1.3919 + const LAllocation &initLength, const LAllocation &object) 1.3920 + { 1.3921 + setOperand(0, elements); 1.3922 + setOperand(1, index); 1.3923 + setOperand(2, initLength); 1.3924 + setOperand(3, object); 1.3925 + } 1.3926 + const MInArray *mir() const { 1.3927 + return mir_->toInArray(); 1.3928 + } 1.3929 + const LAllocation *elements() { 1.3930 + return getOperand(0); 1.3931 + } 1.3932 + const LAllocation *index() { 1.3933 + return getOperand(1); 1.3934 + } 1.3935 + const LAllocation *initLength() { 1.3936 + return getOperand(2); 1.3937 + } 1.3938 + const LAllocation *object() { 1.3939 + return getOperand(3); 1.3940 + } 1.3941 +}; 1.3942 + 1.3943 + 1.3944 +// Load a value from a dense array's elements vector. Bail out if it's the hole value. 1.3945 +class LLoadElementHole : public LInstructionHelper<BOX_PIECES, 3, 0> 1.3946 +{ 1.3947 + public: 1.3948 + LIR_HEADER(LoadElementHole) 1.3949 + 1.3950 + LLoadElementHole(const LAllocation &elements, const LAllocation &index, const LAllocation &initLength) { 1.3951 + setOperand(0, elements); 1.3952 + setOperand(1, index); 1.3953 + setOperand(2, initLength); 1.3954 + } 1.3955 + 1.3956 + const char *extraName() const { 1.3957 + return mir()->needsHoleCheck() ? "HoleCheck" : nullptr; 1.3958 + } 1.3959 + 1.3960 + const MLoadElementHole *mir() const { 1.3961 + return mir_->toLoadElementHole(); 1.3962 + } 1.3963 + const LAllocation *elements() { 1.3964 + return getOperand(0); 1.3965 + } 1.3966 + const LAllocation *index() { 1.3967 + return getOperand(1); 1.3968 + } 1.3969 + const LAllocation *initLength() { 1.3970 + return getOperand(2); 1.3971 + } 1.3972 +}; 1.3973 + 1.3974 +// Load a typed value from a dense array's elements vector. The array must be 1.3975 +// known to be packed, so that we don't have to check for the hole value. 1.3976 +// This instruction does not load the type tag and can directly load into a 1.3977 +// FP register. 1.3978 +class LLoadElementT : public LInstructionHelper<1, 2, 0> 1.3979 +{ 1.3980 + public: 1.3981 + LIR_HEADER(LoadElementT) 1.3982 + 1.3983 + LLoadElementT(const LAllocation &elements, const LAllocation &index) { 1.3984 + setOperand(0, elements); 1.3985 + setOperand(1, index); 1.3986 + } 1.3987 + 1.3988 + const char *extraName() const { 1.3989 + return mir()->needsHoleCheck() ? "HoleCheck" 1.3990 + : (mir()->loadDoubles() ? "Doubles" : nullptr); 1.3991 + } 1.3992 + 1.3993 + const MLoadElement *mir() const { 1.3994 + return mir_->toLoadElement(); 1.3995 + } 1.3996 + const LAllocation *elements() { 1.3997 + return getOperand(0); 1.3998 + } 1.3999 + const LAllocation *index() { 1.4000 + return getOperand(1); 1.4001 + } 1.4002 +}; 1.4003 + 1.4004 +// Store a boxed value to a dense array's element vector. 1.4005 +class LStoreElementV : public LInstructionHelper<0, 2 + BOX_PIECES, 0> 1.4006 +{ 1.4007 + public: 1.4008 + LIR_HEADER(StoreElementV) 1.4009 + 1.4010 + LStoreElementV(const LAllocation &elements, const LAllocation &index) { 1.4011 + setOperand(0, elements); 1.4012 + setOperand(1, index); 1.4013 + } 1.4014 + 1.4015 + const char *extraName() const { 1.4016 + return mir()->needsHoleCheck() ? "HoleCheck" : nullptr; 1.4017 + } 1.4018 + 1.4019 + static const size_t Value = 2; 1.4020 + 1.4021 + const MStoreElement *mir() const { 1.4022 + return mir_->toStoreElement(); 1.4023 + } 1.4024 + const LAllocation *elements() { 1.4025 + return getOperand(0); 1.4026 + } 1.4027 + const LAllocation *index() { 1.4028 + return getOperand(1); 1.4029 + } 1.4030 +}; 1.4031 + 1.4032 +// Store a typed value to a dense array's elements vector. Compared to 1.4033 +// LStoreElementV, this instruction can store doubles and constants directly, 1.4034 +// and does not store the type tag if the array is monomorphic and known to 1.4035 +// be packed. 1.4036 +class LStoreElementT : public LInstructionHelper<0, 3, 0> 1.4037 +{ 1.4038 + public: 1.4039 + LIR_HEADER(StoreElementT) 1.4040 + 1.4041 + LStoreElementT(const LAllocation &elements, const LAllocation &index, const LAllocation &value) { 1.4042 + setOperand(0, elements); 1.4043 + setOperand(1, index); 1.4044 + setOperand(2, value); 1.4045 + } 1.4046 + 1.4047 + const char *extraName() const { 1.4048 + return mir()->needsHoleCheck() ? "HoleCheck" : nullptr; 1.4049 + } 1.4050 + 1.4051 + const MStoreElement *mir() const { 1.4052 + return mir_->toStoreElement(); 1.4053 + } 1.4054 + const LAllocation *elements() { 1.4055 + return getOperand(0); 1.4056 + } 1.4057 + const LAllocation *index() { 1.4058 + return getOperand(1); 1.4059 + } 1.4060 + const LAllocation *value() { 1.4061 + return getOperand(2); 1.4062 + } 1.4063 +}; 1.4064 + 1.4065 +// Like LStoreElementV, but supports indexes >= initialized length. 1.4066 +class LStoreElementHoleV : public LInstructionHelper<0, 3 + BOX_PIECES, 0> 1.4067 +{ 1.4068 + public: 1.4069 + LIR_HEADER(StoreElementHoleV) 1.4070 + 1.4071 + LStoreElementHoleV(const LAllocation &object, const LAllocation &elements, 1.4072 + const LAllocation &index) { 1.4073 + setOperand(0, object); 1.4074 + setOperand(1, elements); 1.4075 + setOperand(2, index); 1.4076 + } 1.4077 + 1.4078 + static const size_t Value = 3; 1.4079 + 1.4080 + const MStoreElementHole *mir() const { 1.4081 + return mir_->toStoreElementHole(); 1.4082 + } 1.4083 + const LAllocation *object() { 1.4084 + return getOperand(0); 1.4085 + } 1.4086 + const LAllocation *elements() { 1.4087 + return getOperand(1); 1.4088 + } 1.4089 + const LAllocation *index() { 1.4090 + return getOperand(2); 1.4091 + } 1.4092 +}; 1.4093 + 1.4094 +// Like LStoreElementT, but supports indexes >= initialized length. 1.4095 +class LStoreElementHoleT : public LInstructionHelper<0, 4, 0> 1.4096 +{ 1.4097 + public: 1.4098 + LIR_HEADER(StoreElementHoleT) 1.4099 + 1.4100 + LStoreElementHoleT(const LAllocation &object, const LAllocation &elements, 1.4101 + const LAllocation &index, const LAllocation &value) { 1.4102 + setOperand(0, object); 1.4103 + setOperand(1, elements); 1.4104 + setOperand(2, index); 1.4105 + setOperand(3, value); 1.4106 + } 1.4107 + 1.4108 + const MStoreElementHole *mir() const { 1.4109 + return mir_->toStoreElementHole(); 1.4110 + } 1.4111 + const LAllocation *object() { 1.4112 + return getOperand(0); 1.4113 + } 1.4114 + const LAllocation *elements() { 1.4115 + return getOperand(1); 1.4116 + } 1.4117 + const LAllocation *index() { 1.4118 + return getOperand(2); 1.4119 + } 1.4120 + const LAllocation *value() { 1.4121 + return getOperand(3); 1.4122 + } 1.4123 +}; 1.4124 + 1.4125 +class LArrayPopShiftV : public LInstructionHelper<BOX_PIECES, 1, 2> 1.4126 +{ 1.4127 + public: 1.4128 + LIR_HEADER(ArrayPopShiftV) 1.4129 + 1.4130 + LArrayPopShiftV(const LAllocation &object, const LDefinition &temp0, const LDefinition &temp1) { 1.4131 + setOperand(0, object); 1.4132 + setTemp(0, temp0); 1.4133 + setTemp(1, temp1); 1.4134 + } 1.4135 + 1.4136 + const char *extraName() const { 1.4137 + return mir()->mode() == MArrayPopShift::Pop ? "Pop" : "Shift"; 1.4138 + } 1.4139 + 1.4140 + const MArrayPopShift *mir() const { 1.4141 + return mir_->toArrayPopShift(); 1.4142 + } 1.4143 + const LAllocation *object() { 1.4144 + return getOperand(0); 1.4145 + } 1.4146 + const LDefinition *temp0() { 1.4147 + return getTemp(0); 1.4148 + } 1.4149 + const LDefinition *temp1() { 1.4150 + return getTemp(1); 1.4151 + } 1.4152 +}; 1.4153 + 1.4154 +class LArrayPopShiftT : public LInstructionHelper<1, 1, 2> 1.4155 +{ 1.4156 + public: 1.4157 + LIR_HEADER(ArrayPopShiftT) 1.4158 + 1.4159 + LArrayPopShiftT(const LAllocation &object, const LDefinition &temp0, const LDefinition &temp1) { 1.4160 + setOperand(0, object); 1.4161 + setTemp(0, temp0); 1.4162 + setTemp(1, temp1); 1.4163 + } 1.4164 + 1.4165 + const char *extraName() const { 1.4166 + return mir()->mode() == MArrayPopShift::Pop ? "Pop" : "Shift"; 1.4167 + } 1.4168 + 1.4169 + const MArrayPopShift *mir() const { 1.4170 + return mir_->toArrayPopShift(); 1.4171 + } 1.4172 + const LAllocation *object() { 1.4173 + return getOperand(0); 1.4174 + } 1.4175 + const LDefinition *temp0() { 1.4176 + return getTemp(0); 1.4177 + } 1.4178 + const LDefinition *temp1() { 1.4179 + return getTemp(1); 1.4180 + } 1.4181 +}; 1.4182 + 1.4183 +class LArrayPushV : public LInstructionHelper<1, 1 + BOX_PIECES, 1> 1.4184 +{ 1.4185 + public: 1.4186 + LIR_HEADER(ArrayPushV) 1.4187 + 1.4188 + LArrayPushV(const LAllocation &object, const LDefinition &temp) { 1.4189 + setOperand(0, object); 1.4190 + setTemp(0, temp); 1.4191 + } 1.4192 + 1.4193 + static const size_t Value = 1; 1.4194 + 1.4195 + const MArrayPush *mir() const { 1.4196 + return mir_->toArrayPush(); 1.4197 + } 1.4198 + const LAllocation *object() { 1.4199 + return getOperand(0); 1.4200 + } 1.4201 + const LDefinition *temp() { 1.4202 + return getTemp(0); 1.4203 + } 1.4204 +}; 1.4205 + 1.4206 +class LArrayPushT : public LInstructionHelper<1, 2, 1> 1.4207 +{ 1.4208 + public: 1.4209 + LIR_HEADER(ArrayPushT) 1.4210 + 1.4211 + LArrayPushT(const LAllocation &object, const LAllocation &value, const LDefinition &temp) { 1.4212 + setOperand(0, object); 1.4213 + setOperand(1, value); 1.4214 + setTemp(0, temp); 1.4215 + } 1.4216 + 1.4217 + const MArrayPush *mir() const { 1.4218 + return mir_->toArrayPush(); 1.4219 + } 1.4220 + const LAllocation *object() { 1.4221 + return getOperand(0); 1.4222 + } 1.4223 + const LAllocation *value() { 1.4224 + return getOperand(1); 1.4225 + } 1.4226 + const LDefinition *temp() { 1.4227 + return getTemp(0); 1.4228 + } 1.4229 +}; 1.4230 + 1.4231 +class LArrayConcat : public LCallInstructionHelper<1, 2, 2> 1.4232 +{ 1.4233 + public: 1.4234 + LIR_HEADER(ArrayConcat) 1.4235 + 1.4236 + LArrayConcat(const LAllocation &lhs, const LAllocation &rhs, 1.4237 + const LDefinition &temp1, const LDefinition &temp2) { 1.4238 + setOperand(0, lhs); 1.4239 + setOperand(1, rhs); 1.4240 + setTemp(0, temp1); 1.4241 + setTemp(1, temp2); 1.4242 + } 1.4243 + const MArrayConcat *mir() const { 1.4244 + return mir_->toArrayConcat(); 1.4245 + } 1.4246 + const LAllocation *lhs() { 1.4247 + return getOperand(0); 1.4248 + } 1.4249 + const LAllocation *rhs() { 1.4250 + return getOperand(1); 1.4251 + } 1.4252 + const LDefinition *temp1() { 1.4253 + return getTemp(0); 1.4254 + } 1.4255 + const LDefinition *temp2() { 1.4256 + return getTemp(1); 1.4257 + } 1.4258 +}; 1.4259 + 1.4260 +// Load a typed value from a typed array's elements vector. 1.4261 +class LLoadTypedArrayElement : public LInstructionHelper<1, 2, 1> 1.4262 +{ 1.4263 + public: 1.4264 + LIR_HEADER(LoadTypedArrayElement) 1.4265 + 1.4266 + LLoadTypedArrayElement(const LAllocation &elements, const LAllocation &index, 1.4267 + const LDefinition &temp) { 1.4268 + setOperand(0, elements); 1.4269 + setOperand(1, index); 1.4270 + setTemp(0, temp); 1.4271 + } 1.4272 + const MLoadTypedArrayElement *mir() const { 1.4273 + return mir_->toLoadTypedArrayElement(); 1.4274 + } 1.4275 + const LAllocation *elements() { 1.4276 + return getOperand(0); 1.4277 + } 1.4278 + const LAllocation *index() { 1.4279 + return getOperand(1); 1.4280 + } 1.4281 + const LDefinition *temp() { 1.4282 + return getTemp(0); 1.4283 + } 1.4284 +}; 1.4285 + 1.4286 +class LLoadTypedArrayElementHole : public LInstructionHelper<BOX_PIECES, 2, 0> 1.4287 +{ 1.4288 + public: 1.4289 + LIR_HEADER(LoadTypedArrayElementHole) 1.4290 + 1.4291 + LLoadTypedArrayElementHole(const LAllocation &object, const LAllocation &index) { 1.4292 + setOperand(0, object); 1.4293 + setOperand(1, index); 1.4294 + } 1.4295 + const MLoadTypedArrayElementHole *mir() const { 1.4296 + return mir_->toLoadTypedArrayElementHole(); 1.4297 + } 1.4298 + const LAllocation *object() { 1.4299 + return getOperand(0); 1.4300 + } 1.4301 + const LAllocation *index() { 1.4302 + return getOperand(1); 1.4303 + } 1.4304 +}; 1.4305 + 1.4306 +class LLoadTypedArrayElementStatic : public LInstructionHelper<1, 1, 0> 1.4307 +{ 1.4308 + public: 1.4309 + LIR_HEADER(LoadTypedArrayElementStatic); 1.4310 + LLoadTypedArrayElementStatic(const LAllocation &ptr) { 1.4311 + setOperand(0, ptr); 1.4312 + } 1.4313 + MLoadTypedArrayElementStatic *mir() const { 1.4314 + return mir_->toLoadTypedArrayElementStatic(); 1.4315 + } 1.4316 + const LAllocation *ptr() { 1.4317 + return getOperand(0); 1.4318 + } 1.4319 +}; 1.4320 + 1.4321 +class LStoreTypedArrayElement : public LInstructionHelper<0, 3, 0> 1.4322 +{ 1.4323 + public: 1.4324 + LIR_HEADER(StoreTypedArrayElement) 1.4325 + 1.4326 + LStoreTypedArrayElement(const LAllocation &elements, const LAllocation &index, 1.4327 + const LAllocation &value) { 1.4328 + setOperand(0, elements); 1.4329 + setOperand(1, index); 1.4330 + setOperand(2, value); 1.4331 + } 1.4332 + 1.4333 + const MStoreTypedArrayElement *mir() const { 1.4334 + return mir_->toStoreTypedArrayElement(); 1.4335 + } 1.4336 + const LAllocation *elements() { 1.4337 + return getOperand(0); 1.4338 + } 1.4339 + const LAllocation *index() { 1.4340 + return getOperand(1); 1.4341 + } 1.4342 + const LAllocation *value() { 1.4343 + return getOperand(2); 1.4344 + } 1.4345 +}; 1.4346 + 1.4347 +class LStoreTypedArrayElementHole : public LInstructionHelper<0, 4, 0> 1.4348 +{ 1.4349 + public: 1.4350 + LIR_HEADER(StoreTypedArrayElementHole) 1.4351 + 1.4352 + LStoreTypedArrayElementHole(const LAllocation &elements, const LAllocation &length, 1.4353 + const LAllocation &index, const LAllocation &value) 1.4354 + { 1.4355 + setOperand(0, elements); 1.4356 + setOperand(1, length); 1.4357 + setOperand(2, index); 1.4358 + setOperand(3, value); 1.4359 + } 1.4360 + 1.4361 + const MStoreTypedArrayElementHole *mir() const { 1.4362 + return mir_->toStoreTypedArrayElementHole(); 1.4363 + } 1.4364 + const LAllocation *elements() { 1.4365 + return getOperand(0); 1.4366 + } 1.4367 + const LAllocation *length() { 1.4368 + return getOperand(1); 1.4369 + } 1.4370 + const LAllocation *index() { 1.4371 + return getOperand(2); 1.4372 + } 1.4373 + const LAllocation *value() { 1.4374 + return getOperand(3); 1.4375 + } 1.4376 +}; 1.4377 + 1.4378 +class LStoreTypedArrayElementStatic : public LInstructionHelper<0, 2, 0> 1.4379 +{ 1.4380 + public: 1.4381 + LIR_HEADER(StoreTypedArrayElementStatic); 1.4382 + LStoreTypedArrayElementStatic(const LAllocation &ptr, const LAllocation &value) { 1.4383 + setOperand(0, ptr); 1.4384 + setOperand(1, value); 1.4385 + } 1.4386 + MStoreTypedArrayElementStatic *mir() const { 1.4387 + return mir_->toStoreTypedArrayElementStatic(); 1.4388 + } 1.4389 + const LAllocation *ptr() { 1.4390 + return getOperand(0); 1.4391 + } 1.4392 + const LAllocation *value() { 1.4393 + return getOperand(1); 1.4394 + } 1.4395 +}; 1.4396 + 1.4397 +class LEffectiveAddress : public LInstructionHelper<1, 2, 0> 1.4398 +{ 1.4399 + public: 1.4400 + LIR_HEADER(EffectiveAddress); 1.4401 + 1.4402 + LEffectiveAddress(const LAllocation &base, const LAllocation &index) { 1.4403 + setOperand(0, base); 1.4404 + setOperand(1, index); 1.4405 + } 1.4406 + const MEffectiveAddress *mir() const { 1.4407 + return mir_->toEffectiveAddress(); 1.4408 + } 1.4409 + const LAllocation *base() { 1.4410 + return getOperand(0); 1.4411 + } 1.4412 + const LAllocation *index() { 1.4413 + return getOperand(1); 1.4414 + } 1.4415 +}; 1.4416 + 1.4417 +class LClampIToUint8 : public LInstructionHelper<1, 1, 0> 1.4418 +{ 1.4419 + public: 1.4420 + LIR_HEADER(ClampIToUint8) 1.4421 + 1.4422 + LClampIToUint8(const LAllocation &in) { 1.4423 + setOperand(0, in); 1.4424 + } 1.4425 +}; 1.4426 + 1.4427 +class LClampDToUint8 : public LInstructionHelper<1, 1, 1> 1.4428 +{ 1.4429 + public: 1.4430 + LIR_HEADER(ClampDToUint8) 1.4431 + 1.4432 + LClampDToUint8(const LAllocation &in, const LDefinition &temp) { 1.4433 + setOperand(0, in); 1.4434 + setTemp(0, temp); 1.4435 + } 1.4436 +}; 1.4437 + 1.4438 +class LClampVToUint8 : public LInstructionHelper<1, BOX_PIECES, 1> 1.4439 +{ 1.4440 + public: 1.4441 + LIR_HEADER(ClampVToUint8) 1.4442 + 1.4443 + LClampVToUint8(const LDefinition &tempFloat) { 1.4444 + setTemp(0, tempFloat); 1.4445 + } 1.4446 + 1.4447 + static const size_t Input = 0; 1.4448 + 1.4449 + const LDefinition *tempFloat() { 1.4450 + return getTemp(0); 1.4451 + } 1.4452 + const MClampToUint8 *mir() const { 1.4453 + return mir_->toClampToUint8(); 1.4454 + } 1.4455 +}; 1.4456 + 1.4457 +// Load a boxed value from an object's fixed slot. 1.4458 +class LLoadFixedSlotV : public LInstructionHelper<BOX_PIECES, 1, 0> 1.4459 +{ 1.4460 + public: 1.4461 + LIR_HEADER(LoadFixedSlotV) 1.4462 + 1.4463 + LLoadFixedSlotV(const LAllocation &object) { 1.4464 + setOperand(0, object); 1.4465 + } 1.4466 + const MLoadFixedSlot *mir() const { 1.4467 + return mir_->toLoadFixedSlot(); 1.4468 + } 1.4469 +}; 1.4470 + 1.4471 +// Load a typed value from an object's fixed slot. 1.4472 +class LLoadFixedSlotT : public LInstructionHelper<1, 1, 0> 1.4473 +{ 1.4474 + public: 1.4475 + LIR_HEADER(LoadFixedSlotT) 1.4476 + 1.4477 + LLoadFixedSlotT(const LAllocation &object) { 1.4478 + setOperand(0, object); 1.4479 + } 1.4480 + const MLoadFixedSlot *mir() const { 1.4481 + return mir_->toLoadFixedSlot(); 1.4482 + } 1.4483 +}; 1.4484 + 1.4485 +// Store a boxed value to an object's fixed slot. 1.4486 +class LStoreFixedSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0> 1.4487 +{ 1.4488 + public: 1.4489 + LIR_HEADER(StoreFixedSlotV) 1.4490 + 1.4491 + LStoreFixedSlotV(const LAllocation &obj) { 1.4492 + setOperand(0, obj); 1.4493 + } 1.4494 + 1.4495 + static const size_t Value = 1; 1.4496 + 1.4497 + const MStoreFixedSlot *mir() const { 1.4498 + return mir_->toStoreFixedSlot(); 1.4499 + } 1.4500 + const LAllocation *obj() { 1.4501 + return getOperand(0); 1.4502 + } 1.4503 +}; 1.4504 + 1.4505 +// Store a typed value to an object's fixed slot. 1.4506 +class LStoreFixedSlotT : public LInstructionHelper<0, 2, 0> 1.4507 +{ 1.4508 + public: 1.4509 + LIR_HEADER(StoreFixedSlotT) 1.4510 + 1.4511 + LStoreFixedSlotT(const LAllocation &obj, const LAllocation &value) 1.4512 + { 1.4513 + setOperand(0, obj); 1.4514 + setOperand(1, value); 1.4515 + } 1.4516 + const MStoreFixedSlot *mir() const { 1.4517 + return mir_->toStoreFixedSlot(); 1.4518 + } 1.4519 + const LAllocation *obj() { 1.4520 + return getOperand(0); 1.4521 + } 1.4522 + const LAllocation *value() { 1.4523 + return getOperand(1); 1.4524 + } 1.4525 +}; 1.4526 + 1.4527 +// Note, Name ICs always return a Value. There are no V/T variants. 1.4528 +class LGetNameCache : public LInstructionHelper<BOX_PIECES, 1, 0> 1.4529 +{ 1.4530 + public: 1.4531 + LIR_HEADER(GetNameCache) 1.4532 + 1.4533 + LGetNameCache(const LAllocation &scopeObj) { 1.4534 + setOperand(0, scopeObj); 1.4535 + } 1.4536 + const LAllocation *scopeObj() { 1.4537 + return getOperand(0); 1.4538 + } 1.4539 + const MGetNameCache *mir() const { 1.4540 + return mir_->toGetNameCache(); 1.4541 + } 1.4542 +}; 1.4543 + 1.4544 +class LCallGetIntrinsicValue : public LCallInstructionHelper<BOX_PIECES, 0, 0> 1.4545 +{ 1.4546 + public: 1.4547 + LIR_HEADER(CallGetIntrinsicValue) 1.4548 + 1.4549 + const MCallGetIntrinsicValue *mir() const { 1.4550 + return mir_->toCallGetIntrinsicValue(); 1.4551 + } 1.4552 +}; 1.4553 + 1.4554 +class LCallsiteCloneCache : public LInstructionHelper<1, 1, 0> 1.4555 +{ 1.4556 + public: 1.4557 + LIR_HEADER(CallsiteCloneCache); 1.4558 + 1.4559 + LCallsiteCloneCache(const LAllocation &callee) { 1.4560 + setOperand(0, callee); 1.4561 + } 1.4562 + const LAllocation *callee() { 1.4563 + return getOperand(0); 1.4564 + } 1.4565 + const MCallsiteCloneCache *mir() const { 1.4566 + return mir_->toCallsiteCloneCache(); 1.4567 + } 1.4568 +}; 1.4569 + 1.4570 +// Patchable jump to stubs generated for a GetProperty cache, which loads a 1.4571 +// boxed value. 1.4572 +class LGetPropertyCacheV : public LInstructionHelper<BOX_PIECES, 1, 0> 1.4573 +{ 1.4574 + public: 1.4575 + LIR_HEADER(GetPropertyCacheV) 1.4576 + 1.4577 + LGetPropertyCacheV(const LAllocation &object) { 1.4578 + setOperand(0, object); 1.4579 + } 1.4580 + const MGetPropertyCache *mir() const { 1.4581 + return mir_->toGetPropertyCache(); 1.4582 + } 1.4583 +}; 1.4584 + 1.4585 +// Patchable jump to stubs generated for a GetProperty cache, which loads a 1.4586 +// value of a known type, possibly into an FP register. 1.4587 +class LGetPropertyCacheT : public LInstructionHelper<1, 1, 1> 1.4588 +{ 1.4589 + public: 1.4590 + LIR_HEADER(GetPropertyCacheT) 1.4591 + 1.4592 + LGetPropertyCacheT(const LAllocation &object, const LDefinition &temp) { 1.4593 + setOperand(0, object); 1.4594 + setTemp(0, temp); 1.4595 + } 1.4596 + const LDefinition *temp() { 1.4597 + return getTemp(0); 1.4598 + } 1.4599 + const MGetPropertyCache *mir() const { 1.4600 + return mir_->toGetPropertyCache(); 1.4601 + } 1.4602 +}; 1.4603 + 1.4604 +// Emit code to load a boxed value from an object's slots if its shape matches 1.4605 +// one of the shapes observed by the baseline IC, else bails out. 1.4606 +class LGetPropertyPolymorphicV : public LInstructionHelper<BOX_PIECES, 1, 0> 1.4607 +{ 1.4608 + public: 1.4609 + LIR_HEADER(GetPropertyPolymorphicV) 1.4610 + 1.4611 + LGetPropertyPolymorphicV(const LAllocation &obj) { 1.4612 + setOperand(0, obj); 1.4613 + } 1.4614 + const LAllocation *obj() { 1.4615 + return getOperand(0); 1.4616 + } 1.4617 + const MGetPropertyPolymorphic *mir() const { 1.4618 + return mir_->toGetPropertyPolymorphic(); 1.4619 + } 1.4620 +}; 1.4621 + 1.4622 +// Emit code to load a typed value from an object's slots if its shape matches 1.4623 +// one of the shapes observed by the baseline IC, else bails out. 1.4624 +class LGetPropertyPolymorphicT : public LInstructionHelper<1, 1, 1> 1.4625 +{ 1.4626 + public: 1.4627 + LIR_HEADER(GetPropertyPolymorphicT) 1.4628 + 1.4629 + LGetPropertyPolymorphicT(const LAllocation &obj, const LDefinition &temp) { 1.4630 + setOperand(0, obj); 1.4631 + setTemp(0, temp); 1.4632 + } 1.4633 + const LAllocation *obj() { 1.4634 + return getOperand(0); 1.4635 + } 1.4636 + const LDefinition *temp() { 1.4637 + return getTemp(0); 1.4638 + } 1.4639 + const MGetPropertyPolymorphic *mir() const { 1.4640 + return mir_->toGetPropertyPolymorphic(); 1.4641 + } 1.4642 +}; 1.4643 + 1.4644 +// Emit code to store a boxed value to an object's slots if its shape matches 1.4645 +// one of the shapes observed by the baseline IC, else bails out. 1.4646 +class LSetPropertyPolymorphicV : public LInstructionHelper<0, 1 + BOX_PIECES, 1> 1.4647 +{ 1.4648 + public: 1.4649 + LIR_HEADER(SetPropertyPolymorphicV) 1.4650 + 1.4651 + LSetPropertyPolymorphicV(const LAllocation &obj, const LDefinition &temp) { 1.4652 + setOperand(0, obj); 1.4653 + setTemp(0, temp); 1.4654 + } 1.4655 + 1.4656 + static const size_t Value = 1; 1.4657 + 1.4658 + const LAllocation *obj() { 1.4659 + return getOperand(0); 1.4660 + } 1.4661 + const LDefinition *temp() { 1.4662 + return getTemp(0); 1.4663 + } 1.4664 + const MSetPropertyPolymorphic *mir() const { 1.4665 + return mir_->toSetPropertyPolymorphic(); 1.4666 + } 1.4667 +}; 1.4668 + 1.4669 +// Emit code to store a typed value to an object's slots if its shape matches 1.4670 +// one of the shapes observed by the baseline IC, else bails out. 1.4671 +class LSetPropertyPolymorphicT : public LInstructionHelper<0, 2, 1> 1.4672 +{ 1.4673 + MIRType valueType_; 1.4674 + 1.4675 + public: 1.4676 + LIR_HEADER(SetPropertyPolymorphicT) 1.4677 + 1.4678 + LSetPropertyPolymorphicT(const LAllocation &obj, const LAllocation &value, MIRType valueType, 1.4679 + const LDefinition &temp) 1.4680 + : valueType_(valueType) 1.4681 + { 1.4682 + setOperand(0, obj); 1.4683 + setOperand(1, value); 1.4684 + setTemp(0, temp); 1.4685 + } 1.4686 + 1.4687 + const LAllocation *obj() { 1.4688 + return getOperand(0); 1.4689 + } 1.4690 + const LAllocation *value() { 1.4691 + return getOperand(1); 1.4692 + } 1.4693 + const LDefinition *temp() { 1.4694 + return getTemp(0); 1.4695 + } 1.4696 + MIRType valueType() const { 1.4697 + return valueType_; 1.4698 + } 1.4699 + const MSetPropertyPolymorphic *mir() const { 1.4700 + return mir_->toSetPropertyPolymorphic(); 1.4701 + } 1.4702 + const char *extraName() const { 1.4703 + return StringFromMIRType(valueType_); 1.4704 + } 1.4705 +}; 1.4706 + 1.4707 +class LGetElementCacheV : public LInstructionHelper<BOX_PIECES, 1 + BOX_PIECES, 0> 1.4708 +{ 1.4709 + public: 1.4710 + LIR_HEADER(GetElementCacheV) 1.4711 + 1.4712 + static const size_t Index = 1; 1.4713 + 1.4714 + LGetElementCacheV(const LAllocation &object) { 1.4715 + setOperand(0, object); 1.4716 + } 1.4717 + const LAllocation *object() { 1.4718 + return getOperand(0); 1.4719 + } 1.4720 + const MGetElementCache *mir() const { 1.4721 + return mir_->toGetElementCache(); 1.4722 + } 1.4723 +}; 1.4724 + 1.4725 +class LGetElementCacheT : public LInstructionHelper<1, 2, 1> 1.4726 +{ 1.4727 + public: 1.4728 + LIR_HEADER(GetElementCacheT) 1.4729 + 1.4730 + LGetElementCacheT(const LAllocation &object, const LAllocation &index, 1.4731 + const LDefinition &temp) { 1.4732 + setOperand(0, object); 1.4733 + setOperand(1, index); 1.4734 + setTemp(0, temp); 1.4735 + } 1.4736 + const LAllocation *object() { 1.4737 + return getOperand(0); 1.4738 + } 1.4739 + const LAllocation *index() { 1.4740 + return getOperand(1); 1.4741 + } 1.4742 + const LDefinition *output() { 1.4743 + return getDef(0); 1.4744 + } 1.4745 + const LDefinition *temp() { 1.4746 + return getTemp(0); 1.4747 + } 1.4748 + const MGetElementCache *mir() const { 1.4749 + return mir_->toGetElementCache(); 1.4750 + } 1.4751 +}; 1.4752 + 1.4753 +class LBindNameCache : public LInstructionHelper<1, 1, 0> 1.4754 +{ 1.4755 + public: 1.4756 + LIR_HEADER(BindNameCache) 1.4757 + 1.4758 + LBindNameCache(const LAllocation &scopeChain) { 1.4759 + setOperand(0, scopeChain); 1.4760 + } 1.4761 + const LAllocation *scopeChain() { 1.4762 + return getOperand(0); 1.4763 + } 1.4764 + const MBindNameCache *mir() const { 1.4765 + return mir_->toBindNameCache(); 1.4766 + } 1.4767 +}; 1.4768 + 1.4769 +// Load a value from an object's dslots or a slots vector. 1.4770 +class LLoadSlotV : public LInstructionHelper<BOX_PIECES, 1, 0> 1.4771 +{ 1.4772 + public: 1.4773 + LIR_HEADER(LoadSlotV) 1.4774 + 1.4775 + LLoadSlotV(const LAllocation &in) { 1.4776 + setOperand(0, in); 1.4777 + } 1.4778 + const MLoadSlot *mir() const { 1.4779 + return mir_->toLoadSlot(); 1.4780 + } 1.4781 +}; 1.4782 + 1.4783 +// Load a typed value from an object's dslots or a slots vector. Unlike 1.4784 +// LLoadSlotV, this can bypass extracting a type tag, directly retrieving a 1.4785 +// pointer, integer, or double. 1.4786 +class LLoadSlotT : public LInstructionHelper<1, 1, 0> 1.4787 +{ 1.4788 + public: 1.4789 + LIR_HEADER(LoadSlotT) 1.4790 + 1.4791 + LLoadSlotT(const LAllocation &in) { 1.4792 + setOperand(0, in); 1.4793 + } 1.4794 + const MLoadSlot *mir() const { 1.4795 + return mir_->toLoadSlot(); 1.4796 + } 1.4797 +}; 1.4798 + 1.4799 +// Store a value to an object's dslots or a slots vector. 1.4800 +class LStoreSlotV : public LInstructionHelper<0, 1 + BOX_PIECES, 0> 1.4801 +{ 1.4802 + public: 1.4803 + LIR_HEADER(StoreSlotV) 1.4804 + 1.4805 + LStoreSlotV(const LAllocation &slots) { 1.4806 + setOperand(0, slots); 1.4807 + } 1.4808 + 1.4809 + static const size_t Value = 1; 1.4810 + 1.4811 + const MStoreSlot *mir() const { 1.4812 + return mir_->toStoreSlot(); 1.4813 + } 1.4814 + const LAllocation *slots() { 1.4815 + return getOperand(0); 1.4816 + } 1.4817 +}; 1.4818 + 1.4819 +// Store a typed value to an object's dslots or a slots vector. This has a 1.4820 +// few advantages over LStoreSlotV: 1.4821 +// 1) We can bypass storing the type tag if the slot has the same type as 1.4822 +// the value. 1.4823 +// 2) Better register allocation: we can store constants and FP regs directly 1.4824 +// without requiring a second register for the value. 1.4825 +class LStoreSlotT : public LInstructionHelper<0, 2, 0> 1.4826 +{ 1.4827 + public: 1.4828 + LIR_HEADER(StoreSlotT) 1.4829 + 1.4830 + LStoreSlotT(const LAllocation &slots, const LAllocation &value) { 1.4831 + setOperand(0, slots); 1.4832 + setOperand(1, value); 1.4833 + } 1.4834 + const MStoreSlot *mir() const { 1.4835 + return mir_->toStoreSlot(); 1.4836 + } 1.4837 + const LAllocation *slots() { 1.4838 + return getOperand(0); 1.4839 + } 1.4840 + const LAllocation *value() { 1.4841 + return getOperand(1); 1.4842 + } 1.4843 +}; 1.4844 + 1.4845 +// Read length field of a JSString*. 1.4846 +class LStringLength : public LInstructionHelper<1, 1, 0> 1.4847 +{ 1.4848 + public: 1.4849 + LIR_HEADER(StringLength) 1.4850 + 1.4851 + LStringLength(const LAllocation &string) { 1.4852 + setOperand(0, string); 1.4853 + } 1.4854 + 1.4855 + const LAllocation *string() { 1.4856 + return getOperand(0); 1.4857 + } 1.4858 +}; 1.4859 + 1.4860 +// Take the floor of a double precision number. Implements Math.floor(). 1.4861 +class LFloor : public LInstructionHelper<1, 1, 0> 1.4862 +{ 1.4863 + public: 1.4864 + LIR_HEADER(Floor) 1.4865 + 1.4866 + LFloor(const LAllocation &num) { 1.4867 + setOperand(0, num); 1.4868 + } 1.4869 +}; 1.4870 + 1.4871 +// Take the floor of a single precision number. Implements Math.floor(). 1.4872 +class LFloorF : public LInstructionHelper<1, 1, 0> 1.4873 +{ 1.4874 + public: 1.4875 + LIR_HEADER(FloorF) 1.4876 + 1.4877 + LFloorF(const LAllocation &num) { 1.4878 + setOperand(0, num); 1.4879 + } 1.4880 +}; 1.4881 + 1.4882 +// Round a double precision number. Implements Math.round(). 1.4883 +class LRound : public LInstructionHelper<1, 1, 1> 1.4884 +{ 1.4885 + public: 1.4886 + LIR_HEADER(Round) 1.4887 + 1.4888 + LRound(const LAllocation &num, const LDefinition &temp) { 1.4889 + setOperand(0, num); 1.4890 + setTemp(0, temp); 1.4891 + } 1.4892 + 1.4893 + const LDefinition *temp() { 1.4894 + return getTemp(0); 1.4895 + } 1.4896 + MRound *mir() const { 1.4897 + return mir_->toRound(); 1.4898 + } 1.4899 +}; 1.4900 + 1.4901 +// Round a single precision number. Implements Math.round(). 1.4902 +class LRoundF : public LInstructionHelper<1, 1, 1> 1.4903 +{ 1.4904 + public: 1.4905 + LIR_HEADER(RoundF) 1.4906 + 1.4907 + LRoundF(const LAllocation &num, const LDefinition &temp) { 1.4908 + setOperand(0, num); 1.4909 + setTemp(0, temp); 1.4910 + } 1.4911 + 1.4912 + const LDefinition *temp() { 1.4913 + return getTemp(0); 1.4914 + } 1.4915 + MRound *mir() const { 1.4916 + return mir_->toRound(); 1.4917 + } 1.4918 +}; 1.4919 + 1.4920 +// Load a function's call environment. 1.4921 +class LFunctionEnvironment : public LInstructionHelper<1, 1, 0> 1.4922 +{ 1.4923 + public: 1.4924 + LIR_HEADER(FunctionEnvironment) 1.4925 + 1.4926 + LFunctionEnvironment(const LAllocation &function) { 1.4927 + setOperand(0, function); 1.4928 + } 1.4929 + const LAllocation *function() { 1.4930 + return getOperand(0); 1.4931 + } 1.4932 +}; 1.4933 + 1.4934 +class LForkJoinContext : public LCallInstructionHelper<1, 0, 1> 1.4935 +{ 1.4936 + public: 1.4937 + LIR_HEADER(ForkJoinContext); 1.4938 + 1.4939 + LForkJoinContext(const LDefinition &temp1) { 1.4940 + setTemp(0, temp1); 1.4941 + } 1.4942 + 1.4943 + const LDefinition *getTempReg() { 1.4944 + return getTemp(0); 1.4945 + } 1.4946 +}; 1.4947 + 1.4948 +class LForkJoinGetSlice : public LInstructionHelper<1, 1, 4> 1.4949 +{ 1.4950 + public: 1.4951 + LIR_HEADER(ForkJoinGetSlice); 1.4952 + 1.4953 + LForkJoinGetSlice(const LAllocation &cx, 1.4954 + const LDefinition &temp1, const LDefinition &temp2, 1.4955 + const LDefinition &temp3, const LDefinition &temp4) { 1.4956 + setOperand(0, cx); 1.4957 + setTemp(0, temp1); 1.4958 + setTemp(1, temp2); 1.4959 + setTemp(2, temp3); 1.4960 + setTemp(3, temp4); 1.4961 + } 1.4962 + 1.4963 + const LAllocation *forkJoinContext() { 1.4964 + return getOperand(0); 1.4965 + } 1.4966 + const LDefinition *temp1() { 1.4967 + return getTemp(0); 1.4968 + } 1.4969 + const LDefinition *temp2() { 1.4970 + return getTemp(1); 1.4971 + } 1.4972 + const LDefinition *temp3() { 1.4973 + return getTemp(2); 1.4974 + } 1.4975 + const LDefinition *temp4() { 1.4976 + return getTemp(3); 1.4977 + } 1.4978 +}; 1.4979 + 1.4980 +class LCallGetProperty : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES, 0> 1.4981 +{ 1.4982 + public: 1.4983 + LIR_HEADER(CallGetProperty) 1.4984 + 1.4985 + static const size_t Value = 0; 1.4986 + 1.4987 + MCallGetProperty *mir() const { 1.4988 + return mir_->toCallGetProperty(); 1.4989 + } 1.4990 +}; 1.4991 + 1.4992 +// Call js::GetElement. 1.4993 +class LCallGetElement : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0> 1.4994 +{ 1.4995 + public: 1.4996 + LIR_HEADER(CallGetElement) 1.4997 + 1.4998 + static const size_t LhsInput = 0; 1.4999 + static const size_t RhsInput = BOX_PIECES; 1.5000 + 1.5001 + MCallGetElement *mir() const { 1.5002 + return mir_->toCallGetElement(); 1.5003 + } 1.5004 +}; 1.5005 + 1.5006 +// Call js::SetElement. 1.5007 +class LCallSetElement : public LCallInstructionHelper<0, 1 + 2 * BOX_PIECES, 0> 1.5008 +{ 1.5009 + public: 1.5010 + LIR_HEADER(CallSetElement) 1.5011 + 1.5012 + static const size_t Index = 1; 1.5013 + static const size_t Value = 1 + BOX_PIECES; 1.5014 +}; 1.5015 + 1.5016 +// Call js::InitElementArray. 1.5017 +class LCallInitElementArray : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> 1.5018 +{ 1.5019 +public: 1.5020 + LIR_HEADER(CallInitElementArray) 1.5021 + 1.5022 + static const size_t Value = 1; 1.5023 + 1.5024 + const MCallInitElementArray *mir() const { 1.5025 + return mir_->toCallInitElementArray(); 1.5026 + } 1.5027 +}; 1.5028 + 1.5029 +// Call a VM function to perform a property or name assignment of a generic value. 1.5030 +class LCallSetProperty : public LCallInstructionHelper<0, 1 + BOX_PIECES, 0> 1.5031 +{ 1.5032 + public: 1.5033 + LIR_HEADER(CallSetProperty) 1.5034 + 1.5035 + LCallSetProperty(const LAllocation &obj) { 1.5036 + setOperand(0, obj); 1.5037 + } 1.5038 + 1.5039 + static const size_t Value = 1; 1.5040 + 1.5041 + const MCallSetProperty *mir() const { 1.5042 + return mir_->toCallSetProperty(); 1.5043 + } 1.5044 +}; 1.5045 + 1.5046 +class LCallDeleteProperty : public LCallInstructionHelper<1, BOX_PIECES, 0> 1.5047 +{ 1.5048 + public: 1.5049 + LIR_HEADER(CallDeleteProperty) 1.5050 + 1.5051 + static const size_t Value = 0; 1.5052 + 1.5053 + MDeleteProperty *mir() const { 1.5054 + return mir_->toDeleteProperty(); 1.5055 + } 1.5056 +}; 1.5057 + 1.5058 +class LCallDeleteElement : public LCallInstructionHelper<1, 2 * BOX_PIECES, 0> 1.5059 +{ 1.5060 + public: 1.5061 + LIR_HEADER(CallDeleteElement) 1.5062 + 1.5063 + static const size_t Value = 0; 1.5064 + static const size_t Index = BOX_PIECES; 1.5065 + 1.5066 + MDeleteElement *mir() const { 1.5067 + return mir_->toDeleteElement(); 1.5068 + } 1.5069 +}; 1.5070 + 1.5071 +// Patchable jump to stubs generated for a SetProperty cache, which stores a 1.5072 +// boxed value. 1.5073 +class LSetPropertyCacheV : public LInstructionHelper<0, 1 + BOX_PIECES, 2> 1.5074 +{ 1.5075 + public: 1.5076 + LIR_HEADER(SetPropertyCacheV) 1.5077 + 1.5078 + LSetPropertyCacheV(const LAllocation &object, const LDefinition &slots, 1.5079 + const LDefinition &temp) { 1.5080 + setOperand(0, object); 1.5081 + setTemp(0, slots); 1.5082 + setTemp(1, temp); 1.5083 + } 1.5084 + 1.5085 + static const size_t Value = 1; 1.5086 + 1.5087 + const MSetPropertyCache *mir() const { 1.5088 + return mir_->toSetPropertyCache(); 1.5089 + } 1.5090 + 1.5091 + const LDefinition *tempForDispatchCache() { 1.5092 + return getTemp(1); 1.5093 + } 1.5094 +}; 1.5095 + 1.5096 +// Patchable jump to stubs generated for a SetProperty cache, which stores a 1.5097 +// value of a known type. 1.5098 +class LSetPropertyCacheT : public LInstructionHelper<0, 2, 2> 1.5099 +{ 1.5100 + MIRType valueType_; 1.5101 + 1.5102 + public: 1.5103 + LIR_HEADER(SetPropertyCacheT) 1.5104 + 1.5105 + LSetPropertyCacheT(const LAllocation &object, const LDefinition &slots, 1.5106 + const LAllocation &value, const LDefinition &temp, 1.5107 + MIRType valueType) 1.5108 + : valueType_(valueType) 1.5109 + { 1.5110 + setOperand(0, object); 1.5111 + setOperand(1, value); 1.5112 + setTemp(0, slots); 1.5113 + setTemp(1, temp); 1.5114 + } 1.5115 + 1.5116 + const MSetPropertyCache *mir() const { 1.5117 + return mir_->toSetPropertyCache(); 1.5118 + } 1.5119 + MIRType valueType() { 1.5120 + return valueType_; 1.5121 + } 1.5122 + const char *extraName() const { 1.5123 + return StringFromMIRType(valueType_); 1.5124 + } 1.5125 + 1.5126 + const LDefinition *tempForDispatchCache() { 1.5127 + return getTemp(1); 1.5128 + } 1.5129 +}; 1.5130 + 1.5131 +class LSetElementCacheV : public LInstructionHelper<0, 1 + 2 * BOX_PIECES, 3> 1.5132 +{ 1.5133 + public: 1.5134 + LIR_HEADER(SetElementCacheV); 1.5135 + 1.5136 + static const size_t Index = 1; 1.5137 + static const size_t Value = 1 + BOX_PIECES; 1.5138 + 1.5139 + LSetElementCacheV(const LAllocation &object, const LDefinition &tempToUnboxIndex, 1.5140 + const LDefinition &temp, const LDefinition &tempFloat) 1.5141 + { 1.5142 + setOperand(0, object); 1.5143 + setTemp(0, tempToUnboxIndex); 1.5144 + setTemp(1, temp); 1.5145 + setTemp(2, tempFloat); 1.5146 + } 1.5147 + const MSetElementCache *mir() const { 1.5148 + return mir_->toSetElementCache(); 1.5149 + } 1.5150 + 1.5151 + const LAllocation *object() { 1.5152 + return getOperand(0); 1.5153 + } 1.5154 + const LDefinition *tempToUnboxIndex() { 1.5155 + return getTemp(0); 1.5156 + } 1.5157 + const LDefinition *temp() { 1.5158 + return getTemp(1); 1.5159 + } 1.5160 + const LDefinition *tempFloat() { 1.5161 + return getTemp(2); 1.5162 + } 1.5163 +}; 1.5164 + 1.5165 +class LSetElementCacheT : public LInstructionHelper<0, 2 + BOX_PIECES, 3> 1.5166 +{ 1.5167 + public: 1.5168 + LIR_HEADER(SetElementCacheT); 1.5169 + 1.5170 + static const size_t Index = 2; 1.5171 + 1.5172 + LSetElementCacheT(const LAllocation &object, const LAllocation &value, 1.5173 + const LDefinition &tempToUnboxIndex, 1.5174 + const LDefinition &temp, const LDefinition &tempFloat) { 1.5175 + setOperand(0, object); 1.5176 + setOperand(1, value); 1.5177 + setTemp(0, tempToUnboxIndex); 1.5178 + setTemp(1, temp); 1.5179 + setTemp(2, tempFloat); 1.5180 + } 1.5181 + const MSetElementCache *mir() const { 1.5182 + return mir_->toSetElementCache(); 1.5183 + } 1.5184 + 1.5185 + const LAllocation *object() { 1.5186 + return getOperand(0); 1.5187 + } 1.5188 + const LAllocation *value() { 1.5189 + return getOperand(1); 1.5190 + } 1.5191 + const LDefinition *tempToUnboxIndex() { 1.5192 + return getTemp(0); 1.5193 + } 1.5194 + const LDefinition *temp() { 1.5195 + return getTemp(1); 1.5196 + } 1.5197 + const LDefinition *tempFloat() { 1.5198 + return getTemp(2); 1.5199 + } 1.5200 +}; 1.5201 + 1.5202 +class LCallIteratorStart : public LCallInstructionHelper<1, 1, 0> 1.5203 +{ 1.5204 + public: 1.5205 + LIR_HEADER(CallIteratorStart) 1.5206 + 1.5207 + LCallIteratorStart(const LAllocation &object) { 1.5208 + setOperand(0, object); 1.5209 + } 1.5210 + const LAllocation *object() { 1.5211 + return getOperand(0); 1.5212 + } 1.5213 + MIteratorStart *mir() const { 1.5214 + return mir_->toIteratorStart(); 1.5215 + } 1.5216 +}; 1.5217 + 1.5218 +class LIteratorStart : public LInstructionHelper<1, 1, 3> 1.5219 +{ 1.5220 + public: 1.5221 + LIR_HEADER(IteratorStart) 1.5222 + 1.5223 + LIteratorStart(const LAllocation &object, const LDefinition &temp1, 1.5224 + const LDefinition &temp2, const LDefinition &temp3) { 1.5225 + setOperand(0, object); 1.5226 + setTemp(0, temp1); 1.5227 + setTemp(1, temp2); 1.5228 + setTemp(2, temp3); 1.5229 + } 1.5230 + const LAllocation *object() { 1.5231 + return getOperand(0); 1.5232 + } 1.5233 + const LDefinition *temp1() { 1.5234 + return getTemp(0); 1.5235 + } 1.5236 + const LDefinition *temp2() { 1.5237 + return getTemp(1); 1.5238 + } 1.5239 + const LDefinition *temp3() { 1.5240 + return getTemp(2); 1.5241 + } 1.5242 + MIteratorStart *mir() const { 1.5243 + return mir_->toIteratorStart(); 1.5244 + } 1.5245 +}; 1.5246 + 1.5247 +class LIteratorNext : public LInstructionHelper<BOX_PIECES, 1, 1> 1.5248 +{ 1.5249 + public: 1.5250 + LIR_HEADER(IteratorNext) 1.5251 + 1.5252 + LIteratorNext(const LAllocation &iterator, const LDefinition &temp) { 1.5253 + setOperand(0, iterator); 1.5254 + setTemp(0, temp); 1.5255 + } 1.5256 + const LAllocation *object() { 1.5257 + return getOperand(0); 1.5258 + } 1.5259 + const LDefinition *temp() { 1.5260 + return getTemp(0); 1.5261 + } 1.5262 + MIteratorNext *mir() const { 1.5263 + return mir_->toIteratorNext(); 1.5264 + } 1.5265 +}; 1.5266 + 1.5267 +class LIteratorMore : public LInstructionHelper<1, 1, 1> 1.5268 +{ 1.5269 + public: 1.5270 + LIR_HEADER(IteratorMore) 1.5271 + 1.5272 + LIteratorMore(const LAllocation &iterator, const LDefinition &temp) { 1.5273 + setOperand(0, iterator); 1.5274 + setTemp(0, temp); 1.5275 + } 1.5276 + const LAllocation *object() { 1.5277 + return getOperand(0); 1.5278 + } 1.5279 + const LDefinition *temp() { 1.5280 + return getTemp(0); 1.5281 + } 1.5282 + MIteratorMore *mir() const { 1.5283 + return mir_->toIteratorMore(); 1.5284 + } 1.5285 +}; 1.5286 + 1.5287 +class LIteratorEnd : public LInstructionHelper<0, 1, 3> 1.5288 +{ 1.5289 + public: 1.5290 + LIR_HEADER(IteratorEnd) 1.5291 + 1.5292 + LIteratorEnd(const LAllocation &iterator, const LDefinition &temp1, 1.5293 + const LDefinition &temp2, const LDefinition &temp3) { 1.5294 + setOperand(0, iterator); 1.5295 + setTemp(0, temp1); 1.5296 + setTemp(1, temp2); 1.5297 + setTemp(2, temp3); 1.5298 + } 1.5299 + const LAllocation *object() { 1.5300 + return getOperand(0); 1.5301 + } 1.5302 + const LDefinition *temp1() { 1.5303 + return getTemp(0); 1.5304 + } 1.5305 + const LDefinition *temp2() { 1.5306 + return getTemp(1); 1.5307 + } 1.5308 + const LDefinition *temp3() { 1.5309 + return getTemp(2); 1.5310 + } 1.5311 + MIteratorEnd *mir() const { 1.5312 + return mir_->toIteratorEnd(); 1.5313 + } 1.5314 +}; 1.5315 + 1.5316 +// Read the number of actual arguments. 1.5317 +class LArgumentsLength : public LInstructionHelper<1, 0, 0> 1.5318 +{ 1.5319 + public: 1.5320 + LIR_HEADER(ArgumentsLength) 1.5321 +}; 1.5322 + 1.5323 +// Load a value from the actual arguments. 1.5324 +class LGetFrameArgument : public LInstructionHelper<BOX_PIECES, 1, 0> 1.5325 +{ 1.5326 + public: 1.5327 + LIR_HEADER(GetFrameArgument) 1.5328 + 1.5329 + LGetFrameArgument(const LAllocation &index) { 1.5330 + setOperand(0, index); 1.5331 + } 1.5332 + const LAllocation *index() { 1.5333 + return getOperand(0); 1.5334 + } 1.5335 +}; 1.5336 + 1.5337 +// Load a value from the actual arguments. 1.5338 +class LSetFrameArgumentT : public LInstructionHelper<0, 1, 0> 1.5339 +{ 1.5340 + public: 1.5341 + LIR_HEADER(SetFrameArgumentT) 1.5342 + 1.5343 + LSetFrameArgumentT(const LAllocation &input) { 1.5344 + setOperand(0, input); 1.5345 + } 1.5346 + MSetFrameArgument *mir() const { 1.5347 + return mir_->toSetFrameArgument(); 1.5348 + } 1.5349 + const LAllocation *input() { 1.5350 + return getOperand(0); 1.5351 + } 1.5352 +}; 1.5353 + 1.5354 +// Load a value from the actual arguments. 1.5355 +class LSetFrameArgumentC : public LInstructionHelper<0, 0, 0> 1.5356 +{ 1.5357 + Value val_; 1.5358 + 1.5359 + public: 1.5360 + LIR_HEADER(SetFrameArgumentC) 1.5361 + 1.5362 + LSetFrameArgumentC(const Value &val) { 1.5363 + val_ = val; 1.5364 + } 1.5365 + MSetFrameArgument *mir() const { 1.5366 + return mir_->toSetFrameArgument(); 1.5367 + } 1.5368 + const Value &val() const { 1.5369 + return val_; 1.5370 + } 1.5371 +}; 1.5372 + 1.5373 +// Load a value from the actual arguments. 1.5374 +class LSetFrameArgumentV : public LInstructionHelper<0, BOX_PIECES, 0> 1.5375 +{ 1.5376 + public: 1.5377 + LIR_HEADER(SetFrameArgumentV) 1.5378 + 1.5379 + LSetFrameArgumentV() {} 1.5380 + 1.5381 + static const size_t Input = 0; 1.5382 + 1.5383 + MSetFrameArgument *mir() const { 1.5384 + return mir_->toSetFrameArgument(); 1.5385 + } 1.5386 +}; 1.5387 + 1.5388 +class LRunOncePrologue : public LCallInstructionHelper<0, 0, 0> 1.5389 +{ 1.5390 + public: 1.5391 + LIR_HEADER(RunOncePrologue) 1.5392 + 1.5393 + MRunOncePrologue *mir() const { 1.5394 + return mir_->toRunOncePrologue(); 1.5395 + } 1.5396 +}; 1.5397 + 1.5398 +// Create the rest parameter. 1.5399 +class LRest : public LCallInstructionHelper<1, 1, 3> 1.5400 +{ 1.5401 + public: 1.5402 + LIR_HEADER(Rest) 1.5403 + 1.5404 + LRest(const LAllocation &numActuals, const LDefinition &temp1, const LDefinition &temp2, 1.5405 + const LDefinition &temp3) 1.5406 + { 1.5407 + setOperand(0, numActuals); 1.5408 + setTemp(0, temp1); 1.5409 + setTemp(1, temp2); 1.5410 + setTemp(2, temp3); 1.5411 + } 1.5412 + const LAllocation *numActuals() { 1.5413 + return getOperand(0); 1.5414 + } 1.5415 + MRest *mir() const { 1.5416 + return mir_->toRest(); 1.5417 + } 1.5418 +}; 1.5419 + 1.5420 +class LRestPar : public LCallInstructionHelper<1, 2, 3> 1.5421 +{ 1.5422 + public: 1.5423 + LIR_HEADER(RestPar); 1.5424 + 1.5425 + LRestPar(const LAllocation &cx, const LAllocation &numActuals, 1.5426 + const LDefinition &temp1, const LDefinition &temp2, const LDefinition &temp3) 1.5427 + { 1.5428 + setOperand(0, cx); 1.5429 + setOperand(1, numActuals); 1.5430 + setTemp(0, temp1); 1.5431 + setTemp(1, temp2); 1.5432 + setTemp(2, temp3); 1.5433 + } 1.5434 + const LAllocation *forkJoinContext() { 1.5435 + return getOperand(0); 1.5436 + } 1.5437 + const LAllocation *numActuals() { 1.5438 + return getOperand(1); 1.5439 + } 1.5440 + MRestPar *mir() const { 1.5441 + return mir_->toRestPar(); 1.5442 + } 1.5443 +}; 1.5444 + 1.5445 +class LGuardThreadExclusive : public LCallInstructionHelper<0, 2, 1> 1.5446 +{ 1.5447 + public: 1.5448 + LIR_HEADER(GuardThreadExclusive); 1.5449 + 1.5450 + LGuardThreadExclusive(const LAllocation &cx, const LAllocation &object, const LDefinition &temp1) { 1.5451 + setOperand(0, cx); 1.5452 + setOperand(1, object); 1.5453 + setTemp(0, temp1); 1.5454 + } 1.5455 + 1.5456 + const LAllocation *forkJoinContext() { 1.5457 + return getOperand(0); 1.5458 + } 1.5459 + 1.5460 + const LAllocation *object() { 1.5461 + return getOperand(1); 1.5462 + } 1.5463 + 1.5464 + const LDefinition *getTempReg() { 1.5465 + return getTemp(0); 1.5466 + } 1.5467 +}; 1.5468 + 1.5469 +// Guard that a value is in a TypeSet. 1.5470 +class LTypeBarrierV : public LInstructionHelper<0, BOX_PIECES, 1> 1.5471 +{ 1.5472 + public: 1.5473 + LIR_HEADER(TypeBarrierV) 1.5474 + 1.5475 + LTypeBarrierV(const LDefinition &temp) { 1.5476 + setTemp(0, temp); 1.5477 + } 1.5478 + 1.5479 + static const size_t Input = 0; 1.5480 + 1.5481 + const MTypeBarrier *mir() const { 1.5482 + return mir_->toTypeBarrier(); 1.5483 + } 1.5484 + const LDefinition *temp() { 1.5485 + return getTemp(0); 1.5486 + } 1.5487 +}; 1.5488 + 1.5489 +// Guard that a object is in a TypeSet. 1.5490 +class LTypeBarrierO : public LInstructionHelper<0, 1, 1> 1.5491 +{ 1.5492 + public: 1.5493 + LIR_HEADER(TypeBarrierO) 1.5494 + 1.5495 + LTypeBarrierO(const LAllocation &obj, const LDefinition &temp) { 1.5496 + setOperand(0, obj); 1.5497 + setTemp(0, temp); 1.5498 + } 1.5499 + const MTypeBarrier *mir() const { 1.5500 + return mir_->toTypeBarrier(); 1.5501 + } 1.5502 + const LAllocation *object() { 1.5503 + return getOperand(0); 1.5504 + } 1.5505 + const LDefinition *temp() { 1.5506 + return getTemp(0); 1.5507 + } 1.5508 +}; 1.5509 + 1.5510 +// Guard that a value is in a TypeSet. 1.5511 +class LMonitorTypes : public LInstructionHelper<0, BOX_PIECES, 1> 1.5512 +{ 1.5513 + public: 1.5514 + LIR_HEADER(MonitorTypes) 1.5515 + 1.5516 + LMonitorTypes(const LDefinition &temp) { 1.5517 + setTemp(0, temp); 1.5518 + } 1.5519 + 1.5520 + static const size_t Input = 0; 1.5521 + 1.5522 + const MMonitorTypes *mir() const { 1.5523 + return mir_->toMonitorTypes(); 1.5524 + } 1.5525 + const LDefinition *temp() { 1.5526 + return getTemp(0); 1.5527 + } 1.5528 +}; 1.5529 + 1.5530 +// Generational write barrier used when writing an object to another object. 1.5531 +class LPostWriteBarrierO : public LInstructionHelper<0, 2, 1> 1.5532 +{ 1.5533 + public: 1.5534 + LIR_HEADER(PostWriteBarrierO) 1.5535 + 1.5536 + LPostWriteBarrierO(const LAllocation &obj, const LAllocation &value, 1.5537 + const LDefinition &temp) { 1.5538 + setOperand(0, obj); 1.5539 + setOperand(1, value); 1.5540 + setTemp(0, temp); 1.5541 + } 1.5542 + 1.5543 + const MPostWriteBarrier *mir() const { 1.5544 + return mir_->toPostWriteBarrier(); 1.5545 + } 1.5546 + const LAllocation *object() { 1.5547 + return getOperand(0); 1.5548 + } 1.5549 + const LAllocation *value() { 1.5550 + return getOperand(1); 1.5551 + } 1.5552 + const LDefinition *temp() { 1.5553 + return getTemp(0); 1.5554 + } 1.5555 +}; 1.5556 + 1.5557 +// Generational write barrier used when writing a value to another object. 1.5558 +class LPostWriteBarrierV : public LInstructionHelper<0, 1 + BOX_PIECES, 1> 1.5559 +{ 1.5560 + public: 1.5561 + LIR_HEADER(PostWriteBarrierV) 1.5562 + 1.5563 + LPostWriteBarrierV(const LAllocation &obj, const LDefinition &temp) { 1.5564 + setOperand(0, obj); 1.5565 + setTemp(0, temp); 1.5566 + } 1.5567 + 1.5568 + static const size_t Input = 1; 1.5569 + 1.5570 + const MPostWriteBarrier *mir() const { 1.5571 + return mir_->toPostWriteBarrier(); 1.5572 + } 1.5573 + const LAllocation *object() { 1.5574 + return getOperand(0); 1.5575 + } 1.5576 + const LDefinition *temp() { 1.5577 + return getTemp(0); 1.5578 + } 1.5579 +}; 1.5580 + 1.5581 +// Guard against an object's identity. 1.5582 +class LGuardObjectIdentity : public LInstructionHelper<0, 1, 0> 1.5583 +{ 1.5584 + public: 1.5585 + LIR_HEADER(GuardObjectIdentity) 1.5586 + 1.5587 + LGuardObjectIdentity(const LAllocation &in) { 1.5588 + setOperand(0, in); 1.5589 + } 1.5590 + const MGuardObjectIdentity *mir() const { 1.5591 + return mir_->toGuardObjectIdentity(); 1.5592 + } 1.5593 +}; 1.5594 + 1.5595 +// Guard against an object's class. 1.5596 +class LGuardClass : public LInstructionHelper<0, 1, 1> 1.5597 +{ 1.5598 + public: 1.5599 + LIR_HEADER(GuardClass) 1.5600 + 1.5601 + LGuardClass(const LAllocation &in, const LDefinition &temp) { 1.5602 + setOperand(0, in); 1.5603 + setTemp(0, temp); 1.5604 + } 1.5605 + const MGuardClass *mir() const { 1.5606 + return mir_->toGuardClass(); 1.5607 + } 1.5608 + const LDefinition *tempInt() { 1.5609 + return getTemp(0); 1.5610 + } 1.5611 +}; 1.5612 + 1.5613 +class MPhi; 1.5614 + 1.5615 +// Phi is a pseudo-instruction that emits no code, and is an annotation for the 1.5616 +// register allocator. Like its equivalent in MIR, phis are collected at the 1.5617 +// top of blocks and are meant to be executed in parallel, choosing the input 1.5618 +// corresponding to the predecessor taken in the control flow graph. 1.5619 +class LPhi MOZ_FINAL : public LInstruction 1.5620 +{ 1.5621 + LAllocation *inputs_; 1.5622 + LDefinition def_; 1.5623 + 1.5624 + LPhi() 1.5625 + { } 1.5626 + 1.5627 + public: 1.5628 + LIR_HEADER(Phi) 1.5629 + 1.5630 + static LPhi *New(MIRGenerator *gen, MPhi *phi); 1.5631 + 1.5632 + size_t numDefs() const { 1.5633 + return 1; 1.5634 + } 1.5635 + LDefinition *getDef(size_t index) { 1.5636 + JS_ASSERT(index == 0); 1.5637 + return &def_; 1.5638 + } 1.5639 + void setDef(size_t index, const LDefinition &def) { 1.5640 + JS_ASSERT(index == 0); 1.5641 + def_ = def; 1.5642 + } 1.5643 + size_t numOperands() const { 1.5644 + return mir_->toPhi()->numOperands(); 1.5645 + } 1.5646 + LAllocation *getOperand(size_t index) { 1.5647 + JS_ASSERT(index < numOperands()); 1.5648 + return &inputs_[index]; 1.5649 + } 1.5650 + void setOperand(size_t index, const LAllocation &a) { 1.5651 + JS_ASSERT(index < numOperands()); 1.5652 + inputs_[index] = a; 1.5653 + } 1.5654 + size_t numTemps() const { 1.5655 + return 0; 1.5656 + } 1.5657 + LDefinition *getTemp(size_t index) { 1.5658 + MOZ_ASSUME_UNREACHABLE("no temps"); 1.5659 + } 1.5660 + void setTemp(size_t index, const LDefinition &temp) { 1.5661 + MOZ_ASSUME_UNREACHABLE("no temps"); 1.5662 + } 1.5663 + size_t numSuccessors() const { 1.5664 + return 0; 1.5665 + } 1.5666 + MBasicBlock *getSuccessor(size_t i) const { 1.5667 + MOZ_ASSUME_UNREACHABLE("no successors"); 1.5668 + } 1.5669 + void setSuccessor(size_t i, MBasicBlock *) { 1.5670 + MOZ_ASSUME_UNREACHABLE("no successors"); 1.5671 + } 1.5672 + 1.5673 + virtual void printInfo(FILE *fp) { 1.5674 + printOperands(fp); 1.5675 + } 1.5676 +}; 1.5677 + 1.5678 +class LIn : public LCallInstructionHelper<1, BOX_PIECES+1, 0> 1.5679 +{ 1.5680 + public: 1.5681 + LIR_HEADER(In) 1.5682 + LIn(const LAllocation &rhs) { 1.5683 + setOperand(RHS, rhs); 1.5684 + } 1.5685 + 1.5686 + const LAllocation *lhs() { 1.5687 + return getOperand(LHS); 1.5688 + } 1.5689 + const LAllocation *rhs() { 1.5690 + return getOperand(RHS); 1.5691 + } 1.5692 + 1.5693 + static const size_t LHS = 0; 1.5694 + static const size_t RHS = BOX_PIECES; 1.5695 +}; 1.5696 + 1.5697 +class LInstanceOfO : public LInstructionHelper<1, 1, 0> 1.5698 +{ 1.5699 + public: 1.5700 + LIR_HEADER(InstanceOfO) 1.5701 + LInstanceOfO(const LAllocation &lhs) { 1.5702 + setOperand(0, lhs); 1.5703 + } 1.5704 + 1.5705 + MInstanceOf *mir() const { 1.5706 + return mir_->toInstanceOf(); 1.5707 + } 1.5708 + 1.5709 + const LAllocation *lhs() { 1.5710 + return getOperand(0); 1.5711 + } 1.5712 +}; 1.5713 + 1.5714 +class LInstanceOfV : public LInstructionHelper<1, BOX_PIECES, 0> 1.5715 +{ 1.5716 + public: 1.5717 + LIR_HEADER(InstanceOfV) 1.5718 + LInstanceOfV() { 1.5719 + } 1.5720 + 1.5721 + MInstanceOf *mir() const { 1.5722 + return mir_->toInstanceOf(); 1.5723 + } 1.5724 + 1.5725 + const LAllocation *lhs() { 1.5726 + return getOperand(LHS); 1.5727 + } 1.5728 + 1.5729 + static const size_t LHS = 0; 1.5730 +}; 1.5731 + 1.5732 +class LCallInstanceOf : public LCallInstructionHelper<1, BOX_PIECES+1, 0> 1.5733 +{ 1.5734 + public: 1.5735 + LIR_HEADER(CallInstanceOf) 1.5736 + LCallInstanceOf(const LAllocation &rhs) { 1.5737 + setOperand(RHS, rhs); 1.5738 + } 1.5739 + 1.5740 + const LDefinition *output() { 1.5741 + return this->getDef(0); 1.5742 + } 1.5743 + const LAllocation *lhs() { 1.5744 + return getOperand(LHS); 1.5745 + } 1.5746 + const LAllocation *rhs() { 1.5747 + return getOperand(RHS); 1.5748 + } 1.5749 + 1.5750 + static const size_t LHS = 0; 1.5751 + static const size_t RHS = BOX_PIECES; 1.5752 +}; 1.5753 + 1.5754 +class LProfilerStackOp : public LInstructionHelper<0, 0, 1> 1.5755 +{ 1.5756 + public: 1.5757 + LIR_HEADER(ProfilerStackOp) 1.5758 + 1.5759 + LProfilerStackOp(const LDefinition &temp) { 1.5760 + setTemp(0, temp); 1.5761 + } 1.5762 + 1.5763 + const LDefinition *temp() { 1.5764 + return getTemp(0); 1.5765 + } 1.5766 + 1.5767 + JSScript *script() { 1.5768 + return mir_->toProfilerStackOp()->script(); 1.5769 + } 1.5770 + 1.5771 + MProfilerStackOp::Type type() { 1.5772 + return mir_->toProfilerStackOp()->type(); 1.5773 + } 1.5774 + 1.5775 + unsigned inlineLevel() { 1.5776 + return mir_->toProfilerStackOp()->inlineLevel(); 1.5777 + } 1.5778 +}; 1.5779 + 1.5780 +class LIsCallable : public LInstructionHelper<1, 1, 0> 1.5781 +{ 1.5782 + public: 1.5783 + LIR_HEADER(IsCallable); 1.5784 + LIsCallable(const LAllocation &object) { 1.5785 + setOperand(0, object); 1.5786 + } 1.5787 + 1.5788 + const LAllocation *object() { 1.5789 + return getOperand(0); 1.5790 + } 1.5791 + MIsCallable *mir() const { 1.5792 + return mir_->toIsCallable(); 1.5793 + } 1.5794 +}; 1.5795 + 1.5796 +class LHaveSameClass : public LInstructionHelper<1, 2, 1> 1.5797 +{ 1.5798 + public: 1.5799 + LIR_HEADER(HaveSameClass); 1.5800 + LHaveSameClass(const LAllocation &left, const LAllocation &right, 1.5801 + const LDefinition &temp) { 1.5802 + setOperand(0, left); 1.5803 + setOperand(1, right); 1.5804 + setTemp(0, temp); 1.5805 + } 1.5806 + 1.5807 + const LAllocation *lhs() { 1.5808 + return getOperand(0); 1.5809 + } 1.5810 + const LAllocation *rhs() { 1.5811 + return getOperand(1); 1.5812 + } 1.5813 + MHaveSameClass *mir() const { 1.5814 + return mir_->toHaveSameClass(); 1.5815 + } 1.5816 +}; 1.5817 + 1.5818 +class LHasClass : public LInstructionHelper<1, 1, 0> 1.5819 +{ 1.5820 + public: 1.5821 + LIR_HEADER(HasClass); 1.5822 + LHasClass(const LAllocation &lhs) { 1.5823 + setOperand(0, lhs); 1.5824 + } 1.5825 + 1.5826 + const LAllocation *lhs() { 1.5827 + return getOperand(0); 1.5828 + } 1.5829 + MHasClass *mir() const { 1.5830 + return mir_->toHasClass(); 1.5831 + } 1.5832 +}; 1.5833 + 1.5834 +class LAsmJSLoadHeap : public LInstructionHelper<1, 1, 0> 1.5835 +{ 1.5836 + public: 1.5837 + LIR_HEADER(AsmJSLoadHeap); 1.5838 + LAsmJSLoadHeap(const LAllocation &ptr) { 1.5839 + setOperand(0, ptr); 1.5840 + } 1.5841 + MAsmJSLoadHeap *mir() const { 1.5842 + return mir_->toAsmJSLoadHeap(); 1.5843 + } 1.5844 + const LAllocation *ptr() { 1.5845 + return getOperand(0); 1.5846 + } 1.5847 +}; 1.5848 + 1.5849 +class LAsmJSStoreHeap : public LInstructionHelper<0, 2, 0> 1.5850 +{ 1.5851 + public: 1.5852 + LIR_HEADER(AsmJSStoreHeap); 1.5853 + LAsmJSStoreHeap(const LAllocation &ptr, const LAllocation &value) { 1.5854 + setOperand(0, ptr); 1.5855 + setOperand(1, value); 1.5856 + } 1.5857 + MAsmJSStoreHeap *mir() const { 1.5858 + return mir_->toAsmJSStoreHeap(); 1.5859 + } 1.5860 + const LAllocation *ptr() { 1.5861 + return getOperand(0); 1.5862 + } 1.5863 + const LAllocation *value() { 1.5864 + return getOperand(1); 1.5865 + } 1.5866 +}; 1.5867 + 1.5868 +class LAsmJSLoadGlobalVar : public LInstructionHelper<1, 0, 0> 1.5869 +{ 1.5870 + public: 1.5871 + LIR_HEADER(AsmJSLoadGlobalVar); 1.5872 + MAsmJSLoadGlobalVar *mir() const { 1.5873 + return mir_->toAsmJSLoadGlobalVar(); 1.5874 + } 1.5875 +}; 1.5876 + 1.5877 +class LAsmJSStoreGlobalVar : public LInstructionHelper<0, 1, 0> 1.5878 +{ 1.5879 + public: 1.5880 + LIR_HEADER(AsmJSStoreGlobalVar); 1.5881 + LAsmJSStoreGlobalVar(const LAllocation &value) { 1.5882 + setOperand(0, value); 1.5883 + } 1.5884 + MAsmJSStoreGlobalVar *mir() const { 1.5885 + return mir_->toAsmJSStoreGlobalVar(); 1.5886 + } 1.5887 + const LAllocation *value() { 1.5888 + return getOperand(0); 1.5889 + } 1.5890 +}; 1.5891 + 1.5892 +class LAsmJSLoadFFIFunc : public LInstructionHelper<1, 0, 0> 1.5893 +{ 1.5894 + public: 1.5895 + LIR_HEADER(AsmJSLoadFFIFunc); 1.5896 + MAsmJSLoadFFIFunc *mir() const { 1.5897 + return mir_->toAsmJSLoadFFIFunc(); 1.5898 + } 1.5899 +}; 1.5900 + 1.5901 +class LAsmJSParameter : public LInstructionHelper<1, 0, 0> 1.5902 +{ 1.5903 + public: 1.5904 + LIR_HEADER(AsmJSParameter); 1.5905 +}; 1.5906 + 1.5907 +class LAsmJSReturn : public LInstructionHelper<0, 1, 0> 1.5908 +{ 1.5909 + public: 1.5910 + LIR_HEADER(AsmJSReturn); 1.5911 +}; 1.5912 + 1.5913 +class LAsmJSVoidReturn : public LInstructionHelper<0, 0, 0> 1.5914 +{ 1.5915 + public: 1.5916 + LIR_HEADER(AsmJSVoidReturn); 1.5917 +}; 1.5918 + 1.5919 +class LAsmJSPassStackArg : public LInstructionHelper<0, 1, 0> 1.5920 +{ 1.5921 + public: 1.5922 + LIR_HEADER(AsmJSPassStackArg); 1.5923 + LAsmJSPassStackArg(const LAllocation &arg) { 1.5924 + setOperand(0, arg); 1.5925 + } 1.5926 + MAsmJSPassStackArg *mir() const { 1.5927 + return mirRaw()->toAsmJSPassStackArg(); 1.5928 + } 1.5929 + const LAllocation *arg() { 1.5930 + return getOperand(0); 1.5931 + } 1.5932 +}; 1.5933 + 1.5934 +class LAsmJSCall MOZ_FINAL : public LInstruction 1.5935 +{ 1.5936 + LAllocation *operands_; 1.5937 + uint32_t numOperands_; 1.5938 + LDefinition def_; 1.5939 + 1.5940 + public: 1.5941 + LIR_HEADER(AsmJSCall); 1.5942 + 1.5943 + LAsmJSCall(LAllocation *operands, uint32_t numOperands) 1.5944 + : operands_(operands), 1.5945 + numOperands_(numOperands), 1.5946 + def_(LDefinition::BogusTemp()) 1.5947 + {} 1.5948 + 1.5949 + MAsmJSCall *mir() const { 1.5950 + return mir_->toAsmJSCall(); 1.5951 + } 1.5952 + 1.5953 + bool isCall() const { 1.5954 + return true; 1.5955 + } 1.5956 + 1.5957 + // LInstruction interface 1.5958 + size_t numDefs() const { 1.5959 + return def_.isBogusTemp() ? 0 : 1; 1.5960 + } 1.5961 + LDefinition *getDef(size_t index) { 1.5962 + JS_ASSERT(numDefs() == 1); 1.5963 + JS_ASSERT(index == 0); 1.5964 + return &def_; 1.5965 + } 1.5966 + void setDef(size_t index, const LDefinition &def) { 1.5967 + JS_ASSERT(index == 0); 1.5968 + def_ = def; 1.5969 + } 1.5970 + size_t numOperands() const { 1.5971 + return numOperands_; 1.5972 + } 1.5973 + LAllocation *getOperand(size_t index) { 1.5974 + JS_ASSERT(index < numOperands_); 1.5975 + return &operands_[index]; 1.5976 + } 1.5977 + void setOperand(size_t index, const LAllocation &a) { 1.5978 + JS_ASSERT(index < numOperands_); 1.5979 + operands_[index] = a; 1.5980 + } 1.5981 + size_t numTemps() const { 1.5982 + return 0; 1.5983 + } 1.5984 + LDefinition *getTemp(size_t index) { 1.5985 + MOZ_ASSUME_UNREACHABLE("no temps"); 1.5986 + } 1.5987 + void setTemp(size_t index, const LDefinition &a) { 1.5988 + MOZ_ASSUME_UNREACHABLE("no temps"); 1.5989 + } 1.5990 + size_t numSuccessors() const { 1.5991 + return 0; 1.5992 + } 1.5993 + MBasicBlock *getSuccessor(size_t i) const { 1.5994 + MOZ_ASSUME_UNREACHABLE("no successors"); 1.5995 + } 1.5996 + void setSuccessor(size_t i, MBasicBlock *) { 1.5997 + MOZ_ASSUME_UNREACHABLE("no successors"); 1.5998 + } 1.5999 +}; 1.6000 + 1.6001 +class LAssertRangeI : public LInstructionHelper<0, 1, 0> 1.6002 +{ 1.6003 + public: 1.6004 + LIR_HEADER(AssertRangeI) 1.6005 + 1.6006 + LAssertRangeI(const LAllocation &input) { 1.6007 + setOperand(0, input); 1.6008 + } 1.6009 + 1.6010 + const LAllocation *input() { 1.6011 + return getOperand(0); 1.6012 + } 1.6013 + 1.6014 + MAssertRange *mir() { 1.6015 + return mir_->toAssertRange(); 1.6016 + } 1.6017 + const Range *range() { 1.6018 + return mir()->assertedRange(); 1.6019 + } 1.6020 +}; 1.6021 + 1.6022 +class LAssertRangeD : public LInstructionHelper<0, 1, 1> 1.6023 +{ 1.6024 + public: 1.6025 + LIR_HEADER(AssertRangeD) 1.6026 + 1.6027 + LAssertRangeD(const LAllocation &input, const LDefinition &temp) { 1.6028 + setOperand(0, input); 1.6029 + setTemp(0, temp); 1.6030 + } 1.6031 + 1.6032 + const LAllocation *input() { 1.6033 + return getOperand(0); 1.6034 + } 1.6035 + 1.6036 + const LDefinition *temp() { 1.6037 + return getTemp(0); 1.6038 + } 1.6039 + 1.6040 + MAssertRange *mir() { 1.6041 + return mir_->toAssertRange(); 1.6042 + } 1.6043 + const Range *range() { 1.6044 + return mir()->assertedRange(); 1.6045 + } 1.6046 +}; 1.6047 + 1.6048 +class LAssertRangeF : public LInstructionHelper<0, 1, 1> 1.6049 +{ 1.6050 + public: 1.6051 + LIR_HEADER(AssertRangeF) 1.6052 + 1.6053 + LAssertRangeF(const LAllocation &input, const LDefinition &temp) { 1.6054 + setOperand(0, input); 1.6055 + setTemp(0, temp); 1.6056 + } 1.6057 + 1.6058 + const LAllocation *input() { 1.6059 + return getOperand(0); 1.6060 + } 1.6061 + 1.6062 + const LDefinition *temp() { 1.6063 + return getTemp(0); 1.6064 + } 1.6065 + 1.6066 + MAssertRange *mir() { 1.6067 + return mir_->toAssertRange(); 1.6068 + } 1.6069 + const Range *range() { 1.6070 + return mir()->assertedRange(); 1.6071 + } 1.6072 +}; 1.6073 + 1.6074 +class LAssertRangeV : public LInstructionHelper<0, BOX_PIECES, 3> 1.6075 +{ 1.6076 + public: 1.6077 + LIR_HEADER(AssertRangeV) 1.6078 + 1.6079 + LAssertRangeV(const LDefinition &temp, const LDefinition &floatTemp1, 1.6080 + const LDefinition &floatTemp2) 1.6081 + { 1.6082 + setTemp(0, temp); 1.6083 + setTemp(1, floatTemp1); 1.6084 + setTemp(2, floatTemp2); 1.6085 + } 1.6086 + 1.6087 + static const size_t Input = 0; 1.6088 + 1.6089 + const LDefinition *temp() { 1.6090 + return getTemp(0); 1.6091 + } 1.6092 + const LDefinition *floatTemp1() { 1.6093 + return getTemp(1); 1.6094 + } 1.6095 + const LDefinition *floatTemp2() { 1.6096 + return getTemp(2); 1.6097 + } 1.6098 + 1.6099 + MAssertRange *mir() { 1.6100 + return mir_->toAssertRange(); 1.6101 + } 1.6102 + const Range *range() { 1.6103 + return mir()->assertedRange(); 1.6104 + } 1.6105 +}; 1.6106 + 1.6107 +class LRecompileCheck : public LInstructionHelper<0, 0, 1> 1.6108 +{ 1.6109 + public: 1.6110 + LIR_HEADER(RecompileCheck) 1.6111 + 1.6112 + LRecompileCheck(const LDefinition &scratch) { 1.6113 + setTemp(0, scratch); 1.6114 + } 1.6115 + 1.6116 + const LDefinition *scratch() { 1.6117 + return getTemp(0); 1.6118 + } 1.6119 + MRecompileCheck *mir() { 1.6120 + return mir_->toRecompileCheck(); 1.6121 + } 1.6122 +}; 1.6123 + 1.6124 +} // namespace jit 1.6125 +} // namespace js 1.6126 + 1.6127 +#endif /* jit_LIR_Common_h */