source: webkit/trunk/JavaScriptCore/VM/Machine.h@ 37682

Last change on this file since 37682 was 37681, checked in by Darin Adler, 17 years ago

JavaScriptCore:

2008-10-18 Darin Adler <Darin Adler>

Reviewed by Oliver Hunt.

Remove casts from JSValue* to derived classes, replacing them with
calls to inline casting functions. These functions are also a bit
better than aidrect cast because they also do a runtime assertion.

Removed use of 0 as for JSValue*, changing call sites to use a
noValue() function instead.

Move things needed by classes derived from JSValue out of the class,
since the classes won't be deriving from JSValue any more soon.

I did most of these changes by changing JSValue to not be JSValue* any
more, then fixing a lot of the compilation problems, then rolling out
the JSValue change.

1.011x as fast on SunSpider (presumably due to some of the Machine.cpp changes)

  • API/APICast.h: Removed unneeded forward declarations.
  • API/JSCallbackObject.h: Added an asCallbackObject function for casting.
  • API/JSCallbackObjectFunctions.h: (JSC::JSCallbackObject::asCallbackObject): Added. (JSC::JSCallbackObject::getOwnPropertySlot): Use asObject. (JSC::JSCallbackObject::call): Use noValue. (JSC::JSCallbackObject::staticValueGetter): Use asCallbackObject. (JSC::JSCallbackObject::staticFunctionGetter): Ditto. (JSC::JSCallbackObject::callbackGetter): Ditto.
  • JavaScriptCore.xcodeproj/project.pbxproj: Added RegExpMatchesArray.h.
  • VM/CTI.cpp: (JSC::CTI::asInteger): Added. For use casting a JSValue to an integer. (JSC::CTI::emitGetArg): Use asInteger. (JSC::CTI::emitGetPutArg): Ditto. (JSC::CTI::getConstantImmediateNumericArg): Ditto. Also use noValue. (JSC::CTI::emitInitRegister): Use asInteger. (JSC::CTI::getDeTaggedConstantImmediate): Ditto. (JSC::CTI::compileOpCallInitializeCallFrame): Ditto. (JSC::CTI::compileOpCall): Ditto. (JSC::CTI::compileOpStrictEq): Ditto. (JSC::CTI::privateCompileMainPass): Ditto. (JSC::CTI::privateCompileGetByIdProto): Ditto. (JSC::CTI::privateCompileGetByIdChain): Ditto. (JSC::CTI::privateCompilePutByIdTransition): Ditto.
  • VM/CTI.h: Rewrite the ARG-related macros to use C++ casts instead of C casts and get rid of some extra parentheses. Addd declaration of asInteger.
  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::emitEqualityOp): Use asString. (JSC::CodeGenerator::emitLoad): Use noValue. (JSC::CodeGenerator::findScopedProperty): Change globalObject argument to JSObject* instead of JSValue*. (JSC::CodeGenerator::emitResolve): Remove unneeded cast. (JSC::CodeGenerator::emitGetScopedVar): Use asCell. (JSC::CodeGenerator::emitPutScopedVar): Ditto.
  • VM/CodeGenerator.h: Changed out argument of findScopedProperty. Also change the JSValueMap to use PtrHash explicitly instead of getting it from DefaultHash.
  • VM/JSPropertyNameIterator.cpp: (JSC::JSPropertyNameIterator::toPrimitive): Use noValue.
  • VM/JSPropertyNameIterator.h: (JSC::JSPropertyNameIterator::next): Ditto.
  • VM/Machine.cpp: (JSC::fastIsNumber): Moved isImmediate check here instead of checking for 0 inside Heap::isNumber. Use asCell and asNumberCell. (JSC::fastToInt32): Ditto. (JSC::fastToUInt32): Ditto. (JSC::jsLess): Use asString. (JSC::jsLessEq): Ditto. (JSC::jsAdd): Ditto. (JSC::jsTypeStringForValue): Use asObject. (JSC::jsIsObjectType): Ditto. (JSC::jsIsFunctionType): Ditto. (JSC::inlineResolveBase): Use noValue. (JSC::Machine::callEval): Use asString. Initialize result to undefined, not 0. (JSC::Machine::Machine): Remove unneeded casts to JSCell*. (JSC::Machine::throwException): Use asObject. (JSC::Machine::debug): Remove explicit calls to the DebuggerCallFrame constructor. (JSC::Machine::checkTimeout): Use noValue. (JSC::cachePrototypeChain): Use asObject. (JSC::Machine::tryCachePutByID): Use asCell. (JSC::Machine::tryCacheGetByID): Use aCell and asObject. (JSC::Machine::privateExecute): Use noValue, asCell, asObject, asString, asArray, asActivation, asFunction. Changed code that creates call frames for host functions to pass 0 for the function pointer -- the call frame needs a JSFunction* and a host function object is not one. This was caught by the assertions in the casting functions. Also remove some unneeded casts in cases where two values are compared. (JSC::Machine::retrieveLastCaller): Use noValue. (JSC::Machine::tryCTICachePutByID): Use asCell. (JSC::Machine::tryCTICacheGetByID): Use aCell and asObject. (JSC::setUpThrowTrampolineReturnAddress): Added this function to restore the PIC-branch-avoidance that was recently lost. (JSC::Machine::cti_op_add): Use asString. (JSC::Machine::cti_op_instanceof): Use asCell and asObject. (JSC::Machine::cti_op_call_JSFunction): Use asFunction. (JSC::Machine::cti_op_call_NotJSFunction): Changed code to pass 0 for the function pointer, since we don't have a JSFunction. Use asObject. (JSC::Machine::cti_op_tear_off_activation): Use asActivation. (JSC::Machine::cti_op_construct_JSConstruct): Use asFunction and asObject. (JSC::Machine::cti_op_construct_NotJSConstruct): use asObject. (JSC::Machine::cti_op_get_by_val): Use asArray and asString. (JSC::Machine::cti_op_resolve_func): Use asPointer; this helps prepare us for a situation where JSValue is not a pointer. (JSC::Machine::cti_op_put_by_val): Use asArray. (JSC::Machine::cti_op_put_by_val_array): Ditto. (JSC::Machine::cti_op_resolve_global): Use asGlobalObject. (JSC::Machine::cti_op_post_inc): Change VM_CHECK_EXCEPTION_2 to VM_CHECK_EXCEPTION_AT_END, since there's no observable work done after that point. Also use asPointer. (JSC::Machine::cti_op_resolve_with_base): Use asPointer. (JSC::Machine::cti_op_post_dec): Change VM_CHECK_EXCEPTION_2 to VM_CHECK_EXCEPTION_AT_END, since there's no observable work done after that point. Also use asPointer. (JSC::Machine::cti_op_call_eval): Use asObject, noValue, and change VM_CHECK_EXCEPTION_ARG to VM_THROW_EXCEPTION_AT_END. (JSC::Machine::cti_op_throw): Change return value to a JSValue*. (JSC::Machine::cti_op_in): Use asObject. (JSC::Machine::cti_op_switch_char): Use asString. (JSC::Machine::cti_op_switch_string): Ditto. (JSC::Machine::cti_op_put_getter): Use asObject. (JSC::Machine::cti_op_put_setter): Ditto. (JSC::Machine::cti_vm_throw): Change return value to a JSValue*. Use noValue.
  • VM/Machine.h: Change return values of both cti_op_throw and cti_vm_throw to JSValue*.
  • VM/Register.h: Remove nullJSValue, which is the same thing as noValue(). Also removed unneeded definition of JSValue.
  • kjs/ArgList.h: Removed unneeded definition of JSValue.
  • kjs/Arguments.h: (JSC::asArguments): Added.
  • kjs/ArrayPrototype.cpp: (JSC::getProperty): Use noValue. (JSC::arrayProtoFuncToString): Use asArray. (JSC::arrayProtoFuncToLocaleString): Ditto. (JSC::arrayProtoFuncConcat): Ditto. (JSC::arrayProtoFuncPop): Ditto. Also removed unneeded initialization of the result, which is set in both sides of the branch. (JSC::arrayProtoFuncPush): Ditto. (JSC::arrayProtoFuncShift): Removed unneeded initialization of the result, which is set in both sides of the branch. (JSC::arrayProtoFuncSort): Use asArray.
  • kjs/BooleanObject.h: (JSC::asBooleanObject): Added.
  • kjs/BooleanPrototype.cpp: (JSC::booleanProtoFuncToString): Use asBooleanObject. (JSC::booleanProtoFuncValueOf): Ditto.
  • kjs/CallData.cpp: (JSC::call): Use asObject and asFunction.
  • kjs/ConstructData.cpp: (JSC::construct): Ditto.
  • kjs/DateConstructor.cpp: (JSC::constructDate): Use asDateInstance.
  • kjs/DateInstance.h: (JSC::asDateInstance): Added.
  • kjs/DatePrototype.cpp: (JSC::dateProtoFuncToString): Use asDateInstance. (JSC::dateProtoFuncToUTCString): Ditto. (JSC::dateProtoFuncToDateString): Ditto. (JSC::dateProtoFuncToTimeString): Ditto. (JSC::dateProtoFuncToLocaleString): Ditto. (JSC::dateProtoFuncToLocaleDateString): Ditto. (JSC::dateProtoFuncToLocaleTimeString): Ditto. (JSC::dateProtoFuncValueOf): Ditto. (JSC::dateProtoFuncGetTime): Ditto. (JSC::dateProtoFuncGetFullYear): Ditto. (JSC::dateProtoFuncGetUTCFullYear): Ditto. (JSC::dateProtoFuncToGMTString): Ditto. (JSC::dateProtoFuncGetMonth): Ditto. (JSC::dateProtoFuncGetUTCMonth): Ditto. (JSC::dateProtoFuncGetDate): Ditto. (JSC::dateProtoFuncGetUTCDate): Ditto. (JSC::dateProtoFuncGetDay): Ditto. (JSC::dateProtoFuncGetUTCDay): Ditto. (JSC::dateProtoFuncGetHours): Ditto. (JSC::dateProtoFuncGetUTCHours): Ditto. (JSC::dateProtoFuncGetMinutes): Ditto. (JSC::dateProtoFuncGetUTCMinutes): Ditto. (JSC::dateProtoFuncGetSeconds): Ditto. (JSC::dateProtoFuncGetUTCSeconds): Ditto. (JSC::dateProtoFuncGetMilliSeconds): Ditto. (JSC::dateProtoFuncGetUTCMilliseconds): Ditto. (JSC::dateProtoFuncGetTimezoneOffset): Ditto. (JSC::dateProtoFuncSetTime): Ditto. (JSC::setNewValueFromTimeArgs): Ditto. (JSC::setNewValueFromDateArgs): Ditto. (JSC::dateProtoFuncSetYear): Ditto. (JSC::dateProtoFuncGetYear): Ditto.
  • kjs/DebuggerCallFrame.cpp: (JSC::DebuggerCallFrame::thisObject): Use asObject. (JSC::DebuggerCallFrame::evaluate): Use noValue.
  • kjs/DebuggerCallFrame.h: Added a constructor that takes only a callFrame.
  • kjs/ExecState.h: (JSC::ExecState::clearException): Use noValue.
  • kjs/FunctionPrototype.cpp: (JSC::functionProtoFuncToString): Use asFunction. (JSC::functionProtoFuncApply): Use asArguments and asArray.
  • kjs/GetterSetter.cpp: (JSC::GetterSetter::getPrimitiveNumber): Use noValue.
  • kjs/GetterSetter.h: (JSC::asGetterSetter): Added.
  • kjs/InternalFunction.cpp: (JSC::InternalFunction::name): Use asString.
  • kjs/InternalFunction.h: (JSC::asInternalFunction): Added.
  • kjs/JSActivation.cpp: (JSC::JSActivation::argumentsGetter): Use asActivation.
  • kjs/JSActivation.h: (JSC::asActivation): Added.
  • kjs/JSArray.cpp: (JSC::JSArray::putSlowCase): Use noValue. (JSC::JSArray::deleteProperty): Ditto. (JSC::JSArray::increaseVectorLength): Ditto. (JSC::JSArray::setLength): Ditto. (JSC::JSArray::pop): Ditto. (JSC::JSArray::sort): Ditto. (JSC::JSArray::compactForSorting): Ditto.
  • kjs/JSArray.h: (JSC::asArray): Added.
  • kjs/JSCell.cpp: (JSC::JSCell::getJSNumber): Use noValue.
  • kjs/JSCell.h: (JSC::asCell): Added. (JSC::JSValue::asCell): Changed to not preserve const. Given the wide use of JSValue* and JSCell*, it's not really useful to use const. (JSC::JSValue::isNumber): Use asValue. (JSC::JSValue::isString): Ditto. (JSC::JSValue::isGetterSetter): Ditto. (JSC::JSValue::isObject): Ditto. (JSC::JSValue::getNumber): Ditto. (JSC::JSValue::getString): Ditto. (JSC::JSValue::getObject): Ditto. (JSC::JSValue::getCallData): Ditto. (JSC::JSValue::getConstructData): Ditto. (JSC::JSValue::getUInt32): Ditto. (JSC::JSValue::getTruncatedInt32): Ditto. (JSC::JSValue::getTruncatedUInt32): Ditto. (JSC::JSValue::mark): Ditto. (JSC::JSValue::marked): Ditto. (JSC::JSValue::toPrimitive): Ditto. (JSC::JSValue::getPrimitiveNumber): Ditto. (JSC::JSValue::toBoolean): Ditto. (JSC::JSValue::toNumber): Ditto. (JSC::JSValue::toString): Ditto. (JSC::JSValue::toObject): Ditto. (JSC::JSValue::toThisObject): Ditto. (JSC::JSValue::needsThisConversion): Ditto. (JSC::JSValue::toThisString): Ditto. (JSC::JSValue::getJSNumber): Ditto.
  • kjs/JSFunction.cpp: (JSC::JSFunction::argumentsGetter): Use asFunction. (JSC::JSFunction::callerGetter): Ditto. (JSC::JSFunction::lengthGetter): Ditto. (JSC::JSFunction::construct): Use asObject.
  • kjs/JSFunction.h: (JSC::asFunction): Added.
  • kjs/JSGlobalObject.cpp: (JSC::lastInPrototypeChain): Use asObject.
  • kjs/JSGlobalObject.h: (JSC::asGlobalObject): Added. (JSC::ScopeChainNode::globalObject): Use asGlobalObject.
  • kjs/JSImmediate.h: Added noValue, asPointer, and makeValue functions. Use rawValue, makeValue, and noValue consistently instead of doing reinterpret_cast in various functions.
  • kjs/JSNumberCell.h: (JSC::asNumberCell): Added. (JSC::JSValue::uncheckedGetNumber): Use asValue and asNumberCell. (JSC::JSValue::toJSNumber): Use asValue.
  • kjs/JSObject.cpp: (JSC::JSObject::put): Use asObject and asGetterSetter. (JSC::callDefaultValueFunction): Use noValue. (JSC::JSObject::defineGetter): Use asGetterSetter. (JSC::JSObject::defineSetter): Ditto. (JSC::JSObject::lookupGetter): Ditto. Also use asObject. (JSC::JSObject::lookupSetter): Ditto. (JSC::JSObject::hasInstance): Use asObject. (JSC::JSObject::fillGetterPropertySlot): Use asGetterSetter.
  • kjs/JSObject.h: (JSC::JSObject::getDirect): Use noValue. (JSC::asObject): Added. (JSC::JSValue::isObject): Use asValue. (JSC::JSObject::get): Removed unneeded const_cast. (JSC::JSObject::getPropertySlot): Use asObject. (JSC::JSValue::get): Removed unneeded const_cast. Use asValue, asCell, and asObject. (JSC::JSValue::put): Ditto. (JSC::JSObject::allocatePropertyStorageInline): Fixed spelling of "oldPropertStorage".
  • kjs/JSString.cpp: (JSC::JSString::getOwnPropertySlot): Use asObject.
  • kjs/JSString.h: (JSC::asString): Added. (JSC::JSValue::toThisJSString): Use asValue.
  • kjs/JSValue.h: Make PreferredPrimitiveType a top level enum instead of a member of JSValue. Added an asValue function that returns this. Removed overload of asCell for const. Use asValue instead of getting right at this.
  • kjs/ObjectPrototype.cpp: (JSC::objectProtoFuncIsPrototypeOf): Use asObject. (JSC::objectProtoFuncDefineGetter): Ditto. (JSC::objectProtoFuncDefineSetter): Ditto.
  • kjs/PropertySlot.h: (JSC::PropertySlot::PropertySlot): Take a const JSValue* so the callers don't have to worry about const. (JSC::PropertySlot::clearBase): Use noValue. (JSC::PropertySlot::clearValue): Ditto.
  • kjs/RegExpConstructor.cpp: (JSC::regExpConstructorDollar1): Use asRegExpConstructor. (JSC::regExpConstructorDollar2): Ditto. (JSC::regExpConstructorDollar3): Ditto. (JSC::regExpConstructorDollar4): Ditto. (JSC::regExpConstructorDollar5): Ditto. (JSC::regExpConstructorDollar6): Ditto. (JSC::regExpConstructorDollar7): Ditto. (JSC::regExpConstructorDollar8): Ditto. (JSC::regExpConstructorDollar9): Ditto. (JSC::regExpConstructorInput): Ditto. (JSC::regExpConstructorMultiline): Ditto. (JSC::regExpConstructorLastMatch): Ditto. (JSC::regExpConstructorLastParen): Ditto. (JSC::regExpConstructorLeftContext): Ditto. (JSC::regExpConstructorRightContext): Ditto. (JSC::setRegExpConstructorInput): Ditto. (JSC::setRegExpConstructorMultiline): Ditto. (JSC::constructRegExp): Use asObject.
  • kjs/RegExpConstructor.h: (JSC::asRegExpConstructor): Added.
  • kjs/RegExpObject.cpp: (JSC::regExpObjectGlobal): Use asRegExpObject. (JSC::regExpObjectIgnoreCase): Ditto. (JSC::regExpObjectMultiline): Ditto. (JSC::regExpObjectSource): Ditto. (JSC::regExpObjectLastIndex): Ditto. (JSC::setRegExpObjectLastIndex): Ditto. (JSC::callRegExpObject): Ditto.
  • kjs/RegExpObject.h: (JSC::asRegExpObject): Added.
  • kjs/RegExpPrototype.cpp: (JSC::regExpProtoFuncTest): Use asRegExpObject. (JSC::regExpProtoFuncExec): Ditto. (JSC::regExpProtoFuncCompile): Ditto. (JSC::regExpProtoFuncToString): Ditto.
  • kjs/StringObject.h: (JSC::StringObject::internalValue): Use asString. (JSC::asStringObject): Added.
  • kjs/StringPrototype.cpp: (JSC::stringProtoFuncReplace): Use asRegExpObject. (JSC::stringProtoFuncToString): Ue asStringObject. (JSC::stringProtoFuncMatch): Use asRegExpObject. (JSC::stringProtoFuncSearch): Ditto. (JSC::stringProtoFuncSplit): Ditto.
  • kjs/StructureID.cpp: (JSC::StructureID::getEnumerablePropertyNames): Use asObject. (JSC::StructureID::createCachedPrototypeChain): Ditto. (JSC::StructureIDChain::StructureIDChain): Use asCell and asObject.
  • kjs/collector.h: (JSC::Heap::isNumber): Removed null handling. This can only be called on valid cells. (JSC::Heap::cellBlock): Removed overload for const and non-const. Whether the JSCell* is const or not really should have no effect on whether you can modify the collector block it's in.
  • kjs/interpreter.cpp: (JSC::Interpreter::evaluate): Use noValue and noObject.
  • kjs/nodes.cpp: (JSC::FunctionCallResolveNode::emitCode): Use JSObject for the global object rather than JSValue. (JSC::PostfixResolveNode::emitCode): Ditto. (JSC::PrefixResolveNode::emitCode): Ditto. (JSC::ReadModifyResolveNode::emitCode): Ditto. (JSC::AssignResolveNode::emitCode): Ditto.
  • kjs/operations.h: (JSC::equalSlowCaseInline): Use asString, asCell, asNumberCell, (JSC::strictEqualSlowCaseInline): Ditto.

WebCore:

2008-10-18 Darin Adler <Darin Adler>

Reviewed by Oliver Hunt.

Update for change to make PreferredPrimitiveType no longer
a member of JSValue.

  • bridge/c/c_instance.cpp: (JSC::Bindings::CInstance::defaultValue): Removed JSValue:: prefix.
  • bridge/jni/jni_instance.cpp: (JavaInstance::defaultValue): Ditto.
  • bridge/objc/objc_instance.mm: (ObjcInstance::defaultValue): Ditto.
  • bridge/qt/qt_instance.cpp: (JSC::Bindings::QtInstance::defaultValue): Ditto.
  • bridge/runtime.h: Ditto. Also removed typedef.
File size: 14.6 KB
Line 
1/*
2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 *
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 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#ifndef Machine_h
30#define Machine_h
31
32#include "ArgList.h"
33#include "JSCell.h"
34#include "JSValue.h"
35#include "Opcode.h"
36#include "RegisterFile.h"
37#include <wtf/HashMap.h>
38
39namespace JSC {
40
41 class CodeBlock;
42 class EvalNode;
43 class FunctionBodyNode;
44 class Instruction;
45 class InternalFunction;
46 class JITCodeBuffer;
47 class JSFunction;
48 class JSGlobalObject;
49 class ProgramNode;
50 class Register;
51 class ScopeChainNode;
52 class SamplingTool;
53
54#if ENABLE(CTI)
55
56#if USE(CTI_ARGUMENT)
57#define CTI_ARGS void** args
58#define ARGS (args)
59#else
60#define CTI_ARGS void* args, ...
61#define ARGS (&args)
62#endif
63
64#if USE(FAST_CALL_CTI_ARGUMENT)
65
66#if COMPILER(MSVC)
67#define SFX_CALL __fastcall
68#elif COMPILER(GCC)
69#define SFX_CALL __attribute__ ((fastcall))
70#else
71#error Need to support fastcall calling convention in this compiler
72#endif
73
74#else
75
76#if COMPILER(MSVC)
77#define SFX_CALL __cdecl
78#else
79#define SFX_CALL
80#endif
81
82#endif
83
84 struct VoidPtrPair { void* first; void* second; };
85#endif
86
87 enum DebugHookID {
88 WillExecuteProgram,
89 DidExecuteProgram,
90 DidEnterCallFrame,
91 DidReachBreakpoint,
92 WillLeaveCallFrame,
93 WillExecuteStatement
94 };
95
96 enum { MaxReentryDepth = 128 };
97
98 class Machine {
99 friend class CTI;
100 public:
101 Machine();
102 ~Machine();
103
104 RegisterFile& registerFile() { return m_registerFile; }
105
106 Opcode getOpcode(OpcodeID id)
107 {
108 #if HAVE(COMPUTED_GOTO)
109 return m_opcodeTable[id];
110 #else
111 return id;
112 #endif
113 }
114
115 OpcodeID getOpcodeID(Opcode opcode)
116 {
117 #if HAVE(COMPUTED_GOTO)
118 ASSERT(isOpcode(opcode));
119 return m_opcodeIDTable.get(opcode);
120 #else
121 return opcode;
122 #endif
123 }
124
125 bool isOpcode(Opcode opcode);
126
127 JSValue* execute(ProgramNode*, CallFrame*, ScopeChainNode*, JSObject* thisObj, JSValue** exception);
128 JSValue* execute(FunctionBodyNode*, CallFrame*, JSFunction*, JSObject* thisObj, const ArgList& args, ScopeChainNode*, JSValue** exception);
129 JSValue* execute(EvalNode* evalNode, CallFrame* exec, JSObject* thisObj, ScopeChainNode* scopeChain, JSValue** exception);
130
131 JSValue* retrieveArguments(CallFrame*, JSFunction*) const;
132 JSValue* retrieveCaller(CallFrame*, InternalFunction*) const;
133 void retrieveLastCaller(CallFrame*, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValue*& function) const;
134
135 void getArgumentsData(CallFrame*, JSFunction*&, ptrdiff_t& firstParameterIndex, Register*& argv, int& argc);
136 void setTimeoutTime(unsigned timeoutTime) { m_timeoutTime = timeoutTime; }
137
138 void startTimeoutCheck()
139 {
140 if (!m_timeoutCheckCount)
141 resetTimeoutCheck();
142
143 ++m_timeoutCheckCount;
144 }
145
146 void stopTimeoutCheck()
147 {
148 ASSERT(m_timeoutCheckCount);
149 --m_timeoutCheckCount;
150 }
151
152 inline void initTimeout()
153 {
154 ASSERT(!m_timeoutCheckCount);
155 resetTimeoutCheck();
156 m_timeoutTime = 0;
157 m_timeoutCheckCount = 0;
158 }
159
160 SamplingTool* m_sampler;
161
162#if ENABLE(CTI)
163
164 static void SFX_CALL cti_timeout_check(CTI_ARGS);
165 static void SFX_CALL cti_register_file_check(CTI_ARGS);
166
167 static JSValue* SFX_CALL cti_op_convert_this(CTI_ARGS);
168 static void SFX_CALL cti_op_end(CTI_ARGS);
169 static JSValue* SFX_CALL cti_op_add(CTI_ARGS);
170 static JSValue* SFX_CALL cti_op_pre_inc(CTI_ARGS);
171 static int SFX_CALL cti_op_loop_if_less(CTI_ARGS);
172 static int SFX_CALL cti_op_loop_if_lesseq(CTI_ARGS);
173 static JSValue* SFX_CALL cti_op_new_object(CTI_ARGS);
174 static void SFX_CALL cti_op_put_by_id(CTI_ARGS);
175 static void SFX_CALL cti_op_put_by_id_second(CTI_ARGS);
176 static void SFX_CALL cti_op_put_by_id_generic(CTI_ARGS);
177 static void SFX_CALL cti_op_put_by_id_fail(CTI_ARGS);
178 static JSValue* SFX_CALL cti_op_get_by_id(CTI_ARGS);
179 static JSValue* SFX_CALL cti_op_get_by_id_second(CTI_ARGS);
180 static JSValue* SFX_CALL cti_op_get_by_id_generic(CTI_ARGS);
181 static JSValue* SFX_CALL cti_op_get_by_id_fail(CTI_ARGS);
182 static JSValue* SFX_CALL cti_op_del_by_id(CTI_ARGS);
183 static JSValue* SFX_CALL cti_op_instanceof(CTI_ARGS);
184 static JSValue* SFX_CALL cti_op_mul(CTI_ARGS);
185 static JSValue* SFX_CALL cti_op_new_func(CTI_ARGS);
186 static VoidPtrPair SFX_CALL cti_op_call_JSFunction(CTI_ARGS);
187 static JSValue* SFX_CALL cti_op_call_NotJSFunction(CTI_ARGS);
188 static void SFX_CALL cti_op_create_arguments(CTI_ARGS);
189 static void SFX_CALL cti_op_create_arguments_no_params(CTI_ARGS);
190 static void SFX_CALL cti_op_tear_off_activation(CTI_ARGS);
191 static void SFX_CALL cti_op_tear_off_arguments(CTI_ARGS);
192 static void SFX_CALL cti_op_ret_scopeChain(CTI_ARGS);
193 static JSValue* SFX_CALL cti_op_new_array(CTI_ARGS);
194 static JSValue* SFX_CALL cti_op_resolve(CTI_ARGS);
195 static JSValue* SFX_CALL cti_op_resolve_global(CTI_ARGS);
196 static JSValue* SFX_CALL cti_op_construct_JSConstructFast(CTI_ARGS);
197 static VoidPtrPair SFX_CALL cti_op_construct_JSConstruct(CTI_ARGS);
198 static JSValue* SFX_CALL cti_op_construct_NotJSConstruct(CTI_ARGS);
199 static JSValue* SFX_CALL cti_op_get_by_val(CTI_ARGS);
200 static VoidPtrPair SFX_CALL cti_op_resolve_func(CTI_ARGS);
201 static JSValue* SFX_CALL cti_op_sub(CTI_ARGS);
202 static void SFX_CALL cti_op_put_by_val(CTI_ARGS);
203 static void SFX_CALL cti_op_put_by_val_array(CTI_ARGS);
204 static JSValue* SFX_CALL cti_op_lesseq(CTI_ARGS);
205 static int SFX_CALL cti_op_loop_if_true(CTI_ARGS);
206 static JSValue* SFX_CALL cti_op_resolve_base(CTI_ARGS);
207 static JSValue* SFX_CALL cti_op_negate(CTI_ARGS);
208 static JSValue* SFX_CALL cti_op_resolve_skip(CTI_ARGS);
209 static JSValue* SFX_CALL cti_op_div(CTI_ARGS);
210 static JSValue* SFX_CALL cti_op_pre_dec(CTI_ARGS);
211 static int SFX_CALL cti_op_jless(CTI_ARGS);
212 static JSValue* SFX_CALL cti_op_not(CTI_ARGS);
213 static int SFX_CALL cti_op_jtrue(CTI_ARGS);
214 static VoidPtrPair SFX_CALL cti_op_post_inc(CTI_ARGS);
215 static JSValue* SFX_CALL cti_op_eq(CTI_ARGS);
216 static JSValue* SFX_CALL cti_op_lshift(CTI_ARGS);
217 static JSValue* SFX_CALL cti_op_bitand(CTI_ARGS);
218 static JSValue* SFX_CALL cti_op_rshift(CTI_ARGS);
219 static JSValue* SFX_CALL cti_op_bitnot(CTI_ARGS);
220 static VoidPtrPair SFX_CALL cti_op_resolve_with_base(CTI_ARGS);
221 static JSValue* SFX_CALL cti_op_new_func_exp(CTI_ARGS);
222 static JSValue* SFX_CALL cti_op_mod(CTI_ARGS);
223 static JSValue* SFX_CALL cti_op_less(CTI_ARGS);
224 static JSValue* SFX_CALL cti_op_neq(CTI_ARGS);
225 static VoidPtrPair SFX_CALL cti_op_post_dec(CTI_ARGS);
226 static JSValue* SFX_CALL cti_op_urshift(CTI_ARGS);
227 static JSValue* SFX_CALL cti_op_bitxor(CTI_ARGS);
228 static JSValue* SFX_CALL cti_op_new_regexp(CTI_ARGS);
229 static JSValue* SFX_CALL cti_op_bitor(CTI_ARGS);
230 static JSValue* SFX_CALL cti_op_call_eval(CTI_ARGS);
231 static JSValue* SFX_CALL cti_op_throw(CTI_ARGS);
232 static JSPropertyNameIterator* SFX_CALL cti_op_get_pnames(CTI_ARGS);
233 static JSValue* SFX_CALL cti_op_next_pname(CTI_ARGS);
234 static void SFX_CALL cti_op_push_scope(CTI_ARGS);
235 static void SFX_CALL cti_op_pop_scope(CTI_ARGS);
236 static JSValue* SFX_CALL cti_op_typeof(CTI_ARGS);
237 static JSValue* SFX_CALL cti_op_is_undefined(CTI_ARGS);
238 static JSValue* SFX_CALL cti_op_is_boolean(CTI_ARGS);
239 static JSValue* SFX_CALL cti_op_is_number(CTI_ARGS);
240 static JSValue* SFX_CALL cti_op_is_string(CTI_ARGS);
241 static JSValue* SFX_CALL cti_op_is_object(CTI_ARGS);
242 static JSValue* SFX_CALL cti_op_is_function(CTI_ARGS);
243 static JSValue* SFX_CALL cti_op_stricteq(CTI_ARGS);
244 static JSValue* SFX_CALL cti_op_nstricteq(CTI_ARGS);
245 static JSValue* SFX_CALL cti_op_to_jsnumber(CTI_ARGS);
246 static JSValue* SFX_CALL cti_op_in(CTI_ARGS);
247 static JSValue* SFX_CALL cti_op_push_new_scope(CTI_ARGS);
248 static void SFX_CALL cti_op_jmp_scopes(CTI_ARGS);
249 static void SFX_CALL cti_op_put_by_index(CTI_ARGS);
250 static void* SFX_CALL cti_op_switch_imm(CTI_ARGS);
251 static void* SFX_CALL cti_op_switch_char(CTI_ARGS);
252 static void* SFX_CALL cti_op_switch_string(CTI_ARGS);
253 static JSValue* SFX_CALL cti_op_del_by_val(CTI_ARGS);
254 static void SFX_CALL cti_op_put_getter(CTI_ARGS);
255 static void SFX_CALL cti_op_put_setter(CTI_ARGS);
256 static JSValue* SFX_CALL cti_op_new_error(CTI_ARGS);
257 static void SFX_CALL cti_op_debug(CTI_ARGS);
258
259 static void SFX_CALL cti_op_call_profiler(CTI_ARGS);
260 static void SFX_CALL cti_op_ret_profiler(CTI_ARGS);
261
262 static JSValue* SFX_CALL cti_vm_throw(CTI_ARGS);
263 static void* SFX_CALL cti_vm_compile(CTI_ARGS);
264 static void* SFX_CALL cti_vm_lazyLinkCall(CTI_ARGS);
265 static JSValue* SFX_CALL cti_op_push_activation(CTI_ARGS);
266
267#endif // ENABLE(CTI)
268
269 // Default number of ticks before a timeout check should be done.
270 static const int initialTickCountThreshold = 1024;
271
272 bool isJSArray(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsArrayVptr; }
273 bool isJSString(JSValue* v) { return !JSImmediate::isImmediate(v) && v->asCell()->vptr() == m_jsStringVptr; }
274
275 private:
276 enum ExecutionFlag { Normal, InitializeAndReturn };
277
278 NEVER_INLINE JSValue* callEval(CallFrame*, JSObject* thisObject, ScopeChainNode*, RegisterFile*, int argv, int argc, JSValue*& exceptionValue);
279 JSValue* execute(EvalNode*, CallFrame*, JSObject* thisObject, int registerOffset, ScopeChainNode*, JSValue** exception);
280
281 NEVER_INLINE void debug(CallFrame*, DebugHookID, int firstLine, int lastLine);
282
283 NEVER_INLINE bool resolve(CallFrame*, Instruction*, JSValue*& exceptionValue);
284 NEVER_INLINE bool resolveSkip(CallFrame*, Instruction*, JSValue*& exceptionValue);
285 NEVER_INLINE bool resolveGlobal(CallFrame*, Instruction*, JSValue*& exceptionValue);
286 NEVER_INLINE void resolveBase(CallFrame*, Instruction* vPC);
287 NEVER_INLINE bool resolveBaseAndProperty(CallFrame*, Instruction*, JSValue*& exceptionValue);
288 NEVER_INLINE ScopeChainNode* createExceptionScope(CallFrame*, const Instruction* vPC);
289
290 NEVER_INLINE bool unwindCallFrame(CallFrame*&, JSValue*, const Instruction*&, CodeBlock*&);
291 NEVER_INLINE Instruction* throwException(CallFrame*&, JSValue*&, const Instruction*, bool);
292 NEVER_INLINE bool resolveBaseAndFunc(CallFrame*, Instruction*, JSValue*& exceptionValue);
293
294 static ALWAYS_INLINE CallFrame* slideRegisterWindowForCall(CodeBlock*, RegisterFile*, CallFrame*, size_t registerOffset, int argc);
295
296 static CallFrame* findFunctionCallFrame(CallFrame*, InternalFunction*);
297
298 JSValue* privateExecute(ExecutionFlag, RegisterFile*, CallFrame*, JSValue** exception);
299
300 void dumpCallFrame(const RegisterFile*, CallFrame*);
301 void dumpRegisters(const RegisterFile*, CallFrame*);
302
303 JSValue* checkTimeout(JSGlobalObject*);
304 void resetTimeoutCheck();
305
306 void tryCacheGetByID(CallFrame*, CodeBlock*, Instruction*, JSValue* baseValue, const Identifier& propertyName, const PropertySlot&);
307 void uncacheGetByID(CodeBlock*, Instruction* vPC);
308 void tryCachePutByID(CallFrame*, CodeBlock*, Instruction*, JSValue* baseValue, const PutPropertySlot&);
309 void uncachePutByID(CodeBlock*, Instruction* vPC);
310
311#if ENABLE(CTI)
312 static void throwStackOverflowPreviousFrame(CallFrame*, JSGlobalData*, void*& returnAddress);
313
314 void tryCTICacheGetByID(CallFrame*, CodeBlock*, void* returnAddress, JSValue* baseValue, const Identifier& propertyName, const PropertySlot&);
315 void tryCTICachePutByID(CallFrame*, CodeBlock*, void* returnAddress, JSValue* baseValue, const PutPropertySlot&);
316
317 void* getCTIArrayLengthTrampoline(CallFrame*, CodeBlock*);
318 void* getCTIStringLengthTrampoline(CallFrame*, CodeBlock*);
319
320 void* m_ctiArrayLengthTrampoline;
321 void* m_ctiStringLengthTrampoline;
322
323 OwnPtr<JITCodeBuffer> m_jitCodeBuffer;
324 JITCodeBuffer* jitCodeBuffer() const { return m_jitCodeBuffer.get(); }
325#endif
326
327 int m_reentryDepth;
328 unsigned m_timeoutTime;
329 unsigned m_timeAtLastCheckTimeout;
330 unsigned m_timeExecuting;
331 unsigned m_timeoutCheckCount;
332 unsigned m_ticksUntilNextTimeoutCheck;
333
334 RegisterFile m_registerFile;
335
336 void* m_jsArrayVptr;
337 void* m_jsStringVptr;
338 void* m_jsFunctionVptr;
339
340#if HAVE(COMPUTED_GOTO)
341 Opcode m_opcodeTable[numOpcodeIDs]; // Maps OpcodeID => Opcode for compiling
342 HashMap<Opcode, OpcodeID> m_opcodeIDTable; // Maps Opcode => OpcodeID for decompiling
343#endif
344 };
345
346} // namespace JSC
347
348#endif // Machine_h
Note: See TracBrowser for help on using the repository browser.