2009-06-25 Dimitri Glazkov <dglazkov@chromium.org>
[webbrowser.git] / JavaScriptCore / jit / JITStubCall.h
blobbc07178c103dd111a24948712385ad59775f32a2
1 /*
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
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.
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.
26 #ifndef JITStubCall_h
27 #define JITStubCall_h
29 #include <wtf/Platform.h>
31 #if ENABLE(JIT)
33 namespace JSC {
35 class JITStubCall {
36 public:
37 JITStubCall(JIT* jit, JSObject* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
38 : m_jit(jit)
39 , m_stub(reinterpret_cast<void*>(stub))
40 , m_returnType(Value)
41 , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference();
45 JITStubCall(JIT* jit, JSPropertyNameIterator* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
46 : m_jit(jit)
47 , m_stub(reinterpret_cast<void*>(stub))
48 , m_returnType(Value)
49 , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference();
53 JITStubCall(JIT* jit, void* (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
54 : m_jit(jit)
55 , m_stub(reinterpret_cast<void*>(stub))
56 , m_returnType(Value)
57 , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference();
61 JITStubCall(JIT* jit, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
62 : m_jit(jit)
63 , m_stub(reinterpret_cast<void*>(stub))
64 , m_returnType(Value)
65 , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference();
69 JITStubCall(JIT* jit, void (JIT_STUB *stub)(STUB_ARGS_DECLARATION))
70 : m_jit(jit)
71 , m_stub(reinterpret_cast<void*>(stub))
72 , m_returnType(Void)
73 , m_argumentIndex(1) // Index 0 is reserved for restoreArgumentReference();
77 // Arguments are added first to last.
79 void addArgument(JIT::Imm32 argument)
81 m_jit->poke(argument, m_argumentIndex);
82 ++m_argumentIndex;
85 void addArgument(JIT::ImmPtr argument)
87 m_jit->poke(argument, m_argumentIndex);
88 ++m_argumentIndex;
91 void addArgument(JIT::RegisterID argument)
93 m_jit->poke(argument, m_argumentIndex);
94 ++m_argumentIndex;
97 void addArgument(unsigned src, JIT::RegisterID scratchRegister) // src is a virtual register.
99 if (m_jit->m_codeBlock->isConstantRegisterIndex(src))
100 addArgument(JIT::ImmPtr(JSValue::encode(m_jit->m_codeBlock->getConstant(src))));
101 else {
102 m_jit->loadPtr(JIT::Address(JIT::callFrameRegister, src * sizeof(Register)), scratchRegister);
103 addArgument(scratchRegister);
105 m_jit->killLastResultRegister();
108 JIT::Call call()
110 #if ENABLE(OPCODE_SAMPLING)
111 if (m_jit->m_bytecodeIndex != (unsigned)-1)
112 m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeIndex, true);
113 #endif
115 m_jit->restoreArgumentReference();
116 JIT::Call call = m_jit->call();
117 m_jit->m_calls.append(CallRecord(call, m_jit->m_bytecodeIndex, m_stub));
119 #if ENABLE(OPCODE_SAMPLING)
120 if (m_jit->m_bytecodeIndex != (unsigned)-1)
121 m_jit->sampleInstruction(m_jit->m_codeBlock->instructions().begin() + m_jit->m_bytecodeIndex, false);
122 #endif
124 m_jit->killLastResultRegister();
125 return call;
128 JIT::Call call(unsigned dst) // dst is a virtual register.
130 ASSERT(m_returnType == Value);
131 JIT::Call call = this->call();
132 m_jit->emitPutVirtualRegister(dst);
133 return call;
136 JIT::Call call(JIT::RegisterID dst)
138 ASSERT(m_returnType == Value);
139 JIT::Call call = this->call();
140 if (dst != JIT::returnValueRegister)
141 m_jit->move(JIT::returnValueRegister, dst);
142 return call;
145 private:
146 JIT* m_jit;
147 void* m_stub;
148 enum { Value, Void } m_returnType;
149 size_t m_argumentIndex;
152 class CallEvalJITStub : public JITStubCall {
153 public:
154 CallEvalJITStub(JIT* jit, Instruction* instruction)
155 : JITStubCall(jit, JITStubs::cti_op_call_eval)
157 int callee = instruction[2].u.operand;
158 int argCount = instruction[3].u.operand;
159 int registerOffset = instruction[4].u.operand;
161 addArgument(callee, JIT::regT2);
162 addArgument(JIT::Imm32(registerOffset));
163 addArgument(JIT::Imm32(argCount));
168 #endif // ENABLE(JIT)
170 #endif // JITStubCall_h