2008-05-21 Maciej Stachowiak <mjs@apple.com>
[WebKit-https.git] / JavaScriptCore / VM / Machine.cpp
1 /*
2  * Copyright (C) 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2008 Cameron Zwarich <cwzwarich@uwaterloo.ca>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1.  Redistributions of source code must retain the above copyright
10  *     notice, this list of conditions and the following disclaimer.
11  * 2.  Redistributions in binary form must reproduce the above copyright
12  *     notice, this list of conditions and the following disclaimer in the
13  *     documentation and/or other materials provided with the distribution.
14  * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15  *     its contributors may be used to endorse or promote products derived
16  *     from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include "config.h"
31 #include "Machine.h"
32
33 #include "CodeBlock.h"
34 #include "DebuggerCallFrame.h"
35 #include "ExceptionHelpers.h"
36 #include "ExecState.h"
37 #include "JSActivation.h"
38 #include "JSLock.h"
39 #include "JSPropertyNameIterator.h"
40 #include "Parser.h"
41 #include "Register.h"
42 #include "array_object.h"
43 #include "debugger.h"
44 #include "function.h"
45 #include "internal.h"
46 #include "object_object.h"
47 #include "operations.h"
48 #include "operations.h"
49 #include "regexp_object.h"
50
51 #if COMPILER(GCC)
52 #define UNLIKELY(x) \
53   __builtin_expect ((x), 0)
54 #else
55 #define UNLIKELY(x) x
56 #endif
57
58 namespace KJS {
59
60 #if HAVE(COMPUTED_GOTO)
61 static void* op_throw_end_indirect;
62 static void* op_call_indirect;
63 #endif
64
65 // Retrieves the offset of a calling function within the current register file.
66 bool getCallerFunctionOffset(Register** registerBase, int callOffset, int& callerOffset)
67 {
68     Register* callFrame = (*registerBase) + callOffset;
69
70     CodeBlock* callerCodeBlock = callFrame[Machine::CallerCodeBlock].u.codeBlock;
71     if (!callerCodeBlock) // test for top frame of re-entrant function call
72         return false;
73
74     callerOffset = callFrame[Machine::CallerRegisterOffset].u.i - callerCodeBlock->numLocals - Machine::CallFrameHeaderSize;
75     if (callerOffset < 0) // test for global frame
76         return false;
77
78     Register* callerCallFrame = (*registerBase) + callerOffset;
79     if (!callerCallFrame[Machine::CallerCodeBlock].u.codeBlock) // test for eval frame
80         return false;
81
82     return true;
83 }
84
85 // Returns the depth of the scope chain within a given call frame.
86 static int depth(ScopeChain& sc)
87 {
88     int scopeDepth = 0;
89     ScopeChainIterator iter = sc.begin(); 
90     ScopeChainIterator end = sc.end(); 
91     while (!(*iter)->isVariableObject()) {
92         ++iter;
93         ++scopeDepth;
94     }
95     return scopeDepth;
96 }
97     
98 static inline bool jsLess(ExecState* exec, JSValue* v1, JSValue* v2)
99 {
100     double n1;
101     double n2;
102     JSValue* p1;
103     JSValue* p2;
104     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
105     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
106
107     if (wasNotString1 | wasNotString2)
108         return n1 < n2;
109
110     return static_cast<const StringImp*>(p1)->value() < static_cast<const StringImp*>(p2)->value();
111 }
112
113 static inline bool jsLessEq(ExecState* exec, JSValue* v1, JSValue* v2)
114 {
115     double n1;
116     double n2;
117     JSValue* p1;
118     JSValue* p2;
119     bool wasNotString1 = v1->getPrimitiveNumber(exec, n1, p1);
120     bool wasNotString2 = v2->getPrimitiveNumber(exec, n2, p2);
121
122     if (wasNotString1 | wasNotString2)
123         return n1 <= n2;
124
125     return !(static_cast<const StringImp*>(p2)->value() < static_cast<const StringImp*>(p1)->value());
126 }
127
128 static JSValue* jsAddSlowCase(ExecState* exec, JSValue* v1, JSValue* v2)
129 {
130     // exception for the Date exception in defaultValue()
131     JSValue* p1 = v1->toPrimitive(exec, UnspecifiedType);
132     JSValue* p2 = v2->toPrimitive(exec, UnspecifiedType);
133
134     if (p1->isString() || p2->isString()) {
135         UString value = p1->toString(exec) + p2->toString(exec);
136         if (value.isNull())
137             return throwOutOfMemoryError(exec);
138         return jsString(value);
139     }
140
141     return jsNumber(p1->toNumber(exec) + p2->toNumber(exec));
142 }
143
144 // Fast-path choices here are based on frequency data from SunSpider:
145 //    <times> Add case: <t1> <t2>
146 //    ---------------------------
147 //    5627160 Add case: 1 1
148 //    247427  Add case: 5 5
149 //    20901   Add case: 5 6
150 //    13978   Add case: 5 1
151 //    4000    Add case: 1 5
152 //    1       Add case: 3 5
153
154 static inline JSValue* jsAdd(ExecState* exec, JSValue* v1, JSValue* v2)
155 {
156     JSType t1 = v1->type();
157     JSType t2 = v2->type();
158     const unsigned bothTypes = (t1 << 3) | t2;
159
160     if (bothTypes == ((NumberType << 3) | NumberType))
161         return jsNumber(v1->uncheckedGetNumber() + v2->uncheckedGetNumber());
162     if (bothTypes == ((StringType << 3) | StringType)) {
163         UString value = static_cast<StringImp*>(v1)->value() + static_cast<StringImp*>(v2)->value();
164         if (value.isNull())
165             return throwOutOfMemoryError(exec);
166         return jsString(value);
167     }
168
169     // All other cases are pretty uncommon
170     return jsAddSlowCase(exec, v1, v2);
171 }
172
173 static JSValue* jsTypeStringForValue(JSValue* v)
174 {
175     switch (v->type()) {
176         case UndefinedType:
177             return jsString("undefined");
178         case NullType:
179             return jsString("object");
180         case BooleanType:
181             return jsString("boolean");
182         case NumberType:
183             return jsString("number");
184         case StringType:
185             return jsString("string");
186         default:
187             if (v->isObject()) {
188                 // Return "undefined" for objects that should be treated
189                 // as null when doing comparisons.
190                 if (static_cast<JSObject*>(v)->masqueradeAsUndefined())
191                     return jsString("undefined");
192                 else if (static_cast<JSObject*>(v)->implementsCall())
193                     return jsString("function");
194             }
195
196             return jsString("object");
197     }
198 }
199
200 static bool NEVER_INLINE resolve(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
201 {
202     int dst = (vPC + 1)->u.operand;
203     int property = (vPC + 2)->u.operand;
204
205     ScopeChainIterator iter = scopeChain->begin();
206     ScopeChainIterator end = scopeChain->end();
207     ASSERT(iter != end);
208
209     PropertySlot slot;
210     Identifier& ident = codeBlock->identifiers[property];
211     do {
212         JSObject* o = *iter;
213         if (o->getPropertySlot(exec, ident, slot)) {
214             JSValue* result = slot.getValue(exec, o, ident);
215             exceptionValue = exec->exception();
216             if (exceptionValue)
217                 return false;
218             r[dst].u.jsValue = result;
219             return true;
220         }
221     } while (++iter != end);
222     exceptionValue = createUndefinedVariableError(exec, ident);
223     return false;
224 }
225     
226 static bool NEVER_INLINE resolve_skip(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
227 {
228     int dst = (vPC + 1)->u.operand;
229     int property = (vPC + 2)->u.operand;
230     int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain;
231     
232     ScopeChainIterator iter = scopeChain->begin();
233     ScopeChainIterator end = scopeChain->end();
234     ASSERT(iter != end);
235     while (skip--) {
236         ++iter;
237         ASSERT(iter != end);
238     }
239     PropertySlot slot;
240     Identifier& ident = codeBlock->identifiers[property];
241     do {
242         JSObject* o = *iter;
243         if (o->getPropertySlot(exec, ident, slot)) {
244             JSValue* result = slot.getValue(exec, o, ident);
245             exceptionValue = exec->exception();
246             if (exceptionValue)
247                 return false;
248             r[dst].u.jsValue = result;
249             return true;
250         }
251     } while (++iter != end);
252     exceptionValue = createUndefinedVariableError(exec, ident);
253     return false;
254 }
255
256 static void NEVER_INLINE resolveBase(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock)
257 {
258     int dst = (vPC + 1)->u.operand;
259     int property = (vPC + 2)->u.operand;
260
261     ScopeChainIterator iter = scopeChain->begin();
262     ScopeChainIterator next = iter;
263     ++next;
264     ScopeChainIterator end = scopeChain->end();
265     ASSERT(iter != end);
266
267     PropertySlot slot;
268     Identifier& ident = codeBlock->identifiers[property];
269     JSObject* base;
270     while (true) {
271         base = *iter;
272         if (next == end || base->getPropertySlot(exec, ident, slot)) {
273             r[dst].u.jsValue = base;
274             return;
275         }
276         iter = next;
277         ++next;
278     }
279 }
280
281 static bool NEVER_INLINE resolveBaseAndProperty(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
282 {
283     int baseDst = (vPC + 1)->u.operand;
284     int propDst = (vPC + 2)->u.operand;
285     int property = (vPC + 3)->u.operand;
286     
287     ScopeChainIterator iter = scopeChain->begin();
288     ScopeChainIterator end = scopeChain->end();
289     
290     // FIXME: add scopeDepthIsZero optimization
291     
292     ASSERT(iter != end);
293     
294     PropertySlot slot;
295     Identifier& ident = codeBlock->identifiers[property];
296     JSObject* base;
297     do {
298         base = *iter;
299         if (base->getPropertySlot(exec, ident, slot)) {
300             JSValue* result = slot.getValue(exec, base, ident);  
301             exceptionValue = exec->exception();
302             if (exceptionValue)
303                 return false;
304             r[propDst].u.jsValue = result;   
305             r[baseDst].u.jsValue = base;
306             return true;
307         }
308         ++iter;
309     } while (iter != end);
310     
311     exceptionValue = createUndefinedVariableError(exec, ident);
312     return false;
313 }
314
315 static bool NEVER_INLINE resolveBaseAndFunc(ExecState* exec, Instruction* vPC, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue*& exceptionValue)
316 {
317     int baseDst = (vPC + 1)->u.operand;
318     int funcDst = (vPC + 2)->u.operand;
319     int property = (vPC + 3)->u.operand;
320
321     ScopeChainIterator iter = scopeChain->begin();
322     ScopeChainIterator end = scopeChain->end();
323     
324     // FIXME: add scopeDepthIsZero optimization
325     
326     ASSERT(iter != end);
327     
328     PropertySlot slot;
329     Identifier& ident = codeBlock->identifiers[property];
330     JSObject* base;
331     do {
332         base = *iter;
333         if (base->getPropertySlot(exec, ident, slot)) {            
334             // ECMA 11.2.3 says that if we hit an activation the this value should be null.
335             // However, section 10.2.3 says that in the case where the value provided
336             // by the caller is null, the global object should be used. It also says
337             // that the section does not apply to internal functions, but for simplicity
338             // of implementation we use the global object anyway here. This guarantees
339             // that in host objects you always get a valid object for this.
340             // We also handle wrapper substitution for the global object at the same time.
341             JSObject* thisObj = base->toThisObject(exec);
342             JSValue* result = slot.getValue(exec, base, ident);
343             exceptionValue = exec->exception();
344             if (exceptionValue)
345                 return false;
346             
347             r[baseDst].u.jsValue = thisObj;
348             r[funcDst].u.jsValue = result;
349             return true;
350         }
351         ++iter;
352     } while (iter != end);
353
354     exceptionValue = createUndefinedVariableError(exec, ident);
355     return false;
356 }
357
358 ALWAYS_INLINE void initializeCallFrame(Register* callFrame, CodeBlock* codeBlock, Instruction* vPC, ScopeChainNode* scopeChain, int registerOffset, int returnValueRegister, int argv, int argc, int calledAsConstructor, JSValue* function)
359 {
360     callFrame[Machine::CallerCodeBlock].u.codeBlock = codeBlock;
361     callFrame[Machine::ReturnVPC].u.vPC = vPC + 1;
362     callFrame[Machine::CallerScopeChain].u.scopeChain = scopeChain;
363     callFrame[Machine::CallerRegisterOffset].u.i = registerOffset;
364     callFrame[Machine::ReturnValueRegister].u.i = returnValueRegister;
365     callFrame[Machine::ArgumentStartRegister].u.i = argv; // original argument vector (for the sake of the "arguments" object)
366     callFrame[Machine::ArgumentCount].u.i = argc; // original argument count (for the sake of the "arguments" object)
367     callFrame[Machine::CalledAsConstructor].u.i = calledAsConstructor;
368     callFrame[Machine::Callee].u.jsValue = function;
369     callFrame[Machine::OptionalCalleeActivation].u.jsValue = 0;
370 }
371
372 ALWAYS_INLINE Register* slideRegisterWindowForCall(ExecState* exec, CodeBlock* newCodeBlock, RegisterFile* registerFile, Register** registerBase, int registerOffset, int argv, int argc, JSValue*& exceptionValue)
373 {
374     Register* r = 0;
375     int oldOffset = registerOffset;
376     registerOffset += argv + newCodeBlock->numLocals;
377     size_t size = registerOffset + newCodeBlock->numTemporaries;
378
379     if (argc == newCodeBlock->numParameters) { // correct number of arguments
380         if (!registerFile->grow(size)) {
381             exceptionValue = createStackOverflowError(exec);
382             return *registerBase + oldOffset;
383         }
384         r = (*registerBase) + registerOffset;
385     } else if (argc < newCodeBlock->numParameters) { // too few arguments -- fill in the blanks
386         if (!registerFile->grow(size)) {
387             exceptionValue = createStackOverflowError(exec);
388             return *registerBase + oldOffset;
389         }
390         r = (*registerBase) + registerOffset;
391         
392         int omittedArgCount = newCodeBlock->numParameters - argc;
393         Register* endOfParams = r - newCodeBlock->numVars;
394         for (Register* it = endOfParams - omittedArgCount; it != endOfParams; ++it)
395             (*it).u.jsValue = jsUndefined();
396     } else { // too many arguments -- copy return info and expected arguments, leaving the extra arguments behind
397         int shift = argc + Machine::CallFrameHeaderSize;
398         registerOffset += shift;
399         size += shift;
400
401         if (!registerFile->grow(size)) {
402             exceptionValue = createStackOverflowError(exec);
403             return *registerBase + oldOffset;
404         }
405         r = (*registerBase) + registerOffset;
406         
407         Register* it = r - newCodeBlock->numLocals - Machine::CallFrameHeaderSize - shift;
408         Register* end = it + Machine::CallFrameHeaderSize + newCodeBlock->numParameters;
409         for ( ; it != end; ++it)
410             *(it + shift) = *it;
411     }
412
413     return r;
414 }
415
416 ALWAYS_INLINE ScopeChainNode* scopeChainForCall(FunctionBodyNode* functionBodyNode, CodeBlock* newCodeBlock, ScopeChainNode* callDataScopeChain, Register** registerBase, Register* r)
417 {
418     if (newCodeBlock->needsFullScopeChain) {
419         JSActivation* activation = new JSActivation(functionBodyNode, registerBase, r - (*registerBase));
420         r[Machine::OptionalCalleeActivation - Machine::CallFrameHeaderSize - newCodeBlock->numLocals].u.jsValue = activation;
421
422         return callDataScopeChain->copy()->push(activation);
423     }
424
425     return callDataScopeChain;
426 }
427
428 static NEVER_INLINE bool isNotObject(ExecState* exec, const Instruction*, CodeBlock*, JSValue* value, JSValue*& exceptionData)
429 {
430     if (value->isObject())
431         return false;
432     exceptionData = createNotAnObjectError(exec, value, 0);
433     return true;
434 }
435
436 static NEVER_INLINE JSValue* eval(ExecState* exec, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, Register* r, int argv, int argc, JSValue*& exceptionValue)
437 {
438     JSValue* x = argc >= 2 ? r[argv + 1].u.jsValue : jsUndefined();
439     
440     if (!x->isString())
441         return x;
442     
443     UString s = x->toString(exec);
444     if (exec->hadException()) {
445         exceptionValue = exec->exception();
446         exec->clearException();
447         return 0;
448     }
449
450     int sourceId;
451     int errLine;
452     UString errMsg;
453     RefPtr<EvalNode> evalNode = parser().parse<EvalNode>(exec, UString(), 0, UStringSourceProvider::create(s), &sourceId, &errLine, &errMsg);
454     
455     if (!evalNode) {
456         exceptionValue = Error::create(exec, SyntaxError, errMsg, errLine, sourceId, NULL);
457         return 0;
458     }
459
460     return machine().execute(evalNode.get(), exec, thisObj, registerFile, r - (*registerFile->basePointer()) + argv + argc, scopeChain, &exceptionValue);
461 }
462
463 Machine& machine()
464 {
465     ASSERT(JSLock::currentThreadIsHoldingLock());
466     static Machine machine;
467     return machine;
468 }
469
470 Machine::Machine()
471     : m_reentryDepth(0)
472 {
473     privateExecute(InitializeAndReturn);
474 }
475
476 void Machine::dumpCallFrame(const CodeBlock* codeBlock, ScopeChainNode* scopeChain, RegisterFile* registerFile, const Register* r)
477 {
478     ScopeChain sc(scopeChain);
479     JSGlobalObject* globalObject = static_cast<JSGlobalObject*>(sc.bottom());
480     codeBlock->dump(globalObject->globalExec());
481     dumpRegisters(codeBlock, registerFile, r);
482 }
483
484 void Machine::dumpRegisters(const CodeBlock* codeBlock, RegisterFile* registerFile, const Register* r)
485 {
486     printf("Register frame: \n\n");
487     printf("----------------------------------------\n");
488     printf("     use      |   address  |    value   \n");
489     printf("----------------------------------------\n");
490     
491     const Register* it;
492     const Register* end;
493     
494     if (isGlobalCallFrame(registerFile->basePointer(), r)) {
495         it = r - registerFile->numGlobalSlots();
496         end = r;
497         if (it != end) {
498             do {
499                 printf("[global var]  | %10p | %10p \n", it, (*it).u.jsValue);
500                 ++it;
501             } while (it != end);
502             printf("----------------------------------------\n");
503         }
504     } else {
505         it = r - codeBlock->numLocals - CallFrameHeaderSize;
506         end = it + CallFrameHeaderSize;
507         if (it != end) {
508             do {
509                 printf("[call frame]  | %10p | %10p \n", it, (*it).u.jsValue);
510                 ++it;
511             } while (it != end);
512             printf("----------------------------------------\n");
513         }
514         
515         end = it + codeBlock->numParameters;
516         if (it != end) {
517             do {
518                 printf("[param]       | %10p | %10p \n", it, (*it).u.jsValue);
519                 ++it;
520             } while (it != end);
521             printf("----------------------------------------\n");
522         }
523
524         end = it + codeBlock->numVars;
525         if (it != end) {
526             do {
527                 printf("[var]         | %10p | %10p \n", it, (*it).u.jsValue);
528                 ++it;
529             } while (it != end);
530             printf("----------------------------------------\n");
531         }
532     }
533
534     end = it + codeBlock->numTemporaries;
535     if (it != end) {
536         do {
537             printf("[temp]        | %10p | %10p \n", it, (*it).u.jsValue);
538             ++it;
539         } while (it != end);
540     }
541 }
542
543 bool Machine::isOpcode(Opcode opcode)
544 {
545 #if HAVE(COMPUTED_GOTO)
546     return opcode != HashTraits<Opcode>::emptyValue()
547         && !HashTraits<Opcode>::isDeletedValue(opcode)
548         && m_opcodeIDTable.contains(opcode);
549 #else
550     return opcode >= 0 && opcode <= op_end;
551 #endif
552 }
553
554 NEVER_INLINE bool Machine::unwindCallFrame(ExecState* exec, JSValue* exceptionValue, Register** registerBase, const Instruction*& vPC, CodeBlock*& codeBlock, JSValue**& k, ScopeChainNode*& scopeChain, Register*& r)
555 {
556     CodeBlock* oldCodeBlock = codeBlock;
557
558     if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
559         if (!isGlobalCallFrame(registerBase, r)) {
560             DebuggerCallFrame debuggerCallFrame(this, exec->dynamicGlobalObject(), codeBlock, scopeChain, exceptionValue, registerBase, r - *registerBase);
561             debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->lastLine());
562         }
563     }
564
565     if (oldCodeBlock->needsFullScopeChain)
566         scopeChain->deref();
567     
568     if (isGlobalCallFrame(registerBase, r))
569         return false;
570
571     Register* callFrame = r - oldCodeBlock->numLocals - CallFrameHeaderSize;
572     
573     codeBlock = callFrame[CallerCodeBlock].u.codeBlock;
574     if (!codeBlock)
575         return false;
576
577     // If this call frame created an activation, tear it off.
578     if (JSActivation* activation = static_cast<JSActivation*>(callFrame[OptionalCalleeActivation].u.jsValue)) {
579         ASSERT(activation->isActivationObject());
580         activation->copyRegisters();
581     }
582
583     k = codeBlock->jsValues.data();
584     scopeChain = callFrame[CallerScopeChain].u.scopeChain;
585     int callerRegisterOffset = callFrame[CallerRegisterOffset].u.i;
586     r = (*registerBase) + callerRegisterOffset;
587     exec->m_callFrameOffset = callerRegisterOffset - codeBlock->numLocals - CallFrameHeaderSize;
588     vPC = callFrame[ReturnVPC].u.vPC;
589     return true;
590 }
591
592 NEVER_INLINE Instruction* Machine::throwException(ExecState* exec, JSValue* exceptionValue, Register** registerBase, const Instruction* vPC, CodeBlock*& codeBlock, JSValue**& k, ScopeChainNode*& scopeChain, Register*& r)
593 {
594     // Set up the exception object
595
596     if (exceptionValue->isObject()) {
597         JSObject* exception = static_cast<JSObject*>(exceptionValue);
598         if (!exception->hasProperty(exec, "line") && !exception->hasProperty(exec, "sourceURL")) {
599             exception->put(exec, "line", jsNumber(codeBlock->lineNumberForVPC(vPC)));
600             exception->put(exec, "sourceURL", jsOwnedString(codeBlock->ownerNode->sourceURL()));
601         }
602     }
603
604     if (Debugger* debugger = exec->dynamicGlobalObject()->debugger()) {
605         DebuggerCallFrame debuggerCallFrame(this, exec->dynamicGlobalObject(), codeBlock, scopeChain, exceptionValue, registerBase, r - *registerBase);
606         debugger->exception(debuggerCallFrame, codeBlock->ownerNode->sourceId(), codeBlock->lineNumberForVPC(vPC));
607     }
608
609     // Calculate an exception handler vPC, unwinding call frames as necessary.
610
611     int scopeDepth;        
612     Instruction* handlerVPC;
613
614     while (!codeBlock->getHandlerForVPC(vPC, handlerVPC, scopeDepth))
615         if (!unwindCallFrame(exec, exceptionValue, registerBase, vPC, codeBlock, k, scopeChain, r))
616             return 0;
617
618     // Now unwind the scope chain within the exception handler's call frame.
619     
620     ScopeChain sc(scopeChain);
621     int scopeDelta = depth(sc) - scopeDepth;
622     ASSERT(scopeDelta >= 0);
623     while (scopeDelta--)
624         sc.pop();
625     setScopeChain(exec, scopeChain, sc.node());
626
627     return handlerVPC;
628 }
629
630 JSValue* Machine::execute(ProgramNode* programNode, ExecState* exec, ScopeChainNode* scopeChain, JSObject* thisObj, RegisterFileStack* registerFileStack, JSValue** exception)
631 {
632     if (m_reentryDepth >= MaxReentryDepth) {
633         *exception = createStackOverflowError(exec);
634         return 0;
635     }
636
637     RegisterFile* registerFile = registerFileStack->pushGlobalRegisterFile();
638     ASSERT(registerFile->numGlobalSlots());
639     CodeBlock* codeBlock = &programNode->code(scopeChain, !registerFileStack->inImplicitCall());
640     registerFile->addGlobalSlots(codeBlock->numVars);
641
642     registerFile->uncheckedGrow(codeBlock->numTemporaries);
643     Register* r = (*registerFile->basePointer());
644
645     r[ProgramCodeThisRegister].u.jsValue = thisObj;
646     
647     if (codeBlock->needsFullScopeChain)
648         scopeChain = scopeChain->copy();
649     
650     ExecState newExec(exec, this, registerFile, scopeChain, -1);
651
652     m_reentryDepth++;
653     JSValue* result = privateExecute(Normal, &newExec, registerFile, r, scopeChain, codeBlock, exception);
654     m_reentryDepth--;
655
656     registerFileStack->popGlobalRegisterFile();
657     return result;
658 }
659
660 JSValue* Machine::execute(FunctionBodyNode* functionBodyNode, ExecState* exec, FunctionImp* function, JSObject* thisObj, const List& args, RegisterFileStack* registerFileStack, ScopeChainNode* scopeChain, JSValue** exception)
661 {
662     if (m_reentryDepth >= MaxReentryDepth) {
663         *exception = createStackOverflowError(exec);
664         return 0;
665     }
666
667     RegisterFile* registerFile = registerFileStack->current();
668
669     int argv = CallFrameHeaderSize;
670     int argc = args.size() + 1; // implicit "this" parameter
671     
672     size_t oldSize = registerFile->size();
673     if (!registerFile->grow(oldSize + CallFrameHeaderSize + argc)) {
674         *exception = createStackOverflowError(exec);
675         return 0;
676     }
677         
678     Register** registerBase = registerFile->basePointer();
679     int registerOffset = oldSize;
680     int callFrameOffset = registerOffset;
681     Register* callFrame = (*registerBase) + callFrameOffset;
682     
683     // put args in place, including "this"
684     Register* dst = callFrame + CallFrameHeaderSize;
685     (*dst).u.jsValue = thisObj;
686     
687     List::const_iterator end = args.end();
688     for (List::const_iterator it = args.begin(); it != end; ++it)
689         (*++dst).u.jsValue = *it;
690
691     // put call frame in place, using a 0 codeBlock to indicate a built-in caller
692     initializeCallFrame(callFrame, 0, 0, 0, registerOffset, 0, argv, argc, 0, function);
693
694     CodeBlock* newCodeBlock = &functionBodyNode->code(scopeChain);
695     Register* r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, argv, argc, *exception);
696     if (*exception) {
697         registerFile->shrink(oldSize);
698         return 0;
699     }
700
701     scopeChain = scopeChainForCall(functionBodyNode, newCodeBlock, scopeChain, registerBase, r);            
702
703     ExecState newExec(exec, this, registerFile, scopeChain, callFrameOffset);
704
705     m_reentryDepth++;
706     JSValue* result = privateExecute(Normal, &newExec, registerFile, r, scopeChain, newCodeBlock, exception);
707     m_reentryDepth--;
708
709     registerFile->shrink(oldSize);
710     return result;
711     
712 }
713
714 JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, RegisterFile* registerFile, int registerOffset, ScopeChainNode* scopeChain, JSValue** exception)
715 {
716     if (m_reentryDepth >= MaxReentryDepth) {
717         *exception = createStackOverflowError(exec);
718         return 0;
719     }
720     EvalCodeBlock* codeBlock = &evalNode->code(scopeChain);
721     
722     JSVariableObject* variableObject;
723     for (ScopeChainNode* node = scopeChain; ; node = node->next) {
724         ASSERT(node);
725         if (node->object->isVariableObject()) {
726             variableObject = static_cast<JSVariableObject*>(node->object);
727             break;
728         }
729     }
730     
731     for (Vector<Identifier>::const_iterator iter = codeBlock->declaredVariableNames.begin(); iter != codeBlock->declaredVariableNames.end(); ++iter) {
732         Identifier ident = *iter;
733         
734         if (!variableObject->hasProperty(exec, ident))
735             variableObject->put(exec, ident, jsUndefined());
736     }
737     
738     ASSERT(codeBlock->functions.size() == codeBlock->declaredFunctionNames.size());
739     for (size_t i = 0; i < codeBlock->functions.size(); ++i)
740         variableObject->put(exec, codeBlock->declaredFunctionNames[i], codeBlock->functions[i]->makeFunction(exec, scopeChain));
741     
742     size_t oldSize = registerFile->size();
743     size_t newSize = registerOffset + codeBlock->numVars + codeBlock->numTemporaries + CallFrameHeaderSize;
744     if (!registerFile->grow(newSize)) {
745         *exception = createStackOverflowError(exec);
746         return 0;
747     }
748
749     Register* callFrame = *registerFile->basePointer() + registerOffset;
750     
751     // put call frame in place, using a 0 codeBlock to indicate a built-in caller
752     initializeCallFrame(callFrame, 0, 0, 0, registerOffset, 0, 0, 0, 0, 0);
753
754     Register* r = callFrame + CallFrameHeaderSize + codeBlock->numVars;
755     r[ProgramCodeThisRegister].u.jsValue = thisObj;
756
757     if (codeBlock->needsFullScopeChain)
758         scopeChain = scopeChain->copy();
759
760     ExecState newExec(exec, this, registerFile, scopeChain, -1);
761
762     m_reentryDepth++;
763     JSValue* result = privateExecute(Normal, &newExec, registerFile, r, scopeChain, codeBlock, exception);
764     m_reentryDepth--;
765
766     registerFile->shrink(oldSize);
767     return result;
768 }
769
770 JSValue* Machine::execute(EvalNode* evalNode, ExecState* exec, JSObject* thisObj, RegisterFileStack* registerFileStack, ScopeChainNode* scopeChain, JSValue** exception)
771 {
772     RegisterFile* registerFile = registerFileStack->current();
773     if (registerFile->safeForReentry())
774         return Machine::execute(evalNode, exec, thisObj, registerFile, registerFile->size(), scopeChain, exception);
775     registerFile = registerFileStack->pushFunctionRegisterFile();
776     JSValue* result = Machine::execute(evalNode, exec, thisObj, registerFile, registerFile->size(), scopeChain, exception);
777     registerFileStack->popFunctionRegisterFile();
778     return result;
779 }
780
781 ALWAYS_INLINE void Machine::setScopeChain(ExecState* exec, ScopeChainNode*& scopeChain, ScopeChainNode* newScopeChain)
782 {
783     scopeChain = newScopeChain;
784     exec->m_scopeChain = newScopeChain;
785 }
786
787 NEVER_INLINE void Machine::debug(ExecState* exec, const Instruction* vPC, const CodeBlock* codeBlock, ScopeChainNode* scopeChain, Register** registerBase, Register* r)
788 {
789     int debugHookID = (++vPC)->u.operand;
790     int firstLine = (++vPC)->u.operand;
791     int lastLine = (++vPC)->u.operand;
792
793     Debugger* debugger = exec->dynamicGlobalObject()->debugger();
794     if (!debugger)
795         return;
796
797     DebuggerCallFrame debuggerCallFrame(this, exec->dynamicGlobalObject(), codeBlock, scopeChain, 0, registerBase, r - *registerBase);
798
799     switch((DebugHookID)debugHookID) {
800     case DidEnterCallFrame: {
801         debugger->callEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), firstLine);
802         return;
803     }
804     case WillLeaveCallFrame: {
805         debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceId(), lastLine);
806         return;
807     }
808     case WillExecuteStatement: {
809         debugger->atStatement(debuggerCallFrame, codeBlock->ownerNode->sourceId(), firstLine);
810         return;
811     }
812     }
813 }
814
815 JSValue* Machine::privateExecute(ExecutionFlag flag, ExecState* exec, RegisterFile* registerFile, Register* r, ScopeChainNode* scopeChain, CodeBlock* codeBlock, JSValue** exception)
816 {
817     // One-time initialization of our address tables. We have to put this code
818     // here because our labels are only in scope inside this function.
819     if (flag == InitializeAndReturn) {
820         #if HAVE(COMPUTED_GOTO)
821             #define ADD_OPCODE(id) m_opcodeTable[id] = &&id;
822                 FOR_EACH_OPCODE_ID(ADD_OPCODE);
823             #undef ADD_OPCODE
824
825             #define ADD_OPCODE_ID(id) m_opcodeIDTable.add(&&id, id);
826                 FOR_EACH_OPCODE_ID(ADD_OPCODE_ID);
827             #undef ADD_OPCODE
828             ASSERT(m_opcodeIDTable.size() == numOpcodeIDs);
829             op_throw_end_indirect = &&op_throw_end;
830             op_call_indirect = &&op_call;
831         #endif // HAVE(COMPUTED_GOTO)
832         return 0;
833     }
834
835     JSValue* exceptionValue = 0;
836     Instruction* handlerVPC = 0;
837     
838     Register** registerBase = registerFile->basePointer();
839     Instruction* vPC = codeBlock->instructions.begin();
840     JSValue** k = codeBlock->jsValues.data();
841     
842     registerFile->setSafeForReentry(false);
843 #define VM_CHECK_EXCEPTION() \
844      do { \
845         if (UNLIKELY(exec->hadException())) { \
846             exceptionValue = exec->exception(); \
847             goto vm_throw; \
848         } \
849     } while (0)
850
851 #if HAVE(COMPUTED_GOTO)
852     #define NEXT_OPCODE goto *vPC->u.opcode
853     #define BEGIN_OPCODE(opcode) opcode:
854     NEXT_OPCODE;
855 #else
856     #define NEXT_OPCODE continue
857     #define BEGIN_OPCODE(opcode) case opcode:
858     while(1) // iterator loop begins
859     switch (vPC->u.opcode)
860 #endif
861     {
862     BEGIN_OPCODE(op_load) {
863         /* load dst(r) src(k)
864
865            Copies constant src to register dst.
866         */
867         int dst = (++vPC)->u.operand;
868         int src = (++vPC)->u.operand;
869         r[dst].u.jsValue = k[src];
870         
871         ++vPC;
872         NEXT_OPCODE;
873     }
874     BEGIN_OPCODE(op_new_object) {
875         /* new_object dst(r)
876
877            Constructs a new empty Object instance using the original
878            constructor, and puts the result in register dst.
879         */
880         int dst = (++vPC)->u.operand;
881         r[dst].u.jsValue = scopeChain->globalObject()->objectConstructor()->construct(exec, exec->emptyList());
882         
883         ++vPC;
884         NEXT_OPCODE;
885     }
886     BEGIN_OPCODE(op_new_array) {
887         /* new_array dst(r)
888
889            Constructs a new empty Array instance using the original
890            constructor, and puts the result in register dst.
891         */
892         int dst = (++vPC)->u.operand;
893         r[dst].u.jsValue = scopeChain->globalObject()->arrayConstructor()->construct(exec, exec->emptyList());
894         
895         ++vPC;
896         NEXT_OPCODE;
897     }
898     BEGIN_OPCODE(op_new_regexp) {
899         /* new_regexp dst(r) regExp(re)
900
901            Constructs a new RegExp instance using the original
902            constructor from regexp regExp, and puts the result in
903            register dst.
904         */
905         int dst = (++vPC)->u.operand;
906         int regExp = (++vPC)->u.operand;
907         r[dst].u.jsValue = new RegExpImp(scopeChain->globalObject()->regExpPrototype(), codeBlock->regexps[regExp]);
908
909         ++vPC;
910         NEXT_OPCODE;
911     }
912     BEGIN_OPCODE(op_mov) {
913         /* mov dst(r) src(r)
914
915            Copies register src to register dst.
916         */
917         int dst = (++vPC)->u.operand;
918         int src = (++vPC)->u.operand;
919         r[dst] = r[src];
920
921         ++vPC;
922         NEXT_OPCODE;
923     }
924     BEGIN_OPCODE(op_eq) {
925         /* eq dst(r) src1(r) src2(r)
926
927            Checks whether register src1 and register src2 are equal,
928            as with the ECMAScript '==' operator, and puts the result
929            as a boolean in register dst.
930         */
931         int dst = (++vPC)->u.operand;
932         int src1 = (++vPC)->u.operand;
933         int src2 = (++vPC)->u.operand;
934         JSValue* result = jsBoolean(equal(exec, r[src1].u.jsValue, r[src2].u.jsValue));
935         VM_CHECK_EXCEPTION();
936         r[dst].u.jsValue = result;
937
938         ++vPC;
939         NEXT_OPCODE;
940     }
941     BEGIN_OPCODE(op_neq) {
942         /* neq dst(r) src1(r) src2(r)
943
944            Checks whether register src1 and register src2 are not
945            equal, as with the ECMAScript '!=' operator, and puts the
946            result as a boolean in register dst.
947         */
948         int dst = (++vPC)->u.operand;
949         int src1 = (++vPC)->u.operand;
950         int src2 = (++vPC)->u.operand;
951         JSValue* result = jsBoolean(!equal(exec, r[src1].u.jsValue, r[src2].u.jsValue));
952         VM_CHECK_EXCEPTION();
953         r[dst].u.jsValue = result;
954
955         ++vPC;
956         NEXT_OPCODE;
957     }
958     BEGIN_OPCODE(op_stricteq) {
959         /* stricteq dst(r) src1(r) src2(r)
960
961            Checks whether register src1 and register src2 are strictly
962            equal, as with the ECMAScript '===' operator, and puts the
963            result as a boolean in register dst.
964         */
965         int dst = (++vPC)->u.operand;
966         int src1 = (++vPC)->u.operand;
967         int src2 = (++vPC)->u.operand;
968         r[dst].u.jsValue = jsBoolean(strictEqual(r[src1].u.jsValue, r[src2].u.jsValue));
969         
970         ++vPC;
971         NEXT_OPCODE;
972     }
973     BEGIN_OPCODE(op_nstricteq) {
974         /* nstricteq dst(r) src1(r) src2(r)
975
976            Checks whether register src1 and register src2 are not
977            strictly equal, as with the ECMAScript '!==' operator, and
978            puts the result as a boolean in register dst.
979         */
980         int dst = (++vPC)->u.operand;
981         int src1 = (++vPC)->u.operand;
982         int src2 = (++vPC)->u.operand;
983         r[dst].u.jsValue = jsBoolean(!strictEqual(r[src1].u.jsValue, r[src2].u.jsValue));
984
985         ++vPC;
986         NEXT_OPCODE;
987     }
988     BEGIN_OPCODE(op_less) {
989         /* less dst(r) src1(r) src2(r)
990
991            Checks whether register src1 is less than register src2, as
992            with the ECMAScript '<' operator, and puts the result as
993            a boolean in register dst.
994         */
995         int dst = (++vPC)->u.operand;
996         int src1 = (++vPC)->u.operand;
997         int src2 = (++vPC)->u.operand;
998         JSValue* result = jsBoolean(jsLess(exec, r[src1].u.jsValue, r[src2].u.jsValue));
999         VM_CHECK_EXCEPTION();
1000         r[dst].u.jsValue = result;
1001
1002         ++vPC;
1003         NEXT_OPCODE;
1004     }
1005     BEGIN_OPCODE(op_lesseq) {
1006         /* lesseq dst(r) src1(r) src2(r)
1007
1008            Checks whether register src1 is less than or equal to
1009            register src2, as with the ECMAScript '<=' operator, and
1010            puts the result as a boolean in register dst.
1011         */
1012         int dst = (++vPC)->u.operand;
1013         int src1 = (++vPC)->u.operand;
1014         int src2 = (++vPC)->u.operand;
1015         JSValue* result = jsBoolean(jsLessEq(exec, r[src1].u.jsValue, r[src2].u.jsValue));
1016         VM_CHECK_EXCEPTION();
1017         r[dst].u.jsValue = result;
1018
1019         ++vPC;
1020         NEXT_OPCODE;
1021     }
1022     BEGIN_OPCODE(op_pre_inc) {
1023         /* pre_inc srcDst(r)
1024
1025            Converts register srcDst to number, adds one, and puts the result
1026            back in register srcDst.
1027         */
1028         int srcDst = (++vPC)->u.operand;
1029         JSValue* result = jsNumber(r[srcDst].u.jsValue->toNumber(exec) + 1);
1030         VM_CHECK_EXCEPTION();
1031         r[srcDst].u.jsValue = result;
1032         
1033         ++vPC;
1034         NEXT_OPCODE;
1035     }
1036     BEGIN_OPCODE(op_pre_dec) {
1037         /* pre_dec srcDst(r)
1038
1039            Converts register srcDst to number, subtracts one, and puts the result
1040            back in register srcDst.
1041         */
1042         int srcDst = (++vPC)->u.operand;
1043         JSValue* result = jsNumber(r[srcDst].u.jsValue->toNumber(exec) - 1);
1044         VM_CHECK_EXCEPTION();
1045         r[srcDst].u.jsValue = result;
1046
1047         ++vPC;
1048         NEXT_OPCODE;
1049     }
1050     BEGIN_OPCODE(op_post_inc) {
1051         /* post_inc dst(r) srcDst(r)
1052
1053            Converts register srcDst to number. The number itself is
1054            written to register dst, and the number plus one is written
1055            back to register srcDst.
1056         */
1057         int dst = (++vPC)->u.operand;
1058         int srcDst = (++vPC)->u.operand;
1059         JSValue* number = r[srcDst].u.jsValue->toJSNumber(exec);
1060         VM_CHECK_EXCEPTION();
1061
1062         r[dst].u.jsValue = number;
1063         r[srcDst].u.jsValue = jsNumber(number->uncheckedGetNumber() + 1);
1064
1065         ++vPC;
1066         NEXT_OPCODE;
1067     }
1068     BEGIN_OPCODE(op_post_dec) {
1069         /* post_dec dst(r) srcDst(r)
1070
1071            Converts register srcDst to number. The number itself is
1072            written to register dst, and the number minus one is written
1073            back to register srcDst.
1074         */
1075         int dst = (++vPC)->u.operand;
1076         int srcDst = (++vPC)->u.operand;
1077         JSValue* number = r[srcDst].u.jsValue->toJSNumber(exec);
1078         VM_CHECK_EXCEPTION();
1079
1080         r[dst].u.jsValue = number;
1081         r[srcDst].u.jsValue = jsNumber(number->uncheckedGetNumber() - 1);
1082
1083         ++vPC;
1084         NEXT_OPCODE;
1085     }
1086     BEGIN_OPCODE(op_to_jsnumber) {
1087         /* to_jsnumber dst(r) src(r)
1088
1089            Converts register src to number, and puts the result
1090            in register dst.
1091         */
1092         int dst = (++vPC)->u.operand;
1093         int src = (++vPC)->u.operand;
1094         JSValue* result = r[src].u.jsValue->toJSNumber(exec);
1095         VM_CHECK_EXCEPTION();
1096
1097         r[dst].u.jsValue = result;
1098
1099         ++vPC;
1100         NEXT_OPCODE;
1101     }
1102     BEGIN_OPCODE(op_negate) {
1103         /* negate dst(r) src(r)
1104
1105            Converts register src to number, negates it, and puts the
1106            result in register dst.
1107         */
1108         int dst = (++vPC)->u.operand;
1109         int src = (++vPC)->u.operand;
1110         JSValue* result = jsNumber(-r[src].u.jsValue->toNumber(exec));
1111         VM_CHECK_EXCEPTION();
1112         r[dst].u.jsValue = result;
1113
1114         ++vPC;
1115         NEXT_OPCODE;
1116     }
1117     BEGIN_OPCODE(op_add) {
1118         /* add dst(r) src1(r) src2(r)
1119
1120            Adds register src1 and register src2, and puts the result
1121            in register dst. (JS add may be string concatenation or
1122            numeric add, depending on the types of the operands.)
1123         */
1124         int dst = (++vPC)->u.operand;
1125         int src1 = (++vPC)->u.operand;
1126         int src2 = (++vPC)->u.operand;
1127         JSValue* result = jsAdd(exec, r[src1].u.jsValue, r[src2].u.jsValue);
1128         VM_CHECK_EXCEPTION();
1129         r[dst].u.jsValue = result;
1130         ++vPC;
1131         NEXT_OPCODE;
1132     }
1133     BEGIN_OPCODE(op_mul) {
1134         /* mul dst(r) src1(r) src2(r)
1135
1136            Multiplies register src1 and register src2 (converted to
1137            numbers), and puts the product in register dst.
1138         */
1139         int dst = (++vPC)->u.operand;
1140         int src1 = (++vPC)->u.operand;
1141         int src2 = (++vPC)->u.operand;
1142         JSValue* result = jsNumber(r[src1].u.jsValue->toNumber(exec) * r[src2].u.jsValue->toNumber(exec));
1143         VM_CHECK_EXCEPTION();
1144         r[dst].u.jsValue = result;
1145
1146         ++vPC;
1147         NEXT_OPCODE;
1148     }
1149     BEGIN_OPCODE(op_div) {
1150         /* div dst(r) dividend(r) divisor(r)
1151
1152            Divides register dividend (converted to number) by the
1153            register divisor (converted to number), and puts the
1154            quotient in register dst.
1155         */
1156         int dst = (++vPC)->u.operand;
1157         int dividend = (++vPC)->u.operand;
1158         int divisor = (++vPC)->u.operand;
1159         JSValue* result = jsNumber(r[dividend].u.jsValue->toNumber(exec) / r[divisor].u.jsValue->toNumber(exec));
1160         VM_CHECK_EXCEPTION();
1161         r[dst].u.jsValue = result;
1162         ++vPC;
1163         NEXT_OPCODE;
1164     }
1165     BEGIN_OPCODE(op_mod) {
1166         /* mod dst(r) dividend(r) divisor(r)
1167
1168            Divides register dividend (converted to number) by 
1169            register divisor (converted to number), and puts the
1170            remainder in register dst.
1171         */
1172         int dst = (++vPC)->u.operand;
1173         int dividend = (++vPC)->u.operand;
1174         int divisor = (++vPC)->u.operand;
1175         double d = r[dividend].u.jsValue->toNumber(exec);
1176         JSValue* result = jsNumber(fmod(d, r[divisor].u.jsValue->toNumber(exec)));
1177         VM_CHECK_EXCEPTION();
1178         r[dst].u.jsValue = result;
1179         ++vPC;
1180         NEXT_OPCODE;
1181     }
1182     BEGIN_OPCODE(op_sub) {
1183         /* sub dst(r) src1(r) src2(r)
1184
1185            Subtracts register src2 (converted to number) from register
1186            src1 (converted to number), and puts the difference in
1187            register dst.
1188         */
1189         int dst = (++vPC)->u.operand;
1190         int src1 = (++vPC)->u.operand;
1191         int src2 = (++vPC)->u.operand;
1192         JSValue* result = jsNumber(r[src1].u.jsValue->toNumber(exec) - r[src2].u.jsValue->toNumber(exec));
1193         VM_CHECK_EXCEPTION();
1194         r[dst].u.jsValue = result;
1195         ++vPC;
1196         NEXT_OPCODE;
1197     }
1198     BEGIN_OPCODE(op_lshift) {
1199         /* lshift dst(r) val(r) shift(r)
1200
1201            Performs left shift of register val (converted to int32) by
1202            register shift (converted to uint32), and puts the result
1203            in register dst.
1204         */
1205         int dst = (++vPC)->u.operand;
1206         int val = (++vPC)->u.operand;
1207         int shift = (++vPC)->u.operand;
1208         JSValue* result = jsNumber((r[val].u.jsValue->toInt32(exec)) << (r[shift].u.jsValue->toUInt32(exec)));
1209         VM_CHECK_EXCEPTION();
1210         r[dst].u.jsValue = result;
1211         
1212         ++vPC;
1213         NEXT_OPCODE;
1214     }
1215     BEGIN_OPCODE(op_rshift) {
1216         /* rshift dst(r) val(r) shift(r)
1217
1218            Performs arithmetic right shift of register val (converted
1219            to int32) by register shift (converted to
1220            uint32), and puts the result in register dst.
1221         */
1222         int dst = (++vPC)->u.operand;
1223         int val = (++vPC)->u.operand;
1224         int shift = (++vPC)->u.operand;
1225         JSValue* result = jsNumber((r[val].u.jsValue->toInt32(exec)) >> (r[shift].u.jsValue->toUInt32(exec)));
1226         VM_CHECK_EXCEPTION();
1227         r[dst].u.jsValue = result;
1228         
1229         ++vPC;
1230         NEXT_OPCODE;
1231     }
1232     BEGIN_OPCODE(op_urshift) {
1233         /* rshift dst(r) val(r) shift(r)
1234
1235            Performs logical right shift of register val (converted
1236            to uint32) by register shift (converted to
1237            uint32), and puts the result in register dst.
1238         */
1239         int dst = (++vPC)->u.operand;
1240         int val = (++vPC)->u.operand;
1241         int shift = (++vPC)->u.operand;
1242         JSValue* result = jsNumber((r[val].u.jsValue->toUInt32(exec)) >> (r[shift].u.jsValue->toUInt32(exec)));
1243         VM_CHECK_EXCEPTION();
1244         r[dst].u.jsValue = result;
1245         
1246         ++vPC;
1247         NEXT_OPCODE;
1248     }
1249     BEGIN_OPCODE(op_bitand) {
1250         /* bitand dst(r) src1(r) src2(r)
1251
1252            Computes bitwise AND of register src1 (converted to int32)
1253            and register src2 (converted to int32), and puts the result
1254            in register dst.
1255         */
1256         int dst = (++vPC)->u.operand;
1257         int src1 = (++vPC)->u.operand;
1258         int src2 = (++vPC)->u.operand;
1259         JSValue* result = jsNumber((r[src1].u.jsValue->toInt32(exec)) & (r[src2].u.jsValue->toInt32(exec)));
1260         VM_CHECK_EXCEPTION();
1261         r[dst].u.jsValue = result;
1262         
1263         ++vPC;
1264         NEXT_OPCODE;
1265     }
1266     BEGIN_OPCODE(op_bitxor) {
1267         /* bitxor dst(r) src1(r) src2(r)
1268
1269            Computes bitwise XOR of register src1 (converted to int32)
1270            and register src2 (converted to int32), and puts the result
1271            in register dst.
1272         */
1273         int dst = (++vPC)->u.operand;
1274         int src1 = (++vPC)->u.operand;
1275         int src2 = (++vPC)->u.operand;
1276         JSValue* result = jsNumber((r[src1].u.jsValue->toInt32(exec)) ^ (r[src2].u.jsValue->toInt32(exec)));
1277         VM_CHECK_EXCEPTION();
1278         r[dst].u.jsValue = result;
1279         
1280         ++vPC;
1281         NEXT_OPCODE;
1282     }
1283     BEGIN_OPCODE(op_bitor) {
1284         /* bitor dst(r) src1(r) src2(r)
1285
1286            Computes bitwise OR of register src1 (converted to int32)
1287            and register src2 (converted to int32), and puts the
1288            result in register dst.
1289         */
1290         int dst = (++vPC)->u.operand;
1291         int src1 = (++vPC)->u.operand;
1292         int src2 = (++vPC)->u.operand;
1293         JSValue* result = jsNumber((r[src1].u.jsValue->toInt32(exec)) | (r[src2].u.jsValue->toInt32(exec)));
1294         VM_CHECK_EXCEPTION();
1295         r[dst].u.jsValue = result;
1296         
1297         ++vPC;
1298         NEXT_OPCODE;
1299     }
1300     BEGIN_OPCODE(op_bitnot) {
1301         /* bitnot dst(r) src(r)
1302
1303            Computes bitwise NOT of register src1 (converted to int32),
1304            and puts the result in register dst.
1305         */
1306         int dst = (++vPC)->u.operand;
1307         int src = (++vPC)->u.operand;
1308         JSValue* result = jsNumber(~r[src].u.jsValue->toInt32(exec));
1309         VM_CHECK_EXCEPTION();
1310         r[dst].u.jsValue = result;
1311
1312         ++vPC;
1313         NEXT_OPCODE;
1314     }
1315     BEGIN_OPCODE(op_not) {
1316         /* not dst(r) src1(r) src2(r)
1317
1318            Computes logical NOT of register src1 (converted to
1319            boolean), and puts the result in register dst.
1320         */
1321         int dst = (++vPC)->u.operand;
1322         int src = (++vPC)->u.operand;
1323         JSValue* result = jsBoolean(!r[src].u.jsValue->toBoolean(exec));
1324         VM_CHECK_EXCEPTION();
1325         r[dst].u.jsValue = result;
1326
1327         ++vPC;
1328         NEXT_OPCODE;
1329     }
1330     BEGIN_OPCODE(op_instanceof) {
1331         /* instanceof dst(r) value(r) constructor(r)
1332
1333            Tests whether register value is an instance of register
1334            constructor, and puts the boolean result in register dst.
1335           
1336            Raises an exception if register constructor is not an
1337            object.
1338         */
1339         int dst = (++vPC)->u.operand;
1340         int value = (++vPC)->u.operand;
1341         int base = (++vPC)->u.operand;
1342
1343         JSValue* baseVal = r[base].u.jsValue;
1344
1345         if (isNotObject(exec, vPC, codeBlock, baseVal, exceptionValue))
1346             goto vm_throw;
1347
1348         JSObject* baseObj = static_cast<JSObject*>(baseVal);
1349         r[dst].u.jsValue = jsBoolean(baseObj->implementsHasInstance() ? baseObj->hasInstance(exec, r[value].u.jsValue) : false);
1350
1351         ++vPC;
1352         NEXT_OPCODE;
1353     }
1354     BEGIN_OPCODE(op_typeof) {
1355         /* typeof dst(r) src(r)
1356
1357            Determines the type string for src according to ECMAScript
1358            rules, and puts the result in register dst.
1359         */
1360         int dst = (++vPC)->u.operand;
1361         int src = (++vPC)->u.operand;
1362         r[dst].u.jsValue = jsTypeStringForValue(r[src].u.jsValue);
1363
1364         ++vPC;
1365         NEXT_OPCODE;
1366     }
1367     BEGIN_OPCODE(op_in) {
1368         /* in dst(r) property(r) base(r)
1369
1370            Tests whether register base has a property named register
1371            property, and puts the boolean result in register dst.
1372           
1373            Raises an exception if register constructor is not an
1374            object.
1375         */
1376         int dst = (++vPC)->u.operand;
1377         int property = (++vPC)->u.operand;
1378         int base = (++vPC)->u.operand;
1379
1380         JSValue* baseVal = r[base].u.jsValue;
1381         if (isNotObject(exec, vPC, codeBlock, baseVal, exceptionValue))
1382             goto vm_throw;
1383
1384         JSObject* baseObj = static_cast<JSObject*>(baseVal);
1385
1386         JSValue* propName = r[property].u.jsValue;
1387
1388         uint32_t i;
1389         if (propName->getUInt32(i))
1390             r[dst].u.jsValue = jsBoolean(baseObj->hasProperty(exec, i));
1391         else {
1392             Identifier property(propName->toString(exec));
1393             VM_CHECK_EXCEPTION();
1394             r[dst].u.jsValue = jsBoolean(baseObj->hasProperty(exec, property));
1395         }
1396
1397         ++vPC;
1398         NEXT_OPCODE;
1399     }
1400     BEGIN_OPCODE(op_resolve) {
1401         /* resolve dst(r) property(id)
1402
1403            Looks up the property named by identifier property in the
1404            scope chain, and writes the resulting value to register
1405            dst. If the property is not found, raises an exception.
1406         */
1407         if (UNLIKELY(!resolve(exec, vPC, r, scopeChain, codeBlock, exceptionValue)))
1408             goto vm_throw;
1409
1410         vPC += 3;
1411         NEXT_OPCODE;
1412     }
1413     BEGIN_OPCODE(op_resolve_skip) {
1414         /* resolve_skip dst(r) property(id) skip(n)
1415          
1416          Looks up the property named by identifier property in the
1417          scope chain skipping the top 'skip' levels, and writes the resulting
1418          value to register dst. If the property is not found, raises an exception.
1419          */
1420         if (UNLIKELY(!resolve_skip(exec, vPC, r, scopeChain, codeBlock, exceptionValue)))
1421             goto vm_throw;
1422         
1423         vPC += 4;
1424         
1425         NEXT_OPCODE;
1426     }
1427     BEGIN_OPCODE(op_get_scoped_var) {
1428         /* get_scoped_var dst(r) index(n) skip(n)
1429          
1430          Loads the contents of the index-th local from the scope skip nodes from
1431          the top of the scope chain, and places it in register dst
1432          */
1433         int dst = (++vPC)->u.operand;
1434         int index = (++vPC)->u.operand;
1435         int skip = (++vPC)->u.operand + codeBlock->needsFullScopeChain;
1436         
1437         ScopeChainIterator iter = scopeChain->begin();
1438         ScopeChainIterator end = scopeChain->end();
1439         ASSERT(iter != end);
1440         while (skip--) {
1441             ++iter;
1442             ASSERT(iter != end);
1443         }
1444         
1445         ASSERT((*iter)->isVariableObject());
1446         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
1447         r[dst].u.jsValue = scope->valueAt(index);
1448         ++vPC;
1449         NEXT_OPCODE;
1450     }
1451     BEGIN_OPCODE(op_put_scoped_var) {
1452         /* put_scoped_var index(n) skip(n) value(r)
1453
1454          */
1455         int index = (++vPC)->u.operand;
1456         int skip = (++vPC)->u.operand + codeBlock->needsFullScopeChain;
1457         int value = (++vPC)->u.operand;
1458         
1459         ScopeChainIterator iter = scopeChain->begin();
1460         ScopeChainIterator end = scopeChain->end();
1461         ASSERT(iter != end);
1462         while (skip--) {
1463             ++iter;
1464             ASSERT(iter != end);
1465         }
1466         
1467         ASSERT((*iter)->isVariableObject());
1468         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
1469         scope->valueAt(index) = r[value].u.jsValue;
1470         ++vPC;
1471         NEXT_OPCODE;
1472     }
1473     BEGIN_OPCODE(op_resolve_base) {
1474         /* resolve_base dst(r) property(id)
1475
1476            Searches the scope chain for an object containing
1477            identifier property, and if one is found, writes it to
1478            register dst. If none is found, the outermost scope (which
1479            will be the global object) is stored in register dst.
1480         */
1481         resolveBase(exec, vPC, r, scopeChain, codeBlock);
1482
1483         vPC += 3;
1484         NEXT_OPCODE;
1485     }
1486     BEGIN_OPCODE(op_resolve_with_base) {
1487         /* resolve_with_base baseDst(r) propDst(r) property(id)
1488
1489            Searches the scope chain for an object containing
1490            identifier property, and if one is found, writes it to
1491            register srcDst, and the retrieved property value to register
1492            propDst. If the property is not found, raises an exception.
1493
1494            This is more efficient than doing resolve_base followed by
1495            resolve, or resolve_base followed by get_by_id, as it
1496            avoids duplicate hash lookups.
1497         */
1498         if (UNLIKELY(!resolveBaseAndProperty(exec, vPC, r, scopeChain, codeBlock, exceptionValue)))
1499             goto vm_throw;
1500
1501         vPC += 4;
1502         NEXT_OPCODE;
1503     }
1504     BEGIN_OPCODE(op_resolve_func) {
1505         /* resolve_func baseDst(r) funcDst(r) property(id)
1506
1507            Searches the scope chain for an object containing
1508            identifier property, and if one is found, writes the
1509            appropriate object to use as "this" when calling its
1510            properties to register baseDst; and the retrieved property
1511            value to register propDst. If the property is not found,
1512            raises an exception.
1513
1514            This differs from resolve_with_base, because the
1515            global this value will be substituted for activations or
1516            the global object, which is the right behavior for function
1517            calls but not for other property lookup.
1518         */
1519         if (UNLIKELY(!resolveBaseAndFunc(exec, vPC, r, scopeChain, codeBlock, exceptionValue)))
1520             goto vm_throw;
1521
1522         vPC += 4;
1523         NEXT_OPCODE;
1524     }
1525     BEGIN_OPCODE(op_get_by_id) {
1526         /* get_by_id dst(r) base(r) property(id)
1527
1528            Converts register base to Object, gets the property
1529            named by identifier property from the object, and puts the
1530            result in register dst.
1531         */
1532         int dst = (++vPC)->u.operand;
1533         int base = (++vPC)->u.operand;
1534         int property = (++vPC)->u.operand;
1535 #ifndef NDEBUG
1536         int registerOffset = r - (*registerBase);
1537 #endif
1538         JSObject* baseObj = r[base].u.jsValue->toObject(exec);
1539
1540         Identifier& ident = codeBlock->identifiers[property];
1541         JSValue *result = baseObj->get(exec, ident);
1542         ASSERT(registerOffset == (r - (*registerBase)));
1543         VM_CHECK_EXCEPTION();
1544         r[dst].u.jsValue = result;
1545         ++vPC;
1546         NEXT_OPCODE;
1547     }
1548     BEGIN_OPCODE(op_put_by_id) {
1549         /* put_by_id base(r) property(id) value(r)
1550
1551            Sets register value on register base as the property named
1552            by identifier property. Base is converted to object first.
1553  
1554            Unlike many opcodes, this one does not write any output to
1555            the register file.
1556         */
1557         int base = (++vPC)->u.operand;
1558         int property = (++vPC)->u.operand;
1559         int value = (++vPC)->u.operand;
1560 #ifndef NDEBUG
1561         int registerOffset = r - (*registerBase);
1562 #endif
1563
1564         JSObject* baseObj = r[base].u.jsValue->toObject(exec);
1565         
1566         Identifier& ident = codeBlock->identifiers[property];
1567         baseObj->put(exec, ident, r[value].u.jsValue);
1568         ASSERT(registerOffset == (r - (*registerBase)));
1569         
1570         VM_CHECK_EXCEPTION();
1571         ++vPC;
1572         NEXT_OPCODE;
1573     }
1574     BEGIN_OPCODE(op_del_by_id) {
1575         /* del_by_id dst(r) base(r) property(id)
1576
1577            Converts register base to Object, deletes the property
1578            named by identifier property from the object, and writes a
1579            boolean indicating success (if true) or failure (if false)
1580            to register dst.
1581         */
1582         int dst = (++vPC)->u.operand;
1583         int base = (++vPC)->u.operand;
1584         int property = (++vPC)->u.operand;
1585
1586         JSObject* baseObj = r[base].u.jsValue->toObject(exec);
1587         
1588         Identifier& ident = codeBlock->identifiers[property];
1589         JSValue* result = jsBoolean(baseObj->deleteProperty(exec, ident));
1590         VM_CHECK_EXCEPTION();
1591         r[dst].u.jsValue = result;
1592         ++vPC;
1593         NEXT_OPCODE;
1594     }
1595     BEGIN_OPCODE(op_get_by_val) {
1596         /* get_by_val dst(r) base(r) property(r)
1597
1598            Converts register base to Object, gets the property named
1599            by register property from the object, and puts the result
1600            in register dst. property is nominally converted to string
1601            but numbers are treated more efficiently.
1602         */
1603         int dst = (++vPC)->u.operand;
1604         int base = (++vPC)->u.operand;
1605         int property = (++vPC)->u.operand;
1606
1607         JSObject* baseObj = r[base].u.jsValue->toObject(exec); // may throw
1608         
1609         JSValue* subscript = r[property].u.jsValue;
1610         JSValue* result;
1611         uint32_t i;
1612         if (subscript->getUInt32(i))
1613             result = baseObj->get(exec, i);
1614         else {
1615             Identifier property;
1616             if (subscript->isObject()) {
1617                 VM_CHECK_EXCEPTION(); // If toObject threw, we must not call toString, which may execute arbitrary code
1618                 property = Identifier(subscript->toString(exec));
1619             } else
1620                 property = Identifier(subscript->toString(exec));
1621
1622             VM_CHECK_EXCEPTION(); // This check is needed to prevent us from incorrectly calling a getter after an exception is thrown
1623             result = baseObj->get(exec, property);
1624         }
1625         
1626         VM_CHECK_EXCEPTION();
1627         r[dst].u.jsValue = result;
1628         ++vPC;
1629         NEXT_OPCODE;
1630     }
1631     BEGIN_OPCODE(op_put_by_val) {
1632         /* put_by_val base(r) property(r) value(r)
1633
1634            Sets register value on register base as the property named
1635            by register property. Base is converted to object
1636            first. register property is nominally converted to string
1637            but numbers are treated more efficiently.
1638  
1639            Unlike many opcodes, this one does not write any output to
1640            the register file.
1641         */
1642         int base = (++vPC)->u.operand;
1643         int property = (++vPC)->u.operand;
1644         int value = (++vPC)->u.operand;
1645
1646         JSObject* baseObj = r[base].u.jsValue->toObject(exec);
1647         
1648         JSValue* subscript = r[property].u.jsValue;
1649
1650         uint32_t i;
1651         if (subscript->getUInt32(i))
1652             baseObj->put(exec, i, r[value].u.jsValue);
1653         else {
1654             Identifier property;
1655             if (subscript->isObject()) {
1656                 VM_CHECK_EXCEPTION(); // If toObject threw, we must not call toString, which may execute arbitrary code
1657                 property = Identifier(subscript->toString(exec));
1658             } else
1659                 property = Identifier(subscript->toString(exec));
1660
1661             VM_CHECK_EXCEPTION(); // This check is needed to prevent us from incorrectly calling a setter after an exception is thrown
1662             baseObj->put(exec, property, r[value].u.jsValue);
1663         }
1664         
1665         VM_CHECK_EXCEPTION();
1666         ++vPC;
1667         NEXT_OPCODE;
1668     }
1669     BEGIN_OPCODE(op_del_by_val) {
1670         /* del_by_val dst(r) base(r) property(r)
1671
1672            Converts register base to Object, deletes the property
1673            named by register property from the object, and writes a
1674            boolean indicating success (if true) or failure (if false)
1675            to register dst.
1676         */
1677         int dst = (++vPC)->u.operand;
1678         int base = (++vPC)->u.operand;
1679         int property = (++vPC)->u.operand;
1680
1681         JSObject* baseObj = r[base].u.jsValue->toObject(exec); // may throw
1682
1683         JSValue* subscript = r[property].u.jsValue;
1684         JSValue* result;
1685         uint32_t i;
1686         if (subscript->getUInt32(i))
1687             result = jsBoolean(baseObj->deleteProperty(exec, i));
1688         else {
1689             VM_CHECK_EXCEPTION(); // If toObject threw, we must not call toString, which may execute arbitrary code
1690             Identifier property(subscript->toString(exec));
1691             VM_CHECK_EXCEPTION();
1692             result = jsBoolean(baseObj->deleteProperty(exec, property));
1693         }
1694         
1695         VM_CHECK_EXCEPTION();
1696         r[dst].u.jsValue = result;
1697         ++vPC;
1698         NEXT_OPCODE;
1699     }
1700     BEGIN_OPCODE(op_put_by_index) {
1701         /* put_by_index base(r) property(n) value(r)
1702
1703            Sets register value on register base as the property named
1704            by the immediate number property. Base is converted to
1705            object first. register property is nominally converted to
1706            string but numbers are treated more efficiently.
1707  
1708            Unlike many opcodes, this one does not write any output to
1709            the register file.
1710
1711            This opcode is mainly used to initialize array literals.
1712         */
1713         int base = (++vPC)->u.operand;
1714         unsigned property = (++vPC)->u.operand;
1715         int value = (++vPC)->u.operand;
1716
1717         r[base].u.jsObject->put(exec, property, r[value].u.jsValue);
1718
1719         ++vPC;
1720         NEXT_OPCODE;
1721     }
1722     BEGIN_OPCODE(op_jmp) {
1723         /* jmp target(offset)
1724          
1725            Jumps unconditionally to offset target from the current
1726            instruction.
1727         */
1728         int target = (++vPC)->u.operand;
1729
1730         vPC += target;
1731         NEXT_OPCODE;
1732     }
1733     BEGIN_OPCODE(op_jtrue) {
1734         /* jtrue cond(r) target(offset)
1735          
1736            Jumps to offset target from the current instruction, if and
1737            only if register cond converts to boolean as true.
1738         */
1739         int cond = (++vPC)->u.operand;
1740         int target = (++vPC)->u.operand;
1741         if (r[cond].u.jsValue->toBoolean(exec)) {
1742             vPC += target;
1743             NEXT_OPCODE;
1744         }
1745
1746         ++vPC;
1747         NEXT_OPCODE;
1748     }
1749     BEGIN_OPCODE(op_jfalse) {
1750         /* jfalse cond(r) target(offset)
1751          
1752            Jumps to offset target from the current instruction, if and
1753            only if register cond converts to boolean as false.
1754         */
1755         int cond = (++vPC)->u.operand;
1756         int target = (++vPC)->u.operand;
1757         if (!r[cond].u.jsValue->toBoolean(exec)) {
1758             vPC += target;
1759             NEXT_OPCODE;
1760         }
1761
1762         ++vPC;
1763         NEXT_OPCODE;
1764     }
1765     BEGIN_OPCODE(op_new_func) {
1766         /* new_func dst(r) func(f)
1767
1768            Constructs a new Function instance from function func and
1769            the current scope chain using the original Function
1770            constructor, using the rules for function declarations, and
1771            puts the result in register dst.
1772         */
1773         int dst = (++vPC)->u.operand;
1774         int func = (++vPC)->u.operand;
1775
1776         r[dst].u.jsValue = codeBlock->functions[func]->makeFunction(exec, scopeChain);
1777
1778         ++vPC;
1779         NEXT_OPCODE;
1780     }
1781     BEGIN_OPCODE(op_new_func_exp) {
1782         /* new_func_exp dst(r) func(f)
1783
1784            Constructs a new Function instance from function func and
1785            the current scope chain using the original Function
1786            constructor, using the rules for function expressions, and
1787            puts the result in register dst.
1788         */
1789         int dst = (++vPC)->u.operand;
1790         int func = (++vPC)->u.operand;
1791
1792         r[dst].u.jsValue = codeBlock->functionExpressions[func]->makeFunction(exec, scopeChain);
1793
1794         ++vPC;
1795         NEXT_OPCODE;
1796     }
1797     BEGIN_OPCODE(op_call_eval) {
1798         int r0 = (++vPC)->u.operand;
1799         int r1 = (++vPC)->u.operand;
1800         int r2 = (++vPC)->u.operand;
1801         int argv = (++vPC)->u.operand;
1802         int argc = (++vPC)->u.operand;
1803
1804         JSValue* v = r[r1].u.jsValue;
1805         JSValue* base = r[r2].u.jsValue;
1806         
1807         if (base == scopeChain->globalObject() && v == scopeChain->globalObject()->evalFunction()) {
1808             int registerOffset = r - (*registerBase);
1809
1810             JSObject* thisObject = r[codeBlock->thisRegister].u.jsObject;
1811
1812             registerFile->setSafeForReentry(true);
1813             JSValue* result = eval(exec, thisObject, scopeChain, registerFile, r, argv, argc, exceptionValue);
1814             registerFile->setSafeForReentry(false);
1815             r = (*registerBase) + registerOffset;
1816
1817             if (exceptionValue)
1818                 goto vm_throw;
1819
1820             r[r0].u.jsValue = result;
1821             
1822             ++vPC;
1823             NEXT_OPCODE;
1824         }
1825         
1826         // We didn't find the blessed version of eval, so reset vPC and process
1827         // this instruction as a normal function call, supplying the proper 'this'
1828         // value.
1829         vPC -= 5;
1830         r[r2].u.jsValue = base->toObject(exec)->toThisObject(exec);
1831
1832 #if HAVE(COMPUTED_GOTO)
1833         // Hack around gcc performance quirk by performing an indirect goto
1834         // in order to set the vPC -- attempting to do so directly results in a
1835         // significant regression.
1836         goto *op_call_indirect; // indirect goto -> op_call
1837 #endif
1838         // fall through to op_call
1839     }
1840     BEGIN_OPCODE(op_call) {
1841         int r0 = (++vPC)->u.operand;
1842         int r1 = (++vPC)->u.operand;
1843         int r2 = (++vPC)->u.operand;
1844         int argv = (++vPC)->u.operand;
1845         int argc = (++vPC)->u.operand;
1846         
1847         JSValue* v = r[r1].u.jsValue;
1848         
1849         CallData callData;
1850         CallType callType = v->getCallData(callData);
1851         
1852         if (callType == CallTypeJS) {
1853             int registerOffset = r - (*registerBase);
1854             Register* callFrame = r + argv - CallFrameHeaderSize;
1855             int callFrameOffset = registerOffset + argv - CallFrameHeaderSize;
1856
1857             r[argv].u.jsValue = r2 == missingThisObjectMarker() ? exec->globalThisValue() : r[r2].u.jsValue; // "this" value
1858             initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, r0, argv, argc, 0, v);
1859
1860             ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
1861             FunctionBodyNode* functionBodyNode = callData.js.functionBody;
1862
1863             CodeBlock* newCodeBlock = &functionBodyNode->code(callDataScopeChain);
1864             r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, argv, argc, exceptionValue);
1865             if (UNLIKELY(exceptionValue != 0))
1866                 goto vm_throw;
1867
1868             codeBlock = newCodeBlock;
1869             exec->m_callFrameOffset = callFrameOffset;
1870             setScopeChain(exec, scopeChain, scopeChainForCall(functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
1871             k = codeBlock->jsValues.data();
1872             vPC = codeBlock->instructions.begin();
1873
1874             NEXT_OPCODE;
1875         }
1876
1877         if (callType == CallTypeNative) {
1878             int registerOffset = r - (*registerBase);
1879             
1880             r[argv].u.jsValue = r2 == missingThisObjectMarker() ? exec->globalThisValue() : (r[r2].u.jsValue)->toObject(exec); // "this" value
1881             JSObject* thisObj = static_cast<JSObject*>(r[argv].u.jsValue);
1882
1883             List args(&r[argv + 1].u.jsValue, argc - 1);
1884
1885             registerFile->setSafeForReentry(true);
1886             JSValue* returnValue = static_cast<JSObject*>(v)->callAsFunction(exec, thisObj, args);
1887             registerFile->setSafeForReentry(false);
1888
1889             r = (*registerBase) + registerOffset;
1890             r[r0].u.jsValue = returnValue;
1891
1892             VM_CHECK_EXCEPTION();
1893
1894             ++vPC;
1895             NEXT_OPCODE;
1896         }
1897
1898         ASSERT(callType == CallTypeNone);
1899
1900         exceptionValue = createNotAFunctionError(exec, v, 0);
1901         goto vm_throw;
1902     }
1903     BEGIN_OPCODE(op_ret) {
1904         int r1 = (++vPC)->u.operand;
1905
1906         CodeBlock* oldCodeBlock = codeBlock;
1907
1908         Register* callFrame = r - oldCodeBlock->numLocals - CallFrameHeaderSize;
1909         JSValue* returnValue = r[r1].u.jsValue;
1910
1911         if (JSActivation* activation = static_cast<JSActivation*>(callFrame[OptionalCalleeActivation].u.jsValue)) {
1912             ASSERT(!codeBlock->needsFullScopeChain || scopeChain->object == activation);
1913             ASSERT(activation->isActivationObject());
1914             activation->copyRegisters();
1915         }
1916
1917         if (codeBlock->needsFullScopeChain)
1918             scopeChain->deref();
1919
1920         if (callFrame[CalledAsConstructor].u.i && !returnValue->isObject()) {
1921             JSValue* thisObject = callFrame[CallFrameHeaderSize].u.jsValue;
1922             returnValue = thisObject;
1923         }
1924          
1925         codeBlock = callFrame[CallerCodeBlock].u.codeBlock;
1926         if (!codeBlock)
1927             return returnValue;
1928         
1929         k = codeBlock->jsValues.data();
1930         vPC = callFrame[ReturnVPC].u.vPC;
1931         setScopeChain(exec, scopeChain, callFrame[CallerScopeChain].u.scopeChain);
1932         int callerRegisterOffset = callFrame[CallerRegisterOffset].u.i;
1933         r = (*registerBase) + callerRegisterOffset;
1934         exec->m_callFrameOffset = callerRegisterOffset - codeBlock->numLocals - CallFrameHeaderSize;
1935         int r0 = callFrame[ReturnValueRegister].u.i;
1936         r[r0].u.jsValue = returnValue;
1937         
1938         NEXT_OPCODE;
1939     }
1940     BEGIN_OPCODE(op_construct) {
1941         int r0 = (++vPC)->u.operand;
1942         int r1 = (++vPC)->u.operand;
1943         int argv = (++vPC)->u.operand;
1944         int argc = (++vPC)->u.operand;
1945
1946         JSValue* v = r[r1].u.jsValue;
1947
1948         ConstructData constructData;
1949         ConstructType constructType = v->getConstructData(constructData);
1950
1951         // Removing this line of code causes a measurable regression on squirrelfish.
1952         JSObject* constructor = static_cast<JSObject*>(v);
1953
1954         if (constructType == ConstructTypeJS) {
1955             int registerOffset = r - (*registerBase);
1956             Register* callFrame = r + argv - CallFrameHeaderSize;
1957             int callFrameOffset = registerOffset + argv - CallFrameHeaderSize;
1958
1959             JSObject* prototype;
1960             JSValue* p = constructor->get(exec, exec->propertyNames().prototype);
1961             if (p->isObject())
1962                 prototype = static_cast<JSObject*>(p);
1963             else
1964                 prototype = scopeChain->globalObject()->objectPrototype();
1965             JSObject* newObject = new JSObject(prototype);
1966             r[argv].u.jsValue = newObject; // "this" value
1967
1968             initializeCallFrame(callFrame, codeBlock, vPC, scopeChain, registerOffset, r0, argv, argc, 1, constructor);
1969             
1970             ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
1971             FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
1972
1973             CodeBlock* newCodeBlock = &functionBodyNode->code(callDataScopeChain);
1974             r = slideRegisterWindowForCall(exec, newCodeBlock, registerFile, registerBase, registerOffset, argv, argc, exceptionValue);
1975             if (exceptionValue)
1976                 goto vm_throw;
1977
1978             codeBlock = newCodeBlock;
1979             exec->m_callFrameOffset = callFrameOffset;
1980             setScopeChain(exec, scopeChain, scopeChainForCall(functionBodyNode, codeBlock, callDataScopeChain, registerBase, r));
1981             k = codeBlock->jsValues.data();
1982             vPC = codeBlock->instructions.begin();
1983
1984             NEXT_OPCODE;
1985         }
1986
1987         if (constructType == ConstructTypeNative) {
1988             int registerOffset = r - (*registerBase);
1989
1990             List args(&r[argv + 1].u.jsValue, argc - 1);
1991             registerFile->setSafeForReentry(true);
1992             JSValue* returnValue = constructor->construct(exec, args);
1993             registerFile->setSafeForReentry(false);
1994         
1995             r = (*registerBase) + registerOffset;
1996             VM_CHECK_EXCEPTION();
1997             r[r0].u.jsValue = returnValue;
1998             
1999             ++vPC;
2000             NEXT_OPCODE;
2001         }
2002
2003         ASSERT(constructType == ConstructTypeNone);
2004
2005         exceptionValue = createNotAConstructorError(exec, v, 0);
2006         goto vm_throw;
2007     }
2008     BEGIN_OPCODE(op_push_scope) {
2009         /* push_scope scope(r)
2010
2011            Converts register scope to object, and pushes it onto the top
2012            of the current scope chain.
2013         */
2014         int scope = (++vPC)->u.operand;
2015         JSValue* v = r[scope].u.jsValue;
2016         JSObject* o = v->toObject(exec);
2017         VM_CHECK_EXCEPTION();
2018         
2019         setScopeChain(exec, scopeChain, scopeChain->push(o));
2020
2021         ++vPC;
2022         NEXT_OPCODE;
2023     }
2024     BEGIN_OPCODE(op_pop_scope) {
2025         /* pop_scope
2026
2027            Removes the top item from the current scope chain.
2028         */
2029         setScopeChain(exec, scopeChain, scopeChain->pop());
2030
2031         ++vPC;
2032         NEXT_OPCODE;
2033     }
2034     BEGIN_OPCODE(op_get_pnames) {
2035         /* get_pnames dst(r) base(r)
2036
2037            Creates a property name list for register base and puts it
2038            in register dst. This is not a true JavaScript value, just
2039            a synthetic value used to keep the iteration state in a
2040            register.
2041         */
2042         int dst = (++vPC)->u.operand;
2043         int base = (++vPC)->u.operand;
2044
2045         r[dst].u.jsPropertyNameIterator = JSPropertyNameIterator::create(exec, r[base].u.jsValue);
2046         ++vPC;
2047         NEXT_OPCODE;
2048     }
2049     BEGIN_OPCODE(op_next_pname) {
2050         /* next_pname dst(r) iter(r) target(offset)
2051
2052            Tries to copies the next name from property name list in
2053            register iter. If there are names left, then copies one to
2054            register dst, and jumps to offset target. If there are none
2055            left, invalidates the iterator and continues to the next
2056            instruction.
2057         */
2058         int dst = (++vPC)->u.operand;
2059         int iter = (++vPC)->u.operand;
2060         int target = (++vPC)->u.operand;
2061
2062         JSPropertyNameIterator* it = r[iter].u.jsPropertyNameIterator;
2063         if (JSValue* temp = it->next(exec)) {
2064             r[dst].u.jsValue = temp;
2065             vPC += target;
2066             NEXT_OPCODE;
2067         }
2068         it->invalidate();
2069
2070         ++vPC;
2071         NEXT_OPCODE;
2072     }
2073     BEGIN_OPCODE(op_jmp_scopes) {
2074         /* jmp_scopes count(n) target(offset)
2075
2076            Removes the a number of items from the current scope chain
2077            specified by immediate number count, then jumps to offset
2078            target.
2079         */
2080         int count = (++vPC)->u.operand;
2081         int target = (++vPC)->u.operand;
2082         
2083         ScopeChainNode* tmp = scopeChain;
2084         while (count--)
2085             tmp = tmp->pop();
2086         setScopeChain(exec, scopeChain, tmp);
2087             
2088         vPC += target;
2089         NEXT_OPCODE;
2090     }
2091     BEGIN_OPCODE(op_catch) {
2092         ASSERT(exceptionValue);
2093         ASSERT(!exec->hadException());
2094         int r0 = (++vPC)->u.operand;
2095         r[r0].u.jsValue = exceptionValue;
2096         exceptionValue = 0;
2097         ++vPC;
2098         NEXT_OPCODE;
2099     }
2100     BEGIN_OPCODE(op_throw) {
2101         int e = (++vPC)->u.operand;
2102         exceptionValue = r[e].u.jsValue;
2103         handlerVPC = throwException(exec, exceptionValue, registerBase, vPC, codeBlock, k, scopeChain, r);
2104         if (!handlerVPC) {
2105             *exception = exceptionValue;
2106             return jsNull();
2107         }
2108
2109 #if HAVE(COMPUTED_GOTO)
2110         // Hack around gcc performance quirk by performing an indirect goto
2111         // in order to set the vPC -- attempting to do so directly results in a
2112         // significant regression.
2113         goto *op_throw_end_indirect; // indirect goto -> op_throw_end
2114     }
2115     op_throw_end: {
2116 #endif
2117
2118         vPC = handlerVPC;
2119         NEXT_OPCODE;
2120     }
2121     BEGIN_OPCODE(op_new_error) {
2122         /* new_error dst(r) type(n) message(k)
2123
2124            Constructs a new Error instance using the original
2125            constructor, using immediate number n as the type and
2126            constant message as the message string. The result is
2127            written to register dst.
2128         */
2129         int dst = (++vPC)->u.operand;
2130         int type = (++vPC)->u.operand;
2131         int message = (++vPC)->u.operand;
2132         
2133         r[dst].u.jsValue = Error::create(exec, (ErrorType)type, k[message]->toString(exec), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceId(), codeBlock->ownerNode->sourceURL());
2134         
2135         ++vPC;
2136         NEXT_OPCODE;
2137     }
2138     BEGIN_OPCODE(op_end) {
2139         if (codeBlock->needsFullScopeChain) {
2140             ASSERT(scopeChain->refCount > 1);
2141             scopeChain->deref();
2142         }
2143         int r0 = (++vPC)->u.operand;
2144         return r[r0].u.jsValue;
2145     }
2146     BEGIN_OPCODE(op_put_getter) {
2147         /* put_getter base(r) property(id) function(r)
2148          
2149            Sets register function on register base as the getter named
2150            by identifier property. Base and function are assumed to be
2151            objects as this op should only be used for getters defined
2152            in object literal form.
2153          
2154            Unlike many opcodes, this one does not write any output to
2155            the register file.
2156         */
2157         int base = (++vPC)->u.operand;
2158         int property = (++vPC)->u.operand;
2159         int function = (++vPC)->u.operand;
2160         
2161         ASSERT(r[base].u.jsValue->isObject());
2162         JSObject* baseObj = static_cast<JSObject*>(r[base].u.jsValue);
2163         Identifier& ident = codeBlock->identifiers[property];
2164         ASSERT(r[function].u.jsValue->isObject());
2165         baseObj->defineGetter(exec, ident, static_cast<JSObject* >(r[function].u.jsValue));
2166
2167         ++vPC;
2168         NEXT_OPCODE;
2169     }
2170     BEGIN_OPCODE(op_put_setter) {
2171         /* put_setter base(r) property(id) function(r)
2172          
2173            Sets register function on register base as the setter named
2174            by identifier property. Base and function are assumed to be
2175            objects as this op should only be used for setters defined
2176            in object literal form.
2177          
2178            Unlike many opcodes, this one does not write any output to
2179            the register file.
2180         */
2181         int base = (++vPC)->u.operand;
2182         int property = (++vPC)->u.operand;
2183         int function = (++vPC)->u.operand;
2184         
2185         ASSERT(r[base].u.jsValue->isObject());
2186         JSObject* baseObj = static_cast<JSObject*>(r[base].u.jsValue);
2187         Identifier& ident = codeBlock->identifiers[property];
2188         ASSERT(r[function].u.jsValue->isObject());
2189         baseObj->defineSetter(exec, ident, static_cast<JSObject* >(r[function].u.jsValue));
2190         
2191         ++vPC;
2192         NEXT_OPCODE;
2193     }
2194     BEGIN_OPCODE(op_jsr) {
2195         /* jsr retAddrDst(r) target(offset)
2196          
2197            Places the address of the next instruction into the retAddrDst
2198            register and jumps to offset target from the current instruction.
2199         */
2200         int retAddrDst = (++vPC)->u.operand;
2201         int target = (++vPC)->u.operand;
2202         r[retAddrDst].u.vPC = vPC + 1;
2203
2204         vPC += target;
2205         NEXT_OPCODE;
2206     }
2207     BEGIN_OPCODE(op_sret) {
2208         /* sret retAddrSrc(r)
2209          
2210          Jumps to the address stored in the retAddrSrc register. This
2211          differs from op_jmp because the target address is stored in a
2212          register, not as an immediate.
2213         */
2214         int retAddrSrc = (++vPC)->u.operand;
2215         vPC = r[retAddrSrc].u.vPC;
2216         NEXT_OPCODE;
2217     }
2218     BEGIN_OPCODE(op_debug) {
2219         /* debug debugHookID(n) firstLine(n) lastLine(n)
2220          
2221          Notifies the debugger of the current state of execution:
2222          didEnterCallFrame; willLeaveCallFrame; or willExecuteStatement.
2223          
2224          This opcode is only generated while the debugger is attached.
2225         */
2226
2227         int registerOffset = r - (*registerBase);
2228         registerFile->setSafeForReentry(true);
2229         debug(exec, vPC, codeBlock, scopeChain, registerBase, r);
2230         registerFile->setSafeForReentry(false);
2231         r = (*registerBase) + registerOffset;
2232
2233         vPC += 4;
2234         NEXT_OPCODE;
2235     }
2236     vm_throw: {
2237         exec->clearException();
2238         handlerVPC = throwException(exec, exceptionValue, registerBase, vPC, codeBlock, k, scopeChain, r);
2239         if (!handlerVPC) {
2240             *exception = exceptionValue;
2241             return jsNull();
2242         }
2243         vPC = handlerVPC;
2244         NEXT_OPCODE;
2245     }          
2246     }
2247     #undef NEXT_OPCODE
2248     #undef BEGIN_OPCODE
2249     #undef VM_CHECK_EXCEPTION
2250 }
2251
2252 JSValue* Machine::retrieveArguments(ExecState* exec, FunctionImp* function) const
2253 {
2254     Register** registerBase;
2255     int callFrameOffset;
2256
2257     if (!getCallFrame(exec, function, registerBase, callFrameOffset))
2258         return jsNull();
2259
2260     Register* callFrame = (*registerBase) + callFrameOffset;
2261     JSActivation* activation = static_cast<JSActivation*>(callFrame[OptionalCalleeActivation].u.jsValue);
2262     if (!activation) {
2263         CodeBlock* codeBlock = &function->body->generatedCode();
2264         activation = new JSActivation(function->body, registerBase, callFrameOffset + CallFrameHeaderSize + codeBlock->numLocals);
2265         callFrame[OptionalCalleeActivation].u.jsValue = activation;
2266     }
2267
2268     return activation->get(exec, exec->propertyNames().arguments);
2269 }
2270
2271 JSValue* Machine::retrieveCaller(ExecState* exec, FunctionImp* function) const
2272 {
2273     Register** registerBase;
2274     int callFrameOffset;
2275
2276     if (!getCallFrame(exec, function, registerBase, callFrameOffset))
2277         return jsNull();
2278
2279     int callerFrameOffset;
2280     if (!getCallerFunctionOffset(registerBase, callFrameOffset, callerFrameOffset))
2281         return jsNull();
2282
2283     Register* callerFrame = (*registerBase) + callerFrameOffset;
2284     ASSERT(callerFrame[Callee].u.jsValue);
2285     return callerFrame[Callee].u.jsValue;
2286 }
2287
2288 bool Machine::getCallFrame(ExecState* exec, FunctionImp* function, Register**& registerBase, int& callFrameOffset) const
2289 {
2290     callFrameOffset = exec->m_callFrameOffset;
2291
2292     while (1) {
2293         while (callFrameOffset < 0) {
2294             exec = exec->m_prev;
2295             if (!exec)
2296                 return false;
2297             callFrameOffset = exec->m_callFrameOffset;
2298         }
2299
2300         registerBase = exec->m_registerFile->basePointer();
2301         Register* callFrame = (*registerBase) + callFrameOffset;
2302         if (callFrame[Callee].u.jsValue == function)
2303             return true;
2304
2305         if (!getCallerFunctionOffset(registerBase, callFrameOffset, callFrameOffset))
2306             callFrameOffset = -1;
2307     }
2308 }
2309
2310 void Machine::getFunctionAndArguments(Register** registerBase, Register* callFrame, FunctionImp*& function, Register*& argv, int& argc)
2311 {
2312     function = static_cast<FunctionImp*>(callFrame[Callee].u.jsValue);
2313     ASSERT(function->inherits(&FunctionImp::info));
2314
2315     argv = (*registerBase) + callFrame[CallerRegisterOffset].u.i + callFrame[ArgumentStartRegister].u.i + 1; // skip "this"
2316     argc = callFrame[ArgumentCount].u.i - 1; // skip "this"
2317 }
2318
2319 } // namespace KJS