Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
| 6 | 6 |
| 7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
| 8 #include "src/compiler.h" | 8 #include "src/compiler.h" |
| 9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
| 10 #include "src/interpreter/control-flow-builders.h" | 10 #include "src/interpreter/control-flow-builders.h" |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 } | 411 } |
| 412 | 412 |
| 413 void PrepareForConsecutiveAllocations(int count) { | 413 void PrepareForConsecutiveAllocations(int count) { |
| 414 allocator_.PrepareForConsecutiveAllocations(count); | 414 allocator_.PrepareForConsecutiveAllocations(count); |
| 415 } | 415 } |
| 416 | 416 |
| 417 Register NextConsecutiveRegister() { | 417 Register NextConsecutiveRegister() { |
| 418 return allocator_.NextConsecutiveRegister(); | 418 return allocator_.NextConsecutiveRegister(); |
| 419 } | 419 } |
| 420 | 420 |
| 421 template <size_t N> | |
| 422 void PrepareAndInitializeConsecutiveAllocations(Register (®isters)[N]) { | |
| 423 return allocator_.PrepareAndInitializeConsecutiveAllocations(registers, N); | |
| 424 } | |
| 425 | |
| 421 bool RegisterIsAllocatedInThisScope(Register reg) const { | 426 bool RegisterIsAllocatedInThisScope(Register reg) const { |
| 422 return allocator_.RegisterIsAllocatedInThisScope(reg); | 427 return allocator_.RegisterIsAllocatedInThisScope(reg); |
| 423 } | 428 } |
| 424 | 429 |
| 425 RegisterAllocationScope* outer() const { return outer_; } | 430 RegisterAllocationScope* outer() const { return outer_; } |
| 426 | 431 |
| 427 private: | 432 private: |
| 428 BytecodeGenerator* generator() const { return generator_; } | 433 BytecodeGenerator* generator() const { return generator_; } |
| 429 BytecodeArrayBuilder* builder() const { return generator_->builder(); } | 434 BytecodeArrayBuilder* builder() const { return generator_->builder(); } |
| 430 | 435 |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 536 result_register_ = reg; | 541 result_register_ = reg; |
| 537 set_result_identified(); | 542 set_result_identified(); |
| 538 } | 543 } |
| 539 | 544 |
| 540 Register ResultRegister() const { return result_register_; } | 545 Register ResultRegister() const { return result_register_; } |
| 541 | 546 |
| 542 private: | 547 private: |
| 543 Register result_register_; | 548 Register result_register_; |
| 544 }; | 549 }; |
| 545 | 550 |
| 551 class BytecodeGenerator::SuperPropertyArguments final { | |
| 552 public: | |
| 553 SuperPropertyArguments() {} | |
| 554 | |
| 555 Register (®isters())[4] { return args_; } | |
| 556 Register receiver() const { return args_[0]; } | |
| 557 Register home_object() const { return args_[1]; } | |
| 558 Register name_or_key() const { return args_[2]; } | |
| 559 Register store_value() const { return args_[3]; } | |
| 560 Register language_mode() const { return args_[3]; } | |
| 561 size_t size() const { return arraysize(args_); } | |
|
rmcilroy
2016/02/12 17:08:43
nit - /s/size/count/
oth
2016/02/12 17:22:59
Done.
| |
| 562 | |
| 563 private: | |
| 564 Register args_[4]; | |
| 565 | |
| 566 DISALLOW_COPY_AND_ASSIGN(SuperPropertyArguments); | |
| 567 }; | |
| 568 | |
| 546 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) | 569 BytecodeGenerator::BytecodeGenerator(Isolate* isolate, Zone* zone) |
| 547 : isolate_(isolate), | 570 : isolate_(isolate), |
| 548 zone_(zone), | 571 zone_(zone), |
| 549 builder_(nullptr), | 572 builder_(nullptr), |
| 550 info_(nullptr), | 573 info_(nullptr), |
| 551 scope_(nullptr), | 574 scope_(nullptr), |
| 552 globals_(0, zone), | 575 globals_(0, zone), |
| 553 execution_control_(nullptr), | 576 execution_control_(nullptr), |
| 554 execution_context_(nullptr), | 577 execution_context_(nullptr), |
| 555 execution_result_(nullptr), | 578 execution_result_(nullptr), |
| 556 register_allocator_(nullptr), | 579 register_allocator_(nullptr), |
| 557 try_catch_nesting_level_(0), | 580 try_catch_nesting_level_(0), |
| 558 try_finally_nesting_level_(0) { | 581 try_finally_nesting_level_(0) { |
| 559 InitializeAstVisitor(isolate); | 582 InitializeAstVisitor(isolate); |
| 560 } | 583 } |
| 561 | 584 |
| 562 | |
| 563 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { | 585 Handle<BytecodeArray> BytecodeGenerator::MakeBytecode(CompilationInfo* info) { |
| 564 set_info(info); | 586 set_info(info); |
| 565 set_scope(info->scope()); | 587 set_scope(info->scope()); |
| 566 | 588 |
| 567 // Initialize bytecode array builder. | 589 // Initialize bytecode array builder. |
| 568 set_builder(new (zone()) BytecodeArrayBuilder( | 590 set_builder(new (zone()) BytecodeArrayBuilder( |
| 569 isolate(), zone(), info->num_parameters_including_this(), | 591 isolate(), zone(), info->num_parameters_including_this(), |
| 570 scope()->MaxNestedContextChainLength(), scope()->num_stack_slots())); | 592 scope()->MaxNestedContextChainLength(), scope()->num_stack_slots())); |
| 571 | 593 |
| 572 // Initialize the incoming context. | 594 // Initialize the incoming context. |
| (...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1043 RegisterAllocationScope register_scope(this); | 1065 RegisterAllocationScope register_scope(this); |
| 1044 Register value = register_allocator()->NewRegister(); | 1066 Register value = register_allocator()->NewRegister(); |
| 1045 builder()->StoreAccumulatorInRegister(value); | 1067 builder()->StoreAccumulatorInRegister(value); |
| 1046 Register object = VisitForRegisterValue(property->obj()); | 1068 Register object = VisitForRegisterValue(property->obj()); |
| 1047 Register key = VisitForRegisterValue(property->key()); | 1069 Register key = VisitForRegisterValue(property->key()); |
| 1048 builder()->LoadAccumulatorWithRegister(value); | 1070 builder()->LoadAccumulatorWithRegister(value); |
| 1049 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 1071 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
| 1050 language_mode()); | 1072 language_mode()); |
| 1051 break; | 1073 break; |
| 1052 } | 1074 } |
| 1053 case NAMED_SUPER_PROPERTY: | 1075 case NAMED_SUPER_PROPERTY: { |
| 1054 case KEYED_SUPER_PROPERTY: | 1076 RegisterAllocationScope register_scope(this); |
| 1055 UNIMPLEMENTED(); | 1077 SuperPropertyArguments super_args; |
| 1078 Register value = register_allocator()->NewRegister(); | |
| 1079 builder()->StoreAccumulatorInRegister(value); | |
| 1080 PrepareNamedSuperPropertyArguments( | |
| 1081 property->obj()->AsSuperPropertyReference(), | |
| 1082 property->key()->AsLiteral()->AsPropertyName(), &super_args); | |
| 1083 builder()->LoadAccumulatorWithRegister(value); | |
| 1084 BuildNamedSuperPropertyStore(&super_args); | |
| 1085 break; | |
| 1086 } | |
| 1087 case KEYED_SUPER_PROPERTY: { | |
| 1088 RegisterAllocationScope register_scope(this); | |
| 1089 SuperPropertyArguments super_args; | |
| 1090 Register value = register_allocator()->NewRegister(); | |
| 1091 builder()->StoreAccumulatorInRegister(value); | |
| 1092 PrepareKeyedSuperPropertyArguments( | |
| 1093 property->obj()->AsSuperPropertyReference(), property->key(), | |
| 1094 &super_args); | |
| 1095 builder()->LoadAccumulatorWithRegister(value); | |
| 1096 BuildKeyedSuperPropertyStore(&super_args); | |
| 1097 break; | |
| 1098 } | |
| 1056 } | 1099 } |
| 1057 } | 1100 } |
| 1058 | 1101 |
| 1059 | 1102 |
| 1060 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { | 1103 void BytecodeGenerator::VisitForInStatement(ForInStatement* stmt) { |
| 1061 if (stmt->subject()->IsNullLiteral() || | 1104 if (stmt->subject()->IsNullLiteral() || |
| 1062 stmt->subject()->IsUndefinedLiteral(isolate())) { | 1105 stmt->subject()->IsUndefinedLiteral(isolate())) { |
| 1063 // ForIn generates lots of code, skip if it wouldn't produce any effects. | 1106 // ForIn generates lots of code, skip if it wouldn't produce any effects. |
| 1064 return; | 1107 return; |
| 1065 } | 1108 } |
| (...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1488 UNREACHABLE(); | 1531 UNREACHABLE(); |
| 1489 case ObjectLiteral::Property::MATERIALIZED_LITERAL: | 1532 case ObjectLiteral::Property::MATERIALIZED_LITERAL: |
| 1490 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); | 1533 DCHECK(!CompileTimeValue::IsCompileTimeValue(property->value())); |
| 1491 // Fall through. | 1534 // Fall through. |
| 1492 case ObjectLiteral::Property::COMPUTED: { | 1535 case ObjectLiteral::Property::COMPUTED: { |
| 1493 // It is safe to use [[Put]] here because the boilerplate already | 1536 // It is safe to use [[Put]] here because the boilerplate already |
| 1494 // contains computed properties with an uninitialized value. | 1537 // contains computed properties with an uninitialized value. |
| 1495 if (literal_key->value()->IsInternalizedString()) { | 1538 if (literal_key->value()->IsInternalizedString()) { |
| 1496 if (property->emit_store()) { | 1539 if (property->emit_store()) { |
| 1497 VisitForAccumulatorValue(property->value()); | 1540 VisitForAccumulatorValue(property->value()); |
| 1498 builder()->StoreNamedProperty( | 1541 if (FunctionLiteral::NeedsHomeObject(property->value())) { |
| 1499 literal, literal_key->AsPropertyName(), | 1542 RegisterAllocationScope register_scope(this); |
| 1500 feedback_index(property->GetSlot(0)), language_mode()); | 1543 Register value = register_allocator()->NewRegister(); |
| 1544 builder()->StoreAccumulatorInRegister(value); | |
| 1545 builder()->StoreNamedProperty( | |
| 1546 literal, literal_key->AsPropertyName(), | |
| 1547 feedback_index(property->GetSlot(0)), language_mode()); | |
| 1548 VisitSetHomeObject(value, literal, property, 1); | |
| 1549 } else { | |
| 1550 builder()->StoreNamedProperty( | |
| 1551 literal, literal_key->AsPropertyName(), | |
| 1552 feedback_index(property->GetSlot(0)), language_mode()); | |
| 1553 } | |
| 1501 } else { | 1554 } else { |
| 1502 VisitForEffect(property->value()); | 1555 VisitForEffect(property->value()); |
| 1503 } | 1556 } |
| 1504 } else { | 1557 } else { |
| 1505 register_allocator()->PrepareForConsecutiveAllocations(4); | 1558 register_allocator()->PrepareForConsecutiveAllocations(4); |
| 1506 Register literal_argument = | 1559 Register literal_argument = |
| 1507 register_allocator()->NextConsecutiveRegister(); | 1560 register_allocator()->NextConsecutiveRegister(); |
| 1508 Register key = register_allocator()->NextConsecutiveRegister(); | 1561 Register key = register_allocator()->NextConsecutiveRegister(); |
| 1509 Register value = register_allocator()->NextConsecutiveRegister(); | 1562 Register value = register_allocator()->NextConsecutiveRegister(); |
| 1510 Register language = register_allocator()->NextConsecutiveRegister(); | 1563 Register language = register_allocator()->NextConsecutiveRegister(); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1778 } | 1831 } |
| 1779 | 1832 |
| 1780 | 1833 |
| 1781 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( | 1834 Register BytecodeGenerator::VisitVariableLoadForRegisterValue( |
| 1782 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { | 1835 Variable* variable, FeedbackVectorSlot slot, TypeofMode typeof_mode) { |
| 1783 RegisterResultScope register_scope(this); | 1836 RegisterResultScope register_scope(this); |
| 1784 VisitVariableLoad(variable, slot, typeof_mode); | 1837 VisitVariableLoad(variable, slot, typeof_mode); |
| 1785 return register_scope.ResultRegister(); | 1838 return register_scope.ResultRegister(); |
| 1786 } | 1839 } |
| 1787 | 1840 |
| 1841 void BytecodeGenerator::PrepareNamedSuperPropertyArguments( | |
| 1842 SuperPropertyReference* super_property, Handle<Name> name, | |
| 1843 SuperPropertyArguments* super_args) { | |
| 1844 register_allocator()->PrepareAndInitializeConsecutiveAllocations( | |
| 1845 super_args->registers()); | |
| 1846 | |
| 1847 VisitForAccumulatorValue(super_property->this_var()); | |
| 1848 builder()->StoreAccumulatorInRegister(super_args->receiver()); | |
| 1849 VisitForAccumulatorValue(super_property->home_object()); | |
| 1850 builder()->StoreAccumulatorInRegister(super_args->home_object()); | |
| 1851 builder()->LoadLiteral(name).StoreAccumulatorInRegister( | |
| 1852 super_args->name_or_key()); | |
| 1853 } | |
| 1854 | |
| 1855 void BytecodeGenerator::PrepareKeyedSuperPropertyArguments( | |
| 1856 SuperPropertyReference* super_property, Expression* key, | |
| 1857 SuperPropertyArguments* super_args) { | |
| 1858 register_allocator()->PrepareAndInitializeConsecutiveAllocations( | |
| 1859 super_args->registers()); | |
| 1860 | |
| 1861 VisitForAccumulatorValue(super_property->this_var()); | |
| 1862 builder()->StoreAccumulatorInRegister(super_args->receiver()); | |
| 1863 VisitForAccumulatorValue(super_property->home_object()); | |
| 1864 builder()->StoreAccumulatorInRegister(super_args->home_object()); | |
| 1865 VisitForAccumulatorValue(key); | |
| 1866 builder()->StoreAccumulatorInRegister(super_args->name_or_key()); | |
| 1867 } | |
| 1868 | |
| 1869 void BytecodeGenerator::BuildNamedSuperPropertyLoad( | |
| 1870 SuperPropertyArguments* super_args) { | |
| 1871 builder() | |
| 1872 ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
| 1873 .StoreAccumulatorInRegister(super_args->language_mode()); | |
| 1874 builder()->CallRuntime(Runtime::kLoadFromSuper, super_args->receiver(), | |
| 1875 super_args->size()); | |
| 1876 } | |
| 1877 | |
| 1878 void BytecodeGenerator::BuildKeyedSuperPropertyLoad( | |
| 1879 SuperPropertyArguments* super_args) { | |
| 1880 builder() | |
| 1881 ->LoadLiteral(Smi::FromInt(static_cast<int>(language_mode()))) | |
| 1882 .StoreAccumulatorInRegister(super_args->language_mode()); | |
| 1883 builder()->CallRuntime(Runtime::kLoadKeyedFromSuper, super_args->receiver(), | |
| 1884 super_args->size()); | |
| 1885 } | |
| 1886 | |
| 1887 void BytecodeGenerator::BuildNamedSuperPropertyStore( | |
| 1888 SuperPropertyArguments* super_args) { | |
| 1889 builder()->StoreAccumulatorInRegister(super_args->store_value()); | |
| 1890 Runtime::FunctionId function_id = is_strict(language_mode()) | |
| 1891 ? Runtime::kStoreToSuper_Strict | |
| 1892 : Runtime::kStoreToSuper_Sloppy; | |
| 1893 builder()->CallRuntime(function_id, super_args->receiver(), | |
| 1894 super_args->size()); | |
| 1895 } | |
| 1896 | |
| 1897 void BytecodeGenerator::BuildKeyedSuperPropertyStore( | |
| 1898 SuperPropertyArguments* super_args) { | |
| 1899 builder()->StoreAccumulatorInRegister(super_args->store_value()); | |
| 1900 Runtime::FunctionId function_id = is_strict(language_mode()) | |
| 1901 ? Runtime::kStoreKeyedToSuper_Strict | |
| 1902 : Runtime::kStoreKeyedToSuper_Sloppy; | |
| 1903 builder()->CallRuntime(function_id, super_args->receiver(), | |
| 1904 super_args->size()); | |
| 1905 } | |
| 1906 | |
| 1788 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { | 1907 void BytecodeGenerator::BuildThrowIfHole(Handle<String> name) { |
| 1789 Register name_reg = register_allocator()->NewRegister(); | 1908 Register name_reg = register_allocator()->NewRegister(); |
| 1790 BytecodeLabel end_label; | 1909 BytecodeLabel end_label; |
| 1791 // TODO(mythria): This will be replaced by a new bytecode that throws an | 1910 // TODO(mythria): This will be replaced by a new bytecode that throws an |
| 1792 // error if the value is the hole. | 1911 // error if the value is the hole. |
| 1793 builder() | 1912 builder() |
| 1794 ->JumpIfNotHole(&end_label) | 1913 ->JumpIfNotHole(&end_label) |
| 1795 .LoadLiteral(name) | 1914 .LoadLiteral(name) |
| 1796 .StoreAccumulatorInRegister(name_reg) | 1915 .StoreAccumulatorInRegister(name_reg) |
| 1797 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1) | 1916 .CallRuntime(Runtime::kThrowReferenceError, name_reg, 1) |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1986 } else { | 2105 } else { |
| 1987 builder()->StoreLookupSlot(variable->name(), language_mode()); | 2106 builder()->StoreLookupSlot(variable->name(), language_mode()); |
| 1988 } | 2107 } |
| 1989 break; | 2108 break; |
| 1990 } | 2109 } |
| 1991 } | 2110 } |
| 1992 } | 2111 } |
| 1993 | 2112 |
| 1994 | 2113 |
| 1995 void BytecodeGenerator::VisitAssignment(Assignment* expr) { | 2114 void BytecodeGenerator::VisitAssignment(Assignment* expr) { |
| 1996 DCHECK(expr->target()->IsValidReferenceExpression()); | 2115 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
| 1997 Register object, key; | 2116 Register object, key; |
| 2117 SuperPropertyArguments super_args; | |
| 1998 Handle<String> name; | 2118 Handle<String> name; |
| 1999 | 2119 |
| 2000 // Left-hand side can only be a property, a global or a variable slot. | 2120 // Left-hand side can only be a property, a global or a variable slot. |
| 2001 Property* property = expr->target()->AsProperty(); | 2121 Property* property = expr->target()->AsProperty(); |
| 2002 LhsKind assign_type = Property::GetAssignType(property); | 2122 LhsKind assign_type = Property::GetAssignType(property); |
| 2003 | 2123 |
| 2004 // Evaluate LHS expression. | 2124 // Evaluate LHS expression. |
| 2005 switch (assign_type) { | 2125 switch (assign_type) { |
| 2006 case VARIABLE: | 2126 case VARIABLE: |
| 2007 // Nothing to do to evaluate variable assignment LHS. | 2127 // Nothing to do to evaluate variable assignment LHS. |
| 2008 break; | 2128 break; |
| 2009 case NAMED_PROPERTY: { | 2129 case NAMED_PROPERTY: { |
| 2010 object = VisitForRegisterValue(property->obj()); | 2130 object = VisitForRegisterValue(property->obj()); |
| 2011 name = property->key()->AsLiteral()->AsPropertyName(); | 2131 name = property->key()->AsLiteral()->AsPropertyName(); |
| 2012 break; | 2132 break; |
| 2013 } | 2133 } |
| 2014 case KEYED_PROPERTY: { | 2134 case KEYED_PROPERTY: { |
| 2015 object = VisitForRegisterValue(property->obj()); | 2135 object = VisitForRegisterValue(property->obj()); |
| 2016 if (expr->is_compound()) { | 2136 if (expr->is_compound()) { |
| 2017 // Use VisitForAccumulator and store to register so that the key is | 2137 // Use VisitForAccumulator and store to register so that the key is |
| 2018 // still in the accumulator for loading the old value below. | 2138 // still in the accumulator for loading the old value below. |
| 2019 key = register_allocator()->NewRegister(); | 2139 key = register_allocator()->NewRegister(); |
| 2020 VisitForAccumulatorValue(property->key()); | 2140 VisitForAccumulatorValue(property->key()); |
| 2021 builder()->StoreAccumulatorInRegister(key); | 2141 builder()->StoreAccumulatorInRegister(key); |
| 2022 } else { | 2142 } else { |
| 2023 key = VisitForRegisterValue(property->key()); | 2143 key = VisitForRegisterValue(property->key()); |
| 2024 } | 2144 } |
| 2025 break; | 2145 break; |
| 2026 } | 2146 } |
| 2027 case NAMED_SUPER_PROPERTY: | 2147 case NAMED_SUPER_PROPERTY: { |
| 2028 case KEYED_SUPER_PROPERTY: | 2148 PrepareNamedSuperPropertyArguments( |
| 2029 UNIMPLEMENTED(); | 2149 property->obj()->AsSuperPropertyReference(), |
| 2150 property->key()->AsLiteral()->AsPropertyName(), &super_args); | |
| 2151 break; | |
| 2152 } | |
| 2153 case KEYED_SUPER_PROPERTY: { | |
| 2154 PrepareKeyedSuperPropertyArguments( | |
| 2155 property->obj()->AsSuperPropertyReference(), property->key(), | |
| 2156 &super_args); | |
| 2157 break; | |
| 2158 } | |
| 2030 } | 2159 } |
| 2031 | 2160 |
| 2032 // Evaluate the value and potentially handle compound assignments by loading | 2161 // Evaluate the value and potentially handle compound assignments by loading |
| 2033 // the left-hand side value and performing a binary operation. | 2162 // the left-hand side value and performing a binary operation. |
| 2034 if (expr->is_compound()) { | 2163 if (expr->is_compound()) { |
| 2035 Register old_value; | 2164 Register old_value; |
| 2036 switch (assign_type) { | 2165 switch (assign_type) { |
| 2037 case VARIABLE: { | 2166 case VARIABLE: { |
| 2038 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 2167 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 2039 old_value = VisitVariableLoadForRegisterValue( | 2168 old_value = VisitVariableLoadForRegisterValue( |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2052 case KEYED_PROPERTY: { | 2181 case KEYED_PROPERTY: { |
| 2053 // Key is already in accumulator at this point due to evaluating the | 2182 // Key is already in accumulator at this point due to evaluating the |
| 2054 // LHS above. | 2183 // LHS above. |
| 2055 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2184 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2056 old_value = register_allocator()->NewRegister(); | 2185 old_value = register_allocator()->NewRegister(); |
| 2057 builder() | 2186 builder() |
| 2058 ->LoadKeyedProperty(object, feedback_index(slot), language_mode()) | 2187 ->LoadKeyedProperty(object, feedback_index(slot), language_mode()) |
| 2059 .StoreAccumulatorInRegister(old_value); | 2188 .StoreAccumulatorInRegister(old_value); |
| 2060 break; | 2189 break; |
| 2061 } | 2190 } |
| 2062 case NAMED_SUPER_PROPERTY: | 2191 case NAMED_SUPER_PROPERTY: { |
| 2063 case KEYED_SUPER_PROPERTY: | 2192 old_value = register_allocator()->NewRegister(); |
| 2064 UNIMPLEMENTED(); | 2193 BuildNamedSuperPropertyLoad(&super_args); |
| 2194 builder()->StoreAccumulatorInRegister(old_value); | |
| 2065 break; | 2195 break; |
| 2196 } | |
| 2197 case KEYED_SUPER_PROPERTY: { | |
| 2198 old_value = register_allocator()->NewRegister(); | |
| 2199 BuildKeyedSuperPropertyLoad(&super_args); | |
| 2200 builder()->StoreAccumulatorInRegister(old_value); | |
| 2201 break; | |
| 2202 } | |
| 2066 } | 2203 } |
| 2067 VisitForAccumulatorValue(expr->value()); | 2204 VisitForAccumulatorValue(expr->value()); |
| 2068 builder()->BinaryOperation(expr->binary_op(), old_value, | 2205 builder()->BinaryOperation(expr->binary_op(), old_value, |
| 2069 language_mode_strength()); | 2206 language_mode_strength()); |
| 2070 } else { | 2207 } else { |
| 2071 VisitForAccumulatorValue(expr->value()); | 2208 VisitForAccumulatorValue(expr->value()); |
| 2072 } | 2209 } |
| 2073 | 2210 |
| 2074 // Store the value. | 2211 // Store the value. |
| 2075 FeedbackVectorSlot slot = expr->AssignmentSlot(); | 2212 FeedbackVectorSlot slot = expr->AssignmentSlot(); |
| 2076 switch (assign_type) { | 2213 switch (assign_type) { |
| 2077 case VARIABLE: { | 2214 case VARIABLE: { |
| 2078 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. | 2215 // TODO(oth): The VisitVariableAssignment() call is hard to reason about. |
| 2079 // Is the value in the accumulator safe? Yes, but scary. | 2216 // Is the value in the accumulator safe? Yes, but scary. |
| 2080 Variable* variable = expr->target()->AsVariableProxy()->var(); | 2217 Variable* variable = expr->target()->AsVariableProxy()->var(); |
| 2081 VisitVariableAssignment(variable, expr->op(), slot); | 2218 VisitVariableAssignment(variable, expr->op(), slot); |
| 2082 break; | 2219 break; |
| 2083 } | 2220 } |
| 2084 case NAMED_PROPERTY: | 2221 case NAMED_PROPERTY: |
| 2085 builder()->StoreNamedProperty(object, name, feedback_index(slot), | 2222 builder()->StoreNamedProperty(object, name, feedback_index(slot), |
| 2086 language_mode()); | 2223 language_mode()); |
| 2087 break; | 2224 break; |
| 2088 case KEYED_PROPERTY: | 2225 case KEYED_PROPERTY: |
| 2089 builder()->StoreKeyedProperty(object, key, feedback_index(slot), | 2226 builder()->StoreKeyedProperty(object, key, feedback_index(slot), |
| 2090 language_mode()); | 2227 language_mode()); |
| 2091 break; | 2228 break; |
| 2092 case NAMED_SUPER_PROPERTY: | 2229 case NAMED_SUPER_PROPERTY: { |
| 2093 case KEYED_SUPER_PROPERTY: | 2230 BuildNamedSuperPropertyStore(&super_args); |
| 2094 UNIMPLEMENTED(); | 2231 break; |
| 2232 } | |
| 2233 case KEYED_SUPER_PROPERTY: { | |
| 2234 BuildKeyedSuperPropertyStore(&super_args); | |
| 2235 break; | |
| 2236 } | |
| 2095 } | 2237 } |
| 2096 execution_result()->SetResultInAccumulator(); | 2238 execution_result()->SetResultInAccumulator(); |
| 2097 } | 2239 } |
| 2098 | 2240 |
| 2099 | 2241 |
| 2100 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } | 2242 void BytecodeGenerator::VisitYield(Yield* expr) { UNIMPLEMENTED(); } |
| 2101 | 2243 |
| 2102 | 2244 |
| 2103 void BytecodeGenerator::VisitThrow(Throw* expr) { | 2245 void BytecodeGenerator::VisitThrow(Throw* expr) { |
| 2104 VisitForAccumulatorValue(expr->exception()); | 2246 VisitForAccumulatorValue(expr->exception()); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2122 expr->key()->AsLiteral()->AsPropertyName(), | 2264 expr->key()->AsLiteral()->AsPropertyName(), |
| 2123 feedback_index(slot), language_mode()); | 2265 feedback_index(slot), language_mode()); |
| 2124 break; | 2266 break; |
| 2125 } | 2267 } |
| 2126 case KEYED_PROPERTY: { | 2268 case KEYED_PROPERTY: { |
| 2127 VisitForAccumulatorValue(expr->key()); | 2269 VisitForAccumulatorValue(expr->key()); |
| 2128 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); | 2270 builder()->LoadKeyedProperty(obj, feedback_index(slot), language_mode()); |
| 2129 break; | 2271 break; |
| 2130 } | 2272 } |
| 2131 case NAMED_SUPER_PROPERTY: | 2273 case NAMED_SUPER_PROPERTY: |
| 2274 VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); | |
| 2275 break; | |
| 2132 case KEYED_SUPER_PROPERTY: | 2276 case KEYED_SUPER_PROPERTY: |
| 2133 UNIMPLEMENTED(); | 2277 VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); |
| 2278 break; | |
| 2134 } | 2279 } |
| 2135 execution_result()->SetResultInAccumulator(); | 2280 execution_result()->SetResultInAccumulator(); |
| 2136 } | 2281 } |
| 2137 | 2282 |
| 2138 | |
| 2139 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, | 2283 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, |
| 2140 Property* expr) { | 2284 Property* expr) { |
| 2141 AccumulatorResultScope result_scope(this); | 2285 AccumulatorResultScope result_scope(this); |
| 2142 VisitPropertyLoad(obj, expr); | 2286 VisitPropertyLoad(obj, expr); |
| 2143 } | 2287 } |
| 2144 | 2288 |
| 2289 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, | |
| 2290 Register opt_receiver_out) { | |
| 2291 RegisterAllocationScope register_scope(this); | |
| 2292 SuperPropertyArguments super_args; | |
| 2293 PrepareNamedSuperPropertyArguments( | |
| 2294 property->obj()->AsSuperPropertyReference(), | |
| 2295 property->key()->AsLiteral()->AsPropertyName(), &super_args); | |
| 2296 if (opt_receiver_out.is_valid()) { | |
| 2297 builder()->MoveRegister(super_args.receiver(), opt_receiver_out); | |
| 2298 } | |
| 2299 BuildNamedSuperPropertyLoad(&super_args); | |
| 2300 } | |
| 2301 | |
| 2302 void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, | |
| 2303 Register opt_receiver_out) { | |
| 2304 RegisterAllocationScope register_scope(this); | |
| 2305 SuperPropertyArguments super_args; | |
| 2306 PrepareKeyedSuperPropertyArguments( | |
| 2307 property->obj()->AsSuperPropertyReference(), property->key(), | |
| 2308 &super_args); | |
| 2309 if (opt_receiver_out.is_valid()) { | |
| 2310 builder()->MoveRegister(super_args.receiver(), opt_receiver_out); | |
| 2311 } | |
| 2312 BuildKeyedSuperPropertyLoad(&super_args); | |
| 2313 } | |
| 2145 | 2314 |
| 2146 void BytecodeGenerator::VisitProperty(Property* expr) { | 2315 void BytecodeGenerator::VisitProperty(Property* expr) { |
| 2147 Register obj = VisitForRegisterValue(expr->obj()); | 2316 LhsKind property_kind = Property::GetAssignType(expr); |
| 2148 VisitPropertyLoad(obj, expr); | 2317 if (property_kind != NAMED_SUPER_PROPERTY && |
| 2318 property_kind != KEYED_SUPER_PROPERTY) { | |
| 2319 Register obj = VisitForRegisterValue(expr->obj()); | |
| 2320 VisitPropertyLoad(obj, expr); | |
| 2321 } else { | |
| 2322 VisitPropertyLoad(Register::invalid_value(), expr); | |
| 2323 } | |
| 2149 } | 2324 } |
| 2150 | 2325 |
| 2151 | |
| 2152 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { | 2326 Register BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args) { |
| 2153 if (args->length() == 0) { | 2327 if (args->length() == 0) { |
| 2154 return Register(); | 2328 return Register(); |
| 2155 } | 2329 } |
| 2156 | 2330 |
| 2157 // Visit arguments and place in a contiguous block of temporary | 2331 // Visit arguments and place in a contiguous block of temporary |
| 2158 // registers. Return the first temporary register corresponding to | 2332 // registers. Return the first temporary register corresponding to |
| 2159 // the first argument. | 2333 // the first argument. |
| 2160 // | 2334 // |
| 2161 // NB the caller may have already called | 2335 // NB the caller may have already called |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2174 // Visit remaining arguments | 2348 // Visit remaining arguments |
| 2175 for (int i = 1; i < static_cast<int>(args->length()); i++) { | 2349 for (int i = 1; i < static_cast<int>(args->length()); i++) { |
| 2176 Register ith_arg = register_allocator()->NextConsecutiveRegister(); | 2350 Register ith_arg = register_allocator()->NextConsecutiveRegister(); |
| 2177 VisitForAccumulatorValue(args->at(i)); | 2351 VisitForAccumulatorValue(args->at(i)); |
| 2178 builder()->StoreAccumulatorInRegister(ith_arg); | 2352 builder()->StoreAccumulatorInRegister(ith_arg); |
| 2179 DCHECK(ith_arg.index() - i == first_arg.index()); | 2353 DCHECK(ith_arg.index() - i == first_arg.index()); |
| 2180 } | 2354 } |
| 2181 return first_arg; | 2355 return first_arg; |
| 2182 } | 2356 } |
| 2183 | 2357 |
| 2184 | |
| 2185 void BytecodeGenerator::VisitCall(Call* expr) { | 2358 void BytecodeGenerator::VisitCall(Call* expr) { |
| 2186 Expression* callee_expr = expr->expression(); | 2359 Expression* callee_expr = expr->expression(); |
| 2187 Call::CallType call_type = expr->GetCallType(isolate()); | 2360 Call::CallType call_type = expr->GetCallType(isolate()); |
| 2188 | 2361 |
| 2362 if (call_type == Call::SUPER_CALL) { | |
| 2363 return VisitCallSuper(expr); | |
| 2364 } | |
| 2365 | |
| 2189 // Prepare the callee and the receiver to the function call. This depends on | 2366 // Prepare the callee and the receiver to the function call. This depends on |
| 2190 // the semantics of the underlying call type. | 2367 // the semantics of the underlying call type. |
| 2191 | 2368 |
| 2192 // The receiver and arguments need to be allocated consecutively for | 2369 // The receiver and arguments need to be allocated consecutively for |
| 2193 // Call(). We allocate the callee and receiver consecutively for calls to | 2370 // Call(). We allocate the callee and receiver consecutively for calls to |
| 2194 // %LoadLookupSlotForCall. Future optimizations could avoid this there are | 2371 // %LoadLookupSlotForCall. Future optimizations could avoid this there are |
| 2195 // no arguments or the receiver and arguments are already consecutive. | 2372 // no arguments or the receiver and arguments are already consecutive. |
| 2196 ZoneList<Expression*>* args = expr->arguments(); | 2373 ZoneList<Expression*>* args = expr->arguments(); |
| 2197 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2); | 2374 register_allocator()->PrepareForConsecutiveAllocations(args->length() + 2); |
| 2198 Register callee = register_allocator()->NextConsecutiveRegister(); | 2375 Register callee = register_allocator()->NextConsecutiveRegister(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2236 } | 2413 } |
| 2237 // Fall through. | 2414 // Fall through. |
| 2238 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); | 2415 DCHECK_EQ(call_type, Call::POSSIBLY_EVAL_CALL); |
| 2239 } | 2416 } |
| 2240 case Call::OTHER_CALL: { | 2417 case Call::OTHER_CALL: { |
| 2241 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 2418 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); |
| 2242 VisitForAccumulatorValue(callee_expr); | 2419 VisitForAccumulatorValue(callee_expr); |
| 2243 builder()->StoreAccumulatorInRegister(callee); | 2420 builder()->StoreAccumulatorInRegister(callee); |
| 2244 break; | 2421 break; |
| 2245 } | 2422 } |
| 2246 case Call::NAMED_SUPER_PROPERTY_CALL: | 2423 case Call::NAMED_SUPER_PROPERTY_CALL: { |
| 2247 case Call::KEYED_SUPER_PROPERTY_CALL: | 2424 Property* property = callee_expr->AsProperty(); |
| 2425 VisitNamedSuperPropertyLoad(property, receiver); | |
| 2426 builder()->StoreAccumulatorInRegister(callee); | |
| 2427 break; | |
| 2428 } | |
| 2429 case Call::KEYED_SUPER_PROPERTY_CALL: { | |
| 2430 Property* property = callee_expr->AsProperty(); | |
| 2431 VisitKeyedSuperPropertyLoad(property, receiver); | |
| 2432 builder()->StoreAccumulatorInRegister(callee); | |
| 2433 break; | |
| 2434 } | |
| 2248 case Call::SUPER_CALL: | 2435 case Call::SUPER_CALL: |
| 2249 UNIMPLEMENTED(); | 2436 UNREACHABLE(); |
| 2437 break; | |
| 2250 } | 2438 } |
| 2251 | 2439 |
| 2252 // Evaluate all arguments to the function call and store in sequential | 2440 // Evaluate all arguments to the function call and store in sequential |
| 2253 // registers. | 2441 // registers. |
| 2254 Register arg = VisitArguments(args); | 2442 Register arg = VisitArguments(args); |
| 2255 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); | 2443 CHECK(args->length() == 0 || arg.index() == receiver.index() + 1); |
| 2256 | 2444 |
| 2257 // Resolve callee for a potential direct eval call. This block will mutate the | 2445 // Resolve callee for a potential direct eval call. This block will mutate the |
| 2258 // callee value. | 2446 // callee value. |
| 2259 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { | 2447 if (call_type == Call::POSSIBLY_EVAL_CALL && args->length() > 0) { |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 2283 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5) | 2471 ->CallRuntime(Runtime::kResolvePossiblyDirectEval, callee_for_eval, 5) |
| 2284 .StoreAccumulatorInRegister(callee); | 2472 .StoreAccumulatorInRegister(callee); |
| 2285 } | 2473 } |
| 2286 | 2474 |
| 2287 builder()->SetExpressionPosition(expr); | 2475 builder()->SetExpressionPosition(expr); |
| 2288 builder()->Call(callee, receiver, 1 + args->length(), | 2476 builder()->Call(callee, receiver, 1 + args->length(), |
| 2289 feedback_index(expr->CallFeedbackICSlot())); | 2477 feedback_index(expr->CallFeedbackICSlot())); |
| 2290 execution_result()->SetResultInAccumulator(); | 2478 execution_result()->SetResultInAccumulator(); |
| 2291 } | 2479 } |
| 2292 | 2480 |
| 2481 void BytecodeGenerator::VisitCallSuper(Call* expr) { | |
| 2482 RegisterAllocationScope register_scope(this); | |
| 2483 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | |
| 2484 | |
| 2485 // Prepare the constructor to the super call. | |
| 2486 Register this_function = register_allocator()->NewRegister(); | |
| 2487 VisitForAccumulatorValue(super->this_function_var()); | |
| 2488 builder() | |
| 2489 ->StoreAccumulatorInRegister(this_function) | |
| 2490 .CallRuntime(Runtime::kInlineGetSuperConstructor, this_function, 1); | |
| 2491 | |
| 2492 Register constructor = this_function; // Re-use dead this_function register. | |
| 2493 builder()->StoreAccumulatorInRegister(constructor); | |
| 2494 | |
| 2495 ZoneList<Expression*>* args = expr->arguments(); | |
| 2496 Register first_arg = VisitArguments(args); | |
| 2497 | |
| 2498 // The new target is loaded into the accumulator from the | |
| 2499 // {new.target} variable. | |
| 2500 VisitForAccumulatorValue(super->new_target_var()); | |
| 2501 | |
| 2502 // Call construct. | |
| 2503 builder()->SetExpressionPosition(expr); | |
| 2504 builder()->New(constructor, first_arg, args->length()); | |
| 2505 execution_result()->SetResultInAccumulator(); | |
| 2506 } | |
| 2293 | 2507 |
| 2294 void BytecodeGenerator::VisitCallNew(CallNew* expr) { | 2508 void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
| 2295 Register constructor = register_allocator()->NewRegister(); | 2509 Register constructor = register_allocator()->NewRegister(); |
| 2296 VisitForAccumulatorValue(expr->expression()); | 2510 VisitForAccumulatorValue(expr->expression()); |
| 2297 builder()->StoreAccumulatorInRegister(constructor); | 2511 builder()->StoreAccumulatorInRegister(constructor); |
| 2298 | 2512 |
| 2299 ZoneList<Expression*>* args = expr->arguments(); | 2513 ZoneList<Expression*>* args = expr->arguments(); |
| 2300 Register first_arg = VisitArguments(args); | 2514 Register first_arg = VisitArguments(args); |
| 2515 | |
| 2301 builder()->SetExpressionPosition(expr); | 2516 builder()->SetExpressionPosition(expr); |
| 2302 builder()->New(constructor, first_arg, args->length()); | 2517 // The accumulator holds new target which is the same as the |
| 2518 // constructor for CallNew. | |
| 2519 builder() | |
| 2520 ->LoadAccumulatorWithRegister(constructor) | |
| 2521 .New(constructor, first_arg, args->length()); | |
| 2303 execution_result()->SetResultInAccumulator(); | 2522 execution_result()->SetResultInAccumulator(); |
| 2304 } | 2523 } |
| 2305 | 2524 |
| 2306 | 2525 |
| 2307 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 2526 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 2308 ZoneList<Expression*>* args = expr->arguments(); | 2527 ZoneList<Expression*>* args = expr->arguments(); |
| 2309 if (expr->is_jsruntime()) { | 2528 if (expr->is_jsruntime()) { |
| 2310 // Allocate a register for the receiver and load it with undefined. | 2529 // Allocate a register for the receiver and load it with undefined. |
| 2311 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length()); | 2530 register_allocator()->PrepareForConsecutiveAllocations(1 + args->length()); |
| 2312 Register receiver = register_allocator()->NextConsecutiveRegister(); | 2531 Register receiver = register_allocator()->NextConsecutiveRegister(); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2446 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); | 2665 DCHECK(expr->expression()->IsValidReferenceExpressionOrThis()); |
| 2447 | 2666 |
| 2448 // Left-hand side can only be a property, a global or a variable slot. | 2667 // Left-hand side can only be a property, a global or a variable slot. |
| 2449 Property* property = expr->expression()->AsProperty(); | 2668 Property* property = expr->expression()->AsProperty(); |
| 2450 LhsKind assign_type = Property::GetAssignType(property); | 2669 LhsKind assign_type = Property::GetAssignType(property); |
| 2451 | 2670 |
| 2452 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. | 2671 // TODO(rmcilroy): Set is_postfix to false if visiting for effect. |
| 2453 bool is_postfix = expr->is_postfix(); | 2672 bool is_postfix = expr->is_postfix(); |
| 2454 | 2673 |
| 2455 // Evaluate LHS expression and get old value. | 2674 // Evaluate LHS expression and get old value. |
| 2456 Register obj, key, old_value; | 2675 Register object, key, old_value; |
| 2676 SuperPropertyArguments super_args; | |
| 2457 Handle<String> name; | 2677 Handle<String> name; |
| 2458 switch (assign_type) { | 2678 switch (assign_type) { |
| 2459 case VARIABLE: { | 2679 case VARIABLE: { |
| 2460 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 2680 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 2461 VisitVariableLoadForAccumulatorValue(proxy->var(), | 2681 VisitVariableLoadForAccumulatorValue(proxy->var(), |
| 2462 proxy->VariableFeedbackSlot()); | 2682 proxy->VariableFeedbackSlot()); |
| 2463 break; | 2683 break; |
| 2464 } | 2684 } |
| 2465 case NAMED_PROPERTY: { | 2685 case NAMED_PROPERTY: { |
| 2466 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2686 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2467 obj = VisitForRegisterValue(property->obj()); | 2687 object = VisitForRegisterValue(property->obj()); |
| 2468 name = property->key()->AsLiteral()->AsPropertyName(); | 2688 name = property->key()->AsLiteral()->AsPropertyName(); |
| 2469 builder()->LoadNamedProperty(obj, name, feedback_index(slot), | 2689 builder()->LoadNamedProperty(object, name, feedback_index(slot), |
| 2470 language_mode()); | 2690 language_mode()); |
| 2471 break; | 2691 break; |
| 2472 } | 2692 } |
| 2473 case KEYED_PROPERTY: { | 2693 case KEYED_PROPERTY: { |
| 2474 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); | 2694 FeedbackVectorSlot slot = property->PropertyFeedbackSlot(); |
| 2475 obj = VisitForRegisterValue(property->obj()); | 2695 object = VisitForRegisterValue(property->obj()); |
| 2476 // Use visit for accumulator here since we need the key in the accumulator | 2696 // Use visit for accumulator here since we need the key in the accumulator |
| 2477 // for the LoadKeyedProperty. | 2697 // for the LoadKeyedProperty. |
| 2478 key = register_allocator()->NewRegister(); | 2698 key = register_allocator()->NewRegister(); |
| 2479 VisitForAccumulatorValue(property->key()); | 2699 VisitForAccumulatorValue(property->key()); |
| 2480 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( | 2700 builder()->StoreAccumulatorInRegister(key).LoadKeyedProperty( |
| 2481 obj, feedback_index(slot), language_mode()); | 2701 object, feedback_index(slot), language_mode()); |
| 2482 break; | 2702 break; |
| 2483 } | 2703 } |
| 2484 case NAMED_SUPER_PROPERTY: | 2704 case NAMED_SUPER_PROPERTY: { |
| 2485 case KEYED_SUPER_PROPERTY: | 2705 PrepareNamedSuperPropertyArguments( |
| 2486 UNIMPLEMENTED(); | 2706 property->obj()->AsSuperPropertyReference(), |
| 2707 property->key()->AsLiteral()->AsPropertyName(), &super_args); | |
| 2708 BuildNamedSuperPropertyLoad(&super_args); | |
| 2709 break; | |
| 2710 } | |
| 2711 case KEYED_SUPER_PROPERTY: { | |
| 2712 PrepareKeyedSuperPropertyArguments( | |
| 2713 property->obj()->AsSuperPropertyReference(), property->key(), | |
| 2714 &super_args); | |
| 2715 BuildKeyedSuperPropertyLoad(&super_args); | |
| 2716 break; | |
| 2717 } | |
| 2487 } | 2718 } |
| 2488 | 2719 |
| 2489 // Convert old value into a number. | 2720 // Convert old value into a number. |
| 2490 if (!is_strong(language_mode())) { | 2721 if (!is_strong(language_mode())) { |
| 2491 builder()->CastAccumulatorToNumber(); | 2722 builder()->CastAccumulatorToNumber(); |
| 2492 } | 2723 } |
| 2493 | 2724 |
| 2494 // Save result for postfix expressions. | 2725 // Save result for postfix expressions. |
| 2495 if (is_postfix) { | 2726 if (is_postfix) { |
| 2496 old_value = register_allocator()->outer()->NewRegister(); | 2727 old_value = register_allocator()->outer()->NewRegister(); |
| 2497 builder()->StoreAccumulatorInRegister(old_value); | 2728 builder()->StoreAccumulatorInRegister(old_value); |
| 2498 } | 2729 } |
| 2499 | 2730 |
| 2500 // Perform +1/-1 operation. | 2731 // Perform +1/-1 operation. |
| 2501 builder()->CountOperation(expr->binary_op(), language_mode_strength()); | 2732 builder()->CountOperation(expr->binary_op(), language_mode_strength()); |
| 2502 | 2733 |
| 2503 // Store the value. | 2734 // Store the value. |
| 2504 FeedbackVectorSlot feedback_slot = expr->CountSlot(); | 2735 FeedbackVectorSlot feedback_slot = expr->CountSlot(); |
| 2505 switch (assign_type) { | 2736 switch (assign_type) { |
| 2506 case VARIABLE: { | 2737 case VARIABLE: { |
| 2507 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2738 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
| 2508 VisitVariableAssignment(variable, expr->op(), feedback_slot); | 2739 VisitVariableAssignment(variable, expr->op(), feedback_slot); |
| 2509 break; | 2740 break; |
| 2510 } | 2741 } |
| 2511 case NAMED_PROPERTY: { | 2742 case NAMED_PROPERTY: { |
| 2512 builder()->StoreNamedProperty(obj, name, feedback_index(feedback_slot), | 2743 builder()->StoreNamedProperty(object, name, feedback_index(feedback_slot), |
| 2513 language_mode()); | 2744 language_mode()); |
| 2514 break; | 2745 break; |
| 2515 } | 2746 } |
| 2516 case KEYED_PROPERTY: { | 2747 case KEYED_PROPERTY: { |
| 2517 builder()->StoreKeyedProperty(obj, key, feedback_index(feedback_slot), | 2748 builder()->StoreKeyedProperty(object, key, feedback_index(feedback_slot), |
| 2518 language_mode()); | 2749 language_mode()); |
| 2519 break; | 2750 break; |
| 2520 } | 2751 } |
| 2521 case NAMED_SUPER_PROPERTY: | 2752 case NAMED_SUPER_PROPERTY: { |
| 2522 case KEYED_SUPER_PROPERTY: | 2753 BuildNamedSuperPropertyStore(&super_args); |
| 2523 UNIMPLEMENTED(); | 2754 break; |
| 2755 } | |
| 2756 case KEYED_SUPER_PROPERTY: { | |
| 2757 BuildKeyedSuperPropertyStore(&super_args); | |
| 2758 break; | |
| 2759 } | |
| 2524 } | 2760 } |
| 2525 | 2761 |
| 2526 // Restore old value for postfix expressions. | 2762 // Restore old value for postfix expressions. |
| 2527 if (is_postfix) { | 2763 if (is_postfix) { |
| 2528 execution_result()->SetResultInRegister(old_value); | 2764 execution_result()->SetResultInRegister(old_value); |
| 2529 } else { | 2765 } else { |
| 2530 execution_result()->SetResultInAccumulator(); | 2766 execution_result()->SetResultInAccumulator(); |
| 2531 } | 2767 } |
| 2532 } | 2768 } |
| 2533 | 2769 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2573 UNREACHABLE(); | 2809 UNREACHABLE(); |
| 2574 } | 2810 } |
| 2575 | 2811 |
| 2576 | 2812 |
| 2577 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { | 2813 void BytecodeGenerator::VisitThisFunction(ThisFunction* expr) { |
| 2578 execution_result()->SetResultInRegister(Register::function_closure()); | 2814 execution_result()->SetResultInRegister(Register::function_closure()); |
| 2579 } | 2815 } |
| 2580 | 2816 |
| 2581 | 2817 |
| 2582 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { | 2818 void BytecodeGenerator::VisitSuperCallReference(SuperCallReference* expr) { |
| 2583 UNIMPLEMENTED(); | 2819 // Handled by VisitCall(). |
| 2820 UNREACHABLE(); | |
| 2584 } | 2821 } |
| 2585 | 2822 |
| 2586 | 2823 |
| 2587 void BytecodeGenerator::VisitSuperPropertyReference( | 2824 void BytecodeGenerator::VisitSuperPropertyReference( |
| 2588 SuperPropertyReference* expr) { | 2825 SuperPropertyReference* expr) { |
| 2589 UNIMPLEMENTED(); | 2826 builder()->CallRuntime(Runtime::kThrowUnsupportedSuperError, Register(0), 0); |
| 2827 execution_result()->SetResultInAccumulator(); | |
| 2590 } | 2828 } |
| 2591 | 2829 |
| 2592 | 2830 |
| 2593 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { | 2831 void BytecodeGenerator::VisitCommaExpression(BinaryOperation* binop) { |
| 2594 VisitForEffect(binop->left()); | 2832 VisitForEffect(binop->left()); |
| 2595 Visit(binop->right()); | 2833 Visit(binop->right()); |
| 2596 } | 2834 } |
| 2597 | 2835 |
| 2598 | 2836 |
| 2599 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { | 2837 void BytecodeGenerator::VisitLogicalOrExpression(BinaryOperation* binop) { |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2752 // TODO(rmcilroy): Replace value_out with VisitForRegister(); | 2990 // TODO(rmcilroy): Replace value_out with VisitForRegister(); |
| 2753 if (property == nullptr) { | 2991 if (property == nullptr) { |
| 2754 builder()->LoadNull().StoreAccumulatorInRegister(value_out); | 2992 builder()->LoadNull().StoreAccumulatorInRegister(value_out); |
| 2755 } else { | 2993 } else { |
| 2756 VisitForAccumulatorValue(property->value()); | 2994 VisitForAccumulatorValue(property->value()); |
| 2757 builder()->StoreAccumulatorInRegister(value_out); | 2995 builder()->StoreAccumulatorInRegister(value_out); |
| 2758 VisitSetHomeObject(value_out, home_object, property); | 2996 VisitSetHomeObject(value_out, home_object, property); |
| 2759 } | 2997 } |
| 2760 } | 2998 } |
| 2761 | 2999 |
| 2762 | |
| 2763 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, | 3000 void BytecodeGenerator::VisitSetHomeObject(Register value, Register home_object, |
| 2764 ObjectLiteralProperty* property, | 3001 ObjectLiteralProperty* property, |
| 2765 int slot_number) { | 3002 int slot_number) { |
| 2766 Expression* expr = property->value(); | 3003 Expression* expr = property->value(); |
| 2767 if (!FunctionLiteral::NeedsHomeObject(expr)) return; | 3004 if (FunctionLiteral::NeedsHomeObject(expr)) { |
| 2768 | 3005 Handle<Name> name = isolate()->factory()->home_object_symbol(); |
| 2769 UNIMPLEMENTED(); | 3006 FeedbackVectorSlot slot = property->GetSlot(slot_number); |
| 3007 builder() | |
| 3008 ->LoadAccumulatorWithRegister(home_object) | |
| 3009 .StoreNamedProperty(value, name, feedback_index(slot), language_mode()); | |
| 3010 } | |
| 2770 } | 3011 } |
| 2771 | 3012 |
| 2772 | 3013 |
| 2773 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { | 3014 void BytecodeGenerator::VisitArgumentsObject(Variable* variable) { |
| 2774 if (variable == nullptr) return; | 3015 if (variable == nullptr) return; |
| 2775 | 3016 |
| 2776 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); | 3017 DCHECK(variable->IsContextSlot() || variable->IsStackAllocated()); |
| 2777 | 3018 |
| 2778 // Allocate and initialize a new arguments object and assign to the | 3019 // Allocate and initialize a new arguments object and assign to the |
| 2779 // {arguments} variable. | 3020 // {arguments} variable. |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 2792 // Allocate and initialize a new rest parameter and assign to the {rest} | 3033 // Allocate and initialize a new rest parameter and assign to the {rest} |
| 2793 // variable. | 3034 // variable. |
| 2794 builder()->CreateArguments(CreateArgumentsType::kRestParameter); | 3035 builder()->CreateArguments(CreateArgumentsType::kRestParameter); |
| 2795 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); | 3036 DCHECK(rest->IsContextSlot() || rest->IsStackAllocated()); |
| 2796 VisitVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid()); | 3037 VisitVariableAssignment(rest, Token::ASSIGN, FeedbackVectorSlot::Invalid()); |
| 2797 } | 3038 } |
| 2798 | 3039 |
| 2799 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { | 3040 void BytecodeGenerator::VisitThisFunctionVariable(Variable* variable) { |
| 2800 if (variable == nullptr) return; | 3041 if (variable == nullptr) return; |
| 2801 | 3042 |
| 2802 // TODO(rmcilroy): Remove once we have tests which exercise this code path. | |
| 2803 UNIMPLEMENTED(); | |
| 2804 | |
| 2805 // Store the closure we were called with in the given variable. | 3043 // Store the closure we were called with in the given variable. |
| 2806 builder()->LoadAccumulatorWithRegister(Register::function_closure()); | 3044 builder()->LoadAccumulatorWithRegister(Register::function_closure()); |
| 2807 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); | 3045 VisitVariableAssignment(variable, Token::INIT, FeedbackVectorSlot::Invalid()); |
| 2808 } | 3046 } |
| 2809 | 3047 |
| 2810 | 3048 |
| 2811 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { | 3049 void BytecodeGenerator::VisitNewTargetVariable(Variable* variable) { |
| 2812 if (variable == nullptr) return; | 3050 if (variable == nullptr) return; |
| 2813 | 3051 |
| 2814 // Store the new target we were called with in the given variable. | 3052 // Store the new target we were called with in the given variable. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2891 } | 3129 } |
| 2892 | 3130 |
| 2893 | 3131 |
| 2894 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { | 3132 int BytecodeGenerator::feedback_index(FeedbackVectorSlot slot) const { |
| 2895 return info()->feedback_vector()->GetIndex(slot); | 3133 return info()->feedback_vector()->GetIndex(slot); |
| 2896 } | 3134 } |
| 2897 | 3135 |
| 2898 } // namespace interpreter | 3136 } // namespace interpreter |
| 2899 } // namespace internal | 3137 } // namespace internal |
| 2900 } // namespace v8 | 3138 } // namespace v8 |
| OLD | NEW |