Changeset 34338 in webkit for trunk/JavaScriptCore/VM/Machine.cpp
- Timestamp:
- Jun 3, 2008, 1:44:55 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/VM/Machine.cpp
r34335 r34338 1941 1941 } 1942 1942 BEGIN_OPCODE(op_call_eval) { 1943 /* call_eval dst(r) func(r) thisVal(r) firstArg(r) argCount(n) 1944 1945 Call a function named "eval" with no explicit "this" value 1946 (which may therefore be the eval operator). If register 1947 thisVal is the global object, and register func contains 1948 that global object's original global eval function, then 1949 perform the eval operator in local scope (interpreting 1950 the argument registers as for the "call" 1951 opcode). Otherwise, act exacty as the "call" opcode. 1952 */ 1953 1943 1954 int dst = (++vPC)->u.operand; 1944 1955 int func = (++vPC)->u.operand; 1945 int base= (++vPC)->u.operand;1946 int argv= (++vPC)->u.operand;1947 int arg c= (++vPC)->u.operand;1956 int thisVal = (++vPC)->u.operand; 1957 int firstArg = (++vPC)->u.operand; 1958 int argCount = (++vPC)->u.operand; 1948 1959 1949 1960 JSValue* funcVal = r[func].u.jsValue; 1950 JSValue* baseVal = r[ base].u.jsValue;1961 JSValue* baseVal = r[thisVal].u.jsValue; 1951 1962 1952 1963 if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) { … … 1957 1968 registerFile->setSafeForReentry(true); 1958 1969 1959 JSValue* result = callEval(exec, thisObject, scopeChain, registerFile, r, argv, argc, exceptionValue);1970 JSValue* result = callEval(exec, thisObject, scopeChain, registerFile, r, firstArg, argCount, exceptionValue); 1960 1971 1961 1972 registerFile->setSafeForReentry(false); … … 1975 1986 // value. 1976 1987 vPC -= 5; 1977 r[ base].u.jsValue = baseVal->toObject(exec)->toThisObject(exec);1988 r[thisVal].u.jsValue = baseVal->toObject(exec)->toThisObject(exec); 1978 1989 1979 1990 #if HAVE(COMPUTED_GOTO) … … 1986 1997 } 1987 1998 BEGIN_OPCODE(op_call) { 1999 /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) 2000 2001 Perform a function call. Specifically, call register func 2002 with a "this" value of register thisVal, and put the result 2003 in register dst. 2004 2005 The arguments start at register firstArg and go up to 2006 argCount, but the "this" value is considered an implicit 2007 first argument, so the argCount should be one greater than 2008 the number of explicit arguments passed, and the register 2009 after firstArg should contain the actual first 2010 argument. This opcode will copy from the thisVal register 2011 to the firstArg register, unless the register index of 2012 thisVal is the special missing this object marker, which is 2013 2^31-1; in that case, the global object will be used as the 2014 "this" value. 2015 2016 If func is a native code function, then this opcode calls 2017 it and returns the value immediately. 2018 2019 But if it is a JS function, then the current scope chain 2020 and code block is set to the function's, and we slide the 2021 register window so that the arguments would form the first 2022 few local registers of the called function's register 2023 window. In addition, a call frame header is written 2024 immediately before the arguments; see the call frame 2025 documentation for an explanation of how many registers a 2026 call frame takes and what they contain. That many registers 2027 before the firstArg register will be overwritten by the 2028 call. In addition, any registers higher than firstArg + 2029 argCount may be overwritten. Once this setup is complete, 2030 execution continues from the called function's first 2031 argument, and does not return until a "ret" opcode is 2032 encountered. 2033 */ 2034 1988 2035 int dst = (++vPC)->u.operand; 1989 2036 int func = (++vPC)->u.operand; 1990 int base= (++vPC)->u.operand;1991 int argv= (++vPC)->u.operand;1992 int arg c= (++vPC)->u.operand;2037 int thisVal = (++vPC)->u.operand; 2038 int firstArg = (++vPC)->u.operand; 2039 int argCount = (++vPC)->u.operand; 1993 2040 1994 2041 JSValue* v = r[func].u.jsValue; … … 2001 2048 (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v)); 2002 2049 int registerOffset = r - (*registerBase); 2003 Register* callFrame = r + argv- CallFrameHeaderSize;2004 int callFrameOffset = registerOffset + argv- CallFrameHeaderSize;2005 2006 r[ argv].u.jsValue = base == missingThisObjectMarker() ? exec->globalThisValue() : r[base].u.jsValue; // "this" value2007 initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, dst, argv, argc, 0, v);2050 Register* callFrame = r + firstArg - CallFrameHeaderSize; 2051 int callFrameOffset = registerOffset + firstArg - CallFrameHeaderSize; 2052 2053 r[firstArg].u.jsValue = thisVal == missingThisObjectMarker() ? exec->globalThisValue() : r[thisVal].u.jsValue; 2054 initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, dst, firstArg, argCount, 0, v); 2008 2055 2009 2056 ScopeChainNode* callDataScopeChain = callData.js.scopeChain; … … 2011 2058 2012 2059 CodeBlock* newCodeBlock = &functionBodyNode->code(callDataScopeChain); 2013 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, argv, argc, exceptionValue);2060 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, firstArg, argCount, exceptionValue); 2014 2061 if (UNLIKELY(exceptionValue != 0)) 2015 2062 goto vm_throw; … … 2029 2076 int registerOffset = r - (*registerBase); 2030 2077 2031 r[ argv].u.jsValue = base == missingThisObjectMarker() ? exec->globalThisValue() : (r[base].u.jsValue)->toObject(exec); // "this" value2032 JSObject* thisObj = static_cast<JSObject*>(r[ argv].u.jsValue);2033 2034 List args(reinterpret_cast<JSValue***>(registerBase), registerOffset + argv + 1, argc- 1);2078 r[firstArg].u.jsValue = thisVal == missingThisObjectMarker() ? exec->globalThisValue() : (r[thisVal].u.jsValue)->toObject(exec); 2079 JSObject* thisObj = static_cast<JSObject*>(r[firstArg].u.jsValue); 2080 2081 List args(reinterpret_cast<JSValue***>(registerBase), registerOffset + firstArg + 1, argCount - 1); 2035 2082 2036 2083 registerFile->setSafeForReentry(true); … … 2055 2102 } 2056 2103 BEGIN_OPCODE(op_ret) { 2057 int r1 = (++vPC)->u.operand; 2104 /* ret result(r) 2105 2106 Return register result as the return value of the current 2107 function call, writing it into the caller's expected return 2108 value register. In addition, unwind one call frame and 2109 restore the scope chain, code block instruction pointer and 2110 register base to those of the calling function. 2111 */ 2112 2113 int result = (++vPC)->u.operand; 2058 2114 2059 2115 CodeBlock* oldCodeBlock = codeBlock; 2060 2116 2061 2117 Register* callFrame = r - oldCodeBlock->numLocals - CallFrameHeaderSize; 2062 JSValue* returnValue = r[r 1].u.jsValue;2118 JSValue* returnValue = r[result].u.jsValue; 2063 2119 2064 2120 if (JSActivation* activation = static_cast<JSActivation*>(callFrame[OptionalCalleeActivation].u.jsValue)) { … … 2089 2145 r = (*registerBase) + callerRegisterOffset; 2090 2146 exec->m_callFrameOffset = callerRegisterOffset - codeBlock->numLocals - CallFrameHeaderSize; 2091 int r0= callFrame[ReturnValueRegister].u.i;2092 r[ r0].u.jsValue = returnValue;2147 int dst = callFrame[ReturnValueRegister].u.i; 2148 r[dst].u.jsValue = returnValue; 2093 2149 2094 2150 NEXT_OPCODE; 2095 2151 } 2096 2152 BEGIN_OPCODE(op_construct) { 2097 int dst = (++vPC)->u.operand; 2098 int func = (++vPC)->u.operand; 2099 int argv = (++vPC)->u.operand; 2100 int argc = (++vPC)->u.operand; 2101 2102 JSValue* funcVal = r[func].u.jsValue; 2153 /* construct dst(r) constr(r) firstArg(r) argCount(n) 2154 2155 Invoke register "constr" as a constructor. For JS 2156 functions, the calling convention is exactly as for the 2157 "call" opcode, except that the "this" value is a newly 2158 created Object. For native constructors, a null "this" 2159 value is passed. In either case, the firstArg and argCount 2160 registers are interpreted as for the "call" opcode. 2161 */ 2162 2163 int dst = (++vPC)->u.operand; 2164 int constr = (++vPC)->u.operand; 2165 int firstArg = (++vPC)->u.operand; 2166 int argCount = (++vPC)->u.operand; 2167 2168 JSValue* constrVal = r[constr].u.jsValue; 2103 2169 2104 2170 ConstructData constructData; 2105 ConstructType constructType = funcVal->getConstructData(constructData);2171 ConstructType constructType = constrVal->getConstructData(constructData); 2106 2172 2107 2173 // Removing this line of code causes a measurable regression on squirrelfish. 2108 JSObject* constructor = static_cast<JSObject*>( funcVal);2174 JSObject* constructor = static_cast<JSObject*>(constrVal); 2109 2175 2110 2176 if (constructType == ConstructTypeJS) { … … 2113 2179 2114 2180 int registerOffset = r - (*registerBase); 2115 Register* callFrame = r + argv- CallFrameHeaderSize;2116 int callFrameOffset = registerOffset + argv- CallFrameHeaderSize;2181 Register* callFrame = r + firstArg - CallFrameHeaderSize; 2182 int callFrameOffset = registerOffset + firstArg - CallFrameHeaderSize; 2117 2183 2118 2184 JSObject* prototype; … … 2123 2189 prototype = scopeChain->globalObject()->objectPrototype(); 2124 2190 JSObject* newObject = new JSObject(prototype); 2125 r[ argv].u.jsValue = newObject; // "this" value2126 2127 initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, dst, argv, argc, 1, constructor);2191 r[firstArg].u.jsValue = newObject; // "this" value 2192 2193 initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, dst, firstArg, argCount, 1, constructor); 2128 2194 2129 2195 ScopeChainNode* callDataScopeChain = constructData.js.scopeChain; … … 2131 2197 2132 2198 CodeBlock* newCodeBlock = &functionBodyNode->code(callDataScopeChain); 2133 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, argv, argc, exceptionValue);2199 r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, firstArg, argCount, exceptionValue); 2134 2200 if (exceptionValue) 2135 2201 goto vm_throw; … … 2150 2216 int registerOffset = r - (*registerBase); 2151 2217 2152 List args(reinterpret_cast<JSValue***>(registerBase), registerOffset + argv + 1, argc- 1);2218 List args(reinterpret_cast<JSValue***>(registerBase), registerOffset + firstArg + 1, argCount - 1); 2153 2219 2154 2220 registerFile->setSafeForReentry(true); … … 2169 2235 ASSERT(constructType == ConstructTypeNone); 2170 2236 2171 exceptionValue = createNotAConstructorError(exec, funcVal, 0);2237 exceptionValue = createNotAConstructorError(exec, constrVal, 0); 2172 2238 goto vm_throw; 2173 2239 } … … 2320 2386 } 2321 2387 BEGIN_OPCODE(op_end) { 2388 /* end result(r) 2389 2390 Return register result as the value of a global or eval 2391 program. Return control to the calling native code. 2392 */ 2393 2322 2394 if (codeBlock->needsFullScopeChain) { 2323 2395 ASSERT(scopeChain->refCount > 1); 2324 2396 scopeChain->deref(); 2325 2397 } 2326 int r 0= (++vPC)->u.operand;2327 return r[r 0].u.jsValue;2398 int result = (++vPC)->u.operand; 2399 return r[result].u.jsValue; 2328 2400 } 2329 2401 BEGIN_OPCODE(op_put_getter) {
Note:
See TracChangeset
for help on using the changeset viewer.