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