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 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 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 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 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 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 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 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 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 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 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 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 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 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