OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/builtins.h" | 5 #include "src/builtins.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
11 #include "src/bootstrapper.h" | 11 #include "src/bootstrapper.h" |
12 #include "src/elements.h" | 12 #include "src/elements.h" |
13 #include "src/frames-inl.h" | 13 #include "src/frames-inl.h" |
14 #include "src/gdb-jit.h" | 14 #include "src/gdb-jit.h" |
15 #include "src/ic/handler-compiler.h" | 15 #include "src/ic/handler-compiler.h" |
16 #include "src/ic/ic.h" | 16 #include "src/ic/ic.h" |
17 #include "src/isolate-inl.h" | 17 #include "src/isolate-inl.h" |
18 #include "src/messages.h" | 18 #include "src/messages.h" |
19 #include "src/profiler/cpu-profiler.h" | 19 #include "src/profiler/cpu-profiler.h" |
20 #include "src/property-descriptor.h" | 20 #include "src/property-descriptor.h" |
21 #include "src/prototype.h" | 21 #include "src/prototype.h" |
| 22 #include "src/string-builder.h" |
22 #include "src/vm-state-inl.h" | 23 #include "src/vm-state-inl.h" |
23 | 24 |
24 namespace v8 { | 25 namespace v8 { |
25 namespace internal { | 26 namespace internal { |
26 | 27 |
27 namespace { | 28 namespace { |
28 | 29 |
29 // Arguments object passed to C++ builtins. | 30 // Arguments object passed to C++ builtins. |
30 template <BuiltinExtraArguments extra_args> | 31 template <BuiltinExtraArguments extra_args> |
31 class BuiltinArguments : public Arguments { | 32 class BuiltinArguments : public Arguments { |
(...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1496 // No callback set and code generation disallowed. | 1497 // No callback set and code generation disallowed. |
1497 return false; | 1498 return false; |
1498 } else { | 1499 } else { |
1499 // Callback set. Let it decide if code generation is allowed. | 1500 // Callback set. Let it decide if code generation is allowed. |
1500 VMState<EXTERNAL> state(isolate); | 1501 VMState<EXTERNAL> state(isolate); |
1501 return callback(v8::Utils::ToLocal(context)); | 1502 return callback(v8::Utils::ToLocal(context)); |
1502 } | 1503 } |
1503 } | 1504 } |
1504 | 1505 |
1505 | 1506 |
1506 // TODO(bmeurer): Also migrate the Function constructor to C++ and share this. | |
1507 MaybeHandle<JSFunction> CompileString(Handle<Context> context, | 1507 MaybeHandle<JSFunction> CompileString(Handle<Context> context, |
1508 Handle<String> source, | 1508 Handle<String> source, |
1509 ParseRestriction restriction) { | 1509 ParseRestriction restriction) { |
1510 Isolate* const isolate = context->GetIsolate(); | 1510 Isolate* const isolate = context->GetIsolate(); |
1511 Handle<Context> native_context(context->native_context(), isolate); | 1511 Handle<Context> native_context(context->native_context(), isolate); |
1512 | 1512 |
1513 // Check if native context allows code generation from | 1513 // Check if native context allows code generation from |
1514 // strings. Throw an exception if it doesn't. | 1514 // strings. Throw an exception if it doesn't. |
1515 if (native_context->allow_code_gen_from_strings()->IsFalse() && | 1515 if (native_context->allow_code_gen_from_strings()->IsFalse() && |
1516 !CodeGenerationFromStringsAllowed(isolate, native_context)) { | 1516 !CodeGenerationFromStringsAllowed(isolate, native_context)) { |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1839 } | 1839 } |
1840 Handle<JSReceiver> receiver = args.at<JSReceiver>(0); | 1840 Handle<JSReceiver> receiver = args.at<JSReceiver>(0); |
1841 Handle<Object> hint = args.at<Object>(1); | 1841 Handle<Object> hint = args.at<Object>(1); |
1842 Handle<Object> result; | 1842 Handle<Object> result; |
1843 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, | 1843 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, |
1844 JSDate::ToPrimitive(receiver, hint)); | 1844 JSDate::ToPrimitive(receiver, hint)); |
1845 return *result; | 1845 return *result; |
1846 } | 1846 } |
1847 | 1847 |
1848 | 1848 |
| 1849 namespace { |
| 1850 |
| 1851 // ES6 section 19.2.1.1.1 CreateDynamicFunction |
| 1852 MaybeHandle<JSFunction> CreateDynamicFunction( |
| 1853 Isolate* isolate, |
| 1854 BuiltinArguments<BuiltinExtraArguments::kTargetAndNewTarget> args, |
| 1855 const char* token) { |
| 1856 // Compute number of arguments, ignoring the receiver. |
| 1857 DCHECK_LE(1, args.length()); |
| 1858 int const argc = args.length() - 1; |
| 1859 |
| 1860 // Build the source string. |
| 1861 Handle<String> source; |
| 1862 { |
| 1863 IncrementalStringBuilder builder(isolate); |
| 1864 builder.AppendCharacter('('); |
| 1865 builder.AppendCString(token); |
| 1866 builder.AppendCharacter('('); |
| 1867 bool parenthesis_in_arg_string = false; |
| 1868 if (argc > 1) { |
| 1869 for (int i = 1; i < argc; ++i) { |
| 1870 if (i > 1) builder.AppendCharacter(','); |
| 1871 Handle<String> param; |
| 1872 ASSIGN_RETURN_ON_EXCEPTION( |
| 1873 isolate, param, Object::ToString(isolate, args.at<Object>(i)), |
| 1874 JSFunction); |
| 1875 param = String::Flatten(param); |
| 1876 builder.AppendString(param); |
| 1877 // If the formal parameters string include ) - an illegal |
| 1878 // character - it may make the combined function expression |
| 1879 // compile. We avoid this problem by checking for this early on. |
| 1880 DisallowHeapAllocation no_gc; // Ensure vectors stay valid. |
| 1881 String::FlatContent param_content = param->GetFlatContent(); |
| 1882 for (int i = 0, length = param->length(); i < length; ++i) { |
| 1883 if (param_content.Get(i) == ')') { |
| 1884 parenthesis_in_arg_string = true; |
| 1885 break; |
| 1886 } |
| 1887 } |
| 1888 } |
| 1889 // If the formal parameters include an unbalanced block comment, the |
| 1890 // function must be rejected. Since JavaScript does not allow nested |
| 1891 // comments we can include a trailing block comment to catch this. |
| 1892 builder.AppendCString("\n/**/"); |
| 1893 } |
| 1894 builder.AppendCString(") {\n"); |
| 1895 if (argc > 0) { |
| 1896 Handle<String> body; |
| 1897 ASSIGN_RETURN_ON_EXCEPTION( |
| 1898 isolate, body, Object::ToString(isolate, args.at<Object>(argc)), |
| 1899 JSFunction); |
| 1900 builder.AppendString(body); |
| 1901 } |
| 1902 builder.AppendCString("\n})"); |
| 1903 ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), JSFunction); |
| 1904 |
| 1905 // The SyntaxError must be thrown after all the (observable) ToString |
| 1906 // conversions are done. |
| 1907 if (parenthesis_in_arg_string) { |
| 1908 THROW_NEW_ERROR(isolate, |
| 1909 NewSyntaxError(MessageTemplate::kParenthesisInArgString), |
| 1910 JSFunction); |
| 1911 } |
| 1912 } |
| 1913 |
| 1914 // Compile the string in the constructor and not a helper so that errors to |
| 1915 // come from here. |
| 1916 Handle<JSFunction> target = args.target(); |
| 1917 Handle<JSObject> target_global_proxy(target->global_proxy(), isolate); |
| 1918 Handle<JSFunction> function; |
| 1919 { |
| 1920 ASSIGN_RETURN_ON_EXCEPTION( |
| 1921 isolate, function, |
| 1922 CompileString(handle(target->native_context(), isolate), source, |
| 1923 ONLY_SINGLE_FUNCTION_LITERAL), |
| 1924 JSFunction); |
| 1925 Handle<Object> result; |
| 1926 ASSIGN_RETURN_ON_EXCEPTION( |
| 1927 isolate, result, |
| 1928 Execution::Call(isolate, function, target_global_proxy, 0, nullptr), |
| 1929 JSFunction); |
| 1930 function = Handle<JSFunction>::cast(result); |
| 1931 function->shared()->set_name_should_print_as_anonymous(true); |
| 1932 } |
| 1933 |
| 1934 // If new.target is equal to target then the function created |
| 1935 // is already correctly setup and nothing else should be done |
| 1936 // here. But if new.target is not equal to target then we are |
| 1937 // have a Function builtin subclassing case and therefore the |
| 1938 // function has wrong initial map. To fix that we create a new |
| 1939 // function object with correct initial map. |
| 1940 Handle<Object> unchecked_new_target = args.new_target(); |
| 1941 if (!unchecked_new_target->IsUndefined() && |
| 1942 !unchecked_new_target.is_identical_to(target)) { |
| 1943 Handle<JSReceiver> new_target = |
| 1944 Handle<JSReceiver>::cast(unchecked_new_target); |
| 1945 Handle<Map> initial_map; |
| 1946 ASSIGN_RETURN_ON_EXCEPTION( |
| 1947 isolate, initial_map, |
| 1948 JSFunction::GetDerivedMap(isolate, target, new_target), JSFunction); |
| 1949 |
| 1950 Handle<SharedFunctionInfo> shared_info(function->shared(), isolate); |
| 1951 Handle<Map> map = Map::AsLanguageMode( |
| 1952 initial_map, shared_info->language_mode(), shared_info->kind()); |
| 1953 |
| 1954 Handle<Context> context(function->context(), isolate); |
| 1955 function = isolate->factory()->NewFunctionFromSharedFunctionInfo( |
| 1956 map, shared_info, context, NOT_TENURED); |
| 1957 } |
| 1958 return function; |
| 1959 } |
| 1960 |
| 1961 } // namespace |
| 1962 |
| 1963 |
| 1964 // ES6 section 19.2.1.1 Function ( p1, p2, ... , pn, body ) |
| 1965 BUILTIN(FunctionConstructor) { |
| 1966 HandleScope scope(isolate); |
| 1967 Handle<JSFunction> result; |
| 1968 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1969 isolate, result, CreateDynamicFunction(isolate, args, "function")); |
| 1970 return *result; |
| 1971 } |
| 1972 |
| 1973 |
1849 // ES6 section 19.2.3.5 Function.prototype.toString ( ) | 1974 // ES6 section 19.2.3.5 Function.prototype.toString ( ) |
1850 BUILTIN(FunctionPrototypeToString) { | 1975 BUILTIN(FunctionPrototypeToString) { |
1851 HandleScope scope(isolate); | 1976 HandleScope scope(isolate); |
1852 Handle<Object> receiver = args.receiver(); | 1977 Handle<Object> receiver = args.receiver(); |
1853 | 1978 |
1854 if (receiver->IsJSFunction()) { | 1979 if (receiver->IsJSFunction()) { |
1855 return *JSFunction::ToString(Handle<JSFunction>::cast(receiver)); | 1980 return *JSFunction::ToString(Handle<JSFunction>::cast(receiver)); |
1856 } | 1981 } |
1857 THROW_NEW_ERROR_RETURN_FAILURE( | 1982 THROW_NEW_ERROR_RETURN_FAILURE( |
1858 isolate, NewTypeError(MessageTemplate::kNotGeneric, | 1983 isolate, NewTypeError(MessageTemplate::kNotGeneric, |
1859 isolate->factory()->NewStringFromAsciiChecked( | 1984 isolate->factory()->NewStringFromAsciiChecked( |
1860 "Function.prototype.toString"))); | 1985 "Function.prototype.toString"))); |
1861 } | 1986 } |
1862 | 1987 |
1863 | 1988 |
| 1989 // ES6 section 25.2.1.1 GeneratorFunction (p1, p2, ... , pn, body) |
| 1990 BUILTIN(GeneratorFunctionConstructor) { |
| 1991 HandleScope scope(isolate); |
| 1992 Handle<JSFunction> result; |
| 1993 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 1994 isolate, result, CreateDynamicFunction(isolate, args, "function*")); |
| 1995 return *result; |
| 1996 } |
| 1997 |
| 1998 |
1864 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Call]] case. | 1999 // ES6 section 19.4.1.1 Symbol ( [ description ] ) for the [[Call]] case. |
1865 BUILTIN(SymbolConstructor) { | 2000 BUILTIN(SymbolConstructor) { |
1866 HandleScope scope(isolate); | 2001 HandleScope scope(isolate); |
1867 DCHECK_EQ(2, args.length()); | 2002 DCHECK_EQ(2, args.length()); |
1868 Handle<Symbol> result = isolate->factory()->NewSymbol(); | 2003 Handle<Symbol> result = isolate->factory()->NewSymbol(); |
1869 Handle<Object> description = args.at<Object>(1); | 2004 Handle<Object> description = args.at<Object>(1); |
1870 if (!description->IsUndefined()) { | 2005 if (!description->IsUndefined()) { |
1871 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, description, | 2006 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, description, |
1872 Object::ToString(isolate, description)); | 2007 Object::ToString(isolate, description)); |
1873 result->set_name(*description); | 2008 result->set_name(*description); |
(...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2590 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 2725 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
2591 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 2726 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
2592 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 2727 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
2593 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 2728 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
2594 #undef DEFINE_BUILTIN_ACCESSOR_C | 2729 #undef DEFINE_BUILTIN_ACCESSOR_C |
2595 #undef DEFINE_BUILTIN_ACCESSOR_A | 2730 #undef DEFINE_BUILTIN_ACCESSOR_A |
2596 | 2731 |
2597 | 2732 |
2598 } // namespace internal | 2733 } // namespace internal |
2599 } // namespace v8 | 2734 } // namespace v8 |
OLD | NEW |