221860e8cc8f18b77c95e37334cd91c01baee8da
[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, ResultType type)
753 {
754     emitOpcode(opcodeID);
755     instructions().append(dst->index());
756     instructions().append(src->index());
757     if (opcodeID == op_negate)
758         instructions().append(type.toInt());
759     return dst;
760 }
761
762 RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
763 {
764     emitOpcode(op_pre_inc);
765     instructions().append(srcDst->index());
766     return srcDst;
767 }
768
769 RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
770 {
771     emitOpcode(op_pre_dec);
772     instructions().append(srcDst->index());
773     return srcDst;
774 }
775
776 RegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
777 {
778     emitOpcode(op_post_inc);
779     instructions().append(dst->index());
780     instructions().append(srcDst->index());
781     return dst;
782 }
783
784 RegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
785 {
786     emitOpcode(op_post_dec);
787     instructions().append(dst->index());
788     instructions().append(srcDst->index());
789     return dst;
790 }
791
792 RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
793 {
794     emitOpcode(opcodeID);
795     instructions().append(dst->index());
796     instructions().append(src1->index());
797     instructions().append(src2->index());
798
799     if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
800         opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub) {
801         instructions().append(types.toInt());
802     }
803
804     return dst;
805 }
806
807 RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
808 {
809     if (m_lastOpcodeID == op_typeof) {
810         int dstIndex;
811         int srcIndex;
812
813         retrieveLastUnaryOp(dstIndex, srcIndex);
814
815         if (src1->index() == dstIndex
816             && src1->isTemporary()
817             && m_codeBlock->isConstantRegisterIndex(src2->index())
818             && m_codeBlock->constantRegisters[src2->index() - m_codeBlock->numVars].jsValue(m_scopeChain->globalObject()->globalExec())->isString()) {
819             const UString& value = asString(m_codeBlock->constantRegisters[src2->index() - m_codeBlock->numVars].jsValue(m_scopeChain->globalObject()->globalExec()))->value();
820             if (value == "undefined") {
821                 rewindUnaryOp();
822                 emitOpcode(op_is_undefined);
823                 instructions().append(dst->index());
824                 instructions().append(srcIndex);
825                 return dst;
826             }
827             if (value == "boolean") {
828                 rewindUnaryOp();
829                 emitOpcode(op_is_boolean);
830                 instructions().append(dst->index());
831                 instructions().append(srcIndex);
832                 return dst;
833             }
834             if (value == "number") {
835                 rewindUnaryOp();
836                 emitOpcode(op_is_number);
837                 instructions().append(dst->index());
838                 instructions().append(srcIndex);
839                 return dst;
840             }
841             if (value == "string") {
842                 rewindUnaryOp();
843                 emitOpcode(op_is_string);
844                 instructions().append(dst->index());
845                 instructions().append(srcIndex);
846                 return dst;
847             }
848             if (value == "object") {
849                 rewindUnaryOp();
850                 emitOpcode(op_is_object);
851                 instructions().append(dst->index());
852                 instructions().append(srcIndex);
853                 return dst;
854             }
855             if (value == "function") {
856                 rewindUnaryOp();
857                 emitOpcode(op_is_function);
858                 instructions().append(dst->index());
859                 instructions().append(srcIndex);
860                 return dst;
861             }
862         }
863     }
864
865     emitOpcode(opcodeID);
866     instructions().append(dst->index());
867     instructions().append(src1->index());
868     instructions().append(src2->index());
869     return dst;
870 }
871
872 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
873 {
874     return emitLoad(dst, jsBoolean(b));
875 }
876
877 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
878 {
879     // FIXME: Our hash tables won't hold infinity, so we make a new JSNumberCell each time.
880     // Later we can do the extra work to handle that like the other cases.
881     if (number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
882         return emitLoad(dst, jsNumber(globalData(), number));
883     JSValue*& valueInMap = m_numberMap.add(number, noValue()).first->second;
884     if (!valueInMap)
885         valueInMap = jsNumber(globalData(), number);
886     return emitLoad(dst, valueInMap);
887 }
888
889 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
890 {
891     JSString*& valueInMap = m_stringMap.add(identifier.ustring().rep(), 0).first->second;
892     if (!valueInMap)
893         valueInMap = jsOwnedString(globalData(), identifier.ustring());
894     return emitLoad(dst, valueInMap);
895 }
896
897 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue* v)
898 {
899     RegisterID* constantID = addConstant(v);
900     if (dst)
901         return emitMove(dst, constantID);
902     return constantID;
903 }
904
905 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSCell* cell)
906 {
907     JSValue* value = cell;
908     return emitLoad(dst, value);
909 }
910
911 RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, bool b)
912 {
913     emitOpcode(op_unexpected_load);
914     instructions().append(dst->index());
915     instructions().append(addUnexpectedConstant(jsBoolean(b)));
916     return dst;
917 }
918
919 RegisterID* BytecodeGenerator::emitUnexpectedLoad(RegisterID* dst, double d)
920 {
921     emitOpcode(op_unexpected_load);
922     instructions().append(dst->index());
923     instructions().append(addUnexpectedConstant(jsNumber(globalData(), d)));
924     return dst;
925 }
926
927 bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, JSObject*& globalObject)
928 {
929     // Cases where we cannot statically optimize the lookup.
930     if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
931         stackDepth = 0;
932         index = missingSymbolMarker();
933
934         if (shouldOptimizeLocals() && m_codeType == GlobalCode) {
935             ScopeChainIterator iter = m_scopeChain->begin();
936             globalObject = *iter;
937             ASSERT((++iter) == m_scopeChain->end());
938         }
939         return false;
940     }
941
942     size_t depth = 0;
943     
944     ScopeChainIterator iter = m_scopeChain->begin();
945     ScopeChainIterator end = m_scopeChain->end();
946     for (; iter != end; ++iter, ++depth) {
947         JSObject* currentScope = *iter;
948         if (!currentScope->isVariableObject())
949             break;
950         JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
951         SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.ustring().rep());
952
953         // Found the property
954         if (!entry.isNull()) {
955             if (entry.isReadOnly() && forWriting) {
956                 stackDepth = 0;
957                 index = missingSymbolMarker();
958                 if (++iter == end)
959                     globalObject = currentVariableObject;
960                 return false;
961             }
962             stackDepth = depth;
963             index = entry.getIndex();
964             if (++iter == end)
965                 globalObject = currentVariableObject;
966             return true;
967         }
968         if (currentVariableObject->isDynamicScope())
969             break;
970     }
971
972     // Can't locate the property but we're able to avoid a few lookups.
973     stackDepth = depth;
974     index = missingSymbolMarker();
975     JSObject* scope = *iter;
976     if (++iter == end)
977         globalObject = scope;
978     return true;
979 }
980
981 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
982
983     emitOpcode(op_instanceof);
984     instructions().append(dst->index());
985     instructions().append(value->index());
986     instructions().append(base->index());
987     instructions().append(basePrototype->index());
988     return dst;
989 }
990
991 RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& property)
992 {
993     size_t depth = 0;
994     int index = 0;
995     JSObject* globalObject = 0;
996     if (!findScopedProperty(property, index, depth, false, globalObject) && !globalObject) {
997         // We can't optimise at all :-(
998         emitOpcode(op_resolve);
999         instructions().append(dst->index());
1000         instructions().append(addConstant(property));
1001         return dst;
1002     }
1003
1004     if (index != missingSymbolMarker()) {
1005         // Directly index the property lookup across multiple scopes.  Yay!
1006         return emitGetScopedVar(dst, depth, index, globalObject);
1007     }
1008
1009     if (globalObject) {
1010         m_codeBlock->globalResolveInstructions.append(instructions().size());
1011         emitOpcode(op_resolve_global);
1012         instructions().append(dst->index());
1013         instructions().append(globalObject);
1014         instructions().append(addConstant(property));
1015         instructions().append(0);
1016         instructions().append(0);
1017         return dst;
1018     }
1019
1020     // In this case we are at least able to drop a few scope chains from the
1021     // lookup chain, although we still need to hash from then on.
1022     emitOpcode(op_resolve_skip);
1023     instructions().append(dst->index());
1024     instructions().append(addConstant(property));
1025     instructions().append(depth);
1026     return dst;
1027 }
1028
1029 RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue* globalObject)
1030 {
1031     if (globalObject) {
1032         emitOpcode(op_get_global_var);
1033         instructions().append(dst->index());
1034         instructions().append(asCell(globalObject));
1035         instructions().append(index);
1036         return dst;
1037     }
1038
1039     emitOpcode(op_get_scoped_var);
1040     instructions().append(dst->index());
1041     instructions().append(index);
1042     instructions().append(depth);
1043     return dst;
1044 }
1045
1046 RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue* globalObject)
1047 {
1048     if (globalObject) {
1049         emitOpcode(op_put_global_var);
1050         instructions().append(asCell(globalObject));
1051         instructions().append(index);
1052         instructions().append(value->index());
1053         return value;
1054     }
1055     emitOpcode(op_put_scoped_var);
1056     instructions().append(index);
1057     instructions().append(depth);
1058     instructions().append(value->index());
1059     return value;
1060 }
1061
1062 RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property)
1063 {
1064     emitOpcode(op_resolve_base);
1065     instructions().append(dst->index());
1066     instructions().append(addConstant(property));
1067     return dst;
1068 }
1069
1070 RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
1071 {
1072     emitOpcode(op_resolve_with_base);
1073     instructions().append(baseDst->index());
1074     instructions().append(propDst->index());
1075     instructions().append(addConstant(property));
1076     return baseDst;
1077 }
1078
1079 RegisterID* BytecodeGenerator::emitResolveFunction(RegisterID* baseDst, RegisterID* funcDst, const Identifier& property)
1080 {
1081     emitOpcode(op_resolve_func);
1082     instructions().append(baseDst->index());
1083     instructions().append(funcDst->index());
1084     instructions().append(addConstant(property));
1085     return baseDst;
1086 }
1087
1088 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1089 {
1090     m_codeBlock->propertyAccessInstructions.append(instructions().size());
1091
1092     emitOpcode(op_get_by_id);
1093     instructions().append(dst->index());
1094     instructions().append(base->index());
1095     instructions().append(addConstant(property));
1096     instructions().append(0);
1097     instructions().append(0);
1098     instructions().append(0);
1099     instructions().append(0);
1100     return dst;
1101 }
1102
1103 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1104 {
1105     m_codeBlock->propertyAccessInstructions.append(instructions().size());
1106
1107     emitOpcode(op_put_by_id);
1108     instructions().append(base->index());
1109     instructions().append(addConstant(property));
1110     instructions().append(value->index());
1111     instructions().append(0);
1112     instructions().append(0);
1113     instructions().append(0);
1114     instructions().append(0);
1115     return value;
1116 }
1117
1118 RegisterID* BytecodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value)
1119 {
1120     emitOpcode(op_put_getter);
1121     instructions().append(base->index());
1122     instructions().append(addConstant(property));
1123     instructions().append(value->index());
1124     return value;
1125 }
1126
1127 RegisterID* BytecodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value)
1128 {
1129     emitOpcode(op_put_setter);
1130     instructions().append(base->index());
1131     instructions().append(addConstant(property));
1132     instructions().append(value->index());
1133     return value;
1134 }
1135
1136 RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
1137 {
1138     emitOpcode(op_del_by_id);
1139     instructions().append(dst->index());
1140     instructions().append(base->index());
1141     instructions().append(addConstant(property));
1142     return dst;
1143 }
1144
1145 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1146 {
1147     emitOpcode(op_get_by_val);
1148     instructions().append(dst->index());
1149     instructions().append(base->index());
1150     instructions().append(property->index());
1151     return dst;
1152 }
1153
1154 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
1155 {
1156     emitOpcode(op_put_by_val);
1157     instructions().append(base->index());
1158     instructions().append(property->index());
1159     instructions().append(value->index());
1160     return value;
1161 }
1162
1163 RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1164 {
1165     emitOpcode(op_del_by_val);
1166     instructions().append(dst->index());
1167     instructions().append(base->index());
1168     instructions().append(property->index());
1169     return dst;
1170 }
1171
1172 RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
1173 {
1174     emitOpcode(op_put_by_index);
1175     instructions().append(base->index());
1176     instructions().append(index);
1177     instructions().append(value->index());
1178     return value;
1179 }
1180
1181 RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
1182 {
1183     emitOpcode(op_new_object);
1184     instructions().append(dst->index());
1185     return dst;
1186 }
1187
1188 RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements)
1189 {
1190     Vector<RefPtr<RegisterID>, 16> argv;
1191     for (ElementNode* n = elements; n; n = n->next()) {
1192         if (n->elision())
1193             break;
1194         argv.append(newTemporary());
1195         emitNode(argv.last().get(), n->value());
1196     }
1197     emitOpcode(op_new_array);
1198     instructions().append(dst->index());
1199     instructions().append(argv.size() ? argv[0]->index() : 0); // argv
1200     instructions().append(argv.size()); // argc
1201     return dst;
1202 }
1203
1204 RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FuncDeclNode* n)
1205 {
1206     emitOpcode(op_new_func);
1207     instructions().append(dst->index());
1208     instructions().append(addConstant(n));
1209     return dst;
1210 }
1211
1212 RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
1213 {
1214     emitOpcode(op_new_regexp);
1215     instructions().append(dst->index());
1216     instructions().append(addRegExp(regExp));
1217     return dst;
1218 }
1219
1220
1221 RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
1222 {
1223     emitOpcode(op_new_func_exp);
1224     instructions().append(r0->index());
1225     instructions().append(addConstant(n));
1226     return r0;
1227 }
1228
1229 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1230 {
1231     return emitCall(op_call, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
1232 }
1233
1234 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1235 {
1236     return emitCall(op_call_eval, dst, func, thisRegister, argumentsNode, divot, startOffset, endOffset);
1237 }
1238
1239 RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, RegisterID* thisRegister, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1240 {
1241     ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
1242     ASSERT(func->refCount());
1243
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> protect = thisRegister;
1250             RefPtr<RegisterID> movedThisRegister = emitMove(newTemporary(), thisRegister);
1251             RefPtr<RegisterID> movedFunc = emitMove(thisRegister, func);
1252             
1253             thisRegister = movedThisRegister.release().releaseRef();
1254             func = movedFunc.release().releaseRef();
1255         }
1256     }
1257
1258     // Generate code for arguments.
1259     Vector<RefPtr<RegisterID>, 16> argv;
1260     argv.append(thisRegister);
1261     for (ArgumentListNode* n = argumentsNode->m_listNode.get(); n; n = n->m_next.get()) {
1262         argv.append(newTemporary());
1263         emitNode(argv.last().get(), n);
1264     }
1265
1266     // Reserve space for call frame.
1267     Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1268     for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1269         callFrame.append(newTemporary());
1270
1271     if (m_shouldEmitProfileHooks) {
1272         emitOpcode(op_profile_will_call);
1273         instructions().append(func->index());
1274     }
1275
1276     emitExpressionInfo(divot, startOffset, endOffset);
1277     m_codeBlock->callLinkInfos.append(CallLinkInfo());
1278
1279     // Emit call.
1280     emitOpcode(opcodeID);
1281     instructions().append(dst->index()); // dst
1282     instructions().append(func->index()); // func
1283     instructions().append(argv.size()); // argCount
1284     instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
1285
1286     if (m_shouldEmitProfileHooks) {
1287         emitOpcode(op_profile_did_call);
1288         instructions().append(func->index());
1289
1290         if (dst == func) {
1291             thisRegister->deref();
1292             func->deref();
1293         }
1294     }
1295
1296     return dst;
1297 }
1298
1299 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
1300 {
1301     if (m_codeBlock->needsFullScopeChain) {
1302         emitOpcode(op_tear_off_activation);
1303         instructions().append(m_activationRegisterIndex);
1304     } else if (m_codeBlock->usesArguments && m_codeBlock->numParameters > 1)
1305         emitOpcode(op_tear_off_arguments);
1306
1307     return emitUnaryNoDstOp(op_ret, src);
1308 }
1309
1310 RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src)
1311 {
1312     emitOpcode(opcodeID);
1313     instructions().append(src->index());
1314     return src;
1315 }
1316
1317 RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, ArgumentsNode* argumentsNode, unsigned divot, unsigned startOffset, unsigned endOffset)
1318 {
1319     ASSERT(func->refCount());
1320
1321     if (m_shouldEmitProfileHooks) {
1322         // If codegen decided to recycle func as this call's destination register,
1323         // we need to undo that optimization here so that func will still be around
1324         // for the sake of op_profile_did_call.
1325         if (dst == func) {
1326             RefPtr<RegisterID> movedFunc = emitMove(newTemporary(), func);
1327             func = movedFunc.release().releaseRef();
1328         }
1329     }
1330
1331     RefPtr<RegisterID> funcProto = newTemporary();
1332
1333     // Generate code for arguments.
1334     Vector<RefPtr<RegisterID>, 16> argv;
1335     argv.append(newTemporary()); // reserve space for "this"
1336     for (ArgumentListNode* n = argumentsNode ? argumentsNode->m_listNode.get() : 0; n; n = n->m_next.get()) {
1337         argv.append(newTemporary());
1338         emitNode(argv.last().get(), n);
1339     }
1340
1341     if (m_shouldEmitProfileHooks) {
1342         emitOpcode(op_profile_will_call);
1343         instructions().append(func->index());
1344     }
1345
1346     // Load prototype.
1347     emitExpressionInfo(divot, startOffset, endOffset);
1348     emitGetById(funcProto.get(), func, globalData()->propertyNames->prototype);
1349
1350     // Reserve space for call frame.
1351     Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1352     for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1353         callFrame.append(newTemporary());
1354
1355     emitExpressionInfo(divot, startOffset, endOffset);
1356     m_codeBlock->callLinkInfos.append(CallLinkInfo());
1357
1358     emitOpcode(op_construct);
1359     instructions().append(dst->index()); // dst
1360     instructions().append(func->index()); // func
1361     instructions().append(argv.size()); // argCount
1362     instructions().append(argv[0]->index() + argv.size() + RegisterFile::CallFrameHeaderSize); // registerOffset
1363     instructions().append(funcProto->index()); // proto
1364     instructions().append(argv[0]->index()); // thisRegister
1365
1366     emitOpcode(op_construct_verify);
1367     instructions().append(dst->index());
1368     instructions().append(argv[0]->index());
1369
1370     if (m_shouldEmitProfileHooks) {
1371         emitOpcode(op_profile_did_call);
1372         instructions().append(func->index());
1373         
1374         if (dst == func)
1375             func->deref();
1376     }
1377
1378     return dst;
1379 }
1380
1381 RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
1382 {
1383     ControlFlowContext context;
1384     context.isFinallyBlock = false;
1385     m_scopeContextStack.append(context);
1386     m_dynamicScopeDepth++;
1387
1388     return emitUnaryNoDstOp(op_push_scope, scope);
1389 }
1390
1391 void BytecodeGenerator::emitPopScope()
1392 {
1393     ASSERT(m_scopeContextStack.size());
1394     ASSERT(!m_scopeContextStack.last().isFinallyBlock);
1395
1396     emitOpcode(op_pop_scope);
1397
1398     m_scopeContextStack.removeLast();
1399     m_dynamicScopeDepth--;
1400 }
1401
1402 void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
1403 {
1404     if (!m_shouldEmitDebugHooks)
1405         return;
1406     emitOpcode(op_debug);
1407     instructions().append(debugHookID);
1408     instructions().append(firstLine);
1409     instructions().append(lastLine);
1410 }
1411
1412 void BytecodeGenerator::pushFinallyContext(Label* target, RegisterID* retAddrDst)
1413 {
1414     ControlFlowContext scope;
1415     scope.isFinallyBlock = true;
1416     FinallyContext context = { target, retAddrDst };
1417     scope.finallyContext = context;
1418     m_scopeContextStack.append(scope);
1419     m_finallyDepth++;
1420 }
1421
1422 void BytecodeGenerator::popFinallyContext()
1423 {
1424     ASSERT(m_scopeContextStack.size());
1425     ASSERT(m_scopeContextStack.last().isFinallyBlock);
1426     ASSERT(m_finallyDepth > 0);
1427     m_scopeContextStack.removeLast();
1428     m_finallyDepth--;
1429 }
1430
1431 LabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
1432 {
1433     // Reclaim free label scopes.
1434     while (m_labelScopes.size() && !m_labelScopes.last().refCount())
1435         m_labelScopes.removeLast();
1436
1437     if (!m_labelScopes.size())
1438         return 0;
1439
1440     // We special-case the following, which is a syntax error in Firefox:
1441     // label:
1442     //     break;
1443     if (name.isEmpty()) {
1444         for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1445             LabelScope* scope = &m_labelScopes[i];
1446             if (scope->type() != LabelScope::NamedLabel) {
1447                 ASSERT(scope->breakTarget());
1448                 return scope;
1449             }
1450         }
1451         return 0;
1452     }
1453
1454     for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1455         LabelScope* scope = &m_labelScopes[i];
1456         if (scope->name() && *scope->name() == name) {
1457             ASSERT(scope->breakTarget());
1458             return scope;
1459         }
1460     }
1461     return 0;
1462 }
1463
1464 LabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
1465 {
1466     // Reclaim free label scopes.
1467     while (m_labelScopes.size() && !m_labelScopes.last().refCount())
1468         m_labelScopes.removeLast();
1469
1470     if (!m_labelScopes.size())
1471         return 0;
1472
1473     if (name.isEmpty()) {
1474         for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1475             LabelScope* scope = &m_labelScopes[i];
1476             if (scope->type() == LabelScope::Loop) {
1477                 ASSERT(scope->continueTarget());
1478                 return scope;
1479             }
1480         }
1481         return 0;
1482     }
1483
1484     // Continue to the loop nested nearest to the label scope that matches
1485     // 'name'.
1486     LabelScope* result = 0;
1487     for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
1488         LabelScope* scope = &m_labelScopes[i];
1489         if (scope->type() == LabelScope::Loop) {
1490             ASSERT(scope->continueTarget());
1491             result = scope;
1492         }
1493         if (scope->name() && *scope->name() == name)
1494             return result; // may be 0
1495     }
1496     return 0;
1497 }
1498
1499 PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
1500 {
1501     while (topScope > bottomScope) {
1502         // First we count the number of dynamic scopes we need to remove to get
1503         // to a finally block.
1504         int nNormalScopes = 0;
1505         while (topScope > bottomScope) {
1506             if (topScope->isFinallyBlock)
1507                 break;
1508             ++nNormalScopes;
1509             --topScope;
1510         }
1511
1512         if (nNormalScopes) {
1513             // We need to remove a number of dynamic scopes to get to the next
1514             // finally block
1515             emitOpcode(op_jmp_scopes);
1516             instructions().append(nNormalScopes);
1517
1518             // If topScope == bottomScope then there isn't actually a finally block
1519             // left to emit, so make the jmp_scopes jump directly to the target label
1520             if (topScope == bottomScope) {
1521                 instructions().append(target->offsetFrom(instructions().size()));
1522                 return target;
1523             }
1524
1525             // Otherwise we just use jmp_scopes to pop a group of scopes and go
1526             // to the next instruction
1527             RefPtr<Label> nextInsn = newLabel();
1528             instructions().append(nextInsn->offsetFrom(instructions().size()));
1529             emitLabel(nextInsn.get());
1530         }
1531
1532         // To get here there must be at least one finally block present
1533         do {
1534             ASSERT(topScope->isFinallyBlock);
1535             emitJumpSubroutine(topScope->finallyContext.retAddrDst, topScope->finallyContext.finallyAddr);
1536             --topScope;
1537             if (!topScope->isFinallyBlock)
1538                 break;
1539         } while (topScope > bottomScope);
1540     }
1541     return emitJump(target);
1542 }
1543
1544 PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetScopeDepth)
1545 {
1546     ASSERT(scopeDepth() - targetScopeDepth >= 0);
1547     ASSERT(target->isForward());
1548
1549     size_t scopeDelta = scopeDepth() - targetScopeDepth;
1550     ASSERT(scopeDelta <= m_scopeContextStack.size());
1551     if (!scopeDelta)
1552         return emitJump(target);
1553
1554     if (m_finallyDepth)
1555         return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
1556
1557     emitOpcode(op_jmp_scopes);
1558     instructions().append(scopeDelta);
1559     instructions().append(target->offsetFrom(instructions().size()));
1560     return target;
1561 }
1562
1563 RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* iter, Label* target)
1564 {
1565     emitOpcode(op_next_pname);
1566     instructions().append(dst->index());
1567     instructions().append(iter->index());
1568     instructions().append(target->offsetFrom(instructions().size()));
1569     return dst;
1570 }
1571
1572 RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
1573 {
1574     HandlerInfo info = { start->offsetFrom(0), end->offsetFrom(0), instructions().size(), m_dynamicScopeDepth, 0 };
1575     exceptionHandlers().append(info);
1576     emitOpcode(op_catch);
1577     instructions().append(targetRegister->index());
1578     return targetRegister;
1579 }
1580
1581 RegisterID* BytecodeGenerator::emitNewError(RegisterID* dst, ErrorType type, JSValue* message)
1582 {
1583     emitOpcode(op_new_error);
1584     instructions().append(dst->index());
1585     instructions().append(static_cast<int>(type));
1586     instructions().append(addUnexpectedConstant(message));
1587     return dst;
1588 }
1589
1590 PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
1591 {
1592     emitOpcode(op_jsr);
1593     instructions().append(retAddrDst->index());
1594     instructions().append(finally->offsetFrom(instructions().size()));
1595     return finally;
1596 }
1597
1598 void BytecodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc)
1599 {
1600     emitOpcode(op_sret);
1601     instructions().append(retAddrSrc->index());
1602 }
1603
1604 void BytecodeGenerator::emitPushNewScope(RegisterID* dst, Identifier& property, RegisterID* value)
1605 {
1606     ControlFlowContext context;
1607     context.isFinallyBlock = false;
1608     m_scopeContextStack.append(context);
1609     m_dynamicScopeDepth++;
1610     
1611     emitOpcode(op_push_new_scope);
1612     instructions().append(dst->index());
1613     instructions().append(addConstant(property));
1614     instructions().append(value->index());
1615 }
1616
1617 void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
1618 {
1619     SwitchInfo info = { instructions().size(), type };
1620     switch (type) {
1621         case SwitchInfo::SwitchImmediate:
1622             emitOpcode(op_switch_imm);
1623             break;
1624         case SwitchInfo::SwitchCharacter:
1625             emitOpcode(op_switch_char);
1626             break;
1627         case SwitchInfo::SwitchString:
1628             emitOpcode(op_switch_string);
1629             break;
1630         default:
1631             ASSERT_NOT_REACHED();
1632     }
1633
1634     instructions().append(0); // place holder for table index
1635     instructions().append(0); // place holder for default target    
1636     instructions().append(scrutineeRegister->index());
1637     m_switchContextStack.append(info);
1638 }
1639
1640 static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max)
1641 {
1642     UNUSED_PARAM(max);
1643     ASSERT(node->isNumber());
1644     double value = static_cast<NumberNode*>(node)->value();
1645     ASSERT(JSImmediate::from(value));
1646     int32_t key = static_cast<int32_t>(value);
1647     ASSERT(key == value);
1648     ASSERT(key >= min);
1649     ASSERT(key <= max);
1650     return key - min;
1651 }
1652
1653 static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
1654 {
1655     jumpTable.min = min;
1656     jumpTable.branchOffsets.resize(max - min + 1);
1657     jumpTable.branchOffsets.fill(0);
1658     for (uint32_t i = 0; i < clauseCount; ++i) {
1659         // We're emitting this after the clause labels should have been fixed, so 
1660         // the labels should not be "forward" references
1661         ASSERT(!labels[i]->isForward());
1662         jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); 
1663     }
1664 }
1665
1666 static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max)
1667 {
1668     UNUSED_PARAM(max);
1669     ASSERT(node->isString());
1670     UString::Rep* clause = static_cast<StringNode*>(node)->value().ustring().rep();
1671     ASSERT(clause->size() == 1);
1672     
1673     int32_t key = clause->data()[0];
1674     ASSERT(key >= min);
1675     ASSERT(key <= max);
1676     return key - min;
1677 }
1678
1679 static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
1680 {
1681     jumpTable.min = min;
1682     jumpTable.branchOffsets.resize(max - min + 1);
1683     jumpTable.branchOffsets.fill(0);
1684     for (uint32_t i = 0; i < clauseCount; ++i) {
1685         // We're emitting this after the clause labels should have been fixed, so 
1686         // the labels should not be "forward" references
1687         ASSERT(!labels[i]->isForward());
1688         jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->offsetFrom(switchAddress)); 
1689     }
1690 }
1691
1692 static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
1693 {
1694     for (uint32_t i = 0; i < clauseCount; ++i) {
1695         // We're emitting this after the clause labels should have been fixed, so 
1696         // the labels should not be "forward" references
1697         ASSERT(!labels[i]->isForward());
1698         
1699         ASSERT(nodes[i]->isString());
1700         UString::Rep* clause = static_cast<StringNode*>(nodes[i])->value().ustring().rep();
1701         OffsetLocation location;
1702         location.branchOffset = labels[i]->offsetFrom(switchAddress);
1703 #if ENABLE(JIT)
1704         location.ctiOffset = 0;
1705 #endif
1706         jumpTable.offsetTable.add(clause, location);
1707     }
1708 }
1709
1710 void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max)
1711 {
1712     SwitchInfo switchInfo = m_switchContextStack.last();
1713     m_switchContextStack.removeLast();
1714     if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
1715         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->immediateSwitchJumpTables.size();
1716         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
1717
1718         m_codeBlock->immediateSwitchJumpTables.append(SimpleJumpTable());
1719         SimpleJumpTable& jumpTable = m_codeBlock->immediateSwitchJumpTables.last();
1720
1721         prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
1722     } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
1723         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->characterSwitchJumpTables.size();
1724         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
1725         
1726         m_codeBlock->characterSwitchJumpTables.append(SimpleJumpTable());
1727         SimpleJumpTable& jumpTable = m_codeBlock->characterSwitchJumpTables.last();
1728
1729         prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes, min, max);
1730     } else {
1731         ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
1732         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->stringSwitchJumpTables.size();
1733         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->offsetFrom(switchInfo.bytecodeOffset + 3);
1734
1735         m_codeBlock->stringSwitchJumpTables.append(StringJumpTable());
1736         StringJumpTable& jumpTable = m_codeBlock->stringSwitchJumpTables.last();
1737
1738         prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset + 3, clauseCount, labels, nodes);
1739     }
1740 }
1741
1742 RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
1743 {
1744     // It would be nice to do an even better job of identifying exactly where the expression is.
1745     // And we could make the caller pass the node pointer in, if there was some way of getting
1746     // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
1747     // is still good enough to get us an accurate line number.
1748     emitExpressionInfo(0, 0, 0);
1749     RegisterID* exception = emitNewError(newTemporary(), SyntaxError, jsString(globalData(), "Expression too deep"));
1750     emitThrow(exception);
1751     return exception;
1752 }
1753
1754 } // namespace JSC