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