blob: 87c7c9112b58c474aaefbb8aff0859442d110e27 [file] [log] [blame]
Emily Bernierd0a1eb72015-03-24 16:35:39 -04001// Copyright 2014 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00005#include "src/runtime/runtime-utils.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -04006
7#include "src/arguments.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/elements.h"
9#include "src/factory.h"
10#include "src/isolate-inl.h"
11#include "src/objects-inl.h"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040012
13namespace v8 {
14namespace internal {
15
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000016
17// ES6 9.5.13 [[Call]] (thisArgument, argumentsList)
18RUNTIME_FUNCTION(Runtime_JSProxyCall) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040019 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000020 DCHECK_LE(2, args.length());
21 // thisArgument == receiver
22 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
23 CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, args.length() - 1);
24 Handle<String> trap_name = isolate->factory()->apply_string();
25 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
26 Handle<Object> handler(proxy->handler(), isolate);
27 // 2. If handler is null, throw a TypeError exception.
28 if (proxy->IsRevoked()) {
29 THROW_NEW_ERROR_RETURN_FAILURE(
30 isolate, NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
31 }
32 // 3. Assert: Type(handler) is Object.
33 DCHECK(handler->IsJSReceiver());
34 // 4. Let target be the value of the [[ProxyTarget]] internal slot of O.
35 Handle<JSReceiver> target(proxy->target(), isolate);
36 // 5. Let trap be ? GetMethod(handler, "apply").
37 Handle<Object> trap;
38 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
39 isolate, trap,
40 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name));
41 // 6. If trap is undefined, then
42 int const arguments_length = args.length() - 2;
Ben Murdoch61f157c2016-09-16 13:49:30 +010043 if (trap->IsUndefined(isolate)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000044 // 6.a. Return Call(target, thisArgument, argumentsList).
45 ScopedVector<Handle<Object>> argv(arguments_length);
46 for (int i = 0; i < arguments_length; ++i) {
47 argv[i] = args.at<Object>(i + 1);
48 }
Ben Murdoch61f157c2016-09-16 13:49:30 +010049 RETURN_RESULT_OR_FAILURE(
50 isolate, Execution::Call(isolate, target, receiver, arguments_length,
51 argv.start()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000052 }
53 // 7. Let argArray be CreateArrayFromList(argumentsList).
54 Handle<JSArray> arg_array = isolate->factory()->NewJSArray(
55 FAST_ELEMENTS, arguments_length, arguments_length);
56 ElementsAccessor* accessor = arg_array->GetElementsAccessor();
57 {
58 DisallowHeapAllocation no_gc;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000059 for (int i = 0; i < arguments_length; i++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010060 accessor->Set(arg_array, i, args[i + 1]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061 }
62 }
63 // 8. Return Call(trap, handler, «target, thisArgument, argArray»).
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000064 Handle<Object> trap_args[] = {target, receiver, arg_array};
Ben Murdoch61f157c2016-09-16 13:49:30 +010065 RETURN_RESULT_OR_FAILURE(
66 isolate,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067 Execution::Call(isolate, trap, handler, arraysize(trap_args), trap_args));
Emily Bernierd0a1eb72015-03-24 16:35:39 -040068}
69
70
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071// 9.5.14 [[Construct]] (argumentsList, newTarget)
72RUNTIME_FUNCTION(Runtime_JSProxyConstruct) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -040073 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000074 DCHECK_LE(3, args.length());
75 CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, args.length() - 2);
76 CONVERT_ARG_HANDLE_CHECKED(Object, new_target, args.length() - 1);
77 Handle<String> trap_name = isolate->factory()->construct_string();
78
79 // 1. Let handler be the value of the [[ProxyHandler]] internal slot of O.
80 Handle<Object> handler(proxy->handler(), isolate);
81 // 2. If handler is null, throw a TypeError exception.
82 if (proxy->IsRevoked()) {
83 THROW_NEW_ERROR_RETURN_FAILURE(
84 isolate, NewTypeError(MessageTemplate::kProxyRevoked, trap_name));
85 }
86 // 3. Assert: Type(handler) is Object.
87 DCHECK(handler->IsJSReceiver());
88 // 4. Let target be the value of the [[ProxyTarget]] internal slot of O.
89 Handle<JSReceiver> target(JSReceiver::cast(proxy->target()), isolate);
90 // 5. Let trap be ? GetMethod(handler, "construct").
91 Handle<Object> trap;
92 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
93 isolate, trap,
94 Object::GetMethod(Handle<JSReceiver>::cast(handler), trap_name));
95 // 6. If trap is undefined, then
96 int const arguments_length = args.length() - 3;
Ben Murdoch61f157c2016-09-16 13:49:30 +010097 if (trap->IsUndefined(isolate)) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000098 // 6.a. Assert: target has a [[Construct]] internal method.
99 DCHECK(target->IsConstructor());
100 // 6.b. Return Construct(target, argumentsList, newTarget).
101 ScopedVector<Handle<Object>> argv(arguments_length);
102 for (int i = 0; i < arguments_length; ++i) {
103 argv[i] = args.at<Object>(i + 1);
104 }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100105 RETURN_RESULT_OR_FAILURE(
106 isolate, Execution::New(isolate, target, new_target, arguments_length,
107 argv.start()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000108 }
109 // 7. Let argArray be CreateArrayFromList(argumentsList).
110 Handle<JSArray> arg_array = isolate->factory()->NewJSArray(
111 FAST_ELEMENTS, arguments_length, arguments_length);
112 ElementsAccessor* accessor = arg_array->GetElementsAccessor();
113 {
114 DisallowHeapAllocation no_gc;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000115 for (int i = 0; i < arguments_length; i++) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100116 accessor->Set(arg_array, i, args[i + 1]);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117 }
118 }
119 // 8. Let newObj be ? Call(trap, handler, «target, argArray, newTarget »).
120 Handle<Object> new_object;
121 Handle<Object> trap_args[] = {target, arg_array, new_target};
122 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
123 isolate, new_object,
124 Execution::Call(isolate, trap, handler, arraysize(trap_args), trap_args));
125 // 9. If Type(newObj) is not Object, throw a TypeError exception.
126 if (!new_object->IsJSReceiver()) {
127 THROW_NEW_ERROR_RETURN_FAILURE(
128 isolate,
129 NewTypeError(MessageTemplate::kProxyConstructNonObject, new_object));
130 }
131 // 10. Return newObj.
132 return *new_object;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400133}
134
135
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000136RUNTIME_FUNCTION(Runtime_IsJSProxy) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400137 SealHandleScope shs(isolate);
138 DCHECK(args.length() == 1);
139 CONVERT_ARG_CHECKED(Object, obj, 0);
140 return isolate->heap()->ToBoolean(obj->IsJSProxy());
141}
142
143
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144RUNTIME_FUNCTION(Runtime_JSProxyGetHandler) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400145 SealHandleScope shs(isolate);
146 DCHECK(args.length() == 1);
147 CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
148 return proxy->handler();
149}
150
151
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000152RUNTIME_FUNCTION(Runtime_JSProxyGetTarget) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400153 SealHandleScope shs(isolate);
154 DCHECK(args.length() == 1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 CONVERT_ARG_CHECKED(JSProxy, proxy, 0);
156 return proxy->target();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400157}
158
159
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000160RUNTIME_FUNCTION(Runtime_JSProxyRevoke) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400161 HandleScope scope(isolate);
162 DCHECK(args.length() == 1);
163 CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 JSProxy::Revoke(proxy);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400165 return isolate->heap()->undefined_value();
166}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000167
168} // namespace internal
169} // namespace v8