793500e9cd705471fd3081f32d188a2820c1db43
[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 "Arguments.h"
34 #include "BatchedTransitionOptimizer.h"
35 #include "CodeBlock.h"
36 #include "DebuggerCallFrame.h"
37 #include "ExceptionHelpers.h"
38 #include "ExecState.h"
39 #include "GlobalEvalFunction.h"
40 #include "JSActivation.h"
41 #include "JSArray.h"
42 #include "JSFunction.h"
43 #include "JSNotAnObject.h"
44 #include "JSPropertyNameIterator.h"
45 #include "JSStaticScopeObject.h"
46 #include "JSString.h"
47 #include "ObjectPrototype.h"
48 #include "Parser.h"
49 #include "Profiler.h"
50 #include "RegExpObject.h"
51 #include "RegExpPrototype.h"
52 #include "Register.h"
53 #include "collector.h"
54 #include "debugger.h"
55 #include "operations.h"
56 #include "SamplingTool.h"
57 #include <stdio.h>
58
59 #if ENABLE(CTI)
60 #include "CTI.h"
61 #endif
62
63 #if PLATFORM(DARWIN)
64 #include <mach/mach.h>
65 #endif
66
67 #if HAVE(SYS_TIME_H)
68 #include <sys/time.h>
69 #endif
70
71 #if PLATFORM(WIN_OS)
72 #include <windows.h>
73 #endif
74
75 #if PLATFORM(QT)
76 #include <QDateTime>
77 #endif
78
79 using namespace std;
80
81 namespace JSC {
82
83 // Preferred number of milliseconds between each timeout check
84 static const int preferredScriptCheckTimeInterval = 1000;
85
86 #if HAVE(COMPUTED_GOTO)
87 static void* op_throw_end_indirect;
88 static void* op_call_indirect;
89 #endif
90
91 #if ENABLE(CTI)
92
93 static ALWAYS_INLINE Instruction* vPCForPC(CodeBlock* codeBlock, void* pc)
94 {
95     if (pc >= codeBlock->instructions.begin() && pc < codeBlock->instructions.end())
96         return static_cast<Instruction*>(pc);
97
98     ASSERT(codeBlock->ctiReturnAddressVPCMap.contains(pc));
99     unsigned vPCIndex = codeBlock->ctiReturnAddressVPCMap.get(pc);
100     return codeBlock->instructions.begin() + vPCIndex;
101 }
102
103 #else // ENABLE(CTI)
104
105 static ALWAYS_INLINE Instruction* vPCForPC(CodeBlock*, void* pc)
106 {
107     return static_cast<Instruction*>(pc);
108 }
109
110 #endif // ENABLE(CTI)
111
112 // Returns the depth of the scope chain within a given call frame.
113 static int depth(CodeBlock* codeBlock, ScopeChain& sc)
114 {
115     if (!codeBlock->needsFullScopeChain)
116         return 0;
117     int scopeDepth = 0;
118     ScopeChainIterator iter = sc.begin();
119     ScopeChainIterator end = sc.end();
120     while (!(*iter)->isObject(&JSActivation::info)) {
121         ++iter;
122         if (iter == end)
123             break;
124         ++scopeDepth;
125     }
126     return scopeDepth;
127 }
128
129 // FIXME: This operation should be called "getNumber", not "isNumber" (as it is in JSValue.h).
130 // FIXME: There's no need to have a "slow" version of this. All versions should be fast.
131 static ALWAYS_INLINE bool fastIsNumber(JSValuePtr value, double& arg)
132 {
133     if (JSImmediate::isNumber(value))
134         arg = JSImmediate::getTruncatedInt32(value);
135     else if (LIKELY(!JSImmediate::isImmediate(value)) && LIKELY(Heap::isNumber(asCell(value))))
136         arg = asNumberCell(value)->value();
137     else
138         return false;
139     return true;
140 }
141
142 // FIXME: Why doesn't JSValuePtr::toInt32 have the Heap::isNumber optimization?
143 static bool fastToInt32(JSValuePtr value, int32_t& arg)
144 {
145     if (JSImmediate::isNumber(value))
146         arg = JSImmediate::getTruncatedInt32(value);
147     else if (LIKELY(!JSImmediate::isImmediate(value)) && LIKELY(Heap::isNumber(asCell(value))))
148         arg = asNumberCell(value)->toInt32();
149     else
150         return false;
151     return true;
152 }
153
154 static ALWAYS_INLINE bool fastToUInt32(JSValuePtr value, uint32_t& arg)
155 {
156     if (JSImmediate::isNumber(value)) {
157         if (JSImmediate::getTruncatedUInt32(value, arg))
158             return true;
159         bool scratch;
160         arg = toUInt32SlowCase(JSImmediate::getTruncatedInt32(value), scratch);
161         return true;
162     } else if (!JSImmediate::isImmediate(value) && Heap::isNumber(asCell(value)))
163         arg = asNumberCell(value)->toUInt32();
164     else
165         return false;
166     return true;
167 }
168
169 static inline bool jsLess(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
170 {
171     if (JSImmediate::areBothImmediateNumbers(v1, v2))
172         return JSImmediate::getTruncatedInt32(v1) < JSImmediate::getTruncatedInt32(v2);
173
174     double n1;
175     double n2;
176     if (fastIsNumber(v1, n1) && fastIsNumber(v2, n2))
177         return n1 < n2;
178
179     Machine* machine = callFrame->machine();
180     if (machine->isJSString(v1) && machine->isJSString(v2))
181         return asString(v1)->value() < asString(v2)->value();
182
183     JSValuePtr p1;
184     JSValuePtr p2;
185     bool wasNotString1 = v1->getPrimitiveNumber(callFrame, n1, p1);
186     bool wasNotString2 = v2->getPrimitiveNumber(callFrame, n2, p2);
187
188     if (wasNotString1 | wasNotString2)
189         return n1 < n2;
190
191     return asString(p1)->value() < asString(p2)->value();
192 }
193
194 static inline bool jsLessEq(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
195 {
196     if (JSImmediate::areBothImmediateNumbers(v1, v2))
197         return JSImmediate::getTruncatedInt32(v1) <= JSImmediate::getTruncatedInt32(v2);
198
199     double n1;
200     double n2;
201     if (fastIsNumber(v1, n1) && fastIsNumber(v2, n2))
202         return n1 <= n2;
203
204     Machine* machine = callFrame->machine();
205     if (machine->isJSString(v1) && machine->isJSString(v2))
206         return !(asString(v2)->value() < asString(v1)->value());
207
208     JSValuePtr p1;
209     JSValuePtr p2;
210     bool wasNotString1 = v1->getPrimitiveNumber(callFrame, n1, p1);
211     bool wasNotString2 = v2->getPrimitiveNumber(callFrame, n2, p2);
212
213     if (wasNotString1 | wasNotString2)
214         return n1 <= n2;
215
216     return !(asString(p2)->value() < asString(p1)->value());
217 }
218
219 static NEVER_INLINE JSValuePtr jsAddSlowCase(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
220 {
221     // exception for the Date exception in defaultValue()
222     JSValuePtr p1 = v1->toPrimitive(callFrame);
223     JSValuePtr p2 = v2->toPrimitive(callFrame);
224
225     if (p1->isString() || p2->isString()) {
226         RefPtr<UString::Rep> value = concatenate(p1->toString(callFrame).rep(), p2->toString(callFrame).rep());
227         if (!value)
228             return throwOutOfMemoryError(callFrame);
229         return jsString(callFrame, value.release());
230     }
231
232     return jsNumber(callFrame, p1->toNumber(callFrame) + p2->toNumber(callFrame));
233 }
234
235 // Fast-path choices here are based on frequency data from SunSpider:
236 //    <times> Add case: <t1> <t2>
237 //    ---------------------------
238 //    5626160 Add case: 3 3 (of these, 3637690 are for immediate values)
239 //    247412  Add case: 5 5
240 //    20900   Add case: 5 6
241 //    13962   Add case: 5 3
242 //    4000    Add case: 3 5
243
244 static ALWAYS_INLINE JSValuePtr jsAdd(CallFrame* callFrame, JSValuePtr v1, JSValuePtr v2)
245 {
246     double left;
247     double right = 0.0;
248
249     bool rightIsNumber = fastIsNumber(v2, right);
250     if (rightIsNumber && fastIsNumber(v1, left))
251         return jsNumber(callFrame, left + right);
252     
253     bool leftIsString = v1->isString();
254     if (leftIsString && v2->isString()) {
255         RefPtr<UString::Rep> value = concatenate(asString(v1)->value().rep(), asString(v2)->value().rep());
256         if (!value)
257             return throwOutOfMemoryError(callFrame);
258         return jsString(callFrame, value.release());
259     }
260
261     if (rightIsNumber & leftIsString) {
262         RefPtr<UString::Rep> value = JSImmediate::isImmediate(v2) ?
263             concatenate(asString(v1)->value().rep(), JSImmediate::getTruncatedInt32(v2)) :
264             concatenate(asString(v1)->value().rep(), right);
265
266         if (!value)
267             return throwOutOfMemoryError(callFrame);
268         return jsString(callFrame, value.release());
269     }
270
271     // All other cases are pretty uncommon
272     return jsAddSlowCase(callFrame, v1, v2);
273 }
274
275 static JSValuePtr jsTypeStringForValue(CallFrame* callFrame, JSValuePtr v)
276 {
277     if (v->isUndefined())
278         return jsNontrivialString(callFrame, "undefined");
279     if (v->isBoolean())
280         return jsNontrivialString(callFrame, "boolean");
281     if (v->isNumber())
282         return jsNontrivialString(callFrame, "number");
283     if (v->isString())
284         return jsNontrivialString(callFrame, "string");
285     if (v->isObject()) {
286         // Return "undefined" for objects that should be treated
287         // as null when doing comparisons.
288         if (asObject(v)->structureID()->typeInfo().masqueradesAsUndefined())
289             return jsNontrivialString(callFrame, "undefined");
290         CallData callData;
291         if (asObject(v)->getCallData(callData) != CallTypeNone)
292             return jsNontrivialString(callFrame, "function");
293     }
294     return jsNontrivialString(callFrame, "object");
295 }
296
297 static bool jsIsObjectType(JSValuePtr v)
298 {
299     if (JSImmediate::isImmediate(v))
300         return v->isNull();
301
302     JSType type = asCell(v)->structureID()->typeInfo().type();
303     if (type == NumberType || type == StringType)
304         return false;
305     if (type == ObjectType) {
306         if (asObject(v)->structureID()->typeInfo().masqueradesAsUndefined())
307             return false;
308         CallData callData;
309         if (asObject(v)->getCallData(callData) != CallTypeNone)
310             return false;
311     }
312     return true;
313 }
314
315 static bool jsIsFunctionType(JSValuePtr v)
316 {
317     if (v->isObject()) {
318         CallData callData;
319         if (asObject(v)->getCallData(callData) != CallTypeNone)
320             return true;
321     }
322     return false;
323 }
324
325 NEVER_INLINE bool Machine::resolve(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
326 {
327     int dst = (vPC + 1)->u.operand;
328     int property = (vPC + 2)->u.operand;
329
330     ScopeChainNode* scopeChain = callFrame->scopeChain();
331     ScopeChainIterator iter = scopeChain->begin();
332     ScopeChainIterator end = scopeChain->end();
333     ASSERT(iter != end);
334
335     CodeBlock* codeBlock = callFrame->codeBlock();
336     Identifier& ident = codeBlock->identifiers[property];
337     do {
338         JSObject* o = *iter;
339         PropertySlot slot(o);
340         if (o->getPropertySlot(callFrame, ident, slot)) {
341             JSValuePtr result = slot.getValue(callFrame, ident);
342             exceptionValue = callFrame->globalData().exception;
343             if (exceptionValue)
344                 return false;
345             callFrame[dst] = result;
346             return true;
347         }
348     } while (++iter != end);
349     exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
350     return false;
351 }
352
353 NEVER_INLINE bool Machine::resolveSkip(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
354 {
355     CodeBlock* codeBlock = callFrame->codeBlock();
356
357     int dst = (vPC + 1)->u.operand;
358     int property = (vPC + 2)->u.operand;
359     int skip = (vPC + 3)->u.operand + codeBlock->needsFullScopeChain;
360
361     ScopeChainNode* scopeChain = callFrame->scopeChain();
362     ScopeChainIterator iter = scopeChain->begin();
363     ScopeChainIterator end = scopeChain->end();
364     ASSERT(iter != end);
365     while (skip--) {
366         ++iter;
367         ASSERT(iter != end);
368     }
369     Identifier& ident = codeBlock->identifiers[property];
370     do {
371         JSObject* o = *iter;
372         PropertySlot slot(o);
373         if (o->getPropertySlot(callFrame, ident, slot)) {
374             JSValuePtr result = slot.getValue(callFrame, ident);
375             exceptionValue = callFrame->globalData().exception;
376             if (exceptionValue)
377                 return false;
378             callFrame[dst] = result;
379             return true;
380         }
381     } while (++iter != end);
382     exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
383     return false;
384 }
385
386 NEVER_INLINE bool Machine::resolveGlobal(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
387 {
388     int dst = (vPC + 1)->u.operand;
389     JSGlobalObject* globalObject = static_cast<JSGlobalObject*>((vPC + 2)->u.jsCell);
390     ASSERT(globalObject->isGlobalObject());
391     int property = (vPC + 3)->u.operand;
392     StructureID* structureID = (vPC + 4)->u.structureID;
393     int offset = (vPC + 5)->u.operand;
394
395     if (structureID == globalObject->structureID()) {
396         callFrame[dst] = globalObject->getDirectOffset(offset);
397         return true;
398     }
399
400     CodeBlock* codeBlock = callFrame->codeBlock();
401     Identifier& ident = codeBlock->identifiers[property];
402     PropertySlot slot(globalObject);
403     if (globalObject->getPropertySlot(callFrame, ident, slot)) {
404         JSValuePtr result = slot.getValue(callFrame, ident);
405         if (slot.isCacheable()) {
406             if (vPC[4].u.structureID)
407                 vPC[4].u.structureID->deref();
408             globalObject->structureID()->ref();
409             vPC[4] = globalObject->structureID();
410             vPC[5] = slot.cachedOffset();
411             callFrame[dst] = result;
412             return true;
413         }
414
415         exceptionValue = callFrame->globalData().exception;
416         if (exceptionValue)
417             return false;
418         callFrame[dst] = result;
419         return true;
420     }
421
422     exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
423     return false;
424 }
425
426 static ALWAYS_INLINE JSValuePtr inlineResolveBase(CallFrame* callFrame, Identifier& property, ScopeChainNode* scopeChain)
427 {
428     ScopeChainIterator iter = scopeChain->begin();
429     ScopeChainIterator next = iter;
430     ++next;
431     ScopeChainIterator end = scopeChain->end();
432     ASSERT(iter != end);
433
434     PropertySlot slot;
435     JSObject* base;
436     while (true) {
437         base = *iter;
438         if (next == end || base->getPropertySlot(callFrame, property, slot))
439             return base;
440
441         iter = next;
442         ++next;
443     }
444
445     ASSERT_NOT_REACHED();
446     return noValue();
447 }
448
449 NEVER_INLINE void Machine::resolveBase(CallFrame* callFrame, Instruction* vPC)
450 {
451     int dst = (vPC + 1)->u.operand;
452     int property = (vPC + 2)->u.operand;
453     callFrame[dst] = inlineResolveBase(callFrame, callFrame->codeBlock()->identifiers[property], callFrame->scopeChain());
454 }
455
456 NEVER_INLINE bool Machine::resolveBaseAndProperty(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
457 {
458     int baseDst = (vPC + 1)->u.operand;
459     int propDst = (vPC + 2)->u.operand;
460     int property = (vPC + 3)->u.operand;
461
462     ScopeChainNode* scopeChain = callFrame->scopeChain();
463     ScopeChainIterator iter = scopeChain->begin();
464     ScopeChainIterator end = scopeChain->end();
465
466     // FIXME: add scopeDepthIsZero optimization
467
468     ASSERT(iter != end);
469
470     CodeBlock* codeBlock = callFrame->codeBlock();
471     Identifier& ident = codeBlock->identifiers[property];
472     JSObject* base;
473     do {
474         base = *iter;
475         PropertySlot slot(base);
476         if (base->getPropertySlot(callFrame, ident, slot)) {
477             JSValuePtr result = slot.getValue(callFrame, ident);
478             exceptionValue = callFrame->globalData().exception;
479             if (exceptionValue)
480                 return false;
481             callFrame[propDst] = result;
482             callFrame[baseDst] = base;
483             return true;
484         }
485         ++iter;
486     } while (iter != end);
487
488     exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
489     return false;
490 }
491
492 NEVER_INLINE bool Machine::resolveBaseAndFunc(CallFrame* callFrame, Instruction* vPC, JSValuePtr& exceptionValue)
493 {
494     int baseDst = (vPC + 1)->u.operand;
495     int funcDst = (vPC + 2)->u.operand;
496     int property = (vPC + 3)->u.operand;
497
498     ScopeChainNode* scopeChain = callFrame->scopeChain();
499     ScopeChainIterator iter = scopeChain->begin();
500     ScopeChainIterator end = scopeChain->end();
501
502     // FIXME: add scopeDepthIsZero optimization
503
504     ASSERT(iter != end);
505
506     CodeBlock* codeBlock = callFrame->codeBlock();
507     Identifier& ident = codeBlock->identifiers[property];
508     JSObject* base;
509     do {
510         base = *iter;
511         PropertySlot slot(base);
512         if (base->getPropertySlot(callFrame, ident, slot)) {            
513             // ECMA 11.2.3 says that if we hit an activation the this value should be null.
514             // However, section 10.2.3 says that in the case where the value provided
515             // by the caller is null, the global object should be used. It also says
516             // that the section does not apply to internal functions, but for simplicity
517             // of implementation we use the global object anyway here. This guarantees
518             // that in host objects you always get a valid object for this.
519             // We also handle wrapper substitution for the global object at the same time.
520             JSObject* thisObj = base->toThisObject(callFrame);
521             JSValuePtr result = slot.getValue(callFrame, ident);
522             exceptionValue = callFrame->globalData().exception;
523             if (exceptionValue)
524                 return false;
525
526             callFrame[baseDst] = thisObj;
527             callFrame[funcDst] = result;
528             return true;
529         }
530         ++iter;
531     } while (iter != end);
532
533     exceptionValue = createUndefinedVariableError(callFrame, ident, vPC, codeBlock);
534     return false;
535 }
536
537 ALWAYS_INLINE CallFrame* Machine::slideRegisterWindowForCall(CodeBlock* newCodeBlock, RegisterFile* registerFile, CallFrame* callFrame, size_t registerOffset, int argc)
538 {
539     Register* r = callFrame->registers();
540     Register* newEnd = r + registerOffset + newCodeBlock->numCalleeRegisters;
541
542     if (LIKELY(argc == newCodeBlock->numParameters)) { // correct number of arguments
543         if (UNLIKELY(!registerFile->grow(newEnd)))
544             return 0;
545         r += registerOffset;
546     } else if (argc < newCodeBlock->numParameters) { // too few arguments -- fill in the blanks
547         size_t omittedArgCount = newCodeBlock->numParameters - argc;
548         registerOffset += omittedArgCount;
549         newEnd += omittedArgCount;
550         if (!registerFile->grow(newEnd))
551             return 0;
552         r += registerOffset;
553
554         Register* argv = r - RegisterFile::CallFrameHeaderSize - omittedArgCount;
555         for (size_t i = 0; i < omittedArgCount; ++i)
556             argv[i] = jsUndefined();
557     } else { // too many arguments -- copy expected arguments, leaving the extra arguments behind
558         size_t numParameters = newCodeBlock->numParameters;
559         registerOffset += numParameters;
560         newEnd += numParameters;
561
562         if (!registerFile->grow(newEnd))
563             return 0;
564         r += registerOffset;
565
566         Register* argv = r - RegisterFile::CallFrameHeaderSize - numParameters - argc;
567         for (size_t i = 0; i < numParameters; ++i)
568             argv[i + argc] = argv[i];
569     }
570
571     return CallFrame::create(r);
572 }
573
574 static NEVER_INLINE bool isNotObject(CallFrame* callFrame, bool forInstanceOf, CodeBlock* codeBlock, const Instruction* vPC, JSValuePtr value, JSValuePtr& exceptionData)
575 {
576     if (value->isObject())
577         return false;
578     exceptionData = createInvalidParamError(callFrame, forInstanceOf ? "instanceof" : "in" , value, vPC, codeBlock);
579     return true;
580 }
581
582 NEVER_INLINE JSValuePtr Machine::callEval(CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, RegisterFile* registerFile, int argv, int argc, JSValuePtr& exceptionValue)
583 {
584     if (argc < 2)
585         return jsUndefined();
586
587     JSValuePtr program = callFrame[argv + 1].jsValue(callFrame);
588
589     if (!program->isString())
590         return program;
591
592     UString programSource = asString(program)->value();
593
594     CodeBlock* codeBlock = callFrame->codeBlock();
595     RefPtr<EvalNode> evalNode = codeBlock->evalCodeCache.get(callFrame, programSource, scopeChain, exceptionValue);
596
597     JSValuePtr result = jsUndefined();
598     if (evalNode)
599         result = callFrame->globalData().machine->execute(evalNode.get(), callFrame, thisObj, callFrame->registers() - registerFile->start() + argv + 1 + RegisterFile::CallFrameHeaderSize, scopeChain, &exceptionValue);
600
601     return result;
602 }
603
604 Machine::Machine()
605     : m_sampler(0)
606 #if ENABLE(CTI)
607     , m_ctiArrayLengthTrampoline(0)
608     , m_ctiStringLengthTrampoline(0)
609     , m_jitCodeBuffer(new JITCodeBuffer(1024 * 1024))
610 #endif
611     , m_reentryDepth(0)
612     , m_timeoutTime(0)
613     , m_timeAtLastCheckTimeout(0)
614     , m_timeExecuting(0)
615     , m_timeoutCheckCount(0)
616     , m_ticksUntilNextTimeoutCheck(initialTickCountThreshold)
617 {
618     initTimeout();
619     privateExecute(InitializeAndReturn, 0, 0, 0);
620     
621     // Bizarrely, calling fastMalloc here is faster than allocating space on the stack.
622     void* storage = fastMalloc(sizeof(CollectorBlock));
623
624     JSCell* jsArray = new (storage) JSArray(JSArray::createStructureID(jsNull()));
625     m_jsArrayVptr = jsArray->vptr();
626     jsArray->~JSCell();
627
628     JSCell* jsString = new (storage) JSString(JSString::VPtrStealingHack);
629     m_jsStringVptr = jsString->vptr();
630     jsString->~JSCell();
631
632     JSCell* jsFunction = new (storage) JSFunction(JSFunction::createStructureID(jsNull()));
633     m_jsFunctionVptr = jsFunction->vptr();
634     jsFunction->~JSCell();
635     
636     fastFree(storage);
637 }
638
639 Machine::~Machine()
640 {
641 #if ENABLE(CTI)
642     if (m_ctiArrayLengthTrampoline)
643         fastFree(m_ctiArrayLengthTrampoline);
644     if (m_ctiStringLengthTrampoline)
645         fastFree(m_ctiStringLengthTrampoline);
646 #endif
647 }
648
649 #ifndef NDEBUG
650
651 void Machine::dumpCallFrame(const RegisterFile* registerFile, CallFrame* callFrame)
652 {
653     JSGlobalObject* globalObject = callFrame->scopeChain()->globalObject();
654
655     CodeBlock* codeBlock = callFrame->codeBlock();
656     codeBlock->dump(globalObject->globalExec());
657
658     dumpRegisters(registerFile, callFrame);
659 }
660
661 void Machine::dumpRegisters(const RegisterFile* registerFile, CallFrame* callFrame)
662 {
663     printf("Register frame: \n\n");
664     printf("----------------------------------------------------\n");
665     printf("            use            |   address  |   value   \n");
666     printf("----------------------------------------------------\n");
667
668     CodeBlock* codeBlock = callFrame->codeBlock();
669     const Register* it;
670     const Register* end;
671
672     if (codeBlock->codeType == GlobalCode) {
673         it = registerFile->lastGlobal();
674         end = it + registerFile->numGlobals();
675         while (it != end) {
676             printf("[global var]               | %10p | %10p \n", it, (*it).v());
677             ++it;
678         }
679         printf("----------------------------------------------------\n");
680     }
681     
682     it = callFrame->registers() - RegisterFile::CallFrameHeaderSize - codeBlock->numParameters;
683     printf("[this]                     | %10p | %10p \n", it, (*it).v()); ++it;
684     end = it + max(codeBlock->numParameters - 1, 0); // - 1 to skip "this"
685     if (it != end) {
686         do {
687             printf("[param]                    | %10p | %10p \n", it, (*it).v());
688             ++it;
689         } while (it != end);
690     }
691     printf("----------------------------------------------------\n");
692
693     printf("[CodeBlock]                | %10p | %10p \n", it, (*it).v()); ++it;
694     printf("[ScopeChain]               | %10p | %10p \n", it, (*it).v()); ++it;
695     printf("[CallerRegisters]          | %10p | %10p \n", it, (*it).v()); ++it;
696     printf("[ReturnPC]                 | %10p | %10p \n", it, (*it).v()); ++it;
697     printf("[ReturnValueRegister]      | %10p | %10p \n", it, (*it).v()); ++it;
698     printf("[ArgumentCount]            | %10p | %10p \n", it, (*it).v()); ++it;
699     printf("[Callee]                   | %10p | %10p \n", it, (*it).v()); ++it;
700     printf("[OptionalCalleeArguments]  | %10p | %10p \n", it, (*it).v()); ++it;
701     printf("----------------------------------------------------\n");
702
703     int registerCount = 0;
704
705     end = it + codeBlock->numVars;
706     if (it != end) {
707         do {
708             printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
709             ++it;
710             ++registerCount;
711         } while (it != end);
712     }
713     printf("----------------------------------------------------\n");
714
715     end = it + codeBlock->numConstants;
716     if (it != end) {
717         do {
718             printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
719             ++it;
720             ++registerCount;
721         } while (it != end);
722     }
723     printf("----------------------------------------------------\n");
724
725     end = it + codeBlock->numCalleeRegisters - codeBlock->numConstants - codeBlock->numVars;
726     if (it != end) {
727         do {
728             printf("[r%2d]                      | %10p | %10p \n", registerCount, it, (*it).v());
729             ++it;
730             ++registerCount;
731         } while (it != end);
732     }
733     printf("----------------------------------------------------\n");
734 }
735
736 #endif
737
738 bool Machine::isOpcode(Opcode opcode)
739 {
740 #if HAVE(COMPUTED_GOTO)
741     return opcode != HashTraits<Opcode>::emptyValue()
742         && !HashTraits<Opcode>::isDeletedValue(opcode)
743         && m_opcodeIDTable.contains(opcode);
744 #else
745     return opcode >= 0 && opcode <= op_end;
746 #endif
747 }
748
749 NEVER_INLINE bool Machine::unwindCallFrame(CallFrame*& callFrame, JSValuePtr exceptionValue, const Instruction*& vPC, CodeBlock*& codeBlock)
750 {
751     CodeBlock* oldCodeBlock = codeBlock;
752     ScopeChainNode* scopeChain = callFrame->scopeChain();
753
754     if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
755         DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
756         if (callFrame->callee())
757             debugger->returnEvent(debuggerCallFrame, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->lastLine());
758         else
759             debugger->didExecuteProgram(debuggerCallFrame, codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->lastLine());
760     }
761
762     if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
763         if (callFrame->callee())
764             profiler->didExecute(callFrame, callFrame->callee());
765         else
766             profiler->didExecute(callFrame, codeBlock->ownerNode->sourceURL(), codeBlock->ownerNode->lineNo());
767     }
768
769     // If this call frame created an activation or an 'arguments' object, tear it off.
770     if (oldCodeBlock->codeType == FunctionCode && oldCodeBlock->needsFullScopeChain) {
771         while (!scopeChain->object->isObject(&JSActivation::info))
772             scopeChain = scopeChain->pop();
773         static_cast<JSActivation*>(scopeChain->object)->copyRegisters(callFrame->optionalCalleeArguments());
774     } else if (Arguments* arguments = callFrame->optionalCalleeArguments()) {
775         if (!arguments->isTornOff())
776             arguments->copyRegisters();
777     }
778
779     if (oldCodeBlock->needsFullScopeChain)
780         scopeChain->deref();
781
782     void* returnPC = callFrame->returnPC();
783     callFrame = callFrame->callerFrame();
784     if (callFrame->hasHostCallFrameFlag())
785         return false;
786
787     codeBlock = callFrame->codeBlock();
788     vPC = vPCForPC(codeBlock, returnPC);
789     return true;
790 }
791
792 NEVER_INLINE Instruction* Machine::throwException(CallFrame*& callFrame, JSValuePtr& exceptionValue, const Instruction* vPC, bool explicitThrow)
793 {
794     // Set up the exception object
795     
796     CodeBlock* codeBlock = callFrame->codeBlock();
797     if (exceptionValue->isObject()) {
798         JSObject* exception = asObject(exceptionValue);
799         if (exception->isNotAnObjectErrorStub()) {
800             exception = createNotAnObjectError(callFrame, static_cast<JSNotAnObjectErrorStub*>(exception), vPC, codeBlock);
801             exceptionValue = exception;
802         } else {
803             if (!exception->hasProperty(callFrame, Identifier(callFrame, "line")) && 
804                 !exception->hasProperty(callFrame, Identifier(callFrame, "sourceId")) && 
805                 !exception->hasProperty(callFrame, Identifier(callFrame, "sourceURL")) && 
806                 !exception->hasProperty(callFrame, Identifier(callFrame, expressionBeginOffsetPropertyName)) && 
807                 !exception->hasProperty(callFrame, Identifier(callFrame, expressionCaretOffsetPropertyName)) && 
808                 !exception->hasProperty(callFrame, Identifier(callFrame, expressionEndOffsetPropertyName))) {
809                 if (explicitThrow) {
810                     int startOffset = 0;
811                     int endOffset = 0;
812                     int divotPoint = 0;
813                     int line = codeBlock->expressionRangeForVPC(vPC, divotPoint, startOffset, endOffset);
814                     exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, line), ReadOnly | DontDelete);
815                     
816                     // We only hit this path for error messages and throw statements, which don't have a specific failure position
817                     // So we just give the full range of the error/throw statement.
818                     exception->putWithAttributes(callFrame, Identifier(callFrame, expressionBeginOffsetPropertyName), jsNumber(callFrame, divotPoint - startOffset), ReadOnly | DontDelete);
819                     exception->putWithAttributes(callFrame, Identifier(callFrame, expressionEndOffsetPropertyName), jsNumber(callFrame, divotPoint + endOffset), ReadOnly | DontDelete);
820                 } else
821                     exception->putWithAttributes(callFrame, Identifier(callFrame, "line"), jsNumber(callFrame, codeBlock->lineNumberForVPC(vPC)), ReadOnly | DontDelete);
822                 exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceId"), jsNumber(callFrame, codeBlock->ownerNode->sourceID()), ReadOnly | DontDelete);
823                 exception->putWithAttributes(callFrame, Identifier(callFrame, "sourceURL"), jsOwnedString(callFrame, codeBlock->ownerNode->sourceURL()), ReadOnly | DontDelete);
824             }
825             
826             if (exception->isWatchdogException()) {
827                 while (unwindCallFrame(callFrame, exceptionValue, vPC, codeBlock)) {
828                     // Don't need handler checks or anything, we just want to unroll all the JS callframes possible.
829                 }
830                 return 0;
831             }
832         }
833     }
834
835     if (Debugger* debugger = callFrame->dynamicGlobalObject()->debugger()) {
836         DebuggerCallFrame debuggerCallFrame(callFrame, exceptionValue);
837         debugger->exception(debuggerCallFrame, codeBlock->ownerNode->sourceID(), codeBlock->lineNumberForVPC(vPC));
838     }
839
840     // If we throw in the middle of a call instruction, we need to notify
841     // the profiler manually that the call instruction has returned, since
842     // we'll never reach the relevant op_profile_did_call.
843     if (Profiler* profiler = *Profiler::enabledProfilerReference()) {
844         if (isCallOpcode(vPC[0].u.opcode))
845             profiler->didExecute(callFrame, callFrame[vPC[2].u.operand].jsValue(callFrame));
846         else if (vPC[8].u.opcode == getOpcode(op_construct))
847             profiler->didExecute(callFrame, callFrame[vPC[10].u.operand].jsValue(callFrame));
848     }
849
850     // Calculate an exception handler vPC, unwinding call frames as necessary.
851
852     int scopeDepth;
853     Instruction* handlerVPC;
854
855     while (!codeBlock->getHandlerForVPC(vPC, handlerVPC, scopeDepth)) {
856         if (!unwindCallFrame(callFrame, exceptionValue, vPC, codeBlock))
857             return 0;
858     }
859
860     // Now unwind the scope chain within the exception handler's call frame.
861
862     ScopeChain sc(callFrame->scopeChain());
863     int scopeDelta = depth(codeBlock, sc) - scopeDepth;
864     ASSERT(scopeDelta >= 0);
865     while (scopeDelta--)
866         sc.pop();
867     callFrame->setScopeChain(sc.node());
868
869     return handlerVPC;
870 }
871
872 class DynamicGlobalObjectScope : Noncopyable {
873 public:
874     DynamicGlobalObjectScope(CallFrame* callFrame, JSGlobalObject* dynamicGlobalObject) 
875         : m_dynamicGlobalObjectSlot(callFrame->globalData().dynamicGlobalObject)
876         , m_savedDynamicGlobalObject(m_dynamicGlobalObjectSlot)
877     {
878         m_dynamicGlobalObjectSlot = dynamicGlobalObject;
879     }
880
881     ~DynamicGlobalObjectScope()
882     {
883         m_dynamicGlobalObjectSlot = m_savedDynamicGlobalObject;
884     }
885
886 private:
887     JSGlobalObject*& m_dynamicGlobalObjectSlot;
888     JSGlobalObject* m_savedDynamicGlobalObject;
889 };
890
891 JSValuePtr Machine::execute(ProgramNode* programNode, CallFrame* callFrame, ScopeChainNode* scopeChain, JSObject* thisObj, JSValuePtr* exception)
892 {
893     ASSERT(!scopeChain->globalData->exception);
894
895     if (m_reentryDepth >= MaxReentryDepth) {
896         *exception = createStackOverflowError(callFrame);
897         return jsNull();
898     }
899
900     CodeBlock* codeBlock = &programNode->byteCode(scopeChain);
901
902     Register* oldEnd = m_registerFile.end();
903     Register* newEnd = oldEnd + codeBlock->numParameters + RegisterFile::CallFrameHeaderSize + codeBlock->numCalleeRegisters;
904     if (!m_registerFile.grow(newEnd)) {
905         *exception = createStackOverflowError(callFrame);
906         return jsNull();
907     }
908
909     DynamicGlobalObjectScope globalObjectScope(callFrame, scopeChain->globalObject());
910
911     JSGlobalObject* lastGlobalObject = m_registerFile.globalObject();
912     JSGlobalObject* globalObject = callFrame->dynamicGlobalObject();
913     globalObject->copyGlobalsTo(m_registerFile);
914
915     CallFrame* newCallFrame = CallFrame::create(oldEnd + codeBlock->numParameters + RegisterFile::CallFrameHeaderSize);
916     newCallFrame[codeBlock->thisRegister] = thisObj;
917     newCallFrame->init(codeBlock, 0, scopeChain, CallFrame::noCaller(), 0, 0, 0);
918
919     if (codeBlock->needsFullScopeChain)
920         scopeChain->ref();
921
922     Profiler** profiler = Profiler::enabledProfilerReference();
923     if (*profiler)
924         (*profiler)->willExecute(newCallFrame, programNode->sourceURL(), programNode->lineNo());
925
926     m_reentryDepth++;
927 #if ENABLE(CTI)
928     if (!codeBlock->ctiCode)
929         CTI::compile(this, newCallFrame, codeBlock);
930     JSValuePtr result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
931 #else
932     JSValuePtr result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
933 #endif
934     m_reentryDepth--;
935
936     MACHINE_SAMPLING_privateExecuteReturned();
937
938     if (*profiler)
939         (*profiler)->didExecute(callFrame, programNode->sourceURL(), programNode->lineNo());
940
941     if (m_reentryDepth && lastGlobalObject && globalObject != lastGlobalObject)
942         lastGlobalObject->copyGlobalsTo(m_registerFile);
943
944     m_registerFile.shrink(oldEnd);
945
946     return result;
947 }
948
949 JSValuePtr Machine::execute(FunctionBodyNode* functionBodyNode, CallFrame* callFrame, JSFunction* function, JSObject* thisObj, const ArgList& args, ScopeChainNode* scopeChain, JSValuePtr* exception)
950 {
951     ASSERT(!scopeChain->globalData->exception);
952
953     if (m_reentryDepth >= MaxReentryDepth) {
954         *exception = createStackOverflowError(callFrame);
955         return jsNull();
956     }
957
958     Register* oldEnd = m_registerFile.end();
959     int argc = 1 + args.size(); // implicit "this" parameter
960
961     if (!m_registerFile.grow(oldEnd + argc)) {
962         *exception = createStackOverflowError(callFrame);
963         return jsNull();
964     }
965
966     DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
967
968     CallFrame* newCallFrame = CallFrame::create(oldEnd);
969     size_t dst = 0;
970     newCallFrame[0] = thisObj;
971     ArgList::const_iterator end = args.end();
972     for (ArgList::const_iterator it = args.begin(); it != end; ++it)
973         newCallFrame[++dst] = *it;
974
975     CodeBlock* codeBlock = &functionBodyNode->byteCode(scopeChain);
976     newCallFrame = slideRegisterWindowForCall(codeBlock, &m_registerFile, newCallFrame, argc + RegisterFile::CallFrameHeaderSize, argc);
977     if (UNLIKELY(!newCallFrame)) {
978         *exception = createStackOverflowError(callFrame);
979         m_registerFile.shrink(oldEnd);
980         return jsNull();
981     }
982     // a 0 codeBlock indicates a built-in caller
983     newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, argc, function);
984
985     Profiler** profiler = Profiler::enabledProfilerReference();
986     if (*profiler)
987         (*profiler)->willExecute(newCallFrame, function);
988
989     m_reentryDepth++;
990 #if ENABLE(CTI)
991     if (!codeBlock->ctiCode)
992         CTI::compile(this, newCallFrame, codeBlock);
993     JSValuePtr result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
994 #else
995     JSValuePtr result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
996 #endif
997     m_reentryDepth--;
998
999     if (*profiler)
1000         (*profiler)->didExecute(newCallFrame, function);
1001
1002     MACHINE_SAMPLING_privateExecuteReturned();
1003
1004     m_registerFile.shrink(oldEnd);
1005     return result;
1006 }
1007
1008 JSValuePtr Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, ScopeChainNode* scopeChain, JSValuePtr* exception)
1009 {
1010     return execute(evalNode, callFrame, thisObj, m_registerFile.size() + evalNode->byteCode(scopeChain).numParameters + RegisterFile::CallFrameHeaderSize, scopeChain, exception);
1011 }
1012
1013 JSValuePtr Machine::execute(EvalNode* evalNode, CallFrame* callFrame, JSObject* thisObj, int registerOffset, ScopeChainNode* scopeChain, JSValuePtr* exception)
1014 {
1015     ASSERT(!scopeChain->globalData->exception);
1016
1017     if (m_reentryDepth >= MaxReentryDepth) {
1018         *exception = createStackOverflowError(callFrame);
1019         return jsNull();
1020     }
1021
1022     DynamicGlobalObjectScope globalObjectScope(callFrame, callFrame->globalData().dynamicGlobalObject ? callFrame->globalData().dynamicGlobalObject : scopeChain->globalObject());
1023
1024     EvalCodeBlock* codeBlock = &evalNode->byteCode(scopeChain);
1025
1026     JSVariableObject* variableObject;
1027     for (ScopeChainNode* node = scopeChain; ; node = node->next) {
1028         ASSERT(node);
1029         if (node->object->isVariableObject()) {
1030             variableObject = static_cast<JSVariableObject*>(node->object);
1031             break;
1032         }
1033     }
1034
1035     { // Scope for BatchedTransitionOptimizer
1036
1037         BatchedTransitionOptimizer optimizer(variableObject);
1038
1039         const Node::VarStack& varStack = codeBlock->ownerNode->varStack();
1040         Node::VarStack::const_iterator varStackEnd = varStack.end();
1041         for (Node::VarStack::const_iterator it = varStack.begin(); it != varStackEnd; ++it) {
1042             const Identifier& ident = (*it).first;
1043             if (!variableObject->hasProperty(callFrame, ident)) {
1044                 PutPropertySlot slot;
1045                 variableObject->put(callFrame, ident, jsUndefined(), slot);
1046             }
1047         }
1048
1049         const Node::FunctionStack& functionStack = codeBlock->ownerNode->functionStack();
1050         Node::FunctionStack::const_iterator functionStackEnd = functionStack.end();
1051         for (Node::FunctionStack::const_iterator it = functionStack.begin(); it != functionStackEnd; ++it) {
1052             PutPropertySlot slot;
1053             variableObject->put(callFrame, (*it)->m_ident, (*it)->makeFunction(callFrame, scopeChain), slot);
1054         }
1055
1056     }
1057
1058     Register* oldEnd = m_registerFile.end();
1059     Register* newEnd = m_registerFile.start() + registerOffset + codeBlock->numCalleeRegisters;
1060     if (!m_registerFile.grow(newEnd)) {
1061         *exception = createStackOverflowError(callFrame);
1062         return jsNull();
1063     }
1064
1065     CallFrame* newCallFrame = CallFrame::create(m_registerFile.start() + registerOffset);
1066
1067     // a 0 codeBlock indicates a built-in caller
1068     newCallFrame[codeBlock->thisRegister] = thisObj;
1069     newCallFrame->init(codeBlock, 0, scopeChain, callFrame->addHostCallFrameFlag(), 0, 0, 0);
1070
1071     if (codeBlock->needsFullScopeChain)
1072         scopeChain->ref();
1073
1074     Profiler** profiler = Profiler::enabledProfilerReference();
1075     if (*profiler)
1076         (*profiler)->willExecute(newCallFrame, evalNode->sourceURL(), evalNode->lineNo());
1077
1078     m_reentryDepth++;
1079 #if ENABLE(CTI)
1080     if (!codeBlock->ctiCode)
1081         CTI::compile(this, newCallFrame, codeBlock);
1082     JSValuePtr result = CTI::execute(codeBlock->ctiCode, &m_registerFile, newCallFrame, scopeChain->globalData, exception);
1083 #else
1084     JSValuePtr result = privateExecute(Normal, &m_registerFile, newCallFrame, exception);
1085 #endif
1086     m_reentryDepth--;
1087
1088     MACHINE_SAMPLING_privateExecuteReturned();
1089
1090     if (*profiler)
1091         (*profiler)->didExecute(callFrame, evalNode->sourceURL(), evalNode->lineNo());
1092
1093     m_registerFile.shrink(oldEnd);
1094     return result;
1095 }
1096
1097 NEVER_INLINE void Machine::debug(CallFrame* callFrame, DebugHookID debugHookID, int firstLine, int lastLine)
1098 {
1099     Debugger* debugger = callFrame->dynamicGlobalObject()->debugger();
1100     if (!debugger)
1101         return;
1102
1103     switch (debugHookID) {
1104         case DidEnterCallFrame:
1105             debugger->callEvent(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
1106             return;
1107         case WillLeaveCallFrame:
1108             debugger->returnEvent(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
1109             return;
1110         case WillExecuteStatement:
1111             debugger->atStatement(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
1112             return;
1113         case WillExecuteProgram:
1114             debugger->willExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), firstLine);
1115             return;
1116         case DidExecuteProgram:
1117             debugger->didExecuteProgram(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
1118             return;
1119         case DidReachBreakpoint:
1120             debugger->didReachBreakpoint(callFrame, callFrame->codeBlock()->ownerNode->sourceID(), lastLine);
1121             return;
1122     }
1123 }
1124
1125 void Machine::resetTimeoutCheck()
1126 {
1127     m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
1128     m_timeAtLastCheckTimeout = 0;
1129     m_timeExecuting = 0;
1130 }
1131
1132 // Returns the time the current thread has spent executing, in milliseconds.
1133 static inline unsigned getCPUTime()
1134 {
1135 #if PLATFORM(DARWIN)
1136     mach_msg_type_number_t infoCount = THREAD_BASIC_INFO_COUNT;
1137     thread_basic_info_data_t info;
1138
1139     // Get thread information
1140     thread_info(mach_thread_self(), THREAD_BASIC_INFO, reinterpret_cast<thread_info_t>(&info), &infoCount);
1141     
1142     unsigned time = info.user_time.seconds * 1000 + info.user_time.microseconds / 1000;
1143     time += info.system_time.seconds * 1000 + info.system_time.microseconds / 1000;
1144     
1145     return time;
1146 #elif HAVE(SYS_TIME_H)
1147     // FIXME: This should probably use getrusage with the RUSAGE_THREAD flag.
1148     struct timeval tv;
1149     gettimeofday(&tv, 0);
1150     return tv.tv_sec * 1000 + tv.tv_usec / 1000;
1151 #elif PLATFORM(QT)
1152     QDateTime t = QDateTime::currentDateTime();
1153     return t.toTime_t() * 1000 + t.time().msec();
1154 #elif PLATFORM(WIN_OS)
1155     union {
1156         FILETIME fileTime;
1157         unsigned long long fileTimeAsLong;
1158     } userTime, kernelTime;
1159     
1160     // GetThreadTimes won't accept NULL arguments so we pass these even though
1161     // they're not used.
1162     FILETIME creationTime, exitTime;
1163     
1164     GetThreadTimes(GetCurrentThread(), &creationTime, &exitTime, &kernelTime.fileTime, &userTime.fileTime);
1165     
1166     return userTime.fileTimeAsLong / 10000 + kernelTime.fileTimeAsLong / 10000;
1167 #else
1168 #error Platform does not have getCurrentTime function
1169 #endif
1170 }
1171
1172 // We have to return a JSValue here, gcc seems to produce worse code if 
1173 // we attempt to return a bool
1174 ALWAYS_INLINE JSValuePtr Machine::checkTimeout(JSGlobalObject* globalObject)
1175 {
1176     unsigned currentTime = getCPUTime();
1177     
1178     if (!m_timeAtLastCheckTimeout) {
1179         // Suspicious amount of looping in a script -- start timing it
1180         m_timeAtLastCheckTimeout = currentTime;
1181         return noValue();
1182     }
1183     
1184     unsigned timeDiff = currentTime - m_timeAtLastCheckTimeout;
1185     
1186     if (timeDiff == 0)
1187         timeDiff = 1;
1188     
1189     m_timeExecuting += timeDiff;
1190     m_timeAtLastCheckTimeout = currentTime;
1191     
1192     // Adjust the tick threshold so we get the next checkTimeout call in the interval specified in 
1193     // preferredScriptCheckTimeInterval
1194     m_ticksUntilNextTimeoutCheck = static_cast<unsigned>((static_cast<float>(preferredScriptCheckTimeInterval) / timeDiff) * m_ticksUntilNextTimeoutCheck);
1195     // If the new threshold is 0 reset it to the default threshold. This can happen if the timeDiff is higher than the
1196     // preferred script check time interval.
1197     if (m_ticksUntilNextTimeoutCheck == 0)
1198         m_ticksUntilNextTimeoutCheck = initialTickCountThreshold;
1199     
1200     if (m_timeoutTime && m_timeExecuting > m_timeoutTime) {
1201         if (globalObject->shouldInterruptScript())
1202             return jsNull(); // Appeasing GCC, all we need is a non-null js value.
1203         
1204         resetTimeoutCheck();
1205     }
1206     
1207     return noValue();
1208 }
1209
1210 NEVER_INLINE ScopeChainNode* Machine::createExceptionScope(CallFrame* callFrame, const Instruction* vPC)
1211 {
1212     int dst = (++vPC)->u.operand;
1213     CodeBlock* codeBlock = callFrame->codeBlock();
1214     Identifier& property = codeBlock->identifiers[(++vPC)->u.operand];
1215     JSValuePtr value = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1216     JSObject* scope = new (callFrame) JSStaticScopeObject(callFrame, property, value, DontDelete);
1217     callFrame[dst] = scope;
1218
1219     return callFrame->scopeChain()->push(scope);
1220 }
1221
1222 static StructureIDChain* cachePrototypeChain(CallFrame* callFrame, StructureID* structureID)
1223 {
1224     JSValuePtr prototype = structureID->prototypeForLookup(callFrame);
1225     if (JSImmediate::isImmediate(prototype))
1226         return 0;
1227     RefPtr<StructureIDChain> chain = StructureIDChain::create(asObject(prototype)->structureID());
1228     structureID->setCachedPrototypeChain(chain.release());
1229     return structureID->cachedPrototypeChain();
1230 }
1231
1232 NEVER_INLINE void Machine::tryCachePutByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValuePtr baseValue, const PutPropertySlot& slot)
1233 {
1234     // Recursive invocation may already have specialized this instruction.
1235     if (vPC[0].u.opcode != getOpcode(op_put_by_id))
1236         return;
1237
1238     if (JSImmediate::isImmediate(baseValue))
1239         return;
1240
1241     // Uncacheable: give up.
1242     if (!slot.isCacheable()) {
1243         vPC[0] = getOpcode(op_put_by_id_generic);
1244         return;
1245     }
1246     
1247     JSCell* baseCell = asCell(baseValue);
1248     StructureID* structureID = baseCell->structureID();
1249
1250     if (structureID->isDictionary()) {
1251         vPC[0] = getOpcode(op_put_by_id_generic);
1252         return;
1253     }
1254
1255     // Cache miss: record StructureID to compare against next time.
1256     StructureID* lastStructureID = vPC[4].u.structureID;
1257     if (structureID != lastStructureID) {
1258         // First miss: record StructureID to compare against next time.
1259         if (!lastStructureID) {
1260             vPC[4] = structureID;
1261             return;
1262         }
1263
1264         // Second miss: give up.
1265         vPC[0] = getOpcode(op_put_by_id_generic);
1266         return;
1267     }
1268
1269     // Cache hit: Specialize instruction and ref StructureIDs.
1270
1271     // If baseCell != slot.base(), then baseCell must be a proxy for another object.
1272     if (baseCell != slot.base()) {
1273         vPC[0] = getOpcode(op_put_by_id_generic);
1274         return;
1275     }
1276
1277     // StructureID transition, cache transition info
1278     if (slot.type() == PutPropertySlot::NewProperty) {
1279         vPC[0] = getOpcode(op_put_by_id_transition);
1280         vPC[4] = structureID->previousID();
1281         vPC[5] = structureID;
1282         StructureIDChain* chain = structureID->cachedPrototypeChain();
1283         if (!chain) {
1284             chain = cachePrototypeChain(callFrame, structureID);
1285             if (!chain) {
1286                 // This happens if someone has manually inserted null into the prototype chain
1287                 vPC[0] = getOpcode(op_put_by_id_generic);
1288                 return;
1289             }
1290         }
1291         vPC[6] = chain;
1292         vPC[7] = slot.cachedOffset();
1293         codeBlock->refStructureIDs(vPC);
1294         return;
1295     }
1296
1297     vPC[0] = getOpcode(op_put_by_id_replace);
1298     vPC[5] = slot.cachedOffset();
1299     codeBlock->refStructureIDs(vPC);
1300 }
1301
1302 NEVER_INLINE void Machine::uncachePutByID(CodeBlock* codeBlock, Instruction* vPC)
1303 {
1304     codeBlock->derefStructureIDs(vPC);
1305     vPC[0] = getOpcode(op_put_by_id);
1306     vPC[4] = 0;
1307 }
1308
1309 NEVER_INLINE void Machine::tryCacheGetByID(CallFrame* callFrame, CodeBlock* codeBlock, Instruction* vPC, JSValuePtr baseValue, const Identifier& propertyName, const PropertySlot& slot)
1310 {
1311     // Recursive invocation may already have specialized this instruction.
1312     if (vPC[0].u.opcode != getOpcode(op_get_by_id))
1313         return;
1314
1315     // FIXME: Cache property access for immediates.
1316     if (JSImmediate::isImmediate(baseValue)) {
1317         vPC[0] = getOpcode(op_get_by_id_generic);
1318         return;
1319     }
1320
1321     if (isJSArray(baseValue) && propertyName == callFrame->propertyNames().length) {
1322         vPC[0] = getOpcode(op_get_array_length);
1323         return;
1324     }
1325
1326     if (isJSString(baseValue) && propertyName == callFrame->propertyNames().length) {
1327         vPC[0] = getOpcode(op_get_string_length);
1328         return;
1329     }
1330
1331     // Uncacheable: give up.
1332     if (!slot.isCacheable()) {
1333         vPC[0] = getOpcode(op_get_by_id_generic);
1334         return;
1335     }
1336
1337     StructureID* structureID = asCell(baseValue)->structureID();
1338
1339     if (structureID->isDictionary()) {
1340         vPC[0] = getOpcode(op_get_by_id_generic);
1341         return;
1342     }
1343
1344     // Cache miss
1345     StructureID* lastStructureID = vPC[4].u.structureID;
1346     if (structureID != lastStructureID) {
1347         // First miss: record StructureID to compare against next time.
1348         if (!lastStructureID) {
1349             vPC[4] = structureID;
1350             return;
1351         }
1352
1353         // Second miss: give up.
1354         vPC[0] = getOpcode(op_get_by_id_generic);
1355         return;
1356     }
1357
1358     // Cache hit: Specialize instruction and ref StructureIDs.
1359
1360     if (slot.slotBase() == baseValue) {
1361         vPC[0] = getOpcode(op_get_by_id_self);
1362         vPC[5] = slot.cachedOffset();
1363
1364         codeBlock->refStructureIDs(vPC);
1365         return;
1366     }
1367
1368     if (slot.slotBase() == structureID->prototypeForLookup(callFrame)) {
1369         ASSERT(slot.slotBase()->isObject());
1370
1371         JSObject* baseObject = asObject(slot.slotBase());
1372
1373         // Heavy access to a prototype is a good indication that it's not being
1374         // used as a dictionary.
1375         if (baseObject->structureID()->isDictionary()) {
1376             RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(baseObject->structureID());
1377             baseObject->setStructureID(transition.release());
1378             asCell(baseValue)->structureID()->setCachedPrototypeChain(0);
1379         }
1380
1381         vPC[0] = getOpcode(op_get_by_id_proto);
1382         vPC[5] = baseObject->structureID();
1383         vPC[6] = slot.cachedOffset();
1384
1385         codeBlock->refStructureIDs(vPC);
1386         return;
1387     }
1388
1389     size_t count = 0;
1390     JSObject* o = asObject(baseValue);
1391     while (slot.slotBase() != o) {
1392         JSValuePtr v = o->structureID()->prototypeForLookup(callFrame);
1393
1394         // If we didn't find base in baseValue's prototype chain, then baseValue
1395         // must be a proxy for another object.
1396         if (v->isNull()) {
1397             vPC[0] = getOpcode(op_get_by_id_generic);
1398             return;
1399         }
1400
1401         o = asObject(v);
1402
1403         // Heavy access to a prototype is a good indication that it's not being
1404         // used as a dictionary.
1405         if (o->structureID()->isDictionary()) {
1406             RefPtr<StructureID> transition = StructureID::fromDictionaryTransition(o->structureID());
1407             o->setStructureID(transition.release());
1408             asObject(baseValue)->structureID()->setCachedPrototypeChain(0);
1409         }
1410
1411         ++count;
1412     }
1413
1414     StructureIDChain* chain = structureID->cachedPrototypeChain();
1415     if (!chain)
1416         chain = cachePrototypeChain(callFrame, structureID);
1417     ASSERT(chain);
1418
1419     vPC[0] = getOpcode(op_get_by_id_chain);
1420     vPC[4] = structureID;
1421     vPC[5] = chain;
1422     vPC[6] = count;
1423     vPC[7] = slot.cachedOffset();
1424     codeBlock->refStructureIDs(vPC);
1425 }
1426
1427 NEVER_INLINE void Machine::uncacheGetByID(CodeBlock* codeBlock, Instruction* vPC)
1428 {
1429     codeBlock->derefStructureIDs(vPC);
1430     vPC[0] = getOpcode(op_get_by_id);
1431     vPC[4] = 0;
1432 }
1433
1434 JSValuePtr Machine::privateExecute(ExecutionFlag flag, RegisterFile* registerFile, CallFrame* callFrame, JSValuePtr* exception)
1435 {
1436     // One-time initialization of our address tables. We have to put this code
1437     // here because our labels are only in scope inside this function.
1438     if (flag == InitializeAndReturn) {
1439         #if HAVE(COMPUTED_GOTO)
1440             #define ADD_OPCODE(id) m_opcodeTable[id] = &&id;
1441                 FOR_EACH_OPCODE_ID(ADD_OPCODE);
1442             #undef ADD_OPCODE
1443
1444             #define ADD_OPCODE_ID(id) m_opcodeIDTable.add(&&id, id);
1445                 FOR_EACH_OPCODE_ID(ADD_OPCODE_ID);
1446             #undef ADD_OPCODE_ID
1447             ASSERT(m_opcodeIDTable.size() == numOpcodeIDs);
1448             op_throw_end_indirect = &&op_throw_end;
1449             op_call_indirect = &&op_call;
1450         #endif // HAVE(COMPUTED_GOTO)
1451         return noValue();
1452     }
1453
1454 #if ENABLE(CTI)
1455     // Currently with CTI enabled we never interpret functions
1456     ASSERT_NOT_REACHED();
1457 #endif
1458
1459     JSGlobalData* globalData = &callFrame->globalData();
1460     JSValuePtr exceptionValue = noValue();
1461     Instruction* handlerVPC = 0;
1462
1463     Instruction* vPC = callFrame->codeBlock()->instructions.begin();
1464     Profiler** enabledProfilerReference = Profiler::enabledProfilerReference();
1465     unsigned tickCount = m_ticksUntilNextTimeoutCheck + 1;
1466
1467 #define VM_CHECK_EXCEPTION() \
1468     do { \
1469         if (UNLIKELY(globalData->exception != noValue())) { \
1470             exceptionValue = globalData->exception; \
1471             goto vm_throw; \
1472         } \
1473     } while (0)
1474
1475 #if DUMP_OPCODE_STATS
1476     OpcodeStats::resetLastInstruction();
1477 #endif
1478
1479 #define CHECK_FOR_TIMEOUT() \
1480     if (!--tickCount) { \
1481         if ((exceptionValue = checkTimeout(callFrame->dynamicGlobalObject()))) \
1482             goto vm_throw; \
1483         tickCount = m_ticksUntilNextTimeoutCheck; \
1484     }
1485
1486 #if HAVE(COMPUTED_GOTO)
1487     #define NEXT_OPCODE MACHINE_SAMPLING_sample(callFrame->codeBlock(), vPC); goto *vPC->u.opcode
1488 #if DUMP_OPCODE_STATS
1489     #define BEGIN_OPCODE(opcode) opcode: OpcodeStats::recordInstruction(opcode);
1490 #else
1491     #define BEGIN_OPCODE(opcode) opcode:
1492 #endif
1493     NEXT_OPCODE;
1494 #else
1495     #define NEXT_OPCODE MACHINE_SAMPLING_sample(callFrame->codeBlock(), vPC); goto interpreterLoopStart
1496 #if DUMP_OPCODE_STATS
1497     #define BEGIN_OPCODE(opcode) case opcode: OpcodeStats::recordInstruction(opcode);
1498 #else
1499     #define BEGIN_OPCODE(opcode) case opcode:
1500 #endif
1501     while (1) { // iterator loop begins
1502     interpreterLoopStart:;
1503     switch (vPC->u.opcode)
1504 #endif
1505     {
1506     BEGIN_OPCODE(op_new_object) {
1507         /* new_object dst(r)
1508
1509            Constructs a new empty Object instance using the original
1510            constructor, and puts the result in register dst.
1511         */
1512         int dst = (++vPC)->u.operand;
1513         callFrame[dst] = constructEmptyObject(callFrame);
1514
1515         ++vPC;
1516         NEXT_OPCODE;
1517     }
1518     BEGIN_OPCODE(op_new_array) {
1519         /* new_array dst(r) firstArg(r) argCount(n)
1520
1521            Constructs a new Array instance using the original
1522            constructor, and puts the result in register dst.
1523            The array will contain argCount elements with values
1524            taken from registers starting at register firstArg.
1525         */
1526         int dst = (++vPC)->u.operand;
1527         int firstArg = (++vPC)->u.operand;
1528         int argCount = (++vPC)->u.operand;
1529         ArgList args(callFrame->registers() + firstArg, argCount);
1530         callFrame[dst] = constructArray(callFrame, args);
1531
1532         ++vPC;
1533         NEXT_OPCODE;
1534     }
1535     BEGIN_OPCODE(op_new_regexp) {
1536         /* new_regexp dst(r) regExp(re)
1537
1538            Constructs a new RegExp instance using the original
1539            constructor from regexp regExp, and puts the result in
1540            register dst.
1541         */
1542         int dst = (++vPC)->u.operand;
1543         int regExp = (++vPC)->u.operand;
1544         callFrame[dst] = new (globalData) RegExpObject(callFrame->scopeChain()->globalObject()->regExpStructure(), callFrame->codeBlock()->regexps[regExp]);
1545
1546         ++vPC;
1547         NEXT_OPCODE;
1548     }
1549     BEGIN_OPCODE(op_mov) {
1550         /* mov dst(r) src(r)
1551
1552            Copies register src to register dst.
1553         */
1554         int dst = (++vPC)->u.operand;
1555         int src = (++vPC)->u.operand;
1556         callFrame[dst] = callFrame[src];
1557
1558         ++vPC;
1559         NEXT_OPCODE;
1560     }
1561     BEGIN_OPCODE(op_eq) {
1562         /* eq dst(r) src1(r) src2(r)
1563
1564            Checks whether register src1 and register src2 are equal,
1565            as with the ECMAScript '==' operator, and puts the result
1566            as a boolean in register dst.
1567         */
1568         int dst = (++vPC)->u.operand;
1569         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1570         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1571         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1572             callFrame[dst] = jsBoolean(src1 == src2);
1573         else {
1574             JSValuePtr result = jsBoolean(equalSlowCase(callFrame, src1, src2));
1575             VM_CHECK_EXCEPTION();
1576             callFrame[dst] = result;
1577         }
1578
1579         ++vPC;
1580         NEXT_OPCODE;
1581     }
1582     BEGIN_OPCODE(op_eq_null) {
1583         /* eq_null dst(r) src(r)
1584
1585            Checks whether register src is null, as with the ECMAScript '!='
1586            operator, and puts the result as a boolean in register dst.
1587         */
1588         int dst = (++vPC)->u.operand;
1589         JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1590
1591         if (src->isUndefinedOrNull()) {
1592             callFrame[dst] = jsBoolean(true);
1593             ++vPC;
1594             NEXT_OPCODE;
1595         }
1596         
1597         callFrame[dst] = jsBoolean(!JSImmediate::isImmediate(src) && src->asCell()->structureID()->typeInfo().masqueradesAsUndefined());
1598         ++vPC;
1599         NEXT_OPCODE;
1600     }
1601     BEGIN_OPCODE(op_neq) {
1602         /* neq dst(r) src1(r) src2(r)
1603
1604            Checks whether register src1 and register src2 are not
1605            equal, as with the ECMAScript '!=' operator, and puts the
1606            result as a boolean in register dst.
1607         */
1608         int dst = (++vPC)->u.operand;
1609         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1610         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1611         if (JSImmediate::areBothImmediateNumbers(src1, src2))
1612             callFrame[dst] = jsBoolean(src1 != src2);
1613         else {
1614             JSValuePtr result = jsBoolean(!equalSlowCase(callFrame, src1, src2));
1615             VM_CHECK_EXCEPTION();
1616             callFrame[dst] = result;
1617         }
1618
1619         ++vPC;
1620         NEXT_OPCODE;
1621     }
1622     BEGIN_OPCODE(op_neq_null) {
1623         /* neq_null dst(r) src(r)
1624
1625            Checks whether register src is not null, as with the ECMAScript '!='
1626            operator, and puts the result as a boolean in register dst.
1627         */
1628         int dst = (++vPC)->u.operand;
1629         JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1630
1631         if (src->isUndefinedOrNull()) {
1632             callFrame[dst] = jsBoolean(false);
1633             ++vPC;
1634             NEXT_OPCODE;
1635         }
1636         
1637         callFrame[dst] = jsBoolean(JSImmediate::isImmediate(src) || !asCell(src)->structureID()->typeInfo().masqueradesAsUndefined());
1638         ++vPC;
1639         NEXT_OPCODE;
1640     }
1641     BEGIN_OPCODE(op_stricteq) {
1642         /* stricteq dst(r) src1(r) src2(r)
1643
1644            Checks whether register src1 and register src2 are strictly
1645            equal, as with the ECMAScript '===' operator, and puts the
1646            result as a boolean in register dst.
1647         */
1648         int dst = (++vPC)->u.operand;
1649         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1650         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1651         if (JSImmediate::areBothImmediate(src1, src2))
1652             callFrame[dst] = jsBoolean(src1 == src2);
1653         else if (JSImmediate::isEitherImmediate(src1, src2) & (src1 != JSImmediate::zeroImmediate()) & (src2 != JSImmediate::zeroImmediate()))
1654             callFrame[dst] = jsBoolean(false);
1655         else
1656             callFrame[dst] = jsBoolean(strictEqualSlowCase(src1, src2));
1657
1658         ++vPC;
1659         NEXT_OPCODE;
1660     }
1661     BEGIN_OPCODE(op_nstricteq) {
1662         /* nstricteq dst(r) src1(r) src2(r)
1663
1664            Checks whether register src1 and register src2 are not
1665            strictly equal, as with the ECMAScript '!==' operator, and
1666            puts the result as a boolean in register dst.
1667         */
1668         int dst = (++vPC)->u.operand;
1669         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1670         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1671
1672         if (JSImmediate::areBothImmediate(src1, src2))
1673             callFrame[dst] = jsBoolean(src1 != src2);
1674         else if (JSImmediate::isEitherImmediate(src1, src2) & (src1 != JSImmediate::zeroImmediate()) & (src2 != JSImmediate::zeroImmediate()))
1675             callFrame[dst] = jsBoolean(true);
1676         else
1677             callFrame[dst] = jsBoolean(!strictEqualSlowCase(src1, src2));
1678
1679         ++vPC;
1680         NEXT_OPCODE;
1681     }
1682     BEGIN_OPCODE(op_less) {
1683         /* less dst(r) src1(r) src2(r)
1684
1685            Checks whether register src1 is less than register src2, as
1686            with the ECMAScript '<' operator, and puts the result as
1687            a boolean in register dst.
1688         */
1689         int dst = (++vPC)->u.operand;
1690         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1691         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1692         JSValuePtr result = jsBoolean(jsLess(callFrame, src1, src2));
1693         VM_CHECK_EXCEPTION();
1694         callFrame[dst] = result;
1695
1696         ++vPC;
1697         NEXT_OPCODE;
1698     }
1699     BEGIN_OPCODE(op_lesseq) {
1700         /* lesseq dst(r) src1(r) src2(r)
1701
1702            Checks whether register src1 is less than or equal to
1703            register src2, as with the ECMAScript '<=' operator, and
1704            puts the result as a boolean in register dst.
1705         */
1706         int dst = (++vPC)->u.operand;
1707         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1708         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1709         JSValuePtr result = jsBoolean(jsLessEq(callFrame, src1, src2));
1710         VM_CHECK_EXCEPTION();
1711         callFrame[dst] = result;
1712
1713         ++vPC;
1714         NEXT_OPCODE;
1715     }
1716     BEGIN_OPCODE(op_pre_inc) {
1717         /* pre_inc srcDst(r)
1718
1719            Converts register srcDst to number, adds one, and puts the result
1720            back in register srcDst.
1721         */
1722         int srcDst = (++vPC)->u.operand;
1723         JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
1724         if (JSImmediate::canDoFastAdditiveOperations(v))
1725             callFrame[srcDst] = JSImmediate::incImmediateNumber(v);
1726         else {
1727             JSValuePtr result = jsNumber(callFrame, v->toNumber(callFrame) + 1);
1728             VM_CHECK_EXCEPTION();
1729             callFrame[srcDst] = result;
1730         }
1731
1732         ++vPC;
1733         NEXT_OPCODE;
1734     }
1735     BEGIN_OPCODE(op_pre_dec) {
1736         /* pre_dec srcDst(r)
1737
1738            Converts register srcDst to number, subtracts one, and puts the result
1739            back in register srcDst.
1740         */
1741         int srcDst = (++vPC)->u.operand;
1742         JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
1743         if (JSImmediate::canDoFastAdditiveOperations(v))
1744             callFrame[srcDst] = JSImmediate::decImmediateNumber(v);
1745         else {
1746             JSValuePtr result = jsNumber(callFrame, v->toNumber(callFrame) - 1);
1747             VM_CHECK_EXCEPTION();
1748             callFrame[srcDst] = result;
1749         }
1750
1751         ++vPC;
1752         NEXT_OPCODE;
1753     }
1754     BEGIN_OPCODE(op_post_inc) {
1755         /* post_inc dst(r) srcDst(r)
1756
1757            Converts register srcDst to number. The number itself is
1758            written to register dst, and the number plus one is written
1759            back to register srcDst.
1760         */
1761         int dst = (++vPC)->u.operand;
1762         int srcDst = (++vPC)->u.operand;
1763         JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
1764         if (JSImmediate::canDoFastAdditiveOperations(v)) {
1765             callFrame[dst] = v;
1766             callFrame[srcDst] = JSImmediate::incImmediateNumber(v);
1767         } else {
1768             JSValuePtr number = callFrame[srcDst].jsValue(callFrame)->toJSNumber(callFrame);
1769             VM_CHECK_EXCEPTION();
1770             callFrame[dst] = number;
1771             callFrame[srcDst] = jsNumber(callFrame, number->uncheckedGetNumber() + 1);
1772         }
1773
1774         ++vPC;
1775         NEXT_OPCODE;
1776     }
1777     BEGIN_OPCODE(op_post_dec) {
1778         /* post_dec dst(r) srcDst(r)
1779
1780            Converts register srcDst to number. The number itself is
1781            written to register dst, and the number minus one is written
1782            back to register srcDst.
1783         */
1784         int dst = (++vPC)->u.operand;
1785         int srcDst = (++vPC)->u.operand;
1786         JSValuePtr v = callFrame[srcDst].jsValue(callFrame);
1787         if (JSImmediate::canDoFastAdditiveOperations(v)) {
1788             callFrame[dst] = v;
1789             callFrame[srcDst] = JSImmediate::decImmediateNumber(v);
1790         } else {
1791             JSValuePtr number = callFrame[srcDst].jsValue(callFrame)->toJSNumber(callFrame);
1792             VM_CHECK_EXCEPTION();
1793             callFrame[dst] = number;
1794             callFrame[srcDst] = jsNumber(callFrame, number->uncheckedGetNumber() - 1);
1795         }
1796
1797         ++vPC;
1798         NEXT_OPCODE;
1799     }
1800     BEGIN_OPCODE(op_to_jsnumber) {
1801         /* to_jsnumber dst(r) src(r)
1802
1803            Converts register src to number, and puts the result
1804            in register dst.
1805         */
1806         int dst = (++vPC)->u.operand;
1807         int src = (++vPC)->u.operand;
1808
1809         JSValuePtr srcVal = callFrame[src].jsValue(callFrame);
1810
1811         if (LIKELY(srcVal->isNumber()))
1812             callFrame[dst] = callFrame[src];
1813         else {
1814             JSValuePtr result = srcVal->toJSNumber(callFrame);
1815             VM_CHECK_EXCEPTION();
1816             callFrame[dst] = result;
1817         }
1818
1819         ++vPC;
1820         NEXT_OPCODE;
1821     }
1822     BEGIN_OPCODE(op_negate) {
1823         /* negate dst(r) src(r)
1824
1825            Converts register src to number, negates it, and puts the
1826            result in register dst.
1827         */
1828         int dst = (++vPC)->u.operand;
1829         JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1830         double v;
1831         if (fastIsNumber(src, v))
1832             callFrame[dst] = jsNumber(callFrame, -v);
1833         else {
1834             JSValuePtr result = jsNumber(callFrame, -src->toNumber(callFrame));
1835             VM_CHECK_EXCEPTION();
1836             callFrame[dst] = result;
1837         }
1838
1839         ++vPC;
1840         NEXT_OPCODE;
1841     }
1842     BEGIN_OPCODE(op_add) {
1843         /* add dst(r) src1(r) src2(r)
1844
1845            Adds register src1 and register src2, and puts the result
1846            in register dst. (JS add may be string concatenation or
1847            numeric add, depending on the types of the operands.)
1848         */
1849         int dst = (++vPC)->u.operand;
1850         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1851         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1852         if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
1853             callFrame[dst] = JSImmediate::addImmediateNumbers(src1, src2);
1854         else {
1855             JSValuePtr result = jsAdd(callFrame, src1, src2);
1856             VM_CHECK_EXCEPTION();
1857             callFrame[dst] = result;
1858         }
1859         vPC += 2;
1860         NEXT_OPCODE;
1861     }
1862     BEGIN_OPCODE(op_mul) {
1863         /* mul dst(r) src1(r) src2(r)
1864
1865            Multiplies register src1 and register src2 (converted to
1866            numbers), and puts the product in register dst.
1867         */
1868         int dst = (++vPC)->u.operand;
1869         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1870         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1871         double left;
1872         double right;
1873         if (JSImmediate::areBothImmediateNumbers(src1, src2)) {
1874             int32_t left = JSImmediate::getTruncatedInt32(src1);
1875             int32_t right = JSImmediate::getTruncatedInt32(src2);
1876             if ((left | right) >> 15 == 0)
1877                 callFrame[dst] = jsNumber(callFrame, left * right);
1878             else
1879                 callFrame[dst] = jsNumber(callFrame, static_cast<double>(left) * static_cast<double>(right));
1880         } else if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
1881             callFrame[dst] = jsNumber(callFrame, left * right);
1882         else {
1883             JSValuePtr result = jsNumber(callFrame, src1->toNumber(callFrame) * src2->toNumber(callFrame));
1884             VM_CHECK_EXCEPTION();
1885             callFrame[dst] = result;
1886         }
1887
1888         vPC += 2;
1889         NEXT_OPCODE;
1890     }
1891     BEGIN_OPCODE(op_div) {
1892         /* div dst(r) dividend(r) divisor(r)
1893
1894            Divides register dividend (converted to number) by the
1895            register divisor (converted to number), and puts the
1896            quotient in register dst.
1897         */
1898         int dst = (++vPC)->u.operand;
1899         JSValuePtr dividend = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1900         JSValuePtr divisor = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1901         double left;
1902         double right;
1903         if (fastIsNumber(dividend, left) && fastIsNumber(divisor, right))
1904             callFrame[dst] = jsNumber(callFrame, left / right);
1905         else {
1906             JSValuePtr result = jsNumber(callFrame, dividend->toNumber(callFrame) / divisor->toNumber(callFrame));
1907             VM_CHECK_EXCEPTION();
1908             callFrame[dst] = result;
1909         }
1910         ++vPC;
1911         NEXT_OPCODE;
1912     }
1913     BEGIN_OPCODE(op_mod) {
1914         /* mod dst(r) dividend(r) divisor(r)
1915
1916            Divides register dividend (converted to number) by
1917            register divisor (converted to number), and puts the
1918            remainder in register dst.
1919         */
1920         int dst = (++vPC)->u.operand;
1921         int dividend = (++vPC)->u.operand;
1922         int divisor = (++vPC)->u.operand;
1923
1924         JSValuePtr dividendValue = callFrame[dividend].jsValue(callFrame);
1925         JSValuePtr divisorValue = callFrame[divisor].jsValue(callFrame);
1926
1927         if (JSImmediate::areBothImmediateNumbers(dividendValue, divisorValue) && divisorValue != JSImmediate::from(0)) {
1928             callFrame[dst] = JSImmediate::from(JSImmediate::getTruncatedInt32(dividendValue) % JSImmediate::getTruncatedInt32(divisorValue));
1929             ++vPC;
1930             NEXT_OPCODE;
1931         }
1932
1933         double d = dividendValue->toNumber(callFrame);
1934         JSValuePtr result = jsNumber(callFrame, fmod(d, divisorValue->toNumber(callFrame)));
1935         VM_CHECK_EXCEPTION();
1936         callFrame[dst] = result;
1937         ++vPC;
1938         NEXT_OPCODE;
1939     }
1940     BEGIN_OPCODE(op_sub) {
1941         /* sub dst(r) src1(r) src2(r)
1942
1943            Subtracts register src2 (converted to number) from register
1944            src1 (converted to number), and puts the difference in
1945            register dst.
1946         */
1947         int dst = (++vPC)->u.operand;
1948         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1949         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1950         double left;
1951         double right;
1952         if (JSImmediate::canDoFastAdditiveOperations(src1) && JSImmediate::canDoFastAdditiveOperations(src2))
1953             callFrame[dst] = JSImmediate::subImmediateNumbers(src1, src2);
1954         else if (fastIsNumber(src1, left) && fastIsNumber(src2, right))
1955             callFrame[dst] = jsNumber(callFrame, left - right);
1956         else {
1957             JSValuePtr result = jsNumber(callFrame, src1->toNumber(callFrame) - src2->toNumber(callFrame));
1958             VM_CHECK_EXCEPTION();
1959             callFrame[dst] = result;
1960         }
1961         vPC += 2;
1962         NEXT_OPCODE;
1963     }
1964     BEGIN_OPCODE(op_lshift) {
1965         /* lshift dst(r) val(r) shift(r)
1966
1967            Performs left shift of register val (converted to int32) by
1968            register shift (converted to uint32), and puts the result
1969            in register dst.
1970         */
1971         int dst = (++vPC)->u.operand;
1972         JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1973         JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1974         int32_t left;
1975         uint32_t right;
1976         if (JSImmediate::areBothImmediateNumbers(val, shift))
1977             callFrame[dst] = jsNumber(callFrame, JSImmediate::getTruncatedInt32(val) << (JSImmediate::getTruncatedUInt32(shift) & 0x1f));
1978         else if (fastToInt32(val, left) && fastToUInt32(shift, right))
1979             callFrame[dst] = jsNumber(callFrame, left << (right & 0x1f));
1980         else {
1981             JSValuePtr result = jsNumber(callFrame, (val->toInt32(callFrame)) << (shift->toUInt32(callFrame) & 0x1f));
1982             VM_CHECK_EXCEPTION();
1983             callFrame[dst] = result;
1984         }
1985
1986         ++vPC;
1987         NEXT_OPCODE;
1988     }
1989     BEGIN_OPCODE(op_rshift) {
1990         /* rshift dst(r) val(r) shift(r)
1991
1992            Performs arithmetic right shift of register val (converted
1993            to int32) by register shift (converted to
1994            uint32), and puts the result in register dst.
1995         */
1996         int dst = (++vPC)->u.operand;
1997         JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1998         JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
1999         int32_t left;
2000         uint32_t right;
2001         if (JSImmediate::areBothImmediateNumbers(val, shift))
2002             callFrame[dst] = JSImmediate::rightShiftImmediateNumbers(val, shift);
2003         else if (fastToInt32(val, left) && fastToUInt32(shift, right))
2004             callFrame[dst] = jsNumber(callFrame, left >> (right & 0x1f));
2005         else {
2006             JSValuePtr result = jsNumber(callFrame, (val->toInt32(callFrame)) >> (shift->toUInt32(callFrame) & 0x1f));
2007             VM_CHECK_EXCEPTION();
2008             callFrame[dst] = result;
2009         }
2010
2011         ++vPC;
2012         NEXT_OPCODE;
2013     }
2014     BEGIN_OPCODE(op_urshift) {
2015         /* rshift dst(r) val(r) shift(r)
2016
2017            Performs logical right shift of register val (converted
2018            to uint32) by register shift (converted to
2019            uint32), and puts the result in register dst.
2020         */
2021         int dst = (++vPC)->u.operand;
2022         JSValuePtr val = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2023         JSValuePtr shift = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2024         if (JSImmediate::areBothImmediateNumbers(val, shift) && !JSImmediate::isNegative(val))
2025             callFrame[dst] = JSImmediate::rightShiftImmediateNumbers(val, shift);
2026         else {
2027             JSValuePtr result = jsNumber(callFrame, (val->toUInt32(callFrame)) >> (shift->toUInt32(callFrame) & 0x1f));
2028             VM_CHECK_EXCEPTION();
2029             callFrame[dst] = result;
2030         }
2031
2032         ++vPC;
2033         NEXT_OPCODE;
2034     }
2035     BEGIN_OPCODE(op_bitand) {
2036         /* bitand dst(r) src1(r) src2(r)
2037
2038            Computes bitwise AND of register src1 (converted to int32)
2039            and register src2 (converted to int32), and puts the result
2040            in register dst.
2041         */
2042         int dst = (++vPC)->u.operand;
2043         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2044         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2045         int32_t left;
2046         int32_t right;
2047         if (JSImmediate::areBothImmediateNumbers(src1, src2))
2048             callFrame[dst] = JSImmediate::andImmediateNumbers(src1, src2);
2049         else if (fastToInt32(src1, left) && fastToInt32(src2, right))
2050             callFrame[dst] = jsNumber(callFrame, left & right);
2051         else {
2052             JSValuePtr result = jsNumber(callFrame, src1->toInt32(callFrame) & src2->toInt32(callFrame));
2053             VM_CHECK_EXCEPTION();
2054             callFrame[dst] = result;
2055         }
2056
2057         vPC += 2;
2058         NEXT_OPCODE;
2059     }
2060     BEGIN_OPCODE(op_bitxor) {
2061         /* bitxor dst(r) src1(r) src2(r)
2062
2063            Computes bitwise XOR of register src1 (converted to int32)
2064            and register src2 (converted to int32), and puts the result
2065            in register dst.
2066         */
2067         int dst = (++vPC)->u.operand;
2068         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2069         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2070         int32_t left;
2071         int32_t right;
2072         if (JSImmediate::areBothImmediateNumbers(src1, src2))
2073             callFrame[dst] = JSImmediate::xorImmediateNumbers(src1, src2);
2074         else if (fastToInt32(src1, left) && fastToInt32(src2, right))
2075             callFrame[dst] = jsNumber(callFrame, left ^ right);
2076         else {
2077             JSValuePtr result = jsNumber(callFrame, src1->toInt32(callFrame) ^ src2->toInt32(callFrame));
2078             VM_CHECK_EXCEPTION();
2079             callFrame[dst] = result;
2080         }
2081
2082         vPC += 2;
2083         NEXT_OPCODE;
2084     }
2085     BEGIN_OPCODE(op_bitor) {
2086         /* bitor dst(r) src1(r) src2(r)
2087
2088            Computes bitwise OR of register src1 (converted to int32)
2089            and register src2 (converted to int32), and puts the
2090            result in register dst.
2091         */
2092         int dst = (++vPC)->u.operand;
2093         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2094         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2095         int32_t left;
2096         int32_t right;
2097         if (JSImmediate::areBothImmediateNumbers(src1, src2))
2098             callFrame[dst] = JSImmediate::orImmediateNumbers(src1, src2);
2099         else if (fastToInt32(src1, left) && fastToInt32(src2, right))
2100             callFrame[dst] = jsNumber(callFrame, left | right);
2101         else {
2102             JSValuePtr result = jsNumber(callFrame, src1->toInt32(callFrame) | src2->toInt32(callFrame));
2103             VM_CHECK_EXCEPTION();
2104             callFrame[dst] = result;
2105         }
2106
2107         vPC += 2;
2108         NEXT_OPCODE;
2109     }
2110     BEGIN_OPCODE(op_bitnot) {
2111         /* bitnot dst(r) src(r)
2112
2113            Computes bitwise NOT of register src1 (converted to int32),
2114            and puts the result in register dst.
2115         */
2116         int dst = (++vPC)->u.operand;
2117         JSValuePtr src = callFrame[(++vPC)->u.operand].jsValue(callFrame);
2118         int32_t value;
2119         if (fastToInt32(src, value))
2120             callFrame[dst] = jsNumber(callFrame, ~value);
2121         else {
2122             JSValuePtr result = jsNumber(callFrame, ~src->toInt32(callFrame));
2123             VM_CHECK_EXCEPTION();
2124             callFrame[dst] = result;
2125         }
2126         ++vPC;
2127         NEXT_OPCODE;
2128     }
2129     BEGIN_OPCODE(op_not) {
2130         /* not dst(r) src(r)
2131
2132            Computes logical NOT of register src (converted to
2133            boolean), and puts the result in register dst.
2134         */
2135         int dst = (++vPC)->u.operand;
2136         int src = (++vPC)->u.operand;
2137         JSValuePtr result = jsBoolean(!callFrame[src].jsValue(callFrame)->toBoolean(callFrame));
2138         VM_CHECK_EXCEPTION();
2139         callFrame[dst] = result;
2140
2141         ++vPC;
2142         NEXT_OPCODE;
2143     }
2144     BEGIN_OPCODE(op_instanceof) {
2145         /* instanceof dst(r) value(r) constructor(r) constructorProto(r)
2146
2147            Tests whether register value is an instance of register
2148            constructor, and puts the boolean result in register
2149            dst. Register constructorProto must contain the "prototype"
2150            property (not the actual prototype) of the object in
2151            register constructor. This lookup is separated so that
2152            polymorphic inline caching can apply.
2153
2154            Raises an exception if register constructor is not an
2155            object.
2156         */
2157         int dst = vPC[1].u.operand;
2158         int value = vPC[2].u.operand;
2159         int base = vPC[3].u.operand;
2160         int baseProto = vPC[4].u.operand;
2161
2162         JSValuePtr baseVal = callFrame[base].jsValue(callFrame);
2163
2164         if (isNotObject(callFrame, true, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
2165             goto vm_throw;
2166
2167         JSObject* baseObj = asObject(baseVal);
2168         callFrame[dst] = jsBoolean(baseObj->structureID()->typeInfo().implementsHasInstance() ? baseObj->hasInstance(callFrame, callFrame[value].jsValue(callFrame), callFrame[baseProto].jsValue(callFrame)) : false);
2169
2170         vPC += 5;
2171         NEXT_OPCODE;
2172     }
2173     BEGIN_OPCODE(op_typeof) {
2174         /* typeof dst(r) src(r)
2175
2176            Determines the type string for src according to ECMAScript
2177            rules, and puts the result in register dst.
2178         */
2179         int dst = (++vPC)->u.operand;
2180         int src = (++vPC)->u.operand;
2181         callFrame[dst] = jsTypeStringForValue(callFrame, callFrame[src].jsValue(callFrame));
2182
2183         ++vPC;
2184         NEXT_OPCODE;
2185     }
2186     BEGIN_OPCODE(op_is_undefined) {
2187         /* is_undefined dst(r) src(r)
2188
2189            Determines whether the type string for src according to
2190            the ECMAScript rules is "undefined", and puts the result
2191            in register dst.
2192         */
2193         int dst = (++vPC)->u.operand;
2194         int src = (++vPC)->u.operand;
2195         JSValuePtr v = callFrame[src].jsValue(callFrame);
2196         callFrame[dst] = jsBoolean(JSImmediate::isImmediate(v) ? v->isUndefined() : v->asCell()->structureID()->typeInfo().masqueradesAsUndefined());
2197
2198         ++vPC;
2199         NEXT_OPCODE;
2200     }
2201     BEGIN_OPCODE(op_is_boolean) {
2202         /* is_boolean dst(r) src(r)
2203
2204            Determines whether the type string for src according to
2205            the ECMAScript rules is "boolean", and puts the result
2206            in register dst.
2207         */
2208         int dst = (++vPC)->u.operand;
2209         int src = (++vPC)->u.operand;
2210         callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isBoolean());
2211
2212         ++vPC;
2213         NEXT_OPCODE;
2214     }
2215     BEGIN_OPCODE(op_is_number) {
2216         /* is_number dst(r) src(r)
2217
2218            Determines whether the type string for src according to
2219            the ECMAScript rules is "number", and puts the result
2220            in register dst.
2221         */
2222         int dst = (++vPC)->u.operand;
2223         int src = (++vPC)->u.operand;
2224         callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isNumber());
2225
2226         ++vPC;
2227         NEXT_OPCODE;
2228     }
2229     BEGIN_OPCODE(op_is_string) {
2230         /* is_string dst(r) src(r)
2231
2232            Determines whether the type string for src according to
2233            the ECMAScript rules is "string", and puts the result
2234            in register dst.
2235         */
2236         int dst = (++vPC)->u.operand;
2237         int src = (++vPC)->u.operand;
2238         callFrame[dst] = jsBoolean(callFrame[src].jsValue(callFrame)->isString());
2239
2240         ++vPC;
2241         NEXT_OPCODE;
2242     }
2243     BEGIN_OPCODE(op_is_object) {
2244         /* is_object dst(r) src(r)
2245
2246            Determines whether the type string for src according to
2247            the ECMAScript rules is "object", and puts the result
2248            in register dst.
2249         */
2250         int dst = (++vPC)->u.operand;
2251         int src = (++vPC)->u.operand;
2252         callFrame[dst] = jsBoolean(jsIsObjectType(callFrame[src].jsValue(callFrame)));
2253
2254         ++vPC;
2255         NEXT_OPCODE;
2256     }
2257     BEGIN_OPCODE(op_is_function) {
2258         /* is_function dst(r) src(r)
2259
2260            Determines whether the type string for src according to
2261            the ECMAScript rules is "function", and puts the result
2262            in register dst.
2263         */
2264         int dst = (++vPC)->u.operand;
2265         int src = (++vPC)->u.operand;
2266         callFrame[dst] = jsBoolean(jsIsFunctionType(callFrame[src].jsValue(callFrame)));
2267
2268         ++vPC;
2269         NEXT_OPCODE;
2270     }
2271     BEGIN_OPCODE(op_in) {
2272         /* in dst(r) property(r) base(r)
2273
2274            Tests whether register base has a property named register
2275            property, and puts the boolean result in register dst.
2276
2277            Raises an exception if register constructor is not an
2278            object.
2279         */
2280         int dst = (++vPC)->u.operand;
2281         int property = (++vPC)->u.operand;
2282         int base = (++vPC)->u.operand;
2283
2284         JSValuePtr baseVal = callFrame[base].jsValue(callFrame);
2285         if (isNotObject(callFrame, false, callFrame->codeBlock(), vPC, baseVal, exceptionValue))
2286             goto vm_throw;
2287
2288         JSObject* baseObj = asObject(baseVal);
2289
2290         JSValuePtr propName = callFrame[property].jsValue(callFrame);
2291
2292         uint32_t i;
2293         if (propName->getUInt32(i))
2294             callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, i));
2295         else {
2296             Identifier property(callFrame, propName->toString(callFrame));
2297             VM_CHECK_EXCEPTION();
2298             callFrame[dst] = jsBoolean(baseObj->hasProperty(callFrame, property));
2299         }
2300
2301         ++vPC;
2302         NEXT_OPCODE;
2303     }
2304     BEGIN_OPCODE(op_resolve) {
2305         /* resolve dst(r) property(id)
2306
2307            Looks up the property named by identifier property in the
2308            scope chain, and writes the resulting value to register
2309            dst. If the property is not found, raises an exception.
2310         */
2311         if (UNLIKELY(!resolve(callFrame, vPC, exceptionValue)))
2312             goto vm_throw;
2313
2314         vPC += 3;
2315         NEXT_OPCODE;
2316     }
2317     BEGIN_OPCODE(op_resolve_skip) {
2318         /* resolve_skip dst(r) property(id) skip(n)
2319
2320          Looks up the property named by identifier property in the
2321          scope chain skipping the top 'skip' levels, and writes the resulting
2322          value to register dst. If the property is not found, raises an exception.
2323          */
2324         if (UNLIKELY(!resolveSkip(callFrame, vPC, exceptionValue)))
2325             goto vm_throw;
2326
2327         vPC += 4;
2328
2329         NEXT_OPCODE;
2330     }
2331     BEGIN_OPCODE(op_resolve_global) {
2332         /* resolve_skip dst(r) globalObject(c) property(id) structureID(sID) offset(n)
2333          
2334            Performs a dynamic property lookup for the given property, on the provided
2335            global object.  If structureID matches the StructureID of the global then perform
2336            a fast lookup using the case offset, otherwise fall back to a full resolve and
2337            cache the new structureID and offset
2338          */
2339         if (UNLIKELY(!resolveGlobal(callFrame, vPC, exceptionValue)))
2340             goto vm_throw;
2341         
2342         vPC += 6;
2343         
2344         NEXT_OPCODE;
2345     }
2346     BEGIN_OPCODE(op_get_global_var) {
2347         /* get_global_var dst(r) globalObject(c) index(n)
2348
2349            Gets the global var at global slot index and places it in register dst.
2350          */
2351         int dst = (++vPC)->u.operand;
2352         JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
2353         ASSERT(scope->isGlobalObject());
2354         int index = (++vPC)->u.operand;
2355
2356         callFrame[dst] = scope->registerAt(index);
2357         ++vPC;
2358         NEXT_OPCODE;
2359     }
2360     BEGIN_OPCODE(op_put_global_var) {
2361         /* put_global_var globalObject(c) index(n) value(r)
2362          
2363            Puts value into global slot index.
2364          */
2365         JSGlobalObject* scope = static_cast<JSGlobalObject*>((++vPC)->u.jsCell);
2366         ASSERT(scope->isGlobalObject());
2367         int index = (++vPC)->u.operand;
2368         int value = (++vPC)->u.operand;
2369         
2370         scope->registerAt(index) = callFrame[value].jsValue(callFrame);
2371         ++vPC;
2372         NEXT_OPCODE;
2373     }            
2374     BEGIN_OPCODE(op_get_scoped_var) {
2375         /* get_scoped_var dst(r) index(n) skip(n)
2376
2377          Loads the contents of the index-th local from the scope skip nodes from
2378          the top of the scope chain, and places it in register dst
2379          */
2380         int dst = (++vPC)->u.operand;
2381         int index = (++vPC)->u.operand;
2382         int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain;
2383
2384         ScopeChainNode* scopeChain = callFrame->scopeChain();
2385         ScopeChainIterator iter = scopeChain->begin();
2386         ScopeChainIterator end = scopeChain->end();
2387         ASSERT(iter != end);
2388         while (skip--) {
2389             ++iter;
2390             ASSERT(iter != end);
2391         }
2392
2393         ASSERT((*iter)->isVariableObject());
2394         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
2395         callFrame[dst] = scope->registerAt(index);
2396         ++vPC;
2397         NEXT_OPCODE;
2398     }
2399     BEGIN_OPCODE(op_put_scoped_var) {
2400         /* put_scoped_var index(n) skip(n) value(r)
2401
2402          */
2403         int index = (++vPC)->u.operand;
2404         int skip = (++vPC)->u.operand + callFrame->codeBlock()->needsFullScopeChain;
2405         int value = (++vPC)->u.operand;
2406
2407         ScopeChainNode* scopeChain = callFrame->scopeChain();
2408         ScopeChainIterator iter = scopeChain->begin();
2409         ScopeChainIterator end = scopeChain->end();
2410         ASSERT(iter != end);
2411         while (skip--) {
2412             ++iter;
2413             ASSERT(iter != end);
2414         }
2415
2416         ASSERT((*iter)->isVariableObject());
2417         JSVariableObject* scope = static_cast<JSVariableObject*>(*iter);
2418         scope->registerAt(index) = callFrame[value].jsValue(callFrame);
2419         ++vPC;
2420         NEXT_OPCODE;
2421     }
2422     BEGIN_OPCODE(op_resolve_base) {
2423         /* resolve_base dst(r) property(id)
2424
2425            Searches the scope chain for an object containing
2426            identifier property, and if one is found, writes it to
2427            register dst. If none is found, the outermost scope (which
2428            will be the global object) is stored in register dst.
2429         */
2430         resolveBase(callFrame, vPC);
2431
2432         vPC += 3;
2433         NEXT_OPCODE;
2434     }
2435     BEGIN_OPCODE(op_resolve_with_base) {
2436         /* resolve_with_base baseDst(r) propDst(r) property(id)
2437
2438            Searches the scope chain for an object containing
2439            identifier property, and if one is found, writes it to
2440            register srcDst, and the retrieved property value to register
2441            propDst. If the property is not found, raises an exception.
2442
2443            This is more efficient than doing resolve_base followed by
2444            resolve, or resolve_base followed by get_by_id, as it
2445            avoids duplicate hash lookups.
2446         */
2447         if (UNLIKELY(!resolveBaseAndProperty(callFrame, vPC, exceptionValue)))
2448             goto vm_throw;
2449
2450         vPC += 4;
2451         NEXT_OPCODE;
2452     }
2453     BEGIN_OPCODE(op_resolve_func) {
2454         /* resolve_func baseDst(r) funcDst(r) property(id)
2455
2456            Searches the scope chain for an object containing
2457            identifier property, and if one is found, writes the
2458            appropriate object to use as "this" when calling its
2459            properties to register baseDst; and the retrieved property
2460            value to register propDst. If the property is not found,
2461            raises an exception.
2462
2463            This differs from resolve_with_base, because the
2464            global this value will be substituted for activations or
2465            the global object, which is the right behavior for function
2466            calls but not for other property lookup.
2467         */
2468         if (UNLIKELY(!resolveBaseAndFunc(callFrame, vPC, exceptionValue)))
2469             goto vm_throw;
2470
2471         vPC += 4;
2472         NEXT_OPCODE;
2473     }
2474     BEGIN_OPCODE(op_get_by_id) {
2475         /* get_by_id dst(r) base(r) property(id) structureID(sID) nop(n) nop(n) nop(n)
2476
2477            Generic property access: Gets the property named by identifier
2478            property from the value base, and puts the result in register dst.
2479         */
2480         int dst = vPC[1].u.operand;
2481         int base = vPC[2].u.operand;
2482         int property = vPC[3].u.operand;
2483
2484         CodeBlock* codeBlock = callFrame->codeBlock();
2485         Identifier& ident = codeBlock->identifiers[property];
2486         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2487         PropertySlot slot(baseValue);
2488         JSValuePtr result = baseValue->get(callFrame, ident, slot);
2489         VM_CHECK_EXCEPTION();
2490
2491         tryCacheGetByID(callFrame, codeBlock, vPC, baseValue, ident, slot);
2492
2493         callFrame[dst] = result;
2494         vPC += 8;
2495         NEXT_OPCODE;
2496     }
2497     BEGIN_OPCODE(op_get_by_id_self) {
2498         /* op_get_by_id_self dst(r) base(r) property(id) structureID(sID) offset(n) nop(n) nop(n)
2499
2500            Cached property access: Attempts to get a cached property from the
2501            value base. If the cache misses, op_get_by_id_self reverts to
2502            op_get_by_id.
2503         */
2504         int base = vPC[2].u.operand;
2505         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2506
2507         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2508             JSCell* baseCell = asCell(baseValue);
2509             StructureID* structureID = vPC[4].u.structureID;
2510
2511             if (LIKELY(baseCell->structureID() == structureID)) {
2512                 ASSERT(baseCell->isObject());
2513                 JSObject* baseObject = asObject(baseCell);
2514                 int dst = vPC[1].u.operand;
2515                 int offset = vPC[5].u.operand;
2516
2517                 ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == baseObject->getDirectOffset(offset));
2518                 callFrame[dst] = baseObject->getDirectOffset(offset);
2519
2520                 vPC += 8;
2521                 NEXT_OPCODE;
2522             }
2523         }
2524
2525         uncacheGetByID(callFrame->codeBlock(), vPC);
2526         NEXT_OPCODE;
2527     }
2528     BEGIN_OPCODE(op_get_by_id_proto) {
2529         /* op_get_by_id_proto dst(r) base(r) property(id) structureID(sID) protoStructureID(sID) offset(n) nop(n)
2530
2531            Cached property access: Attempts to get a cached property from the
2532            value base's prototype. If the cache misses, op_get_by_id_proto
2533            reverts to op_get_by_id.
2534         */
2535         int base = vPC[2].u.operand;
2536         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2537
2538         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2539             JSCell* baseCell = asCell(baseValue);
2540             StructureID* structureID = vPC[4].u.structureID;
2541
2542             if (LIKELY(baseCell->structureID() == structureID)) {
2543                 ASSERT(structureID->prototypeForLookup(callFrame)->isObject());
2544                 JSObject* protoObject = asObject(structureID->prototypeForLookup(callFrame));
2545                 StructureID* protoStructureID = vPC[5].u.structureID;
2546
2547                 if (LIKELY(protoObject->structureID() == protoStructureID)) {
2548                     int dst = vPC[1].u.operand;
2549                     int offset = vPC[6].u.operand;
2550
2551                     ASSERT(protoObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == protoObject->getDirectOffset(offset));
2552                     callFrame[dst] = protoObject->getDirectOffset(offset);
2553
2554                     vPC += 8;
2555                     NEXT_OPCODE;
2556                 }
2557             }
2558         }
2559
2560         uncacheGetByID(callFrame->codeBlock(), vPC);
2561         NEXT_OPCODE;
2562     }
2563     BEGIN_OPCODE(op_get_by_id_chain) {
2564         /* op_get_by_id_chain dst(r) base(r) property(id) structureID(sID) structureIDChain(sIDc) count(n) offset(n)
2565
2566            Cached property access: Attempts to get a cached property from the
2567            value base's prototype chain. If the cache misses, op_get_by_id_chain
2568            reverts to op_get_by_id.
2569         */
2570         int base = vPC[2].u.operand;
2571         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2572
2573         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2574             JSCell* baseCell = asCell(baseValue);
2575             StructureID* structureID = vPC[4].u.structureID;
2576
2577             if (LIKELY(baseCell->structureID() == structureID)) {
2578                 RefPtr<StructureID>* it = vPC[5].u.structureIDChain->head();
2579                 size_t count = vPC[6].u.operand;
2580                 RefPtr<StructureID>* end = it + count;
2581
2582                 JSObject* baseObject = asObject(baseCell);
2583                 while (1) {
2584                     baseObject = asObject(baseObject->structureID()->prototypeForLookup(callFrame));
2585                     if (UNLIKELY(baseObject->structureID() != (*it).get()))
2586                         break;
2587
2588                     if (++it == end) {
2589                         int dst = vPC[1].u.operand;
2590                         int offset = vPC[7].u.operand;
2591
2592                         ASSERT(baseObject->get(callFrame, callFrame->codeBlock()->identifiers[vPC[3].u.operand]) == baseObject->getDirectOffset(offset));
2593                         callFrame[dst] = baseObject->getDirectOffset(offset);
2594
2595                         vPC += 8;
2596                         NEXT_OPCODE;
2597                     }
2598                 }
2599             }
2600         }
2601
2602         uncacheGetByID(callFrame->codeBlock(), vPC);
2603         NEXT_OPCODE;
2604     }
2605     BEGIN_OPCODE(op_get_by_id_generic) {
2606         /* op_get_by_id_generic dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
2607
2608            Generic property access: Gets the property named by identifier
2609            property from the value base, and puts the result in register dst.
2610         */
2611         int dst = vPC[1].u.operand;
2612         int base = vPC[2].u.operand;
2613         int property = vPC[3].u.operand;
2614
2615         Identifier& ident = callFrame->codeBlock()->identifiers[property];
2616         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2617         PropertySlot slot(baseValue);
2618         JSValuePtr result = baseValue->get(callFrame, ident, slot);
2619         VM_CHECK_EXCEPTION();
2620
2621         callFrame[dst] = result;
2622         vPC += 8;
2623         NEXT_OPCODE;
2624     }
2625     BEGIN_OPCODE(op_get_array_length) {
2626         /* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
2627
2628            Cached property access: Gets the length of the array in register base,
2629            and puts the result in register dst. If register base does not hold
2630            an array, op_get_array_length reverts to op_get_by_id.
2631         */
2632
2633         int base = vPC[2].u.operand;
2634         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2635         if (LIKELY(isJSArray(baseValue))) {
2636             int dst = vPC[1].u.operand;
2637             callFrame[dst] = jsNumber(callFrame, asArray(baseValue)->length());
2638             vPC += 8;
2639             NEXT_OPCODE;
2640         }
2641
2642         uncacheGetByID(callFrame->codeBlock(), vPC);
2643         NEXT_OPCODE;
2644     }
2645     BEGIN_OPCODE(op_get_string_length) {
2646         /* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
2647
2648            Cached property access: Gets the length of the string in register base,
2649            and puts the result in register dst. If register base does not hold
2650            a string, op_get_string_length reverts to op_get_by_id.
2651         */
2652
2653         int base = vPC[2].u.operand;
2654         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2655         if (LIKELY(isJSString(baseValue))) {
2656             int dst = vPC[1].u.operand;
2657             callFrame[dst] = jsNumber(callFrame, asString(baseValue)->value().size());
2658             vPC += 8;
2659             NEXT_OPCODE;
2660         }
2661
2662         uncacheGetByID(callFrame->codeBlock(), vPC);
2663         NEXT_OPCODE;
2664     }
2665     BEGIN_OPCODE(op_put_by_id) {
2666         /* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n)
2667
2668            Generic property access: Sets the property named by identifier
2669            property, belonging to register base, to register value.
2670
2671            Unlike many opcodes, this one does not write any output to
2672            the register file.
2673         */
2674
2675         int base = vPC[1].u.operand;
2676         int property = vPC[2].u.operand;
2677         int value = vPC[3].u.operand;
2678
2679         CodeBlock* codeBlock = callFrame->codeBlock();
2680         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2681         Identifier& ident = codeBlock->identifiers[property];
2682         PutPropertySlot slot;
2683         baseValue->put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
2684         VM_CHECK_EXCEPTION();
2685
2686         tryCachePutByID(callFrame, codeBlock, vPC, baseValue, slot);
2687
2688         vPC += 8;
2689         NEXT_OPCODE;
2690     }
2691     BEGIN_OPCODE(op_put_by_id_transition) {
2692         /* op_put_by_id_transition base(r) property(id) value(r) oldStructureID(sID) newStructureID(sID) structureIDChain(sIDc) offset(n)
2693          
2694            Cached property access: Attempts to set a new property with a cached transition
2695            property named by identifier property, belonging to register base,
2696            to register value. If the cache misses, op_put_by_id_transition
2697            reverts to op_put_by_id_generic.
2698          
2699            Unlike many opcodes, this one does not write any output to
2700            the register file.
2701          */
2702         int base = vPC[1].u.operand;
2703         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2704         
2705         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2706             JSCell* baseCell = asCell(baseValue);
2707             StructureID* oldStructureID = vPC[4].u.structureID;
2708             StructureID* newStructureID = vPC[5].u.structureID;
2709             
2710             if (LIKELY(baseCell->structureID() == oldStructureID)) {
2711                 ASSERT(baseCell->isObject());
2712                 JSObject* baseObject = asObject(baseCell);
2713
2714                 RefPtr<StructureID>* it = vPC[6].u.structureIDChain->head();
2715
2716                 JSValuePtr proto = baseObject->structureID()->prototypeForLookup(callFrame);
2717                 while (!proto->isNull()) {
2718                     if (UNLIKELY(asObject(proto)->structureID() != (*it).get())) {
2719                         uncachePutByID(callFrame->codeBlock(), vPC);
2720                         NEXT_OPCODE;
2721                     }
2722                     ++it;
2723                     proto = asObject(proto)->structureID()->prototypeForLookup(callFrame);
2724                 }
2725
2726                 baseObject->transitionTo(newStructureID);
2727
2728                 int value = vPC[3].u.operand;
2729                 unsigned offset = vPC[7].u.operand;
2730                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifiers[vPC[2].u.operand])) == offset);
2731                 baseObject->putDirectOffset(offset, callFrame[value].jsValue(callFrame));
2732
2733                 vPC += 8;
2734                 NEXT_OPCODE;
2735             }
2736         }
2737         
2738         uncachePutByID(callFrame->codeBlock(), vPC);
2739         NEXT_OPCODE;
2740     }
2741     BEGIN_OPCODE(op_put_by_id_replace) {
2742         /* op_put_by_id_replace base(r) property(id) value(r) structureID(sID) offset(n) nop(n) nop(n)
2743
2744            Cached property access: Attempts to set a pre-existing, cached
2745            property named by identifier property, belonging to register base,
2746            to register value. If the cache misses, op_put_by_id_replace
2747            reverts to op_put_by_id.
2748
2749            Unlike many opcodes, this one does not write any output to
2750            the register file.
2751         */
2752         int base = vPC[1].u.operand;
2753         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2754
2755         if (LIKELY(!JSImmediate::isImmediate(baseValue))) {
2756             JSCell* baseCell = asCell(baseValue);
2757             StructureID* structureID = vPC[4].u.structureID;
2758
2759             if (LIKELY(baseCell->structureID() == structureID)) {
2760                 ASSERT(baseCell->isObject());
2761                 JSObject* baseObject = asObject(baseCell);
2762                 int value = vPC[3].u.operand;
2763                 unsigned offset = vPC[5].u.operand;
2764                 
2765                 ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(callFrame->codeBlock()->identifiers[vPC[2].u.operand])) == offset);
2766                 baseObject->putDirectOffset(offset, callFrame[value].jsValue(callFrame));
2767
2768                 vPC += 8;
2769                 NEXT_OPCODE;
2770             }
2771         }
2772
2773         uncachePutByID(callFrame->codeBlock(), vPC);
2774         NEXT_OPCODE;
2775     }
2776     BEGIN_OPCODE(op_put_by_id_generic) {
2777         /* op_put_by_id_generic base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n)
2778
2779            Generic property access: Sets the property named by identifier
2780            property, belonging to register base, to register value.
2781
2782            Unlike many opcodes, this one does not write any output to
2783            the register file.
2784         */
2785         int base = vPC[1].u.operand;
2786         int property = vPC[2].u.operand;
2787         int value = vPC[3].u.operand;
2788
2789         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2790         Identifier& ident = callFrame->codeBlock()->identifiers[property];
2791         PutPropertySlot slot;
2792         baseValue->put(callFrame, ident, callFrame[value].jsValue(callFrame), slot);
2793         VM_CHECK_EXCEPTION();
2794
2795         vPC += 8;
2796         NEXT_OPCODE;
2797     }
2798     BEGIN_OPCODE(op_del_by_id) {
2799         /* del_by_id dst(r) base(r) property(id)
2800
2801            Converts register base to Object, deletes the property
2802            named by identifier property from the object, and writes a
2803            boolean indicating success (if true) or failure (if false)
2804            to register dst.
2805         */
2806         int dst = (++vPC)->u.operand;
2807         int base = (++vPC)->u.operand;
2808         int property = (++vPC)->u.operand;
2809
2810         JSObject* baseObj = callFrame[base].jsValue(callFrame)->toObject(callFrame);
2811         Identifier& ident = callFrame->codeBlock()->identifiers[property];
2812         JSValuePtr result = jsBoolean(baseObj->deleteProperty(callFrame, ident));
2813         VM_CHECK_EXCEPTION();
2814         callFrame[dst] = result;
2815         ++vPC;
2816         NEXT_OPCODE;
2817     }
2818     BEGIN_OPCODE(op_get_by_val) {
2819         /* get_by_val dst(r) base(r) property(r)
2820
2821            Converts register base to Object, gets the property named
2822            by register property from the object, and puts the result
2823            in register dst. property is nominally converted to string
2824            but numbers are treated more efficiently.
2825         */
2826         int dst = (++vPC)->u.operand;
2827         int base = (++vPC)->u.operand;
2828         int property = (++vPC)->u.operand;
2829         
2830         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2831         JSValuePtr subscript = callFrame[property].jsValue(callFrame);
2832
2833         JSValuePtr result;
2834         unsigned i;
2835
2836         bool isUInt32 = JSImmediate::getUInt32(subscript, i);
2837         if (LIKELY(isUInt32)) {
2838             if (isJSArray(baseValue)) {
2839                 JSArray* jsArray = asArray(baseValue);
2840                 if (jsArray->canGetIndex(i))
2841                     result = jsArray->getIndex(i);
2842                 else
2843                     result = jsArray->JSArray::get(callFrame, i);
2844             } else if (isJSString(baseValue) && asString(baseValue)->canGetIndex(i))
2845                 result = asString(baseValue)->getIndex(&callFrame->globalData(), i);
2846             else
2847                 result = baseValue->get(callFrame, i);
2848         } else {
2849             Identifier property(callFrame, subscript->toString(callFrame));
2850             result = baseValue->get(callFrame, property);
2851         }
2852
2853         VM_CHECK_EXCEPTION();
2854         callFrame[dst] = result;
2855         ++vPC;
2856         NEXT_OPCODE;
2857     }
2858     BEGIN_OPCODE(op_put_by_val) {
2859         /* put_by_val base(r) property(r) value(r)
2860
2861            Sets register value on register base as the property named
2862            by register property. Base is converted to object
2863            first. register property is nominally converted to string
2864            but numbers are treated more efficiently.
2865
2866            Unlike many opcodes, this one does not write any output to
2867            the register file.
2868         */
2869         int base = (++vPC)->u.operand;
2870         int property = (++vPC)->u.operand;
2871         int value = (++vPC)->u.operand;
2872
2873         JSValuePtr baseValue = callFrame[base].jsValue(callFrame);
2874         JSValuePtr subscript = callFrame[property].jsValue(callFrame);
2875
2876         unsigned i;
2877
2878         bool isUInt32 = JSImmediate::getUInt32(subscript, i);
2879         if (LIKELY(isUInt32)) {
2880             if (isJSArray(baseValue)) {
2881                 JSArray* jsArray = asArray(baseValue);
2882                 if (jsArray->canSetIndex(i))
2883                     jsArray->setIndex(i, callFrame[value].jsValue(callFrame));
2884                 else
2885                     jsArray->JSArray::put(callFrame, i, callFrame[value].jsValue(callFrame));
2886             } else
2887                 baseValue->put(callFrame, i, callFrame[value].jsValue(callFrame));
2888         } else {
2889             Identifier property(callFrame, subscript->toString(callFrame));
2890             if (!globalData->exception) { // Don't put to an object if toString threw an exception.
2891                 PutPropertySlot slot;
2892                 baseValue->put(callFrame, property, callFrame[value].jsValue(callFrame), slot);
2893             }
2894         }
2895
2896         VM_CHECK_EXCEPTION();
2897         ++vPC;
2898         NEXT_OPCODE;
2899     }
2900     BEGIN_OPCODE(op_del_by_val) {
2901         /* del_by_val dst(r) base(r) property(r)
2902
2903            Converts register base to Object, deletes the property
2904            named by register property from the object, and writes a
2905            boolean indicating success (if true) or failure (if false)
2906            to register dst.
2907         */
2908         int dst = (++vPC)->u.operand;
2909         int base = (++vPC)->u.operand;
2910         int property = (++vPC)->u.operand;
2911
2912         JSObject* baseObj = callFrame[base].jsValue(callFrame)->toObject(callFrame); // may throw
2913
2914         JSValuePtr subscript = callFrame[property].jsValue(callFrame);
2915         JSValuePtr result;
2916         uint32_t i;
2917         if (subscript->getUInt32(i))
2918             result = jsBoolean(baseObj->deleteProperty(callFrame, i));
2919         else {
2920             VM_CHECK_EXCEPTION();
2921             Identifier property(callFrame, subscript->toString(callFrame));
2922             VM_CHECK_EXCEPTION();
2923             result = jsBoolean(baseObj->deleteProperty(callFrame, property));
2924         }
2925
2926         VM_CHECK_EXCEPTION();
2927         callFrame[dst] = result;
2928         ++vPC;
2929         NEXT_OPCODE;
2930     }
2931     BEGIN_OPCODE(op_put_by_index) {
2932         /* put_by_index base(r) property(n) value(r)
2933
2934            Sets register value on register base as the property named
2935            by the immediate number property. Base is converted to
2936            object first.
2937
2938            Unlike many opcodes, this one does not write any output to
2939            the register file.
2940
2941            This opcode is mainly used to initialize array literals.
2942         */
2943         int base = (++vPC)->u.operand;
2944         unsigned property = (++vPC)->u.operand;
2945         int value = (++vPC)->u.operand;
2946
2947         callFrame[base].jsValue(callFrame)->put(callFrame, property, callFrame[value].jsValue(callFrame));
2948
2949         ++vPC;
2950         NEXT_OPCODE;
2951     }
2952     BEGIN_OPCODE(op_loop) {
2953         /* loop target(offset)
2954          
2955            Jumps unconditionally to offset target from the current
2956            instruction.
2957
2958            Additionally this loop instruction may terminate JS execution is
2959            the JS timeout is reached.
2960          */
2961 #if DUMP_OPCODE_STATS
2962         OpcodeStats::resetLastInstruction();
2963 #endif
2964         int target = (++vPC)->u.operand;
2965         CHECK_FOR_TIMEOUT();
2966         vPC += target;
2967         NEXT_OPCODE;
2968     }
2969     BEGIN_OPCODE(op_jmp) {
2970         /* jmp target(offset)
2971
2972            Jumps unconditionally to offset target from the current
2973            instruction.
2974         */
2975 #if DUMP_OPCODE_STATS
2976         OpcodeStats::resetLastInstruction();
2977 #endif
2978         int target = (++vPC)->u.operand;
2979
2980         vPC += target;
2981         NEXT_OPCODE;
2982     }
2983     BEGIN_OPCODE(op_loop_if_true) {
2984         /* loop_if_true cond(r) target(offset)
2985          
2986            Jumps to offset target from the current instruction, if and
2987            only if register cond converts to boolean as true.
2988
2989            Additionally this loop instruction may terminate JS execution is
2990            the JS timeout is reached.
2991          */
2992         int cond = (++vPC)->u.operand;
2993         int target = (++vPC)->u.operand;
2994         if (callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
2995             vPC += target;
2996             CHECK_FOR_TIMEOUT();
2997             NEXT_OPCODE;
2998         }
2999         
3000         ++vPC;
3001         NEXT_OPCODE;
3002     }
3003     BEGIN_OPCODE(op_jtrue) {
3004         /* jtrue cond(r) target(offset)
3005
3006            Jumps to offset target from the current instruction, if and
3007            only if register cond converts to boolean as true.
3008         */
3009         int cond = (++vPC)->u.operand;
3010         int target = (++vPC)->u.operand;
3011         if (callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
3012             vPC += target;
3013             NEXT_OPCODE;
3014         }
3015
3016         ++vPC;
3017         NEXT_OPCODE;
3018     }
3019     BEGIN_OPCODE(op_jfalse) {
3020         /* jfalse cond(r) target(offset)
3021
3022            Jumps to offset target from the current instruction, if and
3023            only if register cond converts to boolean as false.
3024         */
3025         int cond = (++vPC)->u.operand;
3026         int target = (++vPC)->u.operand;
3027         if (!callFrame[cond].jsValue(callFrame)->toBoolean(callFrame)) {
3028             vPC += target;
3029             NEXT_OPCODE;
3030         }
3031
3032         ++vPC;
3033         NEXT_OPCODE;
3034     }
3035     BEGIN_OPCODE(op_jeq_null) {
3036         /* jeq_null src(r) target(offset)
3037
3038            Jumps to offset target from the current instruction, if and
3039            only if register src is null.
3040         */
3041         int src = (++vPC)->u.operand;
3042         int target = (++vPC)->u.operand;
3043         JSValuePtr srcValue = callFrame[src].jsValue(callFrame);
3044
3045         if (srcValue->isUndefinedOrNull() || (!JSImmediate::isImmediate(srcValue) && srcValue->asCell()->structureID()->typeInfo().masqueradesAsUndefined())) {
3046             vPC += target;
3047             NEXT_OPCODE;
3048         }
3049
3050         ++vPC;
3051         NEXT_OPCODE;
3052     }
3053     BEGIN_OPCODE(op_jneq_null) {
3054         /* jneq_null src(r) target(offset)
3055
3056            Jumps to offset target from the current instruction, if and
3057            only if register src is not null.
3058         */
3059         int src = (++vPC)->u.operand;
3060         int target = (++vPC)->u.operand;
3061         JSValuePtr srcValue = callFrame[src].jsValue(callFrame);
3062
3063         if (!srcValue->isUndefinedOrNull() || (!JSImmediate::isImmediate(srcValue) && !srcValue->asCell()->structureID()->typeInfo().masqueradesAsUndefined())) {
3064             vPC += target;
3065             NEXT_OPCODE;
3066         }
3067
3068         ++vPC;
3069         NEXT_OPCODE;
3070     }
3071     BEGIN_OPCODE(op_loop_if_less) {
3072         /* loop_if_less src1(r) src2(r) target(offset)
3073
3074            Checks whether register src1 is less than register src2, as
3075            with the ECMAScript '<' operator, and then jumps to offset
3076            target from the current instruction, if and only if the 
3077            result of the comparison is true.
3078
3079            Additionally this loop instruction may terminate JS execution is
3080            the JS timeout is reached.
3081          */
3082         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3083         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3084         int target = (++vPC)->u.operand;
3085         
3086         bool result = jsLess(callFrame, src1, src2);
3087         VM_CHECK_EXCEPTION();
3088         
3089         if (result) {
3090             vPC += target;
3091             CHECK_FOR_TIMEOUT();
3092             NEXT_OPCODE;
3093         }
3094         
3095         ++vPC;
3096         NEXT_OPCODE;
3097     }
3098     BEGIN_OPCODE(op_loop_if_lesseq) {
3099         /* loop_if_lesseq src1(r) src2(r) target(offset)
3100
3101            Checks whether register src1 is less than or equal to register
3102            src2, as with the ECMAScript '<=' operator, and then jumps to
3103            offset target from the current instruction, if and only if the 
3104            result of the comparison is true.
3105
3106            Additionally this loop instruction may terminate JS execution is
3107            the JS timeout is reached.
3108         */
3109         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3110         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3111         int target = (++vPC)->u.operand;
3112         
3113         bool result = jsLessEq(callFrame, src1, src2);
3114         VM_CHECK_EXCEPTION();
3115         
3116         if (result) {
3117             vPC += target;
3118             CHECK_FOR_TIMEOUT();
3119             NEXT_OPCODE;
3120         }
3121         
3122         ++vPC;
3123         NEXT_OPCODE;
3124     }
3125     BEGIN_OPCODE(op_jnless) {
3126         /* jnless src1(r) src2(r) target(offset)
3127
3128            Checks whether register src1 is less than register src2, as
3129            with the ECMAScript '<' operator, and then jumps to offset
3130            target from the current instruction, if and only if the 
3131            result of the comparison is false.
3132         */
3133         JSValuePtr src1 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3134         JSValuePtr src2 = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3135         int target = (++vPC)->u.operand;
3136
3137         bool result = jsLess(callFrame, src1, src2);
3138         VM_CHECK_EXCEPTION();
3139         
3140         if (!result) {
3141             vPC += target;
3142             NEXT_OPCODE;
3143         }
3144
3145         ++vPC;
3146         NEXT_OPCODE;
3147     }
3148     BEGIN_OPCODE(op_switch_imm) {
3149         /* switch_imm tableIndex(n) defaultOffset(offset) scrutinee(r)
3150
3151            Performs a range checked switch on the scrutinee value, using
3152            the tableIndex-th immediate switch jump table.  If the scrutinee value
3153            is an immediate number in the range covered by the referenced jump
3154            table, and the value at jumpTable[scrutinee value] is non-zero, then
3155            that value is used as the jump offset, otherwise defaultOffset is used.
3156          */
3157         int tableIndex = (++vPC)->u.operand;
3158         int defaultOffset = (++vPC)->u.operand;
3159         JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3160         if (!JSImmediate::isNumber(scrutinee))
3161             vPC += defaultOffset;
3162         else {
3163             int32_t value = JSImmediate::getTruncatedInt32(scrutinee);
3164             vPC += callFrame->codeBlock()->immediateSwitchJumpTables[tableIndex].offsetForValue(value, defaultOffset);
3165         }
3166         NEXT_OPCODE;
3167     }
3168     BEGIN_OPCODE(op_switch_char) {
3169         /* switch_char tableIndex(n) defaultOffset(offset) scrutinee(r)
3170
3171            Performs a range checked switch on the scrutinee value, using
3172            the tableIndex-th character switch jump table.  If the scrutinee value
3173            is a single character string in the range covered by the referenced jump
3174            table, and the value at jumpTable[scrutinee value] is non-zero, then
3175            that value is used as the jump offset, otherwise defaultOffset is used.
3176          */
3177         int tableIndex = (++vPC)->u.operand;
3178         int defaultOffset = (++vPC)->u.operand;
3179         JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3180         if (!scrutinee->isString())
3181             vPC += defaultOffset;
3182         else {
3183             UString::Rep* value = asString(scrutinee)->value().rep();
3184             if (value->size() != 1)
3185                 vPC += defaultOffset;
3186             else
3187                 vPC += callFrame->codeBlock()->characterSwitchJumpTables[tableIndex].offsetForValue(value->data()[0], defaultOffset);
3188         }
3189         NEXT_OPCODE;
3190     }
3191     BEGIN_OPCODE(op_switch_string) {
3192         /* switch_string tableIndex(n) defaultOffset(offset) scrutinee(r)
3193
3194            Performs a sparse hashmap based switch on the value in the scrutinee
3195            register, using the tableIndex-th string switch jump table.  If the 
3196            scrutinee value is a string that exists as a key in the referenced 
3197            jump table, then the value associated with the string is used as the 
3198            jump offset, otherwise defaultOffset is used.
3199          */
3200         int tableIndex = (++vPC)->u.operand;
3201         int defaultOffset = (++vPC)->u.operand;
3202         JSValuePtr scrutinee = callFrame[(++vPC)->u.operand].jsValue(callFrame);
3203         if (!scrutinee->isString())
3204             vPC += defaultOffset;
3205         else 
3206             vPC += callFrame->codeBlock()->stringSwitchJumpTables[tableIndex].offsetForValue(asString(scrutinee)->value().rep(), defaultOffset);
3207         NEXT_OPCODE;
3208     }
3209     BEGIN_OPCODE(op_new_func) {
3210         /* new_func dst(r) func(f)
3211
3212            Constructs a new Function instance from function func and
3213            the current scope chain using the original Function
3214            constructor, using the rules for function declarations, and
3215            puts the result in register dst.
3216         */
3217         int dst = (++vPC)->u.operand;
3218         int func = (++vPC)->u.operand;
3219
3220         callFrame[dst] = callFrame->codeBlock()->functions[func]->makeFunction(callFrame, callFrame->scopeChain());
3221
3222         ++vPC;
3223         NEXT_OPCODE;
3224     }
3225     BEGIN_OPCODE(op_new_func_exp) {
3226         /* new_func_exp dst(r) func(f)
3227
3228            Constructs a new Function instance from function func and
3229            the current scope chain using the original Function
3230            constructor, using the rules for function expressions, and
3231            puts the result in register dst.
3232         */
3233         int dst = (++vPC)->u.operand;
3234         int func = (++vPC)->u.operand;
3235
3236         callFrame[dst] = callFrame->codeBlock()->functionExpressions[func]->makeFunction(callFrame, callFrame->scopeChain());
3237
3238         ++vPC;
3239         NEXT_OPCODE;
3240     }
3241     BEGIN_OPCODE(op_call_eval) {
3242         /* call_eval dst(r) func(r) thisVal(r) firstArg(r) argCount(n)
3243
3244            Call a function named "eval" with no explicit "this" value
3245            (which may therefore be the eval operator). If register
3246            thisVal is the global object, and register func contains
3247            that global object's original global eval function, then
3248            perform the eval operator in local scope (interpreting
3249            the argument registers as for the "call"
3250            opcode). Otherwise, act exactly as the "call" opcode would.
3251          */
3252
3253         int dst = vPC[1].u.operand;
3254         int func = vPC[2].u.operand;
3255         int thisVal = vPC[3].u.operand;
3256         int firstArg = vPC[4].u.operand;
3257         int argCount = vPC[5].u.operand;
3258
3259         JSValuePtr funcVal = callFrame[func].jsValue(callFrame);
3260         JSValuePtr baseVal = callFrame[thisVal].jsValue(callFrame);
3261
3262         ScopeChainNode* scopeChain = callFrame->scopeChain();
3263         if (baseVal == scopeChain->globalObject() && funcVal == scopeChain->globalObject()->evalFunction()) {
3264             JSObject* thisObject = asObject(callFrame[callFrame->codeBlock()->thisRegister].jsValue(callFrame));
3265             JSValuePtr result = callEval(callFrame, thisObject, scopeChain, registerFile, firstArg, argCount, exceptionValue);
3266             if (exceptionValue)
3267                 goto vm_throw;
3268
3269             callFrame[dst] = result;
3270
3271             vPC += 7;
3272             NEXT_OPCODE;
3273         }
3274
3275         // We didn't find the blessed version of eval, so reset vPC and process
3276         // this instruction as a normal function call, supplying the proper 'this'
3277         // value.
3278         callFrame[thisVal] = baseVal->toThisObject(callFrame);
3279
3280 #if HAVE(COMPUTED_GOTO)
3281         // Hack around gcc performance quirk by performing an indirect goto
3282         // in order to set the vPC -- attempting to do so directly results in a
3283         // significant regression.
3284         goto *op_call_indirect; // indirect goto -> op_call
3285 #endif
3286         // fall through to op_call
3287     }
3288     BEGIN_OPCODE(op_call) {
3289         /* call dst(r) func(r) thisVal(r) firstArg(r) argCount(n) registerOffset(n)
3290
3291            Perform a function call. Specifically, call register func
3292            with a "this" value of register thisVal, and put the result
3293            in register dst.
3294
3295            The arguments start at register firstArg and go up to
3296            argCount, but the "this" value is considered an implicit
3297            first argument, so the argCount should be one greater than
3298            the number of explicit arguments passed, and the register
3299            after firstArg should contain the actual first
3300            argument. This opcode will copy from the thisVal register
3301            to the firstArg register, unless the register index of
3302            thisVal is the special missing this object marker, which is
3303            2^31-1; in that case, the global object will be used as the
3304            "this" value.
3305
3306            If func is a native code function, then this opcode calls
3307            it and returns the value immediately. 
3308
3309            But if it is a JS function, then the current scope chain
3310            and code block is set to the function's, and we slide the
3311            register window so that the arguments would form the first
3312            few local registers of the called function's register
3313            window. In addition, a call frame header is written
3314            immediately before the arguments; see the call frame
3315            documentation for an explanation of how many registers a
3316            call frame takes and what they contain. That many registers
3317            before the firstArg register will be overwritten by the
3318            call. In addition, any registers higher than firstArg +
3319            argCount may be overwritten. Once this setup is complete,
3320            execution continues from the called function's first
3321            argument, and does not return until a "ret" opcode is
3322            encountered.
3323          */
3324
3325         int dst = vPC[1].u.operand;
3326         int func = vPC[2].u.operand;
3327         int thisVal = vPC[3].u.operand;
3328         int firstArg = vPC[4].u.operand;
3329         int argCount = vPC[5].u.operand;
3330         int registerOffset = vPC[6].u.operand;
3331
3332         JSValuePtr v = callFrame[func].jsValue(callFrame);
3333
3334         CallData callData;
3335         CallType callType = v->getCallData(callData);
3336
3337         if (callType == CallTypeJS) {
3338             ScopeChainNode* callDataScopeChain = callData.js.scopeChain;
3339             FunctionBodyNode* functionBodyNode = callData.js.functionBody;
3340             CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
3341
3342             callFrame[firstArg] = thisVal == missingThisObjectMarker() ? callFrame->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
3343             
3344             CallFrame* previousCallFrame = callFrame;
3345
3346             callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
3347             if (UNLIKELY(!callFrame)) {
3348                 callFrame = previousCallFrame;
3349                 exceptionValue = createStackOverflowError(callFrame);
3350                 goto vm_throw;
3351             }
3352
3353             callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
3354             vPC = newCodeBlock->instructions.begin();
3355
3356 #if DUMP_OPCODE_STATS
3357             OpcodeStats::resetLastInstruction();
3358 #endif
3359
3360             NEXT_OPCODE;
3361         }
3362
3363         if (callType == CallTypeHost) {
3364             JSValuePtr thisValue = thisVal == missingThisObjectMarker() ? callFrame->globalThisValue() : callFrame[thisVal].jsValue(callFrame);
3365             ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
3366
3367             ScopeChainNode* scopeChain = callFrame->scopeChain();
3368             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
3369             newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
3370
3371             MACHINE_SAMPLING_callingHostFunction();
3372
3373             JSValuePtr returnValue = callData.native.function(newCallFrame, asObject(v), thisValue, args);
3374             VM_CHECK_EXCEPTION();
3375
3376             callFrame[dst] = returnValue;
3377
3378             vPC += 7;
3379             NEXT_OPCODE;
3380         }
3381
3382         ASSERT(callType == CallTypeNone);
3383
3384         exceptionValue = createNotAFunctionError(callFrame, v, vPC, callFrame->codeBlock());
3385         goto vm_throw;
3386     }
3387     BEGIN_OPCODE(op_tear_off_activation) {
3388         /* tear_off_activation activation(r)
3389
3390            Copy all locals and parameters to new memory allocated on
3391            the heap, and make the passed activation use this memory
3392            in the future when looking up entries in the symbol table.
3393            If there is an 'arguments' object, then it will also use
3394            this memory for storing the named parameters, but not any
3395            extra arguments.
3396
3397            This opcode should only be used immediately before op_ret.
3398         */
3399
3400         int src = (++vPC)->u.operand;
3401         ASSERT(callFrame->codeBlock()->needsFullScopeChain);
3402
3403         asActivation(callFrame[src].getJSValue())->copyRegisters(callFrame->optionalCalleeArguments());
3404
3405         ++vPC;
3406         NEXT_OPCODE;
3407     }
3408     BEGIN_OPCODE(op_tear_off_arguments) {
3409         /* tear_off_arguments
3410
3411            Copy all arguments to new memory allocated on the heap,
3412            and make the 'arguments' object use this memory in the
3413            future when looking up named parameters, but not any
3414            extra arguments. If an activation object exists for the
3415            current function context, then the tear_off_activation
3416            opcode should be used instead.
3417
3418            This opcode should only be used immediately before op_ret.
3419         */
3420
3421         ASSERT(callFrame->codeBlock()->usesArguments && !callFrame->codeBlock()->needsFullScopeChain);
3422
3423         callFrame->optionalCalleeArguments()->copyRegisters();
3424
3425         ++vPC;
3426         NEXT_OPCODE;
3427     }
3428     BEGIN_OPCODE(op_ret) {
3429         /* ret result(r)
3430            
3431            Return register result as the return value of the current
3432            function call, writing it into the caller's expected return
3433            value register. In addition, unwind one call frame and
3434            restore the scope chain, code block instruction pointer and
3435            register base to those of the calling function.
3436         */
3437
3438         int result = (++vPC)->u.operand;
3439
3440         if (callFrame->codeBlock()->needsFullScopeChain)
3441             callFrame->scopeChain()->deref();
3442
3443         JSValuePtr returnValue = callFrame[result].jsValue(callFrame);
3444
3445         vPC = callFrame->returnPC();
3446         int dst = callFrame->returnValueRegister();
3447         callFrame = callFrame->callerFrame();
3448         
3449         if (callFrame->hasHostCallFrameFlag())
3450             return returnValue;
3451
3452         callFrame[dst] = returnValue;
3453
3454         NEXT_OPCODE;
3455     }
3456     BEGIN_OPCODE(op_enter) {
3457         /* enter
3458
3459            Initializes local variables to undefined and fills constant
3460            registers with their values. If the code block requires an
3461            activation, enter_with_activation should be used instead.
3462
3463            This opcode should only be used at the beginning of a code
3464            block.
3465         */
3466
3467         size_t i = 0;
3468         CodeBlock* codeBlock = callFrame->codeBlock();
3469         
3470         for (size_t count = codeBlock->numVars; i < count; ++i)
3471             callFrame[i] = jsUndefined();
3472
3473         for (size_t count = codeBlock->constantRegisters.size(), j = 0; j < count; ++i, ++j)
3474             callFrame[i] = codeBlock->constantRegisters[j];
3475
3476         ++vPC;
3477         NEXT_OPCODE;
3478     }
3479     BEGIN_OPCODE(op_enter_with_activation) {
3480         /* enter_with_activation dst(r)
3481
3482            Initializes local variables to undefined, fills constant
3483            registers with their values, creates an activation object,
3484            and places the new activation both in dst and at the top
3485            of the scope chain. If the code block does not require an
3486            activation, enter should be used instead.
3487
3488            This opcode should only be used at the beginning of a code
3489            block.
3490         */
3491
3492         size_t i = 0;
3493         CodeBlock* codeBlock = callFrame->codeBlock();
3494
3495         for (size_t count = codeBlock->numVars; i < count; ++i)
3496             callFrame[i] = jsUndefined();
3497
3498         for (size_t count = codeBlock->constantRegisters.size(), j = 0; j < count; ++i, ++j)
3499             callFrame[i] = codeBlock->constantRegisters[j];
3500
3501         int dst = (++vPC)->u.operand;
3502         JSActivation* activation = new (globalData) JSActivation(callFrame, static_cast<FunctionBodyNode*>(codeBlock->ownerNode));
3503         callFrame[dst] = activation;
3504         callFrame->setScopeChain(callFrame->scopeChain()->copy()->push(activation));
3505
3506         ++vPC;
3507         NEXT_OPCODE;
3508     }
3509     BEGIN_OPCODE(op_convert_this) {
3510         /* convert_this this(r)
3511
3512            Takes the value in the 'this' register, converts it to a
3513            value that is suitable for use as the 'this' value, and
3514            stores it in the 'this' register. This opcode is emitted
3515            to avoid doing the conversion in the caller unnecessarily.
3516
3517            This opcode should only be used at the beginning of a code
3518            block.
3519         */
3520
3521         int thisRegister = (++vPC)->u.operand;
3522         JSValuePtr thisVal = callFrame[thisRegister].getJSValue();
3523         if (thisVal->needsThisConversion())
3524             callFrame[thisRegister] = thisVal->toThisObject(callFrame);
3525
3526         ++vPC;
3527         NEXT_OPCODE;
3528     }
3529     BEGIN_OPCODE(op_create_arguments) {
3530         /* create_arguments
3531
3532            Creates the 'arguments' object and places it in both the
3533            'arguments' call frame slot and the local 'arguments'
3534            register.
3535
3536            This opcode should only be used at the beginning of a code
3537            block.
3538         */
3539
3540         Arguments* arguments = new (globalData) Arguments(callFrame);
3541         callFrame->setCalleeArguments(arguments);
3542         callFrame[RegisterFile::ArgumentsRegister] = arguments;
3543         
3544         ++vPC;
3545         NEXT_OPCODE;
3546     }
3547     BEGIN_OPCODE(op_construct) {
3548         /* construct dst(r) constr(r) constrProto(r) firstArg(r) argCount(n) registerOffset(n)
3549
3550            Invoke register "constr" as a constructor. For JS
3551            functions, the calling convention is exactly as for the
3552            "call" opcode, except that the "this" value is a newly
3553            created Object. For native constructors, a null "this"
3554            value is passed. In either case, the firstArg and argCount
3555            registers are interpreted as for the "call" opcode.
3556
3557            Register constrProto must contain the prototype property of
3558            register constsr. This is to enable polymorphic inline
3559            caching of this lookup.
3560         */
3561
3562         int dst = vPC[1].u.operand;
3563         int constr = vPC[2].u.operand;
3564         int constrProto = vPC[3].u.operand;
3565         int firstArg = vPC[4].u.operand;
3566         int argCount = vPC[5].u.operand;
3567         int registerOffset = vPC[6].u.operand;
3568
3569         JSValuePtr v = callFrame[constr].jsValue(callFrame);
3570
3571         ConstructData constructData;
3572         ConstructType constructType = v->getConstructData(constructData);
3573
3574         if (constructType == ConstructTypeJS) {
3575             ScopeChainNode* callDataScopeChain = constructData.js.scopeChain;
3576             FunctionBodyNode* functionBodyNode = constructData.js.functionBody;
3577             CodeBlock* newCodeBlock = &functionBodyNode->byteCode(callDataScopeChain);
3578
3579             StructureID* structure;
3580             JSValuePtr prototype = callFrame[constrProto].jsValue(callFrame);
3581             if (prototype->isObject())
3582                 structure = asObject(prototype)->inheritorID();
3583             else
3584                 structure = callDataScopeChain->globalObject()->emptyObjectStructure();
3585             JSObject* newObject = new (globalData) JSObject(structure);
3586
3587             callFrame[firstArg] = newObject; // "this" value
3588
3589             CallFrame* previousCallFrame = callFrame;
3590
3591             callFrame = slideRegisterWindowForCall(newCodeBlock, registerFile, callFrame, registerOffset, argCount);
3592             if (UNLIKELY(!callFrame)) {
3593                 callFrame = previousCallFrame;
3594                 exceptionValue = createStackOverflowError(callFrame);
3595                 goto vm_throw;
3596             }
3597
3598             callFrame->init(newCodeBlock, vPC + 7, callDataScopeChain, previousCallFrame, dst, argCount, asFunction(v));
3599             vPC = newCodeBlock->instructions.begin();
3600
3601 #if DUMP_OPCODE_STATS
3602             OpcodeStats::resetLastInstruction();
3603 #endif
3604
3605             NEXT_OPCODE;
3606         }
3607
3608         if (constructType == ConstructTypeHost) {
3609             ArgList args(callFrame->registers() + firstArg + 1, argCount - 1);
3610
3611             ScopeChainNode* scopeChain = callFrame->scopeChain();
3612             CallFrame* newCallFrame = CallFrame::create(callFrame->registers() + registerOffset);
3613             newCallFrame->init(0, vPC + 7, scopeChain, callFrame, dst, argCount, 0);
3614
3615             MACHINE_SAMPLING_callingHostFunction();
3616
3617             JSValuePtr returnValue = constructData.native.function(newCallFrame, asObject(v), args);
3618
3619             VM_CHECK_EXCEPTION();
3620             callFrame[dst] = returnValue;
3621
3622             vPC += 7;
3623             NEXT_OPCODE;
3624         }
3625
3626         ASSERT(constructType == ConstructTypeNone);
3627
3628         exceptionValue = createNotAConstructorError(callFrame, v, vPC, callFrame->codeBlock());
3629         goto vm_throw;
3630     }
3631     BEGIN_OPCODE(op_construct_verify) {
3632         /* construct_verify dst(r) override(r)
3633
3634            Verifies that register dst holds an object. If not, moves
3635            the object in register override to register dst.
3636         */
3637
3638         int dst = vPC[1].u.operand;;
3639         if (LIKELY(callFrame[dst].jsValue(callFrame)->isObject())) {
3640             vPC += 3;
3641             NEXT_OPCODE;
3642         }
3643
3644         int override = vPC[2].u.operand;
3645         callFrame[dst] = callFrame[override];
3646
3647         vPC += 3;
3648         NEXT_OPCODE;
3649     }
3650     BEGIN_OPCODE(op_push_scope) {
3651         /* push_scope scope(r)
3652
3653            Converts register scope to object, and pushes it onto the top
3654            of the current scope chain.
3655         */
3656         int scope = (++vPC)->u.operand;
3657         JSValuePtr v = callFrame[scope].jsValue(callFrame);
3658         JSObject* o = v->toObject(callFrame);
3659         VM_CHECK_EXCEPTION();
3660
3661         callFrame->setScopeChain(callFrame->scopeChain()->push(o));
3662
3663         ++vPC;
3664         NEXT_OPCODE;
3665     }
3666     BEGIN_OPCODE(op_pop_scope) {
3667         /* pop_scope
3668
3669            Removes the top item from the current scope chain.
3670         */
3671         callFrame->setScopeChain(callFrame->scopeChain()->pop());
3672
3673         ++vPC;
3674         NEXT_OPCODE;
3675     }
3676     BEGIN_OPCODE(op_get_pnames) {
3677         /* get_pnames dst(r) base(r)
3678
3679            Creates a property name list for register base and puts it
3680            in register dst. This is not a true JavaScript value, just
3681            a synthetic value used to keep the iteration state in a
3682            register.
3683         */
3684         int dst = (++vPC)->u.operand;
3685         int base = (++vPC)->u.operand;
3686
3687         callFrame[dst] = JSPropertyNameIterator::create(callFrame, callFrame[base].jsValue(callFrame));
3688         ++vPC;
3689         NEXT_OPCODE;
3690     }
3691     BEGIN_OPCODE(op_next_pname) {
3692         /* next_pname dst(r) iter(r) target(offset)
3693
3694            Tries to copies the next name from property name list in
3695            register iter. If there are names left, then copies one to
3696            register dst, and jumps to offset target. If there are none
3697            left, invalidates the iterator and continues to the next
3698            instruction.
3699         */
3700         int dst = (++vPC)->u.operand;
3701         int iter = (++vPC)->u.operand;
3702         int target = (++vPC)->u.operand;
3703
3704         JSPropertyNameIterator* it = callFrame[iter].propertyNameIterator();
3705         if (JSValuePtr temp = it->next(callFrame)) {
3706             CHECK_FOR_TIMEOUT();
3707             callFrame[dst] = temp;
3708             vPC += target;
3709             NEXT_OPCODE;
3710         }
3711         it->invalidate();
3712
3713         ++vPC;
3714         NEXT_OPCODE;
3715     }
3716     BEGIN_OPCODE(op_jmp_scopes) {
3717         /* jmp_scopes count(n) target(offset)
3718
3719            Removes the a number of items from the current scope chain
3720            specified by immediate number count, then jumps to offset
3721            target.
3722         */
3723         int count = (++vPC)->u.operand;
3724         int target = (++vPC)->u.operand;
3725
3726         ScopeChainNode* tmp = callFrame->scopeChain();
3727         while (count--)
3728             tmp = tmp->pop();
3729         callFrame->setScopeChain(tmp);
3730
3731         vPC += target;
3732         NEXT_OPCODE;
3733     }
3734 #if HAVE(COMPUTED_GOTO)
3735     // Appease GCC
3736     goto *(&&skip_new_scope);
3737 #endif
3738     BEGIN_OPCODE(op_push_new_scope) {
3739         /* new_scope dst(r) property(id) value(r)
3740          
3741            Constructs a new StaticScopeObject with property set to value.  That scope
3742            object is then pushed onto the ScopeChain.  The scope object is then stored
3743            in dst for GC.
3744          */
3745         callFrame->setScopeChain(createExceptionScope(callFrame, vPC));
3746
3747         vPC += 4;
3748         NEXT_OPCODE;
3749     }
3750 #if HAVE(COMPUTED_GOTO)
3751     skip_new_scope:
3752 #endif
3753     BEGIN_OPCODE(op_catch) {
3754         /* catch ex(r)
3755
3756            Retrieves the VMs current exception and puts it in register
3757            ex. This is only valid after an exception has been raised,
3758            and usually forms the beginning of an exception handler.
3759         */
3760         ASSERT(exceptionValue);
3761         ASSERT(!globalData->exception);
3762         int ex = (++vPC)->u.operand;
3763         callFrame[ex] = exceptionValue;
3764         exceptionValue = noValue();
3765
3766         ++vPC;
3767         NEXT_OPCODE;
3768     }
3769     BEGIN_OPCODE(op_throw) {
3770         /* throw ex(r)
3771
3772            Throws register ex as an exception. This involves three
3773            steps: first, it is set as the current exception in the
3774            VM's internal state, then the stack is unwound until an
3775            exception handler or a native code boundary is found, and
3776            then control resumes at the exception handler if any or
3777            else the script returns control to the nearest native caller.
3778         */
3779
3780         int ex = (++vPC)->u.operand;
3781         exceptionValue = callFrame[ex].jsValue(callFrame);
3782
3783         handlerVPC = throwException(callFrame, exceptionValue, vPC, true);
3784         if (!handlerVPC) {
3785             *exception = exceptionValue;
3786             return jsNull();
3787         }
3788
3789 #if HAVE(COMPUTED_GOTO)
3790         // Hack around gcc performance quirk by performing an indirect goto
3791         // in order to set the vPC -- attempting to do so directly results in a
3792         // significant regression.
3793         goto *op_throw_end_indirect; // indirect goto -> op_throw_end
3794     }
3795     op_throw_end: {
3796 #endif
3797
3798         vPC = handlerVPC;
3799         NEXT_OPCODE;
3800     }
3801     BEGIN_OPCODE(op_unexpected_load) {
3802         /* unexpected_load load dst(r) src(k)
3803
3804            Copies constant src to register dst.
3805         */
3806         int dst = (++vPC)->u.operand;
3807         int src = (++vPC)->u.operand;
3808         callFrame[dst] = callFrame->codeBlock()->unexpectedConstants[src];
3809
3810         ++vPC;
3811         NEXT_OPCODE;
3812     }
3813     BEGIN_OPCODE(op_new_error) {
3814         /* new_error dst(r) type(n) message(k)
3815
3816            Constructs a new Error instance using the original
3817            constructor, using immediate number n as the type and
3818            constant message as the message string. The result is
3819            written to register dst.
3820         */
3821         int dst = (++vPC)->u.operand;
3822         int type = (++vPC)->u.operand;
3823         int message = (++vPC)->u.operand;
3824
3825         CodeBlock* codeBlock = callFrame->codeBlock();
3826         callFrame[dst] = Error::create(callFrame, (ErrorType)type, codeBlock->unexpectedConstants[message]->toString(callFrame), codeBlock->lineNumberForVPC(vPC), codeBlock->ownerNode->sourceID(), codeBlock->ownerNode->sourceURL());
3827
3828         ++vPC;
3829         NEXT_OPCODE;
3830     }
3831     BEGIN_OPCODE(op_end) {
3832         /* end result(r)
3833            
3834            Return register result as the value of a global or eval
3835            program. Return control to the calling native code.
3836         */
3837
3838         if (callFrame->codeBlock()->needsFullScopeChain) {
3839             ScopeChainNode* scopeChain = callFrame->scopeChain();
3840             ASSERT(scopeChain->refCount > 1);
3841             scopeChain->deref();
3842         }
3843         int result = (++vPC)->u.operand;
3844         return callFrame[result].jsValue(callFrame);
3845     }
3846     BEGIN_OPCODE(op_put_getter) {
3847         /* put_getter base(r) property(id) function(r)
3848
3849            Sets register function on register base as the getter named
3850            by identifier property. Base and function are assumed to be
3851            objects as this op should only be used for getters defined
3852            in object literal form.
3853
3854            Unlike many opcodes, this one does not write any output to
3855            the register file.
3856         */
3857         int base = (++vPC)->u.operand;
3858         int property = (++vPC)->u.operand;
3859         int function = (++vPC)->u.operand;
3860
3861         ASSERT(callFrame[base].jsValue(callFrame)->isObject());
3862         JSObject* baseObj = asObject(callFrame[base].jsValue(callFrame));
3863         Identifier& ident = callFrame->codeBlock()->identifiers[property];
3864         ASSERT(callFrame[function].jsValue(callFrame)->isObject());
3865         baseObj->defineGetter(callFrame, ident, asObject(callFrame[function].jsValue(callFrame)));
3866
3867         ++vPC;
3868         NEXT_OPCODE;
3869     }
3870     BEGIN_OPCODE(op_put_setter) {
3871         /* put_setter base(r) property(id) function(r)
3872
3873            Sets register function on register base as the setter named
3874            by identifier property. Base and function are assumed to be
3875            objects as this op should only be used for setters defined
3876            in object literal form.
3877
3878            Unlike many opcodes, this one does not write any output to
3879            the register file.
3880         */
3881         int base = (++vPC)->u.operand;
3882         int property = (++vPC)->u.operand;
3883         int function = (++vPC)->u.operand;
3884
3885         ASSERT(callFrame[base].jsValue(callFrame)->isObject());
3886         JSObject* baseObj = asObject(callFrame[base].jsValue(callFrame));
3887         Identifier& ident = callFrame->codeBlock()->identifiers[property];
3888         ASSERT(callFrame[function].jsValue(callFrame)->isObject());
3889         baseObj->defineSetter(callFrame, ident, asObject(callFrame[function].jsValue(callFrame)));
3890
3891         ++vPC;
3892         NEXT_OPCODE;
3893     }
3894     BEGIN_OPCODE(op_jsr) {
3895         /* jsr retAddrDst(r) target(offset)
3896
3897            Places the address of the next instruction into the retAddrDst
3898            register and jumps to offset target from the current instruction.
3899         */
3900         int retAddrDst = (++vPC)->u.operand;
3901         int target = (++vPC)->u.operand;
3902         callFrame[retAddrDst] = vPC + 1;
3903
3904         vPC += target;
3905         NEXT_OPCODE;
3906     }
3907     BEGIN_OPCODE(op_sret) {
3908         /* sret retAddrSrc(r)
3909
3910          Jumps to the address stored in the retAddrSrc register. This
3911          differs from op_jmp because the target address is stored in a
3912          register, not as an immediate.
3913         */
3914         int retAddrSrc = (++vPC)->u.operand;
3915         vPC = callFrame[retAddrSrc].vPC();
3916         NEXT_OPCODE;
3917     }
3918     BEGIN_OPCODE(op_debug) {
3919         /* debug debugHookID(n) firstLine(n) lastLine(n)
3920
3921          Notifies the debugger of the current state of execution. This opcode
3922          is only generated while the debugger is attached.
3923         */
3924         int debugHookID = (++vPC)->u.operand;
3925         int firstLine = (++vPC)->u.operand;
3926         int lastLine = (++vPC)->u.operand;
3927
3928         debug(callFrame, static_cast<DebugHookID>(debugHookID), firstLine, lastLine);
3929
3930         ++vPC;
3931         NEXT_OPCODE;
3932     }
3933     BEGIN_OPCODE(op_profile_will_call) {
3934         /* op_profile_will_call function(r)
3935
3936          Notifies the profiler of the beginning of a function call. This opcode
3937          is only generated if developer tools are enabled.
3938         */
3939         int function = vPC[1].u.operand;
3940
3941         if (*enabledProfilerReference)
3942             (*enabledProfilerReference)->willExecute(callFrame, callFrame[function].jsValue(callFrame));
3943
3944         vPC += 2;
3945         NEXT_OPCODE;
3946     }
3947     BEGIN_OPCODE(op_profile_did_call) {
3948         /* op_profile_did_call function(r)
3949
3950          Notifies the profiler of the end of a function call. This opcode
3951          is only generated if developer tools are enabled.
3952         */
3953         int function = vPC[1].u.operand;
3954
3955         if (*enabledProfilerReference)
3956             (*enabledProfilerReference)->didExecute(callFrame, callFrame[function].jsValue(callFrame));
3957
3958         vPC += 2;
3959         NEXT_OPCODE;
3960     }
3961     vm_throw: {
3962         globalData->exception = noValue();
3963         if (!tickCount) {
3964             // The exceptionValue is a lie! (GCC produces bad code for reasons I 
3965             // cannot fathom if we don't assign to the exceptionValue before branching)
3966             exceptionValue = createInterruptedExecutionException(globalData);
3967         }
3968         handlerVPC = throwException(callFrame, exceptionValue, vPC, false);
3969         if (!handlerVPC) {
3970             *exception = exceptionValue;
3971             return jsNull();
3972         }
3973         vPC = handlerVPC;
3974         NEXT_OPCODE;
3975     }
3976     }
3977 #if !HAVE(COMPUTED_GOTO)
3978     } // iterator loop ends
3979 #endif
3980     #undef NEXT_OPCODE
3981     #undef BEGIN_OPCODE
3982     #undef VM_CHECK_EXCEPTION
3983     #undef CHECK_FOR_TIMEOUT
3984 }
3985
3986 JSValuePtr Machine::retrieveArguments(CallFrame* callFrame, JSFunction* function) const
3987 {
3988     CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
3989     if (!functionCallFrame)
3990         return jsNull();
3991
3992     CodeBlock* codeBlock = functionCallFrame->codeBlock();
3993     if (codeBlock->usesArguments) {
3994         ASSERT(codeBlock->codeType == FunctionCode);
3995         SymbolTable& symbolTable = static_cast<FunctionBodyNode*>(codeBlock->ownerNode)->symbolTable();
3996         int argumentsIndex = symbolTable.get(functionCallFrame->propertyNames().arguments.ustring().rep()).getIndex();
3997         return functionCallFrame[argumentsIndex].jsValue(callFrame);
3998     }
3999
4000     Arguments* arguments = functionCallFrame->optionalCalleeArguments();
4001     if (!arguments) {
4002         arguments = new (functionCallFrame) Arguments(functionCallFrame);
4003         arguments->copyRegisters();
4004         callFrame->setCalleeArguments(arguments);
4005     }
4006
4007     return arguments;
4008 }
4009
4010 JSValuePtr Machine::retrieveCaller(CallFrame* callFrame, InternalFunction* function) const
4011 {
4012     CallFrame* functionCallFrame = findFunctionCallFrame(callFrame, function);
4013     if (!functionCallFrame)
4014         return jsNull();
4015
4016     CallFrame* callerFrame = functionCallFrame->callerFrame();
4017     if (callerFrame->hasHostCallFrameFlag())
4018         return jsNull();
4019
4020     JSValuePtr caller = callerFrame->callee();
4021     if (!caller)
4022         return jsNull();
4023
4024     return caller;
4025 }
4026
4027 void Machine::retrieveLastCaller(CallFrame* callFrame, int& lineNumber, intptr_t& sourceID, UString& sourceURL, JSValuePtr& function) const
4028 {
4029     function = noValue();