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