initial import
[vuplus_webkit] / Source / JavaScriptCore / bytecompiler / BytecodeGenerator.cpp
1 /*
2  * Copyright (C) 2008, 2009 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 "ScopeChain.h"
37 #include "UString.h"
38
39 using namespace std;
40
41 namespace JSC {
42
43 /*
44     The layout of a register frame looks like this:
45
46     For
47
48     function f(x, y) {
49         var v1;
50         function g() { }
51         var v2;
52         return (x) * (y);
53     }
54
55     assuming (x) and (y) generated temporaries t1 and t2, you would have
56
57     ------------------------------------
58     |  x |  y |  g | v2 | v1 | t1 | t2 | <-- value held
59     ------------------------------------
60     | -5 | -4 | -3 | -2 | -1 | +0 | +1 | <-- register index
61     ------------------------------------
62     | params->|<-locals      | temps->
63
64     Because temporary registers are allocated in a stack-like fashion, we
65     can reclaim them with a simple popping algorithm. The same goes for labels.
66     (We never reclaim parameter or local registers, because parameters and
67     locals are DontDelete.)
68
69     The register layout before a function call looks like this:
70
71     For
72
73     function f(x, y)
74     {
75     }
76
77     f(1);
78
79     >                        <------------------------------
80     <                        >  reserved: call frame  |  1 | <-- value held
81     >         >snip<         <------------------------------
82     <                        > +0 | +1 | +2 | +3 | +4 | +5 | <-- register index
83     >                        <------------------------------
84     | params->|<-locals      | temps->
85
86     The call instruction fills in the "call frame" registers. It also pads
87     missing arguments at the end of the call:
88
89     >                        <-----------------------------------
90     <                        >  reserved: call frame  |  1 |  ? | <-- value held ("?" stands for "undefined")
91     >         >snip<         <-----------------------------------
92     <                        > +0 | +1 | +2 | +3 | +4 | +5 | +6 | <-- register index
93     >                        <-----------------------------------
94     | params->|<-locals      | temps->
95
96     After filling in missing arguments, the call instruction sets up the new
97     stack frame to overlap the end of the old stack frame:
98
99                              |---------------------------------->                        <
100                              |  reserved: call frame  |  1 |  ? <                        > <-- value held ("?" stands for "undefined")
101                              |---------------------------------->         >snip<         <
102                              | -7 | -6 | -5 | -4 | -3 | -2 | -1 <                        > <-- register index
103                              |---------------------------------->                        <
104                              |                        | params->|<-locals       | temps->
105
106     That way, arguments are "copied" into the callee's stack frame for free.
107
108     If the caller supplies too many arguments, this trick doesn't work. The
109     extra arguments protrude into space reserved for locals and temporaries.
110     In that case, the call instruction makes a real copy of the call frame header,
111     along with just the arguments expected by the callee, leaving the original
112     call frame header and arguments behind. (The call instruction can't just discard
113     extra arguments, because the "arguments" object may access them later.)
114     This copying strategy ensures that all named values will be at the indices
115     expected by the callee.
116 */
117
118 #ifndef NDEBUG
119 static bool s_dumpsGeneratedCode = false;
120 #endif
121
122 void BytecodeGenerator::setDumpsGeneratedCode(bool dumpsGeneratedCode)
123 {
124 #ifndef NDEBUG
125     s_dumpsGeneratedCode = dumpsGeneratedCode;
126 #else
127     UNUSED_PARAM(dumpsGeneratedCode);
128 #endif
129 }
130
131 bool BytecodeGenerator::dumpsGeneratedCode()
132 {
133 #ifndef NDEBUG
134     return s_dumpsGeneratedCode;
135 #else
136     return false;
137 #endif
138 }
139
140 JSObject* BytecodeGenerator::generate()
141 {
142     m_codeBlock->setThisRegister(m_thisRegister.index());
143
144     m_scopeNode->emitBytecode(*this);
145
146 #ifndef NDEBUG
147     m_codeBlock->setInstructionCount(m_codeBlock->instructions().size());
148
149     if (s_dumpsGeneratedCode)
150         m_codeBlock->dump(m_scopeChain->globalObject->globalExec());
151 #endif
152
153     if ((m_codeType == FunctionCode && !m_codeBlock->needsFullScopeChain() && !m_codeBlock->usesArguments()) || m_codeType == EvalCode)
154         symbolTable().clear();
155
156     m_codeBlock->shrinkToFit();
157
158     if (m_expressionTooDeep)
159         return createOutOfMemoryError(m_scopeChain->globalObject.get());
160     return 0;
161 }
162
163 bool BytecodeGenerator::addVar(const Identifier& ident, bool isConstant, RegisterID*& r0)
164 {
165     int index = m_calleeRegisters.size();
166     SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
167     pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry);
168
169     if (!result.second) {
170         r0 = &registerFor(result.first->second.getIndex());
171         return false;
172     }
173
174     r0 = addVar();
175     return true;
176 }
177
178 int BytecodeGenerator::addGlobalVar(const Identifier& ident, bool isConstant)
179 {
180     int index = symbolTable().size();
181     SymbolTableEntry newEntry(index, isConstant ? ReadOnly : 0);
182     pair<SymbolTable::iterator, bool> result = symbolTable().add(ident.impl(), newEntry);
183     if (!result.second)
184         index = result.first->second.getIndex();
185     return index;
186 }
187
188 void BytecodeGenerator::preserveLastVar()
189 {
190     if ((m_firstConstantIndex = m_calleeRegisters.size()) != 0)
191         m_lastVar = &m_calleeRegisters.last();
192 }
193
194 BytecodeGenerator::BytecodeGenerator(ProgramNode* programNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, ProgramCodeBlock* codeBlock, CompilationKind compilationKind)
195     : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
196     , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
197     , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
198     , m_scopeChain(*scopeChain->globalData, scopeChain)
199     , m_symbolTable(symbolTable)
200     , m_scopeNode(programNode)
201     , m_codeBlock(codeBlock)
202     , m_thisRegister(RegisterFile::ProgramCodeThisRegister)
203     , m_finallyDepth(0)
204     , m_dynamicScopeDepth(0)
205     , m_baseScopeDepth(0)
206     , m_codeType(GlobalCode)
207     , m_nextConstantOffset(0)
208     , m_globalConstantIndex(0)
209     , m_hasCreatedActivation(true)
210     , m_firstLazyFunction(0)
211     , m_lastLazyFunction(0)
212     , m_globalData(scopeChain->globalData)
213     , m_lastOpcodeID(op_end)
214 #ifndef NDEBUG
215     , m_lastOpcodePosition(0)
216 #endif
217     , m_stack(m_globalData->stack())
218     , m_usesExceptions(false)
219     , m_expressionTooDeep(false)
220 {
221     if (m_shouldEmitDebugHooks)
222         m_codeBlock->setNeedsFullScopeChain(true);
223
224     emitOpcode(op_enter);
225     codeBlock->setGlobalData(m_globalData);
226
227     // FIXME: Move code that modifies the global object to Interpreter::execute.
228     
229     m_codeBlock->m_numParameters = 1; // Allocate space for "this"
230     codeBlock->m_numCapturedVars = codeBlock->m_numVars;
231     
232     if (compilationKind == OptimizingCompilation)
233         return;
234
235     JSGlobalObject* globalObject = scopeChain->globalObject.get();
236     ExecState* exec = globalObject->globalExec();
237     
238     BatchedTransitionOptimizer optimizer(*m_globalData, globalObject);
239
240     const VarStack& varStack = programNode->varStack();
241     const FunctionStack& functionStack = programNode->functionStack();
242
243     size_t newGlobals = varStack.size() + functionStack.size();
244     if (!newGlobals)
245         return;
246     globalObject->resizeRegisters(symbolTable->size() + newGlobals);
247
248     for (size_t i = 0; i < functionStack.size(); ++i) {
249         FunctionBodyNode* function = functionStack[i];
250         globalObject->removeDirect(*m_globalData, function->ident()); // Newly declared functions overwrite existing properties.
251
252         JSValue value = JSFunction::create(exec, makeFunction(exec, function), scopeChain);
253         int index = addGlobalVar(function->ident(), false);
254         globalObject->registerAt(index).set(*m_globalData, globalObject, value);
255     }
256
257     for (size_t i = 0; i < varStack.size(); ++i) {
258         if (globalObject->hasProperty(exec, *varStack[i].first))
259             continue;
260         addGlobalVar(*varStack[i].first, varStack[i].second & DeclarationStacks::IsConstant);
261     }
262 }
263
264 BytecodeGenerator::BytecodeGenerator(FunctionBodyNode* functionBody, ScopeChainNode* scopeChain, SymbolTable* symbolTable, CodeBlock* codeBlock, CompilationKind)
265     : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
266     , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
267     , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
268     , m_scopeChain(*scopeChain->globalData, scopeChain)
269     , m_symbolTable(symbolTable)
270     , m_scopeNode(functionBody)
271     , m_codeBlock(codeBlock)
272     , m_activationRegister(0)
273     , m_finallyDepth(0)
274     , m_dynamicScopeDepth(0)
275     , m_baseScopeDepth(0)
276     , m_codeType(FunctionCode)
277     , m_nextConstantOffset(0)
278     , m_globalConstantIndex(0)
279     , m_hasCreatedActivation(false)
280     , m_firstLazyFunction(0)
281     , m_lastLazyFunction(0)
282     , m_globalData(scopeChain->globalData)
283     , m_lastOpcodeID(op_end)
284 #ifndef NDEBUG
285     , m_lastOpcodePosition(0)
286 #endif
287     , m_stack(m_globalData->stack())
288     , m_usesExceptions(false)
289     , m_expressionTooDeep(false)
290 {
291     if (m_shouldEmitDebugHooks)
292         m_codeBlock->setNeedsFullScopeChain(true);
293
294     codeBlock->setGlobalData(m_globalData);
295     
296     emitOpcode(op_enter);
297     if (m_codeBlock->needsFullScopeChain()) {
298         m_activationRegister = addVar();
299         emitInitLazyRegister(m_activationRegister);
300         m_codeBlock->setActivationRegister(m_activationRegister->index());
301     }
302
303     // Both op_tear_off_activation and op_tear_off_arguments tear off the 'arguments'
304     // object, if created.
305     if (m_codeBlock->needsFullScopeChain() || functionBody->usesArguments()) {
306         RegisterID* unmodifiedArgumentsRegister = addVar(); // Anonymous, so it can't be modified by user code.
307         RegisterID* argumentsRegister = addVar(propertyNames().arguments, false); // Can be changed by assigning to 'arguments'.
308
309         // We can save a little space by hard-coding the knowledge that the two
310         // 'arguments' values are stored in consecutive registers, and storing
311         // only the index of the assignable one.
312         codeBlock->setArgumentsRegister(argumentsRegister->index());
313         ASSERT_UNUSED(unmodifiedArgumentsRegister, unmodifiedArgumentsRegister->index() == JSC::unmodifiedArgumentsRegister(codeBlock->argumentsRegister()));
314
315         emitInitLazyRegister(argumentsRegister);
316         emitInitLazyRegister(unmodifiedArgumentsRegister);
317         
318         if (m_codeBlock->isStrictMode()) {
319             emitOpcode(op_create_arguments);
320             instructions().append(argumentsRegister->index());
321         }
322
323         // The debugger currently retrieves the arguments object from an activation rather than pulling
324         // it from a call frame.  In the long-term it should stop doing that (<rdar://problem/6911886>),
325         // but for now we force eager creation of the arguments object when debugging.
326         if (m_shouldEmitDebugHooks) {
327             emitOpcode(op_create_arguments);
328             instructions().append(argumentsRegister->index());
329         }
330     }
331
332     const DeclarationStacks::FunctionStack& functionStack = functionBody->functionStack();
333     const DeclarationStacks::VarStack& varStack = functionBody->varStack();
334
335     // Captured variables and functions go first so that activations don't have
336     // to step over the non-captured locals to mark them.
337     m_hasCreatedActivation = false;
338     if (functionBody->hasCapturedVariables()) {
339         for (size_t i = 0; i < functionStack.size(); ++i) {
340             FunctionBodyNode* function = functionStack[i];
341             const Identifier& ident = function->ident();
342             if (functionBody->captures(ident)) {
343                 if (!m_hasCreatedActivation) {
344                     m_hasCreatedActivation = true;
345                     emitOpcode(op_create_activation);
346                     instructions().append(m_activationRegister->index());
347                 }
348                 m_functions.add(ident.impl());
349                 emitNewFunction(addVar(ident, false), function);
350             }
351         }
352         for (size_t i = 0; i < varStack.size(); ++i) {
353             const Identifier& ident = *varStack[i].first;
354             if (functionBody->captures(ident))
355                 addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
356         }
357     }
358     bool canLazilyCreateFunctions = !functionBody->needsActivationForMoreThanVariables() && !m_shouldEmitDebugHooks;
359     if (!canLazilyCreateFunctions && !m_hasCreatedActivation) {
360         m_hasCreatedActivation = true;
361         emitOpcode(op_create_activation);
362         instructions().append(m_activationRegister->index());
363     }
364
365     codeBlock->m_numCapturedVars = codeBlock->m_numVars;
366     m_firstLazyFunction = codeBlock->m_numVars;
367     for (size_t i = 0; i < functionStack.size(); ++i) {
368         FunctionBodyNode* function = functionStack[i];
369         const Identifier& ident = function->ident();
370         if (!functionBody->captures(ident)) {
371             m_functions.add(ident.impl());
372             RefPtr<RegisterID> reg = addVar(ident, false);
373             // Don't lazily create functions that override the name 'arguments'
374             // as this would complicate lazy instantiation of actual arguments.
375             if (!canLazilyCreateFunctions || ident == propertyNames().arguments)
376                 emitNewFunction(reg.get(), function);
377             else {
378                 emitInitLazyRegister(reg.get());
379                 m_lazyFunctions.set(reg->index(), function);
380             }
381         }
382     }
383     m_lastLazyFunction = canLazilyCreateFunctions ? codeBlock->m_numVars : m_firstLazyFunction;
384     for (size_t i = 0; i < varStack.size(); ++i) {
385         const Identifier& ident = *varStack[i].first;
386         if (!functionBody->captures(ident))
387             addVar(ident, varStack[i].second & DeclarationStacks::IsConstant);
388     }
389     
390     if (m_shouldEmitDebugHooks)
391         codeBlock->m_numCapturedVars = codeBlock->m_numVars;
392
393     FunctionParameters& parameters = *functionBody->parameters();
394     size_t parameterCount = parameters.size();
395     int nextParameterIndex = -RegisterFile::CallFrameHeaderSize - parameterCount - 1;
396     m_parameters.grow(1 + parameterCount); // reserve space for "this"
397
398     // Add "this" as a parameter
399     m_thisRegister.setIndex(nextParameterIndex);
400     ++m_codeBlock->m_numParameters;
401     
402     for (size_t i = 0; i < parameterCount; ++i)
403         addParameter(parameters[i], ++nextParameterIndex);
404
405     preserveLastVar();
406
407     if (isConstructor()) {
408         RefPtr<RegisterID> func = newTemporary();
409         RefPtr<RegisterID> funcProto = newTemporary();
410
411         emitOpcode(op_get_callee);
412         instructions().append(func->index());
413         // Load prototype.
414         emitGetById(funcProto.get(), func.get(), globalData()->propertyNames->prototype);
415
416         emitOpcode(op_create_this);
417         instructions().append(m_thisRegister.index());
418         instructions().append(funcProto->index());
419     } else if (!codeBlock->isStrictMode() && (functionBody->usesThis() || codeBlock->usesEval() || m_shouldEmitDebugHooks)) {
420         emitOpcode(op_convert_this);
421         instructions().append(m_thisRegister.index());
422     }
423 }
424
425 BytecodeGenerator::BytecodeGenerator(EvalNode* evalNode, ScopeChainNode* scopeChain, SymbolTable* symbolTable, EvalCodeBlock* codeBlock, CompilationKind)
426     : m_shouldEmitDebugHooks(scopeChain->globalObject->debugger())
427     , m_shouldEmitProfileHooks(scopeChain->globalObject->supportsProfiling())
428     , m_shouldEmitRichSourceInfo(scopeChain->globalObject->supportsRichSourceInfo())
429     , m_scopeChain(*scopeChain->globalData, scopeChain)
430     , m_symbolTable(symbolTable)
431     , m_scopeNode(evalNode)
432     , m_codeBlock(codeBlock)
433     , m_thisRegister(RegisterFile::ProgramCodeThisRegister)
434     , m_finallyDepth(0)
435     , m_dynamicScopeDepth(0)
436     , m_baseScopeDepth(codeBlock->baseScopeDepth())
437     , m_codeType(EvalCode)
438     , m_nextConstantOffset(0)
439     , m_globalConstantIndex(0)
440     , m_hasCreatedActivation(true)
441     , m_firstLazyFunction(0)
442     , m_lastLazyFunction(0)
443     , m_globalData(scopeChain->globalData)
444     , m_lastOpcodeID(op_end)
445 #ifndef NDEBUG
446     , m_lastOpcodePosition(0)
447 #endif
448     , m_stack(m_globalData->stack())
449     , m_usesExceptions(false)
450     , m_expressionTooDeep(false)
451 {
452     if (m_shouldEmitDebugHooks || m_baseScopeDepth)
453         m_codeBlock->setNeedsFullScopeChain(true);
454
455     emitOpcode(op_enter);
456     codeBlock->setGlobalData(m_globalData);
457     m_codeBlock->m_numParameters = 1; // Allocate space for "this"
458
459     const DeclarationStacks::FunctionStack& functionStack = evalNode->functionStack();
460     for (size_t i = 0; i < functionStack.size(); ++i)
461         m_codeBlock->addFunctionDecl(makeFunction(m_globalData, functionStack[i]));
462
463     const DeclarationStacks::VarStack& varStack = evalNode->varStack();
464     unsigned numVariables = varStack.size();
465     Vector<Identifier> variables;
466     variables.reserveCapacity(numVariables);
467     for (size_t i = 0; i < numVariables; ++i)
468         variables.append(*varStack[i].first);
469     codeBlock->adoptVariables(variables);
470     codeBlock->m_numCapturedVars = codeBlock->m_numVars;
471     preserveLastVar();
472 }
473
474 RegisterID* BytecodeGenerator::emitInitLazyRegister(RegisterID* reg)
475 {
476     emitOpcode(op_init_lazy_reg);
477     instructions().append(reg->index());
478     return reg;
479 }
480
481 void BytecodeGenerator::addParameter(const Identifier& ident, int parameterIndex)
482 {
483     // Parameters overwrite var declarations, but not function declarations.
484     StringImpl* rep = ident.impl();
485     if (!m_functions.contains(rep)) {
486         symbolTable().set(rep, parameterIndex);
487         RegisterID& parameter = registerFor(parameterIndex);
488         parameter.setIndex(parameterIndex);
489     }
490
491     // To maintain the calling convention, we have to allocate unique space for
492     // each parameter, even if the parameter doesn't make it into the symbol table.
493     ++m_codeBlock->m_numParameters;
494 }
495
496 RegisterID* BytecodeGenerator::registerFor(const Identifier& ident)
497 {
498     if (ident == propertyNames().thisIdentifier)
499         return &m_thisRegister;
500         
501     if (m_codeType == GlobalCode)
502         return 0;
503
504     if (!shouldOptimizeLocals())
505         return 0;
506
507     SymbolTableEntry entry = symbolTable().get(ident.impl());
508     if (entry.isNull())
509         return 0;
510
511     if (ident == propertyNames().arguments)
512         createArgumentsIfNecessary();
513
514     return createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
515 }
516
517 RegisterID* BytecodeGenerator::constRegisterFor(const Identifier& ident)
518 {
519     if (m_codeType == EvalCode)
520         return 0;
521
522     if (m_codeType == GlobalCode)
523         return 0;
524
525     SymbolTableEntry entry = symbolTable().get(ident.impl());
526     if (entry.isNull())
527         return 0;
528
529     return createLazyRegisterIfNecessary(&registerFor(entry.getIndex()));
530 }
531
532 bool BytecodeGenerator::willResolveToArguments(const Identifier& ident)
533 {
534     if (ident != propertyNames().arguments)
535         return false;
536     
537     if (!shouldOptimizeLocals())
538         return false;
539     
540     SymbolTableEntry entry = symbolTable().get(ident.impl());
541     if (entry.isNull())
542         return false;
543     
544     if (m_codeBlock->usesArguments() && m_codeType == FunctionCode)
545         return true;
546     
547     return false;
548 }
549
550 RegisterID* BytecodeGenerator::uncheckedRegisterForArguments()
551 {
552     ASSERT(willResolveToArguments(propertyNames().arguments));
553
554     SymbolTableEntry entry = symbolTable().get(propertyNames().arguments.impl());
555     ASSERT(!entry.isNull());
556     return &registerFor(entry.getIndex());
557 }
558
559 RegisterID* BytecodeGenerator::createLazyRegisterIfNecessary(RegisterID* reg)
560 {
561     if (m_lastLazyFunction <= reg->index() || reg->index() < m_firstLazyFunction)
562         return reg;
563     emitLazyNewFunction(reg, m_lazyFunctions.get(reg->index()));
564     return reg;
565 }
566
567 bool BytecodeGenerator::isLocal(const Identifier& ident)
568 {
569     if (ident == propertyNames().thisIdentifier)
570         return true;
571     
572     return shouldOptimizeLocals() && symbolTable().contains(ident.impl());
573 }
574
575 bool BytecodeGenerator::isLocalConstant(const Identifier& ident)
576 {
577     return symbolTable().get(ident.impl()).isReadOnly();
578 }
579
580 RegisterID* BytecodeGenerator::newRegister()
581 {
582     m_calleeRegisters.append(m_calleeRegisters.size());
583     m_codeBlock->m_numCalleeRegisters = max<int>(m_codeBlock->m_numCalleeRegisters, m_calleeRegisters.size());
584     return &m_calleeRegisters.last();
585 }
586
587 RegisterID* BytecodeGenerator::newTemporary()
588 {
589     // Reclaim free register IDs.
590     while (m_calleeRegisters.size() && !m_calleeRegisters.last().refCount())
591         m_calleeRegisters.removeLast();
592         
593     RegisterID* result = newRegister();
594     result->setTemporary();
595     return result;
596 }
597
598 RegisterID* BytecodeGenerator::highestUsedRegister()
599 {
600     size_t count = m_codeBlock->m_numCalleeRegisters;
601     while (m_calleeRegisters.size() < count)
602         newRegister();
603     return &m_calleeRegisters.last();
604 }
605
606 PassRefPtr<LabelScope> BytecodeGenerator::newLabelScope(LabelScope::Type type, const Identifier* name)
607 {
608     // Reclaim free label scopes.
609     while (m_labelScopes.size() && !m_labelScopes.last().refCount())
610         m_labelScopes.removeLast();
611
612     // Allocate new label scope.
613     LabelScope scope(type, name, scopeDepth(), newLabel(), type == LabelScope::Loop ? newLabel() : PassRefPtr<Label>()); // Only loops have continue targets.
614     m_labelScopes.append(scope);
615     return &m_labelScopes.last();
616 }
617
618 PassRefPtr<Label> BytecodeGenerator::newLabel()
619 {
620     // Reclaim free label IDs.
621     while (m_labels.size() && !m_labels.last().refCount())
622         m_labels.removeLast();
623
624     // Allocate new label ID.
625     m_labels.append(m_codeBlock);
626     return &m_labels.last();
627 }
628
629 PassRefPtr<Label> BytecodeGenerator::emitLabel(Label* l0)
630 {
631     unsigned newLabelIndex = instructions().size();
632     l0->setLocation(newLabelIndex);
633
634     if (m_codeBlock->numberOfJumpTargets()) {
635         unsigned lastLabelIndex = m_codeBlock->lastJumpTarget();
636         ASSERT(lastLabelIndex <= newLabelIndex);
637         if (newLabelIndex == lastLabelIndex) {
638             // Peephole optimizations have already been disabled by emitting the last label
639             return l0;
640         }
641     }
642
643     m_codeBlock->addJumpTarget(newLabelIndex);
644
645     // This disables peephole optimizations when an instruction is a jump target
646     m_lastOpcodeID = op_end;
647     return l0;
648 }
649
650 void BytecodeGenerator::emitOpcode(OpcodeID opcodeID)
651 {
652 #ifndef NDEBUG
653     size_t opcodePosition = instructions().size();
654     ASSERT(opcodePosition - m_lastOpcodePosition == opcodeLength(m_lastOpcodeID) || m_lastOpcodeID == op_end);
655     m_lastOpcodePosition = opcodePosition;
656 #endif
657     instructions().append(globalData()->interpreter->getOpcode(opcodeID));
658     m_lastOpcodeID = opcodeID;
659 }
660
661 void BytecodeGenerator::emitLoopHint()
662 {
663 #if ENABLE(TIERED_COMPILATION)
664     emitOpcode(op_loop_hint);
665 #endif
666 }
667
668 void BytecodeGenerator::retrieveLastBinaryOp(int& dstIndex, int& src1Index, int& src2Index)
669 {
670     ASSERT(instructions().size() >= 4);
671     size_t size = instructions().size();
672     dstIndex = instructions().at(size - 3).u.operand;
673     src1Index = instructions().at(size - 2).u.operand;
674     src2Index = instructions().at(size - 1).u.operand;
675 }
676
677 void BytecodeGenerator::retrieveLastUnaryOp(int& dstIndex, int& srcIndex)
678 {
679     ASSERT(instructions().size() >= 3);
680     size_t size = instructions().size();
681     dstIndex = instructions().at(size - 2).u.operand;
682     srcIndex = instructions().at(size - 1).u.operand;
683 }
684
685 void ALWAYS_INLINE BytecodeGenerator::rewindBinaryOp()
686 {
687     ASSERT(instructions().size() >= 4);
688     instructions().shrink(instructions().size() - 4);
689     m_lastOpcodeID = op_end;
690 }
691
692 void ALWAYS_INLINE BytecodeGenerator::rewindUnaryOp()
693 {
694     ASSERT(instructions().size() >= 3);
695     instructions().shrink(instructions().size() - 3);
696     m_lastOpcodeID = op_end;
697 }
698
699 PassRefPtr<Label> BytecodeGenerator::emitJump(Label* target)
700 {
701     size_t begin = instructions().size();
702     emitOpcode(target->isForward() ? op_jmp : op_loop);
703     instructions().append(target->bind(begin, instructions().size()));
704     return target;
705 }
706
707 PassRefPtr<Label> BytecodeGenerator::emitJumpIfTrue(RegisterID* cond, Label* target)
708 {
709     if (m_lastOpcodeID == op_less) {
710         int dstIndex;
711         int src1Index;
712         int src2Index;
713
714         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
715
716         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
717             rewindBinaryOp();
718
719             size_t begin = instructions().size();
720             emitOpcode(target->isForward() ? op_jless : op_loop_if_less);
721             instructions().append(src1Index);
722             instructions().append(src2Index);
723             instructions().append(target->bind(begin, instructions().size()));
724             return target;
725         }
726     } else if (m_lastOpcodeID == op_lesseq) {
727         int dstIndex;
728         int src1Index;
729         int src2Index;
730
731         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
732
733         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
734             rewindBinaryOp();
735
736             size_t begin = instructions().size();
737             emitOpcode(target->isForward() ? op_jlesseq : op_loop_if_lesseq);
738             instructions().append(src1Index);
739             instructions().append(src2Index);
740             instructions().append(target->bind(begin, instructions().size()));
741             return target;
742         }
743     } else if (m_lastOpcodeID == op_greater) {
744         int dstIndex;
745         int src1Index;
746         int src2Index;
747
748         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
749
750         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
751             rewindBinaryOp();
752
753             size_t begin = instructions().size();
754             emitOpcode(target->isForward() ? op_jgreater : op_loop_if_greater);
755             instructions().append(src1Index);
756             instructions().append(src2Index);
757             instructions().append(target->bind(begin, instructions().size()));
758             return target;
759         }
760     } else if (m_lastOpcodeID == op_greatereq) {
761         int dstIndex;
762         int src1Index;
763         int src2Index;
764
765         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
766
767         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
768             rewindBinaryOp();
769
770             size_t begin = instructions().size();
771             emitOpcode(target->isForward() ? op_jgreatereq : op_loop_if_greatereq);
772             instructions().append(src1Index);
773             instructions().append(src2Index);
774             instructions().append(target->bind(begin, instructions().size()));
775             return target;
776         }
777     } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
778         int dstIndex;
779         int srcIndex;
780
781         retrieveLastUnaryOp(dstIndex, srcIndex);
782
783         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
784             rewindUnaryOp();
785
786             size_t begin = instructions().size();
787             emitOpcode(op_jeq_null);
788             instructions().append(srcIndex);
789             instructions().append(target->bind(begin, instructions().size()));
790             return target;
791         }
792     } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
793         int dstIndex;
794         int srcIndex;
795
796         retrieveLastUnaryOp(dstIndex, srcIndex);
797
798         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
799             rewindUnaryOp();
800
801             size_t begin = instructions().size();
802             emitOpcode(op_jneq_null);
803             instructions().append(srcIndex);
804             instructions().append(target->bind(begin, instructions().size()));
805             return target;
806         }
807     }
808
809     size_t begin = instructions().size();
810
811     emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
812     instructions().append(cond->index());
813     instructions().append(target->bind(begin, instructions().size()));
814     return target;
815 }
816
817 PassRefPtr<Label> BytecodeGenerator::emitJumpIfFalse(RegisterID* cond, Label* target)
818 {
819     if (m_lastOpcodeID == op_less && target->isForward()) {
820         int dstIndex;
821         int src1Index;
822         int src2Index;
823
824         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
825
826         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
827             rewindBinaryOp();
828
829             size_t begin = instructions().size();
830             emitOpcode(op_jnless);
831             instructions().append(src1Index);
832             instructions().append(src2Index);
833             instructions().append(target->bind(begin, instructions().size()));
834             return target;
835         }
836     } else if (m_lastOpcodeID == op_lesseq && target->isForward()) {
837         int dstIndex;
838         int src1Index;
839         int src2Index;
840
841         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
842
843         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
844             rewindBinaryOp();
845
846             size_t begin = instructions().size();
847             emitOpcode(op_jnlesseq);
848             instructions().append(src1Index);
849             instructions().append(src2Index);
850             instructions().append(target->bind(begin, instructions().size()));
851             return target;
852         }
853     } else if (m_lastOpcodeID == op_greater && target->isForward()) {
854         int dstIndex;
855         int src1Index;
856         int src2Index;
857
858         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
859
860         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
861             rewindBinaryOp();
862
863             size_t begin = instructions().size();
864             emitOpcode(op_jngreater);
865             instructions().append(src1Index);
866             instructions().append(src2Index);
867             instructions().append(target->bind(begin, instructions().size()));
868             return target;
869         }
870     } else if (m_lastOpcodeID == op_greatereq && target->isForward()) {
871         int dstIndex;
872         int src1Index;
873         int src2Index;
874
875         retrieveLastBinaryOp(dstIndex, src1Index, src2Index);
876
877         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
878             rewindBinaryOp();
879
880             size_t begin = instructions().size();
881             emitOpcode(op_jngreatereq);
882             instructions().append(src1Index);
883             instructions().append(src2Index);
884             instructions().append(target->bind(begin, instructions().size()));
885             return target;
886         }
887     } else if (m_lastOpcodeID == op_not) {
888         int dstIndex;
889         int srcIndex;
890
891         retrieveLastUnaryOp(dstIndex, srcIndex);
892
893         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
894             rewindUnaryOp();
895
896             size_t begin = instructions().size();
897             emitOpcode(target->isForward() ? op_jtrue : op_loop_if_true);
898             instructions().append(srcIndex);
899             instructions().append(target->bind(begin, instructions().size()));
900             return target;
901         }
902     } else if (m_lastOpcodeID == op_eq_null && target->isForward()) {
903         int dstIndex;
904         int srcIndex;
905
906         retrieveLastUnaryOp(dstIndex, srcIndex);
907
908         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
909             rewindUnaryOp();
910
911             size_t begin = instructions().size();
912             emitOpcode(op_jneq_null);
913             instructions().append(srcIndex);
914             instructions().append(target->bind(begin, instructions().size()));
915             return target;
916         }
917     } else if (m_lastOpcodeID == op_neq_null && target->isForward()) {
918         int dstIndex;
919         int srcIndex;
920
921         retrieveLastUnaryOp(dstIndex, srcIndex);
922
923         if (cond->index() == dstIndex && cond->isTemporary() && !cond->refCount()) {
924             rewindUnaryOp();
925
926             size_t begin = instructions().size();
927             emitOpcode(op_jeq_null);
928             instructions().append(srcIndex);
929             instructions().append(target->bind(begin, instructions().size()));
930             return target;
931         }
932     }
933
934     size_t begin = instructions().size();
935     emitOpcode(target->isForward() ? op_jfalse : op_loop_if_false);
936     instructions().append(cond->index());
937     instructions().append(target->bind(begin, instructions().size()));
938     return target;
939 }
940
941 PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionCall(RegisterID* cond, Label* target)
942 {
943     size_t begin = instructions().size();
944
945     emitOpcode(op_jneq_ptr);
946     instructions().append(cond->index());
947     instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->callFunction()));
948     instructions().append(target->bind(begin, instructions().size()));
949     return target;
950 }
951
952 PassRefPtr<Label> BytecodeGenerator::emitJumpIfNotFunctionApply(RegisterID* cond, Label* target)
953 {
954     size_t begin = instructions().size();
955
956     emitOpcode(op_jneq_ptr);
957     instructions().append(cond->index());
958     instructions().append(Instruction(*m_globalData, m_codeBlock->ownerExecutable(), m_scopeChain->globalObject->applyFunction()));
959     instructions().append(target->bind(begin, instructions().size()));
960     return target;
961 }
962
963 unsigned BytecodeGenerator::addConstant(const Identifier& ident)
964 {
965     StringImpl* rep = ident.impl();
966     pair<IdentifierMap::iterator, bool> result = m_identifierMap.add(rep, m_codeBlock->numberOfIdentifiers());
967     if (result.second) // new entry
968         m_codeBlock->addIdentifier(Identifier(m_globalData, rep));
969
970     return result.first->second;
971 }
972
973 RegisterID* BytecodeGenerator::addConstantValue(JSValue v)
974 {
975     int index = m_nextConstantOffset;
976
977     pair<JSValueMap::iterator, bool> result = m_jsValueMap.add(JSValue::encode(v), m_nextConstantOffset);
978     if (result.second) {
979         m_constantPoolRegisters.append(FirstConstantRegisterIndex + m_nextConstantOffset);
980         ++m_nextConstantOffset;
981         m_codeBlock->addConstant(JSValue(v));
982     } else
983         index = result.first->second;
984
985     return &m_constantPoolRegisters[index];
986 }
987
988 unsigned BytecodeGenerator::addRegExp(RegExp* r)
989 {
990     return m_codeBlock->addRegExp(r);
991 }
992
993 RegisterID* BytecodeGenerator::emitMove(RegisterID* dst, RegisterID* src)
994 {
995     emitOpcode(op_mov);
996     instructions().append(dst->index());
997     instructions().append(src->index());
998     return dst;
999 }
1000
1001 RegisterID* BytecodeGenerator::emitUnaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src)
1002 {
1003     emitOpcode(opcodeID);
1004     instructions().append(dst->index());
1005     instructions().append(src->index());
1006     return dst;
1007 }
1008
1009 RegisterID* BytecodeGenerator::emitPreInc(RegisterID* srcDst)
1010 {
1011     emitOpcode(op_pre_inc);
1012     instructions().append(srcDst->index());
1013     return srcDst;
1014 }
1015
1016 RegisterID* BytecodeGenerator::emitPreDec(RegisterID* srcDst)
1017 {
1018     emitOpcode(op_pre_dec);
1019     instructions().append(srcDst->index());
1020     return srcDst;
1021 }
1022
1023 RegisterID* BytecodeGenerator::emitPostInc(RegisterID* dst, RegisterID* srcDst)
1024 {
1025     emitOpcode(op_post_inc);
1026     instructions().append(dst->index());
1027     instructions().append(srcDst->index());
1028     return dst;
1029 }
1030
1031 RegisterID* BytecodeGenerator::emitPostDec(RegisterID* dst, RegisterID* srcDst)
1032 {
1033     emitOpcode(op_post_dec);
1034     instructions().append(dst->index());
1035     instructions().append(srcDst->index());
1036     return dst;
1037 }
1038
1039 RegisterID* BytecodeGenerator::emitBinaryOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2, OperandTypes types)
1040 {
1041     emitOpcode(opcodeID);
1042     instructions().append(dst->index());
1043     instructions().append(src1->index());
1044     instructions().append(src2->index());
1045
1046     if (opcodeID == op_bitor || opcodeID == op_bitand || opcodeID == op_bitxor ||
1047         opcodeID == op_add || opcodeID == op_mul || opcodeID == op_sub || opcodeID == op_div)
1048         instructions().append(types.toInt());
1049
1050     return dst;
1051 }
1052
1053 RegisterID* BytecodeGenerator::emitEqualityOp(OpcodeID opcodeID, RegisterID* dst, RegisterID* src1, RegisterID* src2)
1054 {
1055     if (m_lastOpcodeID == op_typeof) {
1056         int dstIndex;
1057         int srcIndex;
1058
1059         retrieveLastUnaryOp(dstIndex, srcIndex);
1060
1061         if (src1->index() == dstIndex
1062             && src1->isTemporary()
1063             && m_codeBlock->isConstantRegisterIndex(src2->index())
1064             && m_codeBlock->constantRegister(src2->index()).get().isString()) {
1065             const UString& value = asString(m_codeBlock->constantRegister(src2->index()).get())->tryGetValue();
1066             if (value == "undefined") {
1067                 rewindUnaryOp();
1068                 emitOpcode(op_is_undefined);
1069                 instructions().append(dst->index());
1070                 instructions().append(srcIndex);
1071                 return dst;
1072             }
1073             if (value == "boolean") {
1074                 rewindUnaryOp();
1075                 emitOpcode(op_is_boolean);
1076                 instructions().append(dst->index());
1077                 instructions().append(srcIndex);
1078                 return dst;
1079             }
1080             if (value == "number") {
1081                 rewindUnaryOp();
1082                 emitOpcode(op_is_number);
1083                 instructions().append(dst->index());
1084                 instructions().append(srcIndex);
1085                 return dst;
1086             }
1087             if (value == "string") {
1088                 rewindUnaryOp();
1089                 emitOpcode(op_is_string);
1090                 instructions().append(dst->index());
1091                 instructions().append(srcIndex);
1092                 return dst;
1093             }
1094             if (value == "object") {
1095                 rewindUnaryOp();
1096                 emitOpcode(op_is_object);
1097                 instructions().append(dst->index());
1098                 instructions().append(srcIndex);
1099                 return dst;
1100             }
1101             if (value == "function") {
1102                 rewindUnaryOp();
1103                 emitOpcode(op_is_function);
1104                 instructions().append(dst->index());
1105                 instructions().append(srcIndex);
1106                 return dst;
1107             }
1108         }
1109     }
1110
1111     emitOpcode(opcodeID);
1112     instructions().append(dst->index());
1113     instructions().append(src1->index());
1114     instructions().append(src2->index());
1115     return dst;
1116 }
1117
1118 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, bool b)
1119 {
1120     return emitLoad(dst, jsBoolean(b));
1121 }
1122
1123 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, double number)
1124 {
1125     // FIXME: Our hash tables won't hold infinity, so we make a new JSValue each time.
1126     // Later we can do the extra work to handle that like the other cases.  They also don't
1127     // work correctly with NaN as a key.
1128     if (isnan(number) || number == HashTraits<double>::emptyValue() || HashTraits<double>::isDeletedValue(number))
1129         return emitLoad(dst, jsNumber(number));
1130     JSValue& valueInMap = m_numberMap.add(number, JSValue()).first->second;
1131     if (!valueInMap)
1132         valueInMap = jsNumber(number);
1133     return emitLoad(dst, valueInMap);
1134 }
1135
1136 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, const Identifier& identifier)
1137 {
1138     JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).first->second;
1139     if (!stringInMap)
1140         stringInMap = jsOwnedString(globalData(), identifier.ustring());
1141     return emitLoad(dst, JSValue(stringInMap));
1142 }
1143
1144 RegisterID* BytecodeGenerator::emitLoad(RegisterID* dst, JSValue v)
1145 {
1146     RegisterID* constantID = addConstantValue(v);
1147     if (dst)
1148         return emitMove(dst, constantID);
1149     return constantID;
1150 }
1151
1152 bool BytecodeGenerator::findScopedProperty(const Identifier& property, int& index, size_t& stackDepth, bool forWriting, bool& requiresDynamicChecks, JSObject*& globalObject)
1153 {
1154     // Cases where we cannot statically optimize the lookup.
1155     if (property == propertyNames().arguments || !canOptimizeNonLocals()) {
1156         stackDepth = 0;
1157         index = missingSymbolMarker();
1158
1159         if (shouldOptimizeLocals() && m_codeType == GlobalCode) {
1160             ScopeChainIterator iter = m_scopeChain->begin();
1161             globalObject = iter->get();
1162             ASSERT((++iter) == m_scopeChain->end());
1163         }
1164         return false;
1165     }
1166
1167     size_t depth = 0;
1168     requiresDynamicChecks = false;
1169     ScopeChainIterator iter = m_scopeChain->begin();
1170     ScopeChainIterator end = m_scopeChain->end();
1171     for (; iter != end; ++iter, ++depth) {
1172         JSObject* currentScope = iter->get();
1173         if (!currentScope->isVariableObject())
1174             break;
1175         JSVariableObject* currentVariableObject = static_cast<JSVariableObject*>(currentScope);
1176         SymbolTableEntry entry = currentVariableObject->symbolTable().get(property.impl());
1177
1178         // Found the property
1179         if (!entry.isNull()) {
1180             if (entry.isReadOnly() && forWriting) {
1181                 stackDepth = 0;
1182                 index = missingSymbolMarker();
1183                 if (++iter == end)
1184                     globalObject = currentVariableObject;
1185                 return false;
1186             }
1187             stackDepth = depth + m_codeBlock->needsFullScopeChain();
1188             index = entry.getIndex();
1189             if (++iter == end)
1190                 globalObject = currentVariableObject;
1191             return true;
1192         }
1193         bool scopeRequiresDynamicChecks = false;
1194         if (currentVariableObject->isDynamicScope(scopeRequiresDynamicChecks))
1195             break;
1196         requiresDynamicChecks |= scopeRequiresDynamicChecks;
1197     }
1198     // Can't locate the property but we're able to avoid a few lookups.
1199     stackDepth = depth + m_codeBlock->needsFullScopeChain();
1200     index = missingSymbolMarker();
1201     JSObject* scope = iter->get();
1202     if (++iter == end)
1203         globalObject = scope;
1204     return true;
1205 }
1206
1207 void BytecodeGenerator::emitCheckHasInstance(RegisterID* base)
1208
1209     emitOpcode(op_check_has_instance);
1210     instructions().append(base->index());
1211 }
1212
1213 RegisterID* BytecodeGenerator::emitInstanceOf(RegisterID* dst, RegisterID* value, RegisterID* base, RegisterID* basePrototype)
1214
1215     emitOpcode(op_instanceof);
1216     instructions().append(dst->index());
1217     instructions().append(value->index());
1218     instructions().append(base->index());
1219     instructions().append(basePrototype->index());
1220     return dst;
1221 }
1222
1223 static const unsigned maxGlobalResolves = 128;
1224
1225 bool BytecodeGenerator::shouldAvoidResolveGlobal()
1226 {
1227     return m_codeBlock->globalResolveInfoCount() > maxGlobalResolves && !m_labelScopes.size();
1228 }
1229
1230 RegisterID* BytecodeGenerator::emitResolve(RegisterID* dst, const Identifier& property)
1231 {
1232     size_t depth = 0;
1233     int index = 0;
1234     JSObject* globalObject = 0;
1235     bool requiresDynamicChecks = false;
1236     if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) && !globalObject) {
1237         // We can't optimise at all :-(
1238         emitOpcode(op_resolve);
1239         instructions().append(dst->index());
1240         instructions().append(addConstant(property));
1241         return dst;
1242     }
1243     if (shouldAvoidResolveGlobal()) {
1244         globalObject = 0;
1245         requiresDynamicChecks = true;
1246     }
1247         
1248     if (globalObject) {
1249         if (index != missingSymbolMarker() && !requiresDynamicChecks) {
1250             // Directly index the property lookup across multiple scopes.
1251             return emitGetScopedVar(dst, depth, index, globalObject);
1252         }
1253
1254 #if ENABLE(JIT)
1255         m_codeBlock->addGlobalResolveInfo(instructions().size());
1256 #endif
1257 #if ENABLE(INTERPRETER)
1258         m_codeBlock->addGlobalResolveInstruction(instructions().size());
1259 #endif
1260         emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1261         instructions().append(dst->index());
1262         instructions().append(addConstant(property));
1263         instructions().append(0);
1264         instructions().append(0);
1265         if (requiresDynamicChecks)
1266             instructions().append(depth);
1267         return dst;
1268     }
1269
1270     if (requiresDynamicChecks) {
1271         // If we get here we have eval nested inside a |with| just give up
1272         emitOpcode(op_resolve);
1273         instructions().append(dst->index());
1274         instructions().append(addConstant(property));
1275         return dst;
1276     }
1277
1278     if (index != missingSymbolMarker()) {
1279         // Directly index the property lookup across multiple scopes.
1280         return emitGetScopedVar(dst, depth, index, globalObject);
1281     }
1282
1283     // In this case we are at least able to drop a few scope chains from the
1284     // lookup chain, although we still need to hash from then on.
1285     emitOpcode(op_resolve_skip);
1286     instructions().append(dst->index());
1287     instructions().append(addConstant(property));
1288     instructions().append(depth);
1289     return dst;
1290 }
1291
1292 RegisterID* BytecodeGenerator::emitGetScopedVar(RegisterID* dst, size_t depth, int index, JSValue globalObject)
1293 {
1294     if (globalObject) {
1295         if (m_lastOpcodeID == op_put_global_var) {
1296             int dstIndex;
1297             int srcIndex;
1298             retrieveLastUnaryOp(dstIndex, srcIndex);
1299             
1300             if (dstIndex == index && srcIndex == dst->index())
1301                 return dst;
1302         }
1303
1304         emitOpcode(op_get_global_var);
1305         instructions().append(dst->index());
1306         instructions().append(index);
1307         return dst;
1308     }
1309
1310     emitOpcode(op_get_scoped_var);
1311     instructions().append(dst->index());
1312     instructions().append(index);
1313     instructions().append(depth);
1314     return dst;
1315 }
1316
1317 RegisterID* BytecodeGenerator::emitPutScopedVar(size_t depth, int index, RegisterID* value, JSValue globalObject)
1318 {
1319     if (globalObject) {
1320         emitOpcode(op_put_global_var);
1321         instructions().append(index);
1322         instructions().append(value->index());
1323         return value;
1324     }
1325     emitOpcode(op_put_scoped_var);
1326     instructions().append(index);
1327     instructions().append(depth);
1328     instructions().append(value->index());
1329     return value;
1330 }
1331
1332 RegisterID* BytecodeGenerator::emitResolveBase(RegisterID* dst, const Identifier& property)
1333 {
1334     size_t depth = 0;
1335     int index = 0;
1336     JSObject* globalObject = 0;
1337     bool requiresDynamicChecks = false;
1338     findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
1339     if (!globalObject || requiresDynamicChecks) {
1340         // We can't optimise at all :-(
1341         emitOpcode(op_resolve_base);
1342         instructions().append(dst->index());
1343         instructions().append(addConstant(property));
1344         instructions().append(false);
1345         return dst;
1346     }
1347
1348     // Global object is the base
1349     return emitLoad(dst, JSValue(globalObject));
1350 }
1351
1352 RegisterID* BytecodeGenerator::emitResolveBaseForPut(RegisterID* dst, const Identifier& property)
1353 {
1354     if (!m_codeBlock->isStrictMode())
1355         return emitResolveBase(dst, property);
1356     size_t depth = 0;
1357     int index = 0;
1358     JSObject* globalObject = 0;
1359     bool requiresDynamicChecks = false;
1360     findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject);
1361     if (!globalObject || requiresDynamicChecks) {
1362         // We can't optimise at all :-(
1363         emitOpcode(op_resolve_base);
1364         instructions().append(dst->index());
1365         instructions().append(addConstant(property));
1366         instructions().append(true);
1367         return dst;
1368     }
1369     
1370     // Global object is the base
1371     RefPtr<RegisterID> result = emitLoad(dst, JSValue(globalObject));
1372     emitOpcode(op_ensure_property_exists);
1373     instructions().append(dst->index());
1374     instructions().append(addConstant(property));
1375     return result.get();
1376 }
1377
1378 RegisterID* BytecodeGenerator::emitResolveWithBase(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
1379 {
1380     size_t depth = 0;
1381     int index = 0;
1382     JSObject* globalObject = 0;
1383     bool requiresDynamicChecks = false;
1384     if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) || !globalObject || requiresDynamicChecks) {
1385         // We can't optimise at all :-(
1386         emitOpcode(op_resolve_with_base);
1387         instructions().append(baseDst->index());
1388         instructions().append(propDst->index());
1389         instructions().append(addConstant(property));
1390         return baseDst;
1391     }
1392
1393     bool forceGlobalResolve = false;
1394
1395     // Global object is the base
1396     emitLoad(baseDst, JSValue(globalObject));
1397
1398     if (index != missingSymbolMarker() && !forceGlobalResolve) {
1399         // Directly index the property lookup across multiple scopes.
1400         emitGetScopedVar(propDst, depth, index, globalObject);
1401         return baseDst;
1402     }
1403     if (shouldAvoidResolveGlobal()) {
1404         emitOpcode(op_resolve);
1405         instructions().append(propDst->index());
1406         instructions().append(addConstant(property));
1407         return baseDst;
1408     }
1409 #if ENABLE(JIT)
1410     m_codeBlock->addGlobalResolveInfo(instructions().size());
1411 #endif
1412 #if ENABLE(INTERPRETER)
1413     m_codeBlock->addGlobalResolveInstruction(instructions().size());
1414 #endif
1415     emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1416     instructions().append(propDst->index());
1417     instructions().append(addConstant(property));
1418     instructions().append(0);
1419     instructions().append(0);
1420     if (requiresDynamicChecks)
1421         instructions().append(depth);
1422     return baseDst;
1423 }
1424
1425 RegisterID* BytecodeGenerator::emitResolveWithThis(RegisterID* baseDst, RegisterID* propDst, const Identifier& property)
1426 {
1427     size_t depth = 0;
1428     int index = 0;
1429     JSObject* globalObject = 0;
1430     bool requiresDynamicChecks = false;
1431     if (!findScopedProperty(property, index, depth, false, requiresDynamicChecks, globalObject) || !globalObject || requiresDynamicChecks) {
1432         // We can't optimise at all :-(
1433         emitOpcode(op_resolve_with_this);
1434         instructions().append(baseDst->index());
1435         instructions().append(propDst->index());
1436         instructions().append(addConstant(property));
1437         return baseDst;
1438     }
1439
1440     bool forceGlobalResolve = false;
1441
1442     // Global object is the base
1443     emitLoad(baseDst, jsUndefined());
1444
1445     if (index != missingSymbolMarker() && !forceGlobalResolve) {
1446         // Directly index the property lookup across multiple scopes.
1447         emitGetScopedVar(propDst, depth, index, globalObject);
1448         return baseDst;
1449     }
1450     if (shouldAvoidResolveGlobal()) {
1451         emitOpcode(op_resolve);
1452         instructions().append(propDst->index());
1453         instructions().append(addConstant(property));
1454         return baseDst;
1455     }
1456 #if ENABLE(JIT)
1457     m_codeBlock->addGlobalResolveInfo(instructions().size());
1458 #endif
1459 #if ENABLE(INTERPRETER)
1460     m_codeBlock->addGlobalResolveInstruction(instructions().size());
1461 #endif
1462     emitOpcode(requiresDynamicChecks ? op_resolve_global_dynamic : op_resolve_global);
1463     instructions().append(propDst->index());
1464     instructions().append(addConstant(property));
1465     instructions().append(0);
1466     instructions().append(0);
1467     if (requiresDynamicChecks)
1468         instructions().append(depth);
1469     return baseDst;
1470 }
1471
1472 void BytecodeGenerator::emitMethodCheck()
1473 {
1474     emitOpcode(op_method_check);
1475 }
1476
1477 RegisterID* BytecodeGenerator::emitGetById(RegisterID* dst, RegisterID* base, const Identifier& property)
1478 {
1479 #if ENABLE(INTERPRETER)
1480     m_codeBlock->addPropertyAccessInstruction(instructions().size());
1481 #endif
1482
1483     emitOpcode(op_get_by_id);
1484     instructions().append(dst->index());
1485     instructions().append(base->index());
1486     instructions().append(addConstant(property));
1487     instructions().append(0);
1488     instructions().append(0);
1489     instructions().append(0);
1490     instructions().append(0);
1491     return dst;
1492 }
1493
1494 RegisterID* BytecodeGenerator::emitGetArgumentsLength(RegisterID* dst, RegisterID* base)
1495 {
1496     emitOpcode(op_get_arguments_length);
1497     instructions().append(dst->index());
1498     ASSERT(base->index() == m_codeBlock->argumentsRegister());
1499     instructions().append(base->index());
1500     instructions().append(addConstant(propertyNames().length));
1501     return dst;
1502 }
1503
1504 RegisterID* BytecodeGenerator::emitPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1505 {
1506 #if ENABLE(INTERPRETER)
1507     m_codeBlock->addPropertyAccessInstruction(instructions().size());
1508 #endif
1509
1510     emitOpcode(op_put_by_id);
1511     instructions().append(base->index());
1512     instructions().append(addConstant(property));
1513     instructions().append(value->index());
1514     instructions().append(0);
1515     instructions().append(0);
1516     instructions().append(0);
1517     instructions().append(0);
1518     instructions().append(0);
1519     return value;
1520 }
1521
1522 RegisterID* BytecodeGenerator::emitDirectPutById(RegisterID* base, const Identifier& property, RegisterID* value)
1523 {
1524 #if ENABLE(INTERPRETER)
1525     m_codeBlock->addPropertyAccessInstruction(instructions().size());
1526 #endif
1527     
1528     emitOpcode(op_put_by_id);
1529     instructions().append(base->index());
1530     instructions().append(addConstant(property));
1531     instructions().append(value->index());
1532     instructions().append(0);
1533     instructions().append(0);
1534     instructions().append(0);
1535     instructions().append(0);
1536     instructions().append(property != m_globalData->propertyNames->underscoreProto);
1537     return value;
1538 }
1539
1540 RegisterID* BytecodeGenerator::emitPutGetter(RegisterID* base, const Identifier& property, RegisterID* value)
1541 {
1542     emitOpcode(op_put_getter);
1543     instructions().append(base->index());
1544     instructions().append(addConstant(property));
1545     instructions().append(value->index());
1546     return value;
1547 }
1548
1549 RegisterID* BytecodeGenerator::emitPutSetter(RegisterID* base, const Identifier& property, RegisterID* value)
1550 {
1551     emitOpcode(op_put_setter);
1552     instructions().append(base->index());
1553     instructions().append(addConstant(property));
1554     instructions().append(value->index());
1555     return value;
1556 }
1557
1558 RegisterID* BytecodeGenerator::emitDeleteById(RegisterID* dst, RegisterID* base, const Identifier& property)
1559 {
1560     emitOpcode(op_del_by_id);
1561     instructions().append(dst->index());
1562     instructions().append(base->index());
1563     instructions().append(addConstant(property));
1564     return dst;
1565 }
1566
1567 RegisterID* BytecodeGenerator::emitGetArgumentByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1568 {
1569     emitOpcode(op_get_argument_by_val);
1570     instructions().append(dst->index());
1571     ASSERT(base->index() == m_codeBlock->argumentsRegister());
1572     instructions().append(base->index());
1573     instructions().append(property->index());
1574     return dst;
1575 }
1576
1577 RegisterID* BytecodeGenerator::emitGetByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1578 {
1579     for (size_t i = m_forInContextStack.size(); i > 0; i--) {
1580         ForInContext& context = m_forInContextStack[i - 1];
1581         if (context.propertyRegister == property) {
1582             emitOpcode(op_get_by_pname);
1583             instructions().append(dst->index());
1584             instructions().append(base->index());
1585             instructions().append(property->index());
1586             instructions().append(context.expectedSubscriptRegister->index());
1587             instructions().append(context.iterRegister->index());
1588             instructions().append(context.indexRegister->index());
1589             return dst;
1590         }
1591     }
1592     emitOpcode(op_get_by_val);
1593     instructions().append(dst->index());
1594     instructions().append(base->index());
1595     instructions().append(property->index());
1596     return dst;
1597 }
1598
1599 RegisterID* BytecodeGenerator::emitPutByVal(RegisterID* base, RegisterID* property, RegisterID* value)
1600 {
1601     emitOpcode(op_put_by_val);
1602     instructions().append(base->index());
1603     instructions().append(property->index());
1604     instructions().append(value->index());
1605     return value;
1606 }
1607
1608 RegisterID* BytecodeGenerator::emitDeleteByVal(RegisterID* dst, RegisterID* base, RegisterID* property)
1609 {
1610     emitOpcode(op_del_by_val);
1611     instructions().append(dst->index());
1612     instructions().append(base->index());
1613     instructions().append(property->index());
1614     return dst;
1615 }
1616
1617 RegisterID* BytecodeGenerator::emitPutByIndex(RegisterID* base, unsigned index, RegisterID* value)
1618 {
1619     emitOpcode(op_put_by_index);
1620     instructions().append(base->index());
1621     instructions().append(index);
1622     instructions().append(value->index());
1623     return value;
1624 }
1625
1626 RegisterID* BytecodeGenerator::emitNewObject(RegisterID* dst)
1627 {
1628     emitOpcode(op_new_object);
1629     instructions().append(dst->index());
1630     return dst;
1631 }
1632
1633 unsigned BytecodeGenerator::addConstantBuffer(unsigned length)
1634 {
1635     return m_codeBlock->addConstantBuffer(length);
1636 }
1637
1638 JSString* BytecodeGenerator::addStringConstant(const Identifier& identifier)
1639 {
1640     JSString*& stringInMap = m_stringMap.add(identifier.impl(), 0).first->second;
1641     if (!stringInMap) {
1642         stringInMap = jsString(globalData(), identifier.ustring());
1643         addConstantValue(stringInMap);
1644     }
1645     return stringInMap;
1646 }
1647
1648 RegisterID* BytecodeGenerator::emitNewArray(RegisterID* dst, ElementNode* elements, unsigned length)
1649 {
1650 #if !ASSERT_DISABLED
1651     unsigned checkLength = 0;
1652 #endif
1653     bool hadVariableExpression = false;
1654     if (length) {
1655         for (ElementNode* n = elements; n; n = n->next()) {
1656             if (!n->value()->isNumber() && !n->value()->isString()) {
1657                 hadVariableExpression = true;
1658                 break;
1659             }
1660             if (n->elision())
1661                 break;
1662 #if !ASSERT_DISABLED
1663             checkLength++;
1664 #endif
1665         }
1666         if (!hadVariableExpression) {
1667             ASSERT(length == checkLength);
1668             unsigned constantBufferIndex = addConstantBuffer(length);
1669             JSValue* constantBuffer = m_codeBlock->constantBuffer(constantBufferIndex);
1670             unsigned index = 0;
1671             for (ElementNode* n = elements; index < length; n = n->next()) {
1672                 if (n->value()->isNumber())
1673                     constantBuffer[index++] = jsNumber(static_cast<NumberNode*>(n->value())->value());
1674                 else {
1675                     ASSERT(n->value()->isString());
1676                     constantBuffer[index++] = addStringConstant(static_cast<StringNode*>(n->value())->value());
1677                 }
1678             }
1679             emitOpcode(op_new_array_buffer);
1680             instructions().append(dst->index());
1681             instructions().append(constantBufferIndex);
1682             instructions().append(length);
1683             return dst;
1684         }
1685     }
1686
1687     Vector<RefPtr<RegisterID>, 16> argv;
1688     for (ElementNode* n = elements; n; n = n->next()) {
1689         if (n->elision())
1690             break;
1691         argv.append(newTemporary());
1692         // op_new_array requires the initial values to be a sequential range of registers
1693         ASSERT(argv.size() == 1 || argv[argv.size() - 1]->index() == argv[argv.size() - 2]->index() + 1);
1694         emitNode(argv.last().get(), n->value());
1695     }
1696     emitOpcode(op_new_array);
1697     instructions().append(dst->index());
1698     instructions().append(argv.size() ? argv[0]->index() : 0); // argv
1699     instructions().append(argv.size()); // argc
1700     return dst;
1701 }
1702
1703 RegisterID* BytecodeGenerator::emitNewFunction(RegisterID* dst, FunctionBodyNode* function)
1704 {
1705     return emitNewFunctionInternal(dst, m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function)), false);
1706 }
1707
1708 RegisterID* BytecodeGenerator::emitLazyNewFunction(RegisterID* dst, FunctionBodyNode* function)
1709 {
1710     std::pair<FunctionOffsetMap::iterator, bool> ptr = m_functionOffsets.add(function, 0);
1711     if (ptr.second)
1712         ptr.first->second = m_codeBlock->addFunctionDecl(makeFunction(m_globalData, function));
1713     return emitNewFunctionInternal(dst, ptr.first->second, true);
1714 }
1715
1716 RegisterID* BytecodeGenerator::emitNewFunctionInternal(RegisterID* dst, unsigned index, bool doNullCheck)
1717 {
1718     createActivationIfNecessary();
1719     emitOpcode(op_new_func);
1720     instructions().append(dst->index());
1721     instructions().append(index);
1722     instructions().append(doNullCheck);
1723     return dst;
1724 }
1725
1726 RegisterID* BytecodeGenerator::emitNewRegExp(RegisterID* dst, RegExp* regExp)
1727 {
1728     emitOpcode(op_new_regexp);
1729     instructions().append(dst->index());
1730     instructions().append(addRegExp(regExp));
1731     return dst;
1732 }
1733
1734 RegisterID* BytecodeGenerator::emitNewFunctionExpression(RegisterID* r0, FuncExprNode* n)
1735 {
1736     FunctionBodyNode* function = n->body();
1737     unsigned index = m_codeBlock->addFunctionExpr(makeFunction(m_globalData, function));
1738     
1739     createActivationIfNecessary();
1740     emitOpcode(op_new_func_exp);
1741     instructions().append(r0->index());
1742     instructions().append(index);
1743     return r0;
1744 }
1745
1746 RegisterID* BytecodeGenerator::emitCall(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
1747 {
1748     return emitCall(op_call, dst, func, callArguments, divot, startOffset, endOffset);
1749 }
1750
1751 void BytecodeGenerator::createArgumentsIfNecessary()
1752 {
1753     if (m_codeType != FunctionCode)
1754         return;
1755     
1756     if (!m_codeBlock->usesArguments())
1757         return;
1758
1759     // If we're in strict mode we tear off the arguments on function
1760     // entry, so there's no need to check if we need to create them
1761     // now
1762     if (m_codeBlock->isStrictMode())
1763         return;
1764
1765     emitOpcode(op_create_arguments);
1766     instructions().append(m_codeBlock->argumentsRegister());
1767 }
1768
1769 void BytecodeGenerator::createActivationIfNecessary()
1770 {
1771     if (m_hasCreatedActivation)
1772         return;
1773     if (!m_codeBlock->needsFullScopeChain())
1774         return;
1775     emitOpcode(op_create_activation);
1776     instructions().append(m_activationRegister->index());
1777 }
1778
1779 RegisterID* BytecodeGenerator::emitCallEval(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
1780 {
1781     return emitCall(op_call_eval, dst, func, callArguments, divot, startOffset, endOffset);
1782 }
1783
1784 RegisterID* BytecodeGenerator::emitCall(OpcodeID opcodeID, RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
1785 {
1786     ASSERT(opcodeID == op_call || opcodeID == op_call_eval);
1787     ASSERT(func->refCount());
1788
1789     if (m_shouldEmitProfileHooks)
1790         emitMove(callArguments.profileHookRegister(), func);
1791
1792     // Generate code for arguments.
1793     unsigned argumentIndex = 0;
1794     for (ArgumentListNode* n = callArguments.argumentsNode()->m_listNode; n; n = n->m_next)
1795         emitNode(callArguments.argumentRegister(argumentIndex++), n);
1796
1797     // Reserve space for call frame.
1798     Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1799     for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1800         callFrame.append(newTemporary());
1801
1802     if (m_shouldEmitProfileHooks) {
1803         emitOpcode(op_profile_will_call);
1804         instructions().append(callArguments.profileHookRegister()->index());
1805     }
1806
1807     emitExpressionInfo(divot, startOffset, endOffset);
1808
1809     // Emit call.
1810     emitOpcode(opcodeID);
1811     instructions().append(func->index()); // func
1812     instructions().append(callArguments.count()); // argCount
1813     instructions().append(callArguments.callFrame()); // registerOffset
1814     if (dst != ignoredResult()) {
1815         emitOpcode(op_call_put_result);
1816         instructions().append(dst->index()); // dst
1817     }
1818
1819     if (m_shouldEmitProfileHooks) {
1820         emitOpcode(op_profile_did_call);
1821         instructions().append(callArguments.profileHookRegister()->index());
1822     }
1823
1824     return dst;
1825 }
1826
1827 RegisterID* BytecodeGenerator::emitLoadVarargs(RegisterID* argCountDst, RegisterID* thisRegister, RegisterID* arguments)
1828 {
1829     ASSERT(argCountDst->index() < arguments->index());
1830     emitOpcode(op_load_varargs);
1831     instructions().append(argCountDst->index());
1832     instructions().append(arguments->index());
1833     instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset
1834     return argCountDst;
1835 }
1836
1837 RegisterID* BytecodeGenerator::emitCallVarargs(RegisterID* dst, RegisterID* func, RegisterID* thisRegister, RegisterID* argCountRegister, unsigned divot, unsigned startOffset, unsigned endOffset)
1838 {
1839     ASSERT(func->refCount());
1840     ASSERT(thisRegister->refCount());
1841     ASSERT(dst != func);
1842     if (m_shouldEmitProfileHooks) {
1843         emitOpcode(op_profile_will_call);
1844         instructions().append(func->index());
1845     }
1846     
1847     emitExpressionInfo(divot, startOffset, endOffset);
1848     
1849     // Emit call.
1850     emitOpcode(op_call_varargs);
1851     instructions().append(func->index()); // func
1852     instructions().append(argCountRegister->index()); // arg count
1853     instructions().append(thisRegister->index() + RegisterFile::CallFrameHeaderSize); // initial registerOffset
1854     if (dst != ignoredResult()) {
1855         emitOpcode(op_call_put_result);
1856         instructions().append(dst->index()); // dst
1857     }
1858     if (m_shouldEmitProfileHooks) {
1859         emitOpcode(op_profile_did_call);
1860         instructions().append(func->index());
1861     }
1862     return dst;
1863 }
1864
1865 RegisterID* BytecodeGenerator::emitReturn(RegisterID* src)
1866 {
1867     if (m_codeBlock->needsFullScopeChain()) {
1868         emitOpcode(op_tear_off_activation);
1869         instructions().append(m_activationRegister->index());
1870         instructions().append(m_codeBlock->argumentsRegister());
1871     } else if (m_codeBlock->usesArguments() && m_codeBlock->m_numParameters > 1
1872                && !m_codeBlock->isStrictMode()) { // If there are no named parameters, there's nothing to tear off, since extra / unnamed parameters get copied to the arguments object at construct time.
1873         emitOpcode(op_tear_off_arguments);
1874         instructions().append(m_codeBlock->argumentsRegister());
1875     }
1876
1877     // Constructors use op_ret_object_or_this to check the result is an
1878     // object, unless we can trivially determine the check is not
1879     // necessary (currently, if the return value is 'this').
1880     if (isConstructor() && (src->index() != m_thisRegister.index())) {
1881         emitOpcode(op_ret_object_or_this);
1882         instructions().append(src->index());
1883         instructions().append(m_thisRegister.index());
1884         return src;
1885     }
1886     return emitUnaryNoDstOp(op_ret, src);
1887 }
1888
1889 RegisterID* BytecodeGenerator::emitUnaryNoDstOp(OpcodeID opcodeID, RegisterID* src)
1890 {
1891     emitOpcode(opcodeID);
1892     instructions().append(src->index());
1893     return src;
1894 }
1895
1896 RegisterID* BytecodeGenerator::emitConstruct(RegisterID* dst, RegisterID* func, CallArguments& callArguments, unsigned divot, unsigned startOffset, unsigned endOffset)
1897 {
1898     ASSERT(func->refCount());
1899
1900     if (m_shouldEmitProfileHooks)
1901         emitMove(callArguments.profileHookRegister(), func);
1902
1903     // Generate code for arguments.
1904     unsigned argumentIndex = 0;
1905     if (ArgumentsNode* argumentsNode = callArguments.argumentsNode()) {
1906         for (ArgumentListNode* n = argumentsNode->m_listNode; n; n = n->m_next)
1907             emitNode(callArguments.argumentRegister(argumentIndex++), n);
1908     }
1909
1910     if (m_shouldEmitProfileHooks) {
1911         emitOpcode(op_profile_will_call);
1912         instructions().append(callArguments.profileHookRegister()->index());
1913     }
1914
1915     // Reserve space for call frame.
1916     Vector<RefPtr<RegisterID>, RegisterFile::CallFrameHeaderSize> callFrame;
1917     for (int i = 0; i < RegisterFile::CallFrameHeaderSize; ++i)
1918         callFrame.append(newTemporary());
1919
1920     emitExpressionInfo(divot, startOffset, endOffset);
1921
1922     emitOpcode(op_construct);
1923     instructions().append(func->index()); // func
1924     instructions().append(callArguments.count()); // argCount
1925     instructions().append(callArguments.callFrame()); // registerOffset
1926     if (dst != ignoredResult()) {
1927         emitOpcode(op_call_put_result);
1928         instructions().append(dst->index()); // dst
1929     }
1930
1931     if (m_shouldEmitProfileHooks) {
1932         emitOpcode(op_profile_did_call);
1933         instructions().append(callArguments.profileHookRegister()->index());
1934     }
1935
1936     return dst;
1937 }
1938
1939 RegisterID* BytecodeGenerator::emitStrcat(RegisterID* dst, RegisterID* src, int count)
1940 {
1941     emitOpcode(op_strcat);
1942     instructions().append(dst->index());
1943     instructions().append(src->index());
1944     instructions().append(count);
1945
1946     return dst;
1947 }
1948
1949 void BytecodeGenerator::emitToPrimitive(RegisterID* dst, RegisterID* src)
1950 {
1951     emitOpcode(op_to_primitive);
1952     instructions().append(dst->index());
1953     instructions().append(src->index());
1954 }
1955
1956 RegisterID* BytecodeGenerator::emitPushScope(RegisterID* scope)
1957 {
1958     ASSERT(scope->isTemporary());
1959     ControlFlowContext context;
1960     context.isFinallyBlock = false;
1961     m_scopeContextStack.append(context);
1962     m_dynamicScopeDepth++;
1963
1964     return emitUnaryNoDstOp(op_push_scope, scope);
1965 }
1966
1967 void BytecodeGenerator::emitPopScope()
1968 {
1969     ASSERT(m_scopeContextStack.size());
1970     ASSERT(!m_scopeContextStack.last().isFinallyBlock);
1971
1972     emitOpcode(op_pop_scope);
1973
1974     m_scopeContextStack.removeLast();
1975     m_dynamicScopeDepth--;
1976 }
1977
1978 void BytecodeGenerator::emitDebugHook(DebugHookID debugHookID, int firstLine, int lastLine)
1979 {
1980 #if ENABLE(DEBUG_WITH_BREAKPOINT)
1981     if (debugHookID != DidReachBreakpoint)
1982         return;
1983 #else
1984     if (!m_shouldEmitDebugHooks)
1985         return;
1986 #endif
1987     emitOpcode(op_debug);
1988     instructions().append(debugHookID);
1989     instructions().append(firstLine);
1990     instructions().append(lastLine);
1991 }
1992
1993 void BytecodeGenerator::pushFinallyContext(Label* target, RegisterID* retAddrDst)
1994 {
1995     ControlFlowContext scope;
1996     scope.isFinallyBlock = true;
1997     FinallyContext context = { target, retAddrDst };
1998     scope.finallyContext = context;
1999     m_scopeContextStack.append(scope);
2000     m_finallyDepth++;
2001 }
2002
2003 void BytecodeGenerator::popFinallyContext()
2004 {
2005     ASSERT(m_scopeContextStack.size());
2006     ASSERT(m_scopeContextStack.last().isFinallyBlock);
2007     ASSERT(m_finallyDepth > 0);
2008     m_scopeContextStack.removeLast();
2009     m_finallyDepth--;
2010 }
2011
2012 LabelScope* BytecodeGenerator::breakTarget(const Identifier& name)
2013 {
2014     // Reclaim free label scopes.
2015     //
2016     // The condition was previously coded as 'm_labelScopes.size() && !m_labelScopes.last().refCount()',
2017     // however sometimes this appears to lead to GCC going a little haywire and entering the loop with
2018     // size 0, leading to segfaulty badness.  We are yet to identify a valid cause within our code to
2019     // cause the GCC codegen to misbehave in this fashion, and as such the following refactoring of the
2020     // loop condition is a workaround.
2021     while (m_labelScopes.size()) {
2022         if  (m_labelScopes.last().refCount())
2023             break;
2024         m_labelScopes.removeLast();
2025     }
2026
2027     if (!m_labelScopes.size())
2028         return 0;
2029
2030     // We special-case the following, which is a syntax error in Firefox:
2031     // label:
2032     //     break;
2033     if (name.isEmpty()) {
2034         for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2035             LabelScope* scope = &m_labelScopes[i];
2036             if (scope->type() != LabelScope::NamedLabel) {
2037                 ASSERT(scope->breakTarget());
2038                 return scope;
2039             }
2040         }
2041         return 0;
2042     }
2043
2044     for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2045         LabelScope* scope = &m_labelScopes[i];
2046         if (scope->name() && *scope->name() == name) {
2047             ASSERT(scope->breakTarget());
2048             return scope;
2049         }
2050     }
2051     return 0;
2052 }
2053
2054 LabelScope* BytecodeGenerator::continueTarget(const Identifier& name)
2055 {
2056     // Reclaim free label scopes.
2057     while (m_labelScopes.size() && !m_labelScopes.last().refCount())
2058         m_labelScopes.removeLast();
2059
2060     if (!m_labelScopes.size())
2061         return 0;
2062
2063     if (name.isEmpty()) {
2064         for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2065             LabelScope* scope = &m_labelScopes[i];
2066             if (scope->type() == LabelScope::Loop) {
2067                 ASSERT(scope->continueTarget());
2068                 return scope;
2069             }
2070         }
2071         return 0;
2072     }
2073
2074     // Continue to the loop nested nearest to the label scope that matches
2075     // 'name'.
2076     LabelScope* result = 0;
2077     for (int i = m_labelScopes.size() - 1; i >= 0; --i) {
2078         LabelScope* scope = &m_labelScopes[i];
2079         if (scope->type() == LabelScope::Loop) {
2080             ASSERT(scope->continueTarget());
2081             result = scope;
2082         }
2083         if (scope->name() && *scope->name() == name)
2084             return result; // may be 0
2085     }
2086     return 0;
2087 }
2088
2089 PassRefPtr<Label> BytecodeGenerator::emitComplexJumpScopes(Label* target, ControlFlowContext* topScope, ControlFlowContext* bottomScope)
2090 {
2091     while (topScope > bottomScope) {
2092         // First we count the number of dynamic scopes we need to remove to get
2093         // to a finally block.
2094         int nNormalScopes = 0;
2095         while (topScope > bottomScope) {
2096             if (topScope->isFinallyBlock)
2097                 break;
2098             ++nNormalScopes;
2099             --topScope;
2100         }
2101
2102         if (nNormalScopes) {
2103             size_t begin = instructions().size();
2104
2105             // We need to remove a number of dynamic scopes to get to the next
2106             // finally block
2107             emitOpcode(op_jmp_scopes);
2108             instructions().append(nNormalScopes);
2109
2110             // If topScope == bottomScope then there isn't actually a finally block
2111             // left to emit, so make the jmp_scopes jump directly to the target label
2112             if (topScope == bottomScope) {
2113                 instructions().append(target->bind(begin, instructions().size()));
2114                 return target;
2115             }
2116
2117             // Otherwise we just use jmp_scopes to pop a group of scopes and go
2118             // to the next instruction
2119             RefPtr<Label> nextInsn = newLabel();
2120             instructions().append(nextInsn->bind(begin, instructions().size()));
2121             emitLabel(nextInsn.get());
2122         }
2123
2124         while (topScope > bottomScope && topScope->isFinallyBlock) {
2125             emitJumpSubroutine(topScope->finallyContext.retAddrDst, topScope->finallyContext.finallyAddr);
2126             --topScope;
2127         }
2128     }
2129     return emitJump(target);
2130 }
2131
2132 PassRefPtr<Label> BytecodeGenerator::emitJumpScopes(Label* target, int targetScopeDepth)
2133 {
2134     ASSERT(scopeDepth() - targetScopeDepth >= 0);
2135     ASSERT(target->isForward());
2136
2137     size_t scopeDelta = scopeDepth() - targetScopeDepth;
2138     ASSERT(scopeDelta <= m_scopeContextStack.size());
2139     if (!scopeDelta)
2140         return emitJump(target);
2141
2142     if (m_finallyDepth)
2143         return emitComplexJumpScopes(target, &m_scopeContextStack.last(), &m_scopeContextStack.last() - scopeDelta);
2144
2145     size_t begin = instructions().size();
2146
2147     emitOpcode(op_jmp_scopes);
2148     instructions().append(scopeDelta);
2149     instructions().append(target->bind(begin, instructions().size()));
2150     return target;
2151 }
2152
2153 RegisterID* BytecodeGenerator::emitGetPropertyNames(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, Label* breakTarget)
2154 {
2155     size_t begin = instructions().size();
2156
2157     emitOpcode(op_get_pnames);
2158     instructions().append(dst->index());
2159     instructions().append(base->index());
2160     instructions().append(i->index());
2161     instructions().append(size->index());
2162     instructions().append(breakTarget->bind(begin, instructions().size()));
2163     return dst;
2164 }
2165
2166 RegisterID* BytecodeGenerator::emitNextPropertyName(RegisterID* dst, RegisterID* base, RegisterID* i, RegisterID* size, RegisterID* iter, Label* target)
2167 {
2168     size_t begin = instructions().size();
2169
2170     emitOpcode(op_next_pname);
2171     instructions().append(dst->index());
2172     instructions().append(base->index());
2173     instructions().append(i->index());
2174     instructions().append(size->index());
2175     instructions().append(iter->index());
2176     instructions().append(target->bind(begin, instructions().size()));
2177     return dst;
2178 }
2179
2180 RegisterID* BytecodeGenerator::emitCatch(RegisterID* targetRegister, Label* start, Label* end)
2181 {
2182     m_usesExceptions = true;
2183 #if ENABLE(JIT)
2184     HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth, CodeLocationLabel() };
2185 #else
2186     HandlerInfo info = { start->bind(0, 0), end->bind(0, 0), instructions().size(), m_dynamicScopeDepth + m_baseScopeDepth };
2187 #endif
2188
2189     m_codeBlock->addExceptionHandler(info);
2190     emitOpcode(op_catch);
2191     instructions().append(targetRegister->index());
2192     return targetRegister;
2193 }
2194
2195 void BytecodeGenerator::emitThrowReferenceError(const UString& message)
2196 {
2197     emitOpcode(op_throw_reference_error);
2198     instructions().append(addConstantValue(jsString(globalData(), message))->index());
2199 }
2200
2201 PassRefPtr<Label> BytecodeGenerator::emitJumpSubroutine(RegisterID* retAddrDst, Label* finally)
2202 {
2203     size_t begin = instructions().size();
2204
2205     emitOpcode(op_jsr);
2206     instructions().append(retAddrDst->index());
2207     instructions().append(finally->bind(begin, instructions().size()));
2208     emitLabel(newLabel().get()); // Record the fact that the next instruction is implicitly labeled, because op_sret will return to it.
2209     return finally;
2210 }
2211
2212 void BytecodeGenerator::emitSubroutineReturn(RegisterID* retAddrSrc)
2213 {
2214     emitOpcode(op_sret);
2215     instructions().append(retAddrSrc->index());
2216 }
2217
2218 void BytecodeGenerator::emitPushNewScope(RegisterID* dst, const Identifier& property, RegisterID* value)
2219 {
2220     ControlFlowContext context;
2221     context.isFinallyBlock = false;
2222     m_scopeContextStack.append(context);
2223     m_dynamicScopeDepth++;
2224
2225     emitOpcode(op_push_new_scope);
2226     instructions().append(dst->index());
2227     instructions().append(addConstant(property));
2228     instructions().append(value->index());
2229 }
2230
2231 void BytecodeGenerator::beginSwitch(RegisterID* scrutineeRegister, SwitchInfo::SwitchType type)
2232 {
2233     SwitchInfo info = { instructions().size(), type };
2234     switch (type) {
2235         case SwitchInfo::SwitchImmediate:
2236             emitOpcode(op_switch_imm);
2237             break;
2238         case SwitchInfo::SwitchCharacter:
2239             emitOpcode(op_switch_char);
2240             break;
2241         case SwitchInfo::SwitchString:
2242             emitOpcode(op_switch_string);
2243             break;
2244         default:
2245             ASSERT_NOT_REACHED();
2246     }
2247
2248     instructions().append(0); // place holder for table index
2249     instructions().append(0); // place holder for default target    
2250     instructions().append(scrutineeRegister->index());
2251     m_switchContextStack.append(info);
2252 }
2253
2254 static int32_t keyForImmediateSwitch(ExpressionNode* node, int32_t min, int32_t max)
2255 {
2256     UNUSED_PARAM(max);
2257     ASSERT(node->isNumber());
2258     double value = static_cast<NumberNode*>(node)->value();
2259     int32_t key = static_cast<int32_t>(value);
2260     ASSERT(key == value);
2261     ASSERT(key >= min);
2262     ASSERT(key <= max);
2263     return key - min;
2264 }
2265
2266 static void prepareJumpTableForImmediateSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
2267 {
2268     jumpTable.min = min;
2269     jumpTable.branchOffsets.resize(max - min + 1);
2270     jumpTable.branchOffsets.fill(0);
2271     for (uint32_t i = 0; i < clauseCount; ++i) {
2272         // We're emitting this after the clause labels should have been fixed, so 
2273         // the labels should not be "forward" references
2274         ASSERT(!labels[i]->isForward());
2275         jumpTable.add(keyForImmediateSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); 
2276     }
2277 }
2278
2279 static int32_t keyForCharacterSwitch(ExpressionNode* node, int32_t min, int32_t max)
2280 {
2281     UNUSED_PARAM(max);
2282     ASSERT(node->isString());
2283     StringImpl* clause = static_cast<StringNode*>(node)->value().impl();
2284     ASSERT(clause->length() == 1);
2285     
2286     int32_t key = (*clause)[0];
2287     ASSERT(key >= min);
2288     ASSERT(key <= max);
2289     return key - min;
2290 }
2291
2292 static void prepareJumpTableForCharacterSwitch(SimpleJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, int32_t min, int32_t max)
2293 {
2294     jumpTable.min = min;
2295     jumpTable.branchOffsets.resize(max - min + 1);
2296     jumpTable.branchOffsets.fill(0);
2297     for (uint32_t i = 0; i < clauseCount; ++i) {
2298         // We're emitting this after the clause labels should have been fixed, so 
2299         // the labels should not be "forward" references
2300         ASSERT(!labels[i]->isForward());
2301         jumpTable.add(keyForCharacterSwitch(nodes[i], min, max), labels[i]->bind(switchAddress, switchAddress + 3)); 
2302     }
2303 }
2304
2305 static void prepareJumpTableForStringSwitch(StringJumpTable& jumpTable, int32_t switchAddress, uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes)
2306 {
2307     for (uint32_t i = 0; i < clauseCount; ++i) {
2308         // We're emitting this after the clause labels should have been fixed, so 
2309         // the labels should not be "forward" references
2310         ASSERT(!labels[i]->isForward());
2311         
2312         ASSERT(nodes[i]->isString());
2313         StringImpl* clause = static_cast<StringNode*>(nodes[i])->value().impl();
2314         OffsetLocation location;
2315         location.branchOffset = labels[i]->bind(switchAddress, switchAddress + 3);
2316         jumpTable.offsetTable.add(clause, location);
2317     }
2318 }
2319
2320 void BytecodeGenerator::endSwitch(uint32_t clauseCount, RefPtr<Label>* labels, ExpressionNode** nodes, Label* defaultLabel, int32_t min, int32_t max)
2321 {
2322     SwitchInfo switchInfo = m_switchContextStack.last();
2323     m_switchContextStack.removeLast();
2324     if (switchInfo.switchType == SwitchInfo::SwitchImmediate) {
2325         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfImmediateSwitchJumpTables();
2326         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2327
2328         SimpleJumpTable& jumpTable = m_codeBlock->addImmediateSwitchJumpTable();
2329         prepareJumpTableForImmediateSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
2330     } else if (switchInfo.switchType == SwitchInfo::SwitchCharacter) {
2331         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfCharacterSwitchJumpTables();
2332         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2333         
2334         SimpleJumpTable& jumpTable = m_codeBlock->addCharacterSwitchJumpTable();
2335         prepareJumpTableForCharacterSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes, min, max);
2336     } else {
2337         ASSERT(switchInfo.switchType == SwitchInfo::SwitchString);
2338         instructions()[switchInfo.bytecodeOffset + 1] = m_codeBlock->numberOfStringSwitchJumpTables();
2339         instructions()[switchInfo.bytecodeOffset + 2] = defaultLabel->bind(switchInfo.bytecodeOffset, switchInfo.bytecodeOffset + 3);
2340
2341         StringJumpTable& jumpTable = m_codeBlock->addStringSwitchJumpTable();
2342         prepareJumpTableForStringSwitch(jumpTable, switchInfo.bytecodeOffset, clauseCount, labels, nodes);
2343     }
2344 }
2345
2346 RegisterID* BytecodeGenerator::emitThrowExpressionTooDeepException()
2347 {
2348     // It would be nice to do an even better job of identifying exactly where the expression is.
2349     // And we could make the caller pass the node pointer in, if there was some way of getting
2350     // that from an arbitrary node. However, calling emitExpressionInfo without any useful data
2351     // is still good enough to get us an accurate line number.
2352     m_expressionTooDeep = true;
2353     return newTemporary();
2354 }
2355
2356 void BytecodeGenerator::setIsNumericCompareFunction(bool isNumericCompareFunction)
2357 {
2358     m_codeBlock->setIsNumericCompareFunction(isNumericCompareFunction);
2359 }
2360
2361 int BytecodeGenerator::argumentNumberFor(const Identifier& ident)
2362 {
2363     int parameterCount = m_parameters.size(); // includes 'this'
2364     RegisterID* registerID = registerFor(ident);
2365     if (!registerID)
2366         return 0;
2367     int index = registerID->index() + RegisterFile::CallFrameHeaderSize + parameterCount;
2368     return (index > 0 && index < parameterCount) ? index : 0;
2369 }
2370
2371 } // namespace JSC