OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 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/builtins/builtins.h" |
| 6 #include "src/builtins/builtins-utils.h" |
| 7 |
| 8 #include "src/property-descriptor.h" |
| 9 |
| 10 namespace v8 { |
| 11 namespace internal { |
| 12 |
| 13 // ----------------------------------------------------------------------------- |
| 14 // ES6 section 26.1 The Reflect Object |
| 15 |
| 16 // ES6 section 26.1.3 Reflect.defineProperty |
| 17 BUILTIN(ReflectDefineProperty) { |
| 18 HandleScope scope(isolate); |
| 19 DCHECK_EQ(4, args.length()); |
| 20 Handle<Object> target = args.at<Object>(1); |
| 21 Handle<Object> key = args.at<Object>(2); |
| 22 Handle<Object> attributes = args.at<Object>(3); |
| 23 |
| 24 if (!target->IsJSReceiver()) { |
| 25 THROW_NEW_ERROR_RETURN_FAILURE( |
| 26 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 27 isolate->factory()->NewStringFromAsciiChecked( |
| 28 "Reflect.defineProperty"))); |
| 29 } |
| 30 |
| 31 Handle<Name> name; |
| 32 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, |
| 33 Object::ToName(isolate, key)); |
| 34 |
| 35 PropertyDescriptor desc; |
| 36 if (!PropertyDescriptor::ToPropertyDescriptor(isolate, attributes, &desc)) { |
| 37 return isolate->heap()->exception(); |
| 38 } |
| 39 |
| 40 Maybe<bool> result = |
| 41 JSReceiver::DefineOwnProperty(isolate, Handle<JSReceiver>::cast(target), |
| 42 name, &desc, Object::DONT_THROW); |
| 43 MAYBE_RETURN(result, isolate->heap()->exception()); |
| 44 return *isolate->factory()->ToBoolean(result.FromJust()); |
| 45 } |
| 46 |
| 47 // ES6 section 26.1.4 Reflect.deleteProperty |
| 48 BUILTIN(ReflectDeleteProperty) { |
| 49 HandleScope scope(isolate); |
| 50 DCHECK_EQ(3, args.length()); |
| 51 Handle<Object> target = args.at<Object>(1); |
| 52 Handle<Object> key = args.at<Object>(2); |
| 53 |
| 54 if (!target->IsJSReceiver()) { |
| 55 THROW_NEW_ERROR_RETURN_FAILURE( |
| 56 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 57 isolate->factory()->NewStringFromAsciiChecked( |
| 58 "Reflect.deleteProperty"))); |
| 59 } |
| 60 |
| 61 Handle<Name> name; |
| 62 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, |
| 63 Object::ToName(isolate, key)); |
| 64 |
| 65 Maybe<bool> result = JSReceiver::DeletePropertyOrElement( |
| 66 Handle<JSReceiver>::cast(target), name, SLOPPY); |
| 67 MAYBE_RETURN(result, isolate->heap()->exception()); |
| 68 return *isolate->factory()->ToBoolean(result.FromJust()); |
| 69 } |
| 70 |
| 71 // ES6 section 26.1.6 Reflect.get |
| 72 BUILTIN(ReflectGet) { |
| 73 HandleScope scope(isolate); |
| 74 Handle<Object> target = args.atOrUndefined(isolate, 1); |
| 75 Handle<Object> key = args.atOrUndefined(isolate, 2); |
| 76 Handle<Object> receiver = args.length() > 3 ? args.at<Object>(3) : target; |
| 77 |
| 78 if (!target->IsJSReceiver()) { |
| 79 THROW_NEW_ERROR_RETURN_FAILURE( |
| 80 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 81 isolate->factory()->NewStringFromAsciiChecked( |
| 82 "Reflect.get"))); |
| 83 } |
| 84 |
| 85 Handle<Name> name; |
| 86 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, |
| 87 Object::ToName(isolate, key)); |
| 88 |
| 89 RETURN_RESULT_OR_FAILURE( |
| 90 isolate, Object::GetPropertyOrElement(receiver, name, |
| 91 Handle<JSReceiver>::cast(target))); |
| 92 } |
| 93 |
| 94 // ES6 section 26.1.7 Reflect.getOwnPropertyDescriptor |
| 95 BUILTIN(ReflectGetOwnPropertyDescriptor) { |
| 96 HandleScope scope(isolate); |
| 97 DCHECK_EQ(3, args.length()); |
| 98 Handle<Object> target = args.at<Object>(1); |
| 99 Handle<Object> key = args.at<Object>(2); |
| 100 |
| 101 if (!target->IsJSReceiver()) { |
| 102 THROW_NEW_ERROR_RETURN_FAILURE( |
| 103 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 104 isolate->factory()->NewStringFromAsciiChecked( |
| 105 "Reflect.getOwnPropertyDescriptor"))); |
| 106 } |
| 107 |
| 108 Handle<Name> name; |
| 109 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, |
| 110 Object::ToName(isolate, key)); |
| 111 |
| 112 PropertyDescriptor desc; |
| 113 Maybe<bool> found = JSReceiver::GetOwnPropertyDescriptor( |
| 114 isolate, Handle<JSReceiver>::cast(target), name, &desc); |
| 115 MAYBE_RETURN(found, isolate->heap()->exception()); |
| 116 if (!found.FromJust()) return isolate->heap()->undefined_value(); |
| 117 return *desc.ToObject(isolate); |
| 118 } |
| 119 |
| 120 // ES6 section 26.1.8 Reflect.getPrototypeOf |
| 121 BUILTIN(ReflectGetPrototypeOf) { |
| 122 HandleScope scope(isolate); |
| 123 DCHECK_EQ(2, args.length()); |
| 124 Handle<Object> target = args.at<Object>(1); |
| 125 |
| 126 if (!target->IsJSReceiver()) { |
| 127 THROW_NEW_ERROR_RETURN_FAILURE( |
| 128 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 129 isolate->factory()->NewStringFromAsciiChecked( |
| 130 "Reflect.getPrototypeOf"))); |
| 131 } |
| 132 Handle<JSReceiver> receiver = Handle<JSReceiver>::cast(target); |
| 133 RETURN_RESULT_OR_FAILURE(isolate, |
| 134 JSReceiver::GetPrototype(isolate, receiver)); |
| 135 } |
| 136 |
| 137 // ES6 section 26.1.9 Reflect.has |
| 138 BUILTIN(ReflectHas) { |
| 139 HandleScope scope(isolate); |
| 140 DCHECK_EQ(3, args.length()); |
| 141 Handle<Object> target = args.at<Object>(1); |
| 142 Handle<Object> key = args.at<Object>(2); |
| 143 |
| 144 if (!target->IsJSReceiver()) { |
| 145 THROW_NEW_ERROR_RETURN_FAILURE( |
| 146 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 147 isolate->factory()->NewStringFromAsciiChecked( |
| 148 "Reflect.has"))); |
| 149 } |
| 150 |
| 151 Handle<Name> name; |
| 152 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, |
| 153 Object::ToName(isolate, key)); |
| 154 |
| 155 Maybe<bool> result = |
| 156 JSReceiver::HasProperty(Handle<JSReceiver>::cast(target), name); |
| 157 return result.IsJust() ? *isolate->factory()->ToBoolean(result.FromJust()) |
| 158 : isolate->heap()->exception(); |
| 159 } |
| 160 |
| 161 // ES6 section 26.1.10 Reflect.isExtensible |
| 162 BUILTIN(ReflectIsExtensible) { |
| 163 HandleScope scope(isolate); |
| 164 DCHECK_EQ(2, args.length()); |
| 165 Handle<Object> target = args.at<Object>(1); |
| 166 |
| 167 if (!target->IsJSReceiver()) { |
| 168 THROW_NEW_ERROR_RETURN_FAILURE( |
| 169 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 170 isolate->factory()->NewStringFromAsciiChecked( |
| 171 "Reflect.isExtensible"))); |
| 172 } |
| 173 |
| 174 Maybe<bool> result = |
| 175 JSReceiver::IsExtensible(Handle<JSReceiver>::cast(target)); |
| 176 MAYBE_RETURN(result, isolate->heap()->exception()); |
| 177 return *isolate->factory()->ToBoolean(result.FromJust()); |
| 178 } |
| 179 |
| 180 // ES6 section 26.1.11 Reflect.ownKeys |
| 181 BUILTIN(ReflectOwnKeys) { |
| 182 HandleScope scope(isolate); |
| 183 DCHECK_EQ(2, args.length()); |
| 184 Handle<Object> target = args.at<Object>(1); |
| 185 |
| 186 if (!target->IsJSReceiver()) { |
| 187 THROW_NEW_ERROR_RETURN_FAILURE( |
| 188 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 189 isolate->factory()->NewStringFromAsciiChecked( |
| 190 "Reflect.ownKeys"))); |
| 191 } |
| 192 |
| 193 Handle<FixedArray> keys; |
| 194 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| 195 isolate, keys, |
| 196 KeyAccumulator::GetKeys(Handle<JSReceiver>::cast(target), |
| 197 KeyCollectionMode::kOwnOnly, ALL_PROPERTIES, |
| 198 GetKeysConversion::kConvertToString)); |
| 199 return *isolate->factory()->NewJSArrayWithElements(keys); |
| 200 } |
| 201 |
| 202 // ES6 section 26.1.12 Reflect.preventExtensions |
| 203 BUILTIN(ReflectPreventExtensions) { |
| 204 HandleScope scope(isolate); |
| 205 DCHECK_EQ(2, args.length()); |
| 206 Handle<Object> target = args.at<Object>(1); |
| 207 |
| 208 if (!target->IsJSReceiver()) { |
| 209 THROW_NEW_ERROR_RETURN_FAILURE( |
| 210 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 211 isolate->factory()->NewStringFromAsciiChecked( |
| 212 "Reflect.preventExtensions"))); |
| 213 } |
| 214 |
| 215 Maybe<bool> result = JSReceiver::PreventExtensions( |
| 216 Handle<JSReceiver>::cast(target), Object::DONT_THROW); |
| 217 MAYBE_RETURN(result, isolate->heap()->exception()); |
| 218 return *isolate->factory()->ToBoolean(result.FromJust()); |
| 219 } |
| 220 |
| 221 // ES6 section 26.1.13 Reflect.set |
| 222 BUILTIN(ReflectSet) { |
| 223 HandleScope scope(isolate); |
| 224 Handle<Object> target = args.atOrUndefined(isolate, 1); |
| 225 Handle<Object> key = args.atOrUndefined(isolate, 2); |
| 226 Handle<Object> value = args.atOrUndefined(isolate, 3); |
| 227 Handle<Object> receiver = args.length() > 4 ? args.at<Object>(4) : target; |
| 228 |
| 229 if (!target->IsJSReceiver()) { |
| 230 THROW_NEW_ERROR_RETURN_FAILURE( |
| 231 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 232 isolate->factory()->NewStringFromAsciiChecked( |
| 233 "Reflect.set"))); |
| 234 } |
| 235 |
| 236 Handle<Name> name; |
| 237 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, |
| 238 Object::ToName(isolate, key)); |
| 239 |
| 240 LookupIterator it = LookupIterator::PropertyOrElement( |
| 241 isolate, receiver, name, Handle<JSReceiver>::cast(target)); |
| 242 Maybe<bool> result = Object::SetSuperProperty( |
| 243 &it, value, SLOPPY, Object::MAY_BE_STORE_FROM_KEYED); |
| 244 MAYBE_RETURN(result, isolate->heap()->exception()); |
| 245 return *isolate->factory()->ToBoolean(result.FromJust()); |
| 246 } |
| 247 |
| 248 // ES6 section 26.1.14 Reflect.setPrototypeOf |
| 249 BUILTIN(ReflectSetPrototypeOf) { |
| 250 HandleScope scope(isolate); |
| 251 DCHECK_EQ(3, args.length()); |
| 252 Handle<Object> target = args.at<Object>(1); |
| 253 Handle<Object> proto = args.at<Object>(2); |
| 254 |
| 255 if (!target->IsJSReceiver()) { |
| 256 THROW_NEW_ERROR_RETURN_FAILURE( |
| 257 isolate, NewTypeError(MessageTemplate::kCalledOnNonObject, |
| 258 isolate->factory()->NewStringFromAsciiChecked( |
| 259 "Reflect.setPrototypeOf"))); |
| 260 } |
| 261 |
| 262 if (!proto->IsJSReceiver() && !proto->IsNull(isolate)) { |
| 263 THROW_NEW_ERROR_RETURN_FAILURE( |
| 264 isolate, NewTypeError(MessageTemplate::kProtoObjectOrNull, proto)); |
| 265 } |
| 266 |
| 267 Maybe<bool> result = JSReceiver::SetPrototype( |
| 268 Handle<JSReceiver>::cast(target), proto, true, Object::DONT_THROW); |
| 269 MAYBE_RETURN(result, isolate->heap()->exception()); |
| 270 return *isolate->factory()->ToBoolean(result.FromJust()); |
| 271 } |
| 272 |
| 273 } // namespace internal |
| 274 } // namespace v8 |
OLD | NEW |