blob: 766509e2a5a40831d30097fef01882d1bfb1e3c8 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
Ben Murdochb8a8cc12014-11-26 15:28:44 +00005#include "src/accessors.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00006
Ben Murdochb8a8cc12014-11-26 15:28:44 +00007#include "src/api.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/contexts.h"
9#include "src/deoptimizer.h"
10#include "src/execution.h"
11#include "src/factory.h"
12#include "src/frames-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000013#include "src/isolate-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000014#include "src/list-inl.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000015#include "src/messages.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000016#include "src/property-details.h"
17#include "src/prototype.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000018
19namespace v8 {
20namespace internal {
21
22
Ben Murdochb8a8cc12014-11-26 15:28:44 +000023Handle<AccessorInfo> Accessors::MakeAccessor(
24 Isolate* isolate,
25 Handle<Name> name,
26 AccessorNameGetterCallback getter,
27 AccessorNameSetterCallback setter,
28 PropertyAttributes attributes) {
29 Factory* factory = isolate->factory();
Ben Murdoch097c5b22016-05-18 11:27:45 +010030 Handle<AccessorInfo> info = factory->NewAccessorInfo();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031 info->set_property_attributes(attributes);
32 info->set_all_can_read(false);
33 info->set_all_can_write(false);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000034 info->set_is_special_data_property(true);
Ben Murdoch097c5b22016-05-18 11:27:45 +010035 name = factory->InternalizeName(name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000036 info->set_name(*name);
37 Handle<Object> get = v8::FromCData(isolate, getter);
Ben Murdoch097c5b22016-05-18 11:27:45 +010038 if (setter == nullptr) setter = &ReconfigureToDataProperty;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039 Handle<Object> set = v8::FromCData(isolate, setter);
40 info->set_getter(*get);
41 info->set_setter(*set);
42 return info;
Steve Blocka7e24c12009-10-30 11:49:00 +000043}
44
45
Ben Murdochb8a8cc12014-11-26 15:28:44 +000046static V8_INLINE bool CheckForName(Handle<Name> name,
47 Handle<String> property_name,
48 int offset,
49 int* object_offset) {
50 if (Name::Equals(name, property_name)) {
51 *object_offset = offset;
52 return true;
53 }
54 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +000055}
56
57
Ben Murdochb8a8cc12014-11-26 15:28:44 +000058// Returns true for properties that are accessors to object fields.
59// If true, *object_offset contains offset of object field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000061 int* object_offset) {
62 Isolate* isolate = name->GetIsolate();
63
Ben Murdochb8a8cc12014-11-26 15:28:44 +000064 switch (map->instance_type()) {
65 case JS_ARRAY_TYPE:
66 return
67 CheckForName(name, isolate->factory()->length_string(),
68 JSArray::kLengthOffset, object_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000069 case JS_ARRAY_BUFFER_TYPE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000070 return CheckForName(name, isolate->factory()->byte_length_string(),
71 JSArrayBuffer::kByteLengthOffset, object_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000072 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073 if (map->instance_type() < FIRST_NONSTRING_TYPE) {
74 return CheckForName(name, isolate->factory()->length_string(),
75 String::kLengthOffset, object_offset);
76 }
77
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 return false;
79 }
80}
81
82
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000083bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map,
84 Handle<Name> name,
85 int* object_offset) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010086 DCHECK(name->IsUniqueName());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 Isolate* isolate = name->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000088
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089 switch (map->instance_type()) {
90 case JS_TYPED_ARRAY_TYPE: {
91 if (!CheckForName(name, isolate->factory()->length_string(),
92 JSTypedArray::kLengthOffset, object_offset) &&
93 !CheckForName(name, isolate->factory()->byte_length_string(),
94 JSTypedArray::kByteLengthOffset, object_offset) &&
95 !CheckForName(name, isolate->factory()->byte_offset_string(),
96 JSTypedArray::kByteOffsetOffset, object_offset)) {
97 return false;
98 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000099
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000100 if (map->is_dictionary_map()) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000101
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 // Check if the property is overridden on the instance.
103 DescriptorArray* descriptors = map->instance_descriptors();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100104 int descriptor = descriptors->SearchWithCache(isolate, *name, *map);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 if (descriptor != DescriptorArray::kNotFound) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107 Handle<Object> proto = Handle<Object>(map->prototype(), isolate);
108 if (!proto->IsJSReceiver()) return false;
109
110 // Check if the property is defined in the prototype chain.
111 LookupIterator it(proto, name);
112 if (!it.IsFound()) return false;
113
114 Object* original_proto =
115 JSFunction::cast(map->GetConstructor())->prototype();
116
117 // Property is not configurable. It is enough to verify that
118 // the holder is the same.
119 return *it.GetHolder<Object>() == original_proto;
120 }
121 case JS_DATA_VIEW_TYPE:
122 return CheckForName(name, isolate->factory()->byte_length_string(),
123 JSDataView::kByteLengthOffset, object_offset) ||
124 CheckForName(name, isolate->factory()->byte_offset_string(),
125 JSDataView::kByteOffsetOffset, object_offset);
126 default:
127 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000128 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129}
130
Ben Murdoch097c5b22016-05-18 11:27:45 +0100131MUST_USE_RESULT static MaybeHandle<Object> ReplaceAccessorWithDataProperty(
132 Isolate* isolate, Handle<JSObject> receiver, Handle<JSObject> holder,
133 Handle<Name> name, Handle<Object> value, bool observe) {
134 LookupIterator it(receiver, name, holder,
135 LookupIterator::OWN_SKIP_INTERCEPTOR);
136 // Skip any access checks we might hit. This accessor should never hit in a
137 // situation where the caller does not have access.
138 if (it.state() == LookupIterator::ACCESS_CHECK) {
139 CHECK(it.HasAccess());
140 it.Next();
141 }
142 CHECK_EQ(LookupIterator::ACCESSOR, it.state());
143
144 Handle<Object> old_value;
145 bool is_observed = observe && receiver->map()->is_observed();
146 if (is_observed) {
147 MaybeHandle<Object> maybe_old = Object::GetPropertyWithAccessor(&it);
148 if (!maybe_old.ToHandle(&old_value)) return maybe_old;
149 }
150
151 it.ReconfigureDataProperty(value, it.property_attributes());
152
153 if (is_observed && !old_value->SameValue(*value)) {
154 return JSObject::EnqueueChangeRecord(receiver, "update", name, old_value);
155 }
156
157 return value;
158}
159
160void Accessors::ReconfigureToDataProperty(
161 v8::Local<v8::Name> key, v8::Local<v8::Value> val,
162 const v8::PropertyCallbackInfo<void>& info) {
163 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
164 HandleScope scope(isolate);
165 Handle<JSObject> receiver =
166 Handle<JSObject>::cast(Utils::OpenHandle(*info.This()));
167 Handle<JSObject> holder =
168 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
169 Handle<Name> name = Utils::OpenHandle(*key);
170 Handle<Object> value = Utils::OpenHandle(*val);
171 MaybeHandle<Object> result = ReplaceAccessorWithDataProperty(
172 isolate, receiver, holder, name, value, false);
173 if (result.is_null()) isolate->OptionalRescheduleException(false);
174}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175
176//
177// Accessors::ArgumentsIterator
178//
179
180
181void Accessors::ArgumentsIteratorGetter(
182 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
183 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
184 DisallowHeapAllocation no_allocation;
185 HandleScope scope(isolate);
186 Object* result = isolate->native_context()->array_values_iterator();
187 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
188}
189
190
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
192 Isolate* isolate, PropertyAttributes attributes) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400193 Handle<Name> name = isolate->factory()->iterator_symbol();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100194 return MakeAccessor(isolate, name, &ArgumentsIteratorGetter, nullptr,
195 attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000196}
197
198
199//
200// Accessors::ArrayLength
201//
202
203
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000204void Accessors::ArrayLengthGetter(
205 v8::Local<v8::Name> name,
206 const v8::PropertyCallbackInfo<v8::Value>& info) {
207 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
208 DisallowHeapAllocation no_allocation;
Steve Block44f0eee2011-05-26 01:26:41 +0100209 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
211 Object* result = holder->length();
212 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000213}
214
215
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000216void Accessors::ArrayLengthSetter(
217 v8::Local<v8::Name> name,
218 v8::Local<v8::Value> val,
219 const v8::PropertyCallbackInfo<void>& info) {
220 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
221 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000222
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000223 Handle<JSReceiver> object = Utils::OpenHandle(*info.This());
224 Handle<JSArray> array = Handle<JSArray>::cast(object);
225 Handle<Object> length_obj = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000226
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227 uint32_t length = 0;
228 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000229 isolate->OptionalRescheduleException(false);
230 return;
231 }
232
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000233 if (JSArray::ObservableSetLength(array, length).is_null()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234 isolate->OptionalRescheduleException(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000235 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100236
237 if (info.ShouldThrowOnError()) {
238 uint32_t actual_new_len = 0;
239 CHECK(array->length()->ToArrayLength(&actual_new_len));
240 // Throw TypeError if there were non-deletable elements.
241 if (actual_new_len != length) {
242 Factory* factory = isolate->factory();
243 isolate->Throw(*factory->NewTypeError(
244 MessageTemplate::kStrictDeleteProperty,
245 factory->NewNumberFromUint(actual_new_len - 1), array));
246 isolate->OptionalRescheduleException(false);
247 }
248 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000249}
250
251
252Handle<AccessorInfo> Accessors::ArrayLengthInfo(
253 Isolate* isolate, PropertyAttributes attributes) {
254 return MakeAccessor(isolate,
255 isolate->factory()->length_string(),
256 &ArrayLengthGetter,
257 &ArrayLengthSetter,
258 attributes);
259}
260
Steve Blocka7e24c12009-10-30 11:49:00 +0000261
Steve Blocka7e24c12009-10-30 11:49:00 +0000262//
263// Accessors::StringLength
264//
265
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000266void Accessors::StringLengthGetter(
267 v8::Local<v8::Name> name,
268 const v8::PropertyCallbackInfo<v8::Value>& info) {
269 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
270 DisallowHeapAllocation no_allocation;
271 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000272
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000273 // We have a slight impedance mismatch between the external API and the way we
274 // use callbacks internally: Externally, callbacks can only be used with
275 // v8::Object, but internally we have callbacks on entities which are higher
276 // in the hierarchy, in this case for String values.
277
278 Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
279 if (!value->IsString()) {
280 // Not a string value. That means that we either got a String wrapper or
281 // a Value with a String wrapper in its prototype chain.
282 value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
283 }
284 Object* result = Smi::FromInt(String::cast(value)->length());
285 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000286}
287
288
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000289Handle<AccessorInfo> Accessors::StringLengthInfo(
290 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100291 return MakeAccessor(isolate, isolate->factory()->length_string(),
292 &StringLengthGetter, nullptr, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000293}
294
295
Steve Blocka7e24c12009-10-30 11:49:00 +0000296//
297// Accessors::ScriptColumnOffset
298//
299
300
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000301void Accessors::ScriptColumnOffsetGetter(
302 v8::Local<v8::Name> name,
303 const v8::PropertyCallbackInfo<v8::Value>& info) {
304 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
305 DisallowHeapAllocation no_allocation;
306 HandleScope scope(isolate);
307 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000308 Object* res = Smi::FromInt(
309 Script::cast(JSValue::cast(object)->value())->column_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000310 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000311}
312
313
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000314Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
315 Isolate* isolate, PropertyAttributes attributes) {
316 Handle<String> name(isolate->factory()->InternalizeOneByteString(
317 STATIC_CHAR_VECTOR("column_offset")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100318 return MakeAccessor(isolate, name, &ScriptColumnOffsetGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000319 attributes);
320}
321
322
323//
324// Accessors::ScriptId
325//
326
327
328void Accessors::ScriptIdGetter(
329 v8::Local<v8::Name> name,
330 const v8::PropertyCallbackInfo<v8::Value>& info) {
331 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
332 DisallowHeapAllocation no_allocation;
333 HandleScope scope(isolate);
334 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000335 Object* id = Smi::FromInt(Script::cast(JSValue::cast(object)->value())->id());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000336 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate)));
337}
338
339
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000340Handle<AccessorInfo> Accessors::ScriptIdInfo(
341 Isolate* isolate, PropertyAttributes attributes) {
342 Handle<String> name(
343 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100344 return MakeAccessor(isolate, name, &ScriptIdGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000345}
346
347
348//
349// Accessors::ScriptName
350//
351
352
353void Accessors::ScriptNameGetter(
354 v8::Local<v8::Name> name,
355 const v8::PropertyCallbackInfo<v8::Value>& info) {
356 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
357 DisallowHeapAllocation no_allocation;
358 HandleScope scope(isolate);
359 Object* object = *Utils::OpenHandle(*info.This());
360 Object* source = Script::cast(JSValue::cast(object)->value())->name();
361 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
362}
363
364
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000365Handle<AccessorInfo> Accessors::ScriptNameInfo(
366 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100367 return MakeAccessor(isolate, isolate->factory()->name_string(),
368 &ScriptNameGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000369}
370
371
372//
373// Accessors::ScriptSource
374//
375
376
377void Accessors::ScriptSourceGetter(
378 v8::Local<v8::Name> name,
379 const v8::PropertyCallbackInfo<v8::Value>& info) {
380 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
381 DisallowHeapAllocation no_allocation;
382 HandleScope scope(isolate);
383 Object* object = *Utils::OpenHandle(*info.This());
384 Object* source = Script::cast(JSValue::cast(object)->value())->source();
385 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
386}
387
388
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000389Handle<AccessorInfo> Accessors::ScriptSourceInfo(
390 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100391 return MakeAccessor(isolate, isolate->factory()->source_string(),
392 &ScriptSourceGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393}
394
395
396//
397// Accessors::ScriptLineOffset
398//
399
400
401void Accessors::ScriptLineOffsetGetter(
402 v8::Local<v8::Name> name,
403 const v8::PropertyCallbackInfo<v8::Value>& info) {
404 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
405 DisallowHeapAllocation no_allocation;
406 HandleScope scope(isolate);
407 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000408 Object* res =
409 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->line_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000410 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
411}
412
413
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000414Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
415 Isolate* isolate, PropertyAttributes attributes) {
416 Handle<String> name(isolate->factory()->InternalizeOneByteString(
417 STATIC_CHAR_VECTOR("line_offset")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100418 return MakeAccessor(isolate, name, &ScriptLineOffsetGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000419 attributes);
420}
Steve Blocka7e24c12009-10-30 11:49:00 +0000421
422
423//
424// Accessors::ScriptType
425//
426
427
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000428void Accessors::ScriptTypeGetter(
429 v8::Local<v8::Name> name,
430 const v8::PropertyCallbackInfo<v8::Value>& info) {
431 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
432 DisallowHeapAllocation no_allocation;
433 HandleScope scope(isolate);
434 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435 Object* res =
436 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->type());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000437 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000438}
439
440
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000441Handle<AccessorInfo> Accessors::ScriptTypeInfo(
442 Isolate* isolate, PropertyAttributes attributes) {
443 Handle<String> name(
444 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100445 return MakeAccessor(isolate, name, &ScriptTypeGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000446}
Steve Blocka7e24c12009-10-30 11:49:00 +0000447
448
449//
450// Accessors::ScriptCompilationType
451//
452
453
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000454void Accessors::ScriptCompilationTypeGetter(
455 v8::Local<v8::Name> name,
456 const v8::PropertyCallbackInfo<v8::Value>& info) {
457 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
458 DisallowHeapAllocation no_allocation;
459 HandleScope scope(isolate);
460 Object* object = *Utils::OpenHandle(*info.This());
461 Object* res = Smi::FromInt(
462 Script::cast(JSValue::cast(object)->value())->compilation_type());
463 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000464}
465
466
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000467Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
468 Isolate* isolate, PropertyAttributes attributes) {
469 Handle<String> name(isolate->factory()->InternalizeOneByteString(
470 STATIC_CHAR_VECTOR("compilation_type")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100471 return MakeAccessor(isolate, name, &ScriptCompilationTypeGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000472 attributes);
473}
Steve Blocka7e24c12009-10-30 11:49:00 +0000474
475
476//
477// Accessors::ScriptGetLineEnds
478//
479
480
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000481void Accessors::ScriptLineEndsGetter(
482 v8::Local<v8::Name> name,
483 const v8::PropertyCallbackInfo<v8::Value>& info) {
484 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
Steve Block44f0eee2011-05-26 01:26:41 +0100485 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000486 Handle<Object> object = Utils::OpenHandle(*info.This());
487 Handle<Script> script(
488 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
489 Script::InitLineEnds(script);
490 DCHECK(script->line_ends()->IsFixedArray());
Steve Blockd0582a62009-12-15 09:54:21 +0000491 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800492 // We do not want anyone to modify this array from JS.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000493 DCHECK(*line_ends == isolate->heap()->empty_fixed_array() ||
Steve Block44f0eee2011-05-26 01:26:41 +0100494 line_ends->map() == isolate->heap()->fixed_cow_array_map());
495 Handle<JSArray> js_array =
496 isolate->factory()->NewJSArrayWithElements(line_ends);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000497 info.GetReturnValue().Set(Utils::ToLocal(js_array));
Steve Blocka7e24c12009-10-30 11:49:00 +0000498}
499
500
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000501Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
502 Isolate* isolate, PropertyAttributes attributes) {
503 Handle<String> name(isolate->factory()->InternalizeOneByteString(
504 STATIC_CHAR_VECTOR("line_ends")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100505 return MakeAccessor(isolate, name, &ScriptLineEndsGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000506 attributes);
507}
508
509
510//
511// Accessors::ScriptSourceUrl
512//
513
514
515void Accessors::ScriptSourceUrlGetter(
516 v8::Local<v8::Name> name,
517 const v8::PropertyCallbackInfo<v8::Value>& info) {
518 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
519 DisallowHeapAllocation no_allocation;
520 HandleScope scope(isolate);
521 Object* object = *Utils::OpenHandle(*info.This());
522 Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
523 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
524}
525
526
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000527Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
528 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100529 return MakeAccessor(isolate, isolate->factory()->source_url_string(),
530 &ScriptSourceUrlGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000531}
532
533
534//
535// Accessors::ScriptSourceMappingUrl
536//
537
538
539void Accessors::ScriptSourceMappingUrlGetter(
540 v8::Local<v8::Name> name,
541 const v8::PropertyCallbackInfo<v8::Value>& info) {
542 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
543 DisallowHeapAllocation no_allocation;
544 HandleScope scope(isolate);
545 Object* object = *Utils::OpenHandle(*info.This());
546 Object* url =
547 Script::cast(JSValue::cast(object)->value())->source_mapping_url();
548 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
549}
550
551
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000552Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
553 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100554 return MakeAccessor(isolate, isolate->factory()->source_mapping_url_string(),
555 &ScriptSourceMappingUrlGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000556}
Steve Blocka7e24c12009-10-30 11:49:00 +0000557
558
559//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000560// Accessors::ScriptIsEmbedderDebugScript
561//
562
563
564void Accessors::ScriptIsEmbedderDebugScriptGetter(
565 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
566 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
567 DisallowHeapAllocation no_allocation;
568 HandleScope scope(isolate);
569 Object* object = *Utils::OpenHandle(*info.This());
570 bool is_embedder_debug_script = Script::cast(JSValue::cast(object)->value())
571 ->origin_options()
572 .IsEmbedderDebugScript();
573 Object* res = *isolate->factory()->ToBoolean(is_embedder_debug_script);
574 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
575}
576
577
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000578Handle<AccessorInfo> Accessors::ScriptIsEmbedderDebugScriptInfo(
579 Isolate* isolate, PropertyAttributes attributes) {
580 Handle<String> name(isolate->factory()->InternalizeOneByteString(
581 STATIC_CHAR_VECTOR("is_debugger_script")));
582 return MakeAccessor(isolate, name, &ScriptIsEmbedderDebugScriptGetter,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100583 nullptr, attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000584}
585
586
587//
Steve Blocka7e24c12009-10-30 11:49:00 +0000588// Accessors::ScriptGetContextData
589//
590
591
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000592void Accessors::ScriptContextDataGetter(
593 v8::Local<v8::Name> name,
594 const v8::PropertyCallbackInfo<v8::Value>& info) {
595 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
596 DisallowHeapAllocation no_allocation;
597 HandleScope scope(isolate);
598 Object* object = *Utils::OpenHandle(*info.This());
599 Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
600 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000601}
602
603
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000604Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
605 Isolate* isolate, PropertyAttributes attributes) {
606 Handle<String> name(isolate->factory()->InternalizeOneByteString(
607 STATIC_CHAR_VECTOR("context_data")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100608 return MakeAccessor(isolate, name, &ScriptContextDataGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000609 attributes);
610}
Steve Blocka7e24c12009-10-30 11:49:00 +0000611
612
613//
Steve Blockd0582a62009-12-15 09:54:21 +0000614// Accessors::ScriptGetEvalFromScript
Steve Blocka7e24c12009-10-30 11:49:00 +0000615//
616
617
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000618void Accessors::ScriptEvalFromScriptGetter(
619 v8::Local<v8::Name> name,
620 const v8::PropertyCallbackInfo<v8::Value>& info) {
621 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
622 HandleScope scope(isolate);
623 Handle<Object> object = Utils::OpenHandle(*info.This());
624 Handle<Script> script(
625 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
626 Handle<Object> result = isolate->factory()->undefined_value();
627 if (!script->eval_from_shared()->IsUndefined()) {
Steve Blockd0582a62009-12-15 09:54:21 +0000628 Handle<SharedFunctionInfo> eval_from_shared(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000629 SharedFunctionInfo::cast(script->eval_from_shared()));
Steve Blockd0582a62009-12-15 09:54:21 +0000630 if (eval_from_shared->script()->IsScript()) {
631 Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000632 result = Script::GetWrapper(eval_from_script);
Steve Blockd0582a62009-12-15 09:54:21 +0000633 }
634 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000635
636 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000637}
638
639
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000640Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
641 Isolate* isolate, PropertyAttributes attributes) {
642 Handle<String> name(isolate->factory()->InternalizeOneByteString(
643 STATIC_CHAR_VECTOR("eval_from_script")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100644 return MakeAccessor(isolate, name, &ScriptEvalFromScriptGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000645 attributes);
646}
Steve Blocka7e24c12009-10-30 11:49:00 +0000647
648
649//
Steve Blockd0582a62009-12-15 09:54:21 +0000650// Accessors::ScriptGetEvalFromScriptPosition
Steve Blocka7e24c12009-10-30 11:49:00 +0000651//
652
653
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000654void Accessors::ScriptEvalFromScriptPositionGetter(
655 v8::Local<v8::Name> name,
656 const v8::PropertyCallbackInfo<v8::Value>& info) {
657 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
658 HandleScope scope(isolate);
659 Handle<Object> object = Utils::OpenHandle(*info.This());
660 Handle<Script> script(
661 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
662 Handle<Object> result = isolate->factory()->undefined_value();
663 if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
664 Handle<Code> code(SharedFunctionInfo::cast(
665 script->eval_from_shared())->code());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000666 result = Handle<Object>(Smi::FromInt(code->SourcePosition(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000667 script->eval_from_instructions_offset())),
668 isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000669 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000670 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000671}
672
673
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000674Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
675 Isolate* isolate, PropertyAttributes attributes) {
676 Handle<String> name(isolate->factory()->InternalizeOneByteString(
677 STATIC_CHAR_VECTOR("eval_from_script_position")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100678 return MakeAccessor(isolate, name, &ScriptEvalFromScriptPositionGetter,
679 nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000680}
Steve Blockd0582a62009-12-15 09:54:21 +0000681
682
683//
684// Accessors::ScriptGetEvalFromFunctionName
685//
686
687
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000688void Accessors::ScriptEvalFromFunctionNameGetter(
689 v8::Local<v8::Name> name,
690 const v8::PropertyCallbackInfo<v8::Value>& info) {
691 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
692 HandleScope scope(isolate);
693 Handle<Object> object = Utils::OpenHandle(*info.This());
694 Handle<Script> script(
695 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
696 Handle<Object> result;
697 Handle<SharedFunctionInfo> shared(
698 SharedFunctionInfo::cast(script->eval_from_shared()));
Steve Blockd0582a62009-12-15 09:54:21 +0000699 // Find the name of the function calling eval.
700 if (!shared->name()->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000701 result = Handle<Object>(shared->name(), isolate);
Steve Blockd0582a62009-12-15 09:54:21 +0000702 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000703 result = Handle<Object>(shared->inferred_name(), isolate);
Steve Blockd0582a62009-12-15 09:54:21 +0000704 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000705 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blockd0582a62009-12-15 09:54:21 +0000706}
707
708
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000709Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
710 Isolate* isolate, PropertyAttributes attributes) {
711 Handle<String> name(isolate->factory()->InternalizeOneByteString(
712 STATIC_CHAR_VECTOR("eval_from_function_name")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100713 return MakeAccessor(isolate, name, &ScriptEvalFromFunctionNameGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000714 attributes);
715}
Steve Blocka7e24c12009-10-30 11:49:00 +0000716
717
718//
719// Accessors::FunctionPrototype
720//
721
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000722static Handle<Object> GetFunctionPrototype(Isolate* isolate,
723 Handle<JSFunction> function) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000724 if (!function->has_prototype()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000725 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
726 JSFunction::SetPrototype(function, proto);
Steve Blocka7e24c12009-10-30 11:49:00 +0000727 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000728 return Handle<Object>(function->prototype(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000729}
730
731
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400732MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype(
733 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000734 Handle<Object> old_value;
735 bool is_observed = function->map()->is_observed();
736 if (is_observed) {
737 if (function->has_prototype())
738 old_value = handle(function->prototype(), isolate);
739 else
740 old_value = isolate->factory()->NewFunctionPrototype(function);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100741 }
742
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000743 JSFunction::SetPrototype(function, value);
744 DCHECK(function->prototype() == *value);
745
746 if (is_observed && !old_value->SameValue(*value)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400747 MaybeHandle<Object> result = JSObject::EnqueueChangeRecord(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000748 function, "update", isolate->factory()->prototype_string(), old_value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400749 if (result.is_null()) return MaybeHandle<Object>();
John Reck59135872010-11-02 12:39:01 -0700750 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000751
Steve Blocka7e24c12009-10-30 11:49:00 +0000752 return function;
753}
754
755
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400756MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
757 Handle<Object> prototype) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000758 DCHECK(function->IsConstructor());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000759 Isolate* isolate = function->GetIsolate();
760 return SetFunctionPrototype(isolate, function, prototype);
761}
762
763
764void Accessors::FunctionPrototypeGetter(
765 v8::Local<v8::Name> name,
766 const v8::PropertyCallbackInfo<v8::Value>& info) {
767 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
768 HandleScope scope(isolate);
769 Handle<JSFunction> function =
770 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
771 Handle<Object> result = GetFunctionPrototype(isolate, function);
772 info.GetReturnValue().Set(Utils::ToLocal(result));
773}
774
775
776void Accessors::FunctionPrototypeSetter(
777 v8::Local<v8::Name> name,
778 v8::Local<v8::Value> val,
779 const v8::PropertyCallbackInfo<void>& info) {
780 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
781 HandleScope scope(isolate);
782 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000783 Handle<JSFunction> object =
784 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400785 if (SetFunctionPrototype(isolate, object, value).is_null()) {
786 isolate->OptionalRescheduleException(false);
787 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000788}
789
790
791Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
792 Isolate* isolate, PropertyAttributes attributes) {
793 return MakeAccessor(isolate,
794 isolate->factory()->prototype_string(),
795 &FunctionPrototypeGetter,
796 &FunctionPrototypeSetter,
797 attributes);
798}
Steve Blocka7e24c12009-10-30 11:49:00 +0000799
800
801//
802// Accessors::FunctionLength
803//
804
805
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000806void Accessors::FunctionLengthGetter(
807 v8::Local<v8::Name> name,
808 const v8::PropertyCallbackInfo<v8::Value>& info) {
809 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
810 HandleScope scope(isolate);
811 Handle<JSFunction> function =
812 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
813
814 int length = 0;
815 if (function->shared()->is_compiled()) {
816 length = function->shared()->length();
817 } else {
Steve Blocka7e24c12009-10-30 11:49:00 +0000818 // If the function isn't compiled yet, the length is not computed
819 // correctly yet. Compile it now and return the right length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000820 if (Compiler::Compile(function, KEEP_EXCEPTION)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000821 length = function->shared()->length();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100822 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000823 if (isolate->has_pending_exception()) {
824 isolate->OptionalRescheduleException(false);
825 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000826 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000827 Handle<Object> result(Smi::FromInt(length), isolate);
828 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000829}
830
Ben Murdoch097c5b22016-05-18 11:27:45 +0100831void Accessors::ObservedReconfigureToDataProperty(
832 v8::Local<v8::Name> key, v8::Local<v8::Value> val,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000833 const v8::PropertyCallbackInfo<void>& info) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000834 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
835 HandleScope scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100836 Handle<JSObject> receiver =
837 Handle<JSObject>::cast(Utils::OpenHandle(*info.This()));
838 Handle<JSObject> holder =
839 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
840 Handle<Name> name = Utils::OpenHandle(*key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000841 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100842 MaybeHandle<Object> result = ReplaceAccessorWithDataProperty(
843 isolate, receiver, holder, name, value, true);
844 if (result.is_null()) isolate->OptionalRescheduleException(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000845}
846
847
848Handle<AccessorInfo> Accessors::FunctionLengthInfo(
849 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100850 return MakeAccessor(isolate, isolate->factory()->length_string(),
851 &FunctionLengthGetter, &ObservedReconfigureToDataProperty,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000852 attributes);
853}
Steve Blocka7e24c12009-10-30 11:49:00 +0000854
855
856//
857// Accessors::FunctionName
858//
859
860
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861void Accessors::FunctionNameGetter(
862 v8::Local<v8::Name> name,
863 const v8::PropertyCallbackInfo<v8::Value>& info) {
864 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
865 HandleScope scope(isolate);
866 Handle<JSFunction> function =
867 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000868 Handle<Object> result;
869 if (function->shared()->name_should_print_as_anonymous()) {
870 result = isolate->factory()->anonymous_string();
871 } else {
872 result = handle(function->shared()->name(), isolate);
873 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000874 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000875}
876
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000877Handle<AccessorInfo> Accessors::FunctionNameInfo(
878 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100879 return MakeAccessor(isolate, isolate->factory()->name_string(),
880 &FunctionNameGetter, &ObservedReconfigureToDataProperty,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000881 attributes);
882}
Steve Blocka7e24c12009-10-30 11:49:00 +0000883
884
885//
886// Accessors::FunctionArguments
887//
888
Ben Murdochb0fe1622011-05-05 13:52:32 +0100889
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000890static Handle<Object> ArgumentsForInlinedFunction(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100891 JavaScriptFrame* frame,
892 Handle<JSFunction> inlined_function,
893 int inlined_frame_index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000894 Isolate* isolate = inlined_function->GetIsolate();
895 Factory* factory = isolate->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000896
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000897 TranslatedState translated_values(frame);
898 translated_values.Prepare(false, frame->fp());
899
900 int argument_count = 0;
901 TranslatedFrame* translated_frame =
902 translated_values.GetArgumentsInfoFromJSFrameIndex(inlined_frame_index,
903 &argument_count);
904 TranslatedFrame::iterator iter = translated_frame->begin();
905
906 // Skip the function.
907 iter++;
908
909 // Skip the receiver.
910 iter++;
911 argument_count--;
912
Ben Murdochb0fe1622011-05-05 13:52:32 +0100913 Handle<JSObject> arguments =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000914 factory->NewArgumentsObject(inlined_function, argument_count);
915 Handle<FixedArray> array = factory->NewFixedArray(argument_count);
916 bool should_deoptimize = false;
917 for (int i = 0; i < argument_count; ++i) {
918 // If we materialize any object, we should deopt because we might alias
919 // an object that was eliminated by escape analysis.
920 should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
921 Handle<Object> value = iter->GetValue();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100922 array->set(i, *value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000923 iter++;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100924 }
925 arguments->set_elements(*array);
926
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000927 if (should_deoptimize) {
928 translated_values.StoreMaterializedValuesAndDeopt();
929 }
930
Ben Murdochb0fe1622011-05-05 13:52:32 +0100931 // Return the freshly allocated arguments object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000932 return arguments;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100933}
934
Steve Blocka7e24c12009-10-30 11:49:00 +0000935
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000936static int FindFunctionInFrame(JavaScriptFrame* frame,
937 Handle<JSFunction> function) {
938 DisallowHeapAllocation no_allocation;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100939 List<JSFunction*> functions(2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000940 frame->GetFunctions(&functions);
941 for (int i = functions.length() - 1; i >= 0; i--) {
942 if (functions[i] == *function) return i;
943 }
944 return -1;
945}
946
947
Ben Murdoch097c5b22016-05-18 11:27:45 +0100948namespace {
949
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000950Handle<Object> GetFunctionArguments(Isolate* isolate,
951 Handle<JSFunction> function) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000952 // Find the top invocation of the function by traversing frames.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100953 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000954 JavaScriptFrame* frame = it.frame();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000955 int function_index = FindFunctionInFrame(frame, function);
956 if (function_index < 0) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +0000957
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000958 if (function_index > 0) {
959 // The function in question was inlined. Inlined functions have the
960 // correct number of arguments and no allocated arguments object, so
961 // we can construct a fresh one by interpreting the function's
962 // deoptimization input data.
963 return ArgumentsForInlinedFunction(frame, function, function_index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000964 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000965
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000966 // Find the frame that holds the actual arguments passed to the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000967 it.AdvanceToArgumentsFrame();
968 frame = it.frame();
969
970 // Get the number of arguments and construct an arguments object
971 // mirror for the right frame.
972 const int length = frame->ComputeParametersCount();
973 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
974 function, length);
975 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
976
977 // Copy the parameters to the arguments object.
978 DCHECK(array->length() == length);
979 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
980 arguments->set_elements(*array);
981
982 // Return the freshly allocated arguments object.
983 return arguments;
Steve Blocka7e24c12009-10-30 11:49:00 +0000984 }
985
986 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000987 return isolate->factory()->null_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000988}
989
Ben Murdoch097c5b22016-05-18 11:27:45 +0100990} // namespace
Steve Blocka7e24c12009-10-30 11:49:00 +0000991
Ben Murdoch097c5b22016-05-18 11:27:45 +0100992
993Handle<JSObject> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
994 Handle<Object> arguments =
995 GetFunctionArguments(function->GetIsolate(), function);
996 CHECK(arguments->IsJSObject());
997 return Handle<JSObject>::cast(arguments);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000998}
999
1000
1001void Accessors::FunctionArgumentsGetter(
1002 v8::Local<v8::Name> name,
1003 const v8::PropertyCallbackInfo<v8::Value>& info) {
1004 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1005 HandleScope scope(isolate);
1006 Handle<JSFunction> function =
1007 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001008 Handle<Object> result =
1009 function->shared()->native()
1010 ? Handle<Object>::cast(isolate->factory()->null_value())
1011 : GetFunctionArguments(isolate, function);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001012 info.GetReturnValue().Set(Utils::ToLocal(result));
1013}
1014
1015
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001016Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
1017 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001018 return MakeAccessor(isolate, isolate->factory()->arguments_string(),
1019 &FunctionArgumentsGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001020}
Steve Blocka7e24c12009-10-30 11:49:00 +00001021
1022
1023//
1024// Accessors::FunctionCaller
1025//
1026
1027
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001028static inline bool AllowAccessToFunction(Context* current_context,
1029 JSFunction* function) {
1030 return current_context->HasSameSecurityTokenAs(function->context());
Steve Block44f0eee2011-05-26 01:26:41 +01001031}
1032
1033
Ben Murdoch257744e2011-11-30 15:57:28 +00001034class FrameFunctionIterator {
1035 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001036 FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
1037 : isolate_(isolate),
1038 frame_iterator_(isolate),
Ben Murdoch257744e2011-11-30 15:57:28 +00001039 functions_(2),
1040 index_(0) {
1041 GetFunctions();
1042 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001043 JSFunction* next() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001044 while (true) {
1045 if (functions_.length() == 0) return NULL;
1046 JSFunction* next_function = functions_[index_];
1047 index_--;
1048 if (index_ < 0) {
1049 GetFunctions();
1050 }
1051 // Skip functions from other origins.
1052 if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
1053 return next_function;
Ben Murdoch257744e2011-11-30 15:57:28 +00001054 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001055 }
1056
1057 // Iterate through functions until the first occurence of 'function'.
1058 // Returns true if 'function' is found, and false if the iterator ends
1059 // without finding it.
1060 bool Find(JSFunction* function) {
1061 JSFunction* next_function;
1062 do {
1063 next_function = next();
1064 if (next_function == function) return true;
1065 } while (next_function != NULL);
1066 return false;
1067 }
Ben Murdoch589d6972011-11-30 16:04:58 +00001068
Ben Murdoch257744e2011-11-30 15:57:28 +00001069 private:
1070 void GetFunctions() {
1071 functions_.Rewind(0);
1072 if (frame_iterator_.done()) return;
1073 JavaScriptFrame* frame = frame_iterator_.frame();
1074 frame->GetFunctions(&functions_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001075 DCHECK(functions_.length() > 0);
Ben Murdoch257744e2011-11-30 15:57:28 +00001076 frame_iterator_.Advance();
1077 index_ = functions_.length() - 1;
1078 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001079 Isolate* isolate_;
Ben Murdoch257744e2011-11-30 15:57:28 +00001080 JavaScriptFrameIterator frame_iterator_;
1081 List<JSFunction*> functions_;
1082 int index_;
1083};
1084
1085
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001086MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
1087 Handle<JSFunction> function) {
1088 DisallowHeapAllocation no_allocation;
1089 FrameFunctionIterator it(isolate, no_allocation);
1090 if (function->shared()->native()) {
1091 return MaybeHandle<JSFunction>();
1092 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001093 // Find the function from the frames.
1094 if (!it.Find(*function)) {
1095 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001096 return MaybeHandle<JSFunction>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001097 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001098 // Find previously called non-toplevel function.
1099 JSFunction* caller;
1100 do {
1101 caller = it.next();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001102 if (caller == NULL) return MaybeHandle<JSFunction>();
Ben Murdoch257744e2011-11-30 15:57:28 +00001103 } while (caller->shared()->is_toplevel());
1104
1105 // If caller is a built-in function and caller's caller is also built-in,
1106 // use that instead.
1107 JSFunction* potential_caller = caller;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001108 while (potential_caller != NULL && potential_caller->shared()->IsBuiltin()) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001109 caller = potential_caller;
1110 potential_caller = it.next();
1111 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001112 if (!caller->shared()->native() && potential_caller != NULL) {
1113 caller = potential_caller;
1114 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001115 // Censor if the caller is not a sloppy mode function.
1116 // Change from ES5, which used to throw, see:
1117 // https://bugs.ecmascript.org/show_bug.cgi?id=310
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001118 if (is_strict(caller->shared()->language_mode())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001119 return MaybeHandle<JSFunction>();
1120 }
1121 // Don't return caller from another security context.
1122 if (!AllowAccessToFunction(isolate->context(), caller)) {
1123 return MaybeHandle<JSFunction>();
1124 }
1125 return Handle<JSFunction>(caller);
Steve Blocka7e24c12009-10-30 11:49:00 +00001126}
1127
1128
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001129void Accessors::FunctionCallerGetter(
1130 v8::Local<v8::Name> name,
1131 const v8::PropertyCallbackInfo<v8::Value>& info) {
1132 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1133 HandleScope scope(isolate);
1134 Handle<JSFunction> function =
1135 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1136 Handle<Object> result;
1137 MaybeHandle<JSFunction> maybe_caller;
1138 maybe_caller = FindCaller(isolate, function);
1139 Handle<JSFunction> caller;
1140 if (maybe_caller.ToHandle(&caller)) {
1141 result = caller;
1142 } else {
1143 result = isolate->factory()->null_value();
1144 }
1145 info.GetReturnValue().Set(Utils::ToLocal(result));
1146}
1147
1148
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001149Handle<AccessorInfo> Accessors::FunctionCallerInfo(
1150 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001151 return MakeAccessor(isolate, isolate->factory()->caller_string(),
1152 &FunctionCallerGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001153}
Steve Blocka7e24c12009-10-30 11:49:00 +00001154
1155
1156//
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001157// Accessors::MakeModuleExport
Steve Blocka7e24c12009-10-30 11:49:00 +00001158//
1159
Ben Murdoch097c5b22016-05-18 11:27:45 +01001160static void ModuleGetExport(v8::Local<v8::Name> property,
1161 const v8::PropertyCallbackInfo<v8::Value>& info) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001162 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
1163 Context* context = Context::cast(instance->context());
1164 DCHECK(context->IsModuleContext());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001165 Isolate* isolate = instance->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001166 int slot = info.Data()
1167 ->Int32Value(info.GetIsolate()->GetCurrentContext())
1168 .FromMaybe(-1);
1169 if (slot < 0 || slot >= context->length()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001170 Handle<Name> name = v8::Utils::OpenHandle(*property);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001171
1172 Handle<Object> exception = isolate->factory()->NewReferenceError(
1173 MessageTemplate::kNotDefined, name);
1174 isolate->ScheduleThrow(*exception);
1175 return;
1176 }
1177 Object* value = context->get(slot);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001178 if (value->IsTheHole()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001179 Handle<Name> name = v8::Utils::OpenHandle(*property);
Steve Blocka7e24c12009-10-30 11:49:00 +00001180
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001181 Handle<Object> exception = isolate->factory()->NewReferenceError(
1182 MessageTemplate::kNotDefined, name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001183 isolate->ScheduleThrow(*exception);
1184 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001185 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001186 info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001187}
1188
1189
Ben Murdoch097c5b22016-05-18 11:27:45 +01001190static void ModuleSetExport(v8::Local<v8::Name> property,
1191 v8::Local<v8::Value> value,
1192 const v8::PropertyCallbackInfo<void>& info) {
1193 if (!info.ShouldThrowOnError()) return;
1194 Handle<Name> name = v8::Utils::OpenHandle(*property);
1195 Isolate* isolate = name->GetIsolate();
1196 Handle<Object> exception =
1197 isolate->factory()->NewTypeError(MessageTemplate::kNotDefined, name);
1198 isolate->ScheduleThrow(*exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00001199}
1200
1201
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001202Handle<AccessorInfo> Accessors::MakeModuleExport(
1203 Handle<String> name,
1204 int index,
1205 PropertyAttributes attributes) {
1206 Isolate* isolate = name->GetIsolate();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001207 Handle<AccessorInfo> info = MakeAccessor(isolate, name, &ModuleGetExport,
1208 &ModuleSetExport, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001209 info->set_data(Smi::FromInt(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001210 return info;
1211}
1212
Steve Blocka7e24c12009-10-30 11:49:00 +00001213
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001214} // namespace internal
1215} // namespace v8