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