Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: src/builtins/builtins-function.cc

Issue 2752143004: [refactor] Separate generated builtins and C++ builtins into separate files (Closed)
Patch Set: tentative gcmole fix Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/builtins/builtins-forin-gen.cc ('k') | src/builtins/builtins-function-gen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/builtins-utils.h" 5 #include "src/builtins/builtins-utils.h"
6 #include "src/builtins/builtins.h" 6 #include "src/builtins/builtins.h"
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/code-stub-assembler.h"
9 #include "src/compiler.h" 8 #include "src/compiler.h"
10 #include "src/conversions.h" 9 #include "src/conversions.h"
11 #include "src/counters.h" 10 #include "src/counters.h"
12 #include "src/lookup.h" 11 #include "src/lookup.h"
13 #include "src/objects-inl.h" 12 #include "src/objects-inl.h"
14 #include "src/string-builder.h" 13 #include "src/string-builder.h"
15 14
16 namespace v8 { 15 namespace v8 {
17 namespace internal { 16 namespace internal {
18 17
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 &it, name, it.property_attributes())); 264 &it, name, it.property_attributes()));
266 } 265 }
267 return *function; 266 return *function;
268 } 267 }
269 268
270 } // namespace 269 } // namespace
271 270
272 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args ) 271 // ES6 section 19.2.3.2 Function.prototype.bind ( thisArg, ...args )
273 BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); } 272 BUILTIN(FunctionPrototypeBind) { return DoFunctionBind(isolate, args); }
274 273
275 TF_BUILTIN(FastFunctionPrototypeBind, CodeStubAssembler) {
276 Label slow(this);
277
278 Node* argc = Parameter(BuiltinDescriptor::kArgumentsCount);
279 Node* context = Parameter(BuiltinDescriptor::kContext);
280 Node* new_target = Parameter(BuiltinDescriptor::kNewTarget);
281
282 CodeStubArguments args(this, ChangeInt32ToIntPtr(argc));
283
284 // Check that receiver has instance type of JS_FUNCTION_TYPE
285 Node* receiver = args.GetReceiver();
286 GotoIf(TaggedIsSmi(receiver), &slow);
287
288 Node* receiver_map = LoadMap(receiver);
289 Node* instance_type = LoadMapInstanceType(receiver_map);
290 GotoIf(Word32NotEqual(instance_type, Int32Constant(JS_FUNCTION_TYPE)), &slow);
291
292 // Disallow binding of slow-mode functions. We need to figure out whether the
293 // length and name property are in the original state.
294 Comment("Disallow binding of slow-mode functions");
295 GotoIf(IsDictionaryMap(receiver_map), &slow);
296
297 // Check whether the length and name properties are still present as
298 // AccessorInfo objects. In that case, their value can be recomputed even if
299 // the actual value on the object changes.
300 Comment("Check descriptor array length");
301 Node* descriptors = LoadMapDescriptors(receiver_map);
302 Node* descriptors_length = LoadFixedArrayBaseLength(descriptors);
303 GotoIf(SmiLessThanOrEqual(descriptors_length, SmiConstant(1)), &slow);
304
305 // Check whether the length and name properties are still present as
306 // AccessorInfo objects. In that case, their value can be recomputed even if
307 // the actual value on the object changes.
308 Comment("Check name and length properties");
309 const int length_index = JSFunction::kLengthDescriptorIndex;
310 Node* maybe_length = LoadFixedArrayElement(
311 descriptors, DescriptorArray::ToKeyIndex(length_index));
312 GotoIf(WordNotEqual(maybe_length, LoadRoot(Heap::klength_stringRootIndex)),
313 &slow);
314
315 Node* maybe_length_accessor = LoadFixedArrayElement(
316 descriptors, DescriptorArray::ToValueIndex(length_index));
317 GotoIf(TaggedIsSmi(maybe_length_accessor), &slow);
318 Node* length_value_map = LoadMap(maybe_length_accessor);
319 GotoIfNot(IsAccessorInfoMap(length_value_map), &slow);
320
321 const int name_index = JSFunction::kNameDescriptorIndex;
322 Node* maybe_name = LoadFixedArrayElement(
323 descriptors, DescriptorArray::ToKeyIndex(name_index));
324 GotoIf(WordNotEqual(maybe_name, LoadRoot(Heap::kname_stringRootIndex)),
325 &slow);
326
327 Node* maybe_name_accessor = LoadFixedArrayElement(
328 descriptors, DescriptorArray::ToValueIndex(name_index));
329 GotoIf(TaggedIsSmi(maybe_name_accessor), &slow);
330 Node* name_value_map = LoadMap(maybe_name_accessor);
331 GotoIfNot(IsAccessorInfoMap(name_value_map), &slow);
332
333 // Choose the right bound function map based on whether the target is
334 // constructable.
335 Comment("Choose the right bound function map");
336 Variable bound_function_map(this, MachineRepresentation::kTagged);
337 Label with_constructor(this);
338 VariableList vars({&bound_function_map}, zone());
339 Node* native_context = LoadNativeContext(context);
340
341 Label map_done(this, vars);
342 Node* bit_field = LoadMapBitField(receiver_map);
343 int mask = static_cast<int>(1 << Map::kIsConstructor);
344 GotoIf(IsSetWord32(bit_field, mask), &with_constructor);
345
346 bound_function_map.Bind(LoadContextElement(
347 native_context, Context::BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX));
348 Goto(&map_done);
349
350 Bind(&with_constructor);
351 bound_function_map.Bind(LoadContextElement(
352 native_context, Context::BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX));
353 Goto(&map_done);
354
355 Bind(&map_done);
356
357 // Verify that __proto__ matches that of a the target bound function.
358 Comment("Verify that __proto__ matches target bound function");
359 Node* prototype = LoadMapPrototype(receiver_map);
360 Node* expected_prototype = LoadMapPrototype(bound_function_map.value());
361 GotoIf(WordNotEqual(prototype, expected_prototype), &slow);
362
363 // Allocate the arguments array.
364 Comment("Allocate the arguments array");
365 Variable argument_array(this, MachineRepresentation::kTagged);
366 Label empty_arguments(this);
367 Label arguments_done(this, &argument_array);
368 GotoIf(Uint32LessThanOrEqual(argc, Int32Constant(1)), &empty_arguments);
369 Node* elements_length = ChangeUint32ToWord(Int32Sub(argc, Int32Constant(1)));
370 Node* elements = AllocateFixedArray(FAST_ELEMENTS, elements_length);
371 Variable index(this, MachineType::PointerRepresentation());
372 index.Bind(IntPtrConstant(0));
373 VariableList foreach_vars({&index}, zone());
374 args.ForEach(foreach_vars,
375 [this, elements, &index](Node* arg) {
376 StoreFixedArrayElement(elements, index.value(), arg);
377 Increment(index);
378 },
379 IntPtrConstant(1));
380 argument_array.Bind(elements);
381 Goto(&arguments_done);
382
383 Bind(&empty_arguments);
384 argument_array.Bind(EmptyFixedArrayConstant());
385 Goto(&arguments_done);
386
387 Bind(&arguments_done);
388
389 // Determine bound receiver.
390 Comment("Determine bound receiver");
391 Variable bound_receiver(this, MachineRepresentation::kTagged);
392 Label has_receiver(this);
393 Label receiver_done(this, &bound_receiver);
394 GotoIf(Word32NotEqual(argc, Int32Constant(0)), &has_receiver);
395 bound_receiver.Bind(UndefinedConstant());
396 Goto(&receiver_done);
397
398 Bind(&has_receiver);
399 bound_receiver.Bind(args.AtIndex(0));
400 Goto(&receiver_done);
401
402 Bind(&receiver_done);
403
404 // Allocate the resulting bound function.
405 Comment("Allocate the resulting bound function");
406 Node* bound_function = Allocate(JSBoundFunction::kSize);
407 StoreMapNoWriteBarrier(bound_function, bound_function_map.value());
408 StoreObjectFieldNoWriteBarrier(
409 bound_function, JSBoundFunction::kBoundTargetFunctionOffset, receiver);
410 StoreObjectFieldNoWriteBarrier(bound_function,
411 JSBoundFunction::kBoundThisOffset,
412 bound_receiver.value());
413 StoreObjectFieldNoWriteBarrier(bound_function,
414 JSBoundFunction::kBoundArgumentsOffset,
415 argument_array.value());
416 Node* empty_fixed_array = EmptyFixedArrayConstant();
417 StoreObjectFieldNoWriteBarrier(bound_function, JSObject::kPropertiesOffset,
418 empty_fixed_array);
419 StoreObjectFieldNoWriteBarrier(bound_function, JSObject::kElementsOffset,
420 empty_fixed_array);
421
422 args.PopAndReturn(bound_function);
423 Bind(&slow);
424
425 Node* target = LoadFromFrame(StandardFrameConstants::kFunctionOffset,
426 MachineType::TaggedPointer());
427 TailCallStub(CodeFactory::FunctionPrototypeBind(isolate()), context, target,
428 new_target, argc);
429 }
430
431 // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub 274 // TODO(verwaest): This is a temporary helper until the FastFunctionBind stub
432 // can tailcall to the builtin directly. 275 // can tailcall to the builtin directly.
433 RUNTIME_FUNCTION(Runtime_FunctionBind) { 276 RUNTIME_FUNCTION(Runtime_FunctionBind) {
434 DCHECK_EQ(2, args.length()); 277 DCHECK_EQ(2, args.length());
435 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]); 278 Arguments* incoming = reinterpret_cast<Arguments*>(args[0]);
436 // Rewrap the arguments as builtins arguments. 279 // Rewrap the arguments as builtins arguments.
437 int argc = incoming->length() + BuiltinArguments::kNumExtraArgsWithReceiver; 280 int argc = incoming->length() + BuiltinArguments::kNumExtraArgsWithReceiver;
438 BuiltinArguments caller_args(argc, incoming->arguments() + 1); 281 BuiltinArguments caller_args(argc, incoming->arguments() + 1);
439 return DoFunctionBind(isolate, caller_args); 282 return DoFunctionBind(isolate, caller_args);
440 } 283 }
441 284
442 // ES6 section 19.2.3.5 Function.prototype.toString ( ) 285 // ES6 section 19.2.3.5 Function.prototype.toString ( )
443 BUILTIN(FunctionPrototypeToString) { 286 BUILTIN(FunctionPrototypeToString) {
444 HandleScope scope(isolate); 287 HandleScope scope(isolate);
445 Handle<Object> receiver = args.receiver(); 288 Handle<Object> receiver = args.receiver();
446 if (receiver->IsJSBoundFunction()) { 289 if (receiver->IsJSBoundFunction()) {
447 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver)); 290 return *JSBoundFunction::ToString(Handle<JSBoundFunction>::cast(receiver));
448 } else if (receiver->IsJSFunction()) { 291 } else if (receiver->IsJSFunction()) {
449 return *JSFunction::ToString(Handle<JSFunction>::cast(receiver)); 292 return *JSFunction::ToString(Handle<JSFunction>::cast(receiver));
450 } 293 }
451 THROW_NEW_ERROR_RETURN_FAILURE( 294 THROW_NEW_ERROR_RETURN_FAILURE(
452 isolate, NewTypeError(MessageTemplate::kNotGeneric, 295 isolate, NewTypeError(MessageTemplate::kNotGeneric,
453 isolate->factory()->NewStringFromAsciiChecked( 296 isolate->factory()->NewStringFromAsciiChecked(
454 "Function.prototype.toString"))); 297 "Function.prototype.toString")));
455 } 298 }
456 299
457 // ES6 section 19.2.3.6 Function.prototype [ @@hasInstance ] ( V )
458 TF_BUILTIN(FunctionPrototypeHasInstance, CodeStubAssembler) {
459 Node* f = Parameter(0);
460 Node* v = Parameter(1);
461 Node* context = Parameter(4);
462 Node* result = OrdinaryHasInstance(context, f, v);
463 Return(result);
464 }
465
466 } // namespace internal 300 } // namespace internal
467 } // namespace v8 301 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins-forin-gen.cc ('k') | src/builtins/builtins-function-gen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698