OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 723 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
734 VisitForAccumulatorValue(function); | 734 VisitForAccumulatorValue(function); |
735 __ pop(edx); | 735 __ pop(edx); |
736 } else { | 736 } else { |
737 __ mov(edx, eax); | 737 __ mov(edx, eax); |
738 __ mov(eax, Factory::the_hole_value()); | 738 __ mov(eax, Factory::the_hole_value()); |
739 } | 739 } |
740 ASSERT(prop->key()->AsLiteral() != NULL && | 740 ASSERT(prop->key()->AsLiteral() != NULL && |
741 prop->key()->AsLiteral()->handle()->IsSmi()); | 741 prop->key()->AsLiteral()->handle()->IsSmi()); |
742 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 742 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
743 | 743 |
744 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 744 Handle<Code> ic(Builtins::builtin(is_strict() |
| 745 ? Builtins::KeyedStoreIC_Initialize_Strict |
| 746 : Builtins::KeyedStoreIC_Initialize)); |
745 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 747 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
746 } | 748 } |
747 } | 749 } |
748 } | 750 } |
749 | 751 |
750 | 752 |
751 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { | 753 void FullCodeGenerator::VisitDeclaration(Declaration* decl) { |
752 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); | 754 EmitDeclaration(decl->proxy()->var(), decl->mode(), decl->fun()); |
753 } | 755 } |
754 | 756 |
755 | 757 |
756 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { | 758 void FullCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) { |
757 // Call the runtime to declare the globals. | 759 // Call the runtime to declare the globals. |
758 __ push(esi); // The context is the first argument. | 760 __ push(esi); // The context is the first argument. |
759 __ push(Immediate(pairs)); | 761 __ push(Immediate(pairs)); |
760 __ push(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); | 762 __ push(Immediate(Smi::FromInt(is_eval() ? 1 : 0))); |
761 __ CallRuntime(Runtime::kDeclareGlobals, 3); | 763 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); |
| 764 __ CallRuntime(Runtime::kDeclareGlobals, 4); |
762 // Return value is ignored. | 765 // Return value is ignored. |
763 } | 766 } |
764 | 767 |
765 | 768 |
766 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { | 769 void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { |
767 Comment cmnt(masm_, "[ SwitchStatement"); | 770 Comment cmnt(masm_, "[ SwitchStatement"); |
768 Breakable nested_statement(this, stmt); | 771 Breakable nested_statement(this, stmt); |
769 SetStatementPosition(stmt); | 772 SetStatementPosition(stmt); |
770 | 773 |
771 // Keep the switch value on the stack until a case matches. | 774 // Keep the switch value on the stack until a case matches. |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 switch (property->kind()) { | 1376 switch (property->kind()) { |
1374 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1377 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
1375 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 1378 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
1376 // Fall through. | 1379 // Fall through. |
1377 case ObjectLiteral::Property::COMPUTED: | 1380 case ObjectLiteral::Property::COMPUTED: |
1378 if (key->handle()->IsSymbol()) { | 1381 if (key->handle()->IsSymbol()) { |
1379 if (property->emit_store()) { | 1382 if (property->emit_store()) { |
1380 VisitForAccumulatorValue(value); | 1383 VisitForAccumulatorValue(value); |
1381 __ mov(ecx, Immediate(key->handle())); | 1384 __ mov(ecx, Immediate(key->handle())); |
1382 __ mov(edx, Operand(esp, 0)); | 1385 __ mov(edx, Operand(esp, 0)); |
1383 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1386 Handle<Code> ic(Builtins::builtin( |
| 1387 is_strict() ? Builtins::StoreIC_Initialize_Strict |
| 1388 : Builtins::StoreIC_Initialize)); |
1384 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1389 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1385 PrepareForBailoutForId(key->id(), NO_REGISTERS); | 1390 PrepareForBailoutForId(key->id(), NO_REGISTERS); |
1386 } else { | 1391 } else { |
1387 VisitForEffect(value); | 1392 VisitForEffect(value); |
1388 } | 1393 } |
1389 break; | 1394 break; |
1390 } | 1395 } |
1391 // Fall through. | 1396 // Fall through. |
1392 case ObjectLiteral::Property::PROTOTYPE: | 1397 case ObjectLiteral::Property::PROTOTYPE: |
1393 __ push(Operand(esp, 0)); // Duplicate receiver. | 1398 __ push(Operand(esp, 0)); // Duplicate receiver. |
1394 VisitForStackValue(key); | 1399 VisitForStackValue(key); |
1395 VisitForStackValue(value); | 1400 VisitForStackValue(value); |
1396 if (property->emit_store()) { | 1401 if (property->emit_store()) { |
1397 __ CallRuntime(Runtime::kSetProperty, 3); | 1402 __ push(Immediate(Smi::FromInt(NONE))); // PropertyAttributes |
| 1403 __ CallRuntime(Runtime::kSetProperty, 4); |
1398 } else { | 1404 } else { |
1399 __ Drop(3); | 1405 __ Drop(3); |
1400 } | 1406 } |
1401 break; | 1407 break; |
1402 case ObjectLiteral::Property::SETTER: | 1408 case ObjectLiteral::Property::SETTER: |
1403 case ObjectLiteral::Property::GETTER: | 1409 case ObjectLiteral::Property::GETTER: |
1404 __ push(Operand(esp, 0)); // Duplicate receiver. | 1410 __ push(Operand(esp, 0)); // Duplicate receiver. |
1405 VisitForStackValue(key); | 1411 VisitForStackValue(key); |
1406 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? | 1412 __ push(Immediate(property->kind() == ObjectLiteral::Property::SETTER ? |
1407 Smi::FromInt(1) : | 1413 Smi::FromInt(1) : |
(...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1978 EffectContext context(this); | 1984 EffectContext context(this); |
1979 EmitVariableAssignment(var, Token::ASSIGN); | 1985 EmitVariableAssignment(var, Token::ASSIGN); |
1980 break; | 1986 break; |
1981 } | 1987 } |
1982 case NAMED_PROPERTY: { | 1988 case NAMED_PROPERTY: { |
1983 __ push(eax); // Preserve value. | 1989 __ push(eax); // Preserve value. |
1984 VisitForAccumulatorValue(prop->obj()); | 1990 VisitForAccumulatorValue(prop->obj()); |
1985 __ mov(edx, eax); | 1991 __ mov(edx, eax); |
1986 __ pop(eax); // Restore value. | 1992 __ pop(eax); // Restore value. |
1987 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1993 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
1988 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1994 Handle<Code> ic(Builtins::builtin( |
| 1995 is_strict() ? Builtins::StoreIC_Initialize_Strict |
| 1996 : Builtins::StoreIC_Initialize)); |
1989 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 1997 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
1990 break; | 1998 break; |
1991 } | 1999 } |
1992 case KEYED_PROPERTY: { | 2000 case KEYED_PROPERTY: { |
1993 __ push(eax); // Preserve value. | 2001 __ push(eax); // Preserve value. |
1994 if (prop->is_synthetic()) { | 2002 if (prop->is_synthetic()) { |
1995 ASSERT(prop->obj()->AsVariableProxy() != NULL); | 2003 ASSERT(prop->obj()->AsVariableProxy() != NULL); |
1996 ASSERT(prop->key()->AsLiteral() != NULL); | 2004 ASSERT(prop->key()->AsLiteral() != NULL); |
1997 { AccumulatorValueContext for_object(this); | 2005 { AccumulatorValueContext for_object(this); |
1998 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); | 2006 EmitVariableLoad(prop->obj()->AsVariableProxy()->var()); |
1999 } | 2007 } |
2000 __ mov(edx, eax); | 2008 __ mov(edx, eax); |
2001 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); | 2009 __ Set(ecx, Immediate(prop->key()->AsLiteral()->handle())); |
2002 } else { | 2010 } else { |
2003 VisitForStackValue(prop->obj()); | 2011 VisitForStackValue(prop->obj()); |
2004 VisitForAccumulatorValue(prop->key()); | 2012 VisitForAccumulatorValue(prop->key()); |
2005 __ mov(ecx, eax); | 2013 __ mov(ecx, eax); |
2006 __ pop(edx); | 2014 __ pop(edx); |
2007 } | 2015 } |
2008 __ pop(eax); // Restore value. | 2016 __ pop(eax); // Restore value. |
2009 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 2017 Handle<Code> ic(Builtins::builtin( |
| 2018 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 2019 : Builtins::KeyedStoreIC_Initialize)); |
2010 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2020 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
2011 break; | 2021 break; |
2012 } | 2022 } |
2013 } | 2023 } |
2014 PrepareForBailoutForId(bailout_ast_id, TOS_REG); | 2024 PrepareForBailoutForId(bailout_ast_id, TOS_REG); |
2015 context()->Plug(eax); | 2025 context()->Plug(eax); |
2016 } | 2026 } |
2017 | 2027 |
2018 | 2028 |
2019 void FullCodeGenerator::EmitVariableAssignment(Variable* var, | 2029 void FullCodeGenerator::EmitVariableAssignment(Variable* var, |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2094 int offset = Context::SlotOffset(slot->index()); | 2104 int offset = Context::SlotOffset(slot->index()); |
2095 __ RecordWrite(ecx, offset, edx, ebx); | 2105 __ RecordWrite(ecx, offset, edx, ebx); |
2096 break; | 2106 break; |
2097 } | 2107 } |
2098 | 2108 |
2099 case Slot::LOOKUP: | 2109 case Slot::LOOKUP: |
2100 // Call the runtime for the assignment. | 2110 // Call the runtime for the assignment. |
2101 __ push(eax); // Value. | 2111 __ push(eax); // Value. |
2102 __ push(esi); // Context. | 2112 __ push(esi); // Context. |
2103 __ push(Immediate(var->name())); | 2113 __ push(Immediate(var->name())); |
2104 __ CallRuntime(Runtime::kStoreContextSlot, 3); | 2114 __ push(Immediate(Smi::FromInt(strict_mode_flag()))); |
| 2115 __ CallRuntime(Runtime::kStoreContextSlot, 4); |
2105 break; | 2116 break; |
2106 } | 2117 } |
2107 } | 2118 } |
2108 } | 2119 } |
2109 | 2120 |
2110 | 2121 |
2111 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { | 2122 void FullCodeGenerator::EmitNamedPropertyAssignment(Assignment* expr) { |
2112 // Assignment to a property, using a named store IC. | 2123 // Assignment to a property, using a named store IC. |
2113 Property* prop = expr->target()->AsProperty(); | 2124 Property* prop = expr->target()->AsProperty(); |
2114 ASSERT(prop != NULL); | 2125 ASSERT(prop != NULL); |
(...skipping 10 matching lines...) Expand all Loading... |
2125 } | 2136 } |
2126 | 2137 |
2127 // Record source code position before IC call. | 2138 // Record source code position before IC call. |
2128 SetSourcePosition(expr->position()); | 2139 SetSourcePosition(expr->position()); |
2129 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 2140 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
2130 if (expr->ends_initialization_block()) { | 2141 if (expr->ends_initialization_block()) { |
2131 __ mov(edx, Operand(esp, 0)); | 2142 __ mov(edx, Operand(esp, 0)); |
2132 } else { | 2143 } else { |
2133 __ pop(edx); | 2144 __ pop(edx); |
2134 } | 2145 } |
2135 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 2146 Handle<Code> ic(Builtins::builtin( |
| 2147 is_strict() ? Builtins::StoreIC_Initialize_Strict |
| 2148 : Builtins::StoreIC_Initialize)); |
2136 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2149 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
2137 | 2150 |
2138 // If the assignment ends an initialization block, revert to fast case. | 2151 // If the assignment ends an initialization block, revert to fast case. |
2139 if (expr->ends_initialization_block()) { | 2152 if (expr->ends_initialization_block()) { |
2140 __ push(eax); // Result of assignment, saved even if not needed. | 2153 __ push(eax); // Result of assignment, saved even if not needed. |
2141 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 2154 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
2142 __ CallRuntime(Runtime::kToFastProperties, 1); | 2155 __ CallRuntime(Runtime::kToFastProperties, 1); |
2143 __ pop(eax); | 2156 __ pop(eax); |
2144 __ Drop(1); | 2157 __ Drop(1); |
2145 } | 2158 } |
(...skipping 17 matching lines...) Expand all Loading... |
2163 } | 2176 } |
2164 | 2177 |
2165 __ pop(ecx); | 2178 __ pop(ecx); |
2166 if (expr->ends_initialization_block()) { | 2179 if (expr->ends_initialization_block()) { |
2167 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. | 2180 __ mov(edx, Operand(esp, 0)); // Leave receiver on the stack for later. |
2168 } else { | 2181 } else { |
2169 __ pop(edx); | 2182 __ pop(edx); |
2170 } | 2183 } |
2171 // Record source code position before IC call. | 2184 // Record source code position before IC call. |
2172 SetSourcePosition(expr->position()); | 2185 SetSourcePosition(expr->position()); |
2173 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 2186 Handle<Code> ic(Builtins::builtin( |
| 2187 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 2188 : Builtins::KeyedStoreIC_Initialize)); |
2174 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 2189 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
2175 | 2190 |
2176 // If the assignment ends an initialization block, revert to fast case. | 2191 // If the assignment ends an initialization block, revert to fast case. |
2177 if (expr->ends_initialization_block()) { | 2192 if (expr->ends_initialization_block()) { |
2178 __ pop(edx); | 2193 __ pop(edx); |
2179 __ push(eax); // Result of assignment, saved even if not needed. | 2194 __ push(eax); // Result of assignment, saved even if not needed. |
2180 __ push(edx); | 2195 __ push(edx); |
2181 __ CallRuntime(Runtime::kToFastProperties, 1); | 2196 __ CallRuntime(Runtime::kToFastProperties, 1); |
2182 __ pop(eax); | 2197 __ pop(eax); |
2183 } | 2198 } |
(...skipping 1834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4018 // Perform the assignment as if via '='. | 4033 // Perform the assignment as if via '='. |
4019 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 4034 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
4020 Token::ASSIGN); | 4035 Token::ASSIGN); |
4021 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4036 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4022 context()->Plug(eax); | 4037 context()->Plug(eax); |
4023 } | 4038 } |
4024 break; | 4039 break; |
4025 case NAMED_PROPERTY: { | 4040 case NAMED_PROPERTY: { |
4026 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 4041 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
4027 __ pop(edx); | 4042 __ pop(edx); |
4028 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 4043 Handle<Code> ic(Builtins::builtin( |
| 4044 is_strict() ? Builtins::StoreIC_Initialize_Strict |
| 4045 : Builtins::StoreIC_Initialize)); |
4029 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 4046 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
4030 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4047 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4031 if (expr->is_postfix()) { | 4048 if (expr->is_postfix()) { |
4032 if (!context()->IsEffect()) { | 4049 if (!context()->IsEffect()) { |
4033 context()->PlugTOS(); | 4050 context()->PlugTOS(); |
4034 } | 4051 } |
4035 } else { | 4052 } else { |
4036 context()->Plug(eax); | 4053 context()->Plug(eax); |
4037 } | 4054 } |
4038 break; | 4055 break; |
4039 } | 4056 } |
4040 case KEYED_PROPERTY: { | 4057 case KEYED_PROPERTY: { |
4041 __ pop(ecx); | 4058 __ pop(ecx); |
4042 __ pop(edx); | 4059 __ pop(edx); |
4043 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 4060 Handle<Code> ic(Builtins::builtin( |
| 4061 is_strict() ? Builtins::KeyedStoreIC_Initialize_Strict |
| 4062 : Builtins::KeyedStoreIC_Initialize)); |
4044 EmitCallIC(ic, RelocInfo::CODE_TARGET); | 4063 EmitCallIC(ic, RelocInfo::CODE_TARGET); |
4045 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); | 4064 PrepareForBailoutForId(expr->AssignmentId(), TOS_REG); |
4046 if (expr->is_postfix()) { | 4065 if (expr->is_postfix()) { |
4047 // Result is on the stack | 4066 // Result is on the stack |
4048 if (!context()->IsEffect()) { | 4067 if (!context()->IsEffect()) { |
4049 context()->PlugTOS(); | 4068 context()->PlugTOS(); |
4050 } | 4069 } |
4051 } else { | 4070 } else { |
4052 context()->Plug(eax); | 4071 context()->Plug(eax); |
4053 } | 4072 } |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4453 // And return. | 4472 // And return. |
4454 __ ret(0); | 4473 __ ret(0); |
4455 } | 4474 } |
4456 | 4475 |
4457 | 4476 |
4458 #undef __ | 4477 #undef __ |
4459 | 4478 |
4460 } } // namespace v8::internal | 4479 } } // namespace v8::internal |
4461 | 4480 |
4462 #endif // V8_TARGET_ARCH_IA32 | 4481 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |