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