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 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
200 ASSERT(slot != NULL); | 200 ASSERT(slot != NULL); |
201 if (expr->location().is_temporary()) { | 201 if (expr->location().is_temporary()) { |
202 __ push(Operand(ebp, SlotOffset(slot))); | 202 __ push(Operand(ebp, SlotOffset(slot))); |
203 } else { | 203 } else { |
204 ASSERT(expr->location().is_nowhere()); | 204 ASSERT(expr->location().is_nowhere()); |
205 } | 205 } |
206 } | 206 } |
207 } | 207 } |
208 | 208 |
209 | 209 |
| 210 void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { |
| 211 Comment cmnt(masm_, "[ ObjectLiteral"); |
| 212 Label exists; |
| 213 // Registers will be used as follows: |
| 214 // edi = JS function. |
| 215 // ebx = literals array. |
| 216 // eax = boilerplate |
| 217 |
| 218 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
| 219 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset)); |
| 220 int literal_offset = |
| 221 FixedArray::kHeaderSize + expr->literal_index() * kPointerSize; |
| 222 __ mov(eax, FieldOperand(ebx, literal_offset)); |
| 223 __ cmp(eax, Factory::undefined_value()); |
| 224 __ j(not_equal, &exists); |
| 225 // Create boilerplate if it does not exist. |
| 226 // Literal array (0). |
| 227 __ push(ebx); |
| 228 // Literal index (1). |
| 229 __ push(Immediate(Smi::FromInt(expr->literal_index()))); |
| 230 // Constant properties (2). |
| 231 __ push(Immediate(expr->constant_properties())); |
| 232 __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3); |
| 233 __ bind(&exists); |
| 234 // eax contains boilerplate. |
| 235 // Clone boilerplate. |
| 236 __ push(eax); |
| 237 if (expr->depth() == 1) { |
| 238 __ CallRuntime(Runtime::kCloneShallowLiteralBoilerplate, 1); |
| 239 } else { |
| 240 __ CallRuntime(Runtime::kCloneLiteralBoilerplate, 1); |
| 241 } |
| 242 |
| 243 // If result_saved == true: the result is saved on top of the stack. |
| 244 // If result_saved == false: the result not on the stack, just is in eax. |
| 245 bool result_saved = false; |
| 246 |
| 247 for (int i = 0; i < expr->properties()->length(); i++) { |
| 248 ObjectLiteral::Property* property = expr->properties()->at(i); |
| 249 Literal* key = property->key(); |
| 250 Expression* value = property->value(); |
| 251 if (property->kind() == ObjectLiteral::Property::CONSTANT) continue; |
| 252 if (property->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && |
| 253 CompileTimeValue::IsCompileTimeValue(value)) { |
| 254 continue; |
| 255 } |
| 256 if (!result_saved) { |
| 257 __ push(eax); // Save result on the stack |
| 258 result_saved = true; |
| 259 } |
| 260 switch (property->kind()) { |
| 261 case ObjectLiteral::Property::MATERIALIZED_LITERAL: // fall through |
| 262 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
| 263 case ObjectLiteral::Property::COMPUTED: |
| 264 if (key->handle()->IsSymbol()) { |
| 265 Visit(value); |
| 266 ASSERT(value->location().is_temporary()); |
| 267 __ pop(eax); |
| 268 __ mov(ecx, Immediate(key->handle())); |
| 269 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
| 270 __ call(ic, RelocInfo::CODE_TARGET); |
| 271 // StoreIC leaves the receiver on the stack. |
| 272 break; |
| 273 } |
| 274 // fall through |
| 275 case ObjectLiteral::Property::PROTOTYPE: |
| 276 __ push(eax); |
| 277 Visit(key); |
| 278 if (key->location().is_constant()) { |
| 279 __ push(Immediate(key->handle())); |
| 280 } |
| 281 Visit(value); |
| 282 ASSERT(value->location().is_temporary()); |
| 283 __ CallRuntime(Runtime::kSetProperty, 3); |
| 284 __ mov(eax, Operand(esp, 0)); // Restore result into eax. |
| 285 break; |
| 286 case ObjectLiteral::Property::SETTER: // fall through |
| 287 case ObjectLiteral::Property::GETTER: |
| 288 __ push(eax); |
| 289 Visit(key); |
| 290 if (key->location().is_constant()) { |
| 291 __ push(Immediate(key->handle())); |
| 292 } |
| 293 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? |
| 294 Smi::FromInt(1) : |
| 295 Smi::FromInt(0))); |
| 296 Visit(value); |
| 297 ASSERT(value->location().is_temporary()); |
| 298 __ CallRuntime(Runtime::kDefineAccessor, 4); |
| 299 __ mov(eax, Operand(esp, 0)); // Restore result into eax. |
| 300 break; |
| 301 default: UNREACHABLE(); |
| 302 } |
| 303 } |
| 304 if (expr->location().is_nowhere() && result_saved) { |
| 305 __ add(Operand(esp), Immediate(kPointerSize)); |
| 306 } else if (expr->location().is_temporary() && !result_saved) { |
| 307 __ push(eax); |
| 308 } |
| 309 } |
| 310 |
| 311 |
210 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { | 312 void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { |
211 Comment cmnt(masm_, "[ RegExp Literal"); | 313 Comment cmnt(masm_, "[ RegExp Literal"); |
212 Label done; | 314 Label done; |
213 // Registers will be used as follows: | 315 // Registers will be used as follows: |
214 // edi = JS function. | 316 // edi = JS function. |
215 // ebx = literals array. | 317 // ebx = literals array. |
216 // eax = regexp literal. | 318 // eax = regexp literal. |
217 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 319 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
218 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset)); | 320 __ mov(ebx, FieldOperand(edi, JSFunction::kLiteralsOffset)); |
219 int literal_offset = | 321 int literal_offset = |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 __ CallRuntime(function, arg_count); | 542 __ CallRuntime(function, arg_count); |
441 if (expr->location().is_temporary()) { | 543 if (expr->location().is_temporary()) { |
442 __ push(eax); | 544 __ push(eax); |
443 } else { | 545 } else { |
444 ASSERT(expr->location().is_nowhere()); | 546 ASSERT(expr->location().is_nowhere()); |
445 } | 547 } |
446 } | 548 } |
447 | 549 |
448 | 550 |
449 } } // namespace v8::internal | 551 } } // namespace v8::internal |
OLD | NEW |