7409cfe1b4cb1699006ddfa841ab89c4fdc883dd
[WebKit-https.git] / JavaScriptCore / bytecompiler / BytecodeGenerator.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 "BytecodeGenerator.h"
32
33 #include "BatchedTransitionOptimizer.h"
34 #include "JSFunction.h"
35 #include "Interpreter.h"
36 #include "UString.h"
37
38 using namespace std;
39
40 namespace JSC {
41
42 /*
43     The layout of a register frame looks like this:
44
45     For
46
47     function f(x, y) {
48         var v1;
49         function g() { }
50         var v2;
51         return (x) * (y);
52     }
53
54     assuming (x) and (y) generated temporaries t1 and t2, you would have
55
56     ------------------------------------
57     |  x |  y |  g | v2 | v1 | t1 | t2 | <-- value held
58     ------------------------------------
59     | -5 | -4 | -3 | -2 | -1 | +0 | +1 | <-- register index
60     ------------------------------------
61     | params->|<-locals      | temps->
62
63     Because temporary registers are allocated in a stack-like fashion, we
64     can reclaim them with a simple popping algorithm. The same goes for labels.
65     (We never reclaim parameter or local registers, because parameters and
66     locals are DontDelete.)
67
68     The register layout before a function call looks like this:
69
70     For
71
72     function f(x, y)
73     {
74     }
75
76     f(1);
77
78     >                        <------------------------------
79     <                        >  reserved: call frame  |  1 | <-- value held
80     >         >snip<         <------------------------------
81     <                        > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index
82     >                        <------------------------------
83     | params->|<-locals      | temps->
84
85     The call instruction fills in the "call frame" registers. It also pads
86     missing arguments at the end of the call:
87
88     >                        <-----------------------------------
89     <                        >  reserved: call frame  |  1 |  ? | <-- value held ("?" stands for "undefined")
90     >         >snip<         <-----------------------------------
91     <                        > +0 | +1 | +2 | +3 | +4 | +5 | +6 | <-- register index
92     >                        <-----------------------------------
93     | params->|<-locals      | temps->
94
95     After filling in missing arguments, the call instruction sets up the new
96     stack frame to overlap the end of the old stack frame:
97
98                              |---------------------------------->                        <
99                              |  reserved: call frame  |  1 |  ? <                        > <-- value held ("?" stands for "undefined")
100                              |---------------------------------->         >snip<         <
101                              | -7 | -6 | -5 | -4 | -3 | -2 | -1 <                        > <-- register index
102                              |---------------------------------->                        <
103                              |                        | params->|<-locals       | temps->
104
105     That way, arguments are "copied" into the callee's stack frame for free.
106
107     If the caller supplies too many arguments, this trick doesn't work. The
108     extra arguments protrude into space reserved for locals and temporaries.
109     In that case, the call instruction makes a real copy of the call frame header,
110     along with just the arguments expected by the callee, leaving the original
111     call frame header and arguments behind. (The call instruction can't just discard
112     extra arguments, because the "arguments" object may access them later.)
113     This copying strategy ensures that all named values will be at the indices
114     expected by the callee.
115 */
116
117 #ifndef NDEBUG
118 bool BytecodeGenerator::s_dumpsGeneratedCode = false;
119 #endif
120
121 void BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
122 {
123 #ifndef NDEBUG
124     s_dumpsGeneratedCode = dumpsGeneratedCode;
125 #else
126     UNUSED_PARAM(dumpsGeneratedCode);
127 #endif
128 }
129
130 bool BytecodeGenerator::dumpsGeneratedCode()
131 {
132 #ifndef NDEBUG
133     return s_dumpsGeneratedCode;
134 #else
135     return false;
136 #endif
137 }
138
139 void BytecodeGenerator::generate()
140 {
141     m_codeBlock->setThisRegister(m_thisRegister.index());
142
143     m_scopeNode->emitBytecode(*this);
144
145 #ifndef NDEBUG
146     m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
147
148     if (s_dumpsGeneratedCode) {
149         JSGlobalObject* globalObject = m_scopeChain->globalObject();
150         m_codeBlock->dump(globalObject->globalExec());
151     }
152 #endif
153
154     m_codeBlock->shrinkToFit();
155     if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
156         symbolTable().clear();
157 }
158
159 bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
160 {
161     int index = m_calleeRegisters.size();
162     SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
163     pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.ustring().rep(), newEntry);
164
165     if (!result.second) {
166         r0 = &registerFor(result.first->second.getIndex());
167         return false;
168     }
169
170     ++m_codeBlock->m_numVars;
171     r0 = newRegister();
172     return true;
173 }
174
175 bool BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
176 {
177     int index = m_nextGlobalIndex;
178     SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
179     pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.ustring().rep(), newEntry);
180
181     if (!result.second)
182         index = result.first->second.getIndex();
183     else {
184         --m_nextGlobalIndex;
185         m_globals.append(index + m_globalVarStorageOffset);
186     }
187
188     r0 = &registerFor(index);
189     return result.second;
190 }
191
192 void BytecodeGenerator::allocateConstants(size_t count)
193 {
194     m_codeBlock->m_numConstants = count;
195     if (!count)
196         return;
197     
198     m_nextConstantIndex = m_calleeRegisters.size();
199
200     for (size_t i = 0; i < count; ++i)
201         newRegister();
202     m_lastConstant = &m_calleeRegisters.last();
203 }
204
205 BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock)
206     : m_shouldEmitDebugHooks(!!debugger)
207     , m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
208     , m_scopeChain(&scopeChain)
209     , m_symbolTable(symbolTable)
210     , m_scopeNode(programNode)
211     , m_codeBlock(codeBlock)
212     , m_thisRegister(RegisterFile::ProgramCodeThisRegister)
213     , m_finallyDepth(0)
214     , m_dynamicScopeDepth(0)
215     , m_codeType(GlobalCode)
216     , m_nextGlobalIndex(-1)
217     , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
218     , m_lastOpcodeID(op_end)
219     , m_emitNodeDepth(0)
220 {
221     if (m_shouldEmitDebugHooks)
222         m_codeBlock->setNeedsFullScopeChain(true);
223
224     emitOpcode(op_enter);
225     codeBlock->setGlobalData(m_globalData);
226
227     // FIXME: Move code that modifies the global object to Interpreter::execute.
228     
229     m_codeBlock->m_numParameters = 1; // Allocate space for "this"
230
231     JSGlobalObject* globalObject = scopeChain.globalObject();
232     ExecState* exec = globalObject->globalExec();
233     RegisterFile* registerFile = &exec->globalData().interpreter->registerFile();
234     
235     // Shift register indexes in generated code to elide registers allocated by intermediate stack frames.
236     m_globalVarStorageOffset = -RegisterFile::CallFrameHeaderSize - m_codeBlock->m_numParameters - registerFile->size();
237
238     // Add previously defined symbols to bookkeeping.
239     m_globals.grow(symbolTable->size());
240     SymbolTable::iterator end = symbolTable->end();
241     for (SymbolTable::iterator it = symbolTable->begin(); it != end; ++it)
242         registerFor(it->second.getIndex()).setIndex(it->second.getIndex() + m_globalVarStorageOffset);
243         
244     BatchedTransitionOptimizer optimizer(globalObject);
245
246     const VarStack& varStack = programNode->varStack();
247     const FunctionStack& functionStack = programNode->functionStack();
248     bool canOptimizeNewGlobals = symbolTable->size() + functionStack.size() + varStack.size() < registerFile->maxGlobals();
249     if (canOptimizeNewGlobals) {
250         // Shift new symbols so they get stored prior to existing symbols.
251         m_nextGlobalIndex -= symbolTable->size();
252
253         for (size_t i = 0; i < functionStack.size(); ++i) {
254             FuncDeclNode* funcDecl = functionStack[i].get();
255             globalObject->removeDirect(funcDecl->m_ident); // Make sure our new function is not shadowed by an old property.
256             emitNewFunction(addGlobalVar(funcDecl->m_ident, false), funcDecl);
257         }
258
259         Vector<RegisterID*, 32> newVars;
260         for (size_t i = 0; i < varStack.size(); ++i)
261             if (!globalObject->hasProperty(exec, varStack[i].first))
262                 newVars.append(addGlobalVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant));
263
264         allocateConstants(programNode->neededConstants());
265
266         for (size_t i = 0; i < newVars.size(); ++i)
267             emitLoad(newVars[i], jsUndefined());
268     } else {
269         for (size_t i = 0; i < functionStack.size(); ++i) {
270             FuncDeclNode* funcDecl = functionStack[i].get();
271             globalObject->putWithAttributes(exec, funcDecl->m_ident, funcDecl->makeFunction(exec, scopeChain.node()), DontDelete);
272         }
273         for (size_t i = 0; i < varStack.size(); ++i) {
274             if (globalObject->hasProperty(exec, varStack[i].first))
275                 continue;
276             int attributes = DontDelete;
277             if (varStack[i].second & DeclarationStacks::IsConstant)
278                 attributes |= ReadOnly;
279             globalObject->putWithAttributes(exec, varStack[i].first, jsUndefined(), attributes);
280         }
281
282         allocateConstants(programNode->neededConstants());
283     }
284 }
285
286 BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock)
287     : m_shouldEmitDebugHooks(!!debugger)
288     , m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
289     , m_scopeChain(&scopeChain)
290     , m_symbolTable(symbolTable)
291     , m_scopeNode(functionBody)
292     , m_codeBlock(codeBlock)
293     , m_finallyDepth(0)
294     , m_dynamicScopeDepth(0)
295     , m_codeType(FunctionCode)
296     , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
297     , m_lastOpcodeID(op_end)
298     , m_emitNodeDepth(0)
299 {
300     if (m_shouldEmitDebugHooks)
301         m_codeBlock->setNeedsFullScopeChain(true);
302
303     codeBlock->setGlobalData(m_globalData);
304
305     bool usesArguments = functionBody->usesArguments();
306     codeBlock->setUsesArguments(usesArguments);
307     if (usesArguments) {
308         m_argumentsRegister.setIndex(RegisterFile::OptionalCalleeArguments);
309         addVar(propertyNames().arguments, false);
310     }
311
312     if (m_codeBlock->needsFullScopeChain()) {
313         ++m_codeBlock->m_numVars;
314         m_activationRegisterIndex = newRegister()->index();
315         emitOpcode(op_enter_with_activation);
316         instructions().append(m_activationRegisterIndex);
317     } else
318         emitOpcode(op_enter);
319
320     if (usesArguments)
321         emitOpcode(op_create_arguments);
322
323     const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
324     for (size_t i = 0; i < functionStack.size(); ++i) {
325         FuncDeclNode* funcDecl = functionStack[i].get();
326         const Identifier& ident = funcDecl->m_ident;
327         m_functions.add(ident.ustring().rep());
328         emitNewFunction(addVar(ident, false), funcDecl);
329     }
330
331     const DeclarationStacks::VarStack& varStack = functionBody->varStack();
332     for (size_t i = 0; i < varStack.size(); ++i)
333         addVar(varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
334
335     const Identifier* parameters = functionBody->parameters();
336     size_t parameterCount = functionBody->parameterCount();
337     m_nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
338     m_parameters.grow(1 + parameterCount); // reserve space for "this"
339
340     // Add "this" as a parameter
341     m_thisRegister.setIndex(m_nextParameterIndex);
342     ++m_nextParameterIndex;
343     ++m_codeBlock->m_numParameters;
344
345     if (functionBody->usesThis() || m_shouldEmitDebugHooks) {
346         emitOpcode(op_convert_this);
347         instructions().append(m_thisRegister.index());
348     }
349     
350     for (size_t i = 0; i < parameterCount; ++i)
351         addParameter(parameters[i]);
352
353     allocateConstants(functionBody->neededConstants());
354 }
355
356 BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, const Debugger* debugger, const ScopeChain& scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock)
357     : m_shouldEmitDebugHooks(!!debugger)
358     , m_shouldEmitProfileHooks(scopeChain.globalObject()->supportsProfiling())
359     , m_scopeChain(&scopeChain)
360     , m_symbolTable(symbolTable)
361     , m_scopeNode(evalNode)
362     , m_codeBlock(codeBlock)
363     , m_thisRegister(RegisterFile::ProgramCodeThisRegister)
364     , m_finallyDepth(0)
365     , m_dynamicScopeDepth(0)
366     , m_codeType(EvalCode)
367     , m_globalData(&scopeChain.globalObject()->globalExec()->globalData())
368     , m_lastOpcodeID(op_end)
369     , m_emitNodeDepth(0)
370 {
371     if (m_shouldEmitDebugHooks)
372         m_codeBlock->setNeedsFullScopeChain(true);
373
374     emitOpcode(op_enter);
375     codeBlock->setGlobalData(m_globalData);
376     m_codeBlock->m_numParameters = 1; // Allocate space for "this"
377
378     allocateConstants(evalNode->neededConstants());
379 }
380
381 RegisterID* BytecodeGenerator::addParameter(const Identifier& ident)
382 {
383     // Parameters overwrite var declarations, but not function declarations.
384     RegisterID* result = 0;
385     UString::Rep* rep = ident.ustring().rep();
386     if (!m_functions.contains(rep)) {
387         symbolTable().set(rep, m_nextParameterIndex);
388         RegisterID& parameter = registerFor(m_nextParameterIndex);
389         parameter.setIndex(m_nextParameterIndex);
390         result = &parameter;
391     }
392
393     // To maintain the calling convention, we have to allocate unique space for
394     // each parameter, even if the parameter doesn't make it into the symbol table.
395     ++m_nextParameterIndex;
396     ++m_codeBlock->m_numParameters;
397     return result;
398 }
399
400 RegisterID* BytecodeGenerator::registerFor(const Identifier& ident)
401 {
402     if (ident == propertyNames().thisIdentifier)
403         return &m_thisRegister;
404
405     if (!shouldOptimizeLocals())
406         return 0;
407
408     SymbolTableEntry entry = symbolTable().get(ident.ustring().rep());
409     if (entry.isNull())
410         return 0;
411
412     return &registerFor(entry.getIndex());
413 }
414
415 RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident)
416 {
417     if (m_codeType == EvalCode)
418         return 0;
419
420     SymbolTableEntry entry = symbolTable().get(ident.ustring().rep());
421     ASSERT(!entry.isNull());
422
423     return &registerFor(entry.getIndex());
424 }
425
426 bool BytecodeGenerator::isLocal(const Identifier& ident)
427 {
428     if (ident == propertyNames().thisIdentifier)
429         return true;
430     
431     return shouldOptimizeLocals() && symbolTable().contains(ident.ustring().rep());
432 }
433
434 bool BytecodeGenerator::isLocalConstant(const Identifier& ident)
435 {
436     return symbolTable().get(ident.ustring().rep()).isReadOnly();
437 }
438
439 RegisterID* BytecodeGenerator::newRegister()
440 {
441     m_calleeRegisters.append(m_calleeRegisters.size());
442     m_codeBlock->m_numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size());
443     return &m_calleeRegisters.last();
444 }
445
446 RegisterID* BytecodeGenerator::newTemporary()
447 {
448     // Reclaim free register IDs.
449     while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount())
450         m_calleeRegisters.removeLast();
451         
452     RegisterID* result = newRegister();
453     result->setTemporary();
454     return result;
455 }
456
457 RegisterID* BytecodeGenerator::highestUsedRegister()
458 {
459     size_t count = m_codeBlock->m_numCalleeRegisters;
460     while (m_calleeRegisters.size() < count)
461         newRegister();
462     return &m_calleeRegisters.last();
463 }
464
465 PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
466 {
467     // Reclaim free label scopes.
468     while (m_labelScopes.size() && !m_labelScopes.last().refCount())
469         m_labelScopes.removeLast();
470
471     // Allocate new label scope.
472     LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : 0); // Only loops have continue targets.
473     m_labelScopes.append(scope);
474     return &m_labelScopes.last();
475 }
476
477 PassRefPtr<Label> BytecodeGenerator::newLabel()
478 {
479     // Reclaim free label IDs.
480     while (m_labels.size() && !m_labels.last().refCount())
481         m_labels.removeLast();
482
483     // Allocate new label ID.
484     m_labels.append(m_codeBlock);
485     return &m_labels.last();
486 }
487
488 PassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0)
489 {
490     unsigned newLabelIndex = instructions().size();
491     l0->setLocation(newLabelIndex);
492
493     if (m_codeBlock->numberOfJumpTargets()) {
494         unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
495         ASSERT(lastLabelIndex <= newLabelIndex);
496         if (newLabelIndex == lastLabelIndex) {
497             // Peephole optimizations have already been disabled by emitting the last label
498             return l0;
499         }
500     }
501
502     m_codeBlock->addJumpTarget(newLabelIndex);
503
504     // This disables peephole optimizations when an instruction is a jump target
505     m_lastOpcodeID = op_end;
506     return l0;
507 }
508
509 void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
510 {
511     instructions().append(globalData()->interpreter->getOpcode(opcodeID));
512     m_lastOpcodeID = opcodeID;
513 }
514
515 void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
516 {
517     ASSERT(instructions().size() >= 4);
518     size_t size = instructions().size();
519     dstIndex = instructions().at(size - 3).u.operand;
520     src1Index = instructions().at(size - 2).u.operand;
521     src2Index = instructions().at(size - 1).u.operand;
522 }
523
524 void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
525 {
526     ASSERT(instructions().size() >= 3);
527     size_t size = instructions().size();
528     dstIndex = instructions().at(size - 2).u.operand;
529     srcIndex = instructions().at(size - 1).u.operand;
530 }
531
532 void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
533 {
534     ASSERT(instructions().size() >= 4);
535     instructions().shrink(instructions().size() - 4);
536 }
537
538 void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
539 {
540     ASSERT(instructions().size() >= 3);
541     instructions().shrink(instructions().size() - 3);
542 }
543
544 PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
545 {
546     emitOpcode(target->isForward() ? op_jmp : op_loop);
547     instructions().append(target->offsetFrom(instructions().size()));
548     return target;
549 }
550
551 PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
552 {
553     if (m_lastOpcodeID == op_less && !target->isForward()) {
554         int dstIndex;
555         int src1Index;
556         int src2Index;
557
558         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
559
560         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
561             rewindBinaryOp();
562             emitOpcode(op_loop_if_less);
563             instructions().append(src1Index);
564             instructions().append(src2Index);
565             instructions().append(target->offsetFrom(instructions().size()));
566             return target;
567         }
568     } else if (m_lastOpcodeID == op_lesseq && !target->isForward()) {
569         int dstIndex;
570         int src1Index;
571         int src2Index;
572
573         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
574
575         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
576             rewindBinaryOp();
577             emitOpcode(op_loop_if_lesseq);
578             instructions().append(src1Index);
579             instructions().append(src2Index);
580             instructions().append(target->offsetFrom(instructions().size()));
581             return target;
582         }
583     } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
584         int dstIndex;
585         int srcIndex;
586
587         retrieveLastUnaryOp(dstIndex, srcIndex);
588
589         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
590             rewindUnaryOp();
591             emitOpcode(op_jeq_null);
592             instructions().append(srcIndex);
593             instructions().append(target->offsetFrom(instructions().size()));
594             return target;
595         }
596     } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
597         int dstIndex;
598         int srcIndex;
599
600         retrieveLastUnaryOp(dstIndex, srcIndex);
601
602         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
603             rewindUnaryOp();
604             emitOpcode(op_jneq_null);
605             instructions().append(srcIndex);
606             instructions().append(target->offsetFrom(instructions().size()));
607             return target;
608         }
609     }
610
611     emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
612     instructions().append(cond->index());
613     instructions().append(target->offsetFrom(instructions().size()));
614     return target;
615 }
616
617 PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
618 {
619     ASSERT(target->isForward());
620
621     if (m_lastOpcodeID == op_less) {
622         int dstIndex;
623         int src1Index;
624         int src2Index;
625
626         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
627
628         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
629             rewindBinaryOp();
630             emitOpcode(op_jnless);
631             instructions().append(src1Index);
632             instructions().append(src2Index);
633             instructions().append(target->offsetFrom(instructions().size()));
634             return target;
635         }
636     } else if (m_lastOpcodeID == op_not) {
637         int dstIndex;
638         int srcIndex;
639
640         retrieveLastUnaryOp(dstIndex, srcIndex);
641
642         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
643             rewindUnaryOp();
644             emitOpcode(op_jtrue);
645             instructions().append(srcIndex);
646             instructions().append(target->offsetFrom(instructions().size()));
647             return target;
648         }
649     } else if (m_lastOpcodeID == op_eq_null) {
650         int dstIndex;
651         int srcIndex;
652
653         retrieveLastUnaryOp(dstIndex, srcIndex);
654
655         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
656             rewindUnaryOp();
657             emitOpcode(op_jneq_null);
658             instructions().append(srcIndex);
659             instructions().append(target->offsetFrom(instructions().size()));
660             return target;
661         }
662     } else if (m_lastOpcodeID == op_neq_null) {
663         int dstIndex;
664         int srcIndex;
665
666         retrieveLastUnaryOp(dstIndex, srcIndex);
667
668         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
669             rewindUnaryOp();
670             emitOpcode(op_jeq_null);
671             instructions().append(srcIndex);
672             instructions().append(target->offsetFrom(instructions().size()));
673             return target;
674         }
675     }
676
677     emitOpcode(op_jfalse);
678     instructions().append(cond->index());
679     instructions().append(target->offsetFrom(instructions().size()));
680     return target;
681 }
682
683 unsigned BytecodeGenerator::addConstant(FuncDeclNode* n)
684 {
685     // No need to explicitly unique function body nodes -- they're unique already.
686     return m_codeBlock->addFunction(n);
687 }
688
689 unsigned BytecodeGenerator::addConstant(FuncExprNode* n)
690 {
691     // No need to explicitly unique function expression nodes -- they're unique already.
692     return m_codeBlock->addFunctionExpression(n);
693 }
694
695 unsigned BytecodeGenerator::addConstant(const Identifier& ident)
696 {
697     UString::Rep* rep = ident.ustring().rep();
698     pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
699     if (result.second) // new entry
700         m_codeBlock->addIdentifier(Identifier(m_globalData, rep));
701
702     return result.first->second;
703 }
704
705 RegisterID* BytecodeGenerator::addConstant(JSValue* v)
706 {
707     pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(v, m_nextConstantIndex);
708     if (result.second) {
709         RegisterID& constant = m_calleeRegisters[m_nextConstantIndex];
710         
711         ++m_nextConstantIndex;
712
713         m_codeBlock->addConstantRegister(v);
714         return &constant;
715     }
716
717     return &registerFor(result.first->second);
718 }
719
720 unsigned BytecodeGenerator::addUnexpectedConstant(JSValue* v)
721 {
722     return m_codeBlock->addUnexpectedConstant(v);
723 }
724
725 unsigned BytecodeGenerator::addRegExp(RegExp* r)
726 {
727     return m_codeBlock->addRegExp(r);
728 }
729
730 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
731 {
732     emitOpcode(op_mov);
733     instructions().append(dst->index());
734     instructions().append(src->index());
735     return dst;
736 }
737
738 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
739 {
740     emitOpcode(opcodeID);
741     instructions().append(dst->index());
742     instructions().append(src->index());
743     return dst;
744 }
745
746 RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
747 {
748     emitOpcode(op_pre_inc);
749     instructions().append(srcDst->index());
750     return srcDst;
751 }
752
753 RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
754 {
755     emitOpcode(op_pre_dec);
756     instructions().append(srcDst->index());
757     return srcDst;
758 }
759
760 RegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
761 {
762     emitOpcode(op_post_inc);
763     instructions().append(dst->index());
764     instructions().append(srcDst->index());
765     return dst;
766 }
767
768 RegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
769 {
770     emitOpcode(op_post_dec);
771     instructions().append(dst->index());
772     instructions().append(srcDst->index());
773     return dst;
774 }
775
776 RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
777 {
778     emitOpcode(opcodeID);
779     instructions().append(dst->index());
780     instructions().append(src1->index());
781     instructions().append(src2->index());
782
783     if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
784         opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub) {
785         instructions().append(types.toInt());
786     }
787
788     return dst;
789 }
790
791 RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
792 {
793     if (m_lastOpcodeID == op_typeof) {
794         int dstIndex;
795         int srcIndex;
796
797         retrieveLastUnaryOp(dstIndex, srcIndex);
798
799         if (src1->index() == dstIndex
800             && src1->isTemporary()
801             && m_codeBlock->isConstantRegisterIndex(src2->index())
802             && m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec())->isString()) {
803             const UString& value = asString(m_codeBlock->constantRegister(src2->index() - m_codeBlock->m_numVars).jsValue(m_scopeChain->globalObject()->globalExec()))->value();
804             if (value == "undefined") {
805                 rewindUnaryOp();
806                 emitOpcode(op_is_undefined);
807                 instructions().append(dst->index());
808                 instructions().append(srcIndex);
809                 return dst;
810             }
811             if (value == "boolean") {
812                 rewindUnaryOp();
813                 emitOpcode(op_is_boolean);
814                 instructions().append(dst->index());
815                 instructions().append(srcIndex);
816                 return dst;
817             }
818             if (value == "number") {
819                 rewindUnaryOp();
820                 emitOpcode(op_is_number);
821                 instructions().append(dst->index());
822                 instructions().append(srcIndex);
823                 return dst;
824             }
825             if (value == "string") {
826                 rewindUnaryOp();
827                 emitOpcode(op_is_string);
828                 instructions().append(dst->index());
829                 instructions().append(srcIndex);
830                 return dst;
831             }
832             if (value == "object") {
833                 rewindUnaryOp();
834                 emitOpcode(op_is_object);
835                 instructions().append(dst->index());
836                 instructions().append(srcIndex);
837                 return dst;
838             }
839             if (value == "function") {
840                 rewindUnaryOp();
841                 emitOpcode(op_is_function);
842                 instructions().append(dst->index());
843                 instructions().append(srcIndex);
844                 return dst;
845             }
846         }
847     }
848
849     emitOpcode(opcodeID);
850     instructions().append(dst->index());
851     instructions().append(src1->index());
852     instructions().append(src2->index());
853     return dst;
854 }
855
856 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
857 {
858     return emitLoad(dst, jsBoolean(b));
859 }
860
861 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
862 {
863     // FIXME: Our hash tables won't hold infinity, so we make a new JSNumberCell each time.
864     // Later we can do the extra work to handle that like the other cases.
865     if (number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
866         return emitLoad(dst, jsNumber(globalData(), number));
867     JSValue*& valueInMap = m_numberMap.add(number, noValue()).first->second;
868     if (!valueInMap)
869         valueInMap = jsNumber(globalData(), number);
870     return emitLoad(dst, valueInMap);
871 }
872
873 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
874 {
875     JSString*& valueInMap = m_stringMap.add(identifier.ustring().rep(), 0).first->second;
876     if (!valueInMap)
877         valueInMap = jsOwnedString(globalData(), identifier.ustring());
878     return emitLoad(dst, valueInMap);
879 }
880
881 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue* v)
882 {
883     RegisterID* constantID = addConstant(v);
884     if (dst)
885         return emitMove(dst, constantID);
886     return constantID;
887 }
888
889 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSCell* cell)
890 {
891     JSValue* value = cell;
892     return emitLoad(dst, value);
893 }
894
895 RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, bool b)
896 {
897     emitOpcode(op_unexpected_load);
898     instructions().append(dst->index());
899     instructions().append(addUnexpectedConstant(jsBoolean(b)));
900     return dst;
901 }
902
903 RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d)
904 {
905     emitOpcode(op_unexpected_load);
906     instructions().append(dst->index());
907     instructions().append(addUnexpectedConstant(jsNumber(globalData(), d)));
908     return dst;
909 }
910
911 bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
912 {
913     // Cases where we cannot statically optimize the lookup.
914     if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
915         stackDepth = 0;
916         index = missingSymbolMarker();
917
918         if (shouldOptimizeLocals() && m_codeType == GlobalCode) {
919             ScopeChainIterator iter = m_scopeChain->begin();
920             globalObject = *iter;
921             ASSERT((++iter) == m_scopeChain->end());
922         }
923         return false;
924     }
925
926     size_t depth = 0;
927     
928     ScopeChainIterator iter = m_scopeChain->begin();
929     ScopeChainIterator end = m_scopeChain->end();
930     for (; iter != end; ++iter, ++depth) {
931         JSObject* currentScope = *iter;
932         if (!currentScope->isVariableObject())
933             break;
934         JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
935         SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.ustring().rep());
936
937         // Found the property
938         if (!entry.isNull()) {
939             if (entry.isReadOnly() && forWriting) {
940                 stackDepth = 0;
941                 index = missingSymbolMarker();
942                 if (++iter == end)
943                     globalObject = currentVariableObject;
944                 return false;
945             }
946             stackDepth = depth;
947             index = entry.getIndex();
948             if (++iter == end)
949                 globalObject = currentVariableObject;
950             return true;
951         }
952         if (currentVariableObject->isDynamicScope())
953             break;
954     }
955
956     // Can't locate the property but we're able to avoid a few lookups.
957     stackDepth = depth;
958     index = missingSymbolMarker();
959     JSObject* scope = *iter;
960     if (++iter == end)
961         globalObject = scope;
962     return true;
963 }
964
965 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
966
967     emitOpcode(op_instanceof);
968     instructions().append(dst->index());
969     instructions().append(value->index());
970     instructions().append(base->index());
971     instructions().append(basePrototype->index());
972     return dst;
973 }
974
975 RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& property)
976 {
977     size_t depth = 0;
978     int index = 0;
979     JSObject* globalObject = 0;
980     if (!findScopedProperty(property, index, depth, false, globalObject) && !globalObject) {
981         // We can't optimise at all :-(
982         emitOpcode(op_resolve);
983         instructions().append(dst->index());
984         instructions().append(addConstant(property));
985         return dst;
986     }
987
988     if (index != missingSymbolMarker()) {
989         // Directly index the property lookup across multiple scopes.  Yay!
990         return emitGetScopedVar(dst, depth, index, globalObject);
991     }
992
993     if (globalObject) {
994 #if ENABLE(JIT)
995         m_codeBlock->addGlobalResolveInfo();
996 #else
997         m_codeBlock->addGlobalResolveInstruction(instructions().size());
998 #endif
999         emitOpcode(op_resolve_global);
1000         instructions().append(dst->index());
1001         instructions().append(globalObject);
1002         instructions().append(addConstant(property));
1003         instructions().append(0);
1004         instructions().append(0);
1005         return dst;
1006     }
1007
1008     // In this case we are at least able to drop a few scope chains from the
1009     // lookup chain, although we still need to hash from then on.
1010     emitOpcode(op_resolve_skip);
1011     instructions().append(dst->index());
1012     instructions().append(addConstant(property));
1013     instructions().append(depth);
1014     return dst;
1015 }
1016
1017 RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue* globalObject)
1018 {
1019     if (globalObject) {
1020         emitOpcode(op_get_global_var);
1021         instructions().append(dst->index());
1022         instructions().append(asCell(globalObject));
1023         instructions().append(index);
1024         return dst;
1025     }
1026
1027     emitOpcode(op_get_scoped_var);
1028     instructions().append(dst->index());
1029     instructions().append(index);
1030     instructions().append(depth);
1031     return dst;
1032 }
1033
1034 RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue* globalObject)
1035 {
1036     if (globalObject) {
1037         emitOpcode(op_put_global_var);
1038         instructions().append(asCell(globalObject));
1039         instructions().append(index);
1040         instructions().append(value->index());
1041         return value;
1042     }
1043     emitOpcode(op_put_scoped_var);
1044     instructions().append(index);
1045     instructions().append(depth);
1046     instructions().append(value->index());
1047     return value;
1048 }
1049
1050 RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property)
1051 {
1052     emitOpcode(op_resolve_base);
1053     instructions().append(dst->index());
1054     instructions().append(addConstant(property));
1055     return dst;
1056 }
1057
1058 RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
1059 {
1060     emitOpcode(op_resolve_with_base);
1061     instructions().append(baseDst->index());
1062     instructions().append(propDst->index());
1063     instructions().append(addConstant(property));
1064     return baseDst;
1065 }
1066
1067 RegisterID* BytecodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property)
1068 {
1069     emitOpcode(op_resolve_func);
1070     instructions().append(baseDst->index());
1071     instructions().append(funcDst->index());
1072     instructions().append(addConstant(property));
1073     return baseDst;
1074 }
1075
1076 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1077 {
1078 #if ENABLE(JIT)
1079     m_codeBlock->addStructureStubInfo(StructureStubInfo(op_get_by_id));
1080 #else
1081     m_codeBlock->addPropertyAccessInstruction(instructions().size());
1082 #endif
1083
1084     emitOpcode(op_get_by_id);
1085     instructions().append(dst->index());
1086     instructions().append(base->index());
1087     instructions().append(addConstant(property));
1088     instructions().append(0);
1089     instructions().append(0);
1090     instructions().append(0);
1091     instructions().append(0);
1092     return dst;
1093 }
1094
1095 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1096 {
1097 #if ENABLE(JIT)
1098     m_codeBlock->addStructureStubInfo(StructureStubInfo(op_put_by_id));
1099 #else
1100     m_codeBlock->addPropertyAccessInstruction(instructions().size());
1101 #endif
1102
1103     emitOpcode(op_put_by_id);
1104     instructions().append(base->index());
1105     instructions().append(addConstant(property));
1106     instructions().append(value->index());
1107     instructions().append(0);
1108     instructions().append(0);
1109     instructions().append(0);
1110     instructions().append(0);
1111     return value;
1112 }
1113
1114 RegisterID* BytecodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value)
1115 {
1116     emitOpcode(op_put_getter);
1117     instructions().append(base->index());
1118     instructions().append(addConstant(property));
1119     instructions().append(value->index());
1120     return value;
1121 }
1122
1123 RegisterID* BytecodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value)
1124 {
1125     emitOpcode(op_put_setter);
1126     instructions().append(base->index());
1127     instructions().append(addConstant(property));
1128     instructions().append(value->index());
1129     return value;
1130 }
1131
1132 RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
1133 {
1134     emitOpcode(op_del_by_id);
1135     instructions().append(dst->index());
1136     instructions().append(base->index());
1137     instructions().append(addConstant(property));
1138     return dst;
1139 }
1140
1141 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1142 {
1143     emitOpcode(op_get_by_val);
1144     instructions().append(dst->index());
1145     instructions().append(base->index());
1146     instructions().append(property->index());
1147     return dst;
1148 }
1149
1150 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
1151 {
1152     emitOpcode(op_put_by_val);
1153     instructions().append(base->index());
1154     instructions().append(property->index());
1155     instructions().append(value->index());
1156     return value;
1157 }
1158
1159 RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1160 {
1161     emitOpcode(op_del_by_val);
1162     instructions().append(dst->index());
1163     instructions().append(base->index());
1164     instructions().append(property->index());
1165     return dst;
1166 }
1167
1168 RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
1169 {
1170     emitOpcode(op_put_by_index);
1171     instructions().append(base->index());
1172     instructions().append(index);
1173     instructions().append(value->index());
1174     return value;
1175 }
1176
1177 RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
1178 {
1179     emitOpcode(op_new_object);
1180     instructions().append(dst->index());
1181     return dst;
1182 }
1183
1184 RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
1185 {
1186     Vector<RefPtr<RegisterID>, 16> argv;
1187     for (ElementNode* n = elements; n; n = n->next()) {
1188         if (n->elision())
1189             break;
1190         argv.append(newTemporary());
1191         // op_new_array requires the initial values to be a sequential range of registers
1192         ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
1193         emitNode(argv.last().get(), n->value());
1194     }
1195     emitOpcode(op_new_array);
1196     instructions().append(dst->index());
1197     instructions().append(argv.size() ? argv[0]->index() : 0); // argv
1198     instructions().append(argv.size()); // argc
1199     return dst;
1200 }
1201
1202 RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FuncDeclNode* n)
1203 {
1204     emitOpcode(op_new_func);
1205     instructions().append(dst->index());
1206     instructions().append(addConstant(n));
1207     return dst;
1208 }
1209
1210 RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
1211 {
1212     emitOpcode(op_new_regexp);
1213     instructions().append(dst->index());
1214     instructions().append(addRegExp(regExp));
1215     return dst;
1216 }
1217
1218
1219 RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
1220 {
1221     emitOpcode(op_new_func_exp);
1222     instructions().append(r0->index());
1223     instructions().append(addConstant(n));
1224     return r0;
1225 }
1226
1227 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1228 {
1229     return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
1230 }
1231
1232 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1233 {
1234     return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
1235 }
1236
1237 RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1238 {
1239     ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
1240     ASSERT(func->refCount());
1241     ASSERT(thisRegister->refCount());
1242
1243     RegisterID* originalFunc = func;
1244     if (m_shouldEmitProfileHooks) {
1245         // If codegen decided to recycle func as this call's destination register,
1246         // we need to undo that optimization here so that func will still be around
1247         // for the sake of op_profile_did_call.
1248         if (dst == func) {
1249             RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), thisRegister);
1250             RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func);
1251             
1252             thisRegister = movedThisRegister.release().releaseRef();
1253             func = movedFunc.release().releaseRef();
1254         }
1255     }
1256
1257     // Generate code for arguments.
1258     Vector<RefPtr<RegisterID>, 16> argv;
1259     argv.append(thisRegister);
1260     for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
1261         argv.append(newTemporary());
1262         // op_call requires the arguments to be a sequential range of registers
1263         ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
1264         emitNode(argv.last().get(), n);
1265     }
1266
1267     // Reserve space for call frame.
1268     Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1269     for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1270         callFrame.append(newTemporary());
1271
1272     if (m_shouldEmitProfileHooks) {
1273         emitOpcode(op_profile_will_call);
1274         instructions().append(func->index());
1275
1276 #if ENABLE(JIT)
1277         m_codeBlock->addFunctionRegisterInfo(instructions().size(), func->index());
1278 #endif
1279     }
1280
1281     emitExpressionInfo(divot, startOffset, endOffset);
1282
1283 #if ENABLE(JIT)
1284     m_codeBlock->addCallLinkInfo();
1285 #endif
1286
1287     // Emit call.
1288     emitOpcode(opcodeID);
1289     instructions().append(dst->index()); // dst
1290     instructions().append(func->index()); // func
1291     instructions().append(argv.size()); // argCount
1292     instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
1293
1294     if (m_shouldEmitProfileHooks) {
1295         emitOpcode(op_profile_did_call);
1296         instructions().append(func->index());
1297
1298         if (dst == originalFunc) {
1299             thisRegister->deref();
1300             func->deref();
1301         }
1302     }
1303
1304     return dst;
1305 }
1306
1307 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
1308 {
1309     if (m_codeBlock->needsFullScopeChain()) {
1310         emitOpcode(op_tear_off_activation);
1311         instructions().append(m_activationRegisterIndex);
1312     } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1)
1313         emitOpcode(op_tear_off_arguments);
1314
1315     return emitUnaryNoDstOp(op_ret, src);
1316 }
1317
1318 RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src)
1319 {
1320     emitOpcode(opcodeID);
1321     instructions().append(src->index());
1322     return src;
1323 }
1324
1325 RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1326 {
1327     ASSERT(func->refCount());
1328
1329     RegisterID* originalFunc = func;
1330     if (m_shouldEmitProfileHooks) {
1331         // If codegen decided to recycle func as this call's destination register,
1332         // we need to undo that optimization here so that func will still be around
1333         // for the sake of op_profile_did_call.
1334         if (dst == func) {
1335             RefPtr<RegisterID> movedFunc = emitMove(newTemporary(), func);
1336             func = movedFunc.release().releaseRef();
1337         }
1338     }
1339
1340     RefPtr<RegisterID> funcProto = newTemporary();
1341
1342     // Generate code for arguments.
1343     Vector<RefPtr<RegisterID>, 16> argv;
1344     argv.append(newTemporary()); // reserve space for "this"
1345     for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) {
1346         argv.append(newTemporary());
1347         // op_construct requires the arguments to be a sequential range of registers
1348         ASSERT(argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
1349         emitNode(argv.last().get(), n);
1350     }
1351
1352     if (m_shouldEmitProfileHooks) {
1353         emitOpcode(op_profile_will_call);
1354         instructions().append(func->index());
1355     }
1356
1357     // Load prototype.
1358     emitExpressionInfo(divot, startOffset, endOffset);
1359     emitGetByIdExceptionInfo(op_construct);
1360     emitGetById(funcProto.get(), func, globalData()->propertyNames->prototype);
1361
1362     // Reserve space for call frame.
1363     Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1364     for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1365         callFrame.append(newTemporary());
1366
1367     emitExpressionInfo(divot, startOffset, endOffset);
1368
1369 #if ENABLE(JIT)
1370     m_codeBlock->addCallLinkInfo();
1371 #endif
1372
1373     emitOpcode(op_construct);
1374     instructions().append(dst->index()); // dst
1375     instructions().append(func->index()); // func
1376     instructions().append(argv.size()); // argCount
1377     instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
1378     instructions().append(funcProto->index()); // proto
1379     instructions().append(argv[0]->index()); // thisRegister
1380
1381     emitOpcode(op_construct_verify);
1382     instructions().append(dst->index());
1383     instructions().append(argv[0]->index());
1384
1385     if (m_shouldEmitProfileHooks) {
1386         emitOpcode(op_profile_did_call);
1387         instructions().append(func->index());
1388         
1389         if (dst == originalFunc)
1390             func->deref();
1391     }
1392
1393     return dst;
1394 }
1395
1396 RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
1397 {
1398     ASSERT(scope->isTemporary());
1399     ControlFlowContext context;
1400     context.isFinallyBlock = false;
1401     m_scopeContextStack.append(context);
1402     m_dynamicScopeDepth++;
1403
1404     return emitUnaryNoDstOp(op_push_scope, scope);
1405 }
1406
1407 void BytecodeGenerator::emitPopScope()
1408 {
1409     ASSERT(m_scopeContextStack.size());
1410     ASSERT(!m_scopeContextStack.last().isFinallyBlock);
1411
1412     emitOpcode(op_pop_scope);
1413
1414     m_scopeContextStack.removeLast();
1415     m_dynamicScopeDepth--;
1416 }
1417
1418 void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
1419 {
1420     if (!m_shouldEmitDebugHooks)
1421         return;
1422     emitOpcode(op_debug);
1423     instructions().append(debugHookID);
1424     instructions().append(firstLine);
1425     instructions().append(lastLine);
1426 }
1427
1428 void BytecodeGenerator::pushFinallyContext(Label* target, RegisterID* retAddrDst)
1429 {
1430     ControlFlowContext scope;
1431     scope.isFinallyBlock = true;
1432     FinallyContext context = { target, retAddrDst };
1433     scope.finallyContext = context;
1434     m_scopeContextStack.append(scope);
1435     m_finallyDepth++;
1436 }
1437
1438 void BytecodeGenerator::popFinallyContext()
1439 {
1440     ASSERT(m_scopeContextStack.size());
1441     ASSERT(m_scopeContextStack.last().isFinallyBlock);
1442     ASSERT(m_finallyDepth > 0);
1443     m_scopeContextStack.removeLast();
1444     m_finallyDepth--;
1445 }
1446
1447 LabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
1448 {
1449     // Reclaim free label scopes.
1450     while (m_labelScopes.size() && !m_labelScopes.last().refCount())
1451         m_labelScopes.removeLast();
1452
1453     if (!m_labelScopes.size())
1454         return 0;
1455
1456     // We special-case the following, which is a syntax error in Firefox:
1457     // label:
1458     //     break;
1459     if (name.isEmpty()) {
1460         for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1461             LabelScope* scope = &m_labelScopes[i];
1462             if (scope->type() != LabelScope::NamedLabel) {
1463                 ASSERT(scope->breakTarget());
1464                 return scope;
1465             }
1466         }
1467         return 0;
1468     }
1469
1470     for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1471         LabelScope* scope = &m_labelScopes[i];
1472         if (scope->name() && *scope->name() == name) {
1473             ASSERT(scope->breakTarget());
1474             return scope;
1475         }
1476     }
1477     return 0;
1478 }
1479
1480 LabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
1481 {
1482     // Reclaim free label scopes.
1483     while (m_labelScopes.size() && !m_labelScopes.last().refCount())
1484         m_labelScopes.removeLast();
1485
1486     if (!m_labelScopes.size())
1487         return 0;
1488
1489     if (name.isEmpty()) {
1490         for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1491             LabelScope* scope = &m_labelScopes[i];
1492             if (scope->type() == LabelScope::Loop) {
1493                 ASSERT(scope->continueTarget());
1494                 return scope;
1495             }
1496         }
1497         return 0;
1498     }
1499
1500     // Continue to the loop nested nearest to the label scope that matches
1501     // 'name'.
1502     LabelScope* result = 0;
1503     for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1504         LabelScope* scope = &m_labelScopes[i];
1505         if (scope->type() == LabelScope::Loop) {
1506             ASSERT(scope->continueTarget());
1507             result = scope;
1508         }
1509         if (scope->name() && *scope->name() == name)
1510             return result; // may be 0
1511     }
1512     return 0;
1513 }
1514
1515 PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
1516 {
1517     while (topScope > bottomScope) {
1518         // First we count the number of dynamic scopes we need to remove to get
1519         // to a finally block.
1520         int nNormalScopes = 0;
1521         while (topScope > bottomScope) {
1522             if (topScope->isFinallyBlock)
1523                 break;
1524             ++nNormalScopes;
1525             --topScope;
1526         }
1527
1528         if (nNormalScopes) {
1529             // We need to remove a number of dynamic scopes to get to the next
1530             // finally block
1531             emitOpcode(op_jmp_scopes);
1532             instructions().append(nNormalScopes);
1533
1534             // If topScope == bottomScope then there isn't actually a finally block
1535             // left to emit, so make the jmp_scopes jump directly to the target label
1536             if (topScope == bottomScope) {
1537                 instructions().append(target->offsetFrom(instructions().size()));
1538                 return target;
1539             }
1540
1541             // Otherwise we just use jmp_scopes to pop a group of scopes and go
1542             // to the next instruction
1543             RefPtr<Label> nextInsn = newLabel();
1544             instructions().append(nextInsn->offsetFrom(instructions().size()));
1545             emitLabel(nextInsn.get());
1546         }
1547
1548         // To get here there must be at least one finally block present
1549         do {
1550             ASSERT(topScope->isFinallyBlock);
1551             emitJumpSubroutine(topScope->finallyContext.retAddrDst, topScope->finallyContext.finallyAddr);
1552             --topScope;
1553             if (!topScope->isFinallyBlock)
1554                 break;
1555         } while (topScope > bottomScope);
1556     }
1557     return emitJump(target);
1558 }
1559
1560 PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetScopeDepth)
1561 {
1562     ASSERT(scopeDepth() - targetScopeDepth >= 0);
1563     ASSERT(target->isForward());
1564
1565     size_t scopeDelta = scopeDepth() - targetScopeDepth;
1566     ASSERT(scopeDelta <= m_scopeContextStack.size());
1567     if (!scopeDelta)
1568         return emitJump(target);
1569
1570     if (m_finallyDepth)
1571         return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
1572
1573     emitOpcode(op_jmp_scopes);
1574     instructions().append(scopeDelta);
1575     instructions().append(target->offsetFrom(instructions().size()));
1576     return target;
1577 }
1578
1579 RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target)
1580 {
1581     emitOpcode(op_next_pname);
1582     instructions().append(dst->index());
1583     instructions().append(iter->index());
1584     instructions().append(target->offsetFrom(instructions().size()));
1585     return dst;
1586 }
1587
1588 RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
1589 {
1590 #if ENABLE(JIT)
1591     HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth, 0 };
1592 #else
1593     HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth };
1594 #endif
1595
1596     m_codeBlock->addExceptionHandler(info);
1597     emitOpcode(op_catch);
1598     instructions().append(targetRegister->index());
1599     return targetRegister;
1600 }
1601
1602 RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValue* message)
1603 {
1604     emitOpcode(op_new_error);
1605     instructions().append(dst->index());
1606     instructions().append(static_cast<int>(type));
1607     instructions().append(addUnexpectedConstant(message));
1608     return dst;
1609 }
1610
1611 PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
1612 {
1613     emitOpcode(op_jsr);
1614     instructions().append(retAddrDst->index());
1615     instructions().append(finally->offsetFrom(instructions().size()));
1616     return finally;
1617 }
1618
1619 void BytecodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc)
1620 {
1621     emitOpcode(op_sret);
1622     instructions().append(retAddrSrc->index());
1623 }
1624
1625 void BytecodeGenerator::emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value)
1626 {
1627     ControlFlowContext context;
1628     context.isFinallyBlock = false;
1629     m_scopeContextStack.append(context);
1630     m_dynamicScopeDepth++;
1631     
1632     emitOpcode(op_push_new_scope);
1633     instructions().append(dst->index());
1634     instructions().append(addConstant(property));
1635     instructions().append(value->index());
1636 }
1637
1638 void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
1639 {
1640     SwitchInfo info = { instructions().size(), type };
1641     switch (type) {
1642         case SwitchInfo::SwitchImmediate:
1643             emitOpcode(op_switch_imm);
1644             break;
1645         case SwitchInfo::SwitchCharacter:
1646             emitOpcode(op_switch_char);
1647             break;
1648         case SwitchInfo::SwitchString:
1649             emitOpcode(op_switch_string);
1650             break;
1651         default:
1652             ASSERT_NOT_REACHED();
1653     }
1654
1655     instructions().append(0); // place holder for table index
1656     instructions().append(0); // place holder for default target    
1657     instructions().append(scrutineeRegister->index());
1658     m_switchContextStack.append(info);
1659 }
1660
1661 static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max)
1662 {
1663     UNUSED_PARAM(max);
1664     ASSERT(node->isNumber());
1665     double value = static_cast<NumberNode*>(node)->value();
1666     ASSERT(JSImmediate::from(value));
1667     int32_t key = static_cast<int32_t>(value);
1668     ASSERT(key == value);
1669     ASSERT(key >= min);
1670     ASSERT(key <= max);
1671     return key - min;
1672 }
1673
1674 static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
1675 {
1676     jumpTable.min = min;
1677     jumpTable.branchOffsets.resize(max - min + 1);
1678     jumpTable.branchOffsets.fill(0);
1679     for (uint32_t i = 0; i < clauseCount; ++i) {
1680         // We're emitting this after the clause labels should have been fixed, so 
1681         // the labels should not be "forward" references
1682         ASSERT(!labels[i]->isForward());
1683         jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); 
1684     }
1685 }
1686
1687 static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max)
1688 {
1689     UNUSED_PARAM(max);
1690     ASSERT(node->isString());
1691     UString::Rep* clause = static_cast<StringNode*>(node)->value().ustring().rep();
1692     ASSERT(clause->size() == 1);
1693     
1694     int32_t key = clause->data()[0];
1695     ASSERT(key >= min);
1696     ASSERT(key <= max);
1697     return key - min;
1698 }
1699
1700 static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
1701 {
1702     jumpTable.min = min;
1703     jumpTable.branchOffsets.resize(max - min + 1);
1704     jumpTable.branchOffsets.fill(0);
1705     for (uint32_t i = 0; i < clauseCount; ++i) {
1706         // We're emitting this after the clause labels should have been fixed, so 
1707         // the labels should not be "forward" references
1708         ASSERT(!labels[i]->isForward());
1709         jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); 
1710     }
1711 }
1712
1713 static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
1714 {
1715     for (uint32_t i = 0; i < clauseCount; ++i) {
1716         // We're emitting this after the clause labels should have been fixed, so 
1717         // the labels should not be "forward" references
1718         ASSERT(!labels[i]->isForward());
1719         
1720         ASSERT(nodes[i]->isString());
1721         UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep();
1722         OffsetLocation location;
1723         location.branchOffset = labels[i]->offsetFrom(switchAddress);
1724 #if ENABLE(JIT)
1725         location.ctiOffset = 0;
1726 #endif
1727         jumpTable.offsetTable.add(clause, location);
1728     }
1729 }
1730
1731 void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max)
1732 {
1733     SwitchInfo switchInfo = m_switchContextStack.last();
1734     m_switchContextStack.removeLast();
1735     if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
1736         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables();
1737         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
1738
1739         SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
1740         prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
1741     } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
1742         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables();
1743         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
1744         
1745         SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
1746         prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
1747     } else {
1748         ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
1749         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
1750         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
1751
1752         StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
1753         prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes);
1754     }
1755 }
1756
1757 RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
1758 {
1759     // It would be nice to do an even better job of identifying exactly where the expression is.
1760     // And we could make the caller pass the node pointer in, if there was some way of getting
1761     // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
1762     // is still good enough to get us an accurate line number.
1763     emitExpressionInfo(0, 0, 0);
1764     RegisterID* exception = emitNewError(newTemporary(), SyntaxError, jsString(globalData(), "Expression too deep"));
1765     emitThrow(exception);
1766     return exception;
1767 }
1768
1769 } // namespace JSC