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