Changeset 34338 in webkit for trunk/JavaScriptCore/VM/Machine.cpp


Ignore:
Timestamp:
Jun 3, 2008, 1:44:55 AM (17 years ago)
Author:
[email protected]
Message:

2008-06-03 Maciej Stachowiak <[email protected]>

Reviewed by Oliver.


  • document remaining opcodes.
  • VM/Machine.cpp: (KJS::Machine::privateExecute): Document call, call_eval, construct, ret and end opcodes.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/VM/Machine.cpp

    r34335 r34338  
    19411941    }
    19421942    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
    19431954        int dst = (++vPC)->u.operand;
    19441955        int func = (++vPC)->u.operand;
    1945         int base = (++vPC)->u.operand;
    1946         int argv = (++vPC)->u.operand;
    1947         int argc = (++vPC)->u.operand;
     1956        int thisVal = (++vPC)->u.operand;
     1957        int firstArg = (++vPC)->u.operand;
     1958        int argCount = (++vPC)->u.operand;
    19481959
    19491960        JSValue* funcVal = r[func].u.jsValue;
    1950         JSValue* baseVal = r[base].u.jsValue;
     1961        JSValue* baseVal = r[thisVal].u.jsValue;
    19511962       
    19521963        if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
     
    19571968            registerFile->setSafeForReentry(true);
    19581969
    1959             JSValue* result = callEval(exec, thisObject, scopeChain, registerFile, r, argv, argc, exceptionValue);
     1970            JSValue* result = callEval(exec, thisObject, scopeChain, registerFile, r, firstArg, argCount, exceptionValue);
    19601971
    19611972            registerFile->setSafeForReentry(false);
     
    19751986        // value.
    19761987        vPC -= 5;
    1977         r[base].u.jsValue = baseVal->toObject(exec)->toThisObject(exec);
     1988        r[thisVal].u.jsValue = baseVal->toObject(exec)->toThisObject(exec);
    19781989
    19791990#if HAVE(COMPUTED_GOTO)
     
    19861997    }
    19871998    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
    19882035        int dst = (++vPC)->u.operand;
    19892036        int func = (++vPC)->u.operand;
    1990         int base = (++vPC)->u.operand;
    1991         int argv = (++vPC)->u.operand;
    1992         int argc = (++vPC)->u.operand;
     2037        int thisVal = (++vPC)->u.operand;
     2038        int firstArg = (++vPC)->u.operand;
     2039        int argCount = (++vPC)->u.operand;
    19932040       
    19942041        JSValue* v = r[func].u.jsValue;
     
    20012048                (*enabledProfilerReference)->willExecute(exec, static_cast<JSObject*>(v));
    20022049            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" value
    2007             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);
    20082055
    20092056            ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
     
    20112058
    20122059            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);
    20142061            if (UNLIKELY(exceptionValue != 0))
    20152062                goto vm_throw;
     
    20292076            int registerOffset = r - (*registerBase);
    20302077
    2031             r[argv].u.jsValue = base == missingThisObjectMarker() ? exec->globalThisValue() : (r[base].u.jsValue)->toObject(exec); // "this" value
    2032             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);
    20352082
    20362083            registerFile->setSafeForReentry(true);
     
    20552102    }
    20562103    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;
    20582114
    20592115        CodeBlock* oldCodeBlock = codeBlock;
    20602116
    20612117        Register* callFrame = r - oldCodeBlock->numLocals - CallFrameHeaderSize;
    2062         JSValue* returnValue = r[r1].u.jsValue;
     2118        JSValue* returnValue = r[result].u.jsValue;
    20632119
    20642120        if (JSActivation* activation = static_cast<JSActivation*>(callFrame[OptionalCalleeActivation].u.jsValue)) {
     
    20892145        r = (*registerBase) + callerRegisterOffset;
    20902146        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;
    20932149
    20942150        NEXT_OPCODE;
    20952151    }
    20962152    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;
    21032169
    21042170        ConstructData constructData;
    2105         ConstructType constructType = funcVal->getConstructData(constructData);
     2171        ConstructType constructType = constrVal->getConstructData(constructData);
    21062172
    21072173        // 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);
    21092175
    21102176        if (constructType == ConstructTypeJS) {
     
    21132179
    21142180            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;
    21172183
    21182184            JSObject* prototype;
     
    21232189                prototype = scopeChain->globalObject()->objectPrototype();
    21242190            JSObject* newObject = new JSObject(prototype);
    2125             r[argv].u.jsValue = newObject; // "this" value
    2126 
    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);
    21282194
    21292195            ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
     
    21312197
    21322198            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);
    21342200            if (exceptionValue)
    21352201                goto vm_throw;
     
    21502216            int registerOffset = r - (*registerBase);
    21512217
    2152             List args(reinterpret_cast<JSValue***>(registerBase), registerOffset + argv + 1, argc - 1);
     2218            List args(reinterpret_cast<JSValue***>(registerBase), registerOffset + firstArg + 1, argCount - 1);
    21532219
    21542220            registerFile->setSafeForReentry(true);
     
    21692235        ASSERT(constructType == ConstructTypeNone);
    21702236
    2171         exceptionValue = createNotAConstructorError(exec, funcVal, 0);
     2237        exceptionValue = createNotAConstructorError(exec, constrVal, 0);
    21722238        goto vm_throw;
    21732239    }
     
    23202386    }
    23212387    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
    23222394        if (codeBlock->needsFullScopeChain) {
    23232395            ASSERT(scopeChain->refCount > 1);
    23242396            scopeChain->deref();
    23252397        }
    2326         int r0 = (++vPC)->u.operand;
    2327         return r[r0].u.jsValue;
     2398        int result = (++vPC)->u.operand;
     2399        return r[result].u.jsValue;
    23282400    }
    23292401    BEGIN_OPCODE(op_put_getter) {
Note: See TracChangeset for help on using the changeset viewer.