OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 11 matching lines...) Expand all Loading... |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 | 29 |
30 #include "codegen-inl.h" | 30 #include "codegen-inl.h" |
31 #include "fast-codegen.h" | 31 #include "fast-codegen.h" |
| 32 #include "stub-cache.h" |
| 33 #include "debug.h" |
32 | 34 |
33 namespace v8 { | 35 namespace v8 { |
34 namespace internal { | 36 namespace internal { |
35 | 37 |
36 Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun, | 38 Handle<Code> FastCodeGenerator::MakeCode(FunctionLiteral* fun, |
37 Handle<Script> script) { | 39 Handle<Script> script, |
| 40 bool is_eval) { |
38 CodeGenerator::MakeCodePrologue(fun); | 41 CodeGenerator::MakeCodePrologue(fun); |
39 const int kInitialBufferSize = 4 * KB; | 42 const int kInitialBufferSize = 4 * KB; |
40 MacroAssembler masm(NULL, kInitialBufferSize); | 43 MacroAssembler masm(NULL, kInitialBufferSize); |
41 FastCodeGenerator cgen(&masm); | 44 FastCodeGenerator cgen(&masm, script, is_eval); |
42 cgen.Generate(fun); | 45 cgen.Generate(fun); |
43 if (cgen.HasStackOverflow()) { | 46 if (cgen.HasStackOverflow()) { |
44 ASSERT(!Top::has_pending_exception()); | 47 ASSERT(!Top::has_pending_exception()); |
45 return Handle<Code>::null(); | 48 return Handle<Code>::null(); |
46 } | 49 } |
47 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); | 50 Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); |
48 return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script); | 51 return CodeGenerator::MakeCodeEpilogue(fun, &masm, flags, script); |
49 } | 52 } |
50 | 53 |
51 | 54 |
52 int FastCodeGenerator::SlotOffset(Slot* slot) { | 55 int FastCodeGenerator::SlotOffset(Slot* slot) { |
53 // Offset is negative because higher indexes are at lower addresses. | 56 // Offset is negative because higher indexes are at lower addresses. |
54 int offset = -slot->index() * kPointerSize; | 57 int offset = -slot->index() * kPointerSize; |
55 // Adjust by a (parameter or local) base offset. | 58 // Adjust by a (parameter or local) base offset. |
56 switch (slot->type()) { | 59 switch (slot->type()) { |
57 case Slot::PARAMETER: | 60 case Slot::PARAMETER: |
58 offset += (function_->scope()->num_parameters() + 1) * kPointerSize; | 61 offset += (function_->scope()->num_parameters() + 1) * kPointerSize; |
59 break; | 62 break; |
60 case Slot::LOCAL: | 63 case Slot::LOCAL: |
61 offset += JavaScriptFrameConstants::kLocal0Offset; | 64 offset += JavaScriptFrameConstants::kLocal0Offset; |
62 break; | 65 break; |
63 default: | 66 default: |
64 UNREACHABLE(); | 67 UNREACHABLE(); |
65 } | 68 } |
66 return offset; | 69 return offset; |
67 } | 70 } |
68 | 71 |
| 72 |
| 73 void FastCodeGenerator::VisitDeclarations( |
| 74 ZoneList<Declaration*>* declarations) { |
| 75 int length = declarations->length(); |
| 76 int globals = 0; |
| 77 for (int i = 0; i < length; i++) { |
| 78 Declaration* node = declarations->at(i); |
| 79 Variable* var = node->proxy()->var(); |
| 80 Slot* slot = var->slot(); |
| 81 |
| 82 // If it was not possible to allocate the variable at compile |
| 83 // time, we need to "declare" it at runtime to make sure it |
| 84 // actually exists in the local context. |
| 85 if ((slot != NULL && slot->type() == Slot::LOOKUP) || !var->is_global()) { |
| 86 UNREACHABLE(); |
| 87 } else { |
| 88 // Count global variables and functions for later processing |
| 89 globals++; |
| 90 } |
| 91 } |
| 92 |
| 93 // Return in case of no declared global functions or variables. |
| 94 if (globals == 0) return; |
| 95 |
| 96 // Compute array of global variable and function declarations. |
| 97 Handle<FixedArray> array = Factory::NewFixedArray(2 * globals, TENURED); |
| 98 for (int j = 0, i = 0; i < length; i++) { |
| 99 Declaration* node = declarations->at(i); |
| 100 Variable* var = node->proxy()->var(); |
| 101 Slot* slot = var->slot(); |
| 102 |
| 103 if ((slot == NULL || slot->type() != Slot::LOOKUP) && var->is_global()) { |
| 104 array->set(j++, *(var->name())); |
| 105 if (node->fun() == NULL) { |
| 106 if (var->mode() == Variable::CONST) { |
| 107 // In case this is const property use the hole. |
| 108 array->set_the_hole(j++); |
| 109 } else { |
| 110 array->set_undefined(j++); |
| 111 } |
| 112 } else { |
| 113 Handle<JSFunction> function = BuildBoilerplate(node->fun()); |
| 114 // Check for stack-overflow exception. |
| 115 if (HasStackOverflow()) return; |
| 116 array->set(j++, *function); |
| 117 } |
| 118 } |
| 119 } |
| 120 |
| 121 // Invoke the platform-dependent code generator to do the actual |
| 122 // declaration the global variables and functions. |
| 123 DeclareGlobals(array); |
| 124 } |
| 125 |
| 126 Handle<JSFunction> FastCodeGenerator::BuildBoilerplate(FunctionLiteral* fun) { |
| 127 #ifdef DEBUG |
| 128 // We should not try to compile the same function literal more than |
| 129 // once. |
| 130 fun->mark_as_compiled(); |
| 131 #endif |
| 132 |
| 133 // Generate code |
| 134 Handle<Code> code = CodeGenerator::ComputeLazyCompile(fun->num_parameters()); |
| 135 // Check for stack-overflow exception. |
| 136 if (code.is_null()) { |
| 137 SetStackOverflow(); |
| 138 return Handle<JSFunction>::null(); |
| 139 } |
| 140 |
| 141 // Create a boilerplate function. |
| 142 Handle<JSFunction> function = |
| 143 Factory::NewFunctionBoilerplate(fun->name(), |
| 144 fun->materialized_literal_count(), |
| 145 code); |
| 146 CodeGenerator::SetFunctionInfo(function, fun, false, script_); |
| 147 |
| 148 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 149 // Notify debugger that a new function has been added. |
| 150 Debugger::OnNewFunction(function); |
| 151 #endif |
| 152 |
| 153 // Set the expected number of properties for instances and return |
| 154 // the resulting function. |
| 155 SetExpectedNofPropertiesFromEstimate(function, |
| 156 fun->expected_property_count()); |
| 157 return function; |
| 158 } |
| 159 |
| 160 |
69 void FastCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { | 161 void FastCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { |
70 if (FLAG_debug_info) { | 162 if (FLAG_debug_info) { |
71 CodeGenerator::RecordPositions(masm_, fun->start_position()); | 163 CodeGenerator::RecordPositions(masm_, fun->start_position()); |
72 } | 164 } |
73 } | 165 } |
74 | 166 |
75 | 167 |
76 void FastCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { | 168 void FastCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { |
77 if (FLAG_debug_info) { | 169 if (FLAG_debug_info) { |
78 CodeGenerator::RecordPositions(masm_, fun->end_position()); | 170 CodeGenerator::RecordPositions(masm_, fun->end_position()); |
(...skipping 13 matching lines...) Expand all Loading... |
92 masm_->RecordPosition(pos); | 184 masm_->RecordPosition(pos); |
93 } | 185 } |
94 } | 186 } |
95 | 187 |
96 | 188 |
97 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { | 189 void FastCodeGenerator::VisitDeclaration(Declaration* decl) { |
98 UNREACHABLE(); | 190 UNREACHABLE(); |
99 } | 191 } |
100 | 192 |
101 | 193 |
102 void FastCodeGenerator::VisitBlock(Block* stmt) { | |
103 UNREACHABLE(); | |
104 } | |
105 | |
106 | |
107 void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { | 194 void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { |
108 UNREACHABLE(); | 195 UNREACHABLE(); |
109 } | 196 } |
110 | 197 |
111 | 198 |
112 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) { | 199 void FastCodeGenerator::VisitIfStatement(IfStatement* stmt) { |
113 UNREACHABLE(); | 200 UNREACHABLE(); |
114 } | 201 } |
115 | 202 |
116 | 203 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 254 void FastCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
168 UNREACHABLE(); | 255 UNREACHABLE(); |
169 } | 256 } |
170 | 257 |
171 | 258 |
172 void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { | 259 void FastCodeGenerator::VisitDebuggerStatement(DebuggerStatement* stmt) { |
173 UNREACHABLE(); | 260 UNREACHABLE(); |
174 } | 261 } |
175 | 262 |
176 | 263 |
177 void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { | |
178 UNREACHABLE(); | |
179 } | |
180 | |
181 | |
182 void FastCodeGenerator::VisitFunctionBoilerplateLiteral( | 264 void FastCodeGenerator::VisitFunctionBoilerplateLiteral( |
183 FunctionBoilerplateLiteral* expr) { | 265 FunctionBoilerplateLiteral* expr) { |
184 UNREACHABLE(); | 266 UNREACHABLE(); |
185 } | 267 } |
186 | 268 |
187 | 269 |
188 void FastCodeGenerator::VisitConditional(Conditional* expr) { | 270 void FastCodeGenerator::VisitConditional(Conditional* expr) { |
189 UNREACHABLE(); | 271 UNREACHABLE(); |
190 } | 272 } |
191 | 273 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 void FastCodeGenerator::VisitThrow(Throw* expr) { | 306 void FastCodeGenerator::VisitThrow(Throw* expr) { |
225 UNREACHABLE(); | 307 UNREACHABLE(); |
226 } | 308 } |
227 | 309 |
228 | 310 |
229 void FastCodeGenerator::VisitProperty(Property* expr) { | 311 void FastCodeGenerator::VisitProperty(Property* expr) { |
230 UNREACHABLE(); | 312 UNREACHABLE(); |
231 } | 313 } |
232 | 314 |
233 | 315 |
234 void FastCodeGenerator::VisitCall(Call* expr) { | |
235 UNREACHABLE(); | |
236 } | |
237 | |
238 | |
239 void FastCodeGenerator::VisitCallNew(CallNew* expr) { | 316 void FastCodeGenerator::VisitCallNew(CallNew* expr) { |
240 UNREACHABLE(); | 317 UNREACHABLE(); |
241 } | 318 } |
242 | 319 |
243 | 320 |
244 void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | |
245 UNREACHABLE(); | |
246 } | |
247 | |
248 | |
249 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { | 321 void FastCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) { |
250 UNREACHABLE(); | 322 UNREACHABLE(); |
251 } | 323 } |
252 | 324 |
253 | 325 |
254 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { | 326 void FastCodeGenerator::VisitCountOperation(CountOperation* expr) { |
255 UNREACHABLE(); | 327 UNREACHABLE(); |
256 } | 328 } |
257 | 329 |
258 | 330 |
259 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { | 331 void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { |
260 UNREACHABLE(); | 332 UNREACHABLE(); |
261 } | 333 } |
262 | 334 |
263 | 335 |
264 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 336 void FastCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
265 UNREACHABLE(); | 337 UNREACHABLE(); |
266 } | 338 } |
267 | 339 |
268 | 340 |
269 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { | 341 void FastCodeGenerator::VisitThisFunction(ThisFunction* expr) { |
270 UNREACHABLE(); | 342 UNREACHABLE(); |
271 } | 343 } |
272 | 344 |
273 | 345 |
274 } } // namespace v8::internal | 346 } } // namespace v8::internal |
OLD | NEW |