summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/interpreter
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/interpreter')
-rw-r--r--Source/JavaScriptCore/interpreter/AbstractPC.cpp55
-rw-r--r--Source/JavaScriptCore/interpreter/AbstractPC.h91
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.cpp100
-rw-r--r--Source/JavaScriptCore/interpreter/CallFrame.h23
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp93
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.h16
6 files changed, 292 insertions, 86 deletions
diff --git a/Source/JavaScriptCore/interpreter/AbstractPC.cpp b/Source/JavaScriptCore/interpreter/AbstractPC.cpp
new file mode 100644
index 000000000..863915bda
--- /dev/null
+++ b/Source/JavaScriptCore/interpreter/AbstractPC.cpp
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "AbstractPC.h"
+
+#include "CallFrame.h"
+#include "JSGlobalData.h"
+#include "JSObject.h"
+#include "ScopeChain.h"
+
+namespace JSC {
+
+AbstractPC::AbstractPC(JSGlobalData& globalData, ExecState* exec)
+{
+ UNUSED_PARAM(globalData);
+
+#if ENABLE(JIT)
+ if (globalData.canUseJIT()) {
+ m_pointer = exec->returnPC().value();
+ m_mode = JIT;
+ return;
+ }
+#endif
+
+#if ENABLE(INTERPRETER)
+ m_pointer = exec->returnVPC();
+ m_mode = Interpreter;
+#endif
+}
+
+} // namespace JSC
+
diff --git a/Source/JavaScriptCore/interpreter/AbstractPC.h b/Source/JavaScriptCore/interpreter/AbstractPC.h
new file mode 100644
index 000000000..dffaaf343
--- /dev/null
+++ b/Source/JavaScriptCore/interpreter/AbstractPC.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef AbstractPC_h
+#define AbstractPC_h
+
+#include "MacroAssemblerCodeRef.h"
+#include <wtf/Platform.h>
+
+namespace JSC {
+
+class JSGlobalData;
+class ExecState;
+struct Instruction;
+
+class AbstractPC {
+public:
+ AbstractPC()
+ : m_pointer(0)
+ , m_mode(None)
+ {
+ }
+
+ AbstractPC(JSGlobalData&, ExecState*);
+
+#if ENABLE(JIT)
+ AbstractPC(ReturnAddressPtr ptr)
+ : m_pointer(ptr.value())
+ , m_mode(JIT)
+ {
+ }
+
+ bool hasJITReturnAddress() const { return m_mode == JIT; }
+ ReturnAddressPtr jitReturnAddress() const
+ {
+ ASSERT(hasJITReturnAddress());
+ return ReturnAddressPtr(m_pointer);
+ }
+#endif
+
+#if ENABLE(INTERPRETER)
+ AbstractPC(Instruction* vPC)
+ : m_pointer(vPC)
+ , m_mode(Interpreter)
+ {
+ }
+
+ bool hasInterpreterReturnAddress() const { return m_mode == Interpreter; }
+ Instruction* interpreterReturnAddress() const
+ {
+ ASSERT(hasInterpreterReturnAddress());
+ return static_cast<Instruction*>(m_pointer);
+ }
+#endif
+
+ bool isSet() const { return m_mode != None; }
+ bool operator!() const { return !isSet(); }
+
+private:
+ void* m_pointer;
+
+ enum Mode { None, JIT, Interpreter };
+ Mode m_mode;
+};
+
+} // namespace JSC
+
+#endif // AbstractPC_h
+
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.cpp b/Source/JavaScriptCore/interpreter/CallFrame.cpp
index 6dba77898..3ef5bd26f 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.cpp
+++ b/Source/JavaScriptCore/interpreter/CallFrame.cpp
@@ -61,53 +61,66 @@ bool CallFrame::isInlineCallFrameSlow()
JSFunction* calleeAsFunction = asFunction(calleeAsFunctionCell);
return calleeAsFunction->executable() != codeBlock()->ownerExecutable();
}
-
-CallFrame* CallFrame::trueCallerFrame()
+
+CallFrame* CallFrame::trueCallFrame(AbstractPC pc)
{
- // this -> The callee; this is either an inlined callee in which case it already has
- // a pointer to the true caller. Otherwise it contains current PC in the machine
- // caller.
- //
- // machineCaller -> The caller according to the machine, which may be zero or
- // more frames above the true caller due to inlining.
- //
- // trueCaller -> The real caller.
-
// Am I an inline call frame? If so, we're done.
if (isInlineCallFrame())
- return callerFrame();
+ return this;
- // I am a machine call frame, so the question is: is my caller a machine call frame
- // that has inlines or a machine call frame that doesn't?
- CallFrame* machineCaller = callerFrame()->removeHostCallFrameFlag();
- if (!machineCaller)
- return 0;
- ASSERT(!machineCaller->isInlineCallFrame());
- if (!machineCaller->codeBlock())
- return machineCaller;
- if (!machineCaller->codeBlock()->hasCodeOrigins())
- return machineCaller; // No inlining, so machineCaller == trueCaller
+ // If I don't have a code block, then I'm not DFG code, so I'm the true call frame.
+ CodeBlock* machineCodeBlock = codeBlock();
+ if (!machineCodeBlock)
+ return this;
- // Figure out where the caller frame would have gone relative to the machine
- // caller, and rematerialize it. Do so for the entire inline stack.
+ // If the code block does not have any code origins, then there was no inlining, so
+ // I'm done.
+ if (!machineCodeBlock->hasCodeOrigins())
+ return this;
- CodeOrigin codeOrigin = machineCaller->codeBlock()->codeOriginForReturn(returnPC());
+ // At this point the PC must be due either to the DFG, or it must be unset.
+ ASSERT(pc.hasJITReturnAddress() || !pc);
+
+ // Try to determine the CodeOrigin. If we don't have a pc set then the only way
+ // that this makes sense is if the CodeOrigin index was set in the call frame.
+ // FIXME: Note that you will see "Not currently in inlined code" comments below.
+ // Currently, we do not record code origins for code that is not inlined, because
+ // the only thing that we use code origins for is determining the inline stack.
+ // But in the future, we'll want to use this same functionality (having a code
+ // origin mapping for any calls out of JIT code) to determine the PC at any point
+ // in the stack even if not in inlined code. When that happens, the code below
+ // will have to change the way it detects the presence of inlining: it will always
+ // get a code origin, but sometimes, that code origin will not have an inline call
+ // frame. In that case, this method should bail and return this.
+ CodeOrigin codeOrigin;
+ if (pc.isSet()) {
+ ReturnAddressPtr currentReturnPC = pc.jitReturnAddress();
+
+ if (!machineCodeBlock->codeOriginForReturn(currentReturnPC, codeOrigin))
+ return this; // Not currently in inlined code.
+ } else {
+ unsigned index = codeOriginIndexForDFGWithInlining();
+ if (index == UINT_MAX)
+ return this; // Not currently in inlined code.
+
+ codeOrigin = machineCodeBlock->codeOrigin(index);
+ }
for (InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame; inlineCallFrame;) {
InlineCallFrame* nextInlineCallFrame = inlineCallFrame->caller.inlineCallFrame;
- CallFrame* inlinedCaller = machineCaller + inlineCallFrame->stackOffset;
+ CallFrame* inlinedCaller = this + inlineCallFrame->stackOffset;
JSFunction* calleeAsFunction = inlineCallFrame->callee.get();
// Fill in the inlinedCaller
- inlinedCaller->setCodeBlock(machineCaller->codeBlock());
+ inlinedCaller->setCodeBlock(machineCodeBlock);
inlinedCaller->setScopeChain(calleeAsFunction->scope());
if (nextInlineCallFrame)
- inlinedCaller->setCallerFrame(machineCaller + nextInlineCallFrame->stackOffset);
+ inlinedCaller->setCallerFrame(this + nextInlineCallFrame->stackOffset);
else
- inlinedCaller->setCallerFrame(machineCaller);
+ inlinedCaller->setCallerFrame(this);
inlinedCaller->setInlineCallFrame(inlineCallFrame);
inlinedCaller->setArgumentCountIncludingThis(inlineCallFrame->arguments.size());
@@ -116,7 +129,34 @@ CallFrame* CallFrame::trueCallerFrame()
inlineCallFrame = nextInlineCallFrame;
}
- return machineCaller + codeOrigin.inlineCallFrame->stackOffset;
+ return this + codeOrigin.inlineCallFrame->stackOffset;
+}
+
+CallFrame* CallFrame::trueCallerFrame()
+{
+ // this -> The callee; this is either an inlined callee in which case it already has
+ // a pointer to the true caller. Otherwise it contains current PC in the machine
+ // caller.
+ //
+ // machineCaller -> The caller according to the machine, which may be zero or
+ // more frames above the true caller due to inlining.
+
+ // Am I an inline call frame? If so, we're done.
+ if (isInlineCallFrame())
+ return callerFrame();
+
+ // I am a machine call frame, so the question is: is my caller a machine call frame
+ // that has inlines or a machine call frame that doesn't?
+ CallFrame* machineCaller = callerFrame()->removeHostCallFrameFlag();
+ if (!machineCaller)
+ return 0;
+ ASSERT(!machineCaller->isInlineCallFrame());
+
+ // Figure out how we want to get the current code location.
+ if (hasHostCallFrameFlag() || returnAddressIsInCtiTrampoline(returnPC()))
+ return machineCaller->trueCallFrameFromVMCode();
+
+ return machineCaller->trueCallFrame(returnPC());
}
#endif
diff --git a/Source/JavaScriptCore/interpreter/CallFrame.h b/Source/JavaScriptCore/interpreter/CallFrame.h
index d5037b794..e0a291f8b 100644
--- a/Source/JavaScriptCore/interpreter/CallFrame.h
+++ b/Source/JavaScriptCore/interpreter/CallFrame.h
@@ -23,6 +23,7 @@
#ifndef CallFrame_h
#define CallFrame_h
+#include "AbstractPC.h"
#include "JSGlobalData.h"
#include "MacroAssemblerCodeRef.h"
#include "RegisterFile.h"
@@ -104,8 +105,10 @@ namespace JSC {
#if ENABLE(JIT)
ReturnAddressPtr returnPC() const { return ReturnAddressPtr(this[RegisterFile::ReturnPC].vPC()); }
#endif
+ AbstractPC abstractReturnPC(JSGlobalData& globalData) { return AbstractPC(globalData, this); }
#if ENABLE(DFG_JIT)
InlineCallFrame* inlineCallFrame() const { return this[RegisterFile::ReturnPC].asInlineCallFrame(); }
+ unsigned codeOriginIndexForDFGWithInlining() const { return this[RegisterFile::ArgumentCount].tag(); }
#else
// This will never be called if !ENABLE(DFG_JIT) since all calls should be guarded by
// isInlineCallFrame(). But to make it easier to write code without having a bunch of
@@ -185,14 +188,30 @@ namespace JSC {
void setInlineCallFrame(InlineCallFrame* inlineCallFrame) { static_cast<Register*>(this)[RegisterFile::ReturnPC] = inlineCallFrame; }
- // Call this to get the semantically correct JS CallFrame*. This resolves issues
- // surrounding inlining and the HostCallFrameFlag stuff.
+ // Call this to get the semantically correct JS CallFrame* for the
+ // currently executing function.
+ CallFrame* trueCallFrame(AbstractPC);
+
+ // Call this to get the semantically correct JS CallFrame* corresponding
+ // to the caller. This resolves issues surrounding inlining and the
+ // HostCallFrameFlag stuff.
CallFrame* trueCallerFrame();
#else
bool isInlineCallFrame() { return false; }
+ CallFrame* trueCallFrame(AbstractPC) { return this; }
CallFrame* trueCallerFrame() { return callerFrame()->removeHostCallFrameFlag(); }
#endif
+
+ // Call this to get the true call frame (accounted for inlining and any
+ // other optimizations), when you have entered into VM code through one
+ // of the "blessed" entrypoints (JITStubs or DFGOperations). This means
+ // that if you're pretty much anywhere in the VM you can safely call this;
+ // though if you were to magically get an ExecState* by, say, interrupting
+ // a thread that is running JS code and brutishly scraped the call frame
+ // register, calling this method would probably lead to horrible things
+ // happening.
+ CallFrame* trueCallFrameFromVMCode() { return trueCallFrame(AbstractPC()); }
private:
static const intptr_t HostCallFrameFlag = 1;
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 980bf8a1a..51843f2d2 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -905,7 +905,7 @@ JSValue Interpreter::execute(ProgramExecutable* program, CallFrame* callFrame, S
PutPropertySlot slot;
globalObject->methodTable()->put(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, slot);
} else
- globalObject->methodTable()->putWithAttributes(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, DontEnum | DontDelete);
+ globalObject->methodTable()->putDirectVirtual(globalObject, callFrame, JSONPPath[0].m_pathEntryName, JSONPValue, DontEnum | DontDelete);
// var declarations return undefined
result = jsUndefined();
continue;
@@ -1324,7 +1324,7 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
JSObject* variableObject;
for (ScopeChainNode* node = scopeChain; ; node = node->next.get()) {
ASSERT(node);
- if (node->object->isVariableObject()) {
+ if (node->object->isVariableObject() && !node->object->isStaticScopeObject()) {
variableObject = static_cast<JSVariableObject*>(node->object.get());
break;
}
@@ -2579,7 +2579,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (propName.getUInt32(i))
callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, i));
else {
- Identifier property(callFrame, propName.toString(callFrame));
+ Identifier property(callFrame, propName.toString(callFrame)->value(callFrame));
CHECK_FOR_EXCEPTION();
callFrame->uncheckedR(dst) = jsBoolean(baseObj->hasProperty(callFrame, property));
}
@@ -3310,9 +3310,10 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
Identifier& ident = codeBlock->identifier(property);
PutPropertySlot slot(codeBlock->isStrictMode());
- if (direct)
- baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot);
- else
+ if (direct) {
+ ASSERT(baseValue.isObject());
+ asObject(baseValue)->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
+ } else
baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
CHECK_FOR_EXCEPTION();
@@ -3428,9 +3429,10 @@ skip_id_custom_self:
JSValue baseValue = callFrame->r(base).jsValue();
Identifier& ident = codeBlock->identifier(property);
PutPropertySlot slot(codeBlock->isStrictMode());
- if (direct)
- baseValue.putDirect(callFrame, ident, callFrame->r(value).jsValue(), slot);
- else
+ if (direct) {
+ ASSERT(baseValue.isObject());
+ asObject(baseValue)->putDirect(*globalData, ident, callFrame->r(value).jsValue(), slot);
+ } else
baseValue.put(callFrame, ident, callFrame->r(value).jsValue(), slot);
CHECK_FOR_EXCEPTION();
@@ -3482,7 +3484,7 @@ skip_id_custom_self:
NEXT_INSTRUCTION();
}
{
- Identifier propertyName(callFrame, subscript.toString(callFrame));
+ Identifier propertyName(callFrame, subscript.toString(callFrame)->value(callFrame));
result = baseValue.get(callFrame, propertyName);
}
CHECK_FOR_EXCEPTION();
@@ -3557,7 +3559,7 @@ skip_id_custom_self:
else
result = baseValue.get(callFrame, i);
} else {
- Identifier property(callFrame, subscript.toString(callFrame));
+ Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
result = baseValue.get(callFrame, property);
}
@@ -3604,7 +3606,7 @@ skip_id_custom_self:
} else
baseValue.put(callFrame, i, callFrame->r(value).jsValue());
} else {
- Identifier property(callFrame, subscript.toString(callFrame));
+ Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
if (!globalData->exception) { // Don't put to an object if toString threw an exception.
PutPropertySlot slot(codeBlock->isStrictMode());
baseValue.put(callFrame, property, callFrame->r(value).jsValue(), slot);
@@ -3636,7 +3638,7 @@ skip_id_custom_self:
result = baseObj->methodTable()->deletePropertyByIndex(baseObj, callFrame, i);
else {
CHECK_FOR_EXCEPTION();
- Identifier property(callFrame, subscript.toString(callFrame));
+ Identifier property(callFrame, subscript.toString(callFrame)->value(callFrame));
CHECK_FOR_EXCEPTION();
result = baseObj->methodTable()->deleteProperty(baseObj, callFrame, property);
}
@@ -4943,7 +4945,7 @@ skip_id_custom_self:
original constructor, using constant message as the
message string. The result is thrown.
*/
- UString message = callFrame->r(vPC[1].u.operand).jsValue().toString(callFrame);
+ UString message = callFrame->r(vPC[1].u.operand).jsValue().toString(callFrame)->value(callFrame);
exceptionValue = JSValue(createReferenceError(callFrame, message));
goto vm_throw;
}
@@ -4957,52 +4959,41 @@ skip_id_custom_self:
int result = vPC[1].u.operand;
return callFrame->r(result).jsValue();
}
- DEFINE_OPCODE(op_put_getter) {
- /* put_getter base(r) property(id) function(r)
+ DEFINE_OPCODE(op_put_getter_setter) {
+ /* put_getter_setter base(r) property(id) getter(r) setter(r)
- Sets register function on register base as the getter named
- by identifier property. Base and function are assumed to be
- objects as this op should only be used for getters defined
- in object literal form.
+ Puts accessor descriptor to register base as the named
+ identifier property. Base and function may be objects
+ or undefined, this op should only be used for accessors
+ defined in object literal form.
Unlike many opcodes, this one does not write any output to
the register file.
*/
int base = vPC[1].u.operand;
int property = vPC[2].u.operand;
- int function = vPC[3].u.operand;
+ int getterReg = vPC[3].u.operand;
+ int setterReg = vPC[4].u.operand;
ASSERT(callFrame->r(base).jsValue().isObject());
JSObject* baseObj = asObject(callFrame->r(base).jsValue());
Identifier& ident = codeBlock->identifier(property);
- ASSERT(callFrame->r(function).jsValue().isObject());
- baseObj->methodTable()->defineGetter(baseObj, callFrame, ident, asObject(callFrame->r(function).jsValue()), 0);
- vPC += OPCODE_LENGTH(op_put_getter);
- NEXT_INSTRUCTION();
- }
- DEFINE_OPCODE(op_put_setter) {
- /* put_setter base(r) property(id) function(r)
+ GetterSetter* accessor = GetterSetter::create(callFrame);
- Sets register function on register base as the setter named
- by identifier property. Base and function are assumed to be
- objects as this op should only be used for setters defined
- in object literal form.
+ JSValue getter = callFrame->r(getterReg).jsValue();
+ JSValue setter = callFrame->r(setterReg).jsValue();
+ ASSERT(getter.isObject() || getter.isUndefined());
+ ASSERT(setter.isObject() || setter.isUndefined());
+ ASSERT(getter.isObject() || setter.isObject());
- Unlike many opcodes, this one does not write any output to
- the register file.
- */
- int base = vPC[1].u.operand;
- int property = vPC[2].u.operand;
- int function = vPC[3].u.operand;
-
- ASSERT(callFrame->r(base).jsValue().isObject());
- JSObject* baseObj = asObject(callFrame->r(base).jsValue());
- Identifier& ident = codeBlock->identifier(property);
- ASSERT(callFrame->r(function).jsValue().isObject());
- baseObj->methodTable()->defineSetter(baseObj, callFrame, ident, asObject(callFrame->r(function).jsValue()), 0);
+ if (!getter.isUndefined())
+ accessor->setGetter(callFrame->globalData(), asObject(getter));
+ if (!setter.isUndefined())
+ accessor->setSetter(callFrame->globalData(), asObject(setter));
+ baseObj->putDirectAccessor(callFrame->globalData(), ident, accessor, Accessor);
- vPC += OPCODE_LENGTH(op_put_setter);
+ vPC += OPCODE_LENGTH(op_put_getter_setter);
NEXT_INSTRUCTION();
}
DEFINE_OPCODE(op_method_check) {
@@ -5106,9 +5097,9 @@ skip_id_custom_self:
#endif // ENABLE(INTERPRETER)
}
-JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* function) const
+JSValue Interpreter::retrieveArgumentsFromVMCode(CallFrame* callFrame, JSFunction* function) const
{
- CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
+ CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
if (!functionCallFrame)
return jsNull();
@@ -5130,9 +5121,9 @@ JSValue Interpreter::retrieveArguments(CallFrame* callFrame, JSFunction* functio
return JSValue(arguments);
}
-JSValue Interpreter::retrieveCaller(CallFrame* callFrame, JSFunction* function) const
+JSValue Interpreter::retrieveCallerFromVMCode(CallFrame* callFrame, JSFunction* function) const
{
- CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
+ CallFrame* functionCallFrame = findFunctionCallFrameFromVMCode(callFrame, function);
if (!functionCallFrame)
return jsNull();
@@ -5177,9 +5168,9 @@ void Interpreter::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intp
function = callerFrame->callee();
}
-CallFrame* Interpreter::findFunctionCallFrame(CallFrame* callFrame, JSFunction* function)
+CallFrame* Interpreter::findFunctionCallFrameFromVMCode(CallFrame* callFrame, JSFunction* function)
{
- for (CallFrame* candidate = callFrame; candidate; candidate = candidate->trueCallerFrame()) {
+ for (CallFrame* candidate = callFrame->trueCallFrameFromVMCode(); candidate; candidate = candidate->trueCallerFrame()) {
if (candidate->callee() == function)
return candidate;
}
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.h b/Source/JavaScriptCore/interpreter/Interpreter.h
index 6dfd331f8..1943513ae 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.h
+++ b/Source/JavaScriptCore/interpreter/Interpreter.h
@@ -79,6 +79,16 @@ namespace JSC {
JSGlobalData& globalData;
CallFrame* oldCallFrame;
};
+
+ class NativeCallFrameTracer {
+ public:
+ ALWAYS_INLINE NativeCallFrameTracer(JSGlobalData* global, CallFrame* callFrame)
+ {
+ ASSERT(global);
+ ASSERT(callFrame);
+ global->topCallFrame = callFrame;
+ }
+ };
#if PLATFORM(IOS)
// We use a smaller reentrancy limit on iPhone because of the high amount of
@@ -131,8 +141,8 @@ namespace JSC {
JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, ScopeChainNode*);
JSValue execute(EvalExecutable*, CallFrame*, JSValue thisValue, ScopeChainNode*, int globalRegisterOffset);
- JSValue retrieveArguments(CallFrame*, JSFunction*) const;
- JS_EXPORT_PRIVATE JSValue retrieveCaller(CallFrame*, JSFunction*) const;
+ JSValue retrieveArgumentsFromVMCode(CallFrame*, JSFunction*) const;
+ JS_EXPORT_PRIVATE JSValue retrieveCallerFromVMCode(CallFrame*, JSFunction*) const;
JS_EXPORT_PRIVATE void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue& function) const;
void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
@@ -172,7 +182,7 @@ namespace JSC {
static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
- static CallFrame* findFunctionCallFrame(CallFrame*, JSFunction*);
+ static CallFrame* findFunctionCallFrameFromVMCode(CallFrame*, JSFunction*);
JSValue privateExecute(ExecutionFlag, RegisterFile*, CallFrame*);