diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/v8/src/builtins/function.tq | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/v8/src/builtins/function.tq')
-rw-r--r-- | chromium/v8/src/builtins/function.tq | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/chromium/v8/src/builtins/function.tq b/chromium/v8/src/builtins/function.tq new file mode 100644 index 00000000000..8266714c7be --- /dev/null +++ b/chromium/v8/src/builtins/function.tq @@ -0,0 +1,109 @@ +// Copyright 2020 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +namespace function { + +extern macro OrdinaryHasInstance(Context, Object, Object): JSAny; + +// ES6 section 19.2.3.6 Function.prototype[@@hasInstance] +javascript builtin FunctionPrototypeHasInstance( + js-implicit context: NativeContext, receiver: JSAny)(value: JSAny): JSAny { + return OrdinaryHasInstance(context, receiver, value); +} + +extern transitioning builtin +FunctionPrototypeBind(implicit context: Context)( + JSFunction, JSAny, int32): JSAny; + +const kLengthDescriptorIndex: + constexpr int32 generates 'JSFunction::kLengthDescriptorIndex'; +const kNameDescriptorIndex: + constexpr int32 generates 'JSFunction::kNameDescriptorIndex'; +const kMinDescriptorsForFastBind: + constexpr int31 generates 'JSFunction::kMinDescriptorsForFastBind'; + +macro CheckAccessor(implicit context: Context)( + array: DescriptorArray, index: constexpr int32, name: Name) labels Slow { + const descriptor: DescriptorEntry = array.descriptors[index]; + const key: Name|Undefined = descriptor.key; + if (!TaggedEqual(key, name)) goto Slow; + + // The descriptor value must be an AccessorInfo. + Cast<AccessorInfo>(descriptor.value) otherwise goto Slow; +} + +// ES6 section 19.2.3.2 Function.prototype.bind +transitioning javascript builtin +FastFunctionPrototypeBind( + js-implicit context: NativeContext, receiver: JSAny, newTarget: JSAny, + target: JSFunction)(...arguments): JSAny { + const argc: intptr = arguments.length; + try { + typeswitch (receiver) { + case (fn: JSFunction|JSBoundFunction): { + // Disallow binding of slow-mode functions. We need to figure out + // whether the length and name property are in the original state. + Comment('Disallow binding of slow-mode functions'); + if (IsDictionaryMap(fn.map)) goto Slow; + + // Check whether the length and name properties are still present as + // AccessorInfo objects. If so, their value can be recomputed even if + // the actual value on the object changes. + + if (fn.map.bit_field3.number_of_own_descriptors < + kMinDescriptorsForFastBind) { + goto Slow; + } + + const descriptors: DescriptorArray = fn.map.instance_descriptors; + CheckAccessor( + descriptors, kLengthDescriptorIndex, LengthStringConstant()) + otherwise Slow; + CheckAccessor(descriptors, kNameDescriptorIndex, NameStringConstant()) + otherwise Slow; + + // Choose the right bound function map based on whether the target is + // constructable. + + const boundFunctionMap: Map = UnsafeCast<Map>( + IsConstructor(fn) ? + context[NativeContextSlot:: + BOUND_FUNCTION_WITH_CONSTRUCTOR_MAP_INDEX] : + context[NativeContextSlot:: + BOUND_FUNCTION_WITHOUT_CONSTRUCTOR_MAP_INDEX]); + + // Verify that prototype matches that of the target bound function. + + if (fn.map.prototype != boundFunctionMap.prototype) goto Slow; + + // Allocate the arguments array. + + const argumentsArray = arguments.length <= 1 ? + kEmptyFixedArray : + NewFixedArray( + arguments.length - 1, ArgumentsIterator{arguments, current: 1}); + + const boundReceiver: JSAny = arguments[0]; + + const result = new JSBoundFunction{ + map: boundFunctionMap, + properties_or_hash: kEmptyFixedArray, + elements: kEmptyFixedArray, + bound_target_function: fn, + bound_this: boundReceiver, + bound_arguments: argumentsArray + }; + return result; + } + + case (JSAny): { + goto Slow; + } + } + } label Slow { + tail FunctionPrototypeBind( + LoadTargetFromFrame(), newTarget, Convert<int32>(argc)); + } +} +} // namespace function |