5 #include "src/builtins/builtins-utils-inl.h" 6 #include "src/builtins/builtins.h" 7 #include "src/code-factory.h" 8 #include "src/compiler.h" 9 #include "src/conversions.h" 10 #include "src/counters.h" 11 #include "src/lookup.h" 12 #include "src/objects-inl.h" 13 #include "src/objects/api-callbacks.h" 14 #include "src/string-builder-inl.h" 22 MaybeHandle<Object> CreateDynamicFunction(Isolate* isolate,
23 BuiltinArguments args,
26 DCHECK_LE(1, args.length());
27 int const argc = args.length() - 1;
29 Handle<JSFunction> target = args.target();
30 Handle<JSObject> target_global_proxy(target->global_proxy(), isolate);
32 if (!Builtins::AllowDynamicFunction(isolate, target, target_global_proxy)) {
33 isolate->CountUsage(v8::Isolate::kFunctionConstructorReturnedUndefined);
34 return isolate->factory()->undefined_value();
38 Handle<String> source;
39 int parameters_end_pos = kNoSourcePosition;
41 IncrementalStringBuilder builder(isolate);
42 builder.AppendCharacter(
'(');
43 builder.AppendCString(token);
44 builder.AppendCString(
" anonymous(");
45 bool parenthesis_in_arg_string =
false;
47 for (
int i = 1;
i < argc; ++
i) {
48 if (
i > 1) builder.AppendCharacter(
',');
50 ASSIGN_RETURN_ON_EXCEPTION(
51 isolate, param, Object::ToString(isolate, args.at(
i)), Object);
52 param = String::Flatten(isolate, param);
53 builder.AppendString(param);
56 builder.AppendCharacter(
'\n');
57 parameters_end_pos = builder.Length();
58 builder.AppendCString(
") {\n");
61 ASSIGN_RETURN_ON_EXCEPTION(
62 isolate, body, Object::ToString(isolate, args.at(argc)), Object);
63 builder.AppendString(body);
65 builder.AppendCString(
"\n})");
66 ASSIGN_RETURN_ON_EXCEPTION(isolate, source, builder.Finish(), Object);
70 if (parenthesis_in_arg_string) {
71 THROW_NEW_ERROR(isolate,
72 NewSyntaxError(MessageTemplate::kParenthesisInArgString),
79 Handle<JSFunction>
function;
81 ASSIGN_RETURN_ON_EXCEPTION(
83 Compiler::GetFunctionFromString(
84 handle(target->native_context(), isolate), source,
85 ONLY_SINGLE_FUNCTION_LITERAL, parameters_end_pos),
87 Handle<Object> result;
88 ASSIGN_RETURN_ON_EXCEPTION(
90 Execution::Call(isolate,
function, target_global_proxy, 0,
nullptr),
92 function = Handle<JSFunction>::cast(result);
93 function->shared()->set_name_should_print_as_anonymous(
true);
102 Handle<Object> unchecked_new_target = args.new_target();
103 if (!unchecked_new_target->IsUndefined(isolate) &&
104 !unchecked_new_target.is_identical_to(target)) {
105 Handle<JSReceiver> new_target =
106 Handle<JSReceiver>::cast(unchecked_new_target);
107 Handle<Map> initial_map;
108 ASSIGN_RETURN_ON_EXCEPTION(
109 isolate, initial_map,
110 JSFunction::GetDerivedMap(isolate, target, new_target), Object);
112 Handle<SharedFunctionInfo> shared_info(function->shared(), isolate);
113 Handle<Map> map = Map::AsLanguageMode(isolate, initial_map, shared_info);
115 Handle<Context> context(function->context(), isolate);
116 function = isolate->factory()->NewFunctionFromSharedFunctionInfo(
117 map, shared_info, context, NOT_TENURED);
125 BUILTIN(FunctionConstructor) {
126 HandleScope scope(isolate);
127 Handle<Object> result;
128 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
129 isolate, result, CreateDynamicFunction(isolate, args,
"function"));
134 BUILTIN(GeneratorFunctionConstructor) {
135 HandleScope scope(isolate);
136 RETURN_RESULT_OR_FAILURE(isolate,
137 CreateDynamicFunction(isolate, args,
"function*"));
140 BUILTIN(AsyncFunctionConstructor) {
141 HandleScope scope(isolate);
142 Handle<Object> maybe_func;
143 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
145 CreateDynamicFunction(isolate, args,
"async function"));
146 if (!maybe_func->IsJSFunction())
return *maybe_func;
150 Handle<JSFunction> func = Handle<JSFunction>::cast(maybe_func);
151 Handle<Script> script =
152 handle(Script::cast(func->shared()->script()), isolate);
153 int position = script->GetEvalPosition();
159 BUILTIN(AsyncGeneratorFunctionConstructor) {
160 HandleScope scope(isolate);
161 Handle<Object> maybe_func;
162 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
164 CreateDynamicFunction(isolate, args,
"async function*"));
165 if (!maybe_func->IsJSFunction())
return *maybe_func;
169 Handle<JSFunction> func = Handle<JSFunction>::cast(maybe_func);
170 Handle<Script> script =
171 handle(Script::cast(func->shared()->script()), isolate);
172 int position = script->GetEvalPosition();
180 Object* DoFunctionBind(Isolate* isolate, BuiltinArguments args) {
181 HandleScope scope(isolate);
182 DCHECK_LE(1, args.length());
183 if (!args.receiver()->IsCallable()) {
184 THROW_NEW_ERROR_RETURN_FAILURE(
185 isolate, NewTypeError(MessageTemplate::kFunctionBind));
189 Handle<JSReceiver> target = args.at<JSReceiver>(0);
190 Handle<Object> this_arg = isolate->factory()->undefined_value();
191 ScopedVector<Handle<Object>> argv(std::max(0, args.length() - 2));
192 if (args.length() > 1) {
193 this_arg = args.at(1);
194 for (
int i = 2;
i < args.length(); ++
i) {
195 argv[
i - 2] = args.at(
i);
198 Handle<JSBoundFunction>
function;
199 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
201 isolate->factory()->NewJSBoundFunction(target, this_arg, argv));
203 LookupIterator length_lookup(target, isolate->factory()->length_string(),
204 target, LookupIterator::OWN);
209 if (!target->IsJSFunction() ||
210 length_lookup.state() != LookupIterator::ACCESSOR ||
211 !length_lookup.GetAccessors()->IsAccessorInfo()) {
212 Handle<Object> length(Smi::kZero, isolate);
213 Maybe<PropertyAttributes> attributes =
214 JSReceiver::GetPropertyAttributes(&length_lookup);
215 if (attributes.IsNothing())
return ReadOnlyRoots(isolate).exception();
216 if (attributes.FromJust() != ABSENT) {
217 Handle<Object> target_length;
218 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target_length,
219 Object::GetProperty(&length_lookup));
220 if (target_length->IsNumber()) {
221 length = isolate->factory()->NewNumber(std::max(
222 0.0, DoubleToInteger(target_length->Number()) - argv.length()));
225 LookupIterator it(
function, isolate->factory()->length_string(),
function);
226 DCHECK_EQ(LookupIterator::ACCESSOR, it.state());
227 RETURN_FAILURE_ON_EXCEPTION(isolate,
228 JSObject::DefineOwnPropertyIgnoreAttributes(
229 &it, length, it.property_attributes()));
236 LookupIterator name_lookup(target, isolate->factory()->name_string(), target);
237 if (!target->IsJSFunction() ||
238 name_lookup.state() != LookupIterator::ACCESSOR ||
239 !name_lookup.GetAccessors()->IsAccessorInfo() ||
240 (name_lookup.IsFound() && !name_lookup.HolderIsReceiver())) {
241 Handle<Object> target_name;
242 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, target_name,
243 Object::GetProperty(&name_lookup));
245 if (target_name->IsString()) {
246 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
248 Name::ToFunctionName(isolate, Handle<String>::cast(target_name)));
249 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
250 isolate, name, isolate->factory()->NewConsString(
251 isolate->factory()->bound__string(), name));
253 name = isolate->factory()->bound__string();
255 LookupIterator it(isolate,
function, isolate->factory()->name_string());
256 DCHECK_EQ(LookupIterator::ACCESSOR, it.state());
257 RETURN_FAILURE_ON_EXCEPTION(isolate,
258 JSObject::DefineOwnPropertyIgnoreAttributes(
259 &it, name, it.property_attributes()));
267 BUILTIN(FunctionPrototypeBind) {
return DoFunctionBind(isolate, args); }
270 BUILTIN(FunctionPrototypeToString) {
271 HandleScope scope(isolate);
272 Handle<Object> receiver = args.receiver();
273 if (receiver->IsJSBoundFunction()) {
274 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver));
276 if (receiver->IsJSFunction()) {
277 return *JSFunction::ToString(Handle<JSFunction>::cast(receiver));
281 if (receiver->IsJSReceiver() &&
282 JSReceiver::cast(*receiver)->map()->is_callable()) {
283 return ReadOnlyRoots(isolate).function_native_code_string();
285 THROW_NEW_ERROR_RETURN_FAILURE(
286 isolate, NewTypeError(MessageTemplate::kNotGeneric,
287 isolate->factory()->NewStringFromAsciiChecked(
288 "Function.prototype.toString"),
289 isolate->factory()->Function_string()));