1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2  * vim: set ts=8 sts=2 et sw=2 tw=80:
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef jit_BaselineCacheIRCompiler_h
8 #define jit_BaselineCacheIRCompiler_h
9 
10 #include "mozilla/Attributes.h"
11 #include "mozilla/Maybe.h"
12 
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 #include "jstypes.h"
17 
18 #include "jit/CacheIR.h"
19 #include "jit/CacheIRCompiler.h"
20 #include "jit/CacheIROpsGenerated.h"
21 #include "jit/CacheIRReader.h"
22 
23 struct JS_PUBLIC_API JSContext;
24 
25 class JSScript;
26 
27 namespace js {
28 namespace jit {
29 
30 class CacheIRWriter;
31 class ICFallbackStub;
32 class ICScript;
33 class JitCode;
34 class Label;
35 class MacroAssembler;
36 
37 struct Address;
38 struct Register;
39 
40 enum class TailCallVMFunctionId;
41 
42 enum class ICAttachResult { Attached, DuplicateStub, TooLarge, OOM };
43 
44 ICAttachResult AttachBaselineCacheIRStub(JSContext* cx,
45                                          const CacheIRWriter& writer,
46                                          CacheKind kind, JSScript* outerScript,
47                                          ICScript* icScript,
48                                          ICFallbackStub* stub);
49 
50 // BaselineCacheIRCompiler compiles CacheIR to BaselineIC native code.
51 class MOZ_RAII BaselineCacheIRCompiler : public CacheIRCompiler {
52   bool makesGCCalls_;
53 
54   void tailCallVMInternal(MacroAssembler& masm, TailCallVMFunctionId id);
55 
56   template <typename Fn, Fn fn>
57   void tailCallVM(MacroAssembler& masm);
58 
59   [[nodiscard]] bool emitStoreSlotShared(bool isFixed, ObjOperandId objId,
60                                          uint32_t offsetOffset,
61                                          ValOperandId rhsId);
62   [[nodiscard]] bool emitAddAndStoreSlotShared(
63       CacheOp op, ObjOperandId objId, uint32_t offsetOffset, ValOperandId rhsId,
64       uint32_t newShapeOffset, mozilla::Maybe<uint32_t> numNewSlotsOffset);
65 
66   bool updateArgc(CallFlags flags, Register argcReg, Register scratch);
67   void loadStackObject(ArgumentKind kind, CallFlags flags, size_t stackPushed,
68                        Register argcReg, Register dest);
69   void pushArguments(Register argcReg, Register calleeReg, Register scratch,
70                      Register scratch2, CallFlags flags, bool isJitCall);
71   void pushStandardArguments(Register argcReg, Register scratch,
72                              Register scratch2, bool isJitCall,
73                              bool isConstructing);
74   void pushArrayArguments(Register argcReg, Register scratch, Register scratch2,
75                           bool isJitCall, bool isConstructing);
76   void pushFunCallArguments(Register argcReg, Register calleeReg,
77                             Register scratch, Register scratch2,
78                             bool isJitCall);
79   void pushFunApplyArgsObj(Register argcReg, Register calleeReg,
80                            Register scratch, Register scratch2, bool isJitCall);
81   void createThis(Register argcReg, Register calleeReg, Register scratch,
82                   CallFlags flags);
83   template <typename T>
84   void storeThis(const T& newThis, Register argcReg, CallFlags flags);
85   void updateReturnValue();
86 
87   enum class NativeCallType { Native, ClassHook };
88   bool emitCallNativeShared(NativeCallType callType, ObjOperandId calleeId,
89                             Int32OperandId argcId, CallFlags flags,
90                             mozilla::Maybe<bool> ignoresReturnValue,
91                             mozilla::Maybe<uint32_t> targetOffset);
92 
93   enum class StringCode { CodeUnit, CodePoint };
94   bool emitStringFromCodeResult(Int32OperandId codeId, StringCode stringCode);
95 
96   void emitAtomizeString(Register str, Register temp, Label* failure);
97 
98   bool emitCallScriptedGetterShared(ValOperandId receiverId,
99                                     uint32_t getterOffset, bool sameRealm,
100                                     uint32_t nargsAndFlagsOffset,
101                                     mozilla::Maybe<uint32_t> icScriptOffset);
102   bool emitCallScriptedSetterShared(ObjOperandId receiverId,
103                                     uint32_t setterOffset, ValOperandId rhsId,
104                                     bool sameRealm,
105                                     uint32_t nargsAndFlagsOffset,
106                                     mozilla::Maybe<uint32_t> icScriptOffset);
107 
108  public:
109   friend class AutoStubFrame;
110 
111   BaselineCacheIRCompiler(JSContext* cx, const CacheIRWriter& writer,
112                           uint32_t stubDataOffset);
113 
114   [[nodiscard]] bool init(CacheKind kind);
115 
116   template <typename Fn, Fn fn>
117   void callVM(MacroAssembler& masm);
118 
119   JitCode* compile();
120 
121   bool makesGCCalls() const;
122 
123   Address stubAddress(uint32_t offset) const;
124 
125  private:
126   CACHE_IR_COMPILER_UNSHARED_GENERATED
127 };
128 
129 }  // namespace jit
130 }  // namespace js
131 
132 #endif /* jit_BaselineCacheIRCompiler_h */
133