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 <wtf/Platform.h>
37 JITStubCall(JIT
* jit
, JSObject
* (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
39 , m_stub(reinterpret_cast<void*>(stub
))
41 , m_stackIndex(stackIndexStart
)
45 JITStubCall(JIT
* jit
, JSPropertyNameIterator
* (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
47 , m_stub(reinterpret_cast<void*>(stub
))
49 , m_stackIndex(stackIndexStart
)
53 JITStubCall(JIT
* jit
, void* (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
55 , m_stub(reinterpret_cast<void*>(stub
))
56 , m_returnType(VoidPtr
)
57 , m_stackIndex(stackIndexStart
)
61 JITStubCall(JIT
* jit
, int (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
63 , m_stub(reinterpret_cast<void*>(stub
))
65 , m_stackIndex(stackIndexStart
)
69 JITStubCall(JIT
* jit
, bool (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
71 , m_stub(reinterpret_cast<void*>(stub
))
73 , m_stackIndex(stackIndexStart
)
77 JITStubCall(JIT
* jit
, void (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
79 , m_stub(reinterpret_cast<void*>(stub
))
81 , m_stackIndex(stackIndexStart
)
86 JITStubCall(JIT
* jit
, EncodedJSValue (JIT_STUB
*stub
)(STUB_ARGS_DECLARATION
))
88 , m_stub(reinterpret_cast<void*>(stub
))
90 , m_stackIndex(stackIndexStart
)
95 // Arguments are added first to last.
99 m_stackIndex
+= stackIndexStep
;
102 void addArgument(JIT::Imm32 argument
)
104 m_jit
->poke(argument
, m_stackIndex
);
105 m_stackIndex
+= stackIndexStep
;
108 void addArgument(JIT::ImmPtr 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 void addArgument(const JSValue
& value
)
122 m_jit
->poke(JIT::Imm32(value
.payload()), m_stackIndex
);
123 m_jit
->poke(JIT::Imm32(value
.tag()), m_stackIndex
+ 1);
124 m_stackIndex
+= stackIndexStep
;
127 void addArgument(JIT::RegisterID tag
, JIT::RegisterID payload
)
129 m_jit
->poke(payload
, m_stackIndex
);
130 m_jit
->poke(tag
, m_stackIndex
+ 1);
131 m_stackIndex
+= stackIndexStep
;
134 #if USE(JSVALUE32_64)
135 void addArgument(unsigned srcVirtualRegister
)
137 if (m_jit
->m_codeBlock
->isConstantRegisterIndex(srcVirtualRegister
)) {
138 addArgument(m_jit
->getConstantOperand(srcVirtualRegister
));
142 m_jit
->emitLoad(srcVirtualRegister
, JIT::regT1
, JIT::regT0
);
143 addArgument(JIT::regT1
, JIT::regT0
);
146 void getArgument(size_t argumentNumber
, JIT::RegisterID tag
, JIT::RegisterID payload
)
148 size_t stackIndex
= stackIndexStart
+ (argumentNumber
* stackIndexStep
);
149 m_jit
->peek(payload
, stackIndex
);
150 m_jit
->peek(tag
, stackIndex
+ 1);
153 void addArgument(unsigned src
, JIT::RegisterID scratchRegister
) // src is a virtual register.
155 if (m_jit
->m_codeBlock
->isConstantRegisterIndex(src
))
156 addArgument(JIT::ImmPtr(JSValue::encode(m_jit
->m_codeBlock
->getConstant(src
))));
158 m_jit
->loadPtr(JIT::Address(JIT::callFrameRegister
, src
* sizeof(Register
)), scratchRegister
);
159 addArgument(scratchRegister
);
161 m_jit
->killLastResultRegister();
167 #if ENABLE(OPCODE_SAMPLING)
168 if (m_jit
->m_bytecodeIndex
!= (unsigned)-1)
169 m_jit
->sampleInstruction(m_jit
->m_codeBlock
->instructions().begin() + m_jit
->m_bytecodeIndex
, true);
172 m_jit
->restoreArgumentReference();
173 JIT::Call call
= m_jit
->call();
174 m_jit
->m_calls
.append(CallRecord(call
, m_jit
->m_bytecodeIndex
, m_stub
));
176 #if ENABLE(OPCODE_SAMPLING)
177 if (m_jit
->m_bytecodeIndex
!= (unsigned)-1)
178 m_jit
->sampleInstruction(m_jit
->m_codeBlock
->instructions().begin() + m_jit
->m_bytecodeIndex
, false);
181 #if USE(JSVALUE32_64)
184 m_jit
->killLastResultRegister();
189 #if USE(JSVALUE32_64)
190 JIT::Call
call(unsigned dst
) // dst is a virtual register.
192 ASSERT(m_returnType
== Value
|| m_returnType
== Cell
);
193 JIT::Call call
= this->call();
194 if (m_returnType
== Value
)
195 m_jit
->emitStore(dst
, JIT::regT1
, JIT::regT0
);
197 m_jit
->emitStoreCell(dst
, JIT::returnValueRegister
);
201 JIT::Call
call(unsigned dst
) // dst is a virtual register.
203 ASSERT(m_returnType
== VoidPtr
|| m_returnType
== Cell
);
204 JIT::Call call
= this->call();
205 m_jit
->emitPutVirtualRegister(dst
);
210 JIT::Call
call(JIT::RegisterID dst
) // dst is a machine register.
212 #if USE(JSVALUE32_64)
213 ASSERT(m_returnType
== Value
|| m_returnType
== VoidPtr
|| m_returnType
== Int
|| m_returnType
== Cell
);
215 ASSERT(m_returnType
== VoidPtr
|| m_returnType
== Int
|| m_returnType
== Cell
);
217 JIT::Call call
= this->call();
218 if (dst
!= JIT::returnValueRegister
)
219 m_jit
->move(JIT::returnValueRegister
, dst
);
224 static const size_t stackIndexStep
= sizeof(EncodedJSValue
) == 2 * sizeof(void*) ? 2 : 1;
225 static const size_t stackIndexStart
= 1; // Index 0 is reserved for restoreArgumentReference().
229 enum { Void
, VoidPtr
, Int
, Value
, Cell
} m_returnType
;
234 #endif // ENABLE(JIT)
236 #endif // JITStubCall_h