| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/code-stubs.h" | 10 #include "src/code-stubs.h" |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 __ call(isolate()->builtins()->InterruptCheck(), | 462 __ call(isolate()->builtins()->InterruptCheck(), |
| 463 RelocInfo::CODE_TARGET); | 463 RelocInfo::CODE_TARGET); |
| 464 __ pop(eax); | 464 __ pop(eax); |
| 465 EmitProfilingCounterReset(); | 465 EmitProfilingCounterReset(); |
| 466 __ bind(&ok); | 466 __ bind(&ok); |
| 467 #ifdef DEBUG | 467 #ifdef DEBUG |
| 468 // Add a label for checking the size of the code used for returning. | 468 // Add a label for checking the size of the code used for returning. |
| 469 Label check_exit_codesize; | 469 Label check_exit_codesize; |
| 470 masm_->bind(&check_exit_codesize); | 470 masm_->bind(&check_exit_codesize); |
| 471 #endif | 471 #endif |
| 472 SetSourcePosition(function()->end_position() - 1); | 472 SetReturnPosition(function()); |
| 473 __ RecordJSReturn(); | 473 __ RecordJSReturn(); |
| 474 // Do not use the leave instruction here because it is too short to | 474 // Do not use the leave instruction here because it is too short to |
| 475 // patch with the code required by the debugger. | 475 // patch with the code required by the debugger. |
| 476 __ mov(esp, ebp); | 476 __ mov(esp, ebp); |
| 477 int no_frame_start = masm_->pc_offset(); | 477 int no_frame_start = masm_->pc_offset(); |
| 478 __ pop(ebp); | 478 __ pop(ebp); |
| 479 | 479 |
| 480 int arg_count = info_->scope()->num_parameters() + 1; | 480 int arg_count = info_->scope()->num_parameters() + 1; |
| 481 int arguments_bytes = arg_count * kPointerSize; | 481 int arguments_bytes = arg_count * kPointerSize; |
| 482 __ Ret(arguments_bytes, ecx); | 482 __ Ret(arguments_bytes, ecx); |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1015 __ or_(ecx, eax); | 1015 __ or_(ecx, eax); |
| 1016 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 1016 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
| 1017 | 1017 |
| 1018 __ cmp(edx, eax); | 1018 __ cmp(edx, eax); |
| 1019 __ j(not_equal, &next_test); | 1019 __ j(not_equal, &next_test); |
| 1020 __ Drop(1); // Switch value is no longer needed. | 1020 __ Drop(1); // Switch value is no longer needed. |
| 1021 __ jmp(clause->body_target()); | 1021 __ jmp(clause->body_target()); |
| 1022 __ bind(&slow_case); | 1022 __ bind(&slow_case); |
| 1023 } | 1023 } |
| 1024 | 1024 |
| 1025 // Record position before stub call for type feedback. | 1025 SetExpressionPosition(clause); |
| 1026 SetSourcePosition(clause->position()); | |
| 1027 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, | 1026 Handle<Code> ic = CodeFactory::CompareIC(isolate(), Token::EQ_STRICT, |
| 1028 strength(language_mode())).code(); | 1027 strength(language_mode())).code(); |
| 1029 CallIC(ic, clause->CompareId()); | 1028 CallIC(ic, clause->CompareId()); |
| 1030 patch_site.EmitPatchInfo(); | 1029 patch_site.EmitPatchInfo(); |
| 1031 | 1030 |
| 1032 Label skip; | 1031 Label skip; |
| 1033 __ jmp(&skip, Label::kNear); | 1032 __ jmp(&skip, Label::kNear); |
| 1034 PrepareForBailout(clause, TOS_REG); | 1033 PrepareForBailout(clause, TOS_REG); |
| 1035 __ cmp(eax, isolate()->factory()->true_value()); | 1034 __ cmp(eax, isolate()->factory()->true_value()); |
| 1036 __ j(not_equal, &next_test); | 1035 __ j(not_equal, &next_test); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1063 VisitStatements(clause->statements()); | 1062 VisitStatements(clause->statements()); |
| 1064 } | 1063 } |
| 1065 | 1064 |
| 1066 __ bind(nested_statement.break_label()); | 1065 __ bind(nested_statement.break_label()); |
| 1067 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); | 1066 PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
| 1068 } | 1067 } |
| 1069 | 1068 |
| 1070 | 1069 |
| 1071 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1070 void FullCodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 1072 Comment cmnt(masm_, "[ ForInStatement"); | 1071 Comment cmnt(masm_, "[ ForInStatement"); |
| 1072 SetStatementPosition(stmt, SKIP_BREAK); |
| 1073 |
| 1073 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); | 1074 FeedbackVectorSlot slot = stmt->ForInFeedbackSlot(); |
| 1074 | 1075 |
| 1075 SetStatementPosition(stmt); | |
| 1076 | |
| 1077 Label loop, exit; | 1076 Label loop, exit; |
| 1078 ForIn loop_statement(this, stmt); | 1077 ForIn loop_statement(this, stmt); |
| 1079 increment_loop_depth(); | 1078 increment_loop_depth(); |
| 1080 | 1079 |
| 1081 // Get the object to enumerate over. If the object is null or undefined, skip | 1080 // Get the object to enumerate over. If the object is null or undefined, skip |
| 1082 // over the loop. See ECMA-262 version 5, section 12.6.4. | 1081 // over the loop. See ECMA-262 version 5, section 12.6.4. |
| 1083 SetExpressionPosition(stmt->enumerable()); | 1082 SetExpressionAsStatementPosition(stmt->enumerable()); |
| 1084 VisitForAccumulatorValue(stmt->enumerable()); | 1083 VisitForAccumulatorValue(stmt->enumerable()); |
| 1085 __ cmp(eax, isolate()->factory()->undefined_value()); | 1084 __ cmp(eax, isolate()->factory()->undefined_value()); |
| 1086 __ j(equal, &exit); | 1085 __ j(equal, &exit); |
| 1087 __ cmp(eax, isolate()->factory()->null_value()); | 1086 __ cmp(eax, isolate()->factory()->null_value()); |
| 1088 __ j(equal, &exit); | 1087 __ j(equal, &exit); |
| 1089 | 1088 |
| 1090 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); | 1089 PrepareForBailoutForId(stmt->PrepareId(), TOS_REG); |
| 1091 | 1090 |
| 1092 // Convert the object to a JS object. | 1091 // Convert the object to a JS object. |
| 1093 Label convert, done_convert; | 1092 Label convert, done_convert; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 __ bind(&non_proxy); | 1167 __ bind(&non_proxy); |
| 1169 __ push(ebx); // Smi | 1168 __ push(ebx); // Smi |
| 1170 __ push(eax); // Array | 1169 __ push(eax); // Array |
| 1171 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); | 1170 __ mov(eax, FieldOperand(eax, FixedArray::kLengthOffset)); |
| 1172 __ push(eax); // Fixed array length (as smi). | 1171 __ push(eax); // Fixed array length (as smi). |
| 1173 __ push(Immediate(Smi::FromInt(0))); // Initial index. | 1172 __ push(Immediate(Smi::FromInt(0))); // Initial index. |
| 1174 | 1173 |
| 1175 // Generate code for doing the condition check. | 1174 // Generate code for doing the condition check. |
| 1176 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); | 1175 PrepareForBailoutForId(stmt->BodyId(), NO_REGISTERS); |
| 1177 __ bind(&loop); | 1176 __ bind(&loop); |
| 1178 SetExpressionPosition(stmt->each()); | 1177 SetExpressionAsStatementPosition(stmt->each()); |
| 1179 | 1178 |
| 1180 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. | 1179 __ mov(eax, Operand(esp, 0 * kPointerSize)); // Get the current index. |
| 1181 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. | 1180 __ cmp(eax, Operand(esp, 1 * kPointerSize)); // Compare to the array length. |
| 1182 __ j(above_equal, loop_statement.break_label()); | 1181 __ j(above_equal, loop_statement.break_label()); |
| 1183 | 1182 |
| 1184 // Get the current entry of the array into register ebx. | 1183 // Get the current entry of the array into register ebx. |
| 1185 __ mov(ebx, Operand(esp, 2 * kPointerSize)); | 1184 __ mov(ebx, Operand(esp, 2 * kPointerSize)); |
| 1186 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); | 1185 __ mov(ebx, FieldOperand(ebx, eax, times_2, FixedArray::kHeaderSize)); |
| 1187 | 1186 |
| 1188 // Get the expected map from the stack or a smi in the | 1187 // Get the expected map from the stack or a smi in the |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1413 __ push(Immediate(var->name())); | 1412 __ push(Immediate(var->name())); |
| 1414 __ CallRuntime(Runtime::kThrowReferenceError, 1); | 1413 __ CallRuntime(Runtime::kThrowReferenceError, 1); |
| 1415 } | 1414 } |
| 1416 } | 1415 } |
| 1417 __ jmp(done); | 1416 __ jmp(done); |
| 1418 } | 1417 } |
| 1419 } | 1418 } |
| 1420 | 1419 |
| 1421 | 1420 |
| 1422 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { | 1421 void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) { |
| 1423 // Record position before possible IC call. | 1422 SetExpressionPosition(proxy); |
| 1424 SetSourcePosition(proxy->position()); | |
| 1425 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); | 1423 PrepareForBailoutForId(proxy->BeforeId(), NO_REGISTERS); |
| 1426 Variable* var = proxy->var(); | 1424 Variable* var = proxy->var(); |
| 1427 | 1425 |
| 1428 // Three cases: global variables, lookup variables, and all other types of | 1426 // Three cases: global variables, lookup variables, and all other types of |
| 1429 // variables. | 1427 // variables. |
| 1430 switch (var->location()) { | 1428 switch (var->location()) { |
| 1431 case Variable::UNALLOCATED: { | 1429 case Variable::UNALLOCATED: { |
| 1432 Comment cmnt(masm_, "[ Global variable"); | 1430 Comment cmnt(masm_, "[ Global variable"); |
| 1433 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); | 1431 __ mov(LoadDescriptor::ReceiverRegister(), GlobalObjectOperand()); |
| 1434 __ mov(LoadDescriptor::NameRegister(), var->name()); | 1432 __ mov(LoadDescriptor::NameRegister(), var->name()); |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1912 } else { | 1910 } else { |
| 1913 context()->Plug(eax); | 1911 context()->Plug(eax); |
| 1914 } | 1912 } |
| 1915 } | 1913 } |
| 1916 | 1914 |
| 1917 | 1915 |
| 1918 void FullCodeGenerator::VisitAssignment(Assignment* expr) { | 1916 void FullCodeGenerator::VisitAssignment(Assignment* expr) { |
| 1919 DCHECK(expr->target()->IsValidReferenceExpression()); | 1917 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1920 | 1918 |
| 1921 Comment cmnt(masm_, "[ Assignment"); | 1919 Comment cmnt(masm_, "[ Assignment"); |
| 1920 SetExpressionPosition(expr, INSERT_BREAK); |
| 1922 | 1921 |
| 1923 Property* property = expr->target()->AsProperty(); | 1922 Property* property = expr->target()->AsProperty(); |
| 1924 LhsKind assign_type = Property::GetAssignType(property); | 1923 LhsKind assign_type = Property::GetAssignType(property); |
| 1925 | 1924 |
| 1926 // Evaluate LHS expression. | 1925 // Evaluate LHS expression. |
| 1927 switch (assign_type) { | 1926 switch (assign_type) { |
| 1928 case VARIABLE: | 1927 case VARIABLE: |
| 1929 // Nothing to do here. | 1928 // Nothing to do here. |
| 1930 break; | 1929 break; |
| 1931 case NAMED_SUPER_PROPERTY: | 1930 case NAMED_SUPER_PROPERTY: |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2001 EmitKeyedPropertyLoad(property); | 2000 EmitKeyedPropertyLoad(property); |
| 2002 PrepareForBailoutForId(property->LoadId(), TOS_REG); | 2001 PrepareForBailoutForId(property->LoadId(), TOS_REG); |
| 2003 break; | 2002 break; |
| 2004 } | 2003 } |
| 2005 } | 2004 } |
| 2006 | 2005 |
| 2007 Token::Value op = expr->binary_op(); | 2006 Token::Value op = expr->binary_op(); |
| 2008 __ push(eax); // Left operand goes on the stack. | 2007 __ push(eax); // Left operand goes on the stack. |
| 2009 VisitForAccumulatorValue(expr->value()); | 2008 VisitForAccumulatorValue(expr->value()); |
| 2010 | 2009 |
| 2011 SetSourcePosition(expr->position() + 1); | |
| 2012 if (ShouldInlineSmiCase(op)) { | 2010 if (ShouldInlineSmiCase(op)) { |
| 2013 EmitInlineSmiBinaryOp(expr->binary_operation(), | 2011 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| 2014 op, | 2012 op, |
| 2015 expr->target(), | 2013 expr->target(), |
| 2016 expr->value()); | 2014 expr->value()); |
| 2017 } else { | 2015 } else { |
| 2018 EmitBinaryOp(expr->binary_operation(), op); | 2016 EmitBinaryOp(expr->binary_operation(), op); |
| 2019 } | 2017 } |
| 2020 | 2018 |
| 2021 // Deoptimization point in case the binary operation may have side effects. | 2019 // Deoptimization point in case the binary operation may have side effects. |
| 2022 PrepareForBailout(expr->binary_operation(), TOS_REG); | 2020 PrepareForBailout(expr->binary_operation(), TOS_REG); |
| 2023 } else { | 2021 } else { |
| 2024 VisitForAccumulatorValue(expr->value()); | 2022 VisitForAccumulatorValue(expr->value()); |
| 2025 } | 2023 } |
| 2026 | 2024 |
| 2027 // Record source position before possible IC call. | 2025 SetExpressionPosition(expr); |
| 2028 SetSourcePosition(expr->position()); | |
| 2029 | 2026 |
| 2030 // Store the value. | 2027 // Store the value. |
| 2031 switch (assign_type) { | 2028 switch (assign_type) { |
| 2032 case VARIABLE: | 2029 case VARIABLE: |
| 2033 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), | 2030 EmitVariableAssignment(expr->target()->AsVariableProxy()->var(), |
| 2034 expr->op(), expr->AssignmentSlot()); | 2031 expr->op(), expr->AssignmentSlot()); |
| 2035 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2032 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2036 context()->Plug(eax); | 2033 context()->Plug(eax); |
| 2037 break; | 2034 break; |
| 2038 case NAMED_PROPERTY: | 2035 case NAMED_PROPERTY: |
| 2039 EmitNamedPropertyAssignment(expr); | 2036 EmitNamedPropertyAssignment(expr); |
| 2040 break; | 2037 break; |
| 2041 case NAMED_SUPER_PROPERTY: | 2038 case NAMED_SUPER_PROPERTY: |
| 2042 EmitNamedSuperPropertyStore(property); | 2039 EmitNamedSuperPropertyStore(property); |
| 2043 context()->Plug(result_register()); | 2040 context()->Plug(result_register()); |
| 2044 break; | 2041 break; |
| 2045 case KEYED_SUPER_PROPERTY: | 2042 case KEYED_SUPER_PROPERTY: |
| 2046 EmitKeyedSuperPropertyStore(property); | 2043 EmitKeyedSuperPropertyStore(property); |
| 2047 context()->Plug(result_register()); | 2044 context()->Plug(result_register()); |
| 2048 break; | 2045 break; |
| 2049 case KEYED_PROPERTY: | 2046 case KEYED_PROPERTY: |
| 2050 EmitKeyedPropertyAssignment(expr); | 2047 EmitKeyedPropertyAssignment(expr); |
| 2051 break; | 2048 break; |
| 2052 } | 2049 } |
| 2053 } | 2050 } |
| 2054 | 2051 |
| 2055 | 2052 |
| 2056 void FullCodeGenerator::VisitYield(Yield* expr) { | 2053 void FullCodeGenerator::VisitYield(Yield* expr) { |
| 2057 Comment cmnt(masm_, "[ Yield"); | 2054 Comment cmnt(masm_, "[ Yield"); |
| 2055 SetExpressionPosition(expr); |
| 2056 |
| 2058 // Evaluate yielded value first; the initial iterator definition depends on | 2057 // Evaluate yielded value first; the initial iterator definition depends on |
| 2059 // this. It stays on the stack while we update the iterator. | 2058 // this. It stays on the stack while we update the iterator. |
| 2060 VisitForStackValue(expr->expression()); | 2059 VisitForStackValue(expr->expression()); |
| 2061 | 2060 |
| 2062 switch (expr->yield_kind()) { | 2061 switch (expr->yield_kind()) { |
| 2063 case Yield::kSuspend: | 2062 case Yield::kSuspend: |
| 2064 // Pop value from top-of-stack slot; box result into result register. | 2063 // Pop value from top-of-stack slot; box result into result register. |
| 2065 EmitCreateIteratorResult(false); | 2064 EmitCreateIteratorResult(false); |
| 2066 __ push(result_register()); | 2065 __ push(result_register()); |
| 2067 // Fall through. | 2066 // Fall through. |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2333 __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx); | 2332 __ mov(FieldOperand(eax, JSGeneratorObject::kResultDonePropertyOffset), edx); |
| 2334 | 2333 |
| 2335 // Only the value field needs a write barrier, as the other values are in the | 2334 // Only the value field needs a write barrier, as the other values are in the |
| 2336 // root set. | 2335 // root set. |
| 2337 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, | 2336 __ RecordWriteField(eax, JSGeneratorObject::kResultValuePropertyOffset, |
| 2338 ecx, edx, kDontSaveFPRegs); | 2337 ecx, edx, kDontSaveFPRegs); |
| 2339 } | 2338 } |
| 2340 | 2339 |
| 2341 | 2340 |
| 2342 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { | 2341 void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { |
| 2343 SetSourcePosition(prop->position()); | 2342 SetExpressionPosition(prop); |
| 2344 Literal* key = prop->key()->AsLiteral(); | 2343 Literal* key = prop->key()->AsLiteral(); |
| 2345 DCHECK(!key->value()->IsSmi()); | 2344 DCHECK(!key->value()->IsSmi()); |
| 2346 DCHECK(!prop->IsSuperAccess()); | 2345 DCHECK(!prop->IsSuperAccess()); |
| 2347 | 2346 |
| 2348 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); | 2347 __ mov(LoadDescriptor::NameRegister(), Immediate(key->value())); |
| 2349 __ mov(LoadDescriptor::SlotRegister(), | 2348 __ mov(LoadDescriptor::SlotRegister(), |
| 2350 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2349 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
| 2351 CallLoadIC(NOT_CONTEXTUAL, language_mode()); | 2350 CallLoadIC(NOT_CONTEXTUAL, language_mode()); |
| 2352 } | 2351 } |
| 2353 | 2352 |
| 2354 | 2353 |
| 2355 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { | 2354 void FullCodeGenerator::EmitNamedSuperPropertyLoad(Property* prop) { |
| 2356 // Stack: receiver, home_object. | 2355 // Stack: receiver, home_object. |
| 2357 SetSourcePosition(prop->position()); | 2356 SetExpressionPosition(prop); |
| 2358 Literal* key = prop->key()->AsLiteral(); | 2357 Literal* key = prop->key()->AsLiteral(); |
| 2359 DCHECK(!key->value()->IsSmi()); | 2358 DCHECK(!key->value()->IsSmi()); |
| 2360 DCHECK(prop->IsSuperAccess()); | 2359 DCHECK(prop->IsSuperAccess()); |
| 2361 | 2360 |
| 2362 __ push(Immediate(key->value())); | 2361 __ push(Immediate(key->value())); |
| 2363 __ push(Immediate(Smi::FromInt(language_mode()))); | 2362 __ push(Immediate(Smi::FromInt(language_mode()))); |
| 2364 __ CallRuntime(Runtime::kLoadFromSuper, 4); | 2363 __ CallRuntime(Runtime::kLoadFromSuper, 4); |
| 2365 } | 2364 } |
| 2366 | 2365 |
| 2367 | 2366 |
| 2368 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { | 2367 void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
| 2369 SetSourcePosition(prop->position()); | 2368 SetExpressionPosition(prop); |
| 2370 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); | 2369 Handle<Code> ic = CodeFactory::KeyedLoadIC(isolate(), language_mode()).code(); |
| 2371 __ mov(LoadDescriptor::SlotRegister(), | 2370 __ mov(LoadDescriptor::SlotRegister(), |
| 2372 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); | 2371 Immediate(SmiFromSlot(prop->PropertyFeedbackSlot()))); |
| 2373 CallIC(ic); | 2372 CallIC(ic); |
| 2374 } | 2373 } |
| 2375 | 2374 |
| 2376 | 2375 |
| 2377 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { | 2376 void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) { |
| 2378 // Stack: receiver, home_object, key. | 2377 // Stack: receiver, home_object, key. |
| 2378 SetExpressionPosition(prop); |
| 2379 __ push(Immediate(Smi::FromInt(language_mode()))); | 2379 __ push(Immediate(Smi::FromInt(language_mode()))); |
| 2380 SetSourcePosition(prop->position()); | |
| 2381 | |
| 2382 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); | 2380 __ CallRuntime(Runtime::kLoadKeyedFromSuper, 4); |
| 2383 } | 2381 } |
| 2384 | 2382 |
| 2385 | 2383 |
| 2386 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 2384 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
| 2387 Token::Value op, | 2385 Token::Value op, |
| 2388 Expression* left, | 2386 Expression* left, |
| 2389 Expression* right) { | 2387 Expression* right) { |
| 2390 // Do combined smi check of the operands. Left operand is on the | 2388 // Do combined smi check of the operands. Left operand is on the |
| 2391 // stack. Right operand is in eax. | 2389 // stack. Right operand is in eax. |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2731 } | 2729 } |
| 2732 // Silently ignore store in sloppy mode. | 2730 // Silently ignore store in sloppy mode. |
| 2733 } | 2731 } |
| 2734 } | 2732 } |
| 2735 | 2733 |
| 2736 | 2734 |
| 2737 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2735 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
| 2738 // Assignment to a property, using a named store IC. | 2736 // Assignment to a property, using a named store IC. |
| 2739 // eax : value | 2737 // eax : value |
| 2740 // esp[0] : receiver | 2738 // esp[0] : receiver |
| 2739 SetExpressionPosition(expr); |
| 2741 | 2740 |
| 2742 Property* prop = expr->target()->AsProperty(); | 2741 Property* prop = expr->target()->AsProperty(); |
| 2743 DCHECK(prop != NULL); | 2742 DCHECK(prop != NULL); |
| 2744 DCHECK(prop->key()->IsLiteral()); | 2743 DCHECK(prop->key()->IsLiteral()); |
| 2745 | 2744 |
| 2746 // Record source code position before IC call. | |
| 2747 SetSourcePosition(expr->position()); | |
| 2748 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); | 2745 __ mov(StoreDescriptor::NameRegister(), prop->key()->AsLiteral()->value()); |
| 2749 __ pop(StoreDescriptor::ReceiverRegister()); | 2746 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2750 if (FLAG_vector_stores) { | 2747 if (FLAG_vector_stores) { |
| 2751 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2748 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2752 CallStoreIC(); | 2749 CallStoreIC(); |
| 2753 } else { | 2750 } else { |
| 2754 CallStoreIC(expr->AssignmentFeedbackId()); | 2751 CallStoreIC(expr->AssignmentFeedbackId()); |
| 2755 } | 2752 } |
| 2756 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2753 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2757 context()->Plug(eax); | 2754 context()->Plug(eax); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 2781 | 2778 |
| 2782 __ push(eax); | 2779 __ push(eax); |
| 2783 __ CallRuntime( | 2780 __ CallRuntime( |
| 2784 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 2781 (is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
| 2785 : Runtime::kStoreKeyedToSuper_Sloppy), | 2782 : Runtime::kStoreKeyedToSuper_Sloppy), |
| 2786 4); | 2783 4); |
| 2787 } | 2784 } |
| 2788 | 2785 |
| 2789 | 2786 |
| 2790 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 2787 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 2788 SetExpressionPosition(expr); |
| 2791 // Assignment to a property, using a keyed store IC. | 2789 // Assignment to a property, using a keyed store IC. |
| 2792 // eax : value | 2790 // eax : value |
| 2793 // esp[0] : key | 2791 // esp[0] : key |
| 2794 // esp[kPointerSize] : receiver | 2792 // esp[kPointerSize] : receiver |
| 2795 | 2793 |
| 2796 __ pop(StoreDescriptor::NameRegister()); // Key. | 2794 __ pop(StoreDescriptor::NameRegister()); // Key. |
| 2797 __ pop(StoreDescriptor::ReceiverRegister()); | 2795 __ pop(StoreDescriptor::ReceiverRegister()); |
| 2798 DCHECK(StoreDescriptor::ValueRegister().is(eax)); | 2796 DCHECK(StoreDescriptor::ValueRegister().is(eax)); |
| 2799 // Record source code position before IC call. | |
| 2800 SetSourcePosition(expr->position()); | |
| 2801 Handle<Code> ic = | 2797 Handle<Code> ic = |
| 2802 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); | 2798 CodeFactory::KeyedStoreIC(isolate(), language_mode()).code(); |
| 2803 if (FLAG_vector_stores) { | 2799 if (FLAG_vector_stores) { |
| 2804 EmitLoadStoreICSlot(expr->AssignmentSlot()); | 2800 EmitLoadStoreICSlot(expr->AssignmentSlot()); |
| 2805 CallIC(ic); | 2801 CallIC(ic); |
| 2806 } else { | 2802 } else { |
| 2807 CallIC(ic, expr->AssignmentFeedbackId()); | 2803 CallIC(ic, expr->AssignmentFeedbackId()); |
| 2808 } | 2804 } |
| 2809 | 2805 |
| 2810 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 2806 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
| 2811 context()->Plug(eax); | 2807 context()->Plug(eax); |
| 2812 } | 2808 } |
| 2813 | 2809 |
| 2814 | 2810 |
| 2815 void FullCodeGenerator::VisitProperty(Property* expr) { | 2811 void FullCodeGenerator::VisitProperty(Property* expr) { |
| 2816 Comment cmnt(masm_, "[ Property"); | 2812 Comment cmnt(masm_, "[ Property"); |
| 2813 SetExpressionPosition(expr); |
| 2814 |
| 2817 Expression* key = expr->key(); | 2815 Expression* key = expr->key(); |
| 2818 | 2816 |
| 2819 if (key->IsPropertyName()) { | 2817 if (key->IsPropertyName()) { |
| 2820 if (!expr->IsSuperAccess()) { | 2818 if (!expr->IsSuperAccess()) { |
| 2821 VisitForAccumulatorValue(expr->obj()); | 2819 VisitForAccumulatorValue(expr->obj()); |
| 2822 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); | 2820 __ Move(LoadDescriptor::ReceiverRegister(), result_register()); |
| 2823 EmitNamedPropertyLoad(expr); | 2821 EmitNamedPropertyLoad(expr); |
| 2824 } else { | 2822 } else { |
| 2825 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); | 2823 VisitForStackValue(expr->obj()->AsSuperPropertyReference()->this_var()); |
| 2826 VisitForStackValue( | 2824 VisitForStackValue( |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2879 // Push the target function under the receiver. | 2877 // Push the target function under the receiver. |
| 2880 __ push(Operand(esp, 0)); | 2878 __ push(Operand(esp, 0)); |
| 2881 __ mov(Operand(esp, kPointerSize), eax); | 2879 __ mov(Operand(esp, kPointerSize), eax); |
| 2882 } | 2880 } |
| 2883 | 2881 |
| 2884 EmitCall(expr, call_type); | 2882 EmitCall(expr, call_type); |
| 2885 } | 2883 } |
| 2886 | 2884 |
| 2887 | 2885 |
| 2888 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | 2886 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { |
| 2887 SetExpressionPosition(expr); |
| 2889 Expression* callee = expr->expression(); | 2888 Expression* callee = expr->expression(); |
| 2890 DCHECK(callee->IsProperty()); | 2889 DCHECK(callee->IsProperty()); |
| 2891 Property* prop = callee->AsProperty(); | 2890 Property* prop = callee->AsProperty(); |
| 2892 DCHECK(prop->IsSuperAccess()); | 2891 DCHECK(prop->IsSuperAccess()); |
| 2893 | 2892 |
| 2894 SetSourcePosition(prop->position()); | |
| 2895 Literal* key = prop->key()->AsLiteral(); | 2893 Literal* key = prop->key()->AsLiteral(); |
| 2896 DCHECK(!key->value()->IsSmi()); | 2894 DCHECK(!key->value()->IsSmi()); |
| 2897 // Load the function from the receiver. | 2895 // Load the function from the receiver. |
| 2898 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2896 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
| 2899 VisitForStackValue(super_ref->home_object()); | 2897 VisitForStackValue(super_ref->home_object()); |
| 2900 VisitForAccumulatorValue(super_ref->this_var()); | 2898 VisitForAccumulatorValue(super_ref->this_var()); |
| 2901 __ push(eax); | 2899 __ push(eax); |
| 2902 __ push(eax); | 2900 __ push(eax); |
| 2903 __ push(Operand(esp, kPointerSize * 2)); | 2901 __ push(Operand(esp, kPointerSize * 2)); |
| 2904 __ push(Immediate(key->value())); | 2902 __ push(Immediate(key->value())); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2944 EmitCall(expr, CallICState::METHOD); | 2942 EmitCall(expr, CallICState::METHOD); |
| 2945 } | 2943 } |
| 2946 | 2944 |
| 2947 | 2945 |
| 2948 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | 2946 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { |
| 2949 Expression* callee = expr->expression(); | 2947 Expression* callee = expr->expression(); |
| 2950 DCHECK(callee->IsProperty()); | 2948 DCHECK(callee->IsProperty()); |
| 2951 Property* prop = callee->AsProperty(); | 2949 Property* prop = callee->AsProperty(); |
| 2952 DCHECK(prop->IsSuperAccess()); | 2950 DCHECK(prop->IsSuperAccess()); |
| 2953 | 2951 |
| 2954 SetSourcePosition(prop->position()); | 2952 SetExpressionPosition(prop); |
| 2955 // Load the function from the receiver. | 2953 // Load the function from the receiver. |
| 2956 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | 2954 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); |
| 2957 VisitForStackValue(super_ref->home_object()); | 2955 VisitForStackValue(super_ref->home_object()); |
| 2958 VisitForAccumulatorValue(super_ref->this_var()); | 2956 VisitForAccumulatorValue(super_ref->this_var()); |
| 2959 __ push(eax); | 2957 __ push(eax); |
| 2960 __ push(eax); | 2958 __ push(eax); |
| 2961 __ push(Operand(esp, kPointerSize * 2)); | 2959 __ push(Operand(esp, kPointerSize * 2)); |
| 2962 VisitForStackValue(prop->key()); | 2960 VisitForStackValue(prop->key()); |
| 2963 __ push(Immediate(Smi::FromInt(language_mode()))); | 2961 __ push(Immediate(Smi::FromInt(language_mode()))); |
| 2964 // Stack here: | 2962 // Stack here: |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2977 // - target function | 2975 // - target function |
| 2978 // - this (receiver) | 2976 // - this (receiver) |
| 2979 EmitCall(expr, CallICState::METHOD); | 2977 EmitCall(expr, CallICState::METHOD); |
| 2980 } | 2978 } |
| 2981 | 2979 |
| 2982 | 2980 |
| 2983 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { | 2981 void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) { |
| 2984 // Load the arguments. | 2982 // Load the arguments. |
| 2985 ZoneList<Expression*>* args = expr->arguments(); | 2983 ZoneList<Expression*>* args = expr->arguments(); |
| 2986 int arg_count = args->length(); | 2984 int arg_count = args->length(); |
| 2987 { PreservePositionScope scope(masm()->positions_recorder()); | 2985 for (int i = 0; i < arg_count; i++) { |
| 2988 for (int i = 0; i < arg_count; i++) { | 2986 VisitForStackValue(args->at(i)); |
| 2989 VisitForStackValue(args->at(i)); | |
| 2990 } | |
| 2991 } | 2987 } |
| 2992 | 2988 |
| 2993 // Record source position of the IC call. | 2989 SetExpressionPosition(expr); |
| 2994 SetSourcePosition(expr->position()); | |
| 2995 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); | 2990 Handle<Code> ic = CodeFactory::CallIC(isolate(), arg_count, call_type).code(); |
| 2996 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); | 2991 __ Move(edx, Immediate(SmiFromSlot(expr->CallFeedbackICSlot()))); |
| 2997 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 2992 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 2998 // Don't assign a type feedback id to the IC, since type feedback is provided | 2993 // Don't assign a type feedback id to the IC, since type feedback is provided |
| 2999 // by the vector above. | 2994 // by the vector above. |
| 3000 CallIC(ic); | 2995 CallIC(ic); |
| 3001 | 2996 |
| 3002 RecordJSReturnSite(expr); | 2997 RecordJSReturnSite(expr); |
| 3003 | 2998 |
| 3004 // Restore context register. | 2999 // Restore context register. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3044 | 3039 |
| 3045 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); | 3040 EmitVariableAssignment(this_var, Token::INIT_CONST, slot); |
| 3046 } | 3041 } |
| 3047 | 3042 |
| 3048 | 3043 |
| 3049 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. | 3044 // See http://www.ecma-international.org/ecma-262/6.0/#sec-function-calls. |
| 3050 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { | 3045 void FullCodeGenerator::PushCalleeAndWithBaseObject(Call* expr) { |
| 3051 VariableProxy* callee = expr->expression()->AsVariableProxy(); | 3046 VariableProxy* callee = expr->expression()->AsVariableProxy(); |
| 3052 if (callee->var()->IsLookupSlot()) { | 3047 if (callee->var()->IsLookupSlot()) { |
| 3053 Label slow, done; | 3048 Label slow, done; |
| 3054 SetSourcePosition(callee->position()); | 3049 SetExpressionPosition(callee); |
| 3055 { | 3050 // Generate code for loading from variables potentially shadowed by |
| 3056 PreservePositionScope scope(masm()->positions_recorder()); | 3051 // eval-introduced variables. |
| 3057 // Generate code for loading from variables potentially shadowed by | 3052 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); |
| 3058 // eval-introduced variables. | 3053 |
| 3059 EmitDynamicLookupFastCase(callee, NOT_INSIDE_TYPEOF, &slow, &done); | |
| 3060 } | |
| 3061 __ bind(&slow); | 3054 __ bind(&slow); |
| 3062 // Call the runtime to find the function to call (returned in eax) and | 3055 // Call the runtime to find the function to call (returned in eax) and |
| 3063 // the object holding it (returned in edx). | 3056 // the object holding it (returned in edx). |
| 3064 __ push(context_register()); | 3057 __ push(context_register()); |
| 3065 __ push(Immediate(callee->name())); | 3058 __ push(Immediate(callee->name())); |
| 3066 __ CallRuntime(Runtime::kLoadLookupSlot, 2); | 3059 __ CallRuntime(Runtime::kLoadLookupSlot, 2); |
| 3067 __ push(eax); // Function. | 3060 __ push(eax); // Function. |
| 3068 __ push(edx); // Receiver. | 3061 __ push(edx); // Receiver. |
| 3069 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); | 3062 PrepareForBailoutForId(expr->LookupId(), NO_REGISTERS); |
| 3070 | 3063 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 3099 Comment cmnt(masm_, "[ Call"); | 3092 Comment cmnt(masm_, "[ Call"); |
| 3100 Expression* callee = expr->expression(); | 3093 Expression* callee = expr->expression(); |
| 3101 Call::CallType call_type = expr->GetCallType(isolate()); | 3094 Call::CallType call_type = expr->GetCallType(isolate()); |
| 3102 | 3095 |
| 3103 if (call_type == Call::POSSIBLY_EVAL_CALL) { | 3096 if (call_type == Call::POSSIBLY_EVAL_CALL) { |
| 3104 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval | 3097 // In a call to eval, we first call RuntimeHidden_ResolvePossiblyDirectEval |
| 3105 // to resolve the function we need to call. Then we call the resolved | 3098 // to resolve the function we need to call. Then we call the resolved |
| 3106 // function using the given arguments. | 3099 // function using the given arguments. |
| 3107 ZoneList<Expression*>* args = expr->arguments(); | 3100 ZoneList<Expression*>* args = expr->arguments(); |
| 3108 int arg_count = args->length(); | 3101 int arg_count = args->length(); |
| 3109 { PreservePositionScope pos_scope(masm()->positions_recorder()); | |
| 3110 PushCalleeAndWithBaseObject(expr); | |
| 3111 | 3102 |
| 3112 // Push the arguments. | 3103 PushCalleeAndWithBaseObject(expr); |
| 3113 for (int i = 0; i < arg_count; i++) { | |
| 3114 VisitForStackValue(args->at(i)); | |
| 3115 } | |
| 3116 | 3104 |
| 3117 // Push a copy of the function (found below the arguments) and | 3105 // Push the arguments. |
| 3118 // resolve eval. | 3106 for (int i = 0; i < arg_count; i++) { |
| 3119 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); | 3107 VisitForStackValue(args->at(i)); |
| 3120 EmitResolvePossiblyDirectEval(arg_count); | 3108 } |
| 3121 | 3109 |
| 3122 // Touch up the stack with the resolved function. | 3110 // Push a copy of the function (found below the arguments) and |
| 3123 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); | 3111 // resolve eval. |
| 3112 __ push(Operand(esp, (arg_count + 1) * kPointerSize)); |
| 3113 EmitResolvePossiblyDirectEval(arg_count); |
| 3124 | 3114 |
| 3125 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); | 3115 // Touch up the stack with the resolved function. |
| 3126 } | 3116 __ mov(Operand(esp, (arg_count + 1) * kPointerSize), eax); |
| 3127 // Record source position for debugger. | 3117 |
| 3128 SetSourcePosition(expr->position()); | 3118 PrepareForBailoutForId(expr->EvalId(), NO_REGISTERS); |
| 3119 |
| 3120 SetExpressionPosition(expr); |
| 3129 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 3121 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 3130 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 3122 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 3131 __ CallStub(&stub); | 3123 __ CallStub(&stub); |
| 3132 RecordJSReturnSite(expr); | 3124 RecordJSReturnSite(expr); |
| 3133 // Restore context register. | 3125 // Restore context register. |
| 3134 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3126 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 3135 context()->DropAndPlug(1, eax); | 3127 context()->DropAndPlug(1, eax); |
| 3136 | 3128 |
| 3137 } else if (call_type == Call::GLOBAL_CALL) { | 3129 } else if (call_type == Call::GLOBAL_CALL) { |
| 3138 EmitCallWithLoadIC(expr); | 3130 EmitCallWithLoadIC(expr); |
| 3139 } else if (call_type == Call::LOOKUP_SLOT_CALL) { | 3131 } else if (call_type == Call::LOOKUP_SLOT_CALL) { |
| 3140 // Call to a lookup slot (dynamically introduced variable). | 3132 // Call to a lookup slot (dynamically introduced variable). |
| 3141 PushCalleeAndWithBaseObject(expr); | 3133 PushCalleeAndWithBaseObject(expr); |
| 3142 EmitCall(expr); | 3134 EmitCall(expr); |
| 3143 } else if (call_type == Call::PROPERTY_CALL) { | 3135 } else if (call_type == Call::PROPERTY_CALL) { |
| 3144 Property* property = callee->AsProperty(); | 3136 Property* property = callee->AsProperty(); |
| 3145 bool is_named_call = property->key()->IsPropertyName(); | 3137 bool is_named_call = property->key()->IsPropertyName(); |
| 3146 if (property->IsSuperAccess()) { | 3138 if (property->IsSuperAccess()) { |
| 3147 if (is_named_call) { | 3139 if (is_named_call) { |
| 3148 EmitSuperCallWithLoadIC(expr); | 3140 EmitSuperCallWithLoadIC(expr); |
| 3149 } else { | 3141 } else { |
| 3150 EmitKeyedSuperCallWithLoadIC(expr); | 3142 EmitKeyedSuperCallWithLoadIC(expr); |
| 3151 } | 3143 } |
| 3152 } else { | 3144 } else { |
| 3153 { | 3145 VisitForStackValue(property->obj()); |
| 3154 PreservePositionScope scope(masm()->positions_recorder()); | |
| 3155 VisitForStackValue(property->obj()); | |
| 3156 } | |
| 3157 if (is_named_call) { | 3146 if (is_named_call) { |
| 3158 EmitCallWithLoadIC(expr); | 3147 EmitCallWithLoadIC(expr); |
| 3159 } else { | 3148 } else { |
| 3160 EmitKeyedCallWithLoadIC(expr, property->key()); | 3149 EmitKeyedCallWithLoadIC(expr, property->key()); |
| 3161 } | 3150 } |
| 3162 } | 3151 } |
| 3163 } else if (call_type == Call::SUPER_CALL) { | 3152 } else if (call_type == Call::SUPER_CALL) { |
| 3164 EmitSuperConstructorCall(expr); | 3153 EmitSuperConstructorCall(expr); |
| 3165 } else { | 3154 } else { |
| 3166 DCHECK(call_type == Call::OTHER_CALL); | 3155 DCHECK(call_type == Call::OTHER_CALL); |
| 3167 // Call to an arbitrary expression not handled specially above. | 3156 // Call to an arbitrary expression not handled specially above. |
| 3168 { PreservePositionScope scope(masm()->positions_recorder()); | 3157 VisitForStackValue(callee); |
| 3169 VisitForStackValue(callee); | |
| 3170 } | |
| 3171 __ push(Immediate(isolate()->factory()->undefined_value())); | 3158 __ push(Immediate(isolate()->factory()->undefined_value())); |
| 3172 // Emit function call. | 3159 // Emit function call. |
| 3173 EmitCall(expr); | 3160 EmitCall(expr); |
| 3174 } | 3161 } |
| 3175 | 3162 |
| 3176 #ifdef DEBUG | 3163 #ifdef DEBUG |
| 3177 // RecordJSReturnSite should have been called. | 3164 // RecordJSReturnSite should have been called. |
| 3178 DCHECK(expr->return_is_recorded_); | 3165 DCHECK(expr->return_is_recorded_); |
| 3179 #endif | 3166 #endif |
| 3180 } | 3167 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3194 | 3181 |
| 3195 // Push the arguments ("left-to-right") on the stack. | 3182 // Push the arguments ("left-to-right") on the stack. |
| 3196 ZoneList<Expression*>* args = expr->arguments(); | 3183 ZoneList<Expression*>* args = expr->arguments(); |
| 3197 int arg_count = args->length(); | 3184 int arg_count = args->length(); |
| 3198 for (int i = 0; i < arg_count; i++) { | 3185 for (int i = 0; i < arg_count; i++) { |
| 3199 VisitForStackValue(args->at(i)); | 3186 VisitForStackValue(args->at(i)); |
| 3200 } | 3187 } |
| 3201 | 3188 |
| 3202 // Call the construct call builtin that handles allocation and | 3189 // Call the construct call builtin that handles allocation and |
| 3203 // constructor invocation. | 3190 // constructor invocation. |
| 3204 SetSourcePosition(expr->position()); | 3191 SetExpressionPosition(expr); |
| 3205 | 3192 |
| 3206 // Load function and argument count into edi and eax. | 3193 // Load function and argument count into edi and eax. |
| 3207 __ Move(eax, Immediate(arg_count)); | 3194 __ Move(eax, Immediate(arg_count)); |
| 3208 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 3195 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
| 3209 | 3196 |
| 3210 // Record call targets in unoptimized code. | 3197 // Record call targets in unoptimized code. |
| 3211 if (FLAG_pretenuring_call_new) { | 3198 if (FLAG_pretenuring_call_new) { |
| 3212 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3199 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
| 3213 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == | 3200 DCHECK(expr->AllocationSiteFeedbackSlot().ToInt() == |
| 3214 expr->CallNewFeedbackSlot().ToInt() + 1); | 3201 expr->CallNewFeedbackSlot().ToInt() + 1); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 3237 | 3224 |
| 3238 // Push the arguments ("left-to-right") on the stack. | 3225 // Push the arguments ("left-to-right") on the stack. |
| 3239 ZoneList<Expression*>* args = expr->arguments(); | 3226 ZoneList<Expression*>* args = expr->arguments(); |
| 3240 int arg_count = args->length(); | 3227 int arg_count = args->length(); |
| 3241 for (int i = 0; i < arg_count; i++) { | 3228 for (int i = 0; i < arg_count; i++) { |
| 3242 VisitForStackValue(args->at(i)); | 3229 VisitForStackValue(args->at(i)); |
| 3243 } | 3230 } |
| 3244 | 3231 |
| 3245 // Call the construct call builtin that handles allocation and | 3232 // Call the construct call builtin that handles allocation and |
| 3246 // constructor invocation. | 3233 // constructor invocation. |
| 3247 SetSourcePosition(expr->position()); | 3234 SetExpressionPosition(expr); |
| 3248 | 3235 |
| 3249 // Load function and argument count into edi and eax. | 3236 // Load function and argument count into edi and eax. |
| 3250 __ Move(eax, Immediate(arg_count)); | 3237 __ Move(eax, Immediate(arg_count)); |
| 3251 __ mov(edi, Operand(esp, arg_count * kPointerSize)); | 3238 __ mov(edi, Operand(esp, arg_count * kPointerSize)); |
| 3252 | 3239 |
| 3253 // Record call targets in unoptimized code. | 3240 // Record call targets in unoptimized code. |
| 3254 if (FLAG_pretenuring_call_new) { | 3241 if (FLAG_pretenuring_call_new) { |
| 3255 UNREACHABLE(); | 3242 UNREACHABLE(); |
| 3256 /* TODO(dslomov): support pretenuring. | 3243 /* TODO(dslomov): support pretenuring. |
| 3257 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); | 3244 EnsureSlotContainsAllocationSite(expr->AllocationSiteFeedbackSlot()); |
| (...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4660 __ mov(LoadDescriptor::SlotRegister(), | 4647 __ mov(LoadDescriptor::SlotRegister(), |
| 4661 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); | 4648 Immediate(SmiFromSlot(expr->CallRuntimeFeedbackSlot()))); |
| 4662 CallLoadIC(NOT_CONTEXTUAL); | 4649 CallLoadIC(NOT_CONTEXTUAL); |
| 4663 } | 4650 } |
| 4664 | 4651 |
| 4665 | 4652 |
| 4666 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { | 4653 void FullCodeGenerator::EmitCallJSRuntimeFunction(CallRuntime* expr) { |
| 4667 ZoneList<Expression*>* args = expr->arguments(); | 4654 ZoneList<Expression*>* args = expr->arguments(); |
| 4668 int arg_count = args->length(); | 4655 int arg_count = args->length(); |
| 4669 | 4656 |
| 4670 // Record source position of the IC call. | 4657 SetExpressionPosition(expr); |
| 4671 SetSourcePosition(expr->position()); | |
| 4672 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); | 4658 CallFunctionStub stub(isolate(), arg_count, NO_CALL_FUNCTION_FLAGS); |
| 4673 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); | 4659 __ mov(edi, Operand(esp, (arg_count + 1) * kPointerSize)); |
| 4674 __ CallStub(&stub); | 4660 __ CallStub(&stub); |
| 4675 } | 4661 } |
| 4676 | 4662 |
| 4677 | 4663 |
| 4678 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 4664 void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 4679 ZoneList<Expression*>* args = expr->arguments(); | 4665 ZoneList<Expression*>* args = expr->arguments(); |
| 4680 int arg_count = args->length(); | 4666 int arg_count = args->length(); |
| 4681 | 4667 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4841 default: | 4827 default: |
| 4842 UNREACHABLE(); | 4828 UNREACHABLE(); |
| 4843 } | 4829 } |
| 4844 } | 4830 } |
| 4845 | 4831 |
| 4846 | 4832 |
| 4847 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { | 4833 void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { |
| 4848 DCHECK(expr->expression()->IsValidReferenceExpression()); | 4834 DCHECK(expr->expression()->IsValidReferenceExpression()); |
| 4849 | 4835 |
| 4850 Comment cmnt(masm_, "[ CountOperation"); | 4836 Comment cmnt(masm_, "[ CountOperation"); |
| 4851 SetSourcePosition(expr->position()); | |
| 4852 | 4837 |
| 4853 Property* prop = expr->expression()->AsProperty(); | 4838 Property* prop = expr->expression()->AsProperty(); |
| 4854 LhsKind assign_type = Property::GetAssignType(prop); | 4839 LhsKind assign_type = Property::GetAssignType(prop); |
| 4855 | 4840 |
| 4856 // Evaluate expression and get value. | 4841 // Evaluate expression and get value. |
| 4857 if (assign_type == VARIABLE) { | 4842 if (assign_type == VARIABLE) { |
| 4858 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); | 4843 DCHECK(expr->expression()->AsVariableProxy()->var() != NULL); |
| 4859 AccumulatorValueContext context(this); | 4844 AccumulatorValueContext context(this); |
| 4860 EmitVariableLoad(expr->expression()->AsVariableProxy()); | 4845 EmitVariableLoad(expr->expression()->AsVariableProxy()); |
| 4861 } else { | 4846 } else { |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4992 case KEYED_PROPERTY: | 4977 case KEYED_PROPERTY: |
| 4993 __ mov(Operand(esp, 2 * kPointerSize), eax); | 4978 __ mov(Operand(esp, 2 * kPointerSize), eax); |
| 4994 break; | 4979 break; |
| 4995 case KEYED_SUPER_PROPERTY: | 4980 case KEYED_SUPER_PROPERTY: |
| 4996 __ mov(Operand(esp, 3 * kPointerSize), eax); | 4981 __ mov(Operand(esp, 3 * kPointerSize), eax); |
| 4997 break; | 4982 break; |
| 4998 } | 4983 } |
| 4999 } | 4984 } |
| 5000 } | 4985 } |
| 5001 | 4986 |
| 5002 // Record position before stub call. | 4987 SetExpressionPosition(expr); |
| 5003 SetSourcePosition(expr->position()); | |
| 5004 | 4988 |
| 5005 // Call stub for +1/-1. | 4989 // Call stub for +1/-1. |
| 5006 __ bind(&stub_call); | 4990 __ bind(&stub_call); |
| 5007 __ mov(edx, eax); | 4991 __ mov(edx, eax); |
| 5008 __ mov(eax, Immediate(Smi::FromInt(1))); | 4992 __ mov(eax, Immediate(Smi::FromInt(1))); |
| 5009 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), | 4993 Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(), |
| 5010 strength(language_mode())).code(); | 4994 strength(language_mode())).code(); |
| 5011 CallIC(code, expr->CountBinOpFeedbackId()); | 4995 CallIC(code, expr->CountBinOpFeedbackId()); |
| 5012 patch_site.EmitPatchInfo(); | 4996 patch_site.EmitPatchInfo(); |
| 5013 __ bind(&done); | 4997 __ bind(&done); |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5214 Split(zero, if_true, if_false, fall_through); | 5198 Split(zero, if_true, if_false, fall_through); |
| 5215 } else { | 5199 } else { |
| 5216 if (if_false != fall_through) __ jmp(if_false); | 5200 if (if_false != fall_through) __ jmp(if_false); |
| 5217 } | 5201 } |
| 5218 context()->Plug(if_true, if_false); | 5202 context()->Plug(if_true, if_false); |
| 5219 } | 5203 } |
| 5220 | 5204 |
| 5221 | 5205 |
| 5222 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { | 5206 void FullCodeGenerator::VisitCompareOperation(CompareOperation* expr) { |
| 5223 Comment cmnt(masm_, "[ CompareOperation"); | 5207 Comment cmnt(masm_, "[ CompareOperation"); |
| 5224 SetSourcePosition(expr->position()); | 5208 SetExpressionPosition(expr); |
| 5225 | 5209 |
| 5226 // First we try a fast inlined version of the compare when one of | 5210 // First we try a fast inlined version of the compare when one of |
| 5227 // the operands is a literal. | 5211 // the operands is a literal. |
| 5228 if (TryLiteralCompare(expr)) return; | 5212 if (TryLiteralCompare(expr)) return; |
| 5229 | 5213 |
| 5230 // Always perform the comparison for its control flow. Pack the result | 5214 // Always perform the comparison for its control flow. Pack the result |
| 5231 // into the expression's context after the comparison is performed. | 5215 // into the expression's context after the comparison is performed. |
| 5232 Label materialize_true, materialize_false; | 5216 Label materialize_true, materialize_false; |
| 5233 Label* if_true = NULL; | 5217 Label* if_true = NULL; |
| 5234 Label* if_false = NULL; | 5218 Label* if_false = NULL; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5268 if (inline_smi_code) { | 5252 if (inline_smi_code) { |
| 5269 Label slow_case; | 5253 Label slow_case; |
| 5270 __ mov(ecx, edx); | 5254 __ mov(ecx, edx); |
| 5271 __ or_(ecx, eax); | 5255 __ or_(ecx, eax); |
| 5272 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); | 5256 patch_site.EmitJumpIfNotSmi(ecx, &slow_case, Label::kNear); |
| 5273 __ cmp(edx, eax); | 5257 __ cmp(edx, eax); |
| 5274 Split(cc, if_true, if_false, NULL); | 5258 Split(cc, if_true, if_false, NULL); |
| 5275 __ bind(&slow_case); | 5259 __ bind(&slow_case); |
| 5276 } | 5260 } |
| 5277 | 5261 |
| 5278 // Record position and call the compare IC. | |
| 5279 SetSourcePosition(expr->position()); | |
| 5280 Handle<Code> ic = CodeFactory::CompareIC( | 5262 Handle<Code> ic = CodeFactory::CompareIC( |
| 5281 isolate(), op, strength(language_mode())).code(); | 5263 isolate(), op, strength(language_mode())).code(); |
| 5282 CallIC(ic, expr->CompareOperationFeedbackId()); | 5264 CallIC(ic, expr->CompareOperationFeedbackId()); |
| 5283 patch_site.EmitPatchInfo(); | 5265 patch_site.EmitPatchInfo(); |
| 5284 | 5266 |
| 5285 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); | 5267 PrepareForBailoutBeforeSplit(expr, true, if_true, if_false); |
| 5286 __ test(eax, eax); | 5268 __ test(eax, eax); |
| 5287 Split(cc, if_true, if_false, fall_through); | 5269 Split(cc, if_true, if_false, fall_through); |
| 5288 } | 5270 } |
| 5289 } | 5271 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5509 Assembler::target_address_at(call_target_address, | 5491 Assembler::target_address_at(call_target_address, |
| 5510 unoptimized_code)); | 5492 unoptimized_code)); |
| 5511 return OSR_AFTER_STACK_CHECK; | 5493 return OSR_AFTER_STACK_CHECK; |
| 5512 } | 5494 } |
| 5513 | 5495 |
| 5514 | 5496 |
| 5515 } // namespace internal | 5497 } // namespace internal |
| 5516 } // namespace v8 | 5498 } // namespace v8 |
| 5517 | 5499 |
| 5518 #endif // V8_TARGET_ARCH_IA32 | 5500 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |