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