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