blob: 374c0a21f84b25715dc46cc7af9a89c4ba864d07 [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 Murdochda12d292016-06-02 14:46:10 +010035 info->set_is_sloppy(false);
Ben Murdoch097c5b22016-05-18 11:27:45 +010036 name = factory->InternalizeName(name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000037 info->set_name(*name);
38 Handle<Object> get = v8::FromCData(isolate, getter);
Ben Murdoch097c5b22016-05-18 11:27:45 +010039 if (setter == nullptr) setter = &ReconfigureToDataProperty;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000040 Handle<Object> set = v8::FromCData(isolate, setter);
41 info->set_getter(*get);
42 info->set_setter(*set);
43 return info;
Steve Blocka7e24c12009-10-30 11:49:00 +000044}
45
46
Ben Murdochb8a8cc12014-11-26 15:28:44 +000047static V8_INLINE bool CheckForName(Handle<Name> name,
48 Handle<String> property_name,
49 int offset,
50 int* object_offset) {
51 if (Name::Equals(name, property_name)) {
52 *object_offset = offset;
53 return true;
54 }
55 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +000056}
57
58
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059// Returns true for properties that are accessors to object fields.
60// If true, *object_offset contains offset of object field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000061bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000062 int* object_offset) {
63 Isolate* isolate = name->GetIsolate();
64
Ben Murdochb8a8cc12014-11-26 15:28:44 +000065 switch (map->instance_type()) {
66 case JS_ARRAY_TYPE:
67 return
68 CheckForName(name, isolate->factory()->length_string(),
69 JSArray::kLengthOffset, object_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070 case JS_ARRAY_BUFFER_TYPE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000071 return CheckForName(name, isolate->factory()->byte_length_string(),
72 JSArrayBuffer::kByteLengthOffset, object_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000073 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000074 if (map->instance_type() < FIRST_NONSTRING_TYPE) {
75 return CheckForName(name, isolate->factory()->length_string(),
76 String::kLengthOffset, object_offset);
77 }
78
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079 return false;
80 }
81}
82
83
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000084bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map,
85 Handle<Name> name,
86 int* object_offset) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010087 DCHECK(name->IsUniqueName());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000088 Isolate* isolate = name->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000089
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000090 switch (map->instance_type()) {
91 case JS_TYPED_ARRAY_TYPE: {
92 if (!CheckForName(name, isolate->factory()->length_string(),
93 JSTypedArray::kLengthOffset, object_offset) &&
94 !CheckForName(name, isolate->factory()->byte_length_string(),
95 JSTypedArray::kByteLengthOffset, object_offset) &&
96 !CheckForName(name, isolate->factory()->byte_offset_string(),
97 JSTypedArray::kByteOffsetOffset, object_offset)) {
98 return false;
99 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 if (map->is_dictionary_map()) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000102
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000103 // Check if the property is overridden on the instance.
104 DescriptorArray* descriptors = map->instance_descriptors();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100105 int descriptor = descriptors->SearchWithCache(isolate, *name, *map);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000106 if (descriptor != DescriptorArray::kNotFound) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000107
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000108 Handle<Object> proto = Handle<Object>(map->prototype(), isolate);
109 if (!proto->IsJSReceiver()) return false;
110
111 // Check if the property is defined in the prototype chain.
112 LookupIterator it(proto, name);
113 if (!it.IsFound()) return false;
114
115 Object* original_proto =
116 JSFunction::cast(map->GetConstructor())->prototype();
117
118 // Property is not configurable. It is enough to verify that
119 // the holder is the same.
120 return *it.GetHolder<Object>() == original_proto;
121 }
122 case JS_DATA_VIEW_TYPE:
123 return CheckForName(name, isolate->factory()->byte_length_string(),
124 JSDataView::kByteLengthOffset, object_offset) ||
125 CheckForName(name, isolate->factory()->byte_offset_string(),
126 JSDataView::kByteOffsetOffset, object_offset);
127 default:
128 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000130}
131
Ben Murdoch097c5b22016-05-18 11:27:45 +0100132MUST_USE_RESULT static MaybeHandle<Object> ReplaceAccessorWithDataProperty(
133 Isolate* isolate, Handle<JSObject> receiver, Handle<JSObject> holder,
134 Handle<Name> name, Handle<Object> value, bool observe) {
135 LookupIterator it(receiver, name, holder,
136 LookupIterator::OWN_SKIP_INTERCEPTOR);
137 // Skip any access checks we might hit. This accessor should never hit in a
138 // situation where the caller does not have access.
139 if (it.state() == LookupIterator::ACCESS_CHECK) {
140 CHECK(it.HasAccess());
141 it.Next();
142 }
143 CHECK_EQ(LookupIterator::ACCESSOR, it.state());
144
145 Handle<Object> old_value;
146 bool is_observed = observe && receiver->map()->is_observed();
147 if (is_observed) {
148 MaybeHandle<Object> maybe_old = Object::GetPropertyWithAccessor(&it);
149 if (!maybe_old.ToHandle(&old_value)) return maybe_old;
150 }
151
152 it.ReconfigureDataProperty(value, it.property_attributes());
153
154 if (is_observed && !old_value->SameValue(*value)) {
155 return JSObject::EnqueueChangeRecord(receiver, "update", name, old_value);
156 }
157
158 return value;
159}
160
161void Accessors::ReconfigureToDataProperty(
162 v8::Local<v8::Name> key, v8::Local<v8::Value> val,
163 const v8::PropertyCallbackInfo<void>& info) {
164 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
165 HandleScope scope(isolate);
166 Handle<JSObject> receiver =
167 Handle<JSObject>::cast(Utils::OpenHandle(*info.This()));
168 Handle<JSObject> holder =
169 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
170 Handle<Name> name = Utils::OpenHandle(*key);
171 Handle<Object> value = Utils::OpenHandle(*val);
172 MaybeHandle<Object> result = ReplaceAccessorWithDataProperty(
173 isolate, receiver, holder, name, value, false);
174 if (result.is_null()) isolate->OptionalRescheduleException(false);
175}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176
177//
178// Accessors::ArgumentsIterator
179//
180
181
182void Accessors::ArgumentsIteratorGetter(
183 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
184 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
185 DisallowHeapAllocation no_allocation;
186 HandleScope scope(isolate);
187 Object* result = isolate->native_context()->array_values_iterator();
188 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
189}
190
191
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
193 Isolate* isolate, PropertyAttributes attributes) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400194 Handle<Name> name = isolate->factory()->iterator_symbol();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100195 return MakeAccessor(isolate, name, &ArgumentsIteratorGetter, nullptr,
196 attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000197}
198
199
200//
201// Accessors::ArrayLength
202//
203
204
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000205void Accessors::ArrayLengthGetter(
206 v8::Local<v8::Name> name,
207 const v8::PropertyCallbackInfo<v8::Value>& info) {
208 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
209 DisallowHeapAllocation no_allocation;
Steve Block44f0eee2011-05-26 01:26:41 +0100210 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
212 Object* result = holder->length();
213 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000214}
215
216
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000217void Accessors::ArrayLengthSetter(
218 v8::Local<v8::Name> name,
219 v8::Local<v8::Value> val,
220 const v8::PropertyCallbackInfo<void>& info) {
221 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
222 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000223
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 Handle<JSReceiver> object = Utils::OpenHandle(*info.This());
225 Handle<JSArray> array = Handle<JSArray>::cast(object);
226 Handle<Object> length_obj = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000227
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228 uint32_t length = 0;
229 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000230 isolate->OptionalRescheduleException(false);
231 return;
232 }
233
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000234 if (JSArray::ObservableSetLength(array, length).is_null()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000235 isolate->OptionalRescheduleException(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236 }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100237
238 if (info.ShouldThrowOnError()) {
239 uint32_t actual_new_len = 0;
240 CHECK(array->length()->ToArrayLength(&actual_new_len));
241 // Throw TypeError if there were non-deletable elements.
242 if (actual_new_len != length) {
243 Factory* factory = isolate->factory();
244 isolate->Throw(*factory->NewTypeError(
245 MessageTemplate::kStrictDeleteProperty,
246 factory->NewNumberFromUint(actual_new_len - 1), array));
247 isolate->OptionalRescheduleException(false);
248 }
249 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250}
251
252
253Handle<AccessorInfo> Accessors::ArrayLengthInfo(
254 Isolate* isolate, PropertyAttributes attributes) {
255 return MakeAccessor(isolate,
256 isolate->factory()->length_string(),
257 &ArrayLengthGetter,
258 &ArrayLengthSetter,
259 attributes);
260}
261
Steve Blocka7e24c12009-10-30 11:49:00 +0000262
Steve Blocka7e24c12009-10-30 11:49:00 +0000263//
264// Accessors::StringLength
265//
266
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000267void Accessors::StringLengthGetter(
268 v8::Local<v8::Name> name,
269 const v8::PropertyCallbackInfo<v8::Value>& info) {
270 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
271 DisallowHeapAllocation no_allocation;
272 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000273
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000274 // We have a slight impedance mismatch between the external API and the way we
275 // use callbacks internally: Externally, callbacks can only be used with
276 // v8::Object, but internally we have callbacks on entities which are higher
277 // in the hierarchy, in this case for String values.
278
279 Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
280 if (!value->IsString()) {
281 // Not a string value. That means that we either got a String wrapper or
282 // a Value with a String wrapper in its prototype chain.
283 value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
284 }
285 Object* result = Smi::FromInt(String::cast(value)->length());
286 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000287}
288
289
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000290Handle<AccessorInfo> Accessors::StringLengthInfo(
291 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100292 return MakeAccessor(isolate, isolate->factory()->length_string(),
293 &StringLengthGetter, nullptr, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000294}
295
296
Steve Blocka7e24c12009-10-30 11:49:00 +0000297//
298// Accessors::ScriptColumnOffset
299//
300
301
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000302void Accessors::ScriptColumnOffsetGetter(
303 v8::Local<v8::Name> name,
304 const v8::PropertyCallbackInfo<v8::Value>& info) {
305 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
306 DisallowHeapAllocation no_allocation;
307 HandleScope scope(isolate);
308 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000309 Object* res = Smi::FromInt(
310 Script::cast(JSValue::cast(object)->value())->column_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000311 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000312}
313
314
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000315Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
316 Isolate* isolate, PropertyAttributes attributes) {
317 Handle<String> name(isolate->factory()->InternalizeOneByteString(
318 STATIC_CHAR_VECTOR("column_offset")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100319 return MakeAccessor(isolate, name, &ScriptColumnOffsetGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000320 attributes);
321}
322
323
324//
325// Accessors::ScriptId
326//
327
328
329void Accessors::ScriptIdGetter(
330 v8::Local<v8::Name> name,
331 const v8::PropertyCallbackInfo<v8::Value>& info) {
332 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
333 DisallowHeapAllocation no_allocation;
334 HandleScope scope(isolate);
335 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000336 Object* id = Smi::FromInt(Script::cast(JSValue::cast(object)->value())->id());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000337 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate)));
338}
339
340
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341Handle<AccessorInfo> Accessors::ScriptIdInfo(
342 Isolate* isolate, PropertyAttributes attributes) {
343 Handle<String> name(
344 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100345 return MakeAccessor(isolate, name, &ScriptIdGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000346}
347
348
349//
350// Accessors::ScriptName
351//
352
353
354void Accessors::ScriptNameGetter(
355 v8::Local<v8::Name> name,
356 const v8::PropertyCallbackInfo<v8::Value>& info) {
357 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
358 DisallowHeapAllocation no_allocation;
359 HandleScope scope(isolate);
360 Object* object = *Utils::OpenHandle(*info.This());
361 Object* source = Script::cast(JSValue::cast(object)->value())->name();
362 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
363}
364
365
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000366Handle<AccessorInfo> Accessors::ScriptNameInfo(
367 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100368 return MakeAccessor(isolate, isolate->factory()->name_string(),
369 &ScriptNameGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000370}
371
372
373//
374// Accessors::ScriptSource
375//
376
377
378void Accessors::ScriptSourceGetter(
379 v8::Local<v8::Name> name,
380 const v8::PropertyCallbackInfo<v8::Value>& info) {
381 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
382 DisallowHeapAllocation no_allocation;
383 HandleScope scope(isolate);
384 Object* object = *Utils::OpenHandle(*info.This());
385 Object* source = Script::cast(JSValue::cast(object)->value())->source();
386 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
387}
388
389
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000390Handle<AccessorInfo> Accessors::ScriptSourceInfo(
391 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100392 return MakeAccessor(isolate, isolate->factory()->source_string(),
393 &ScriptSourceGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000394}
395
396
397//
398// Accessors::ScriptLineOffset
399//
400
401
402void Accessors::ScriptLineOffsetGetter(
403 v8::Local<v8::Name> name,
404 const v8::PropertyCallbackInfo<v8::Value>& info) {
405 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
406 DisallowHeapAllocation no_allocation;
407 HandleScope scope(isolate);
408 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000409 Object* res =
410 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->line_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000411 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
412}
413
414
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000415Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
416 Isolate* isolate, PropertyAttributes attributes) {
417 Handle<String> name(isolate->factory()->InternalizeOneByteString(
418 STATIC_CHAR_VECTOR("line_offset")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100419 return MakeAccessor(isolate, name, &ScriptLineOffsetGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000420 attributes);
421}
Steve Blocka7e24c12009-10-30 11:49:00 +0000422
423
424//
425// Accessors::ScriptType
426//
427
428
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000429void Accessors::ScriptTypeGetter(
430 v8::Local<v8::Name> name,
431 const v8::PropertyCallbackInfo<v8::Value>& info) {
432 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
433 DisallowHeapAllocation no_allocation;
434 HandleScope scope(isolate);
435 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000436 Object* res =
437 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->type());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000438 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000439}
440
441
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442Handle<AccessorInfo> Accessors::ScriptTypeInfo(
443 Isolate* isolate, PropertyAttributes attributes) {
444 Handle<String> name(
445 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100446 return MakeAccessor(isolate, name, &ScriptTypeGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000447}
Steve Blocka7e24c12009-10-30 11:49:00 +0000448
449
450//
451// Accessors::ScriptCompilationType
452//
453
454
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000455void Accessors::ScriptCompilationTypeGetter(
456 v8::Local<v8::Name> name,
457 const v8::PropertyCallbackInfo<v8::Value>& info) {
458 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
459 DisallowHeapAllocation no_allocation;
460 HandleScope scope(isolate);
461 Object* object = *Utils::OpenHandle(*info.This());
462 Object* res = Smi::FromInt(
463 Script::cast(JSValue::cast(object)->value())->compilation_type());
464 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000465}
466
467
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000468Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
469 Isolate* isolate, PropertyAttributes attributes) {
470 Handle<String> name(isolate->factory()->InternalizeOneByteString(
471 STATIC_CHAR_VECTOR("compilation_type")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100472 return MakeAccessor(isolate, name, &ScriptCompilationTypeGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000473 attributes);
474}
Steve Blocka7e24c12009-10-30 11:49:00 +0000475
476
477//
478// Accessors::ScriptGetLineEnds
479//
480
481
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000482void Accessors::ScriptLineEndsGetter(
483 v8::Local<v8::Name> name,
484 const v8::PropertyCallbackInfo<v8::Value>& info) {
485 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
Steve Block44f0eee2011-05-26 01:26:41 +0100486 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000487 Handle<Object> object = Utils::OpenHandle(*info.This());
488 Handle<Script> script(
489 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
490 Script::InitLineEnds(script);
491 DCHECK(script->line_ends()->IsFixedArray());
Steve Blockd0582a62009-12-15 09:54:21 +0000492 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800493 // We do not want anyone to modify this array from JS.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000494 DCHECK(*line_ends == isolate->heap()->empty_fixed_array() ||
Steve Block44f0eee2011-05-26 01:26:41 +0100495 line_ends->map() == isolate->heap()->fixed_cow_array_map());
496 Handle<JSArray> js_array =
497 isolate->factory()->NewJSArrayWithElements(line_ends);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000498 info.GetReturnValue().Set(Utils::ToLocal(js_array));
Steve Blocka7e24c12009-10-30 11:49:00 +0000499}
500
501
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000502Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
503 Isolate* isolate, PropertyAttributes attributes) {
504 Handle<String> name(isolate->factory()->InternalizeOneByteString(
505 STATIC_CHAR_VECTOR("line_ends")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100506 return MakeAccessor(isolate, name, &ScriptLineEndsGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000507 attributes);
508}
509
510
511//
512// Accessors::ScriptSourceUrl
513//
514
515
516void Accessors::ScriptSourceUrlGetter(
517 v8::Local<v8::Name> name,
518 const v8::PropertyCallbackInfo<v8::Value>& info) {
519 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
520 DisallowHeapAllocation no_allocation;
521 HandleScope scope(isolate);
522 Object* object = *Utils::OpenHandle(*info.This());
523 Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
524 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
525}
526
527
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000528Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
529 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100530 return MakeAccessor(isolate, isolate->factory()->source_url_string(),
531 &ScriptSourceUrlGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000532}
533
534
535//
536// Accessors::ScriptSourceMappingUrl
537//
538
539
540void Accessors::ScriptSourceMappingUrlGetter(
541 v8::Local<v8::Name> name,
542 const v8::PropertyCallbackInfo<v8::Value>& info) {
543 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
544 DisallowHeapAllocation no_allocation;
545 HandleScope scope(isolate);
546 Object* object = *Utils::OpenHandle(*info.This());
547 Object* url =
548 Script::cast(JSValue::cast(object)->value())->source_mapping_url();
549 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
550}
551
552
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000553Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
554 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100555 return MakeAccessor(isolate, isolate->factory()->source_mapping_url_string(),
556 &ScriptSourceMappingUrlGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000557}
Steve Blocka7e24c12009-10-30 11:49:00 +0000558
559
560//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000561// Accessors::ScriptIsEmbedderDebugScript
562//
563
564
565void Accessors::ScriptIsEmbedderDebugScriptGetter(
566 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
567 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
568 DisallowHeapAllocation no_allocation;
569 HandleScope scope(isolate);
570 Object* object = *Utils::OpenHandle(*info.This());
571 bool is_embedder_debug_script = Script::cast(JSValue::cast(object)->value())
572 ->origin_options()
573 .IsEmbedderDebugScript();
574 Object* res = *isolate->factory()->ToBoolean(is_embedder_debug_script);
575 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
576}
577
578
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000579Handle<AccessorInfo> Accessors::ScriptIsEmbedderDebugScriptInfo(
580 Isolate* isolate, PropertyAttributes attributes) {
581 Handle<String> name(isolate->factory()->InternalizeOneByteString(
582 STATIC_CHAR_VECTOR("is_debugger_script")));
583 return MakeAccessor(isolate, name, &ScriptIsEmbedderDebugScriptGetter,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100584 nullptr, attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000585}
586
587
588//
Steve Blocka7e24c12009-10-30 11:49:00 +0000589// Accessors::ScriptGetContextData
590//
591
592
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000593void Accessors::ScriptContextDataGetter(
594 v8::Local<v8::Name> name,
595 const v8::PropertyCallbackInfo<v8::Value>& info) {
596 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
597 DisallowHeapAllocation no_allocation;
598 HandleScope scope(isolate);
599 Object* object = *Utils::OpenHandle(*info.This());
600 Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
601 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000602}
603
604
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000605Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
606 Isolate* isolate, PropertyAttributes attributes) {
607 Handle<String> name(isolate->factory()->InternalizeOneByteString(
608 STATIC_CHAR_VECTOR("context_data")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100609 return MakeAccessor(isolate, name, &ScriptContextDataGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000610 attributes);
611}
Steve Blocka7e24c12009-10-30 11:49:00 +0000612
613
614//
Steve Blockd0582a62009-12-15 09:54:21 +0000615// Accessors::ScriptGetEvalFromScript
Steve Blocka7e24c12009-10-30 11:49:00 +0000616//
617
618
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000619void Accessors::ScriptEvalFromScriptGetter(
620 v8::Local<v8::Name> name,
621 const v8::PropertyCallbackInfo<v8::Value>& info) {
622 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
623 HandleScope scope(isolate);
624 Handle<Object> object = Utils::OpenHandle(*info.This());
625 Handle<Script> script(
626 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
627 Handle<Object> result = isolate->factory()->undefined_value();
628 if (!script->eval_from_shared()->IsUndefined()) {
Steve Blockd0582a62009-12-15 09:54:21 +0000629 Handle<SharedFunctionInfo> eval_from_shared(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000630 SharedFunctionInfo::cast(script->eval_from_shared()));
Steve Blockd0582a62009-12-15 09:54:21 +0000631 if (eval_from_shared->script()->IsScript()) {
632 Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000633 result = Script::GetWrapper(eval_from_script);
Steve Blockd0582a62009-12-15 09:54:21 +0000634 }
635 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000636
637 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000638}
639
640
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000641Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
642 Isolate* isolate, PropertyAttributes attributes) {
643 Handle<String> name(isolate->factory()->InternalizeOneByteString(
644 STATIC_CHAR_VECTOR("eval_from_script")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100645 return MakeAccessor(isolate, name, &ScriptEvalFromScriptGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000646 attributes);
647}
Steve Blocka7e24c12009-10-30 11:49:00 +0000648
649
650//
Steve Blockd0582a62009-12-15 09:54:21 +0000651// Accessors::ScriptGetEvalFromScriptPosition
Steve Blocka7e24c12009-10-30 11:49:00 +0000652//
653
654
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000655void Accessors::ScriptEvalFromScriptPositionGetter(
656 v8::Local<v8::Name> name,
657 const v8::PropertyCallbackInfo<v8::Value>& info) {
658 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
659 HandleScope scope(isolate);
660 Handle<Object> object = Utils::OpenHandle(*info.This());
661 Handle<Script> script(
662 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
663 Handle<Object> result = isolate->factory()->undefined_value();
664 if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
665 Handle<Code> code(SharedFunctionInfo::cast(
666 script->eval_from_shared())->code());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000667 result = Handle<Object>(Smi::FromInt(code->SourcePosition(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000668 script->eval_from_instructions_offset())),
669 isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000670 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000671 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000672}
673
674
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000675Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
676 Isolate* isolate, PropertyAttributes attributes) {
677 Handle<String> name(isolate->factory()->InternalizeOneByteString(
678 STATIC_CHAR_VECTOR("eval_from_script_position")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100679 return MakeAccessor(isolate, name, &ScriptEvalFromScriptPositionGetter,
680 nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000681}
Steve Blockd0582a62009-12-15 09:54:21 +0000682
683
684//
685// Accessors::ScriptGetEvalFromFunctionName
686//
687
688
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000689void Accessors::ScriptEvalFromFunctionNameGetter(
690 v8::Local<v8::Name> name,
691 const v8::PropertyCallbackInfo<v8::Value>& info) {
692 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
693 HandleScope scope(isolate);
694 Handle<Object> object = Utils::OpenHandle(*info.This());
695 Handle<Script> script(
696 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
697 Handle<Object> result;
698 Handle<SharedFunctionInfo> shared(
699 SharedFunctionInfo::cast(script->eval_from_shared()));
Steve Blockd0582a62009-12-15 09:54:21 +0000700 // Find the name of the function calling eval.
701 if (!shared->name()->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000702 result = Handle<Object>(shared->name(), isolate);
Steve Blockd0582a62009-12-15 09:54:21 +0000703 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000704 result = Handle<Object>(shared->inferred_name(), isolate);
Steve Blockd0582a62009-12-15 09:54:21 +0000705 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000706 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blockd0582a62009-12-15 09:54:21 +0000707}
708
709
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000710Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
711 Isolate* isolate, PropertyAttributes attributes) {
712 Handle<String> name(isolate->factory()->InternalizeOneByteString(
713 STATIC_CHAR_VECTOR("eval_from_function_name")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100714 return MakeAccessor(isolate, name, &ScriptEvalFromFunctionNameGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000715 attributes);
716}
Steve Blocka7e24c12009-10-30 11:49:00 +0000717
718
719//
720// Accessors::FunctionPrototype
721//
722
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000723static Handle<Object> GetFunctionPrototype(Isolate* isolate,
724 Handle<JSFunction> function) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000725 if (!function->has_prototype()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000726 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
727 JSFunction::SetPrototype(function, proto);
Steve Blocka7e24c12009-10-30 11:49:00 +0000728 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000729 return Handle<Object>(function->prototype(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000730}
731
732
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400733MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype(
734 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735 Handle<Object> old_value;
736 bool is_observed = function->map()->is_observed();
737 if (is_observed) {
738 if (function->has_prototype())
739 old_value = handle(function->prototype(), isolate);
740 else
741 old_value = isolate->factory()->NewFunctionPrototype(function);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100742 }
743
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000744 JSFunction::SetPrototype(function, value);
745 DCHECK(function->prototype() == *value);
746
747 if (is_observed && !old_value->SameValue(*value)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400748 MaybeHandle<Object> result = JSObject::EnqueueChangeRecord(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000749 function, "update", isolate->factory()->prototype_string(), old_value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400750 if (result.is_null()) return MaybeHandle<Object>();
John Reck59135872010-11-02 12:39:01 -0700751 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000752
Steve Blocka7e24c12009-10-30 11:49:00 +0000753 return function;
754}
755
756
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400757MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
758 Handle<Object> prototype) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000759 DCHECK(function->IsConstructor());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000760 Isolate* isolate = function->GetIsolate();
761 return SetFunctionPrototype(isolate, function, prototype);
762}
763
764
765void Accessors::FunctionPrototypeGetter(
766 v8::Local<v8::Name> name,
767 const v8::PropertyCallbackInfo<v8::Value>& info) {
768 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
769 HandleScope scope(isolate);
770 Handle<JSFunction> function =
771 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
772 Handle<Object> result = GetFunctionPrototype(isolate, function);
773 info.GetReturnValue().Set(Utils::ToLocal(result));
774}
775
776
777void Accessors::FunctionPrototypeSetter(
778 v8::Local<v8::Name> name,
779 v8::Local<v8::Value> val,
780 const v8::PropertyCallbackInfo<void>& info) {
781 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
782 HandleScope scope(isolate);
783 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000784 Handle<JSFunction> object =
785 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400786 if (SetFunctionPrototype(isolate, object, value).is_null()) {
787 isolate->OptionalRescheduleException(false);
788 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000789}
790
791
792Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
793 Isolate* isolate, PropertyAttributes attributes) {
794 return MakeAccessor(isolate,
795 isolate->factory()->prototype_string(),
796 &FunctionPrototypeGetter,
797 &FunctionPrototypeSetter,
798 attributes);
799}
Steve Blocka7e24c12009-10-30 11:49:00 +0000800
801
802//
803// Accessors::FunctionLength
804//
805
806
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000807void Accessors::FunctionLengthGetter(
808 v8::Local<v8::Name> name,
809 const v8::PropertyCallbackInfo<v8::Value>& info) {
810 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
811 HandleScope scope(isolate);
812 Handle<JSFunction> function =
813 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
814
815 int length = 0;
816 if (function->shared()->is_compiled()) {
817 length = function->shared()->length();
818 } else {
Steve Blocka7e24c12009-10-30 11:49:00 +0000819 // If the function isn't compiled yet, the length is not computed
820 // correctly yet. Compile it now and return the right length.
Ben Murdochda12d292016-06-02 14:46:10 +0100821 if (Compiler::Compile(function, Compiler::KEEP_EXCEPTION)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000822 length = function->shared()->length();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100823 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000824 if (isolate->has_pending_exception()) {
825 isolate->OptionalRescheduleException(false);
826 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000827 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000828 Handle<Object> result(Smi::FromInt(length), isolate);
829 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000830}
831
Ben Murdoch097c5b22016-05-18 11:27:45 +0100832void Accessors::ObservedReconfigureToDataProperty(
833 v8::Local<v8::Name> key, v8::Local<v8::Value> val,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000834 const v8::PropertyCallbackInfo<void>& info) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000835 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
836 HandleScope scope(isolate);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100837 Handle<JSObject> receiver =
838 Handle<JSObject>::cast(Utils::OpenHandle(*info.This()));
839 Handle<JSObject> holder =
840 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
841 Handle<Name> name = Utils::OpenHandle(*key);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000842 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100843 MaybeHandle<Object> result = ReplaceAccessorWithDataProperty(
844 isolate, receiver, holder, name, value, true);
845 if (result.is_null()) isolate->OptionalRescheduleException(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000846}
847
848
849Handle<AccessorInfo> Accessors::FunctionLengthInfo(
850 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100851 return MakeAccessor(isolate, isolate->factory()->length_string(),
852 &FunctionLengthGetter, &ObservedReconfigureToDataProperty,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000853 attributes);
854}
Steve Blocka7e24c12009-10-30 11:49:00 +0000855
856
857//
858// Accessors::FunctionName
859//
860
861
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000862void Accessors::FunctionNameGetter(
863 v8::Local<v8::Name> name,
864 const v8::PropertyCallbackInfo<v8::Value>& info) {
865 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
866 HandleScope scope(isolate);
867 Handle<JSFunction> function =
868 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000869 Handle<Object> result;
870 if (function->shared()->name_should_print_as_anonymous()) {
871 result = isolate->factory()->anonymous_string();
872 } else {
873 result = handle(function->shared()->name(), isolate);
874 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000875 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000876}
877
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000878Handle<AccessorInfo> Accessors::FunctionNameInfo(
879 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100880 return MakeAccessor(isolate, isolate->factory()->name_string(),
881 &FunctionNameGetter, &ObservedReconfigureToDataProperty,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000882 attributes);
883}
Steve Blocka7e24c12009-10-30 11:49:00 +0000884
885
886//
887// Accessors::FunctionArguments
888//
889
Ben Murdochb0fe1622011-05-05 13:52:32 +0100890
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000891static Handle<Object> ArgumentsForInlinedFunction(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100892 JavaScriptFrame* frame,
893 Handle<JSFunction> inlined_function,
894 int inlined_frame_index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000895 Isolate* isolate = inlined_function->GetIsolate();
896 Factory* factory = isolate->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000897
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898 TranslatedState translated_values(frame);
899 translated_values.Prepare(false, frame->fp());
900
901 int argument_count = 0;
902 TranslatedFrame* translated_frame =
903 translated_values.GetArgumentsInfoFromJSFrameIndex(inlined_frame_index,
904 &argument_count);
905 TranslatedFrame::iterator iter = translated_frame->begin();
906
907 // Skip the function.
908 iter++;
909
910 // Skip the receiver.
911 iter++;
912 argument_count--;
913
Ben Murdochb0fe1622011-05-05 13:52:32 +0100914 Handle<JSObject> arguments =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000915 factory->NewArgumentsObject(inlined_function, argument_count);
916 Handle<FixedArray> array = factory->NewFixedArray(argument_count);
917 bool should_deoptimize = false;
918 for (int i = 0; i < argument_count; ++i) {
919 // If we materialize any object, we should deopt because we might alias
920 // an object that was eliminated by escape analysis.
921 should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
922 Handle<Object> value = iter->GetValue();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100923 array->set(i, *value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924 iter++;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100925 }
926 arguments->set_elements(*array);
927
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000928 if (should_deoptimize) {
929 translated_values.StoreMaterializedValuesAndDeopt();
930 }
931
Ben Murdochb0fe1622011-05-05 13:52:32 +0100932 // Return the freshly allocated arguments object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000933 return arguments;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100934}
935
Steve Blocka7e24c12009-10-30 11:49:00 +0000936
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000937static int FindFunctionInFrame(JavaScriptFrame* frame,
938 Handle<JSFunction> function) {
939 DisallowHeapAllocation no_allocation;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100940 List<JSFunction*> functions(2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000941 frame->GetFunctions(&functions);
942 for (int i = functions.length() - 1; i >= 0; i--) {
943 if (functions[i] == *function) return i;
944 }
945 return -1;
946}
947
948
Ben Murdoch097c5b22016-05-18 11:27:45 +0100949namespace {
950
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000951Handle<Object> GetFunctionArguments(Isolate* isolate,
952 Handle<JSFunction> function) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000953 // Find the top invocation of the function by traversing frames.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100954 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000955 JavaScriptFrame* frame = it.frame();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000956 int function_index = FindFunctionInFrame(frame, function);
957 if (function_index < 0) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +0000958
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000959 if (function_index > 0) {
960 // The function in question was inlined. Inlined functions have the
961 // correct number of arguments and no allocated arguments object, so
962 // we can construct a fresh one by interpreting the function's
963 // deoptimization input data.
964 return ArgumentsForInlinedFunction(frame, function, function_index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000965 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000966
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000967 // Find the frame that holds the actual arguments passed to the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000968 it.AdvanceToArgumentsFrame();
969 frame = it.frame();
970
971 // Get the number of arguments and construct an arguments object
972 // mirror for the right frame.
973 const int length = frame->ComputeParametersCount();
974 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
975 function, length);
976 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
977
978 // Copy the parameters to the arguments object.
979 DCHECK(array->length() == length);
980 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
981 arguments->set_elements(*array);
982
983 // Return the freshly allocated arguments object.
984 return arguments;
Steve Blocka7e24c12009-10-30 11:49:00 +0000985 }
986
987 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000988 return isolate->factory()->null_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000989}
990
Ben Murdoch097c5b22016-05-18 11:27:45 +0100991} // namespace
Steve Blocka7e24c12009-10-30 11:49:00 +0000992
Ben Murdoch097c5b22016-05-18 11:27:45 +0100993
994Handle<JSObject> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
995 Handle<Object> arguments =
996 GetFunctionArguments(function->GetIsolate(), function);
997 CHECK(arguments->IsJSObject());
998 return Handle<JSObject>::cast(arguments);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000999}
1000
1001
1002void Accessors::FunctionArgumentsGetter(
1003 v8::Local<v8::Name> name,
1004 const v8::PropertyCallbackInfo<v8::Value>& info) {
1005 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1006 HandleScope scope(isolate);
1007 Handle<JSFunction> function =
1008 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdoch097c5b22016-05-18 11:27:45 +01001009 Handle<Object> result =
1010 function->shared()->native()
1011 ? Handle<Object>::cast(isolate->factory()->null_value())
1012 : GetFunctionArguments(isolate, function);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001013 info.GetReturnValue().Set(Utils::ToLocal(result));
1014}
1015
1016
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001017Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
1018 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001019 return MakeAccessor(isolate, isolate->factory()->arguments_string(),
1020 &FunctionArgumentsGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001021}
Steve Blocka7e24c12009-10-30 11:49:00 +00001022
1023
1024//
1025// Accessors::FunctionCaller
1026//
1027
1028
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001029static inline bool AllowAccessToFunction(Context* current_context,
1030 JSFunction* function) {
1031 return current_context->HasSameSecurityTokenAs(function->context());
Steve Block44f0eee2011-05-26 01:26:41 +01001032}
1033
1034
Ben Murdoch257744e2011-11-30 15:57:28 +00001035class FrameFunctionIterator {
1036 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001037 FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
1038 : isolate_(isolate),
1039 frame_iterator_(isolate),
Ben Murdoch257744e2011-11-30 15:57:28 +00001040 functions_(2),
1041 index_(0) {
1042 GetFunctions();
1043 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001044 JSFunction* next() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001045 while (true) {
1046 if (functions_.length() == 0) return NULL;
1047 JSFunction* next_function = functions_[index_];
1048 index_--;
1049 if (index_ < 0) {
1050 GetFunctions();
1051 }
1052 // Skip functions from other origins.
1053 if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
1054 return next_function;
Ben Murdoch257744e2011-11-30 15:57:28 +00001055 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001056 }
1057
1058 // Iterate through functions until the first occurence of 'function'.
1059 // Returns true if 'function' is found, and false if the iterator ends
1060 // without finding it.
1061 bool Find(JSFunction* function) {
1062 JSFunction* next_function;
1063 do {
1064 next_function = next();
1065 if (next_function == function) return true;
1066 } while (next_function != NULL);
1067 return false;
1068 }
Ben Murdoch589d6972011-11-30 16:04:58 +00001069
Ben Murdoch257744e2011-11-30 15:57:28 +00001070 private:
1071 void GetFunctions() {
1072 functions_.Rewind(0);
1073 if (frame_iterator_.done()) return;
1074 JavaScriptFrame* frame = frame_iterator_.frame();
1075 frame->GetFunctions(&functions_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001076 DCHECK(functions_.length() > 0);
Ben Murdoch257744e2011-11-30 15:57:28 +00001077 frame_iterator_.Advance();
1078 index_ = functions_.length() - 1;
1079 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001080 Isolate* isolate_;
Ben Murdoch257744e2011-11-30 15:57:28 +00001081 JavaScriptFrameIterator frame_iterator_;
1082 List<JSFunction*> functions_;
1083 int index_;
1084};
1085
1086
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001087MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
1088 Handle<JSFunction> function) {
1089 DisallowHeapAllocation no_allocation;
1090 FrameFunctionIterator it(isolate, no_allocation);
1091 if (function->shared()->native()) {
1092 return MaybeHandle<JSFunction>();
1093 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001094 // Find the function from the frames.
1095 if (!it.Find(*function)) {
1096 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001097 return MaybeHandle<JSFunction>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001098 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001099 // Find previously called non-toplevel function.
1100 JSFunction* caller;
1101 do {
1102 caller = it.next();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001103 if (caller == NULL) return MaybeHandle<JSFunction>();
Ben Murdoch257744e2011-11-30 15:57:28 +00001104 } while (caller->shared()->is_toplevel());
1105
1106 // If caller is a built-in function and caller's caller is also built-in,
1107 // use that instead.
1108 JSFunction* potential_caller = caller;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001109 while (potential_caller != NULL && potential_caller->shared()->IsBuiltin()) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001110 caller = potential_caller;
1111 potential_caller = it.next();
1112 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001113 if (!caller->shared()->native() && potential_caller != NULL) {
1114 caller = potential_caller;
1115 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001116 // Censor if the caller is not a sloppy mode function.
1117 // Change from ES5, which used to throw, see:
1118 // https://bugs.ecmascript.org/show_bug.cgi?id=310
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001119 if (is_strict(caller->shared()->language_mode())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001120 return MaybeHandle<JSFunction>();
1121 }
1122 // Don't return caller from another security context.
1123 if (!AllowAccessToFunction(isolate->context(), caller)) {
1124 return MaybeHandle<JSFunction>();
1125 }
1126 return Handle<JSFunction>(caller);
Steve Blocka7e24c12009-10-30 11:49:00 +00001127}
1128
1129
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001130void Accessors::FunctionCallerGetter(
1131 v8::Local<v8::Name> name,
1132 const v8::PropertyCallbackInfo<v8::Value>& info) {
1133 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1134 HandleScope scope(isolate);
1135 Handle<JSFunction> function =
1136 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1137 Handle<Object> result;
1138 MaybeHandle<JSFunction> maybe_caller;
1139 maybe_caller = FindCaller(isolate, function);
1140 Handle<JSFunction> caller;
1141 if (maybe_caller.ToHandle(&caller)) {
1142 result = caller;
1143 } else {
1144 result = isolate->factory()->null_value();
1145 }
1146 info.GetReturnValue().Set(Utils::ToLocal(result));
1147}
1148
1149
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001150Handle<AccessorInfo> Accessors::FunctionCallerInfo(
1151 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001152 return MakeAccessor(isolate, isolate->factory()->caller_string(),
1153 &FunctionCallerGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001154}
Steve Blocka7e24c12009-10-30 11:49:00 +00001155
1156
1157//
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001158// Accessors::MakeModuleExport
Steve Blocka7e24c12009-10-30 11:49:00 +00001159//
1160
Ben Murdoch097c5b22016-05-18 11:27:45 +01001161static void ModuleGetExport(v8::Local<v8::Name> property,
1162 const v8::PropertyCallbackInfo<v8::Value>& info) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001163 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
1164 Context* context = Context::cast(instance->context());
1165 DCHECK(context->IsModuleContext());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001166 Isolate* isolate = instance->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001167 int slot = info.Data()
1168 ->Int32Value(info.GetIsolate()->GetCurrentContext())
1169 .FromMaybe(-1);
1170 if (slot < 0 || slot >= context->length()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001171 Handle<Name> name = v8::Utils::OpenHandle(*property);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001172
1173 Handle<Object> exception = isolate->factory()->NewReferenceError(
1174 MessageTemplate::kNotDefined, name);
1175 isolate->ScheduleThrow(*exception);
1176 return;
1177 }
1178 Object* value = context->get(slot);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001179 if (value->IsTheHole()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001180 Handle<Name> name = v8::Utils::OpenHandle(*property);
Steve Blocka7e24c12009-10-30 11:49:00 +00001181
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001182 Handle<Object> exception = isolate->factory()->NewReferenceError(
1183 MessageTemplate::kNotDefined, name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001184 isolate->ScheduleThrow(*exception);
1185 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001186 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001187 info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001188}
1189
1190
Ben Murdoch097c5b22016-05-18 11:27:45 +01001191static void ModuleSetExport(v8::Local<v8::Name> property,
1192 v8::Local<v8::Value> value,
1193 const v8::PropertyCallbackInfo<void>& info) {
1194 if (!info.ShouldThrowOnError()) return;
1195 Handle<Name> name = v8::Utils::OpenHandle(*property);
1196 Isolate* isolate = name->GetIsolate();
1197 Handle<Object> exception =
1198 isolate->factory()->NewTypeError(MessageTemplate::kNotDefined, name);
1199 isolate->ScheduleThrow(*exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00001200}
1201
1202
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001203Handle<AccessorInfo> Accessors::MakeModuleExport(
1204 Handle<String> name,
1205 int index,
1206 PropertyAttributes attributes) {
1207 Isolate* isolate = name->GetIsolate();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001208 Handle<AccessorInfo> info = MakeAccessor(isolate, name, &ModuleGetExport,
1209 &ModuleSetExport, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001210 info->set_data(Smi::FromInt(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001211 return info;
1212}
1213
Steve Blocka7e24c12009-10-30 11:49:00 +00001214
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001215} // namespace internal
1216} // namespace v8