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/interpreter.h" | 5 #include "src/interpreter/interpreter.h" |
| 6 | 6 |
| 7 #include <fstream> | 7 #include <fstream> |
| 8 #include <memory> | 8 #include <memory> |
| 9 | 9 |
| 10 #include "src/ast/prettyprinter.h" | 10 #include "src/ast/prettyprinter.h" |
| (...skipping 1892 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1903 Node* cache_type, Node* cache_array, | 1903 Node* cache_type, Node* cache_array, |
| 1904 Node* cache_length, | 1904 Node* cache_length, |
| 1905 InterpreterAssembler* assembler) { | 1905 InterpreterAssembler* assembler) { |
| 1906 __ StoreRegister(cache_type, output_register); | 1906 __ StoreRegister(cache_type, output_register); |
| 1907 output_register = __ NextRegister(output_register); | 1907 output_register = __ NextRegister(output_register); |
| 1908 __ StoreRegister(cache_array, output_register); | 1908 __ StoreRegister(cache_array, output_register); |
| 1909 output_register = __ NextRegister(output_register); | 1909 output_register = __ NextRegister(output_register); |
| 1910 __ StoreRegister(cache_length, output_register); | 1910 __ StoreRegister(cache_length, output_register); |
| 1911 } | 1911 } |
| 1912 | 1912 |
| 1913 // ForInPrepare <cache_info_triple> | 1913 // ForInPrepare <cache_info_triple> |
|
rmcilroy
2016/08/04 15:41:45
I know you didn't change this, but could you updat
klaasb
2016/08/05 16:08:34
Oops, I actually did that change, just in an earli
| |
| 1914 // | 1914 // |
| 1915 // Returns state for for..in loop execution based on the object in the | 1915 // Returns state for for..in loop execution based on the object in the |
| 1916 // accumulator. The result is output in registers |cache_info_triple| to | 1916 // accumulator. The result is output in registers |cache_info_triple| to |
| 1917 // |cache_info_triple + 2|, with the registers holding cache_type, cache_array, | 1917 // |cache_info_triple + 2|, with the registers holding cache_type, cache_array, |
| 1918 // and cache_length respectively. | 1918 // and cache_length respectively. |
| 1919 void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) { | 1919 void Interpreter::DoForInPrepare(InterpreterAssembler* assembler) { |
| 1920 Node* object_reg = __ BytecodeOperandReg(0); | 1920 Node* object_reg = __ BytecodeOperandReg(0); |
| 1921 Node* object = __ LoadRegister(object_reg); | 1921 Node* receiver = __ LoadRegister(object_reg); |
| 1922 Node* context = __ GetContext(); | 1922 Node* context = __ GetContext(); |
| 1923 Node* const zero_smi = __ SmiConstant(Smi::FromInt(0)); | 1923 Node* const zero_smi = __ SmiConstant(Smi::FromInt(0)); |
| 1924 | 1924 |
|
rmcilroy
2016/08/04 15:41:45
Could you add some debug code (with "if (FLAG_debu
klaasb
2016/08/05 16:08:34
Done.
| |
| 1925 Label test_if_null(assembler), test_if_undefined(assembler), | 1925 Label nothing_to_iterate(assembler, Label::kDeferred), |
| 1926 nothing_to_iterate(assembler, Label::kDeferred), | 1926 use_enum_cache(assembler), use_runtime(assembler, Label::kDeferred); |
| 1927 convert_to_receiver(assembler, Label::kDeferred), | |
| 1928 already_receiver(assembler), check_enum_cache(assembler); | |
| 1929 | 1927 |
| 1930 Variable receiver(assembler, MachineRepresentation::kTagged); | 1928 __ CheckEnumCache(receiver, &use_enum_cache, &use_runtime); |
| 1931 | |
| 1932 // Test if object is already a receiver, no conversion necessary if so. | |
| 1933 Node* instance_type = __ LoadInstanceType(object); | |
| 1934 Node* first_receiver_type = __ Int32Constant(FIRST_JS_RECEIVER_TYPE); | |
| 1935 __ BranchIfInt32GreaterThanOrEqual(instance_type, first_receiver_type, | |
| 1936 &already_receiver, &test_if_null); | |
| 1937 | |
| 1938 __ Bind(&test_if_null); | |
| 1939 { | |
| 1940 __ BranchIfWordEqual(object, assembler->NullConstant(), ¬hing_to_iterate, | |
| 1941 &test_if_undefined); | |
| 1942 } | |
| 1943 | |
| 1944 __ Bind(&test_if_undefined); | |
| 1945 { | |
| 1946 __ BranchIfWordEqual(object, assembler->UndefinedConstant(), | |
| 1947 ¬hing_to_iterate, &convert_to_receiver); | |
|
rmcilroy
2016/08/04 14:06:35
I think we still need the null and undefined check
klaasb
2016/08/04 15:20:54
Null/undefined are also handled in bytecode alread
| |
| 1948 } | |
| 1949 | |
| 1950 __ Bind(&convert_to_receiver); | |
| 1951 { | |
| 1952 Callable callable = CodeFactory::ToObject(assembler->isolate()); | |
| 1953 Node* target = __ HeapConstant(callable.code()); | |
| 1954 Node* result = __ CallStub(callable.descriptor(), target, context, object); | |
| 1955 receiver.Bind(result); | |
| 1956 __ Goto(&check_enum_cache); | |
| 1957 } | |
| 1958 | |
| 1959 __ Bind(&already_receiver); | |
| 1960 { | |
| 1961 receiver.Bind(object); | |
| 1962 __ Goto(&check_enum_cache); | |
| 1963 } | |
| 1964 | |
| 1965 Label use_enum_cache(assembler), use_runtime(assembler, Label::kDeferred); | |
| 1966 __ Bind(&check_enum_cache); | |
| 1967 { __ CheckEnumCache(receiver.value(), &use_enum_cache, &use_runtime); } | |
| 1968 | 1929 |
| 1969 __ Bind(&use_enum_cache); | 1930 __ Bind(&use_enum_cache); |
| 1970 { | 1931 { |
| 1971 // The enum cache is valid. Load the map of the object being | 1932 // The enum cache is valid. Load the map of the object being |
| 1972 // iterated over and use the cache for the iteration. | 1933 // iterated over and use the cache for the iteration. |
| 1973 Node* cache_type = __ LoadMap(receiver.value()); | 1934 Node* cache_type = __ LoadMap(receiver); |
| 1974 Node* cache_length = __ EnumLength(cache_type); | 1935 Node* cache_length = __ EnumLength(cache_type); |
| 1975 __ GotoIf(assembler->WordEqual(cache_length, zero_smi), | 1936 __ GotoIf(assembler->WordEqual(cache_length, zero_smi), |
| 1976 ¬hing_to_iterate); | 1937 ¬hing_to_iterate); |
| 1977 Node* descriptors = __ LoadMapDescriptors(cache_type); | 1938 Node* descriptors = __ LoadMapDescriptors(cache_type); |
| 1978 Node* cache_offset = | 1939 Node* cache_offset = |
| 1979 __ LoadObjectField(descriptors, DescriptorArray::kEnumCacheOffset); | 1940 __ LoadObjectField(descriptors, DescriptorArray::kEnumCacheOffset); |
| 1980 Node* cache_array = __ LoadObjectField( | 1941 Node* cache_array = __ LoadObjectField( |
| 1981 cache_offset, DescriptorArray::kEnumCacheBridgeCacheOffset); | 1942 cache_offset, DescriptorArray::kEnumCacheBridgeCacheOffset); |
| 1982 Node* output_register = __ BytecodeOperandReg(1); | 1943 Node* output_register = __ BytecodeOperandReg(1); |
| 1983 BuildForInPrepareResult(output_register, cache_type, cache_array, | 1944 BuildForInPrepareResult(output_register, cache_type, cache_array, |
| 1984 cache_length, assembler); | 1945 cache_length, assembler); |
| 1985 __ Dispatch(); | 1946 __ Dispatch(); |
| 1986 } | 1947 } |
| 1987 | 1948 |
| 1988 __ Bind(&use_runtime); | 1949 __ Bind(&use_runtime); |
| 1989 { | 1950 { |
| 1990 Node* result_triple = | 1951 Node* result_triple = |
| 1991 __ CallRuntime(Runtime::kForInPrepare, context, object); | 1952 __ CallRuntime(Runtime::kForInPrepare, context, receiver); |
| 1992 Node* cache_type = __ Projection(0, result_triple); | 1953 Node* cache_type = __ Projection(0, result_triple); |
| 1993 Node* cache_array = __ Projection(1, result_triple); | 1954 Node* cache_array = __ Projection(1, result_triple); |
| 1994 Node* cache_length = __ Projection(2, result_triple); | 1955 Node* cache_length = __ Projection(2, result_triple); |
| 1995 Node* output_register = __ BytecodeOperandReg(1); | 1956 Node* output_register = __ BytecodeOperandReg(1); |
| 1996 BuildForInPrepareResult(output_register, cache_type, cache_array, | 1957 BuildForInPrepareResult(output_register, cache_type, cache_array, |
| 1997 cache_length, assembler); | 1958 cache_length, assembler); |
| 1998 __ Dispatch(); | 1959 __ Dispatch(); |
| 1999 } | 1960 } |
| 2000 | 1961 |
| 2001 __ Bind(¬hing_to_iterate); | 1962 __ Bind(¬hing_to_iterate); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2180 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, | 2141 __ StoreObjectField(generator, JSGeneratorObject::kContinuationOffset, |
| 2181 __ SmiTag(new_state)); | 2142 __ SmiTag(new_state)); |
| 2182 __ SetAccumulator(old_state); | 2143 __ SetAccumulator(old_state); |
| 2183 | 2144 |
| 2184 __ Dispatch(); | 2145 __ Dispatch(); |
| 2185 } | 2146 } |
| 2186 | 2147 |
| 2187 } // namespace interpreter | 2148 } // namespace interpreter |
| 2188 } // namespace internal | 2149 } // namespace internal |
| 2189 } // namespace v8 | 2150 } // namespace v8 |
| OLD | NEW |