Remove poisoning of typed array vector
[WebKit-https.git] / Source / JavaScriptCore / llint / LowLevelInterpreter.asm
1 # Copyright (C) 2011-2018 Apple Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions
5 # are met:
6 # 1. Redistributions of source code must retain the above copyright
7 #    notice, this list of conditions and the following disclaimer.
8 # 2. Redistributions in binary form must reproduce the above copyright
9 #    notice, this list of conditions and the following disclaimer in the
10 #    documentation and/or other materials provided with the distribution.
11 #
12 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
13 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
14 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
15 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
16 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
17 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
18 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
19 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
20 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
21 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
22 # THE POSSIBILITY OF SUCH DAMAGE.
23
24 # Crash course on the language that this is written in (which I just call
25 # "assembly" even though it's more than that):
26 #
27 # - Mostly gas-style operand ordering. The last operand tends to be the
28 #   destination. So "a := b" is written as "mov b, a". But unlike gas,
29 #   comparisons are in-order, so "if (a < b)" is written as
30 #   "bilt a, b, ...".
31 #
32 # - "b" = byte, "h" = 16-bit word, "i" = 32-bit word, "p" = pointer.
33 #   For 32-bit, "i" and "p" are interchangeable except when an op supports one
34 #   but not the other.
35 #
36 # - In general, valid operands for macro invocations and instructions are
37 #   registers (eg "t0"), addresses (eg "4[t0]"), base-index addresses
38 #   (eg "7[t0, t1, 2]"), absolute addresses (eg "0xa0000000[]"), or labels
39 #   (eg "_foo" or ".foo"). Macro invocations can also take anonymous
40 #   macros as operands. Instructions cannot take anonymous macros.
41 #
42 # - Labels must have names that begin with either "_" or ".".  A "." label
43 #   is local and gets renamed before code gen to minimize namespace
44 #   pollution. A "_" label is an extern symbol (i.e. ".globl"). The "_"
45 #   may or may not be removed during code gen depending on whether the asm
46 #   conventions for C name mangling on the target platform mandate a "_"
47 #   prefix.
48 #
49 # - A "macro" is a lambda expression, which may be either anonymous or
50 #   named. But this has caveats. "macro" can take zero or more arguments,
51 #   which may be macros or any valid operands, but it can only return
52 #   code. But you can do Turing-complete things via continuation passing
53 #   style: "macro foo (a, b) b(a, a) end foo(foo, foo)". Actually, don't do
54 #   that, since you'll just crash the assembler.
55 #
56 # - An "if" is a conditional on settings. Any identifier supplied in the
57 #   predicate of an "if" is assumed to be a #define that is available
58 #   during code gen. So you can't use "if" for computation in a macro, but
59 #   you can use it to select different pieces of code for different
60 #   platforms.
61 #
62 # - Arguments to macros follow lexical scoping rather than dynamic scoping.
63 #   Const's also follow lexical scoping and may override (hide) arguments
64 #   or other consts. All variables (arguments and constants) can be bound
65 #   to operands. Additionally, arguments (but not constants) can be bound
66 #   to macros.
67
68 # The following general-purpose registers are available:
69 #
70 #  - cfr and sp hold the call frame and (native) stack pointer respectively.
71 #  They are callee-save registers, and guaranteed to be distinct from all other
72 #  registers on all architectures.
73 #
74 #  - lr is defined on non-X86 architectures (ARM64, ARM64E, ARMv7, ARM,
75 #  ARMv7_TRADITIONAL, MIPS and CLOOP) and holds the return PC
76 #
77 #  - pc holds the (native) program counter on 32-bits ARM architectures (ARM,
78 #  ARMv7, ARMv7_TRADITIONAL)
79 #
80 #  - t0, t1, t2, t3, t4 and optionally t5 are temporary registers that can get trashed on
81 #  calls, and are pairwise distinct registers. t4 holds the JS program counter, so use
82 #  with caution in opcodes (actually, don't use it in opcodes at all, except as PC).
83 #
84 #  - r0 and r1 are the platform's customary return registers, and thus are
85 #  two distinct registers
86 #
87 #  - a0, a1, a2 and a3 are the platform's customary argument registers, and
88 #  thus are pairwise distinct registers. Be mindful that:
89 #    + On X86, there are no argument registers. a0 and a1 are edx and
90 #    ecx following the fastcall convention, but you should still use the stack
91 #    to pass your arguments. The cCall2 and cCall4 macros do this for you.
92 #    + On X86_64_WIN, you should allocate space on the stack for the arguments,
93 #    and the return convention is weird for > 8 bytes types. The only place we
94 #    use > 8 bytes return values is on a cCall, and cCall2 and cCall4 handle
95 #    this for you.
96 #
97 #  - The only registers guaranteed to be caller-saved are r0, r1, a0, a1 and a2, and
98 #  you should be mindful of that in functions that are called directly from C.
99 #  If you need more registers, you should push and pop them like a good
100 #  assembly citizen, because any other register will be callee-saved on X86.
101 #
102 # You can additionally assume:
103 #
104 #  - a3, t2, t3, t4 and t5 are never return registers; t0, t1, a0, a1 and a2
105 #  can be return registers.
106 #
107 #  - t4 and t5 are never argument registers, t3 can only be a3, t1 can only be
108 #  a1; but t0 and t2 can be either a0 or a2.
109 #
110 #  - On 64 bits, there are callee-save registers named csr0, csr1, ... csrN.
111 #  The last three csr registers are used used to store the PC base and
112 #  two special tag values. Don't use them for anything else.
113 #
114 # Additional platform-specific details (you shouldn't rely on this remaining
115 # true):
116 #
117 #  - For consistency with the baseline JIT, t0 is always r0 (and t1 is always
118 #  r1 on 32 bits platforms). You should use the r version when you need return
119 #  registers, and the t version otherwise: code using t0 (or t1) should still
120 #  work if swapped with e.g. t3, while code using r0 (or r1) should not. There
121 #  *may* be legacy code relying on this.
122 #
123 #  - On all platforms other than X86, t0 can only be a0 and t2 can only be a2.
124 #
125 #  - On all platforms other than X86 and X86_64, a2 is not a return register.
126 #  a2 is r0 on X86 (because we have so few registers) and r1 on X86_64 (because
127 #  the ABI enforces it).
128 #
129 # The following floating-point registers are available:
130 #
131 #  - ft0-ft5 are temporary floating-point registers that get trashed on calls,
132 #  and are pairwise distinct.
133 #
134 #  - fa0 and fa1 are the platform's customary floating-point argument
135 #  registers, and are both distinct. On 64-bits platforms, fa2 and fa3 are
136 #  additional floating-point argument registers.
137 #
138 #  - fr is the platform's customary floating-point return register
139 #
140 # You can assume that ft1-ft5 or fa1-fa3 are never fr, and that ftX is never
141 # faY if X != Y.
142
143 # First come the common protocols that both interpreters use. Note that each
144 # of these must have an ASSERT() in LLIntData.cpp
145
146 # Work-around for the fact that the toolchain's awareness of armv7k / armv7s
147 # results in a separate slab in the fat binary, yet the offlineasm doesn't know
148 # to expect it.
149 if ARMv7k
150 end
151 if ARMv7s
152 end
153
154 # These declarations must match interpreter/JSStack.h.
155
156 const PtrSize = constexpr (sizeof(void*))
157
158 if JSVALUE64
159     const CallFrameHeaderSlots = 5
160 else
161     const CallFrameHeaderSlots = 4
162     const CallFrameAlignSlots = 1
163 end
164 const SlotSize = 8
165
166 const JSLexicalEnvironment_variables = (sizeof JSLexicalEnvironment + SlotSize - 1) & ~(SlotSize - 1)
167 const DirectArguments_storage = (sizeof DirectArguments + SlotSize - 1) & ~(SlotSize - 1)
168
169 const StackAlignment = 16
170 const StackAlignmentSlots = 2
171 const StackAlignmentMask = StackAlignment - 1
172
173 const CallerFrameAndPCSize = 2 * PtrSize
174
175 const CallerFrame = 0
176 const ReturnPC = CallerFrame + PtrSize
177 const CodeBlock = ReturnPC + PtrSize
178 const Callee = CodeBlock + SlotSize
179 const ArgumentCount = Callee + SlotSize
180 const ThisArgumentOffset = ArgumentCount + SlotSize
181 const FirstArgumentOffset = ThisArgumentOffset + SlotSize
182 const CallFrameHeaderSize = ThisArgumentOffset
183
184 # Some value representation constants.
185 if JSVALUE64
186     const TagBitTypeOther = 0x2
187     const TagBitBool      = 0x4
188     const TagBitUndefined = 0x8
189     const ValueEmpty      = 0x0
190     const ValueFalse      = TagBitTypeOther | TagBitBool
191     const ValueTrue       = TagBitTypeOther | TagBitBool | 1
192     const ValueUndefined  = TagBitTypeOther | TagBitUndefined
193     const ValueNull       = TagBitTypeOther
194     const TagTypeNumber   = 0xffff000000000000
195     const TagMask         = TagTypeNumber | TagBitTypeOther
196 else
197     const Int32Tag = -1
198     const BooleanTag = -2
199     const NullTag = -3
200     const UndefinedTag = -4
201     const CellTag = -5
202     const EmptyValueTag = -6
203     const DeletedValueTag = -7
204     const LowestTag = DeletedValueTag
205 end
206
207 # PutByIdFlags data
208 const PutByIdPrimaryTypeMask = constexpr PutByIdPrimaryTypeMask
209 const PutByIdPrimaryTypeSecondary = constexpr PutByIdPrimaryTypeSecondary
210 const PutByIdPrimaryTypeObjectWithStructure = constexpr PutByIdPrimaryTypeObjectWithStructure
211 const PutByIdPrimaryTypeObjectWithStructureOrOther = constexpr PutByIdPrimaryTypeObjectWithStructureOrOther
212 const PutByIdSecondaryTypeMask = constexpr PutByIdSecondaryTypeMask
213 const PutByIdSecondaryTypeBottom = constexpr PutByIdSecondaryTypeBottom
214 const PutByIdSecondaryTypeBoolean = constexpr PutByIdSecondaryTypeBoolean
215 const PutByIdSecondaryTypeOther = constexpr PutByIdSecondaryTypeOther
216 const PutByIdSecondaryTypeInt32 = constexpr PutByIdSecondaryTypeInt32
217 const PutByIdSecondaryTypeNumber = constexpr PutByIdSecondaryTypeNumber
218 const PutByIdSecondaryTypeString = constexpr PutByIdSecondaryTypeString
219 const PutByIdSecondaryTypeSymbol = constexpr PutByIdSecondaryTypeSymbol
220 const PutByIdSecondaryTypeObject = constexpr PutByIdSecondaryTypeObject
221 const PutByIdSecondaryTypeObjectOrOther = constexpr PutByIdSecondaryTypeObjectOrOther
222 const PutByIdSecondaryTypeTop = constexpr PutByIdSecondaryTypeTop
223
224 const CallOpCodeSize = 9
225
226 if X86_64 or ARM64 or ARM64E or C_LOOP
227     const maxFrameExtentForSlowPathCall = 0
228 elsif ARM or ARMv7_TRADITIONAL or ARMv7
229     const maxFrameExtentForSlowPathCall = 24
230 elsif X86 or X86_WIN
231     const maxFrameExtentForSlowPathCall = 40
232 elsif MIPS
233     const maxFrameExtentForSlowPathCall = 40
234 elsif X86_64_WIN
235     const maxFrameExtentForSlowPathCall = 64
236 end
237
238 if X86_64 or X86_64_WIN or ARM64 or ARM64E
239     const CalleeSaveSpaceAsVirtualRegisters = 3
240 else
241     const CalleeSaveSpaceAsVirtualRegisters = 0
242 end
243
244 const CalleeSaveSpaceStackAligned = (CalleeSaveSpaceAsVirtualRegisters * SlotSize + StackAlignment - 1) & ~StackAlignmentMask
245
246
247 # Watchpoint states
248 const ClearWatchpoint = constexpr ClearWatchpoint
249 const IsWatched = constexpr IsWatched
250 const IsInvalidated = constexpr IsInvalidated
251
252 # ShadowChicken data
253 const ShadowChickenTailMarker = constexpr ShadowChicken::Packet::tailMarkerValue
254
255 # ArithProfile data
256 const ArithProfileInt = 0x400000
257 const ArithProfileIntInt = 0x480000
258 const ArithProfileNumber = 0x800000
259 const ArithProfileNumberInt = 0x880000
260 const ArithProfileNumberNumber = 0x900000
261 const ArithProfileIntNumber = 0x500000
262
263 # Pointer Tags
264 const BytecodePtrTag = constexpr BytecodePtrTag
265 const CodeEntryPtrTag = constexpr CodeEntryPtrTag
266 const CodeEntryWithArityCheckPtrTag = constexpr CodeEntryWithArityCheckPtrTag
267 const ExceptionHandlerPtrTag = constexpr ExceptionHandlerPtrTag
268 const LLIntCallICPtrTag = constexpr LLIntCallICPtrTag
269 const NoPtrTag = constexpr NoPtrTag
270 const SlowPathPtrTag = constexpr SlowPathPtrTag
271
272 # Some register conventions.
273 if JSVALUE64
274     # - Use a pair of registers to represent the PC: one register for the
275     #   base of the bytecodes, and one register for the index.
276     # - The PC base (or PB for short) must be stored in a callee-save register.
277     # - C calls are still given the Instruction* rather than the PC index.
278     #   This requires an add before the call, and a sub after.
279     const PC = t4 # When changing this, make sure LLIntPC is up to date in LLIntPCRanges.h
280     if ARM64 or ARM64E
281         const PB = csr7
282         const tagTypeNumber = csr8
283         const tagMask = csr9
284     elsif X86_64
285         const PB = csr2
286         const tagTypeNumber = csr3
287         const tagMask = csr4
288     elsif X86_64_WIN
289         const PB = csr4
290         const tagTypeNumber = csr5
291         const tagMask = csr6
292     elsif C_LOOP
293         const PB = csr0
294         const tagTypeNumber = csr1
295         const tagMask = csr2
296     end
297
298     macro loadisFromInstruction(offset, dest)
299         loadis offset * 8[PB, PC, 8], dest
300     end
301     
302     macro loadpFromInstruction(offset, dest)
303         loadp offset * 8[PB, PC, 8], dest
304     end
305
306     macro loadisFromStruct(offset, dest)
307         loadis offset[PB, PC, 8], dest
308     end
309
310     macro loadpFromStruct(offset, dest)
311         loadp offset[PB, PC, 8], dest
312     end
313
314     macro storeisToInstruction(value, offset)
315         storei value, offset * 8[PB, PC, 8]
316     end
317
318     macro storepToInstruction(value, offset)
319         storep value, offset * 8[PB, PC, 8]
320     end
321
322     macro storeisFromStruct(value, offset)
323         storei value, offset[PB, PC, 8]
324     end
325
326     macro storepFromStruct(value, offset)
327         storep value, offset[PB, PC, 8]
328     end
329
330 else
331     const PC = t4 # When changing this, make sure LLIntPC is up to date in LLIntPCRanges.h
332     macro loadisFromInstruction(offset, dest)
333         loadis offset * 4[PC], dest
334     end
335     
336     macro loadpFromInstruction(offset, dest)
337         loadp offset * 4[PC], dest
338     end
339
340     macro storeisToInstruction(value, offset)
341         storei value, offset * 4[PC]
342     end
343
344     macro loadisFromStruct(offset, dest)
345         loadis offset[PC], dest
346     end
347
348     macro loadpFromStruct(offset, dest)
349         loadp offset[PC], dest
350     end
351
352     macro storeisToStruct(value, offset)
353         storei value, offset[PC]
354     end
355 end
356
357 if X86_64_WIN
358     const extraTempReg = t0
359 else
360     const extraTempReg = t5
361 end
362
363 # Constants for reasoning about value representation.
364 if BIG_ENDIAN
365     const TagOffset = 0
366     const PayloadOffset = 4
367 else
368     const TagOffset = 4
369     const PayloadOffset = 0
370 end
371
372 # Constant for reasoning about butterflies.
373 const IsArray                  = constexpr IsArray
374 const IndexingShapeMask        = constexpr IndexingShapeMask
375 const NoIndexingShape          = constexpr NoIndexingShape
376 const Int32Shape               = constexpr Int32Shape
377 const DoubleShape              = constexpr DoubleShape
378 const ContiguousShape          = constexpr ContiguousShape
379 const ArrayStorageShape        = constexpr ArrayStorageShape
380 const SlowPutArrayStorageShape = constexpr SlowPutArrayStorageShape
381
382 # Type constants.
383 const StringType = constexpr StringType
384 const SymbolType = constexpr SymbolType
385 const ObjectType = constexpr ObjectType
386 const FinalObjectType = constexpr FinalObjectType
387 const JSFunctionType = constexpr JSFunctionType
388 const ArrayType = constexpr ArrayType
389 const DerivedArrayType = constexpr DerivedArrayType
390 const ProxyObjectType = constexpr ProxyObjectType
391
392 # The typed array types need to be numbered in a particular order because of the manually written
393 # switch statement in get_by_val and put_by_val.
394 const Int8ArrayType = constexpr Int8ArrayType
395 const Uint8ArrayType = constexpr Uint8ArrayType
396 const Uint8ClampedArrayType = constexpr Uint8ClampedArrayType
397 const Int16ArrayType = constexpr Int16ArrayType
398 const Uint16ArrayType = constexpr Uint16ArrayType
399 const Int32ArrayType = constexpr Int32ArrayType
400 const Uint32ArrayType = constexpr Uint32ArrayType
401 const Float32ArrayType = constexpr Float32ArrayType
402 const Float64ArrayType = constexpr Float64ArrayType
403
404 const FirstTypedArrayType = constexpr FirstTypedArrayType
405 const NumberOfTypedArrayTypesExcludingDataView = constexpr NumberOfTypedArrayTypesExcludingDataView
406
407 # Type flags constants.
408 const MasqueradesAsUndefined = constexpr MasqueradesAsUndefined
409 const ImplementsDefaultHasInstance = constexpr ImplementsDefaultHasInstance
410
411 # Bytecode operand constants.
412 const FirstConstantRegisterIndex = constexpr FirstConstantRegisterIndex
413
414 # Code type constants.
415 const GlobalCode = constexpr GlobalCode
416 const EvalCode = constexpr EvalCode
417 const FunctionCode = constexpr FunctionCode
418 const ModuleCode = constexpr ModuleCode
419
420 # The interpreter steals the tag word of the argument count.
421 const LLIntReturnPC = ArgumentCount + TagOffset
422
423 # String flags.
424 const HashFlags8BitBuffer = 8
425
426 # Copied from PropertyOffset.h
427 const firstOutOfLineOffset = 100
428
429 # ResolveType
430 const GlobalProperty = constexpr GlobalProperty
431 const GlobalVar = constexpr GlobalVar
432 const GlobalLexicalVar = constexpr GlobalLexicalVar
433 const ClosureVar = constexpr ClosureVar
434 const LocalClosureVar = constexpr LocalClosureVar
435 const ModuleVar = constexpr ModuleVar
436 const GlobalPropertyWithVarInjectionChecks = constexpr GlobalPropertyWithVarInjectionChecks
437 const GlobalVarWithVarInjectionChecks = constexpr GlobalVarWithVarInjectionChecks
438 const GlobalLexicalVarWithVarInjectionChecks = constexpr GlobalLexicalVarWithVarInjectionChecks
439 const ClosureVarWithVarInjectionChecks = constexpr ClosureVarWithVarInjectionChecks
440
441 const ResolveTypeMask = constexpr GetPutInfo::typeBits
442 const InitializationModeMask = constexpr GetPutInfo::initializationBits
443 const InitializationModeShift = constexpr GetPutInfo::initializationShift
444 const NotInitialization = constexpr InitializationMode::NotInitialization
445
446 const MarkedBlockSize = constexpr MarkedBlock::blockSize
447 const MarkedBlockMask = ~(MarkedBlockSize - 1)
448 const MarkedBlockFooterOffset = constexpr MarkedBlock::offsetOfFooter
449
450 const BlackThreshold = constexpr blackThreshold
451
452 # Allocation constants
453 if JSVALUE64
454     const JSFinalObjectSizeClassIndex = 1
455 else
456     const JSFinalObjectSizeClassIndex = 3
457 end
458
459 # This must match wtf/Vector.h
460 const VectorBufferOffset = 0
461 if JSVALUE64
462     const VectorSizeOffset = 12
463 else
464     const VectorSizeOffset = 8
465 end
466
467 # Some common utilities.
468 macro crash()
469     if C_LOOP
470         cloopCrash
471     else
472         call _llint_crash
473     end
474 end
475
476 macro assert(assertion)
477     if ASSERT_ENABLED
478         assertion(.ok)
479         crash()
480     .ok:
481     end
482 end
483
484 # The probe macro can be used to insert some debugging code without perturbing scalar
485 # registers. Presently, the probe macro only preserves scalar registers. Hence, the
486 # C probe callback function should not trash floating point registers.
487 #
488 # The macro you pass to probe() can pass whatever registers you like to your probe
489 # callback function. However, you need to be mindful of which of the registers are
490 # also used as argument registers, and ensure that you don't trash the register value
491 # before storing it in the probe callback argument register that you desire.
492 #
493 # Here's an example of how it's used:
494 #
495 #     probe(
496 #         macro()
497 #             move cfr, a0 # pass the ExecState* as arg0.
498 #             move t0, a1 # pass the value of register t0 as arg1.
499 #             call _cProbeCallbackFunction # to do whatever you want.
500 #         end
501 #     )
502 #
503 if X86_64 or ARM64 or ARM64E
504     macro probe(action)
505         # save all the registers that the LLInt may use.
506         if ARM64 or ARM64E
507             push cfr, lr
508         end
509         push a0, a1
510         push a2, a3
511         push t0, t1
512         push t2, t3
513         push t4, t5
514         if ARM64 or ARM64E
515             push csr0, csr1
516             push csr2, csr3
517             push csr4, csr5
518             push csr6, csr7
519             push csr8, csr9
520         end
521
522         action()
523
524         # restore all the registers we saved previously.
525         if ARM64 or ARM64E
526             pop csr9, csr8
527             pop csr7, csr6
528             pop csr5, csr4
529             pop csr3, csr2
530             pop csr1, csr0
531         end
532         pop t5, t4
533         pop t3, t2
534         pop t1, t0
535         pop a3, a2
536         pop a1, a0
537         if ARM64 or ARM64E
538             pop lr, cfr
539         end
540     end
541 else
542     macro probe(action)
543     end
544 end
545
546 macro checkStackPointerAlignment(tempReg, location)
547     if ARM64 or ARM64E or C_LOOP
548         # ARM64 and ARM64E will check for us!
549         # C_LOOP does not need the alignment, and can use a little perf
550         # improvement from avoiding useless work.
551     else
552         if ARM or ARMv7 or ARMv7_TRADITIONAL
553             # ARM can't do logical ops with the sp as a source
554             move sp, tempReg
555             andp StackAlignmentMask, tempReg
556         else
557             andp sp, StackAlignmentMask, tempReg
558         end
559         btpz tempReg, .stackPointerOkay
560         move location, tempReg
561         break
562     .stackPointerOkay:
563     end
564 end
565
566 if C_LOOP or ARM64 or ARM64E or X86_64 or X86_64_WIN
567     const CalleeSaveRegisterCount = 0
568 elsif ARM or ARMv7_TRADITIONAL or ARMv7
569     const CalleeSaveRegisterCount = 7
570 elsif MIPS
571     const CalleeSaveRegisterCount = 1
572 elsif X86 or X86_WIN
573     const CalleeSaveRegisterCount = 3
574 end
575
576 const CalleeRegisterSaveSize = CalleeSaveRegisterCount * PtrSize
577
578 # VMEntryTotalFrameSize includes the space for struct VMEntryRecord and the
579 # callee save registers rounded up to keep the stack aligned
580 const VMEntryTotalFrameSize = (CalleeRegisterSaveSize + sizeof VMEntryRecord + StackAlignment - 1) & ~StackAlignmentMask
581
582 macro pushCalleeSaves()
583     if C_LOOP or ARM64 or ARM64E or X86_64 or X86_64_WIN
584     elsif ARM or ARMv7_TRADITIONAL
585         emit "push {r4-r10}"
586     elsif ARMv7
587         emit "push {r4-r6, r8-r11}"
588     elsif MIPS
589         emit "addiu $sp, $sp, -4"
590         emit "sw $s4, 0($sp)"
591         # save $gp to $s4 so that we can restore it after a function call
592         emit "move $s4, $gp"
593     elsif X86
594         emit "push %esi"
595         emit "push %edi"
596         emit "push %ebx"
597     elsif X86_WIN
598         emit "push esi"
599         emit "push edi"
600         emit "push ebx"
601     end
602 end
603
604 macro popCalleeSaves()
605     if C_LOOP or ARM64 or ARM64E or X86_64 or X86_64_WIN
606     elsif ARM or ARMv7_TRADITIONAL
607         emit "pop {r4-r10}"
608     elsif ARMv7
609         emit "pop {r4-r6, r8-r11}"
610     elsif MIPS
611         emit "lw $s4, 0($sp)"
612         emit "addiu $sp, $sp, 4"
613     elsif X86
614         emit "pop %ebx"
615         emit "pop %edi"
616         emit "pop %esi"
617     elsif X86_WIN
618         emit "pop ebx"
619         emit "pop edi"
620         emit "pop esi"
621     end
622 end
623
624 macro preserveCallerPCAndCFR()
625     if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
626         push lr
627         push cfr
628     elsif X86 or X86_WIN or X86_64 or X86_64_WIN
629         push cfr
630     elsif ARM64 or ARM64E
631         push cfr, lr
632     else
633         error
634     end
635     move sp, cfr
636 end
637
638 macro restoreCallerPCAndCFR()
639     move cfr, sp
640     if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
641         pop cfr
642         pop lr
643     elsif X86 or X86_WIN or X86_64 or X86_64_WIN
644         pop cfr
645     elsif ARM64 or ARM64E
646         pop lr, cfr
647     end
648 end
649
650 macro preserveCalleeSavesUsedByLLInt()
651     subp CalleeSaveSpaceStackAligned, sp
652     if C_LOOP
653     elsif ARM or ARMv7_TRADITIONAL
654     elsif ARMv7
655     elsif ARM64 or ARM64E
656         emit "stp x27, x28, [x29, #-16]"
657         emit "stp xzr, x26, [x29, #-32]"
658     elsif MIPS
659     elsif X86
660     elsif X86_WIN
661     elsif X86_64
662         storep csr4, -8[cfr]
663         storep csr3, -16[cfr]
664         storep csr2, -24[cfr]
665     elsif X86_64_WIN
666         storep csr6, -8[cfr]
667         storep csr5, -16[cfr]
668         storep csr4, -24[cfr]
669     end
670 end
671
672 macro restoreCalleeSavesUsedByLLInt()
673     if C_LOOP
674     elsif ARM or ARMv7_TRADITIONAL
675     elsif ARMv7
676     elsif ARM64 or ARM64E
677         emit "ldp xzr, x26, [x29, #-32]"
678         emit "ldp x27, x28, [x29, #-16]"
679     elsif MIPS
680     elsif X86
681     elsif X86_WIN
682     elsif X86_64
683         loadp -24[cfr], csr2
684         loadp -16[cfr], csr3
685         loadp -8[cfr], csr4
686     elsif X86_64_WIN
687         loadp -24[cfr], csr4
688         loadp -16[cfr], csr5
689         loadp -8[cfr], csr6
690     end
691 end
692
693 macro copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(vm, temp)
694     if ARM64 or ARM64E or X86_64 or X86_64_WIN
695         loadp VM::topEntryFrame[vm], temp
696         vmEntryRecord(temp, temp)
697         leap VMEntryRecord::calleeSaveRegistersBuffer[temp], temp
698         if ARM64 or ARM64E
699             storep csr0, [temp]
700             storep csr1, 8[temp]
701             storep csr2, 16[temp]
702             storep csr3, 24[temp]
703             storep csr4, 32[temp]
704             storep csr5, 40[temp]
705             storep csr6, 48[temp]
706             storep csr7, 56[temp]
707             storep csr8, 64[temp]
708             storep csr9, 72[temp]
709             stored csfr0, 80[temp]
710             stored csfr1, 88[temp]
711             stored csfr2, 96[temp]
712             stored csfr3, 104[temp]
713             stored csfr4, 112[temp]
714             stored csfr5, 120[temp]
715             stored csfr6, 128[temp]
716             stored csfr7, 136[temp]
717         elsif X86_64
718             storep csr0, [temp]
719             storep csr1, 8[temp]
720             storep csr2, 16[temp]
721             storep csr3, 24[temp]
722             storep csr4, 32[temp]
723         elsif X86_64_WIN
724             storep csr0, [temp]
725             storep csr1, 8[temp]
726             storep csr2, 16[temp]
727             storep csr3, 24[temp]
728             storep csr4, 32[temp]
729             storep csr5, 40[temp]
730             storep csr6, 48[temp]
731         end
732     end
733 end
734
735 macro restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(vm, temp)
736     if ARM64 or ARM64E or X86_64 or X86_64_WIN
737         loadp VM::topEntryFrame[vm], temp
738         vmEntryRecord(temp, temp)
739         leap VMEntryRecord::calleeSaveRegistersBuffer[temp], temp
740         if ARM64 or ARM64E
741             loadp [temp], csr0
742             loadp 8[temp], csr1
743             loadp 16[temp], csr2
744             loadp 24[temp], csr3
745             loadp 32[temp], csr4
746             loadp 40[temp], csr5
747             loadp 48[temp], csr6
748             loadp 56[temp], csr7
749             loadp 64[temp], csr8
750             loadp 72[temp], csr9
751             loadd 80[temp], csfr0
752             loadd 88[temp], csfr1
753             loadd 96[temp], csfr2
754             loadd 104[temp], csfr3
755             loadd 112[temp], csfr4
756             loadd 120[temp], csfr5
757             loadd 128[temp], csfr6
758             loadd 136[temp], csfr7
759         elsif X86_64
760             loadp [temp], csr0
761             loadp 8[temp], csr1
762             loadp 16[temp], csr2
763             loadp 24[temp], csr3
764             loadp 32[temp], csr4
765         elsif X86_64_WIN
766             loadp [temp], csr0
767             loadp 8[temp], csr1
768             loadp 16[temp], csr2
769             loadp 24[temp], csr3
770             loadp 32[temp], csr4
771             loadp 40[temp], csr5
772             loadp 48[temp], csr6
773         end
774     end
775 end
776
777 macro preserveReturnAddressAfterCall(destinationRegister)
778     if C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or ARM64 or ARM64E or MIPS
779         # In C_LOOP case, we're only preserving the bytecode vPC.
780         move lr, destinationRegister
781     elsif X86 or X86_WIN or X86_64 or X86_64_WIN
782         pop destinationRegister
783     else
784         error
785     end
786 end
787
788 macro unpoison(poison, field, scratch)
789     if POISON
790         loadp poison, scratch
791         xorp scratch, field
792     end
793 end
794
795 macro functionPrologue()
796     tagReturnAddress sp
797     if X86 or X86_WIN or X86_64 or X86_64_WIN
798         push cfr
799     elsif ARM64 or ARM64E
800         push cfr, lr
801     elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
802         push lr
803         push cfr
804     end
805     move sp, cfr
806 end
807
808 macro functionEpilogue()
809     if X86 or X86_WIN or X86_64 or X86_64_WIN
810         pop cfr
811     elsif ARM64 or ARM64E
812         pop lr, cfr
813     elsif C_LOOP or ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
814         pop cfr
815         pop lr
816     end
817 end
818
819 macro vmEntryRecord(entryFramePointer, resultReg)
820     subp entryFramePointer, VMEntryTotalFrameSize, resultReg
821 end
822
823 macro getFrameRegisterSizeForCodeBlock(codeBlock, size)
824     loadi CodeBlock::m_numCalleeLocals[codeBlock], size
825     lshiftp 3, size
826     addp maxFrameExtentForSlowPathCall, size
827 end
828
829 macro restoreStackPointerAfterCall()
830     loadp CodeBlock[cfr], t2
831     getFrameRegisterSizeForCodeBlock(t2, t2)
832     if ARMv7
833         subp cfr, t2, t2
834         move t2, sp
835     else
836         subp cfr, t2, sp
837     end
838 end
839
840 macro traceExecution()
841     if EXECUTION_TRACING
842         callSlowPath(_llint_trace)
843     end
844 end
845
846 macro callTargetFunction(callee, callPtrTag)
847     if C_LOOP
848         cloopCallJSFunction callee
849     else
850         call callee, callPtrTag
851     end
852     restoreStackPointerAfterCall()
853     dispatchAfterCall()
854 end
855
856 macro prepareForRegularCall(callee, temp1, temp2, temp3, callPtrTag)
857     addp CallerFrameAndPCSize, sp
858 end
859
860 # sp points to the new frame
861 macro prepareForTailCall(callee, temp1, temp2, temp3, callPtrTag)
862     restoreCalleeSavesUsedByLLInt()
863
864     loadi PayloadOffset + ArgumentCount[cfr], temp2
865     loadp CodeBlock[cfr], temp1
866     loadp CodeBlock::m_numParameters[temp1], temp1
867     bilteq temp1, temp2, .noArityFixup
868     move temp1, temp2
869
870 .noArityFixup:
871     # We assume < 2^28 arguments
872     muli SlotSize, temp2
873     addi StackAlignment - 1 + CallFrameHeaderSize, temp2
874     andi ~StackAlignmentMask, temp2
875
876     move cfr, temp1
877     addp temp2, temp1
878
879     loadi PayloadOffset + ArgumentCount[sp], temp2
880     # We assume < 2^28 arguments
881     muli SlotSize, temp2
882     addi StackAlignment - 1 + CallFrameHeaderSize, temp2
883     andi ~StackAlignmentMask, temp2
884
885     if ARM or ARMv7_TRADITIONAL or ARMv7 or ARM64 or ARM64E or C_LOOP or MIPS
886         addp 2 * PtrSize, sp
887         subi 2 * PtrSize, temp2
888         loadp PtrSize[cfr], lr
889     else
890         addp PtrSize, sp
891         subi PtrSize, temp2
892         loadp PtrSize[cfr], temp3
893         storep temp3, [sp]
894     end
895
896     if POINTER_PROFILING
897         addp 16, cfr, temp3
898         untagReturnAddress temp3
899     end
900
901     subp temp2, temp1
902     loadp [cfr], cfr
903
904 .copyLoop:
905     subi PtrSize, temp2
906     loadp [sp, temp2, 1], temp3
907     storep temp3, [temp1, temp2, 1]
908     btinz temp2, .copyLoop
909
910     move temp1, sp
911     jmp callee, callPtrTag
912 end
913
914 macro slowPathForCall(slowPath, prepareCall)
915     callCallSlowPath(
916         slowPath,
917         # Those are r0 and r1
918         macro (callee, calleeFramePtr)
919             btpz calleeFramePtr, .dontUpdateSP
920             move calleeFramePtr, sp
921             prepareCall(callee, t2, t3, t4, SlowPathPtrTag)
922         .dontUpdateSP:
923             callTargetFunction(callee, SlowPathPtrTag)
924         end)
925 end
926
927 macro arrayProfile(cellAndIndexingType, profile, scratch)
928     const cell = cellAndIndexingType
929     const indexingType = cellAndIndexingType 
930     loadi JSCell::m_structureID[cell], scratch
931     storei scratch, ArrayProfile::m_lastSeenStructureID[profile]
932     loadb JSCell::m_indexingTypeAndMisc[cell], indexingType
933 end
934
935 macro skipIfIsRememberedOrInEden(cell, slowPath)
936     memfence
937     bba JSCell::m_cellState[cell], BlackThreshold, .done
938     slowPath()
939 .done:
940 end
941
942 macro notifyWrite(set, slow)
943     bbneq WatchpointSet::m_state[set], IsInvalidated, slow
944 end
945
946 macro checkSwitchToJIT(increment, action)
947     loadp CodeBlock[cfr], t0
948     baddis increment, CodeBlock::m_llintExecuteCounter + BaselineExecutionCounter::m_counter[t0], .continue
949     action()
950     .continue:
951 end
952
953 macro checkSwitchToJITForEpilogue()
954     checkSwitchToJIT(
955         10,
956         macro ()
957             callSlowPath(_llint_replace)
958         end)
959 end
960
961 macro assertNotConstant(index)
962     assert(macro (ok) bilt index, FirstConstantRegisterIndex, ok end)
963 end
964
965 macro functionForCallCodeBlockGetter(targetRegister, scratch)
966     if JSVALUE64
967         loadp Callee[cfr], targetRegister
968     else
969         loadp Callee + PayloadOffset[cfr], targetRegister
970     end
971     loadp JSFunction::m_executable[targetRegister], targetRegister
972     unpoison(_g_JSFunctionPoison, targetRegister, scratch)
973     loadp FunctionExecutable::m_codeBlockForCall[targetRegister], targetRegister
974     loadp ExecutableToCodeBlockEdge::m_codeBlock[targetRegister], targetRegister
975 end
976
977 macro functionForConstructCodeBlockGetter(targetRegister, scratch)
978     if JSVALUE64
979         loadp Callee[cfr], targetRegister
980     else
981         loadp Callee + PayloadOffset[cfr], targetRegister
982     end
983     loadp JSFunction::m_executable[targetRegister], targetRegister
984     unpoison(_g_JSFunctionPoison, targetRegister, scratch)
985     loadp FunctionExecutable::m_codeBlockForConstruct[targetRegister], targetRegister
986     loadp ExecutableToCodeBlockEdge::m_codeBlock[targetRegister], targetRegister
987 end
988
989 macro notFunctionCodeBlockGetter(targetRegister, ignored)
990     loadp CodeBlock[cfr], targetRegister
991 end
992
993 macro functionCodeBlockSetter(sourceRegister)
994     storep sourceRegister, CodeBlock[cfr]
995 end
996
997 macro notFunctionCodeBlockSetter(sourceRegister)
998     # Nothing to do!
999 end
1000
1001 # Do the bare minimum required to execute code. Sets up the PC, leave the CodeBlock*
1002 # in t1. May also trigger prologue entry OSR.
1003 macro prologue(codeBlockGetter, codeBlockSetter, osrSlowPath, traceSlowPath, targetPtrTag)
1004     # Set up the call frame and check if we should OSR.
1005     tagReturnAddress sp
1006     preserveCallerPCAndCFR()
1007
1008     if EXECUTION_TRACING
1009         subp maxFrameExtentForSlowPathCall, sp
1010         callSlowPath(traceSlowPath)
1011         addp maxFrameExtentForSlowPathCall, sp
1012     end
1013     codeBlockGetter(t1, t2)
1014     if not C_LOOP
1015         baddis 5, CodeBlock::m_llintExecuteCounter + BaselineExecutionCounter::m_counter[t1], .continue
1016         if JSVALUE64
1017             move cfr, a0
1018             move PC, a1
1019             cCall2(osrSlowPath)
1020         else
1021             # We are after the function prologue, but before we have set up sp from the CodeBlock.
1022             # Temporarily align stack pointer for this call.
1023             subp 8, sp
1024             move cfr, a0
1025             move PC, a1
1026             cCall2(osrSlowPath)
1027             addp 8, sp
1028         end
1029         btpz r0, .recover
1030         move cfr, sp # restore the previous sp
1031         # pop the callerFrame since we will jump to a function that wants to save it
1032         if ARM64 or ARM64E
1033             pop lr, cfr
1034             untagReturnAddress sp
1035         elsif ARM or ARMv7 or ARMv7_TRADITIONAL or MIPS
1036             pop cfr
1037             pop lr
1038         else
1039             pop cfr
1040         end
1041         jmp r0, targetPtrTag
1042     .recover:
1043         codeBlockGetter(t1, t2)
1044     .continue:
1045     end
1046
1047     codeBlockSetter(t1)
1048
1049     preserveCalleeSavesUsedByLLInt()
1050
1051     # Set up the PC.
1052     if JSVALUE64
1053         loadp CodeBlock::m_instructions[t1], PB
1054         unpoison(_g_CodeBlockPoison, PB, t3)
1055         move 0, PC
1056     else
1057         loadp CodeBlock::m_instructions[t1], PC
1058     end
1059
1060     # Get new sp in t0 and check stack height.
1061     getFrameRegisterSizeForCodeBlock(t1, t0)
1062     subp cfr, t0, t0
1063     bpa t0, cfr, .needStackCheck
1064     loadp CodeBlock::m_poisonedVM[t1], t2
1065     unpoison(_g_CodeBlockPoison, t2, t3)
1066     if C_LOOP
1067         bpbeq VM::m_cloopStackLimit[t2], t0, .stackHeightOK
1068     else
1069         bpbeq VM::m_softStackLimit[t2], t0, .stackHeightOK
1070     end
1071
1072 .needStackCheck:
1073     # Stack height check failed - need to call a slow_path.
1074     # Set up temporary stack pointer for call including callee saves
1075     subp maxFrameExtentForSlowPathCall, sp
1076     callSlowPath(_llint_stack_check)
1077     bpeq r1, 0, .stackHeightOKGetCodeBlock
1078     move r1, cfr
1079     dispatch(0) # Go to exception handler in PC
1080
1081 .stackHeightOKGetCodeBlock:
1082     # Stack check slow path returned that the stack was ok.
1083     # Since they were clobbered, need to get CodeBlock and new sp
1084     codeBlockGetter(t1, t2)
1085     getFrameRegisterSizeForCodeBlock(t1, t0)
1086     subp cfr, t0, t0
1087
1088 .stackHeightOK:
1089     if X86_64 or ARM64
1090         # We need to start zeroing from sp as it has been adjusted after saving callee saves.
1091         move sp, t2
1092         move t0, sp
1093 .zeroStackLoop:
1094         bpeq sp, t2, .zeroStackDone
1095         subp PtrSize, t2
1096         storep 0, [t2]
1097         jmp .zeroStackLoop
1098 .zeroStackDone:
1099     else
1100         move t0, sp
1101     end
1102
1103     if JSVALUE64
1104         move TagTypeNumber, tagTypeNumber
1105         addp TagBitTypeOther, tagTypeNumber, tagMask
1106     end
1107 end
1108
1109 # Expects that CodeBlock is in t1, which is what prologue() leaves behind.
1110 # Must call dispatch(0) after calling this.
1111 macro functionInitialization(profileArgSkip)
1112     # Profile the arguments. Unfortunately, we have no choice but to do this. This
1113     # code is pretty horrendous because of the difference in ordering between
1114     # arguments and value profiles, the desire to have a simple loop-down-to-zero
1115     # loop, and the desire to use only three registers so as to preserve the PC and
1116     # the code block. It is likely that this code should be rewritten in a more
1117     # optimal way for architectures that have more than five registers available
1118     # for arbitrary use in the interpreter.
1119     loadi CodeBlock::m_numParameters[t1], t0
1120     addp -profileArgSkip, t0 # Use addi because that's what has the peephole
1121     assert(macro (ok) bpgteq t0, 0, ok end)
1122     btpz t0, .argumentProfileDone
1123     loadp CodeBlock::m_argumentValueProfiles + VectorBufferOffset[t1], t3
1124     mulp sizeof ValueProfile, t0, t2 # Aaaaahhhh! Need strength reduction!
1125     lshiftp 3, t0
1126     addp t2, t3
1127 .argumentProfileLoop:
1128     if JSVALUE64
1129         loadq ThisArgumentOffset - 8 + profileArgSkip * 8[cfr, t0], t2
1130         subp sizeof ValueProfile, t3
1131         storeq t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets[t3]
1132     else
1133         loadi ThisArgumentOffset + TagOffset - 8 + profileArgSkip * 8[cfr, t0], t2
1134         subp sizeof ValueProfile, t3
1135         storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + TagOffset[t3]
1136         loadi ThisArgumentOffset + PayloadOffset - 8 + profileArgSkip * 8[cfr, t0], t2
1137         storei t2, profileArgSkip * sizeof ValueProfile + ValueProfile::m_buckets + PayloadOffset[t3]
1138     end
1139     baddpnz -8, t0, .argumentProfileLoop
1140 .argumentProfileDone:
1141 end
1142
1143 macro doReturn()
1144     restoreCalleeSavesUsedByLLInt()
1145     restoreCallerPCAndCFR()
1146     ret
1147 end
1148
1149 # stub to call into JavaScript or Native functions
1150 # EncodedJSValue vmEntryToJavaScript(void* code, VM* vm, ProtoCallFrame* protoFrame)
1151 # EncodedJSValue vmEntryToNativeFunction(void* code, VM* vm, ProtoCallFrame* protoFrame)
1152
1153 if C_LOOP
1154     _llint_vm_entry_to_javascript:
1155 else
1156     global _vmEntryToJavaScript
1157     _vmEntryToJavaScript:
1158 end
1159     doVMEntry(makeJavaScriptCall)
1160
1161
1162 if C_LOOP
1163     _llint_vm_entry_to_native:
1164 else
1165     global _vmEntryToNative
1166     _vmEntryToNative:
1167 end
1168     doVMEntry(makeHostFunctionCall)
1169
1170
1171 if not C_LOOP
1172     # void sanitizeStackForVMImpl(VM* vm)
1173     global _sanitizeStackForVMImpl
1174     _sanitizeStackForVMImpl:
1175         tagReturnAddress sp
1176         # We need three non-aliased caller-save registers. We are guaranteed
1177         # this for a0, a1 and a2 on all architectures.
1178         if X86 or X86_WIN
1179             loadp 4[sp], a0
1180         end
1181         const vm = a0
1182         const address = a1
1183         const zeroValue = a2
1184     
1185         loadp VM::m_lastStackTop[vm], address
1186         bpbeq sp, address, .zeroFillDone
1187     
1188         move 0, zeroValue
1189     .zeroFillLoop:
1190         storep zeroValue, [address]
1191         addp PtrSize, address
1192         bpa sp, address, .zeroFillLoop
1193
1194     .zeroFillDone:
1195         move sp, address
1196         storep address, VM::m_lastStackTop[vm]
1197         ret
1198     
1199     # VMEntryRecord* vmEntryRecord(const EntryFrame* entryFrame)
1200     global _vmEntryRecord
1201     _vmEntryRecord:
1202         tagReturnAddress sp
1203         if X86 or X86_WIN
1204             loadp 4[sp], a0
1205         end
1206
1207         vmEntryRecord(a0, r0)
1208         ret
1209 end
1210
1211 if C_LOOP
1212     # Dummy entry point the C Loop uses to initialize.
1213     _llint_entry:
1214         crash()
1215 else
1216     macro initPCRelative(pcBase)
1217         if X86_64 or X86_64_WIN or X86 or X86_WIN
1218             call _relativePCBase
1219         _relativePCBase:
1220             pop pcBase
1221         elsif ARM64 or ARM64E
1222         elsif ARMv7
1223         _relativePCBase:
1224             move pc, pcBase
1225             subp 3, pcBase   # Need to back up the PC and set the Thumb2 bit
1226         elsif ARM or ARMv7_TRADITIONAL
1227         _relativePCBase:
1228             move pc, pcBase
1229             subp 8, pcBase
1230         elsif MIPS
1231             la _relativePCBase, pcBase
1232             setcallreg pcBase # needed to set $t9 to the right value for the .cpload created by the label.
1233         _relativePCBase:
1234         end
1235 end
1236
1237 # The PC base is in t1, as this is what _llint_entry leaves behind through
1238 # initPCRelative(t1)
1239 macro setEntryAddress(index, label)
1240     if X86_64 or X86_64_WIN
1241         leap (label - _relativePCBase)[t1], t3
1242         move index, t4
1243         storep t3, [a0, t4, 8]
1244     elsif X86 or X86_WIN
1245         leap (label - _relativePCBase)[t1], t3
1246         move index, t4
1247         storep t3, [a0, t4, 4]
1248     elsif ARM64 or ARM64E
1249         pcrtoaddr label, t1
1250         move index, t4
1251         storep t1, [a0, t4, 8]
1252     elsif ARM or ARMv7 or ARMv7_TRADITIONAL
1253         mvlbl (label - _relativePCBase), t4
1254         addp t4, t1, t4
1255         move index, t3
1256         storep t4, [a0, t3, 4]
1257     elsif MIPS
1258         la label, t4
1259         la _relativePCBase, t3
1260         subp t3, t4
1261         addp t4, t1, t4
1262         move index, t3
1263         storep t4, [a0, t3, 4]
1264     end
1265 end
1266
1267 global _llint_entry
1268 # Entry point for the llint to initialize.
1269 _llint_entry:
1270     functionPrologue()
1271     pushCalleeSaves()
1272     if X86 or X86_WIN
1273         loadp 20[sp], a0
1274     end
1275     initPCRelative(t1)
1276
1277     # Include generated bytecode initialization file.
1278     include InitBytecodes
1279
1280     popCalleeSaves()
1281     functionEpilogue()
1282     ret
1283 end
1284
1285 _llint_program_prologue:
1286     prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue, CodeEntryPtrTag)
1287     dispatch(0)
1288
1289
1290 _llint_module_program_prologue:
1291     prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue, CodeEntryPtrTag)
1292     dispatch(0)
1293
1294
1295 _llint_eval_prologue:
1296     prologue(notFunctionCodeBlockGetter, notFunctionCodeBlockSetter, _llint_entry_osr, _llint_trace_prologue, CodeEntryPtrTag)
1297     dispatch(0)
1298
1299
1300 _llint_function_for_call_prologue:
1301     prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call, _llint_trace_prologue_function_for_call, CodeEntryPtrTag)
1302     functionInitialization(0)
1303     dispatch(0)
1304     
1305
1306 _llint_function_for_construct_prologue:
1307     prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct, _llint_trace_prologue_function_for_construct, CodeEntryPtrTag)
1308     functionInitialization(1)
1309     dispatch(0)
1310     
1311
1312 _llint_function_for_call_arity_check:
1313     prologue(functionForCallCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_call_arityCheck, _llint_trace_arityCheck_for_call, CodeEntryWithArityCheckPtrTag)
1314     functionArityCheck(.functionForCallBegin, _slow_path_call_arityCheck)
1315 .functionForCallBegin:
1316     functionInitialization(0)
1317     dispatch(0)
1318
1319
1320 _llint_function_for_construct_arity_check:
1321     prologue(functionForConstructCodeBlockGetter, functionCodeBlockSetter, _llint_entry_osr_function_for_construct_arityCheck, _llint_trace_arityCheck_for_construct, CodeEntryWithArityCheckPtrTag)
1322     functionArityCheck(.functionForConstructBegin, _slow_path_construct_arityCheck)
1323 .functionForConstructBegin:
1324     functionInitialization(1)
1325     dispatch(0)
1326
1327
1328 # Value-representation-specific code.
1329 if JSVALUE64
1330     include LowLevelInterpreter64
1331 else
1332     include LowLevelInterpreter32_64
1333 end
1334
1335
1336 # Value-representation-agnostic code.
1337 _llint_op_create_direct_arguments:
1338     traceExecution()
1339     callSlowPath(_slow_path_create_direct_arguments)
1340     dispatch(constexpr op_create_direct_arguments_length)
1341
1342
1343 _llint_op_create_scoped_arguments:
1344     traceExecution()
1345     callSlowPath(_slow_path_create_scoped_arguments)
1346     dispatch(constexpr op_create_scoped_arguments_length)
1347
1348
1349 _llint_op_create_cloned_arguments:
1350     traceExecution()
1351     callSlowPath(_slow_path_create_cloned_arguments)
1352     dispatch(constexpr op_create_cloned_arguments_length)
1353
1354
1355 _llint_op_create_this:
1356     traceExecution()
1357     callSlowPath(_slow_path_create_this)
1358     dispatch(constexpr op_create_this_length)
1359
1360
1361 _llint_op_new_object:
1362     traceExecution()
1363     callSlowPath(_llint_slow_path_new_object)
1364     dispatch(constexpr op_new_object_length)
1365
1366
1367 _llint_op_new_func:
1368     traceExecution()
1369     callSlowPath(_llint_slow_path_new_func)
1370     dispatch(constexpr op_new_func_length)
1371
1372
1373 _llint_op_new_generator_func:
1374     traceExecution()
1375     callSlowPath(_llint_slow_path_new_generator_func)
1376     dispatch(constexpr op_new_generator_func_length)
1377
1378 _llint_op_new_async_generator_func:
1379     traceExecution()
1380     callSlowPath(_llint_slow_path_new_async_generator_func)
1381     dispatch(constexpr op_new_async_generator_func_length)
1382
1383 _llint_op_new_async_generator_func_exp:
1384     traceExecution()
1385     callSlowPath(_llint_slow_path_new_async_generator_func_exp)
1386     dispatch(constexpr op_new_async_generator_func_exp_length)
1387
1388 _llint_op_new_async_func:
1389     traceExecution()
1390     callSlowPath(_llint_slow_path_new_async_func)
1391     dispatch(constexpr op_new_async_func_length)
1392
1393
1394 _llint_op_new_array:
1395     traceExecution()
1396     callSlowPath(_llint_slow_path_new_array)
1397     dispatch(constexpr op_new_array_length)
1398
1399
1400 _llint_op_new_array_with_spread:
1401     traceExecution()
1402     callSlowPath(_slow_path_new_array_with_spread)
1403     dispatch(constexpr op_new_array_with_spread_length)
1404
1405
1406 _llint_op_spread:
1407     traceExecution()
1408     callSlowPath(_slow_path_spread)
1409     dispatch(constexpr op_spread_length)
1410
1411
1412 _llint_op_new_array_with_size:
1413     traceExecution()
1414     callSlowPath(_llint_slow_path_new_array_with_size)
1415     dispatch(constexpr op_new_array_with_size_length)
1416
1417
1418 _llint_op_new_array_buffer:
1419     traceExecution()
1420     callSlowPath(_slow_path_new_array_buffer)
1421     dispatch(constexpr op_new_array_buffer_length)
1422
1423
1424 _llint_op_new_regexp:
1425     traceExecution()
1426     callSlowPath(_llint_slow_path_new_regexp)
1427     dispatch(constexpr op_new_regexp_length)
1428
1429
1430 _llint_op_less:
1431     traceExecution()
1432     callSlowPath(_slow_path_less)
1433     dispatch(constexpr op_less_length)
1434
1435
1436 _llint_op_lesseq:
1437     traceExecution()
1438     callSlowPath(_slow_path_lesseq)
1439     dispatch(constexpr op_lesseq_length)
1440
1441
1442 _llint_op_greater:
1443     traceExecution()
1444     callSlowPath(_slow_path_greater)
1445     dispatch(constexpr op_greater_length)
1446
1447
1448 _llint_op_greatereq:
1449     traceExecution()
1450     callSlowPath(_slow_path_greatereq)
1451     dispatch(constexpr op_greatereq_length)
1452
1453
1454 _llint_op_eq:
1455     traceExecution()
1456     equalityComparison(
1457         macro (left, right, result) cieq left, right, result end,
1458         _slow_path_eq)
1459
1460
1461 _llint_op_neq:
1462     traceExecution()
1463     equalityComparison(
1464         macro (left, right, result) cineq left, right, result end,
1465         _slow_path_neq)
1466
1467
1468 _llint_op_below:
1469     traceExecution()
1470     compareUnsigned(
1471         macro (left, right, result) cib left, right, result end)
1472
1473
1474 _llint_op_beloweq:
1475     traceExecution()
1476     compareUnsigned(
1477         macro (left, right, result) cibeq left, right, result end)
1478
1479
1480 _llint_op_mod:
1481     traceExecution()
1482     callSlowPath(_slow_path_mod)
1483     dispatch(constexpr op_mod_length)
1484
1485
1486 _llint_op_pow:
1487     traceExecution()
1488     callSlowPath(_slow_path_pow)
1489     dispatch(constexpr op_pow_length)
1490
1491
1492 _llint_op_typeof:
1493     traceExecution()
1494     callSlowPath(_slow_path_typeof)
1495     dispatch(constexpr op_typeof_length)
1496
1497
1498 _llint_op_is_object_or_null:
1499     traceExecution()
1500     callSlowPath(_slow_path_is_object_or_null)
1501     dispatch(constexpr op_is_object_or_null_length)
1502
1503 _llint_op_is_function:
1504     traceExecution()
1505     callSlowPath(_slow_path_is_function)
1506     dispatch(constexpr op_is_function_length)
1507
1508
1509 _llint_op_in:
1510     traceExecution()
1511     callSlowPath(_slow_path_in)
1512     dispatch(constexpr op_in_length)
1513
1514
1515 _llint_op_try_get_by_id:
1516     traceExecution()
1517     callSlowPath(_llint_slow_path_try_get_by_id)
1518     dispatch(constexpr op_try_get_by_id_length)
1519
1520
1521 _llint_op_del_by_id:
1522     traceExecution()
1523     callSlowPath(_llint_slow_path_del_by_id)
1524     dispatch(constexpr op_del_by_id_length)
1525
1526
1527 _llint_op_del_by_val:
1528     traceExecution()
1529     callSlowPath(_llint_slow_path_del_by_val)
1530     dispatch(constexpr op_del_by_val_length)
1531
1532
1533 _llint_op_put_getter_by_id:
1534     traceExecution()
1535     callSlowPath(_llint_slow_path_put_getter_by_id)
1536     dispatch(constexpr op_put_getter_by_id_length)
1537
1538
1539 _llint_op_put_setter_by_id:
1540     traceExecution()
1541     callSlowPath(_llint_slow_path_put_setter_by_id)
1542     dispatch(constexpr op_put_setter_by_id_length)
1543
1544
1545 _llint_op_put_getter_setter_by_id:
1546     traceExecution()
1547     callSlowPath(_llint_slow_path_put_getter_setter_by_id)
1548     dispatch(constexpr op_put_getter_setter_by_id_length)
1549
1550
1551 _llint_op_put_getter_by_val:
1552     traceExecution()
1553     callSlowPath(_llint_slow_path_put_getter_by_val)
1554     dispatch(constexpr op_put_getter_by_val_length)
1555
1556
1557 _llint_op_put_setter_by_val:
1558     traceExecution()
1559     callSlowPath(_llint_slow_path_put_setter_by_val)
1560     dispatch(constexpr op_put_setter_by_val_length)
1561
1562
1563 _llint_op_define_data_property:
1564     traceExecution()
1565     callSlowPath(_slow_path_define_data_property)
1566     dispatch(constexpr op_define_data_property_length)
1567
1568
1569 _llint_op_define_accessor_property:
1570     traceExecution()
1571     callSlowPath(_slow_path_define_accessor_property)
1572     dispatch(constexpr op_define_accessor_property_length)
1573
1574
1575 _llint_op_jtrue:
1576     traceExecution()
1577     jumpTrueOrFalse(
1578         macro (value, target) btinz value, target end,
1579         _llint_slow_path_jtrue)
1580
1581
1582 _llint_op_jfalse:
1583     traceExecution()
1584     jumpTrueOrFalse(
1585         macro (value, target) btiz value, target end,
1586         _llint_slow_path_jfalse)
1587
1588
1589 _llint_op_jless:
1590     traceExecution()
1591     compareJump(
1592         macro (left, right, target) bilt left, right, target end,
1593         macro (left, right, target) bdlt left, right, target end,
1594         _llint_slow_path_jless)
1595
1596
1597 _llint_op_jnless:
1598     traceExecution()
1599     compareJump(
1600         macro (left, right, target) bigteq left, right, target end,
1601         macro (left, right, target) bdgtequn left, right, target end,
1602         _llint_slow_path_jnless)
1603
1604
1605 _llint_op_jgreater:
1606     traceExecution()
1607     compareJump(
1608         macro (left, right, target) bigt left, right, target end,
1609         macro (left, right, target) bdgt left, right, target end,
1610         _llint_slow_path_jgreater)
1611
1612
1613 _llint_op_jngreater:
1614     traceExecution()
1615     compareJump(
1616         macro (left, right, target) bilteq left, right, target end,
1617         macro (left, right, target) bdltequn left, right, target end,
1618         _llint_slow_path_jngreater)
1619
1620
1621 _llint_op_jlesseq:
1622     traceExecution()
1623     compareJump(
1624         macro (left, right, target) bilteq left, right, target end,
1625         macro (left, right, target) bdlteq left, right, target end,
1626         _llint_slow_path_jlesseq)
1627
1628
1629 _llint_op_jnlesseq:
1630     traceExecution()
1631     compareJump(
1632         macro (left, right, target) bigt left, right, target end,
1633         macro (left, right, target) bdgtun left, right, target end,
1634         _llint_slow_path_jnlesseq)
1635
1636
1637 _llint_op_jgreatereq:
1638     traceExecution()
1639     compareJump(
1640         macro (left, right, target) bigteq left, right, target end,
1641         macro (left, right, target) bdgteq left, right, target end,
1642         _llint_slow_path_jgreatereq)
1643
1644
1645 _llint_op_jngreatereq:
1646     traceExecution()
1647     compareJump(
1648         macro (left, right, target) bilt left, right, target end,
1649         macro (left, right, target) bdltun left, right, target end,
1650         _llint_slow_path_jngreatereq)
1651
1652
1653 _llint_op_jeq:
1654     traceExecution()
1655     equalityJump(
1656         macro (left, right, target) bieq left, right, target end,
1657         _llint_slow_path_jeq)
1658
1659
1660 _llint_op_jneq:
1661     traceExecution()
1662     equalityJump(
1663         macro (left, right, target) bineq left, right, target end,
1664         _llint_slow_path_jneq)
1665
1666
1667 _llint_op_jbelow:
1668     traceExecution()
1669     compareUnsignedJump(
1670         macro (left, right, target) bib left, right, target end)
1671
1672
1673 _llint_op_jbeloweq:
1674     traceExecution()
1675     compareUnsignedJump(
1676         macro (left, right, target) bibeq left, right, target end)
1677
1678
1679 _llint_op_loop_hint:
1680     traceExecution()
1681     checkSwitchToJITForLoop()
1682     dispatch(constexpr op_loop_hint_length)
1683
1684
1685 _llint_op_check_traps:
1686     traceExecution()
1687     loadp CodeBlock[cfr], t1
1688     loadp CodeBlock::m_poisonedVM[t1], t1
1689     unpoison(_g_CodeBlockPoison, t1, t2)
1690     loadb VM::m_traps+VMTraps::m_needTrapHandling[t1], t0
1691     btpnz t0, .handleTraps
1692 .afterHandlingTraps:
1693     dispatch(constexpr op_check_traps_length)
1694 .handleTraps:
1695     callTrapHandler(.throwHandler)
1696     jmp .afterHandlingTraps
1697 .throwHandler:
1698     jmp _llint_throw_from_slow_path_trampoline
1699
1700
1701 # Returns the packet pointer in t0.
1702 macro acquireShadowChickenPacket(slow)
1703     loadp CodeBlock[cfr], t1
1704     loadp CodeBlock::m_poisonedVM[t1], t1
1705     unpoison(_g_CodeBlockPoison, t1, t2)
1706     loadp VM::m_shadowChicken[t1], t2
1707     loadp ShadowChicken::m_logCursor[t2], t0
1708     bpaeq t0, ShadowChicken::m_logEnd[t2], slow
1709     addp sizeof ShadowChicken::Packet, t0, t1
1710     storep t1, ShadowChicken::m_logCursor[t2]
1711 end
1712
1713
1714 _llint_op_nop:
1715     dispatch(constexpr op_nop_length)
1716
1717
1718 _llint_op_super_sampler_begin:
1719     callSlowPath(_llint_slow_path_super_sampler_begin)
1720     dispatch(constexpr op_super_sampler_begin_length)
1721
1722
1723 _llint_op_super_sampler_end:
1724     traceExecution()
1725     callSlowPath(_llint_slow_path_super_sampler_end)
1726     dispatch(constexpr op_super_sampler_end_length)
1727
1728
1729 _llint_op_switch_string:
1730     traceExecution()
1731     callSlowPath(_llint_slow_path_switch_string)
1732     dispatch(0)
1733
1734
1735 _llint_op_new_func_exp:
1736     traceExecution()
1737     callSlowPath(_llint_slow_path_new_func_exp)
1738     dispatch(constexpr op_new_func_exp_length)
1739
1740 _llint_op_new_generator_func_exp:
1741     traceExecution()
1742     callSlowPath(_llint_slow_path_new_generator_func_exp)
1743     dispatch(constexpr op_new_generator_func_exp_length)
1744
1745 _llint_op_new_async_func_exp:
1746     traceExecution()
1747     callSlowPath(_llint_slow_path_new_async_func_exp)
1748     dispatch(constexpr op_new_async_func_exp_length)
1749
1750
1751 _llint_op_set_function_name:
1752     traceExecution()
1753     callSlowPath(_llint_slow_path_set_function_name)
1754     dispatch(constexpr op_set_function_name_length)
1755
1756 _llint_op_call:
1757     traceExecution()
1758     arrayProfileForCall()
1759     doCall(_llint_slow_path_call, prepareForRegularCall)
1760
1761 _llint_op_tail_call:
1762     traceExecution()
1763     arrayProfileForCall()
1764     checkSwitchToJITForEpilogue()
1765     doCall(_llint_slow_path_call, prepareForTailCall)
1766
1767 _llint_op_construct:
1768     traceExecution()
1769     doCall(_llint_slow_path_construct, prepareForRegularCall)
1770
1771 macro doCallVarargs(frameSlowPath, slowPath, prepareCall)
1772     callSlowPath(frameSlowPath)
1773     branchIfException(_llint_throw_from_slow_path_trampoline)
1774     # calleeFrame in r1
1775     if JSVALUE64
1776         move r1, sp
1777     else
1778         # The calleeFrame is not stack aligned, move down by CallerFrameAndPCSize to align
1779         if ARMv7
1780             subp r1, CallerFrameAndPCSize, t2
1781             move t2, sp
1782         else
1783             subp r1, CallerFrameAndPCSize, sp
1784         end
1785     end
1786     slowPathForCall(slowPath, prepareCall)
1787 end
1788
1789 _llint_op_call_varargs:
1790     traceExecution()
1791     doCallVarargs(_llint_slow_path_size_frame_for_varargs, _llint_slow_path_call_varargs, prepareForRegularCall)
1792
1793 _llint_op_tail_call_varargs:
1794     traceExecution()
1795     checkSwitchToJITForEpilogue()
1796     # We lie and perform the tail call instead of preparing it since we can't
1797     # prepare the frame for a call opcode
1798     doCallVarargs(_llint_slow_path_size_frame_for_varargs, _llint_slow_path_call_varargs, prepareForTailCall)
1799
1800
1801 _llint_op_tail_call_forward_arguments:
1802     traceExecution()
1803     checkSwitchToJITForEpilogue()
1804     # We lie and perform the tail call instead of preparing it since we can't
1805     # prepare the frame for a call opcode
1806     doCallVarargs(_llint_slow_path_size_frame_for_forward_arguments, _llint_slow_path_tail_call_forward_arguments, prepareForTailCall)
1807
1808
1809 _llint_op_construct_varargs:
1810     traceExecution()
1811     doCallVarargs(_llint_slow_path_size_frame_for_varargs, _llint_slow_path_construct_varargs, prepareForRegularCall)
1812
1813
1814 _llint_op_call_eval:
1815     traceExecution()
1816     
1817     # Eval is executed in one of two modes:
1818     #
1819     # 1) We find that we're really invoking eval() in which case the
1820     #    execution is perfomed entirely inside the slow_path, and it
1821     #    returns the PC of a function that just returns the return value
1822     #    that the eval returned.
1823     #
1824     # 2) We find that we're invoking something called eval() that is not
1825     #    the real eval. Then the slow_path returns the PC of the thing to
1826     #    call, and we call it.
1827     #
1828     # This allows us to handle two cases, which would require a total of
1829     # up to four pieces of state that cannot be easily packed into two
1830     # registers (C functions can return up to two registers, easily):
1831     #
1832     # - The call frame register. This may or may not have been modified
1833     #   by the slow_path, but the convention is that it returns it. It's not
1834     #   totally clear if that's necessary, since the cfr is callee save.
1835     #   But that's our style in this here interpreter so we stick with it.
1836     #
1837     # - A bit to say if the slow_path successfully executed the eval and has
1838     #   the return value, or did not execute the eval but has a PC for us
1839     #   to call.
1840     #
1841     # - Either:
1842     #   - The JS return value (two registers), or
1843     #
1844     #   - The PC to call.
1845     #
1846     # It turns out to be easier to just always have this return the cfr
1847     # and a PC to call, and that PC may be a dummy thunk that just
1848     # returns the JS value that the eval returned.
1849     
1850     slowPathForCall(_llint_slow_path_call_eval, prepareForRegularCall)
1851
1852
1853 _llint_generic_return_point:
1854     dispatchAfterCall()
1855
1856
1857 _llint_op_strcat:
1858     traceExecution()
1859     callSlowPath(_slow_path_strcat)
1860     dispatch(constexpr op_strcat_length)
1861
1862
1863 _llint_op_push_with_scope:
1864     traceExecution()
1865     callSlowPath(_slow_path_push_with_scope)
1866     dispatch(constexpr op_push_with_scope_length)
1867
1868
1869 _llint_op_identity_with_profile:
1870     traceExecution()
1871     dispatch(constexpr op_identity_with_profile_length)
1872
1873
1874 _llint_op_unreachable:
1875     traceExecution()
1876     callSlowPath(_slow_path_unreachable)
1877     dispatch(constexpr op_unreachable_length)
1878
1879
1880 _llint_op_yield:
1881     notSupported()
1882
1883
1884 _llint_op_create_lexical_environment:
1885     traceExecution()
1886     callSlowPath(_slow_path_create_lexical_environment)
1887     dispatch(constexpr op_create_lexical_environment_length)
1888
1889
1890 _llint_op_throw:
1891     traceExecution()
1892     callSlowPath(_llint_slow_path_throw)
1893     dispatch(constexpr op_throw_length)
1894
1895
1896 _llint_op_throw_static_error:
1897     traceExecution()
1898     callSlowPath(_slow_path_throw_static_error)
1899     dispatch(constexpr op_throw_static_error_length)
1900
1901
1902 _llint_op_debug:
1903     traceExecution()
1904     loadp CodeBlock[cfr], t0
1905     loadi CodeBlock::m_debuggerRequests[t0], t0
1906     btiz t0, .opDebugDone
1907     callSlowPath(_llint_slow_path_debug)
1908 .opDebugDone:                    
1909     dispatch(constexpr op_debug_length)
1910
1911
1912 _llint_native_call_trampoline:
1913     nativeCallTrampoline(NativeExecutable::m_function)
1914
1915
1916 _llint_native_construct_trampoline:
1917     nativeCallTrampoline(NativeExecutable::m_constructor)
1918
1919
1920 _llint_internal_function_call_trampoline:
1921     internalFunctionCallTrampoline(InternalFunction::m_functionForCall)
1922
1923
1924 _llint_internal_function_construct_trampoline:
1925     internalFunctionCallTrampoline(InternalFunction::m_functionForConstruct)
1926
1927
1928 _llint_op_get_enumerable_length:
1929     traceExecution()
1930     callSlowPath(_slow_path_get_enumerable_length)
1931     dispatch(constexpr op_get_enumerable_length_length)
1932
1933 _llint_op_has_indexed_property:
1934     traceExecution()
1935     callSlowPath(_slow_path_has_indexed_property)
1936     dispatch(constexpr op_has_indexed_property_length)
1937
1938 _llint_op_has_structure_property:
1939     traceExecution()
1940     callSlowPath(_slow_path_has_structure_property)
1941     dispatch(constexpr op_has_structure_property_length)
1942
1943 _llint_op_has_generic_property:
1944     traceExecution()
1945     callSlowPath(_slow_path_has_generic_property)
1946     dispatch(constexpr op_has_generic_property_length)
1947
1948 _llint_op_get_direct_pname:
1949     traceExecution()
1950     callSlowPath(_slow_path_get_direct_pname)
1951     dispatch(constexpr op_get_direct_pname_length)
1952
1953 _llint_op_get_property_enumerator:
1954     traceExecution()
1955     callSlowPath(_slow_path_get_property_enumerator)
1956     dispatch(constexpr op_get_property_enumerator_length)
1957
1958 _llint_op_enumerator_structure_pname:
1959     traceExecution()
1960     callSlowPath(_slow_path_next_structure_enumerator_pname)
1961     dispatch(constexpr op_enumerator_structure_pname_length)
1962
1963 _llint_op_enumerator_generic_pname:
1964     traceExecution()
1965     callSlowPath(_slow_path_next_generic_enumerator_pname)
1966     dispatch(constexpr op_enumerator_generic_pname_length)
1967
1968 _llint_op_to_index_string:
1969     traceExecution()
1970     callSlowPath(_slow_path_to_index_string)
1971     dispatch(constexpr op_to_index_string_length)
1972
1973 _llint_op_create_rest:
1974     traceExecution()
1975     callSlowPath(_slow_path_create_rest)
1976     dispatch(constexpr op_create_rest_length)
1977
1978 _llint_op_instanceof:
1979     traceExecution()
1980     callSlowPath(_llint_slow_path_instanceof)
1981     dispatch(constexpr op_instanceof_length)
1982
1983 _llint_op_get_by_id_with_this:
1984     traceExecution()
1985     callSlowPath(_slow_path_get_by_id_with_this)
1986     dispatch(constexpr op_get_by_id_with_this_length)
1987
1988 _llint_op_get_by_val_with_this:
1989     traceExecution()
1990     callSlowPath(_slow_path_get_by_val_with_this)
1991     dispatch(constexpr op_get_by_val_with_this_length)
1992
1993 _llint_op_put_by_id_with_this:
1994     traceExecution()
1995     callSlowPath(_slow_path_put_by_id_with_this)
1996     dispatch(constexpr op_put_by_id_with_this_length)
1997
1998 _llint_op_put_by_val_with_this:
1999     traceExecution()
2000     callSlowPath(_slow_path_put_by_val_with_this)
2001     dispatch(constexpr op_put_by_val_with_this_length)
2002
2003 _llint_op_resolve_scope_for_hoisting_func_decl_in_eval:
2004     traceExecution()
2005     callSlowPath(_slow_path_resolve_scope_for_hoisting_func_decl_in_eval)
2006     dispatch(constexpr op_resolve_scope_for_hoisting_func_decl_in_eval_length)
2007
2008 # Lastly, make sure that we can link even though we don't support all opcodes.
2009 # These opcodes should never arise when using LLInt or either JIT. We assert
2010 # as much.
2011
2012 macro notSupported()
2013     if ASSERT_ENABLED
2014         crash()
2015     else
2016         # We should use whatever the smallest possible instruction is, just to
2017         # ensure that there is a gap between instruction labels. If multiple
2018         # smallest instructions exist, we should pick the one that is most
2019         # likely result in execution being halted. Currently that is the break
2020         # instruction on all architectures we're interested in. (Break is int3
2021         # on Intel, which is 1 byte, and bkpt on ARMv7, which is 2 bytes.)
2022         break
2023     end
2024 end