2 * Copyright (C) 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #include "MacroAssemblerCodeRef.h"
37 JITStubCall(JIT
* jit
, JSObject
* (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
41 , m_stackIndex(JITSTACKFRAME_ARGS_INDEX
)
45 JITStubCall(JIT
* jit
, JSPropertyNameIterator
* (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
49 , m_stackIndex(JITSTACKFRAME_ARGS_INDEX
)
53 JITStubCall(JIT
* jit
, void* (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
56 , m_returnType(VoidPtr
)
57 , m_stackIndex(JITSTACKFRAME_ARGS_INDEX
)
61 JITStubCall(JIT
* jit
, int (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
65 , m_stackIndex(JITSTACKFRAME_ARGS_INDEX
)
69 JITStubCall(JIT
* jit
, bool (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
73 , m_stackIndex(JITSTACKFRAME_ARGS_INDEX
)
77 JITStubCall(JIT
* jit
, void (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
81 , m_stackIndex(JITSTACKFRAME_ARGS_INDEX
)
86 JITStubCall(JIT
* jit
, EncodedJSValue (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
90 , m_stackIndex(JITSTACKFRAME_ARGS_INDEX
)
95 // Arguments are added first to last.
99 m_stackIndex
+= stackIndexStep
;
102 void addArgument(JIT::TrustedImm32 argument
)
104 m_jit
->poke(argument
, m_stackIndex
);
105 m_stackIndex
+= stackIndexStep
;
108 void addArgument(JIT::TrustedImmPtr argument
)
110 m_jit
->poke(argument
, m_stackIndex
);
111 m_stackIndex
+= stackIndexStep
;
114 void addArgument(JIT::RegisterID argument
)
116 m_jit
->poke(argument
, m_stackIndex
);
117 m_stackIndex
+= stackIndexStep
;
120 #if USE(JSVALUE32_64)
121 void addArgument(const JSValue
& value
)
123 m_jit
->poke(JIT::Imm32(value
.payload()), m_stackIndex
);
124 m_jit
->poke(JIT::Imm32(value
.tag()), m_stackIndex
+ 1);
125 m_stackIndex
+= stackIndexStep
;
129 void addArgument(JIT::RegisterID tag
, JIT::RegisterID payload
)
131 m_jit
->poke(payload
, m_stackIndex
);
132 m_jit
->poke(tag
, m_stackIndex
+ 1);
133 m_stackIndex
+= stackIndexStep
;
136 #if USE(JSVALUE32_64)
137 void addArgument(unsigned srcVirtualRegister
)
139 if (m_jit
->m_codeBlock
->isConstantRegisterIndex(srcVirtualRegister
)) {
140 addArgument(m_jit
->getConstantOperand(srcVirtualRegister
));
144 m_jit
->emitLoad(srcVirtualRegister
, JIT::regT1
, JIT::regT0
);
145 addArgument(JIT::regT1
, JIT::regT0
);
148 void getArgument(size_t argumentNumber
, JIT::RegisterID tag
, JIT::RegisterID payload
)
150 size_t stackIndex
= JITSTACKFRAME_ARGS_INDEX
+ (argumentNumber
* stackIndexStep
);
151 m_jit
->peek(payload
, stackIndex
);
152 m_jit
->peek(tag
, stackIndex
+ 1);
155 void addArgument(unsigned src
, JIT::RegisterID scratchRegister
) // src is a virtual register.
157 if (m_jit
->m_codeBlock
->isConstantRegisterIndex(src
))
158 addArgument(JIT::ImmPtr(JSValue::encode(m_jit
->m_codeBlock
->getConstant(src
))));
160 m_jit
->loadPtr(JIT::Address(JIT::callFrameRegister
, src
* sizeof(Register
)), scratchRegister
);
161 addArgument(scratchRegister
);
163 m_jit
->killLastResultRegister();
169 #if ENABLE(OPCODE_SAMPLING)
170 if (m_jit
->m_bytecodeOffset
!= (unsigned)-1)
171 m_jit
->sampleInstruction(m_jit
->m_codeBlock
->instructions().begin() + m_jit
->m_bytecodeOffset
, true);
174 m_jit
->restoreArgumentReference();
175 JIT::Call call
= m_jit
->call();
176 m_jit
->m_calls
.append(CallRecord(call
, m_jit
->m_bytecodeOffset
, m_stub
.value()));
178 #if ENABLE(OPCODE_SAMPLING)
179 if (m_jit
->m_bytecodeOffset
!= (unsigned)-1)
180 m_jit
->sampleInstruction(m_jit
->m_codeBlock
->instructions().begin() + m_jit
->m_bytecodeOffset
, false);
183 #if USE(JSVALUE32_64)
186 m_jit
->killLastResultRegister();
191 #if USE(JSVALUE32_64)
192 JIT::Call
call(unsigned dst
) // dst is a virtual register.
194 ASSERT(m_returnType
== Value
|| m_returnType
== Cell
);
195 JIT::Call call
= this->call();
196 if (m_returnType
== Value
)
197 m_jit
->emitStore(dst
, JIT::regT1
, JIT::regT0
);
199 m_jit
->emitStoreCell(dst
, JIT::returnValueRegister
);
203 JIT::Call
call(unsigned dst
) // dst is a virtual register.
205 ASSERT(m_returnType
== VoidPtr
|| m_returnType
== Cell
);
206 JIT::Call call
= this->call();
207 m_jit
->emitPutVirtualRegister(dst
);
212 JIT::Call
call(JIT::RegisterID dst
) // dst is a machine register.
214 #if USE(JSVALUE32_64)
215 ASSERT(m_returnType
== Value
|| m_returnType
== VoidPtr
|| m_returnType
== Int
|| m_returnType
== Cell
);
217 ASSERT(m_returnType
== VoidPtr
|| m_returnType
== Int
|| m_returnType
== Cell
);
219 JIT::Call call
= this->call();
220 if (dst
!= JIT::returnValueRegister
)
221 m_jit
->move(JIT::returnValueRegister
, dst
);
226 static const size_t stackIndexStep
= sizeof(EncodedJSValue
) == 2 * sizeof(void*) ? 2 : 1;
230 enum { Void
, VoidPtr
, Int
, Value
, Cell
} m_returnType
;
235 #endif // ENABLE(JIT)
237 #endif // JITStubCall_h