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