diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-09-18 14:34:04 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-10-04 11:15:27 +0000 |
commit | e6430e577f105ad8813c92e75c54660c4985026e (patch) | |
tree | 88115e5d1fb471fea807111924dcccbeadbf9e4f /chromium/v8/src/builtins/builtins-proxy-gen.cc | |
parent | 53d399fe6415a96ea6986ec0d402a9c07da72453 (diff) | |
download | qtwebengine-chromium-e6430e577f105ad8813c92e75c54660c4985026e.tar.gz |
BASELINE: Update Chromium to 61.0.3163.99
Change-Id: I8452f34574d88ca2b27af9bd56fc9ff3f16b1367
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/v8/src/builtins/builtins-proxy-gen.cc')
-rw-r--r-- | chromium/v8/src/builtins/builtins-proxy-gen.cc | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/chromium/v8/src/builtins/builtins-proxy-gen.cc b/chromium/v8/src/builtins/builtins-proxy-gen.cc new file mode 100644 index 00000000000..30b0f08ec07 --- /dev/null +++ b/chromium/v8/src/builtins/builtins-proxy-gen.cc @@ -0,0 +1,215 @@ +// Copyright 2016 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. + +#include "src/builtins/builtins-utils-gen.h" +#include "src/builtins/builtins-utils.h" +#include "src/builtins/builtins.h" +#include "src/code-stub-assembler.h" + +#include "src/counters.h" +#include "src/objects-inl.h" + +namespace v8 { +namespace internal { +using compiler::Node; +using compiler::CodeAssembler; + +// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Call]] case. +TF_BUILTIN(ProxyConstructor, CodeStubAssembler) { + Node* context = Parameter(Descriptor::kContext); + ThrowTypeError(context, MessageTemplate::kConstructorNotFunction, "Proxy"); +} + +class ProxiesCodeStubAssembler : public CodeStubAssembler { + public: + explicit ProxiesCodeStubAssembler(compiler::CodeAssemblerState* state) + : CodeStubAssembler(state) {} + + Node* IsProxyRevoked(Node* proxy) { + CSA_ASSERT(this, IsJSProxy(proxy)); + + Node* handler = LoadObjectField(proxy, JSProxy::kHandlerOffset); + CSA_ASSERT(this, Word32Or(IsJSReceiver(handler), IsNull(handler))); + + return IsNull(handler); + } + + void GotoIfProxyRevoked(Node* object, Label* if_proxy_revoked) { + Label continue_checks(this); + GotoIfNot(IsJSProxy(object), &continue_checks); + GotoIf(IsProxyRevoked(object), if_proxy_revoked); + Goto(&continue_checks); + BIND(&continue_checks); + } + + Node* AllocateProxy(Node* target, Node* handler, Node* context) { + VARIABLE(map, MachineRepresentation::kTagged); + + Label callable_target(this), constructor_target(this), none_target(this), + create_proxy(this); + + Node* nativeContext = LoadNativeContext(context); + + Branch(IsCallable(target), &callable_target, &none_target); + + BIND(&callable_target); + { + // Every object that is a constructor is implicitly callable + // so it's okay to nest this check here + GotoIf(IsConstructor(target), &constructor_target); + map.Bind( + LoadContextElement(nativeContext, Context::PROXY_CALLABLE_MAP_INDEX)); + Goto(&create_proxy); + } + BIND(&constructor_target); + { + map.Bind(LoadContextElement(nativeContext, + Context::PROXY_CONSTRUCTOR_MAP_INDEX)); + Goto(&create_proxy); + } + BIND(&none_target); + { + map.Bind(LoadContextElement(nativeContext, Context::PROXY_MAP_INDEX)); + Goto(&create_proxy); + } + + BIND(&create_proxy); + Node* proxy = Allocate(JSProxy::kSize); + StoreMapNoWriteBarrier(proxy, map.value()); + StoreObjectFieldRoot(proxy, JSProxy::kPropertiesOrHashOffset, + Heap::kEmptyPropertiesDictionaryRootIndex); + StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kTargetOffset, target); + StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHandlerOffset, handler); + StoreObjectFieldNoWriteBarrier(proxy, JSProxy::kHashOffset, + UndefinedConstant()); + + return proxy; + } + + Node* AllocateJSArrayForCodeStubArguments(Node* context, + CodeStubArguments& args, Node* argc, + ParameterMode mode) { + Node* array = nullptr; + Node* elements = nullptr; + Node* native_context = LoadNativeContext(context); + Node* array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); + Node* argc_smi = ParameterToTagged(argc, mode); + std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( + PACKED_ELEMENTS, array_map, argc_smi, nullptr, argc, INTPTR_PARAMETERS); + + StoreMapNoWriteBarrier(elements, Heap::kFixedArrayMapRootIndex); + StoreObjectFieldNoWriteBarrier(elements, FixedArrayBase::kLengthOffset, + argc_smi); + + VARIABLE(index, MachineType::PointerRepresentation()); + index.Bind(IntPtrConstant(FixedArrayBase::kHeaderSize - kHeapObjectTag)); + VariableList list({&index}, zone()); + args.ForEach(list, [this, elements, &index](Node* arg) { + StoreNoWriteBarrier(MachineRepresentation::kTagged, elements, + index.value(), arg); + Increment(index, kPointerSize); + }); + return array; + } +}; + +// ES6 section 26.2.1.1 Proxy ( target, handler ) for the [[Construct]] case. +TF_BUILTIN(ProxyConstructor_ConstructStub, ProxiesCodeStubAssembler) { + int const kTargetArg = 0; + int const kHandlerArg = 1; + + Node* argc = + ChangeInt32ToIntPtr(Parameter(BuiltinDescriptor::kArgumentsCount)); + CodeStubArguments args(this, argc); + + Node* target = args.GetOptionalArgumentValue(kTargetArg); + Node* handler = args.GetOptionalArgumentValue(kHandlerArg); + Node* context = Parameter(BuiltinDescriptor::kContext); + + Label throw_proxy_non_object(this, Label::kDeferred), + throw_proxy_handler_or_target_revoked(this, Label::kDeferred), + return_create_proxy(this); + + GotoIf(TaggedIsSmi(target), &throw_proxy_non_object); + GotoIfNot(IsJSReceiver(target), &throw_proxy_non_object); + GotoIfProxyRevoked(target, &throw_proxy_handler_or_target_revoked); + + GotoIf(TaggedIsSmi(handler), &throw_proxy_non_object); + GotoIfNot(IsJSReceiver(handler), &throw_proxy_non_object); + GotoIfProxyRevoked(handler, &throw_proxy_handler_or_target_revoked); + + args.PopAndReturn(AllocateProxy(target, handler, context)); + + BIND(&throw_proxy_non_object); + ThrowTypeError(context, MessageTemplate::kProxyNonObject); + + BIND(&throw_proxy_handler_or_target_revoked); + ThrowTypeError(context, MessageTemplate::kProxyHandlerOrTargetRevoked); +} + +TF_BUILTIN(CallProxy, ProxiesCodeStubAssembler) { + Node* argc = Parameter(Descriptor::kActualArgumentsCount); + Node* argc_ptr = ChangeInt32ToIntPtr(argc); + Node* proxy = Parameter(Descriptor::kFunction); + Node* context = Parameter(Descriptor::kContext); + + CSA_ASSERT(this, IsJSProxy(proxy)); + CSA_ASSERT(this, IsCallable(proxy)); + + Label throw_proxy_handler_revoked(this, Label::kDeferred), + trap_undefined(this), trap_defined(this, Label::kDeferred); + + // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O. + Node* handler = LoadObjectField(proxy, JSProxy::kHandlerOffset); + + // 2. If handler is null, throw a TypeError exception. + CSA_ASSERT(this, Word32Or(IsJSReceiver(handler), IsNull(handler))); + GotoIf(IsNull(handler), &throw_proxy_handler_revoked); + + // 3. Assert: Type(handler) is Object. + CSA_ASSERT(this, IsJSReceiver(handler)); + + // 4. Let target be the value of the [[ProxyTarget]] internal slot of O. + Node* target = LoadObjectField(proxy, JSProxy::kTargetOffset); + + // 5. Let trap be ? GetMethod(handler, "apply"). + Handle<Name> trap_name = factory()->apply_string(); + Node* trap = GetProperty(context, handler, trap_name); + + // 6. If trap is undefined, then + GotoIf(IsUndefined(trap), &trap_undefined); + Branch(IsNull(trap), &trap_undefined, &trap_defined); + + BIND(&trap_defined); + { + CodeStubArguments args(this, argc_ptr); + Node* receiver = args.GetReceiver(); + + // 7. Let argArray be CreateArrayFromList(argumentsList). + Node* array = AllocateJSArrayForCodeStubArguments(context, args, argc_ptr, + INTPTR_PARAMETERS); + + // 8. Return Call(trap, handler, «target, thisArgument, argArray»). + Node* result = CallJS(CodeFactory::Call(isolate()), context, trap, handler, + target, receiver, array); + args.PopAndReturn(result); + } + + BIND(&trap_undefined); + { + // 6.a. Return Call(target, thisArgument, argumentsList). + TailCallStub(CodeFactory::Call(isolate()), context, target, argc); + } + + BIND(&throw_proxy_handler_revoked); + { + CallRuntime(Runtime::kThrowTypeError, context, + SmiConstant(MessageTemplate::kProxyRevoked), + StringConstant("apply")); + Unreachable(); + } +} + +} // namespace internal +} // namespace v8 |