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 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
910 result_saved = true; | 910 result_saved = true; |
911 } | 911 } |
912 switch (property->kind()) { | 912 switch (property->kind()) { |
913 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 913 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
914 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); | 914 ASSERT(!CompileTimeValue::IsCompileTimeValue(value)); |
915 // Fall through. | 915 // Fall through. |
916 case ObjectLiteral::Property::COMPUTED: | 916 case ObjectLiteral::Property::COMPUTED: |
917 if (key->handle()->IsSymbol()) { | 917 if (key->handle()->IsSymbol()) { |
918 VisitForValue(value, kAccumulator); | 918 VisitForValue(value, kAccumulator); |
919 __ mov(ecx, Immediate(key->handle())); | 919 __ mov(ecx, Immediate(key->handle())); |
| 920 __ mov(edx, Operand(esp, 0)); |
920 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 921 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
921 __ call(ic, RelocInfo::CODE_TARGET); | 922 __ call(ic, RelocInfo::CODE_TARGET); |
922 __ nop(); | 923 __ nop(); |
923 // StoreIC leaves the receiver on the stack. | |
924 break; | 924 break; |
925 } | 925 } |
926 // Fall through. | 926 // Fall through. |
927 case ObjectLiteral::Property::PROTOTYPE: | 927 case ObjectLiteral::Property::PROTOTYPE: |
928 __ push(Operand(esp, 0)); // Duplicate receiver. | 928 __ push(Operand(esp, 0)); // Duplicate receiver. |
929 VisitForValue(key, kStack); | 929 VisitForValue(key, kStack); |
930 VisitForValue(value, kStack); | 930 VisitForValue(value, kStack); |
931 __ CallRuntime(Runtime::kSetProperty, 3); | 931 __ CallRuntime(Runtime::kSetProperty, 3); |
932 break; | 932 break; |
933 case ObjectLiteral::Property::SETTER: | 933 case ObjectLiteral::Property::SETTER: |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1039 ASSERT(var != NULL); | 1039 ASSERT(var != NULL); |
1040 ASSERT(var->is_global() || var->slot() != NULL); | 1040 ASSERT(var->is_global() || var->slot() != NULL); |
1041 | 1041 |
1042 Slot* slot = var->slot(); | 1042 Slot* slot = var->slot(); |
1043 if (var->is_global()) { | 1043 if (var->is_global()) { |
1044 ASSERT(!var->is_this()); | 1044 ASSERT(!var->is_this()); |
1045 // Assignment to a global variable. Use inline caching for the | 1045 // Assignment to a global variable. Use inline caching for the |
1046 // assignment. Right-hand-side value is passed in eax, variable name in | 1046 // assignment. Right-hand-side value is passed in eax, variable name in |
1047 // ecx, and the global object on the stack. | 1047 // ecx, and the global object on the stack. |
1048 __ mov(ecx, var->name()); | 1048 __ mov(ecx, var->name()); |
1049 __ push(CodeGenerator::GlobalObject()); | 1049 __ mov(edx, CodeGenerator::GlobalObject()); |
1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1050 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1051 __ call(ic, RelocInfo::CODE_TARGET); | 1051 __ call(ic, RelocInfo::CODE_TARGET); |
1052 __ nop(); | 1052 __ nop(); |
1053 // Overwrite the receiver on the stack with the result if needed. | 1053 Apply(context, eax); |
1054 DropAndApply(1, context, eax); | |
1055 | 1054 |
1056 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { | 1055 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
1057 __ push(result_register()); // Value. | 1056 __ push(result_register()); // Value. |
1058 __ push(esi); // Context. | 1057 __ push(esi); // Context. |
1059 __ push(Immediate(var->name())); | 1058 __ push(Immediate(var->name())); |
1060 __ CallRuntime(Runtime::kStoreContextSlot, 3); | 1059 __ CallRuntime(Runtime::kStoreContextSlot, 3); |
1061 Apply(context, eax); | 1060 Apply(context, eax); |
1062 | 1061 |
1063 } else if (slot != NULL) { | 1062 } else if (slot != NULL) { |
1064 switch (slot->type()) { | 1063 switch (slot->type()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 if (expr->starts_initialization_block()) { | 1103 if (expr->starts_initialization_block()) { |
1105 __ push(result_register()); | 1104 __ push(result_register()); |
1106 __ push(Operand(esp, kPointerSize)); // Receiver is now under value. | 1105 __ push(Operand(esp, kPointerSize)); // Receiver is now under value. |
1107 __ CallRuntime(Runtime::kToSlowProperties, 1); | 1106 __ CallRuntime(Runtime::kToSlowProperties, 1); |
1108 __ pop(result_register()); | 1107 __ pop(result_register()); |
1109 } | 1108 } |
1110 | 1109 |
1111 // Record source code position before IC call. | 1110 // Record source code position before IC call. |
1112 SetSourcePosition(expr->position()); | 1111 SetSourcePosition(expr->position()); |
1113 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1112 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1113 if (expr->ends_initialization_block()) { |
| 1114 __ mov(edx, Operand(esp, 0)); |
| 1115 } else { |
| 1116 __ pop(edx); |
| 1117 } |
1114 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1118 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1115 __ call(ic, RelocInfo::CODE_TARGET); | 1119 __ call(ic, RelocInfo::CODE_TARGET); |
1116 __ nop(); | 1120 __ nop(); |
1117 | 1121 |
1118 // If the assignment ends an initialization block, revert to fast case. | 1122 // If the assignment ends an initialization block, revert to fast case. |
1119 if (expr->ends_initialization_block()) { | 1123 if (expr->ends_initialization_block()) { |
1120 __ push(eax); // Result of assignment, saved even if not needed. | 1124 __ push(eax); // Result of assignment, saved even if not needed. |
1121 __ push(Operand(esp, kPointerSize)); // Receiver is under value. | 1125 __ push(Operand(esp, kPointerSize)); // Receiver is under value. |
1122 __ CallRuntime(Runtime::kToFastProperties, 1); | 1126 __ CallRuntime(Runtime::kToFastProperties, 1); |
1123 __ pop(eax); | 1127 __ pop(eax); |
| 1128 DropAndApply(1, context_, eax); |
| 1129 } else { |
| 1130 Apply(context_, eax); |
1124 } | 1131 } |
1125 | |
1126 DropAndApply(1, context_, eax); | |
1127 } | 1132 } |
1128 | 1133 |
1129 | 1134 |
1130 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1135 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
1131 // Assignment to a property, using a keyed store IC. | 1136 // Assignment to a property, using a keyed store IC. |
1132 | 1137 |
1133 // If the assignment starts a block of assignments to the same object, | 1138 // If the assignment starts a block of assignments to the same object, |
1134 // change to slow case to avoid the quadratic behavior of repeatedly | 1139 // change to slow case to avoid the quadratic behavior of repeatedly |
1135 // adding fast properties. | 1140 // adding fast properties. |
1136 if (expr->starts_initialization_block()) { | 1141 if (expr->starts_initialization_block()) { |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1635 if (context_ != Expression::kEffect) { | 1640 if (context_ != Expression::kEffect) { |
1636 ApplyTOS(context_); | 1641 ApplyTOS(context_); |
1637 } | 1642 } |
1638 } else { | 1643 } else { |
1639 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), | 1644 EmitVariableAssignment(expr->expression()->AsVariableProxy()->var(), |
1640 context_); | 1645 context_); |
1641 } | 1646 } |
1642 break; | 1647 break; |
1643 case NAMED_PROPERTY: { | 1648 case NAMED_PROPERTY: { |
1644 __ mov(ecx, prop->key()->AsLiteral()->handle()); | 1649 __ mov(ecx, prop->key()->AsLiteral()->handle()); |
| 1650 __ pop(edx); |
1645 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); | 1651 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
1646 __ call(ic, RelocInfo::CODE_TARGET); | 1652 __ call(ic, RelocInfo::CODE_TARGET); |
1647 // This nop signals to the IC that there is no inlined code at the call | 1653 // This nop signals to the IC that there is no inlined code at the call |
1648 // site for it to patch. | 1654 // site for it to patch. |
1649 __ nop(); | 1655 __ nop(); |
1650 if (expr->is_postfix()) { | 1656 if (expr->is_postfix()) { |
1651 __ Drop(1); // Result is on the stack under the receiver. | |
1652 if (context_ != Expression::kEffect) { | 1657 if (context_ != Expression::kEffect) { |
1653 ApplyTOS(context_); | 1658 ApplyTOS(context_); |
1654 } | 1659 } |
1655 } else { | 1660 } else { |
1656 DropAndApply(1, context_, eax); | 1661 Apply(context_, eax); |
1657 } | 1662 } |
1658 break; | 1663 break; |
1659 } | 1664 } |
1660 case KEYED_PROPERTY: { | 1665 case KEYED_PROPERTY: { |
1661 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 1666 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
1662 __ call(ic, RelocInfo::CODE_TARGET); | 1667 __ call(ic, RelocInfo::CODE_TARGET); |
1663 // This nop signals to the IC that there is no inlined code at the call | 1668 // This nop signals to the IC that there is no inlined code at the call |
1664 // site for it to patch. | 1669 // site for it to patch. |
1665 __ nop(); | 1670 __ nop(); |
1666 if (expr->is_postfix()) { | 1671 if (expr->is_postfix()) { |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1877 __ add(Operand(edx), Immediate(masm_->CodeObject())); | 1882 __ add(Operand(edx), Immediate(masm_->CodeObject())); |
1878 __ mov(Operand(esp, 0), edx); | 1883 __ mov(Operand(esp, 0), edx); |
1879 // And return. | 1884 // And return. |
1880 __ ret(0); | 1885 __ ret(0); |
1881 } | 1886 } |
1882 | 1887 |
1883 | 1888 |
1884 #undef __ | 1889 #undef __ |
1885 | 1890 |
1886 } } // namespace v8::internal | 1891 } } // namespace v8::internal |
OLD | NEW |