RegExpExec/RegExpTest should not unconditionally speculate cell
[WebKit-https.git] / Source / JavaScriptCore / ftl / FTLLowerDFGToB3.cpp
1 /*
2  * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "FTLLowerDFGToB3.h"
28
29 #if ENABLE(FTL_JIT)
30
31 #include "AirGenerationContext.h"
32 #include "AllowMacroScratchRegisterUsage.h"
33 #include "B3StackmapGenerationParams.h"
34 #include "CallFrameShuffler.h"
35 #include "CodeBlockWithJITType.h"
36 #include "DFGAbstractInterpreterInlines.h"
37 #include "DFGDominators.h"
38 #include "DFGInPlaceAbstractState.h"
39 #include "DFGOSRAvailabilityAnalysisPhase.h"
40 #include "DFGOSRExitFuzz.h"
41 #include "DirectArguments.h"
42 #include "FTLAbstractHeapRepository.h"
43 #include "FTLAvailableRecovery.h"
44 #include "FTLExceptionTarget.h"
45 #include "FTLForOSREntryJITCode.h"
46 #include "FTLFormattedValue.h"
47 #include "FTLLazySlowPathCall.h"
48 #include "FTLLoweredNodeValue.h"
49 #include "FTLOperations.h"
50 #include "FTLOutput.h"
51 #include "FTLPatchpointExceptionHandle.h"
52 #include "FTLThunks.h"
53 #include "FTLWeightedTarget.h"
54 #include "JITAddGenerator.h"
55 #include "JITBitAndGenerator.h"
56 #include "JITBitOrGenerator.h"
57 #include "JITBitXorGenerator.h"
58 #include "JITDivGenerator.h"
59 #include "JITInlineCacheGenerator.h"
60 #include "JITLeftShiftGenerator.h"
61 #include "JITMulGenerator.h"
62 #include "JITRightShiftGenerator.h"
63 #include "JITSubGenerator.h"
64 #include "JSCInlines.h"
65 #include "JSGeneratorFunction.h"
66 #include "JSLexicalEnvironment.h"
67 #include "OperandsInlines.h"
68 #include "ScopedArguments.h"
69 #include "ScopedArgumentsTable.h"
70 #include "ScratchRegisterAllocator.h"
71 #include "SetupVarargsFrame.h"
72 #include "VirtualRegister.h"
73 #include "Watchdog.h"
74 #include <atomic>
75 #if !OS(WINDOWS)
76 #include <dlfcn.h>
77 #endif
78 #include <unordered_set>
79 #include <wtf/Box.h>
80 #include <wtf/ProcessID.h>
81
82 namespace JSC { namespace FTL {
83
84 using namespace B3;
85 using namespace DFG;
86
87 namespace {
88
89 std::atomic<int> compileCounter;
90
91 #if ASSERT_DISABLED
92 NO_RETURN_DUE_TO_CRASH static void ftlUnreachable()
93 {
94     CRASH();
95 }
96 #else
97 NO_RETURN_DUE_TO_CRASH static void ftlUnreachable(
98     CodeBlock* codeBlock, BlockIndex blockIndex, unsigned nodeIndex)
99 {
100     dataLog("Crashing in thought-to-be-unreachable FTL-generated code for ", pointerDump(codeBlock), " at basic block #", blockIndex);
101     if (nodeIndex != UINT_MAX)
102         dataLog(", node @", nodeIndex);
103     dataLog(".\n");
104     CRASH();
105 }
106 #endif
107
108 // Using this instead of typeCheck() helps to reduce the load on B3, by creating
109 // significantly less dead code.
110 #define FTL_TYPE_CHECK_WITH_EXIT_KIND(exitKind, lowValue, highValue, typesPassedThrough, failCondition) do { \
111         FormattedValue _ftc_lowValue = (lowValue);                      \
112         Edge _ftc_highValue = (highValue);                              \
113         SpeculatedType _ftc_typesPassedThrough = (typesPassedThrough);  \
114         if (!m_interpreter.needsTypeCheck(_ftc_highValue, _ftc_typesPassedThrough)) \
115             break;                                                      \
116         typeCheck(_ftc_lowValue, _ftc_highValue, _ftc_typesPassedThrough, (failCondition), exitKind); \
117     } while (false)
118
119 #define FTL_TYPE_CHECK(lowValue, highValue, typesPassedThrough, failCondition) \
120     FTL_TYPE_CHECK_WITH_EXIT_KIND(BadType, lowValue, highValue, typesPassedThrough, failCondition)
121
122 class LowerDFGToB3 {
123     WTF_MAKE_NONCOPYABLE(LowerDFGToB3);
124 public:
125     LowerDFGToB3(State& state)
126         : m_graph(state.graph)
127         , m_ftlState(state)
128         , m_out(state)
129         , m_proc(*state.proc)
130         , m_state(state.graph)
131         , m_interpreter(state.graph, m_state)
132     {
133     }
134     
135     void lower()
136     {
137         State* state = &m_ftlState;
138         
139         CString name;
140         if (verboseCompilationEnabled()) {
141             name = toCString(
142                 "jsBody_", ++compileCounter, "_", codeBlock()->inferredName(),
143                 "_", codeBlock()->hash());
144         } else
145             name = "jsBody";
146         
147         m_graph.ensureDominators();
148
149         if (verboseCompilationEnabled())
150             dataLog("Function ready, beginning lowering.\n");
151
152         m_out.initialize(m_heaps);
153
154         // We use prologue frequency for all of the initialization code.
155         m_out.setFrequency(1);
156         
157         m_prologue = FTL_NEW_BLOCK(m_out, ("Prologue"));
158         LBasicBlock stackOverflow = FTL_NEW_BLOCK(m_out, ("Stack overflow"));
159         m_handleExceptions = FTL_NEW_BLOCK(m_out, ("Handle Exceptions"));
160         
161         LBasicBlock checkArguments = FTL_NEW_BLOCK(m_out, ("Check arguments"));
162
163         for (BlockIndex blockIndex = 0; blockIndex < m_graph.numBlocks(); ++blockIndex) {
164             m_highBlock = m_graph.block(blockIndex);
165             if (!m_highBlock)
166                 continue;
167             m_out.setFrequency(m_highBlock->executionCount);
168             m_blocks.add(m_highBlock, FTL_NEW_BLOCK(m_out, ("Block ", *m_highBlock)));
169         }
170
171         // Back to prologue frequency for any bocks that get sneakily created in the initialization code.
172         m_out.setFrequency(1);
173         
174         m_out.appendTo(m_prologue, stackOverflow);
175         m_out.initializeConstants(m_proc, m_prologue);
176         createPhiVariables();
177
178         size_t sizeOfCaptured = sizeof(JSValue) * m_graph.m_nextMachineLocal;
179         B3::SlotBaseValue* capturedBase = m_out.lockedStackSlot(sizeOfCaptured);
180         m_captured = m_out.add(capturedBase, m_out.constIntPtr(sizeOfCaptured));
181         state->capturedValue = capturedBase->slot();
182
183         auto preOrder = m_graph.blocksInPreOrder();
184
185         // We should not create any alloca's after this point, since they will cease to
186         // be mem2reg candidates.
187         
188         m_callFrame = m_out.framePointer();
189         m_tagTypeNumber = m_out.constInt64(TagTypeNumber);
190         m_tagMask = m_out.constInt64(TagMask);
191
192         // Make sure that B3 knows that we really care about the mask registers. This forces the
193         // constants to be materialized in registers.
194         m_proc.addFastConstant(m_tagTypeNumber->key());
195         m_proc.addFastConstant(m_tagMask->key());
196         
197         m_out.storePtr(m_out.constIntPtr(codeBlock()), addressFor(JSStack::CodeBlock));
198         
199         m_out.branch(
200             didOverflowStack(), rarely(stackOverflow), usually(checkArguments));
201         
202         m_out.appendTo(stackOverflow, m_handleExceptions);
203         m_out.call(m_out.voidType, m_out.operation(operationThrowStackOverflowError), m_callFrame, m_out.constIntPtr(codeBlock()));
204         m_out.patchpoint(Void)->setGenerator(
205             [=] (CCallHelpers& jit, const StackmapGenerationParams&) {
206                 // We are terminal, so we can clobber everything. That's why we don't claim to
207                 // clobber scratch.
208                 AllowMacroScratchRegisterUsage allowScratch(jit);
209                 
210                 jit.copyCalleeSavesToVMCalleeSavesBuffer();
211                 jit.move(CCallHelpers::TrustedImmPtr(jit.vm()), GPRInfo::argumentGPR0);
212                 jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
213                 CCallHelpers::Call call = jit.call();
214                 jit.jumpToExceptionHandler();
215
216                 jit.addLinkTask(
217                     [=] (LinkBuffer& linkBuffer) {
218                         linkBuffer.link(call, FunctionPtr(lookupExceptionHandlerFromCallerFrame));
219                     });
220             });
221         m_out.unreachable();
222         
223         m_out.appendTo(m_handleExceptions, checkArguments);
224         Box<CCallHelpers::Label> exceptionHandler = state->exceptionHandler;
225         m_out.patchpoint(Void)->setGenerator(
226             [=] (CCallHelpers& jit, const StackmapGenerationParams&) {
227                 CCallHelpers::Jump jump = jit.jump();
228                 jit.addLinkTask(
229                     [=] (LinkBuffer& linkBuffer) {
230                         linkBuffer.link(jump, linkBuffer.locationOf(*exceptionHandler));
231                     });
232             });
233         m_out.unreachable();
234         
235         m_out.appendTo(checkArguments, lowBlock(m_graph.block(0)));
236         availabilityMap().clear();
237         availabilityMap().m_locals = Operands<Availability>(codeBlock()->numParameters(), 0);
238         for (unsigned i = codeBlock()->numParameters(); i--;) {
239             availabilityMap().m_locals.argument(i) =
240                 Availability(FlushedAt(FlushedJSValue, virtualRegisterForArgument(i)));
241         }
242         m_node = nullptr;
243         m_origin = NodeOrigin(CodeOrigin(0), CodeOrigin(0), true);
244         for (unsigned i = codeBlock()->numParameters(); i--;) {
245             Node* node = m_graph.m_arguments[i];
246             VirtualRegister operand = virtualRegisterForArgument(i);
247             
248             LValue jsValue = m_out.load64(addressFor(operand));
249             
250             if (node) {
251                 DFG_ASSERT(m_graph, node, operand == node->stackAccessData()->machineLocal);
252                 
253                 // This is a hack, but it's an effective one. It allows us to do CSE on the
254                 // primordial load of arguments. This assumes that the GetLocal that got put in
255                 // place of the original SetArgument doesn't have any effects before it. This
256                 // should hold true.
257                 m_loadedArgumentValues.add(node, jsValue);
258             }
259             
260             switch (m_graph.m_argumentFormats[i]) {
261             case FlushedInt32:
262                 speculate(BadType, jsValueValue(jsValue), node, isNotInt32(jsValue));
263                 break;
264             case FlushedBoolean:
265                 speculate(BadType, jsValueValue(jsValue), node, isNotBoolean(jsValue));
266                 break;
267             case FlushedCell:
268                 speculate(BadType, jsValueValue(jsValue), node, isNotCell(jsValue));
269                 break;
270             case FlushedJSValue:
271                 break;
272             default:
273                 DFG_CRASH(m_graph, node, "Bad flush format for argument");
274                 break;
275             }
276         }
277         m_out.jump(lowBlock(m_graph.block(0)));
278         
279         for (DFG::BasicBlock* block : preOrder)
280             compileBlock(block);
281
282         // Make sure everything is decorated. This does a bunch of deferred decorating. This has
283         // to happen last because our abstract heaps are generated lazily. They have to be
284         // generated lazily because we have an infiniten number of numbered, indexed, and
285         // absolute heaps. We only become aware of the ones we actually mention while lowering.
286         m_heaps.computeRangesAndDecorateInstructions();
287
288         // We create all Phi's up front, but we may then decide not to compile the basic block
289         // that would have contained one of them. So this creates orphans, which triggers B3
290         // validation failures. Calling this fixes the issue.
291         //
292         // Note that you should avoid the temptation to make this call conditional upon
293         // validation being enabled. B3 makes no guarantees of any kind of correctness when
294         // dealing with IR that would have failed validation. For example, it would be valid to
295         // write a B3 phase that so aggressively assumes the lack of orphans that it would crash
296         // if any orphans were around. We might even have such phases already.
297         m_proc.deleteOrphans();
298
299         // We put the blocks into the B3 procedure in a super weird order. Now we reorder them.
300         m_out.applyBlockOrder();
301     }
302
303 private:
304     
305     void createPhiVariables()
306     {
307         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
308             DFG::BasicBlock* block = m_graph.block(blockIndex);
309             if (!block)
310                 continue;
311             for (unsigned nodeIndex = block->size(); nodeIndex--;) {
312                 Node* node = block->at(nodeIndex);
313                 if (node->op() != DFG::Phi)
314                     continue;
315                 LType type;
316                 switch (node->flags() & NodeResultMask) {
317                 case NodeResultDouble:
318                     type = m_out.doubleType;
319                     break;
320                 case NodeResultInt32:
321                     type = m_out.int32;
322                     break;
323                 case NodeResultInt52:
324                     type = m_out.int64;
325                     break;
326                 case NodeResultBoolean:
327                     type = m_out.boolean;
328                     break;
329                 case NodeResultJS:
330                     type = m_out.int64;
331                     break;
332                 default:
333                     DFG_CRASH(m_graph, node, "Bad Phi node result type");
334                     break;
335                 }
336                 m_phis.add(node, m_proc.add<Value>(B3::Phi, type, Origin(node)));
337             }
338         }
339     }
340     
341     void compileBlock(DFG::BasicBlock* block)
342     {
343         if (!block)
344             return;
345         
346         if (verboseCompilationEnabled())
347             dataLog("Compiling block ", *block, "\n");
348         
349         m_highBlock = block;
350         
351         // Make sure that any blocks created while lowering code in the high block have the frequency of
352         // the high block. This is appropriate because B3 doesn't need precise frequencies. It just needs
353         // something roughly approximate for things like register allocation.
354         m_out.setFrequency(m_highBlock->executionCount);
355         
356         LBasicBlock lowBlock = m_blocks.get(m_highBlock);
357         
358         m_nextHighBlock = 0;
359         for (BlockIndex nextBlockIndex = m_highBlock->index + 1; nextBlockIndex < m_graph.numBlocks(); ++nextBlockIndex) {
360             m_nextHighBlock = m_graph.block(nextBlockIndex);
361             if (m_nextHighBlock)
362                 break;
363         }
364         m_nextLowBlock = m_nextHighBlock ? m_blocks.get(m_nextHighBlock) : 0;
365         
366         // All of this effort to find the next block gives us the ability to keep the
367         // generated IR in roughly program order. This ought not affect the performance
368         // of the generated code (since we expect B3 to reorder things) but it will
369         // make IR dumps easier to read.
370         m_out.appendTo(lowBlock, m_nextLowBlock);
371         
372         if (Options::ftlCrashes())
373             m_out.trap();
374         
375         if (!m_highBlock->cfaHasVisited) {
376             if (verboseCompilationEnabled())
377                 dataLog("Bailing because CFA didn't reach.\n");
378             crash(m_highBlock->index, UINT_MAX);
379             return;
380         }
381         
382         m_availabilityCalculator.beginBlock(m_highBlock);
383         
384         m_state.reset();
385         m_state.beginBasicBlock(m_highBlock);
386         
387         for (m_nodeIndex = 0; m_nodeIndex < m_highBlock->size(); ++m_nodeIndex) {
388             if (!compileNode(m_nodeIndex))
389                 break;
390         }
391     }
392
393     void safelyInvalidateAfterTermination()
394     {
395         if (verboseCompilationEnabled())
396             dataLog("Bailing.\n");
397         crash();
398
399         // Invalidate dominated blocks. Under normal circumstances we would expect
400         // them to be invalidated already. But you can have the CFA become more
401         // precise over time because the structures of objects change on the main
402         // thread. Failing to do this would result in weird crashes due to a value
403         // being used but not defined. Race conditions FTW!
404         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
405             DFG::BasicBlock* target = m_graph.block(blockIndex);
406             if (!target)
407                 continue;
408             if (m_graph.m_dominators->dominates(m_highBlock, target)) {
409                 if (verboseCompilationEnabled())
410                     dataLog("Block ", *target, " will bail also.\n");
411                 target->cfaHasVisited = false;
412             }
413         }
414     }
415
416     bool compileNode(unsigned nodeIndex)
417     {
418         if (!m_state.isValid()) {
419             safelyInvalidateAfterTermination();
420             return false;
421         }
422         
423         m_node = m_highBlock->at(nodeIndex);
424         m_origin = m_node->origin;
425         m_out.setOrigin(m_node);
426         
427         if (verboseCompilationEnabled())
428             dataLog("Lowering ", m_node, "\n");
429         
430         m_availableRecoveries.resize(0);
431         
432         m_interpreter.startExecuting();
433         
434         switch (m_node->op()) {
435         case DFG::Upsilon:
436             compileUpsilon();
437             break;
438         case DFG::Phi:
439             compilePhi();
440             break;
441         case JSConstant:
442             break;
443         case DoubleConstant:
444             compileDoubleConstant();
445             break;
446         case Int52Constant:
447             compileInt52Constant();
448             break;
449         case DoubleRep:
450             compileDoubleRep();
451             break;
452         case DoubleAsInt32:
453             compileDoubleAsInt32();
454             break;
455         case DFG::ValueRep:
456             compileValueRep();
457             break;
458         case Int52Rep:
459             compileInt52Rep();
460             break;
461         case ValueToInt32:
462             compileValueToInt32();
463             break;
464         case BooleanToNumber:
465             compileBooleanToNumber();
466             break;
467         case ExtractOSREntryLocal:
468             compileExtractOSREntryLocal();
469             break;
470         case GetStack:
471             compileGetStack();
472             break;
473         case PutStack:
474             compilePutStack();
475             break;
476         case DFG::Check:
477             compileNoOp();
478             break;
479         case ToThis:
480             compileToThis();
481             break;
482         case ValueAdd:
483             compileValueAdd();
484             break;
485         case StrCat:
486             compileStrCat();
487             break;
488         case ArithAdd:
489         case ArithSub:
490             compileArithAddOrSub();
491             break;
492         case ArithClz32:
493             compileArithClz32();
494             break;
495         case ArithMul:
496             compileArithMul();
497             break;
498         case ArithDiv:
499             compileArithDiv();
500             break;
501         case ArithMod:
502             compileArithMod();
503             break;
504         case ArithMin:
505         case ArithMax:
506             compileArithMinOrMax();
507             break;
508         case ArithAbs:
509             compileArithAbs();
510             break;
511         case ArithSin:
512             compileArithSin();
513             break;
514         case ArithCos:
515             compileArithCos();
516             break;
517         case ArithPow:
518             compileArithPow();
519             break;
520         case ArithRandom:
521             compileArithRandom();
522             break;
523         case ArithRound:
524             compileArithRound();
525             break;
526         case ArithFloor:
527             compileArithFloor();
528             break;
529         case ArithCeil:
530             compileArithCeil();
531             break;
532         case ArithSqrt:
533             compileArithSqrt();
534             break;
535         case ArithLog:
536             compileArithLog();
537             break;
538         case ArithFRound:
539             compileArithFRound();
540             break;
541         case ArithNegate:
542             compileArithNegate();
543             break;
544         case DFG::BitAnd:
545             compileBitAnd();
546             break;
547         case DFG::BitOr:
548             compileBitOr();
549             break;
550         case DFG::BitXor:
551             compileBitXor();
552             break;
553         case BitRShift:
554             compileBitRShift();
555             break;
556         case BitLShift:
557             compileBitLShift();
558             break;
559         case BitURShift:
560             compileBitURShift();
561             break;
562         case UInt32ToNumber:
563             compileUInt32ToNumber();
564             break;
565         case CheckStructure:
566             compileCheckStructure();
567             break;
568         case CheckCell:
569             compileCheckCell();
570             break;
571         case CheckNotEmpty:
572             compileCheckNotEmpty();
573             break;
574         case CheckBadCell:
575             compileCheckBadCell();
576             break;
577         case CheckIdent:
578             compileCheckIdent();
579             break;
580         case GetExecutable:
581             compileGetExecutable();
582             break;
583         case ArrayifyToStructure:
584             compileArrayifyToStructure();
585             break;
586         case PutStructure:
587             compilePutStructure();
588             break;
589         case GetById:
590         case GetByIdFlush:
591             compileGetById();
592             break;
593         case In:
594             compileIn();
595             break;
596         case PutById:
597         case PutByIdDirect:
598         case PutByIdFlush:
599             compilePutById();
600             break;
601         case PutGetterById:
602         case PutSetterById:
603             compilePutAccessorById();
604             break;
605         case PutGetterSetterById:
606             compilePutGetterSetterById();
607             break;
608         case PutGetterByVal:
609         case PutSetterByVal:
610             compilePutAccessorByVal();
611             break;
612         case GetButterfly:
613             compileGetButterfly();
614             break;
615         case GetButterflyReadOnly:
616             compileGetButterflyReadOnly();
617             break;
618         case ConstantStoragePointer:
619             compileConstantStoragePointer();
620             break;
621         case GetIndexedPropertyStorage:
622             compileGetIndexedPropertyStorage();
623             break;
624         case CheckArray:
625             compileCheckArray();
626             break;
627         case GetArrayLength:
628             compileGetArrayLength();
629             break;
630         case CheckInBounds:
631             compileCheckInBounds();
632             break;
633         case GetByVal:
634             compileGetByVal();
635             break;
636         case GetMyArgumentByVal:
637             compileGetMyArgumentByVal();
638             break;
639         case PutByVal:
640         case PutByValAlias:
641         case PutByValDirect:
642             compilePutByVal();
643             break;
644         case ArrayPush:
645             compileArrayPush();
646             break;
647         case ArrayPop:
648             compileArrayPop();
649             break;
650         case CreateActivation:
651             compileCreateActivation();
652             break;
653         case NewFunction:
654         case NewArrowFunction:
655         case NewGeneratorFunction:
656             compileNewFunction();
657             break;
658         case CreateDirectArguments:
659             compileCreateDirectArguments();
660             break;
661         case CreateScopedArguments:
662             compileCreateScopedArguments();
663             break;
664         case CreateClonedArguments:
665             compileCreateClonedArguments();
666             break;
667         case NewObject:
668             compileNewObject();
669             break;
670         case NewArray:
671             compileNewArray();
672             break;
673         case NewArrayBuffer:
674             compileNewArrayBuffer();
675             break;
676         case NewArrayWithSize:
677             compileNewArrayWithSize();
678             break;
679         case NewTypedArray:
680             compileNewTypedArray();
681             break;
682         case GetTypedArrayByteOffset:
683             compileGetTypedArrayByteOffset();
684             break;
685         case AllocatePropertyStorage:
686             compileAllocatePropertyStorage();
687             break;
688         case ReallocatePropertyStorage:
689             compileReallocatePropertyStorage();
690             break;
691         case ToString:
692         case CallStringConstructor:
693             compileToStringOrCallStringConstructor();
694             break;
695         case ToPrimitive:
696             compileToPrimitive();
697             break;
698         case MakeRope:
699             compileMakeRope();
700             break;
701         case StringCharAt:
702             compileStringCharAt();
703             break;
704         case StringCharCodeAt:
705             compileStringCharCodeAt();
706             break;
707         case StringFromCharCode:
708             compileStringFromCharCode();
709             break;
710         case GetByOffset:
711         case GetGetterSetterByOffset:
712             compileGetByOffset();
713             break;
714         case GetGetter:
715             compileGetGetter();
716             break;
717         case GetSetter:
718             compileGetSetter();
719             break;
720         case MultiGetByOffset:
721             compileMultiGetByOffset();
722             break;
723         case PutByOffset:
724             compilePutByOffset();
725             break;
726         case MultiPutByOffset:
727             compileMultiPutByOffset();
728             break;
729         case GetGlobalVar:
730         case GetGlobalLexicalVariable:
731             compileGetGlobalVariable();
732             break;
733         case PutGlobalVariable:
734             compilePutGlobalVariable();
735             break;
736         case NotifyWrite:
737             compileNotifyWrite();
738             break;
739         case GetCallee:
740             compileGetCallee();
741             break;
742         case GetArgumentCount:
743             compileGetArgumentCount();
744             break;
745         case GetScope:
746             compileGetScope();
747             break;
748         case SkipScope:
749             compileSkipScope();
750             break;
751         case GetClosureVar:
752             compileGetClosureVar();
753             break;
754         case PutClosureVar:
755             compilePutClosureVar();
756             break;
757         case GetFromArguments:
758             compileGetFromArguments();
759             break;
760         case PutToArguments:
761             compilePutToArguments();
762             break;
763         case CompareEq:
764             compileCompareEq();
765             break;
766         case CompareStrictEq:
767             compileCompareStrictEq();
768             break;
769         case CompareLess:
770             compileCompareLess();
771             break;
772         case CompareLessEq:
773             compileCompareLessEq();
774             break;
775         case CompareGreater:
776             compileCompareGreater();
777             break;
778         case CompareGreaterEq:
779             compileCompareGreaterEq();
780             break;
781         case LogicalNot:
782             compileLogicalNot();
783             break;
784         case Call:
785         case TailCallInlinedCaller:
786         case Construct:
787             compileCallOrConstruct();
788             break;
789         case TailCall:
790             compileTailCall();
791             break;
792         case CallVarargs:
793         case CallForwardVarargs:
794         case TailCallVarargs:
795         case TailCallVarargsInlinedCaller:
796         case TailCallForwardVarargs:
797         case TailCallForwardVarargsInlinedCaller:
798         case ConstructVarargs:
799         case ConstructForwardVarargs:
800             compileCallOrConstructVarargs();
801             break;
802         case LoadVarargs:
803             compileLoadVarargs();
804             break;
805         case ForwardVarargs:
806             compileForwardVarargs();
807             break;
808         case DFG::Jump:
809             compileJump();
810             break;
811         case DFG::Branch:
812             compileBranch();
813             break;
814         case DFG::Switch:
815             compileSwitch();
816             break;
817         case DFG::Return:
818             compileReturn();
819             break;
820         case ForceOSRExit:
821             compileForceOSRExit();
822             break;
823         case Throw:
824         case ThrowReferenceError:
825             compileThrow();
826             break;
827         case InvalidationPoint:
828             compileInvalidationPoint();
829             break;
830         case IsUndefined:
831             compileIsUndefined();
832             break;
833         case IsBoolean:
834             compileIsBoolean();
835             break;
836         case IsNumber:
837             compileIsNumber();
838             break;
839         case IsString:
840             compileIsString();
841             break;
842         case IsObject:
843             compileIsObject();
844             break;
845         case IsObjectOrNull:
846             compileIsObjectOrNull();
847             break;
848         case IsFunction:
849             compileIsFunction();
850             break;
851         case TypeOf:
852             compileTypeOf();
853             break;
854         case CheckTypeInfoFlags:
855             compileCheckTypeInfoFlags();
856             break;
857         case OverridesHasInstance:
858             compileOverridesHasInstance();
859             break;
860         case InstanceOf:
861             compileInstanceOf();
862             break;
863         case InstanceOfCustom:
864             compileInstanceOfCustom();
865             break;
866         case CountExecution:
867             compileCountExecution();
868             break;
869         case StoreBarrier:
870             compileStoreBarrier();
871             break;
872         case HasIndexedProperty:
873             compileHasIndexedProperty();
874             break;
875         case HasGenericProperty:
876             compileHasGenericProperty();
877             break;
878         case HasStructureProperty:
879             compileHasStructureProperty();
880             break;
881         case GetDirectPname:
882             compileGetDirectPname();
883             break;
884         case GetEnumerableLength:
885             compileGetEnumerableLength();
886             break;
887         case GetPropertyEnumerator:
888             compileGetPropertyEnumerator();
889             break;
890         case GetEnumeratorStructurePname:
891             compileGetEnumeratorStructurePname();
892             break;
893         case GetEnumeratorGenericPname:
894             compileGetEnumeratorGenericPname();
895             break;
896         case ToIndexString:
897             compileToIndexString();
898             break;
899         case CheckStructureImmediate:
900             compileCheckStructureImmediate();
901             break;
902         case MaterializeNewObject:
903             compileMaterializeNewObject();
904             break;
905         case MaterializeCreateActivation:
906             compileMaterializeCreateActivation();
907             break;
908         case CheckWatchdogTimer:
909             compileCheckWatchdogTimer();
910             break;
911         case CopyRest:
912             compileCopyRest();
913             break;
914         case GetRestLength:
915             compileGetRestLength();
916             break;
917         case RegExpExec:
918             compileRegExpExec();
919             break;
920         case RegExpTest:
921             compileRegExpTest();
922             break;
923         case NewRegexp:
924             compileNewRegexp();
925             break;
926         case StringReplace:
927             compileStringReplace();
928             break;
929
930         case PhantomLocal:
931         case LoopHint:
932         case MovHint:
933         case ZombieHint:
934         case ExitOK:
935         case PhantomNewObject:
936         case PhantomNewFunction:
937         case PhantomNewGeneratorFunction:
938         case PhantomCreateActivation:
939         case PhantomDirectArguments:
940         case PhantomClonedArguments:
941         case PutHint:
942         case BottomValue:
943         case KillStack:
944             break;
945         default:
946             DFG_CRASH(m_graph, m_node, "Unrecognized node in FTL backend");
947             break;
948         }
949         
950         if (m_node->isTerminal())
951             return false;
952         
953         if (!m_state.isValid()) {
954             safelyInvalidateAfterTermination();
955             return false;
956         }
957
958         m_availabilityCalculator.executeNode(m_node);
959         m_interpreter.executeEffects(nodeIndex);
960         
961         return true;
962     }
963
964     void compileUpsilon()
965     {
966         LValue upsilonValue = nullptr;
967         switch (m_node->child1().useKind()) {
968         case DoubleRepUse:
969             upsilonValue = lowDouble(m_node->child1());
970             break;
971         case Int32Use:
972         case KnownInt32Use:
973             upsilonValue = lowInt32(m_node->child1());
974             break;
975         case Int52RepUse:
976             upsilonValue = lowInt52(m_node->child1());
977             break;
978         case BooleanUse:
979         case KnownBooleanUse:
980             upsilonValue = lowBoolean(m_node->child1());
981             break;
982         case CellUse:
983         case KnownCellUse:
984             upsilonValue = lowCell(m_node->child1());
985             break;
986         case UntypedUse:
987             upsilonValue = lowJSValue(m_node->child1());
988             break;
989         default:
990             DFG_CRASH(m_graph, m_node, "Bad use kind");
991             break;
992         }
993         ValueFromBlock upsilon = m_out.anchor(upsilonValue);
994         LValue phiNode = m_phis.get(m_node->phi());
995         m_out.addIncomingToPhi(phiNode, upsilon);
996     }
997     
998     void compilePhi()
999     {
1000         LValue phi = m_phis.get(m_node);
1001         m_out.m_block->append(phi);
1002
1003         switch (m_node->flags() & NodeResultMask) {
1004         case NodeResultDouble:
1005             setDouble(phi);
1006             break;
1007         case NodeResultInt32:
1008             setInt32(phi);
1009             break;
1010         case NodeResultInt52:
1011             setInt52(phi);
1012             break;
1013         case NodeResultBoolean:
1014             setBoolean(phi);
1015             break;
1016         case NodeResultJS:
1017             setJSValue(phi);
1018             break;
1019         default:
1020             DFG_CRASH(m_graph, m_node, "Bad use kind");
1021             break;
1022         }
1023     }
1024     
1025     void compileDoubleConstant()
1026     {
1027         setDouble(m_out.constDouble(m_node->asNumber()));
1028     }
1029     
1030     void compileInt52Constant()
1031     {
1032         int64_t value = m_node->asMachineInt();
1033         
1034         setInt52(m_out.constInt64(value << JSValue::int52ShiftAmount));
1035         setStrictInt52(m_out.constInt64(value));
1036     }
1037
1038     void compileDoubleRep()
1039     {
1040         switch (m_node->child1().useKind()) {
1041         case RealNumberUse: {
1042             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1043             
1044             LValue doubleValue = unboxDouble(value);
1045             
1046             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("DoubleRep RealNumberUse int case"));
1047             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("DoubleRep continuation"));
1048             
1049             ValueFromBlock fastResult = m_out.anchor(doubleValue);
1050             m_out.branch(
1051                 m_out.doubleEqual(doubleValue, doubleValue),
1052                 usually(continuation), rarely(intCase));
1053             
1054             LBasicBlock lastNext = m_out.appendTo(intCase, continuation);
1055             
1056             FTL_TYPE_CHECK(
1057                 jsValueValue(value), m_node->child1(), SpecBytecodeRealNumber,
1058                 isNotInt32(value, provenType(m_node->child1()) & ~SpecFullDouble));
1059             ValueFromBlock slowResult = m_out.anchor(m_out.intToDouble(unboxInt32(value)));
1060             m_out.jump(continuation);
1061             
1062             m_out.appendTo(continuation, lastNext);
1063             
1064             setDouble(m_out.phi(m_out.doubleType, fastResult, slowResult));
1065             return;
1066         }
1067             
1068         case NotCellUse:
1069         case NumberUse: {
1070             bool shouldConvertNonNumber = m_node->child1().useKind() == NotCellUse;
1071             
1072             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
1073
1074             LBasicBlock intCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing int case"));
1075             LBasicBlock doubleTesting = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing double case"));
1076             LBasicBlock doubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing double case"));
1077             LBasicBlock nonDoubleCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing undefined case"));
1078             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("jsValueToDouble unboxing continuation"));
1079             
1080             m_out.branch(
1081                 isNotInt32(value, provenType(m_node->child1())),
1082                 unsure(doubleTesting), unsure(intCase));
1083             
1084             LBasicBlock lastNext = m_out.appendTo(intCase, doubleTesting);
1085             
1086             ValueFromBlock intToDouble = m_out.anchor(
1087                 m_out.intToDouble(unboxInt32(value)));
1088             m_out.jump(continuation);
1089             
1090             m_out.appendTo(doubleTesting, doubleCase);
1091             LValue valueIsNumber = isNumber(value, provenType(m_node->child1()));
1092             m_out.branch(valueIsNumber, usually(doubleCase), rarely(nonDoubleCase));
1093
1094             m_out.appendTo(doubleCase, nonDoubleCase);
1095             ValueFromBlock unboxedDouble = m_out.anchor(unboxDouble(value));
1096             m_out.jump(continuation);
1097
1098             if (shouldConvertNonNumber) {
1099                 LBasicBlock undefinedCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting undefined case"));
1100                 LBasicBlock testNullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing null case"));
1101                 LBasicBlock nullCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble converting null case"));
1102                 LBasicBlock testBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble testing boolean true case"));
1103                 LBasicBlock convertBooleanTrueCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean true case"));
1104                 LBasicBlock convertBooleanFalseCase = FTL_NEW_BLOCK(m_out, ("jsValueToDouble convert boolean false case"));
1105
1106                 m_out.appendTo(nonDoubleCase, undefinedCase);
1107                 LValue valueIsUndefined = m_out.equal(value, m_out.constInt64(ValueUndefined));
1108                 m_out.branch(valueIsUndefined, unsure(undefinedCase), unsure(testNullCase));
1109
1110                 m_out.appendTo(undefinedCase, testNullCase);
1111                 ValueFromBlock convertedUndefined = m_out.anchor(m_out.constDouble(PNaN));
1112                 m_out.jump(continuation);
1113
1114                 m_out.appendTo(testNullCase, nullCase);
1115                 LValue valueIsNull = m_out.equal(value, m_out.constInt64(ValueNull));
1116                 m_out.branch(valueIsNull, unsure(nullCase), unsure(testBooleanTrueCase));
1117
1118                 m_out.appendTo(nullCase, testBooleanTrueCase);
1119                 ValueFromBlock convertedNull = m_out.anchor(m_out.constDouble(0));
1120                 m_out.jump(continuation);
1121
1122                 m_out.appendTo(testBooleanTrueCase, convertBooleanTrueCase);
1123                 LValue valueIsBooleanTrue = m_out.equal(value, m_out.constInt64(ValueTrue));
1124                 m_out.branch(valueIsBooleanTrue, unsure(convertBooleanTrueCase), unsure(convertBooleanFalseCase));
1125
1126                 m_out.appendTo(convertBooleanTrueCase, convertBooleanFalseCase);
1127                 ValueFromBlock convertedTrue = m_out.anchor(m_out.constDouble(1));
1128                 m_out.jump(continuation);
1129
1130                 m_out.appendTo(convertBooleanFalseCase, continuation);
1131
1132                 LValue valueIsNotBooleanFalse = m_out.notEqual(value, m_out.constInt64(ValueFalse));
1133                 FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), ~SpecCell, valueIsNotBooleanFalse);
1134                 ValueFromBlock convertedFalse = m_out.anchor(m_out.constDouble(0));
1135                 m_out.jump(continuation);
1136
1137                 m_out.appendTo(continuation, lastNext);
1138                 setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble, convertedUndefined, convertedNull, convertedTrue, convertedFalse));
1139                 return;
1140             }
1141             m_out.appendTo(nonDoubleCase, continuation);
1142             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecBytecodeNumber, m_out.booleanTrue);
1143             m_out.unreachable();
1144
1145             m_out.appendTo(continuation, lastNext);
1146
1147             setDouble(m_out.phi(m_out.doubleType, intToDouble, unboxedDouble));
1148             return;
1149         }
1150             
1151         case Int52RepUse: {
1152             setDouble(strictInt52ToDouble(lowStrictInt52(m_node->child1())));
1153             return;
1154         }
1155             
1156         default:
1157             DFG_CRASH(m_graph, m_node, "Bad use kind");
1158         }
1159     }
1160
1161     void compileDoubleAsInt32()
1162     {
1163         LValue integerValue = convertDoubleToInt32(lowDouble(m_node->child1()), shouldCheckNegativeZero(m_node->arithMode()));
1164         setInt32(integerValue);
1165     }
1166
1167     void compileValueRep()
1168     {
1169         switch (m_node->child1().useKind()) {
1170         case DoubleRepUse: {
1171             LValue value = lowDouble(m_node->child1());
1172             
1173             if (m_interpreter.needsTypeCheck(m_node->child1(), ~SpecDoubleImpureNaN)) {
1174                 value = m_out.select(
1175                     m_out.doubleEqual(value, value), value, m_out.constDouble(PNaN));
1176             }
1177             
1178             setJSValue(boxDouble(value));
1179             return;
1180         }
1181             
1182         case Int52RepUse: {
1183             setJSValue(strictInt52ToJSValue(lowStrictInt52(m_node->child1())));
1184             return;
1185         }
1186             
1187         default:
1188             DFG_CRASH(m_graph, m_node, "Bad use kind");
1189         }
1190     }
1191     
1192     void compileInt52Rep()
1193     {
1194         switch (m_node->child1().useKind()) {
1195         case Int32Use:
1196             setStrictInt52(m_out.signExt32To64(lowInt32(m_node->child1())));
1197             return;
1198             
1199         case MachineIntUse:
1200             setStrictInt52(
1201                 jsValueToStrictInt52(
1202                     m_node->child1(), lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1203             return;
1204             
1205         case DoubleRepMachineIntUse:
1206             setStrictInt52(
1207                 doubleToStrictInt52(
1208                     m_node->child1(), lowDouble(m_node->child1())));
1209             return;
1210             
1211         default:
1212             RELEASE_ASSERT_NOT_REACHED();
1213         }
1214     }
1215     
1216     void compileValueToInt32()
1217     {
1218         switch (m_node->child1().useKind()) {
1219         case Int52RepUse:
1220             setInt32(m_out.castToInt32(lowStrictInt52(m_node->child1())));
1221             break;
1222             
1223         case DoubleRepUse:
1224             setInt32(doubleToInt32(lowDouble(m_node->child1())));
1225             break;
1226             
1227         case NumberUse:
1228         case NotCellUse: {
1229             LoweredNodeValue value = m_int32Values.get(m_node->child1().node());
1230             if (isValid(value)) {
1231                 setInt32(value.value());
1232                 break;
1233             }
1234             
1235             value = m_jsValueValues.get(m_node->child1().node());
1236             if (isValid(value)) {
1237                 setInt32(numberOrNotCellToInt32(m_node->child1(), value.value()));
1238                 break;
1239             }
1240             
1241             // We'll basically just get here for constants. But it's good to have this
1242             // catch-all since we often add new representations into the mix.
1243             setInt32(
1244                 numberOrNotCellToInt32(
1245                     m_node->child1(),
1246                     lowJSValue(m_node->child1(), ManualOperandSpeculation)));
1247             break;
1248         }
1249             
1250         default:
1251             DFG_CRASH(m_graph, m_node, "Bad use kind");
1252             break;
1253         }
1254     }
1255     
1256     void compileBooleanToNumber()
1257     {
1258         switch (m_node->child1().useKind()) {
1259         case BooleanUse: {
1260             setInt32(m_out.zeroExt(lowBoolean(m_node->child1()), m_out.int32));
1261             return;
1262         }
1263             
1264         case UntypedUse: {
1265             LValue value = lowJSValue(m_node->child1());
1266             
1267             if (!m_interpreter.needsTypeCheck(m_node->child1(), SpecBoolInt32 | SpecBoolean)) {
1268                 setInt32(m_out.bitAnd(m_out.castToInt32(value), m_out.int32One));
1269                 return;
1270             }
1271             
1272             LBasicBlock booleanCase = FTL_NEW_BLOCK(m_out, ("BooleanToNumber boolean case"));
1273             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("BooleanToNumber continuation"));
1274             
1275             ValueFromBlock notBooleanResult = m_out.anchor(value);
1276             m_out.branch(
1277                 isBoolean(value, provenType(m_node->child1())),
1278                 unsure(booleanCase), unsure(continuation));
1279             
1280             LBasicBlock lastNext = m_out.appendTo(booleanCase, continuation);
1281             ValueFromBlock booleanResult = m_out.anchor(m_out.bitOr(
1282                 m_out.zeroExt(unboxBoolean(value), m_out.int64), m_tagTypeNumber));
1283             m_out.jump(continuation);
1284             
1285             m_out.appendTo(continuation, lastNext);
1286             setJSValue(m_out.phi(m_out.int64, booleanResult, notBooleanResult));
1287             return;
1288         }
1289             
1290         default:
1291             RELEASE_ASSERT_NOT_REACHED();
1292             return;
1293         }
1294     }
1295
1296     void compileExtractOSREntryLocal()
1297     {
1298         EncodedJSValue* buffer = static_cast<EncodedJSValue*>(
1299             m_ftlState.jitCode->ftlForOSREntry()->entryBuffer()->dataBuffer());
1300         setJSValue(m_out.load64(m_out.absolute(buffer + m_node->unlinkedLocal().toLocal())));
1301     }
1302     
1303     void compileGetStack()
1304     {
1305         // GetLocals arise only for captured variables and arguments. For arguments, we might have
1306         // already loaded it.
1307         if (LValue value = m_loadedArgumentValues.get(m_node)) {
1308             setJSValue(value);
1309             return;
1310         }
1311         
1312         StackAccessData* data = m_node->stackAccessData();
1313         AbstractValue& value = m_state.variables().operand(data->local);
1314         
1315         DFG_ASSERT(m_graph, m_node, isConcrete(data->format));
1316         DFG_ASSERT(m_graph, m_node, data->format != FlushedDouble); // This just happens to not arise for GetStacks, right now. It would be trivial to support.
1317         
1318         if (isInt32Speculation(value.m_type))
1319             setInt32(m_out.load32(payloadFor(data->machineLocal)));
1320         else
1321             setJSValue(m_out.load64(addressFor(data->machineLocal)));
1322     }
1323     
1324     void compilePutStack()
1325     {
1326         StackAccessData* data = m_node->stackAccessData();
1327         switch (data->format) {
1328         case FlushedJSValue: {
1329             LValue value = lowJSValue(m_node->child1());
1330             m_out.store64(value, addressFor(data->machineLocal));
1331             break;
1332         }
1333             
1334         case FlushedDouble: {
1335             LValue value = lowDouble(m_node->child1());
1336             m_out.storeDouble(value, addressFor(data->machineLocal));
1337             break;
1338         }
1339             
1340         case FlushedInt32: {
1341             LValue value = lowInt32(m_node->child1());
1342             m_out.store32(value, payloadFor(data->machineLocal));
1343             break;
1344         }
1345             
1346         case FlushedInt52: {
1347             LValue value = lowInt52(m_node->child1());
1348             m_out.store64(value, addressFor(data->machineLocal));
1349             break;
1350         }
1351             
1352         case FlushedCell: {
1353             LValue value = lowCell(m_node->child1());
1354             m_out.store64(value, addressFor(data->machineLocal));
1355             break;
1356         }
1357             
1358         case FlushedBoolean: {
1359             speculateBoolean(m_node->child1());
1360             m_out.store64(
1361                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1362                 addressFor(data->machineLocal));
1363             break;
1364         }
1365             
1366         default:
1367             DFG_CRASH(m_graph, m_node, "Bad flush format");
1368             break;
1369         }
1370     }
1371     
1372     void compileNoOp()
1373     {
1374         DFG_NODE_DO_TO_CHILDREN(m_graph, m_node, speculate);
1375     }
1376     
1377     void compileToThis()
1378     {
1379         LValue value = lowJSValue(m_node->child1());
1380         
1381         LBasicBlock isCellCase = FTL_NEW_BLOCK(m_out, ("ToThis is cell case"));
1382         LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ToThis slow case"));
1383         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ToThis continuation"));
1384         
1385         m_out.branch(
1386             isCell(value, provenType(m_node->child1())), usually(isCellCase), rarely(slowCase));
1387         
1388         LBasicBlock lastNext = m_out.appendTo(isCellCase, slowCase);
1389         ValueFromBlock fastResult = m_out.anchor(value);
1390         m_out.branch(isType(value, FinalObjectType), usually(continuation), rarely(slowCase));
1391         
1392         m_out.appendTo(slowCase, continuation);
1393         J_JITOperation_EJ function;
1394         if (m_graph.isStrictModeFor(m_node->origin.semantic))
1395             function = operationToThisStrict;
1396         else
1397             function = operationToThis;
1398         ValueFromBlock slowResult = m_out.anchor(
1399             vmCall(m_out.int64, m_out.operation(function), m_callFrame, value));
1400         m_out.jump(continuation);
1401         
1402         m_out.appendTo(continuation, lastNext);
1403         setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
1404     }
1405     
1406     void compileValueAdd()
1407     {
1408         emitBinarySnippet<JITAddGenerator>(operationValueAdd);
1409     }
1410     
1411     void compileStrCat()
1412     {
1413         LValue result;
1414         if (m_node->child3()) {
1415             result = vmCall(
1416                 m_out.int64, m_out.operation(operationStrCat3), m_callFrame,
1417                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1418                 lowJSValue(m_node->child2(), ManualOperandSpeculation),
1419                 lowJSValue(m_node->child3(), ManualOperandSpeculation));
1420         } else {
1421             result = vmCall(
1422                 m_out.int64, m_out.operation(operationStrCat2), m_callFrame,
1423                 lowJSValue(m_node->child1(), ManualOperandSpeculation),
1424                 lowJSValue(m_node->child2(), ManualOperandSpeculation));
1425         }
1426         setJSValue(result);
1427     }
1428     
1429     void compileArithAddOrSub()
1430     {
1431         bool isSub =  m_node->op() == ArithSub;
1432         switch (m_node->binaryUseKind()) {
1433         case Int32Use: {
1434             LValue left = lowInt32(m_node->child1());
1435             LValue right = lowInt32(m_node->child2());
1436
1437             if (!shouldCheckOverflow(m_node->arithMode())) {
1438                 setInt32(isSub ? m_out.sub(left, right) : m_out.add(left, right));
1439                 break;
1440             }
1441
1442             CheckValue* result =
1443                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1444             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1445             setInt32(result);
1446             break;
1447         }
1448             
1449         case Int52RepUse: {
1450             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52)
1451                 && !abstractValue(m_node->child2()).couldBeType(SpecInt52)) {
1452                 Int52Kind kind;
1453                 LValue left = lowWhicheverInt52(m_node->child1(), kind);
1454                 LValue right = lowInt52(m_node->child2(), kind);
1455                 setInt52(isSub ? m_out.sub(left, right) : m_out.add(left, right), kind);
1456                 break;
1457             }
1458
1459             LValue left = lowInt52(m_node->child1());
1460             LValue right = lowInt52(m_node->child2());
1461             CheckValue* result =
1462                 isSub ? m_out.speculateSub(left, right) : m_out.speculateAdd(left, right);
1463             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1464             setInt52(result);
1465             break;
1466         }
1467             
1468         case DoubleRepUse: {
1469             LValue C1 = lowDouble(m_node->child1());
1470             LValue C2 = lowDouble(m_node->child2());
1471
1472             setDouble(isSub ? m_out.doubleSub(C1, C2) : m_out.doubleAdd(C1, C2));
1473             break;
1474         }
1475
1476         case UntypedUse: {
1477             if (!isSub) {
1478                 DFG_CRASH(m_graph, m_node, "Bad use kind");
1479                 break;
1480             }
1481
1482             emitBinarySnippet<JITSubGenerator>(operationValueSub);
1483             break;
1484         }
1485
1486         default:
1487             DFG_CRASH(m_graph, m_node, "Bad use kind");
1488             break;
1489         }
1490     }
1491
1492     void compileArithClz32()
1493     {
1494         LValue operand = lowInt32(m_node->child1());
1495         setInt32(m_out.ctlz32(operand));
1496     }
1497     
1498     void compileArithMul()
1499     {
1500         switch (m_node->binaryUseKind()) {
1501         case Int32Use: {
1502             LValue left = lowInt32(m_node->child1());
1503             LValue right = lowInt32(m_node->child2());
1504             
1505             LValue result;
1506
1507             if (!shouldCheckOverflow(m_node->arithMode()))
1508                 result = m_out.mul(left, right);
1509             else {
1510                 CheckValue* speculation = m_out.speculateMul(left, right);
1511                 blessSpeculation(speculation, Overflow, noValue(), nullptr, m_origin);
1512                 result = speculation;
1513             }
1514             
1515             if (shouldCheckNegativeZero(m_node->arithMode())) {
1516                 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
1517                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
1518                 
1519                 m_out.branch(
1520                     m_out.notZero32(result), usually(continuation), rarely(slowCase));
1521                 
1522                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1523                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int32Zero));
1524                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int32Zero));
1525                 m_out.jump(continuation);
1526                 m_out.appendTo(continuation, lastNext);
1527             }
1528             
1529             setInt32(result);
1530             break;
1531         }
1532             
1533         case Int52RepUse: {
1534             Int52Kind kind;
1535             LValue left = lowWhicheverInt52(m_node->child1(), kind);
1536             LValue right = lowInt52(m_node->child2(), opposite(kind));
1537
1538             CheckValue* result = m_out.speculateMul(left, right);
1539             blessSpeculation(result, Overflow, noValue(), nullptr, m_origin);
1540
1541             if (shouldCheckNegativeZero(m_node->arithMode())) {
1542                 LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("ArithMul slow case"));
1543                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMul continuation"));
1544                 
1545                 m_out.branch(
1546                     m_out.notZero64(result), usually(continuation), rarely(slowCase));
1547                 
1548                 LBasicBlock lastNext = m_out.appendTo(slowCase, continuation);
1549                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(left, m_out.int64Zero));
1550                 speculate(NegativeZero, noValue(), nullptr, m_out.lessThan(right, m_out.int64Zero));
1551                 m_out.jump(continuation);
1552                 m_out.appendTo(continuation, lastNext);
1553             }
1554             
1555             setInt52(result);
1556             break;
1557         }
1558             
1559         case DoubleRepUse: {
1560             setDouble(
1561                 m_out.doubleMul(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1562             break;
1563         }
1564
1565         case UntypedUse: {
1566             emitBinarySnippet<JITMulGenerator>(operationValueMul);
1567             break;
1568         }
1569
1570         default:
1571             DFG_CRASH(m_graph, m_node, "Bad use kind");
1572             break;
1573         }
1574     }
1575
1576     void compileArithDiv()
1577     {
1578         switch (m_node->binaryUseKind()) {
1579         case Int32Use: {
1580             LValue numerator = lowInt32(m_node->child1());
1581             LValue denominator = lowInt32(m_node->child2());
1582
1583             if (shouldCheckNegativeZero(m_node->arithMode())) {
1584                 LBasicBlock zeroNumerator = FTL_NEW_BLOCK(m_out, ("ArithDiv zero numerator"));
1585                 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithDiv numerator continuation"));
1586
1587                 m_out.branch(
1588                     m_out.isZero32(numerator),
1589                     rarely(zeroNumerator), usually(numeratorContinuation));
1590
1591                 LBasicBlock innerLastNext = m_out.appendTo(zeroNumerator, numeratorContinuation);
1592
1593                 speculate(
1594                     NegativeZero, noValue(), 0, m_out.lessThan(denominator, m_out.int32Zero));
1595
1596                 m_out.jump(numeratorContinuation);
1597
1598                 m_out.appendTo(numeratorContinuation, innerLastNext);
1599             }
1600             
1601             if (shouldCheckOverflow(m_node->arithMode())) {
1602                 LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithDiv unsafe denominator"));
1603                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithDiv continuation"));
1604
1605                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1606                 m_out.branch(
1607                     m_out.above(adjustedDenominator, m_out.int32One),
1608                     usually(continuation), rarely(unsafeDenominator));
1609
1610                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1611                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1612                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1613                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1614                 m_out.jump(continuation);
1615
1616                 m_out.appendTo(continuation, lastNext);
1617                 LValue result = m_out.div(numerator, denominator);
1618                 speculate(
1619                     Overflow, noValue(), 0,
1620                     m_out.notEqual(m_out.mul(result, denominator), numerator));
1621                 setInt32(result);
1622             } else
1623                 setInt32(m_out.chillDiv(numerator, denominator));
1624
1625             break;
1626         }
1627             
1628         case DoubleRepUse: {
1629             setDouble(m_out.doubleDiv(
1630                 lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1631             break;
1632         }
1633
1634         case UntypedUse: {
1635             emitBinarySnippet<JITDivGenerator, NeedScratchFPR>(operationValueDiv);
1636             break;
1637         }
1638
1639         default:
1640             DFG_CRASH(m_graph, m_node, "Bad use kind");
1641             break;
1642         }
1643     }
1644     
1645     void compileArithMod()
1646     {
1647         switch (m_node->binaryUseKind()) {
1648         case Int32Use: {
1649             LValue numerator = lowInt32(m_node->child1());
1650             LValue denominator = lowInt32(m_node->child2());
1651
1652             LValue remainder;
1653             if (shouldCheckOverflow(m_node->arithMode())) {
1654                 LBasicBlock unsafeDenominator = FTL_NEW_BLOCK(m_out, ("ArithMod unsafe denominator"));
1655                 LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMod continuation"));
1656
1657                 LValue adjustedDenominator = m_out.add(denominator, m_out.int32One);
1658                 m_out.branch(
1659                     m_out.above(adjustedDenominator, m_out.int32One),
1660                     usually(continuation), rarely(unsafeDenominator));
1661
1662                 LBasicBlock lastNext = m_out.appendTo(unsafeDenominator, continuation);
1663                 LValue neg2ToThe31 = m_out.constInt32(-2147483647-1);
1664                 speculate(Overflow, noValue(), nullptr, m_out.isZero32(denominator));
1665                 speculate(Overflow, noValue(), nullptr, m_out.equal(numerator, neg2ToThe31));
1666                 m_out.jump(continuation);
1667
1668                 m_out.appendTo(continuation, lastNext);
1669                 LValue result = m_out.mod(numerator, denominator);
1670                 remainder = result;
1671             } else
1672                 remainder = m_out.chillMod(numerator, denominator);
1673
1674             if (shouldCheckNegativeZero(m_node->arithMode())) {
1675                 LBasicBlock negativeNumerator = FTL_NEW_BLOCK(m_out, ("ArithMod negative numerator"));
1676                 LBasicBlock numeratorContinuation = FTL_NEW_BLOCK(m_out, ("ArithMod numerator continuation"));
1677
1678                 m_out.branch(
1679                     m_out.lessThan(numerator, m_out.int32Zero),
1680                     unsure(negativeNumerator), unsure(numeratorContinuation));
1681
1682                 LBasicBlock innerLastNext = m_out.appendTo(negativeNumerator, numeratorContinuation);
1683
1684                 speculate(NegativeZero, noValue(), 0, m_out.isZero32(remainder));
1685
1686                 m_out.jump(numeratorContinuation);
1687
1688                 m_out.appendTo(numeratorContinuation, innerLastNext);
1689             }
1690
1691             setInt32(remainder);
1692             break;
1693         }
1694             
1695         case DoubleRepUse: {
1696             setDouble(
1697                 m_out.doubleMod(lowDouble(m_node->child1()), lowDouble(m_node->child2())));
1698             break;
1699         }
1700             
1701         default:
1702             DFG_CRASH(m_graph, m_node, "Bad use kind");
1703             break;
1704         }
1705     }
1706
1707     void compileArithMinOrMax()
1708     {
1709         switch (m_node->binaryUseKind()) {
1710         case Int32Use: {
1711             LValue left = lowInt32(m_node->child1());
1712             LValue right = lowInt32(m_node->child2());
1713             
1714             setInt32(
1715                 m_out.select(
1716                     m_node->op() == ArithMin
1717                         ? m_out.lessThan(left, right)
1718                         : m_out.lessThan(right, left),
1719                     left, right));
1720             break;
1721         }
1722             
1723         case DoubleRepUse: {
1724             LValue left = lowDouble(m_node->child1());
1725             LValue right = lowDouble(m_node->child2());
1726             
1727             LBasicBlock notLessThan = FTL_NEW_BLOCK(m_out, ("ArithMin/ArithMax not less than"));
1728             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithMin/ArithMax continuation"));
1729             
1730             Vector<ValueFromBlock, 2> results;
1731             
1732             results.append(m_out.anchor(left));
1733             m_out.branch(
1734                 m_node->op() == ArithMin
1735                     ? m_out.doubleLessThan(left, right)
1736                     : m_out.doubleGreaterThan(left, right),
1737                 unsure(continuation), unsure(notLessThan));
1738             
1739             LBasicBlock lastNext = m_out.appendTo(notLessThan, continuation);
1740             results.append(m_out.anchor(m_out.select(
1741                 m_node->op() == ArithMin
1742                     ? m_out.doubleGreaterThanOrEqual(left, right)
1743                     : m_out.doubleLessThanOrEqual(left, right),
1744                 right, m_out.constDouble(PNaN))));
1745             m_out.jump(continuation);
1746             
1747             m_out.appendTo(continuation, lastNext);
1748             setDouble(m_out.phi(m_out.doubleType, results));
1749             break;
1750         }
1751             
1752         default:
1753             DFG_CRASH(m_graph, m_node, "Bad use kind");
1754             break;
1755         }
1756     }
1757     
1758     void compileArithAbs()
1759     {
1760         switch (m_node->child1().useKind()) {
1761         case Int32Use: {
1762             LValue value = lowInt32(m_node->child1());
1763
1764             LValue mask = m_out.aShr(value, m_out.constInt32(31));
1765             LValue result = m_out.bitXor(mask, m_out.add(mask, value));
1766
1767             if (shouldCheckOverflow(m_node->arithMode()))
1768                 speculate(Overflow, noValue(), 0, m_out.equal(result, m_out.constInt32(1 << 31)));
1769
1770             setInt32(result);
1771             break;
1772         }
1773             
1774         case DoubleRepUse: {
1775             setDouble(m_out.doubleAbs(lowDouble(m_node->child1())));
1776             break;
1777         }
1778             
1779         default:
1780             DFG_CRASH(m_graph, m_node, "Bad use kind");
1781             break;
1782         }
1783     }
1784
1785     void compileArithSin() { setDouble(m_out.doubleSin(lowDouble(m_node->child1()))); }
1786
1787     void compileArithCos() { setDouble(m_out.doubleCos(lowDouble(m_node->child1()))); }
1788
1789     void compileArithPow()
1790     {
1791         if (m_node->child2().useKind() == Int32Use)
1792             setDouble(m_out.doublePowi(lowDouble(m_node->child1()), lowInt32(m_node->child2())));
1793         else {
1794             LValue base = lowDouble(m_node->child1());
1795             LValue exponent = lowDouble(m_node->child2());
1796
1797             LBasicBlock integerExponentIsSmallBlock = FTL_NEW_BLOCK(m_out, ("ArithPow test integer exponent is small."));
1798             LBasicBlock integerExponentPowBlock = FTL_NEW_BLOCK(m_out, ("ArithPow pow(double, (int)double)."));
1799             LBasicBlock doubleExponentPowBlockEntry = FTL_NEW_BLOCK(m_out, ("ArithPow pow(double, double)."));
1800             LBasicBlock nanExceptionExponentIsInfinity = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, check exponent is infinity."));
1801             LBasicBlock nanExceptionBaseIsOne = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, check base is one."));
1802             LBasicBlock powBlock = FTL_NEW_BLOCK(m_out, ("ArithPow regular pow"));
1803             LBasicBlock nanExceptionResultIsNaN = FTL_NEW_BLOCK(m_out, ("ArithPow NaN Exception, result is NaN."));
1804             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithPow continuation"));
1805
1806             LValue integerExponent = m_out.doubleToInt(exponent);
1807             LValue integerExponentConvertedToDouble = m_out.intToDouble(integerExponent);
1808             LValue exponentIsInteger = m_out.doubleEqual(exponent, integerExponentConvertedToDouble);
1809             m_out.branch(exponentIsInteger, unsure(integerExponentIsSmallBlock), unsure(doubleExponentPowBlockEntry));
1810
1811             LBasicBlock lastNext = m_out.appendTo(integerExponentIsSmallBlock, integerExponentPowBlock);
1812             LValue integerExponentBelow1000 = m_out.below(integerExponent, m_out.constInt32(1000));
1813             m_out.branch(integerExponentBelow1000, usually(integerExponentPowBlock), rarely(doubleExponentPowBlockEntry));
1814
1815             m_out.appendTo(integerExponentPowBlock, doubleExponentPowBlockEntry);
1816             ValueFromBlock powDoubleIntResult = m_out.anchor(m_out.doublePowi(base, integerExponent));
1817             m_out.jump(continuation);
1818
1819             // If y is NaN, the result is NaN.
1820             m_out.appendTo(doubleExponentPowBlockEntry, nanExceptionExponentIsInfinity);
1821             LValue exponentIsNaN;
1822             if (provenType(m_node->child2()) & SpecDoubleNaN)
1823                 exponentIsNaN = m_out.doubleNotEqualOrUnordered(exponent, exponent);
1824             else
1825                 exponentIsNaN = m_out.booleanFalse;
1826             m_out.branch(exponentIsNaN, rarely(nanExceptionResultIsNaN), usually(nanExceptionExponentIsInfinity));
1827
1828             // If abs(x) is 1 and y is +infinity, the result is NaN.
1829             // If abs(x) is 1 and y is -infinity, the result is NaN.
1830             m_out.appendTo(nanExceptionExponentIsInfinity, nanExceptionBaseIsOne);
1831             LValue absoluteExponent = m_out.doubleAbs(exponent);
1832             LValue absoluteExponentIsInfinity = m_out.doubleEqual(absoluteExponent, m_out.constDouble(std::numeric_limits<double>::infinity()));
1833             m_out.branch(absoluteExponentIsInfinity, rarely(nanExceptionBaseIsOne), usually(powBlock));
1834
1835             m_out.appendTo(nanExceptionBaseIsOne, powBlock);
1836             LValue absoluteBase = m_out.doubleAbs(base);
1837             LValue absoluteBaseIsOne = m_out.doubleEqual(absoluteBase, m_out.constDouble(1));
1838             m_out.branch(absoluteBaseIsOne, unsure(nanExceptionResultIsNaN), unsure(powBlock));
1839
1840             m_out.appendTo(powBlock, nanExceptionResultIsNaN);
1841             ValueFromBlock powResult = m_out.anchor(m_out.doublePow(base, exponent));
1842             m_out.jump(continuation);
1843
1844             m_out.appendTo(nanExceptionResultIsNaN, continuation);
1845             ValueFromBlock pureNan = m_out.anchor(m_out.constDouble(PNaN));
1846             m_out.jump(continuation);
1847
1848             m_out.appendTo(continuation, lastNext);
1849             setDouble(m_out.phi(m_out.doubleType, powDoubleIntResult, powResult, pureNan));
1850         }
1851     }
1852
1853     void compileArithRandom()
1854     {
1855         JSGlobalObject* globalObject = m_graph.globalObjectFor(m_node->origin.semantic);
1856
1857         // Inlined WeakRandom::advance().
1858         // uint64_t x = m_low;
1859         void* lowAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::lowOffset();
1860         LValue low = m_out.load64(m_out.absolute(lowAddress));
1861         // uint64_t y = m_high;
1862         void* highAddress = reinterpret_cast<uint8_t*>(globalObject) + JSGlobalObject::weakRandomOffset() + WeakRandom::highOffset();
1863         LValue high = m_out.load64(m_out.absolute(highAddress));
1864         // m_low = y;
1865         m_out.store64(high, m_out.absolute(lowAddress));
1866
1867         // x ^= x << 23;
1868         LValue phase1 = m_out.bitXor(m_out.shl(low, m_out.constInt64(23)), low);
1869
1870         // x ^= x >> 17;
1871         LValue phase2 = m_out.bitXor(m_out.lShr(phase1, m_out.constInt64(17)), phase1);
1872
1873         // x ^= y ^ (y >> 26);
1874         LValue phase3 = m_out.bitXor(m_out.bitXor(high, m_out.lShr(high, m_out.constInt64(26))), phase2);
1875
1876         // m_high = x;
1877         m_out.store64(phase3, m_out.absolute(highAddress));
1878
1879         // return x + y;
1880         LValue random64 = m_out.add(phase3, high);
1881
1882         // Extract random 53bit. [0, 53] bit is safe integer number ranges in double representation.
1883         LValue random53 = m_out.bitAnd(random64, m_out.constInt64((1ULL << 53) - 1));
1884
1885         LValue double53Integer = m_out.intToDouble(random53);
1886
1887         // Convert `(53bit double integer value) / (1 << 53)` to `(53bit double integer value) * (1.0 / (1 << 53))`.
1888         // In latter case, `1.0 / (1 << 53)` will become a double value represented as (mantissa = 0 & exp = 970, it means 1e-(2**54)).
1889         static const double scale = 1.0 / (1ULL << 53);
1890
1891         // Multiplying 1e-(2**54) with the double integer does not change anything of the mantissa part of the double integer.
1892         // It just reduces the exp part of the given 53bit double integer.
1893         // (Except for 0.0. This is specially handled and in this case, exp just becomes 0.)
1894         // Now we get 53bit precision random double value in [0, 1).
1895         LValue result = m_out.doubleMul(double53Integer, m_out.constDouble(scale));
1896
1897         setDouble(result);
1898     }
1899
1900     void compileArithRound()
1901     {
1902         LValue result = nullptr;
1903
1904         if (producesInteger(m_node->arithRoundingMode()) && !shouldCheckNegativeZero(m_node->arithRoundingMode())) {
1905             LValue value = lowDouble(m_node->child1());
1906             result = m_out.doubleFloor(m_out.doubleAdd(value, m_out.constDouble(0.5)));
1907         } else {
1908             LBasicBlock realPartIsMoreThanHalf = FTL_NEW_BLOCK(m_out, ("ArithRound should round down"));
1909             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArithRound continuation"));
1910
1911             LValue value = lowDouble(m_node->child1());
1912             LValue integerValue = m_out.doubleCeil(value);
1913             ValueFromBlock integerValueResult = m_out.anchor(integerValue);
1914
1915             LValue realPart = m_out.doubleSub(integerValue, value);
1916
1917             m_out.branch(m_out.doubleGreaterThanOrUnordered(realPart, m_out.constDouble(0.5)), unsure(realPartIsMoreThanHalf), unsure(continuation));
1918
1919             LBasicBlock lastNext = m_out.appendTo(realPartIsMoreThanHalf, continuation);
1920             LValue integerValueRoundedDown = m_out.doubleSub(integerValue, m_out.constDouble(1));
1921             ValueFromBlock integerValueRoundedDownResult = m_out.anchor(integerValueRoundedDown);
1922             m_out.jump(continuation);
1923             m_out.appendTo(continuation, lastNext);
1924
1925             result = m_out.phi(m_out.doubleType, integerValueResult, integerValueRoundedDownResult);
1926         }
1927
1928         if (producesInteger(m_node->arithRoundingMode())) {
1929             LValue integerValue = convertDoubleToInt32(result, shouldCheckNegativeZero(m_node->arithRoundingMode()));
1930             setInt32(integerValue);
1931         } else
1932             setDouble(result);
1933     }
1934
1935     void compileArithFloor()
1936     {
1937         LValue value = lowDouble(m_node->child1());
1938         LValue integerValue = m_out.doubleFloor(value);
1939         if (producesInteger(m_node->arithRoundingMode()))
1940             setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
1941         else
1942             setDouble(integerValue);
1943     }
1944
1945     void compileArithCeil()
1946     {
1947         LValue value = lowDouble(m_node->child1());
1948         LValue integerValue = m_out.doubleCeil(value);
1949         if (producesInteger(m_node->arithRoundingMode()))
1950             setInt32(convertDoubleToInt32(integerValue, shouldCheckNegativeZero(m_node->arithRoundingMode())));
1951         else
1952             setDouble(integerValue);
1953     }
1954
1955     void compileArithSqrt() { setDouble(m_out.doubleSqrt(lowDouble(m_node->child1()))); }
1956
1957     void compileArithLog() { setDouble(m_out.doubleLog(lowDouble(m_node->child1()))); }
1958     
1959     void compileArithFRound()
1960     {
1961         setDouble(m_out.fround(lowDouble(m_node->child1())));
1962     }
1963     
1964     void compileArithNegate()
1965     {
1966         switch (m_node->child1().useKind()) {
1967         case Int32Use: {
1968             LValue value = lowInt32(m_node->child1());
1969             
1970             LValue result;
1971             if (!shouldCheckOverflow(m_node->arithMode()))
1972                 result = m_out.neg(value);
1973             else if (!shouldCheckNegativeZero(m_node->arithMode())) {
1974                 CheckValue* check = m_out.speculateSub(m_out.int32Zero, value);
1975                 blessSpeculation(check, Overflow, noValue(), nullptr, m_origin);
1976                 result = check;
1977             } else {
1978                 speculate(Overflow, noValue(), 0, m_out.testIsZero32(value, m_out.constInt32(0x7fffffff)));
1979                 result = m_out.neg(value);
1980             }
1981
1982             setInt32(result);
1983             break;
1984         }
1985             
1986         case Int52RepUse: {
1987             if (!abstractValue(m_node->child1()).couldBeType(SpecInt52)) {
1988                 Int52Kind kind;
1989                 LValue value = lowWhicheverInt52(m_node->child1(), kind);
1990                 LValue result = m_out.neg(value);
1991                 if (shouldCheckNegativeZero(m_node->arithMode()))
1992                     speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
1993                 setInt52(result, kind);
1994                 break;
1995             }
1996             
1997             LValue value = lowInt52(m_node->child1());
1998             CheckValue* result = m_out.speculateSub(m_out.int64Zero, value);
1999             blessSpeculation(result, Int52Overflow, noValue(), nullptr, m_origin);
2000             speculate(NegativeZero, noValue(), 0, m_out.isZero64(result));
2001             setInt52(result);
2002             break;
2003         }
2004             
2005         case DoubleRepUse: {
2006             setDouble(m_out.doubleNeg(lowDouble(m_node->child1())));
2007             break;
2008         }
2009             
2010         default:
2011             DFG_CRASH(m_graph, m_node, "Bad use kind");
2012             break;
2013         }
2014     }
2015     
2016     void compileBitAnd()
2017     {
2018         if (m_node->isBinaryUseKind(UntypedUse)) {
2019             emitBinaryBitOpSnippet<JITBitAndGenerator>(operationValueBitAnd);
2020             return;
2021         }
2022         setInt32(m_out.bitAnd(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2023     }
2024     
2025     void compileBitOr()
2026     {
2027         if (m_node->isBinaryUseKind(UntypedUse)) {
2028             emitBinaryBitOpSnippet<JITBitOrGenerator>(operationValueBitOr);
2029             return;
2030         }
2031         setInt32(m_out.bitOr(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2032     }
2033     
2034     void compileBitXor()
2035     {
2036         if (m_node->isBinaryUseKind(UntypedUse)) {
2037             emitBinaryBitOpSnippet<JITBitXorGenerator>(operationValueBitXor);
2038             return;
2039         }
2040         setInt32(m_out.bitXor(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2041     }
2042     
2043     void compileBitRShift()
2044     {
2045         if (m_node->isBinaryUseKind(UntypedUse)) {
2046             emitRightShiftSnippet(JITRightShiftGenerator::SignedShift);
2047             return;
2048         }
2049         setInt32(m_out.aShr(
2050             lowInt32(m_node->child1()),
2051             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2052     }
2053     
2054     void compileBitLShift()
2055     {
2056         if (m_node->isBinaryUseKind(UntypedUse)) {
2057             emitBinaryBitOpSnippet<JITLeftShiftGenerator>(operationValueBitLShift);
2058             return;
2059         }
2060         setInt32(m_out.shl(
2061             lowInt32(m_node->child1()),
2062             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2063     }
2064     
2065     void compileBitURShift()
2066     {
2067         if (m_node->isBinaryUseKind(UntypedUse)) {
2068             emitRightShiftSnippet(JITRightShiftGenerator::UnsignedShift);
2069             return;
2070         }
2071         setInt32(m_out.lShr(
2072             lowInt32(m_node->child1()),
2073             m_out.bitAnd(lowInt32(m_node->child2()), m_out.constInt32(31))));
2074     }
2075     
2076     void compileUInt32ToNumber()
2077     {
2078         LValue value = lowInt32(m_node->child1());
2079
2080         if (doesOverflow(m_node->arithMode())) {
2081             setDouble(m_out.unsignedToDouble(value));
2082             return;
2083         }
2084         
2085         speculate(Overflow, noValue(), 0, m_out.lessThan(value, m_out.int32Zero));
2086         setInt32(value);
2087     }
2088     
2089     void compileCheckStructure()
2090     {
2091         ExitKind exitKind;
2092         if (m_node->child1()->hasConstant())
2093             exitKind = BadConstantCache;
2094         else
2095             exitKind = BadCache;
2096
2097         switch (m_node->child1().useKind()) {
2098         case CellUse:
2099         case KnownCellUse: {
2100             LValue cell = lowCell(m_node->child1());
2101             
2102             checkStructure(
2103                 m_out.load32(cell, m_heaps.JSCell_structureID), jsValueValue(cell),
2104                 exitKind, m_node->structureSet(),
2105                 [&] (Structure* structure) {
2106                     return weakStructureID(structure);
2107                 });
2108             return;
2109         }
2110
2111         case CellOrOtherUse: {
2112             LValue value = lowJSValue(m_node->child1(), ManualOperandSpeculation);
2113
2114             LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("CheckStructure CellOrOtherUse cell case"));
2115             LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("CheckStructure CellOrOtherUse not cell case"));
2116             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("CheckStructure CellOrOtherUse continuation"));
2117
2118             m_out.branch(
2119                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2120
2121             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2122             checkStructure(
2123                 m_out.load32(value, m_heaps.JSCell_structureID), jsValueValue(value),
2124                 exitKind, m_node->structureSet(),
2125                 [&] (Structure* structure) {
2126                     return weakStructureID(structure);
2127                 });
2128             m_out.jump(continuation);
2129
2130             m_out.appendTo(notCellCase, continuation);
2131             FTL_TYPE_CHECK(jsValueValue(value), m_node->child1(), SpecCell | SpecOther, isNotOther(value));
2132             m_out.jump(continuation);
2133
2134             m_out.appendTo(continuation, lastNext);
2135             return;
2136         }
2137
2138         default:
2139             DFG_CRASH(m_graph, m_node, "Bad use kind");
2140             return;
2141         }
2142     }
2143     
2144     void compileCheckCell()
2145     {
2146         LValue cell = lowCell(m_node->child1());
2147         
2148         speculate(
2149             BadCell, jsValueValue(cell), m_node->child1().node(),
2150             m_out.notEqual(cell, weakPointer(m_node->cellOperand()->cell())));
2151     }
2152     
2153     void compileCheckBadCell()
2154     {
2155         terminate(BadCell);
2156     }
2157
2158     void compileCheckNotEmpty()
2159     {
2160         speculate(TDZFailure, noValue(), nullptr, m_out.isZero64(lowJSValue(m_node->child1())));
2161     }
2162
2163     void compileCheckIdent()
2164     {
2165         UniquedStringImpl* uid = m_node->uidOperand();
2166         if (uid->isSymbol()) {
2167             LValue symbol = lowSymbol(m_node->child1());
2168             LValue stringImpl = m_out.loadPtr(symbol, m_heaps.Symbol_privateName);
2169             speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2170         } else {
2171             LValue string = lowStringIdent(m_node->child1());
2172             LValue stringImpl = m_out.loadPtr(string, m_heaps.JSString_value);
2173             speculate(BadIdent, noValue(), nullptr, m_out.notEqual(stringImpl, m_out.constIntPtr(uid)));
2174         }
2175     }
2176
2177     void compileGetExecutable()
2178     {
2179         LValue cell = lowCell(m_node->child1());
2180         speculateFunction(m_node->child1(), cell);
2181         setJSValue(m_out.loadPtr(cell, m_heaps.JSFunction_executable));
2182     }
2183     
2184     void compileArrayifyToStructure()
2185     {
2186         LValue cell = lowCell(m_node->child1());
2187         LValue property = !!m_node->child2() ? lowInt32(m_node->child2()) : 0;
2188         
2189         LBasicBlock unexpectedStructure = FTL_NEW_BLOCK(m_out, ("ArrayifyToStructure unexpected structure"));
2190         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("ArrayifyToStructure continuation"));
2191         
2192         LValue structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2193         
2194         m_out.branch(
2195             m_out.notEqual(structureID, weakStructureID(m_node->structure())),
2196             rarely(unexpectedStructure), usually(continuation));
2197         
2198         LBasicBlock lastNext = m_out.appendTo(unexpectedStructure, continuation);
2199         
2200         if (property) {
2201             switch (m_node->arrayMode().type()) {
2202             case Array::Int32:
2203             case Array::Double:
2204             case Array::Contiguous:
2205                 speculate(
2206                     Uncountable, noValue(), 0,
2207                     m_out.aboveOrEqual(property, m_out.constInt32(MIN_SPARSE_ARRAY_INDEX)));
2208                 break;
2209             default:
2210                 break;
2211             }
2212         }
2213         
2214         switch (m_node->arrayMode().type()) {
2215         case Array::Int32:
2216             vmCall(m_out.voidType, m_out.operation(operationEnsureInt32), m_callFrame, cell);
2217             break;
2218         case Array::Double:
2219             vmCall(m_out.voidType, m_out.operation(operationEnsureDouble), m_callFrame, cell);
2220             break;
2221         case Array::Contiguous:
2222             vmCall(m_out.voidType, m_out.operation(operationEnsureContiguous), m_callFrame, cell);
2223             break;
2224         case Array::ArrayStorage:
2225         case Array::SlowPutArrayStorage:
2226             vmCall(m_out.voidType, m_out.operation(operationEnsureArrayStorage), m_callFrame, cell);
2227             break;
2228         default:
2229             DFG_CRASH(m_graph, m_node, "Bad array type");
2230             break;
2231         }
2232         
2233         structureID = m_out.load32(cell, m_heaps.JSCell_structureID);
2234         speculate(
2235             BadIndexingType, jsValueValue(cell), 0,
2236             m_out.notEqual(structureID, weakStructureID(m_node->structure())));
2237         m_out.jump(continuation);
2238         
2239         m_out.appendTo(continuation, lastNext);
2240     }
2241     
2242     void compilePutStructure()
2243     {
2244         m_ftlState.jitCode->common.notifyCompilingStructureTransition(m_graph.m_plan, codeBlock(), m_node);
2245
2246         Structure* oldStructure = m_node->transition()->previous;
2247         Structure* newStructure = m_node->transition()->next;
2248         ASSERT_UNUSED(oldStructure, oldStructure->indexingType() == newStructure->indexingType());
2249         ASSERT(oldStructure->typeInfo().inlineTypeFlags() == newStructure->typeInfo().inlineTypeFlags());
2250         ASSERT(oldStructure->typeInfo().type() == newStructure->typeInfo().type());
2251
2252         LValue cell = lowCell(m_node->child1()); 
2253         m_out.store32(
2254             weakStructureID(newStructure),
2255             cell, m_heaps.JSCell_structureID);
2256     }
2257     
2258     void compileGetById()
2259     {
2260         switch (m_node->child1().useKind()) {
2261         case CellUse: {
2262             setJSValue(getById(lowCell(m_node->child1())));
2263             return;
2264         }
2265             
2266         case UntypedUse: {
2267             // This is pretty weird, since we duplicate the slow path both here and in the
2268             // code generated by the IC. We should investigate making this less bad.
2269             // https://bugs.webkit.org/show_bug.cgi?id=127830
2270             LValue value = lowJSValue(m_node->child1());
2271             
2272             LBasicBlock cellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped cell case"));
2273             LBasicBlock notCellCase = FTL_NEW_BLOCK(m_out, ("GetById untyped not cell case"));
2274             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetById untyped continuation"));
2275             
2276             m_out.branch(
2277                 isCell(value, provenType(m_node->child1())), unsure(cellCase), unsure(notCellCase));
2278             
2279             LBasicBlock lastNext = m_out.appendTo(cellCase, notCellCase);
2280             ValueFromBlock cellResult = m_out.anchor(getById(value));
2281             m_out.jump(continuation);
2282             
2283             m_out.appendTo(notCellCase, continuation);
2284             ValueFromBlock notCellResult = m_out.anchor(vmCall(
2285                 m_out.int64, m_out.operation(operationGetByIdGeneric),
2286                 m_callFrame, value,
2287                 m_out.constIntPtr(m_graph.identifiers()[m_node->identifierNumber()])));
2288             m_out.jump(continuation);
2289             
2290             m_out.appendTo(continuation, lastNext);
2291             setJSValue(m_out.phi(m_out.int64, cellResult, notCellResult));
2292             return;
2293         }
2294             
2295         default:
2296             DFG_CRASH(m_graph, m_node, "Bad use kind");
2297             return;
2298         }
2299     }
2300     
2301     void compilePutById()
2302     {
2303         Node* node = m_node;
2304         
2305         // See above; CellUse is easier so we do only that for now.
2306         ASSERT(node->child1().useKind() == CellUse);
2307
2308         LValue base = lowCell(node->child1());
2309         LValue value = lowJSValue(node->child2());
2310         auto uid = m_graph.identifiers()[node->identifierNumber()];
2311
2312         B3::PatchpointValue* patchpoint = m_out.patchpoint(Void);
2313         patchpoint->appendSomeRegister(base);
2314         patchpoint->appendSomeRegister(value);
2315         patchpoint->clobber(RegisterSet::macroScratchRegisters());
2316
2317         // FIXME: If this is a PutByIdFlush, we might want to late-clobber volatile registers.
2318         // https://bugs.webkit.org/show_bug.cgi?id=152848
2319
2320         RefPtr<PatchpointExceptionHandle> exceptionHandle =
2321             preparePatchpointForExceptions(patchpoint);
2322
2323         State* state = &m_ftlState;
2324         ECMAMode ecmaMode = m_graph.executableFor(node->origin.semantic)->ecmaMode();
2325         
2326         patchpoint->setGenerator(
2327             [=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2328                 AllowMacroScratchRegisterUsage allowScratch(jit);
2329
2330                 CallSiteIndex callSiteIndex =
2331                     state->jitCode->common.addUniqueCallSiteIndex(node->origin.semantic);
2332
2333                 Box<CCallHelpers::JumpList> exceptions =
2334                     exceptionHandle->scheduleExitCreation(params)->jumps(jit);
2335
2336                 // JS setter call ICs generated by the PutById IC will need this.
2337                 exceptionHandle->scheduleExitCreationForUnwind(params, callSiteIndex);
2338
2339                 auto generator = Box<JITPutByIdGenerator>::create(
2340                     jit.codeBlock(), node->origin.semantic, callSiteIndex,
2341                     params.unavailableRegisters(), JSValueRegs(params[0].gpr()),
2342                     JSValueRegs(params[1].gpr()), GPRInfo::patchpointScratchRegister, ecmaMode,
2343                     node->op() == PutByIdDirect ? Direct : NotDirect);
2344
2345                 generator->generateFastPath(jit);
2346                 CCallHelpers::Label done = jit.label();
2347
2348                 params.addLatePath(
2349                     [=] (CCallHelpers& jit) {
2350                         AllowMacroScratchRegisterUsage allowScratch(jit);
2351
2352                         generator->slowPathJump().link(&jit);
2353                         CCallHelpers::Label slowPathBegin = jit.label();
2354                         CCallHelpers::Call slowPathCall = callOperation(
2355                             *state, params.unavailableRegisters(), jit, node->origin.semantic,
2356                             exceptions.get(), generator->slowPathFunction(), InvalidGPRReg,
2357                             CCallHelpers::TrustedImmPtr(generator->stubInfo()), params[1].gpr(),
2358                             params[0].gpr(), CCallHelpers::TrustedImmPtr(uid)).call();
2359                         jit.jump().linkTo(done, &jit);
2360
2361                         generator->reportSlowPathCall(slowPathBegin, slowPathCall);
2362
2363                         jit.addLinkTask(
2364                             [=] (LinkBuffer& linkBuffer) {
2365                                 generator->finalize(linkBuffer);
2366                             });
2367                     });
2368             });
2369     }
2370     
2371     void compileGetButterfly()
2372     {
2373         setStorage(loadButterflyWithBarrier(lowCell(m_node->child1())));
2374     }
2375
2376     void compileGetButterflyReadOnly()
2377     {
2378         setStorage(loadButterflyReadOnly(lowCell(m_node->child1())));
2379     }
2380     
2381     void compileConstantStoragePointer()
2382     {
2383         setStorage(m_out.constIntPtr(m_node->storagePointer()));
2384     }
2385     
2386     void compileGetIndexedPropertyStorage()
2387     {
2388         LValue cell = lowCell(m_node->child1());
2389         
2390         if (m_node->arrayMode().type() == Array::String) {
2391             LBasicBlock slowPath = FTL_NEW_BLOCK(m_out, ("GetIndexedPropertyStorage String slow case"));
2392             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetIndexedPropertyStorage String continuation"));
2393
2394             LValue fastResultValue = m_out.loadPtr(cell, m_heaps.JSString_value);
2395             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2396             
2397             m_out.branch(
2398                 m_out.notNull(fastResultValue), usually(continuation), rarely(slowPath));
2399             
2400             LBasicBlock lastNext = m_out.appendTo(slowPath, continuation);
2401             
2402             ValueFromBlock slowResult = m_out.anchor(
2403                 vmCall(m_out.intPtr, m_out.operation(operationResolveRope), m_callFrame, cell));
2404             
2405             m_out.jump(continuation);
2406             
2407             m_out.appendTo(continuation, lastNext);
2408             
2409             setStorage(m_out.loadPtr(m_out.phi(m_out.intPtr, fastResult, slowResult), m_heaps.StringImpl_data));
2410             return;
2411         }
2412         
2413         setStorage(loadVectorWithBarrier(cell));
2414     }
2415     
2416     void compileCheckArray()
2417     {
2418         Edge edge = m_node->child1();
2419         LValue cell = lowCell(edge);
2420         
2421         if (m_node->arrayMode().alreadyChecked(m_graph, m_node, abstractValue(edge)))
2422             return;
2423         
2424         speculate(
2425             BadIndexingType, jsValueValue(cell), 0,
2426             m_out.logicalNot(isArrayType(cell, m_node->arrayMode())));
2427     }
2428
2429     void compileGetTypedArrayByteOffset()
2430     {
2431         LValue basePtr = lowCell(m_node->child1());    
2432
2433         LBasicBlock simpleCase = FTL_NEW_BLOCK(m_out, ("GetTypedArrayByteOffset wasteless typed array"));
2434         LBasicBlock wastefulCase = FTL_NEW_BLOCK(m_out, ("GetTypedArrayByteOffset wasteful typed array"));
2435         LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetTypedArrayByteOffset continuation"));
2436         
2437         LValue mode = m_out.load32(basePtr, m_heaps.JSArrayBufferView_mode);
2438         m_out.branch(
2439             m_out.notEqual(mode, m_out.constInt32(WastefulTypedArray)),
2440             unsure(simpleCase), unsure(wastefulCase));
2441
2442         LBasicBlock lastNext = m_out.appendTo(simpleCase, wastefulCase);
2443
2444         ValueFromBlock simpleOut = m_out.anchor(m_out.constIntPtr(0));
2445
2446         m_out.jump(continuation);
2447
2448         m_out.appendTo(wastefulCase, continuation);
2449
2450         LValue vectorPtr = loadVectorReadOnly(basePtr);
2451         LValue butterflyPtr = loadButterflyReadOnly(basePtr);
2452         LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer);
2453         LValue dataPtr = m_out.loadPtr(arrayBufferPtr, m_heaps.ArrayBuffer_data);
2454
2455         ValueFromBlock wastefulOut = m_out.anchor(m_out.sub(vectorPtr, dataPtr));
2456
2457         m_out.jump(continuation);
2458         m_out.appendTo(continuation, lastNext);
2459
2460         setInt32(m_out.castToInt32(m_out.phi(m_out.intPtr, simpleOut, wastefulOut)));
2461     }
2462     
2463     void compileGetArrayLength()
2464     {
2465         switch (m_node->arrayMode().type()) {
2466         case Array::Int32:
2467         case Array::Double:
2468         case Array::Contiguous: {
2469             setInt32(m_out.load32NonNegative(lowStorage(m_node->child2()), m_heaps.Butterfly_publicLength));
2470             return;
2471         }
2472             
2473         case Array::String: {
2474             LValue string = lowCell(m_node->child1());
2475             setInt32(m_out.load32NonNegative(string, m_heaps.JSString_length));
2476             return;
2477         }
2478             
2479         case Array::DirectArguments: {
2480             LValue arguments = lowCell(m_node->child1());
2481             speculate(
2482                 ExoticObjectMode, noValue(), nullptr,
2483                 m_out.notNull(m_out.loadPtr(arguments, m_heaps.DirectArguments_overrides)));
2484             setInt32(m_out.load32NonNegative(arguments, m_heaps.DirectArguments_length));
2485             return;
2486         }
2487             
2488         case Array::ScopedArguments: {
2489             LValue arguments = lowCell(m_node->child1());
2490             speculate(
2491                 ExoticObjectMode, noValue(), nullptr,
2492                 m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
2493             setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
2494             return;
2495         }
2496             
2497         default:
2498             if (m_node->arrayMode().isSomeTypedArrayView()) {
2499                 setInt32(
2500                     m_out.load32NonNegative(lowCell(m_node->child1()), m_heaps.JSArrayBufferView_length));
2501                 return;
2502             }
2503             
2504             DFG_CRASH(m_graph, m_node, "Bad array type");
2505             return;
2506         }
2507     }
2508     
2509     void compileCheckInBounds()
2510     {
2511         speculate(
2512             OutOfBounds, noValue(), 0,
2513             m_out.aboveOrEqual(lowInt32(m_node->child1()), lowInt32(m_node->child2())));
2514     }
2515     
2516     void compileGetByVal()
2517     {
2518         switch (m_node->arrayMode().type()) {
2519         case Array::Int32:
2520         case Array::Contiguous: {
2521             LValue index = lowInt32(m_node->child2());
2522             LValue storage = lowStorage(m_node->child3());
2523             
2524             IndexedAbstractHeap& heap = m_node->arrayMode().type() == Array::Int32 ?
2525                 m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties;
2526             
2527             if (m_node->arrayMode().isInBounds()) {
2528                 LValue result = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2529                 LValue isHole = m_out.isZero64(result);
2530                 if (m_node->arrayMode().isSaneChain()) {
2531                     DFG_ASSERT(
2532                         m_graph, m_node, m_node->arrayMode().type() == Array::Contiguous);
2533                     result = m_out.select(
2534                         isHole, m_out.constInt64(JSValue::encode(jsUndefined())), result);
2535                 } else
2536                     speculate(LoadFromHole, noValue(), 0, isHole);
2537                 setJSValue(result);
2538                 return;
2539             }
2540             
2541             LValue base = lowCell(m_node->child1());
2542             
2543             LBasicBlock fastCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous fast case"));
2544             LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous slow case"));
2545             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal int/contiguous continuation"));
2546             
2547             m_out.branch(
2548                 m_out.aboveOrEqual(
2549                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2550                 rarely(slowCase), usually(fastCase));
2551             
2552             LBasicBlock lastNext = m_out.appendTo(fastCase, slowCase);
2553
2554             LValue fastResultValue = m_out.load64(baseIndex(heap, storage, index, m_node->child2()));
2555             ValueFromBlock fastResult = m_out.anchor(fastResultValue);
2556             m_out.branch(
2557                 m_out.isZero64(fastResultValue), rarely(slowCase), usually(continuation));
2558             
2559             m_out.appendTo(slowCase, continuation);
2560             ValueFromBlock slowResult = m_out.anchor(
2561                 vmCall(m_out.int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2562             m_out.jump(continuation);
2563             
2564             m_out.appendTo(continuation, lastNext);
2565             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2566             return;
2567         }
2568             
2569         case Array::Double: {
2570             LValue index = lowInt32(m_node->child2());
2571             LValue storage = lowStorage(m_node->child3());
2572             
2573             IndexedAbstractHeap& heap = m_heaps.indexedDoubleProperties;
2574             
2575             if (m_node->arrayMode().isInBounds()) {
2576                 LValue result = m_out.loadDouble(
2577                     baseIndex(heap, storage, index, m_node->child2()));
2578                 
2579                 if (!m_node->arrayMode().isSaneChain()) {
2580                     speculate(
2581                         LoadFromHole, noValue(), 0,
2582                         m_out.doubleNotEqualOrUnordered(result, result));
2583                 }
2584                 setDouble(result);
2585                 break;
2586             }
2587             
2588             LValue base = lowCell(m_node->child1());
2589             
2590             LBasicBlock inBounds = FTL_NEW_BLOCK(m_out, ("GetByVal double in bounds"));
2591             LBasicBlock boxPath = FTL_NEW_BLOCK(m_out, ("GetByVal double boxing"));
2592             LBasicBlock slowCase = FTL_NEW_BLOCK(m_out, ("GetByVal double slow case"));
2593             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal double continuation"));
2594             
2595             m_out.branch(
2596                 m_out.aboveOrEqual(
2597                     index, m_out.load32NonNegative(storage, m_heaps.Butterfly_publicLength)),
2598                 rarely(slowCase), usually(inBounds));
2599             
2600             LBasicBlock lastNext = m_out.appendTo(inBounds, boxPath);
2601             LValue doubleValue = m_out.loadDouble(
2602                 baseIndex(heap, storage, index, m_node->child2()));
2603             m_out.branch(
2604                 m_out.doubleNotEqualOrUnordered(doubleValue, doubleValue),
2605                 rarely(slowCase), usually(boxPath));
2606             
2607             m_out.appendTo(boxPath, slowCase);
2608             ValueFromBlock fastResult = m_out.anchor(boxDouble(doubleValue));
2609             m_out.jump(continuation);
2610             
2611             m_out.appendTo(slowCase, continuation);
2612             ValueFromBlock slowResult = m_out.anchor(
2613                 vmCall(m_out.int64, m_out.operation(operationGetByValArrayInt), m_callFrame, base, index));
2614             m_out.jump(continuation);
2615             
2616             m_out.appendTo(continuation, lastNext);
2617             setJSValue(m_out.phi(m_out.int64, fastResult, slowResult));
2618             return;
2619         }
2620
2621         case Array::Undecided: {
2622             LValue index = lowInt32(m_node->child2());
2623
2624             speculate(OutOfBounds, noValue(), m_node, m_out.lessThan(index, m_out.int32Zero));
2625             setJSValue(m_out.constInt64(ValueUndefined));
2626             return;
2627         }
2628             
2629         case Array::DirectArguments: {
2630             LValue base = lowCell(m_node->child1());
2631             LValue index = lowInt32(m_node->child2());
2632             
2633             speculate(
2634                 ExoticObjectMode, noValue(), nullptr,
2635                 m_out.notNull(m_out.loadPtr(base, m_heaps.DirectArguments_overrides)));
2636             speculate(
2637                 ExoticObjectMode, noValue(), nullptr,
2638                 m_out.aboveOrEqual(
2639                     index,
2640                     m_out.load32NonNegative(base, m_heaps.DirectArguments_length)));
2641
2642             TypedPointer address = m_out.baseIndex(
2643                 m_heaps.DirectArguments_storage, base, m_out.zeroExtPtr(index));
2644             setJSValue(m_out.load64(address));
2645             return;
2646         }
2647             
2648         case Array::ScopedArguments: {
2649             LValue base = lowCell(m_node->child1());
2650             LValue index = lowInt32(m_node->child2());
2651             
2652             speculate(
2653                 ExoticObjectMode, noValue(), nullptr,
2654                 m_out.aboveOrEqual(
2655                     index,
2656                     m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
2657             
2658             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
2659             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
2660             
2661             LBasicBlock namedCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments named case"));
2662             LBasicBlock overflowCase = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments overflow case"));
2663             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("GetByVal ScopedArguments continuation"));
2664             
2665             m_out.branch(
2666                 m_out.aboveOrEqual(index, namedLength), unsure(overflowCase), unsure(namedCase));
2667             
2668             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
2669             
2670             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
2671             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
2672             
2673             TypedPointer address = m_out.baseIndex(
2674                 m_heaps.scopedArgumentsTableArguments, arguments, m_out.zeroExtPtr(index));
2675             LValue scopeOffset = m_out.load32(address);
2676             
2677             speculate(
2678                 ExoticObjectMode, noValue(), nullptr,
2679                 m_out.equal(scopeOffset, m_out.constInt32(ScopeOffset::invalidOffset)));
2680             
2681             address = m_out.baseIndex(
2682                 m_heaps.JSEnvironmentRecord_variables, scope, m_out.zeroExtPtr(scopeOffset));
2683             ValueFromBlock namedResult = m_out.anchor(m_out.load64(address));
2684             m_out.jump(continuation);
2685             
2686             m_out.appendTo(overflowCase, continuation);
2687             
2688             address = m_out.baseIndex(
2689                 m_heaps.ScopedArguments_overflowStorage, base,
2690                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
2691             LValue overflowValue = m_out.load64(address);
2692             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
2693             ValueFromBlock overflowResult = m_out.anchor(overflowValue);
2694             m_out.jump(continuation);
2695             
2696             m_out.appendTo(continuation, lastNext);
2697             setJSValue(m_out.phi(m_out.int64, namedResult, overflowResult));
2698             return;
2699         }
2700             
2701         case Array::Generic: {
2702             setJSValue(vmCall(
2703                 m_out.int64, m_out.operation(operationGetByVal), m_callFrame,
2704                 lowJSValue(m_node->child1()), lowJSValue(m_node->child2())));
2705             return;
2706         }
2707             
2708         case Array::String: {
2709             compileStringCharAt();
2710             return;
2711         }
2712             
2713         default: {
2714             LValue index = lowInt32(m_node->child2());
2715             LValue storage = lowStorage(m_node->child3());
2716             
2717             TypedArrayType type = m_node->arrayMode().typedArrayType();
2718             
2719             if (isTypedView(type)) {
2720                 TypedPointer pointer = TypedPointer(
2721                     m_heaps.typedArrayProperties,
2722                     m_out.add(
2723                         storage,
2724                         m_out.shl(
2725                             m_out.zeroExtPtr(index),
2726                             m_out.constIntPtr(logElementSize(type)))));
2727                 
2728                 if (isInt(type)) {
2729                     LValue result;
2730                     switch (elementSize(type)) {
2731                     case 1:
2732                         result = isSigned(type) ? m_out.load8SignExt32(pointer) :  m_out.load8ZeroExt32(pointer);
2733                         break;
2734                     case 2:
2735                         result = isSigned(type) ? m_out.load16SignExt32(pointer) :  m_out.load16ZeroExt32(pointer);
2736                         break;
2737                     case 4:
2738                         result = m_out.load32(pointer);
2739                         break;
2740                     default:
2741                         DFG_CRASH(m_graph, m_node, "Bad element size");
2742                     }
2743                     
2744                     if (elementSize(type) < 4 || isSigned(type)) {
2745                         setInt32(result);
2746                         return;
2747                     }
2748
2749                     if (m_node->shouldSpeculateInt32()) {
2750                         speculate(
2751                             Overflow, noValue(), 0, m_out.lessThan(result, m_out.int32Zero));
2752                         setInt32(result);
2753                         return;
2754                     }
2755                     
2756                     if (m_node->shouldSpeculateMachineInt()) {
2757                         setStrictInt52(m_out.zeroExt(result, m_out.int64));
2758                         return;
2759                     }
2760                     
2761                     setDouble(m_out.unsignedToDouble(result));
2762                     return;
2763                 }
2764             
2765                 ASSERT(isFloat(type));
2766                 
2767                 LValue result;
2768                 switch (type) {
2769                 case TypeFloat32:
2770                     result = m_out.floatToDouble(m_out.loadFloat(pointer));
2771                     break;
2772                 case TypeFloat64:
2773                     result = m_out.loadDouble(pointer);
2774                     break;
2775                 default:
2776                     DFG_CRASH(m_graph, m_node, "Bad typed array type");
2777                 }
2778                 
2779                 setDouble(result);
2780                 return;
2781             }
2782             
2783             DFG_CRASH(m_graph, m_node, "Bad array type");
2784             return;
2785         } }
2786     }
2787     
2788     void compileGetMyArgumentByVal()
2789     {
2790         InlineCallFrame* inlineCallFrame = m_node->child1()->origin.semantic.inlineCallFrame;
2791         
2792         LValue index = lowInt32(m_node->child2());
2793         
2794         LValue limit;
2795         if (inlineCallFrame && !inlineCallFrame->isVarargs())
2796             limit = m_out.constInt32(inlineCallFrame->arguments.size() - 1);
2797         else {
2798             VirtualRegister argumentCountRegister;
2799             if (!inlineCallFrame)
2800                 argumentCountRegister = VirtualRegister(JSStack::ArgumentCount);
2801             else
2802                 argumentCountRegister = inlineCallFrame->argumentCountRegister;
2803             limit = m_out.sub(m_out.load32(payloadFor(argumentCountRegister)), m_out.int32One);
2804         }
2805         
2806         speculate(ExoticObjectMode, noValue(), 0, m_out.aboveOrEqual(index, limit));
2807         
2808         TypedPointer base;
2809         if (inlineCallFrame) {
2810             if (inlineCallFrame->arguments.size() <= 1) {
2811                 // We should have already exited due to the bounds check, above. Just tell the
2812                 // compiler that anything dominated by this instruction is not reachable, so
2813                 // that we don't waste time generating such code. This will also plant some
2814                 // kind of crashing instruction so that if by some fluke the bounds check didn't
2815                 // work, we'll crash in an easy-to-see way.
2816                 didAlreadyTerminate();
2817                 return;
2818             }
2819             base = addressFor(inlineCallFrame->arguments[1].virtualRegister());
2820         } else
2821             base = addressFor(virtualRegisterForArgument(1));
2822         
2823         LValue pointer = m_out.baseIndex(
2824             base.value(), m_out.zeroExt(index, m_out.intPtr), ScaleEight);
2825         setJSValue(m_out.load64(TypedPointer(m_heaps.variables.atAnyIndex(), pointer)));
2826     }
2827     
2828     void compilePutByVal()
2829     {
2830         Edge child1 = m_graph.varArgChild(m_node, 0);
2831         Edge child2 = m_graph.varArgChild(m_node, 1);
2832         Edge child3 = m_graph.varArgChild(m_node, 2);
2833         Edge child4 = m_graph.varArgChild(m_node, 3);
2834         Edge child5 = m_graph.varArgChild(m_node, 4);
2835         
2836         switch (m_node->arrayMode().type()) {
2837         case Array::Generic: {
2838             V_JITOperation_EJJJ operation;
2839             if (m_node->op() == PutByValDirect) {
2840                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
2841                     operation = operationPutByValDirectStrict;
2842                 else
2843                     operation = operationPutByValDirectNonStrict;
2844             } else {
2845                 if (m_graph.isStrictModeFor(m_node->origin.semantic))
2846                     operation = operationPutByValStrict;
2847                 else
2848                     operation = operationPutByValNonStrict;
2849             }
2850                 
2851             vmCall(
2852                 m_out.voidType, m_out.operation(operation), m_callFrame,
2853                 lowJSValue(child1), lowJSValue(child2), lowJSValue(child3));
2854             return;
2855         }
2856             
2857         default:
2858             break;
2859         }
2860
2861         LValue base = lowCell(child1);
2862         LValue index = lowInt32(child2);
2863         LValue storage = lowStorage(child4);
2864         
2865         switch (m_node->arrayMode().type()) {
2866         case Array::Int32:
2867         case Array::Double:
2868         case Array::Contiguous: {
2869             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal continuation"));
2870             LBasicBlock outerLastNext = m_out.appendTo(m_out.m_block, continuation);
2871             
2872             switch (m_node->arrayMode().type()) {
2873             case Array::Int32:
2874             case Array::Contiguous: {
2875                 LValue value = lowJSValue(child3, ManualOperandSpeculation);
2876                 
2877                 if (m_node->arrayMode().type() == Array::Int32)
2878                     FTL_TYPE_CHECK(jsValueValue(value), child3, SpecInt32, isNotInt32(value));
2879                 
2880                 TypedPointer elementPointer = m_out.baseIndex(
2881                     m_node->arrayMode().type() == Array::Int32 ?
2882                     m_heaps.indexedInt32Properties : m_heaps.indexedContiguousProperties,
2883                     storage, m_out.zeroExtPtr(index), provenValue(child2));
2884                 
2885                 if (m_node->op() == PutByValAlias) {
2886                     m_out.store64(value, elementPointer);
2887                     break;
2888                 }
2889                 
2890                 contiguousPutByValOutOfBounds(
2891                     codeBlock()->isStrictMode()
2892                     ? operationPutByValBeyondArrayBoundsStrict
2893                     : operationPutByValBeyondArrayBoundsNonStrict,
2894                     base, storage, index, value, continuation);
2895                 
2896                 m_out.store64(value, elementPointer);
2897                 break;
2898             }
2899                 
2900             case Array::Double: {
2901                 LValue value = lowDouble(child3);
2902                 
2903                 FTL_TYPE_CHECK(
2904                     doubleValue(value), child3, SpecDoubleReal,
2905                     m_out.doubleNotEqualOrUnordered(value, value));
2906                 
2907                 TypedPointer elementPointer = m_out.baseIndex(
2908                     m_heaps.indexedDoubleProperties, storage, m_out.zeroExtPtr(index),
2909                     provenValue(child2));
2910                 
2911                 if (m_node->op() == PutByValAlias) {
2912                     m_out.storeDouble(value, elementPointer);
2913                     break;
2914                 }
2915                 
2916                 contiguousPutByValOutOfBounds(
2917                     codeBlock()->isStrictMode()
2918                     ? operationPutDoubleByValBeyondArrayBoundsStrict
2919                     : operationPutDoubleByValBeyondArrayBoundsNonStrict,
2920                     base, storage, index, value, continuation);
2921                 
2922                 m_out.storeDouble(value, elementPointer);
2923                 break;
2924             }
2925                 
2926             default:
2927                 DFG_CRASH(m_graph, m_node, "Bad array type");
2928             }
2929
2930             m_out.jump(continuation);
2931             m_out.appendTo(continuation, outerLastNext);
2932             return;
2933         }
2934             
2935         default:
2936             TypedArrayType type = m_node->arrayMode().typedArrayType();
2937             
2938             if (isTypedView(type)) {
2939                 TypedPointer pointer = TypedPointer(
2940                     m_heaps.typedArrayProperties,
2941                     m_out.add(
2942                         storage,
2943                         m_out.shl(
2944                             m_out.zeroExt(index, m_out.intPtr),
2945                             m_out.constIntPtr(logElementSize(type)))));
2946                 
2947                 Output::StoreType storeType;
2948                 LValue valueToStore;
2949                 
2950                 if (isInt(type)) {
2951                     LValue intValue;
2952                     switch (child3.useKind()) {
2953                     case Int52RepUse:
2954                     case Int32Use: {
2955                         if (child3.useKind() == Int32Use)
2956                             intValue = lowInt32(child3);
2957                         else
2958                             intValue = m_out.castToInt32(lowStrictInt52(child3));
2959
2960                         if (isClamped(type)) {
2961                             ASSERT(elementSize(type) == 1);
2962                             
2963                             LBasicBlock atLeastZero = FTL_NEW_BLOCK(m_out, ("PutByVal int clamp atLeastZero"));
2964                             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal int clamp continuation"));
2965                             
2966                             Vector<ValueFromBlock, 2> intValues;
2967                             intValues.append(m_out.anchor(m_out.int32Zero));
2968                             m_out.branch(
2969                                 m_out.lessThan(intValue, m_out.int32Zero),
2970                                 unsure(continuation), unsure(atLeastZero));
2971                             
2972                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, continuation);
2973                             
2974                             intValues.append(m_out.anchor(m_out.select(
2975                                 m_out.greaterThan(intValue, m_out.constInt32(255)),
2976                                 m_out.constInt32(255),
2977                                 intValue)));
2978                             m_out.jump(continuation);
2979                             
2980                             m_out.appendTo(continuation, lastNext);
2981                             intValue = m_out.phi(m_out.int32, intValues);
2982                         }
2983                         break;
2984                     }
2985                         
2986                     case DoubleRepUse: {
2987                         LValue doubleValue = lowDouble(child3);
2988                         
2989                         if (isClamped(type)) {
2990                             ASSERT(elementSize(type) == 1);
2991                             
2992                             LBasicBlock atLeastZero = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp atLeastZero"));
2993                             LBasicBlock withinRange = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp withinRange"));
2994                             LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal double clamp continuation"));
2995                             
2996                             Vector<ValueFromBlock, 3> intValues;
2997                             intValues.append(m_out.anchor(m_out.int32Zero));
2998                             m_out.branch(
2999                                 m_out.doubleLessThanOrUnordered(doubleValue, m_out.doubleZero),
3000                                 unsure(continuation), unsure(atLeastZero));
3001                             
3002                             LBasicBlock lastNext = m_out.appendTo(atLeastZero, withinRange);
3003                             intValues.append(m_out.anchor(m_out.constInt32(255)));
3004                             m_out.branch(
3005                                 m_out.doubleGreaterThan(doubleValue, m_out.constDouble(255)),
3006                                 unsure(continuation), unsure(withinRange));
3007                             
3008                             m_out.appendTo(withinRange, continuation);
3009                             intValues.append(m_out.anchor(m_out.doubleToInt(doubleValue)));
3010                             m_out.jump(continuation);
3011                             
3012                             m_out.appendTo(continuation, lastNext);
3013                             intValue = m_out.phi(m_out.int32, intValues);
3014                         } else
3015                             intValue = doubleToInt32(doubleValue);
3016                         break;
3017                     }
3018                         
3019                     default:
3020                         DFG_CRASH(m_graph, m_node, "Bad use kind");
3021                     }
3022
3023                     valueToStore = intValue;
3024                     switch (elementSize(type)) {
3025                     case 1:
3026                         storeType = Output::Store32As8;
3027                         break;
3028                     case 2:
3029                         storeType = Output::Store32As16;
3030                         break;
3031                     case 4:
3032                         storeType = Output::Store32;
3033                         break;
3034                     default:
3035                         DFG_CRASH(m_graph, m_node, "Bad element size");
3036                     }
3037                 } else /* !isInt(type) */ {
3038                     LValue value = lowDouble(child3);
3039                     switch (type) {
3040                     case TypeFloat32:
3041                         valueToStore = m_out.doubleToFloat(value);
3042                         storeType = Output::StoreFloat;
3043                         break;
3044                     case TypeFloat64:
3045                         valueToStore = value;
3046                         storeType = Output::StoreDouble;
3047                         break;
3048                     default:
3049                         DFG_CRASH(m_graph, m_node, "Bad typed array type");
3050                     }
3051                 }
3052                 
3053                 if (m_node->arrayMode().isInBounds() || m_node->op() == PutByValAlias)
3054                     m_out.store(valueToStore, pointer, storeType);
3055                 else {
3056                     LBasicBlock isInBounds = FTL_NEW_BLOCK(m_out, ("PutByVal typed array in bounds case"));
3057                     LBasicBlock continuation = FTL_NEW_BLOCK(m_out, ("PutByVal typed array continuation"));
3058                     
3059                     m_out.branch(
3060                         m_out.aboveOrEqual(index, lowInt32(child5)),
3061                         unsure(continuation), unsure(isInBounds));
3062                     
3063                     LBasicBlock lastNext = m_out.appendTo(isInBounds, continuation);
3064                     m_out.store(valueToStore, pointer, storeType);
3065                     m_out.jump(continuation);
3066                     
3067                     m_out.appendTo(continuation, lastNext);
3068                 }
3069                 
3070                 return;
3071             }
3072             
3073             DFG_CRASH(m_graph, m_node, "Bad array type");
3074             break;
3075         }
3076     }
3077
3078     void compilePutAccessorById()
3079     {
3080         LValue base = lowCell(m_node->child1());
3081         LValue accessor = lowCell(m_node->child2());
3082         auto uid = m_graph.identifiers()[m_node->identifierNumber()];
3083         vmCall(
3084             m_out.voidType,
3085             m_out.operation(m_node->op() == PutGetterById ? operationPutGetterById : operationPutSetterById),
3086             m_callFrame, base, m_out.constIntPtr(uid), m_out.constInt32(m_node->accessorAttributes()), accessor);
3087     }
3088
3089     void compilePutGetterSetterById()
3090     {
3091         LValue base = lowCell(m_node->child1());
3092         LValue getter = lowJSValue(m_node->child2());
3093         LValue setter = lowJSValue(m_node->child3());
3094         auto uid = m_graph.identifiers()[m_node->identifierNumber()];
3095         vmCall(
3096             m_out.voidType, m_out.operation(operationPutGetterSetter),
3097             m_callFrame, base, m_out.constIntPtr(uid), m_out.constInt32(m_node->accessorAttributes()), getter, setter);
3098
3099     }
3100
3101     void compilePutAccessorByVal()
3102     {
3103         LValue base = lowCell(m_node->child1());
3104         LValue subscript = lowJSValue(m_node->child2());
3105         LValue accessor = lowCell(m_node->child3());
3106         vmCall(