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