1// 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
5#include "src/runtime/runtime-utils.h"
6
7#include "src/execution/arguments-inl.h"
8#include "src/execution/isolate-inl.h"
9#include "src/heap/factory.h"
10#include "src/heap/heap-inl.h"  // For ToBoolean. TODO(jkummerow): Drop.
11#include "src/logging/counters.h"
12#include "src/objects/elements.h"
13#include "src/objects/objects-inl.h"
14
15namespace v8 {
16namespace internal {
17
18RUNTIME_FUNCTION(Runtime_IsJSProxy) {
19  SealHandleScope shs(isolate);
20  DCHECK_EQ(1, args.length());
21  Object obj = args[0];
22  return isolate->heap()->ToBoolean(obj.IsJSProxy());
23}
24
25RUNTIME_FUNCTION(Runtime_JSProxyGetHandler) {
26  SealHandleScope shs(isolate);
27  DCHECK_EQ(1, args.length());
28  auto proxy = JSProxy::cast(args[0]);
29  return proxy.handler();
30}
31
32RUNTIME_FUNCTION(Runtime_JSProxyGetTarget) {
33  SealHandleScope shs(isolate);
34  DCHECK_EQ(1, args.length());
35  auto proxy = JSProxy::cast(args[0]);
36  return proxy.target();
37}
38
39RUNTIME_FUNCTION(Runtime_GetPropertyWithReceiver) {
40  HandleScope scope(isolate);
41
42  DCHECK_EQ(4, args.length());
43  Handle<JSReceiver> holder = args.at<JSReceiver>(0);
44  Handle<Object> key = args.at(1);
45  Handle<Object> receiver = args.at(2);
46  // TODO(mythria): Remove the on_non_existent parameter to this function. This
47  // should only be called when getting named properties on receiver. This
48  // doesn't handle the global variable loads.
49#ifdef DEBUG
50  int on_non_existent = args.smi_value_at(3);
51  DCHECK_NE(static_cast<OnNonExistent>(on_non_existent),
52            OnNonExistent::kThrowReferenceError);
53#endif
54
55  bool success = false;
56  PropertyKey lookup_key(isolate, key, &success);
57  if (!success) {
58    DCHECK(isolate->has_pending_exception());
59    return ReadOnlyRoots(isolate).exception();
60  }
61  LookupIterator it(isolate, receiver, lookup_key, holder);
62
63  RETURN_RESULT_OR_FAILURE(isolate, Object::GetProperty(&it));
64}
65
66RUNTIME_FUNCTION(Runtime_SetPropertyWithReceiver) {
67  HandleScope scope(isolate);
68
69  DCHECK_EQ(4, args.length());
70  Handle<JSReceiver> holder = args.at<JSReceiver>(0);
71  Handle<Object> key = args.at(1);
72  Handle<Object> value = args.at(2);
73  Handle<Object> receiver = args.at(3);
74
75  bool success = false;
76  PropertyKey lookup_key(isolate, key, &success);
77  if (!success) {
78    DCHECK(isolate->has_pending_exception());
79    return ReadOnlyRoots(isolate).exception();
80  }
81  LookupIterator it(isolate, receiver, lookup_key, holder);
82  Maybe<bool> result =
83      Object::SetSuperProperty(&it, value, StoreOrigin::kMaybeKeyed);
84  MAYBE_RETURN(result, ReadOnlyRoots(isolate).exception());
85  return *isolate->factory()->ToBoolean(result.FromJust());
86}
87
88RUNTIME_FUNCTION(Runtime_CheckProxyGetSetTrapResult) {
89  HandleScope scope(isolate);
90
91  DCHECK_EQ(4, args.length());
92  Handle<Name> name = args.at<Name>(0);
93  Handle<JSReceiver> target = args.at<JSReceiver>(1);
94  Handle<Object> trap_result = args.at(2);
95  int64_t access_kind = NumberToInt64(args[3]);
96
97  RETURN_RESULT_OR_FAILURE(isolate, JSProxy::CheckGetSetTrapResult(
98                                        isolate, name, target, trap_result,
99                                        JSProxy::AccessKind(access_kind)));
100}
101
102RUNTIME_FUNCTION(Runtime_CheckProxyHasTrapResult) {
103  HandleScope scope(isolate);
104
105  DCHECK_EQ(2, args.length());
106  Handle<Name> name = args.at<Name>(0);
107  Handle<JSReceiver> target = args.at<JSReceiver>(1);
108
109  Maybe<bool> result = JSProxy::CheckHasTrap(isolate, name, target);
110  if (!result.IsJust()) return ReadOnlyRoots(isolate).exception();
111  return isolate->heap()->ToBoolean(result.FromJust());
112}
113
114RUNTIME_FUNCTION(Runtime_CheckProxyDeleteTrapResult) {
115  HandleScope scope(isolate);
116
117  DCHECK_EQ(2, args.length());
118  Handle<Name> name = args.at<Name>(0);
119  Handle<JSReceiver> target = args.at<JSReceiver>(1);
120
121  Maybe<bool> result = JSProxy::CheckDeleteTrap(isolate, name, target);
122  if (!result.IsJust()) return ReadOnlyRoots(isolate).exception();
123  return isolate->heap()->ToBoolean(result.FromJust());
124}
125
126}  // namespace internal
127}  // namespace v8
128