1 // Copyright 2015 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/arguments.h"
8 #include "src/isolate-inl.h"
9 
10 namespace v8 {
11 namespace internal {
12 
13 
RUNTIME_FUNCTION(Runtime_InterpreterEquals)14 RUNTIME_FUNCTION(Runtime_InterpreterEquals) {
15   HandleScope scope(isolate);
16   DCHECK_EQ(2, args.length());
17   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
18   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
19   Maybe<bool> result = Object::Equals(x, y);
20   if (result.IsJust()) {
21     return isolate->heap()->ToBoolean(result.FromJust());
22   } else {
23     return isolate->heap()->exception();
24   }
25 }
26 
27 
RUNTIME_FUNCTION(Runtime_InterpreterNotEquals)28 RUNTIME_FUNCTION(Runtime_InterpreterNotEquals) {
29   HandleScope scope(isolate);
30   DCHECK_EQ(2, args.length());
31   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
32   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
33   Maybe<bool> result = Object::Equals(x, y);
34   if (result.IsJust()) {
35     return isolate->heap()->ToBoolean(!result.FromJust());
36   } else {
37     return isolate->heap()->exception();
38   }
39 }
40 
41 
RUNTIME_FUNCTION(Runtime_InterpreterLessThan)42 RUNTIME_FUNCTION(Runtime_InterpreterLessThan) {
43   HandleScope scope(isolate);
44   DCHECK_EQ(2, args.length());
45   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
46   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
47   Maybe<bool> result = Object::LessThan(x, y);
48   if (result.IsJust()) {
49     return isolate->heap()->ToBoolean(result.FromJust());
50   } else {
51     return isolate->heap()->exception();
52   }
53 }
54 
55 
RUNTIME_FUNCTION(Runtime_InterpreterGreaterThan)56 RUNTIME_FUNCTION(Runtime_InterpreterGreaterThan) {
57   HandleScope scope(isolate);
58   DCHECK_EQ(2, args.length());
59   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
60   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
61   Maybe<bool> result = Object::GreaterThan(x, y);
62   if (result.IsJust()) {
63     return isolate->heap()->ToBoolean(result.FromJust());
64   } else {
65     return isolate->heap()->exception();
66   }
67 }
68 
69 
RUNTIME_FUNCTION(Runtime_InterpreterLessThanOrEqual)70 RUNTIME_FUNCTION(Runtime_InterpreterLessThanOrEqual) {
71   HandleScope scope(isolate);
72   DCHECK_EQ(2, args.length());
73   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
74   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
75   Maybe<bool> result = Object::LessThanOrEqual(x, y);
76   if (result.IsJust()) {
77     return isolate->heap()->ToBoolean(result.FromJust());
78   } else {
79     return isolate->heap()->exception();
80   }
81 }
82 
83 
RUNTIME_FUNCTION(Runtime_InterpreterGreaterThanOrEqual)84 RUNTIME_FUNCTION(Runtime_InterpreterGreaterThanOrEqual) {
85   HandleScope scope(isolate);
86   DCHECK_EQ(2, args.length());
87   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
88   CONVERT_ARG_HANDLE_CHECKED(Object, y, 1);
89   Maybe<bool> result = Object::GreaterThanOrEqual(x, y);
90   if (result.IsJust()) {
91     return isolate->heap()->ToBoolean(result.FromJust());
92   } else {
93     return isolate->heap()->exception();
94   }
95 }
96 
97 
RUNTIME_FUNCTION(Runtime_InterpreterStrictEquals)98 RUNTIME_FUNCTION(Runtime_InterpreterStrictEquals) {
99   SealHandleScope shs(isolate);
100   DCHECK_EQ(2, args.length());
101   CONVERT_ARG_CHECKED(Object, x, 0);
102   CONVERT_ARG_CHECKED(Object, y, 1);
103   return isolate->heap()->ToBoolean(x->StrictEquals(y));
104 }
105 
106 
RUNTIME_FUNCTION(Runtime_InterpreterStrictNotEquals)107 RUNTIME_FUNCTION(Runtime_InterpreterStrictNotEquals) {
108   SealHandleScope shs(isolate);
109   DCHECK_EQ(2, args.length());
110   CONVERT_ARG_CHECKED(Object, x, 0);
111   CONVERT_ARG_CHECKED(Object, y, 1);
112   return isolate->heap()->ToBoolean(!x->StrictEquals(y));
113 }
114 
115 
RUNTIME_FUNCTION(Runtime_InterpreterToBoolean)116 RUNTIME_FUNCTION(Runtime_InterpreterToBoolean) {
117   SealHandleScope shs(isolate);
118   DCHECK_EQ(1, args.length());
119   CONVERT_ARG_CHECKED(Object, x, 0);
120   return isolate->heap()->ToBoolean(x->BooleanValue());
121 }
122 
123 
RUNTIME_FUNCTION(Runtime_InterpreterLogicalNot)124 RUNTIME_FUNCTION(Runtime_InterpreterLogicalNot) {
125   SealHandleScope shs(isolate);
126   DCHECK_EQ(1, args.length());
127   CONVERT_ARG_CHECKED(Object, x, 0);
128   return isolate->heap()->ToBoolean(!x->BooleanValue());
129 }
130 
131 
RUNTIME_FUNCTION(Runtime_InterpreterTypeOf)132 RUNTIME_FUNCTION(Runtime_InterpreterTypeOf) {
133   SealHandleScope shs(isolate);
134   DCHECK_EQ(1, args.length());
135   CONVERT_ARG_HANDLE_CHECKED(Object, x, 0);
136   return Object::cast(*Object::TypeOf(isolate, x));
137 }
138 
139 
RUNTIME_FUNCTION(Runtime_InterpreterNewClosure)140 RUNTIME_FUNCTION(Runtime_InterpreterNewClosure) {
141   HandleScope scope(isolate);
142   DCHECK_EQ(2, args.length());
143   CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
144   CONVERT_SMI_ARG_CHECKED(pretenured_flag, 1);
145   Handle<Context> context(isolate->context(), isolate);
146   return *isolate->factory()->NewFunctionFromSharedFunctionInfo(
147       shared, context, static_cast<PretenureFlag>(pretenured_flag));
148 }
149 
150 
RUNTIME_FUNCTION(Runtime_InterpreterForInPrepare)151 RUNTIME_FUNCTION(Runtime_InterpreterForInPrepare) {
152   HandleScope scope(isolate);
153   DCHECK_EQ(1, args.length());
154   CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
155 
156   Object* property_names = Runtime_GetPropertyNamesFast(
157       1, Handle<Object>::cast(receiver).location(), isolate);
158   if (isolate->has_pending_exception()) {
159     return property_names;
160   }
161 
162   Handle<Object> cache_type(property_names, isolate);
163   Handle<FixedArray> cache_array;
164   int cache_length;
165 
166   Handle<Map> receiver_map = handle(receiver->map(), isolate);
167   if (cache_type->IsMap()) {
168     Handle<Map> cache_type_map =
169         handle(Handle<Map>::cast(cache_type)->map(), isolate);
170     DCHECK(cache_type_map.is_identical_to(isolate->factory()->meta_map()));
171     int enum_length = cache_type_map->EnumLength();
172     DescriptorArray* descriptors = receiver_map->instance_descriptors();
173     if (enum_length > 0 && descriptors->HasEnumCache()) {
174       cache_array = handle(descriptors->GetEnumCache(), isolate);
175       cache_length = cache_array->length();
176     } else {
177       cache_array = isolate->factory()->empty_fixed_array();
178       cache_length = 0;
179     }
180   } else {
181     cache_array = Handle<FixedArray>::cast(cache_type);
182     cache_length = cache_array->length();
183 
184     STATIC_ASSERT(JS_PROXY_TYPE == FIRST_JS_RECEIVER_TYPE);
185     if (receiver_map->instance_type() == JS_PROXY_TYPE) {
186       // Zero indicates proxy
187       cache_type = Handle<Object>(Smi::FromInt(0), isolate);
188     } else {
189       // One entails slow check
190       cache_type = Handle<Object>(Smi::FromInt(1), isolate);
191     }
192   }
193 
194   Handle<FixedArray> result = isolate->factory()->NewFixedArray(3);
195   result->set(0, *cache_type);
196   result->set(1, *cache_array);
197   result->set(2, Smi::FromInt(cache_length));
198   return *result;
199 }
200 
201 }  // namespace internal
202 }  // namespace v8
203