blob: 8b8753b113ee6233e442f6495451e75b07d5f0d1 [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);
Ben Murdochc5610432016-08-08 18:44:38 +010043 Address redirected = info->redirected_getter();
44 if (redirected != nullptr) {
45 Handle<Object> js_get = v8::FromCData(isolate, redirected);
46 info->set_js_getter(*js_get);
47 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048 return info;
Steve Blocka7e24c12009-10-30 11:49:00 +000049}
50
51
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052static V8_INLINE bool CheckForName(Handle<Name> name,
53 Handle<String> property_name,
54 int offset,
55 int* object_offset) {
56 if (Name::Equals(name, property_name)) {
57 *object_offset = offset;
58 return true;
59 }
60 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +000061}
62
63
Ben Murdochb8a8cc12014-11-26 15:28:44 +000064// Returns true for properties that are accessors to object fields.
65// If true, *object_offset contains offset of object field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000066bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000067 int* object_offset) {
68 Isolate* isolate = name->GetIsolate();
69
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070 switch (map->instance_type()) {
71 case JS_ARRAY_TYPE:
72 return
73 CheckForName(name, isolate->factory()->length_string(),
74 JSArray::kLengthOffset, object_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000075 case JS_ARRAY_BUFFER_TYPE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076 return CheckForName(name, isolate->factory()->byte_length_string(),
77 JSArrayBuffer::kByteLengthOffset, object_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000078 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 if (map->instance_type() < FIRST_NONSTRING_TYPE) {
80 return CheckForName(name, isolate->factory()->length_string(),
81 String::kLengthOffset, object_offset);
82 }
83
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084 return false;
85 }
86}
87
88
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000089bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map,
90 Handle<Name> name,
91 int* object_offset) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010092 DCHECK(name->IsUniqueName());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000093 Isolate* isolate = name->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000095 switch (map->instance_type()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000096 case JS_DATA_VIEW_TYPE:
97 return CheckForName(name, isolate->factory()->byte_length_string(),
98 JSDataView::kByteLengthOffset, object_offset) ||
99 CheckForName(name, isolate->factory()->byte_offset_string(),
100 JSDataView::kByteOffsetOffset, object_offset);
101 default:
102 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000103 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000104}
105
Ben Murdochc5610432016-08-08 18:44:38 +0100106namespace {
107
108MUST_USE_RESULT MaybeHandle<Object> ReplaceAccessorWithDataProperty(
109 Isolate* isolate, Handle<Object> receiver, Handle<JSObject> holder,
110 Handle<Name> name, Handle<Object> value) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100111 LookupIterator it(receiver, name, holder,
112 LookupIterator::OWN_SKIP_INTERCEPTOR);
113 // Skip any access checks we might hit. This accessor should never hit in a
114 // situation where the caller does not have access.
115 if (it.state() == LookupIterator::ACCESS_CHECK) {
116 CHECK(it.HasAccess());
117 it.Next();
118 }
Ben Murdochc5610432016-08-08 18:44:38 +0100119 DCHECK(holder.is_identical_to(it.GetHolder<JSObject>()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100120 CHECK_EQ(LookupIterator::ACCESSOR, it.state());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100121 it.ReconfigureDataProperty(value, it.property_attributes());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100122 return value;
123}
124
Ben Murdochc5610432016-08-08 18:44:38 +0100125} // namespace
126
Ben Murdoch097c5b22016-05-18 11:27:45 +0100127void Accessors::ReconfigureToDataProperty(
128 v8::Local<v8::Name> key, v8::Local<v8::Value> val,
129 const v8::PropertyCallbackInfo<void>& info) {
130 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
131 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100132 Handle<Object> receiver = Utils::OpenHandle(*info.This());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100133 Handle<JSObject> holder =
134 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
135 Handle<Name> name = Utils::OpenHandle(*key);
136 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdochc5610432016-08-08 18:44:38 +0100137 MaybeHandle<Object> result =
138 ReplaceAccessorWithDataProperty(isolate, receiver, holder, name, value);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100139 if (result.is_null()) isolate->OptionalRescheduleException(false);
140}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141
142//
143// Accessors::ArgumentsIterator
144//
145
146
147void Accessors::ArgumentsIteratorGetter(
148 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
149 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
150 DisallowHeapAllocation no_allocation;
151 HandleScope scope(isolate);
152 Object* result = isolate->native_context()->array_values_iterator();
153 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
154}
155
156
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
158 Isolate* isolate, PropertyAttributes attributes) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400159 Handle<Name> name = isolate->factory()->iterator_symbol();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100160 return MakeAccessor(isolate, name, &ArgumentsIteratorGetter, nullptr,
161 attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000162}
163
164
165//
166// Accessors::ArrayLength
167//
168
169
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000170void Accessors::ArrayLengthGetter(
171 v8::Local<v8::Name> name,
172 const v8::PropertyCallbackInfo<v8::Value>& info) {
173 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
174 DisallowHeapAllocation no_allocation;
Steve Block44f0eee2011-05-26 01:26:41 +0100175 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000176 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
177 Object* result = holder->length();
178 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000179}
180
181
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000182void Accessors::ArrayLengthSetter(
183 v8::Local<v8::Name> name,
184 v8::Local<v8::Value> val,
185 const v8::PropertyCallbackInfo<void>& info) {
186 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
187 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000188
Ben Murdochc5610432016-08-08 18:44:38 +0100189 Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000190 Handle<JSArray> array = Handle<JSArray>::cast(object);
191 Handle<Object> length_obj = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000192
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000193 uint32_t length = 0;
194 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000195 isolate->OptionalRescheduleException(false);
196 return;
197 }
198
Ben Murdochc5610432016-08-08 18:44:38 +0100199 JSArray::SetLength(array, length);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100200
201 if (info.ShouldThrowOnError()) {
202 uint32_t actual_new_len = 0;
203 CHECK(array->length()->ToArrayLength(&actual_new_len));
204 // Throw TypeError if there were non-deletable elements.
205 if (actual_new_len != length) {
206 Factory* factory = isolate->factory();
207 isolate->Throw(*factory->NewTypeError(
208 MessageTemplate::kStrictDeleteProperty,
209 factory->NewNumberFromUint(actual_new_len - 1), array));
210 isolate->OptionalRescheduleException(false);
211 }
212 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213}
214
215
216Handle<AccessorInfo> Accessors::ArrayLengthInfo(
217 Isolate* isolate, PropertyAttributes attributes) {
218 return MakeAccessor(isolate,
219 isolate->factory()->length_string(),
220 &ArrayLengthGetter,
221 &ArrayLengthSetter,
222 attributes);
223}
224
Steve Blocka7e24c12009-10-30 11:49:00 +0000225
Steve Blocka7e24c12009-10-30 11:49:00 +0000226//
227// Accessors::StringLength
228//
229
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000230void Accessors::StringLengthGetter(
231 v8::Local<v8::Name> name,
232 const v8::PropertyCallbackInfo<v8::Value>& info) {
233 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
234 DisallowHeapAllocation no_allocation;
235 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000236
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000237 // We have a slight impedance mismatch between the external API and the way we
238 // use callbacks internally: Externally, callbacks can only be used with
239 // v8::Object, but internally we have callbacks on entities which are higher
240 // in the hierarchy, in this case for String values.
241
242 Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
243 if (!value->IsString()) {
244 // Not a string value. That means that we either got a String wrapper or
245 // a Value with a String wrapper in its prototype chain.
246 value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
247 }
248 Object* result = Smi::FromInt(String::cast(value)->length());
249 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000250}
251
252
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000253Handle<AccessorInfo> Accessors::StringLengthInfo(
254 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100255 return MakeAccessor(isolate, isolate->factory()->length_string(),
256 &StringLengthGetter, nullptr, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000257}
258
259
Steve Blocka7e24c12009-10-30 11:49:00 +0000260//
261// Accessors::ScriptColumnOffset
262//
263
264
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000265void Accessors::ScriptColumnOffsetGetter(
266 v8::Local<v8::Name> name,
267 const v8::PropertyCallbackInfo<v8::Value>& info) {
268 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
269 DisallowHeapAllocation no_allocation;
270 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100271 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000272 Object* res = Smi::FromInt(
273 Script::cast(JSValue::cast(object)->value())->column_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000274 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000275}
276
277
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000278Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
279 Isolate* isolate, PropertyAttributes attributes) {
280 Handle<String> name(isolate->factory()->InternalizeOneByteString(
281 STATIC_CHAR_VECTOR("column_offset")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100282 return MakeAccessor(isolate, name, &ScriptColumnOffsetGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000283 attributes);
284}
285
286
287//
288// Accessors::ScriptId
289//
290
291
292void Accessors::ScriptIdGetter(
293 v8::Local<v8::Name> name,
294 const v8::PropertyCallbackInfo<v8::Value>& info) {
295 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
296 DisallowHeapAllocation no_allocation;
297 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100298 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000299 Object* id = Smi::FromInt(Script::cast(JSValue::cast(object)->value())->id());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000300 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate)));
301}
302
303
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000304Handle<AccessorInfo> Accessors::ScriptIdInfo(
305 Isolate* isolate, PropertyAttributes attributes) {
306 Handle<String> name(
307 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100308 return MakeAccessor(isolate, name, &ScriptIdGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000309}
310
311
312//
313// Accessors::ScriptName
314//
315
316
317void Accessors::ScriptNameGetter(
318 v8::Local<v8::Name> name,
319 const v8::PropertyCallbackInfo<v8::Value>& info) {
320 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
321 DisallowHeapAllocation no_allocation;
322 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100323 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000324 Object* source = Script::cast(JSValue::cast(object)->value())->name();
325 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
326}
327
328
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000329Handle<AccessorInfo> Accessors::ScriptNameInfo(
330 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100331 return MakeAccessor(isolate, isolate->factory()->name_string(),
332 &ScriptNameGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000333}
334
335
336//
337// Accessors::ScriptSource
338//
339
340
341void Accessors::ScriptSourceGetter(
342 v8::Local<v8::Name> name,
343 const v8::PropertyCallbackInfo<v8::Value>& info) {
344 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
345 DisallowHeapAllocation no_allocation;
346 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100347 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000348 Object* source = Script::cast(JSValue::cast(object)->value())->source();
349 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
350}
351
352
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000353Handle<AccessorInfo> Accessors::ScriptSourceInfo(
354 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100355 return MakeAccessor(isolate, isolate->factory()->source_string(),
356 &ScriptSourceGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000357}
358
359
360//
361// Accessors::ScriptLineOffset
362//
363
364
365void Accessors::ScriptLineOffsetGetter(
366 v8::Local<v8::Name> name,
367 const v8::PropertyCallbackInfo<v8::Value>& info) {
368 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
369 DisallowHeapAllocation no_allocation;
370 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100371 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000372 Object* res =
373 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->line_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000374 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
375}
376
377
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000378Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
379 Isolate* isolate, PropertyAttributes attributes) {
380 Handle<String> name(isolate->factory()->InternalizeOneByteString(
381 STATIC_CHAR_VECTOR("line_offset")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100382 return MakeAccessor(isolate, name, &ScriptLineOffsetGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000383 attributes);
384}
Steve Blocka7e24c12009-10-30 11:49:00 +0000385
386
387//
388// Accessors::ScriptType
389//
390
391
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000392void Accessors::ScriptTypeGetter(
393 v8::Local<v8::Name> name,
394 const v8::PropertyCallbackInfo<v8::Value>& info) {
395 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
396 DisallowHeapAllocation no_allocation;
397 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100398 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000399 Object* res =
400 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->type());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000401 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000402}
403
404
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000405Handle<AccessorInfo> Accessors::ScriptTypeInfo(
406 Isolate* isolate, PropertyAttributes attributes) {
407 Handle<String> name(
408 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100409 return MakeAccessor(isolate, name, &ScriptTypeGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000410}
Steve Blocka7e24c12009-10-30 11:49:00 +0000411
412
413//
414// Accessors::ScriptCompilationType
415//
416
417
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000418void Accessors::ScriptCompilationTypeGetter(
419 v8::Local<v8::Name> name,
420 const v8::PropertyCallbackInfo<v8::Value>& info) {
421 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
422 DisallowHeapAllocation no_allocation;
423 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100424 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425 Object* res = Smi::FromInt(
426 Script::cast(JSValue::cast(object)->value())->compilation_type());
427 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000428}
429
430
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000431Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
432 Isolate* isolate, PropertyAttributes attributes) {
433 Handle<String> name(isolate->factory()->InternalizeOneByteString(
434 STATIC_CHAR_VECTOR("compilation_type")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100435 return MakeAccessor(isolate, name, &ScriptCompilationTypeGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000436 attributes);
437}
Steve Blocka7e24c12009-10-30 11:49:00 +0000438
439
440//
441// Accessors::ScriptGetLineEnds
442//
443
444
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000445void Accessors::ScriptLineEndsGetter(
446 v8::Local<v8::Name> name,
447 const v8::PropertyCallbackInfo<v8::Value>& info) {
448 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
Steve Block44f0eee2011-05-26 01:26:41 +0100449 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100450 Handle<Object> object = Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000451 Handle<Script> script(
452 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
453 Script::InitLineEnds(script);
454 DCHECK(script->line_ends()->IsFixedArray());
Steve Blockd0582a62009-12-15 09:54:21 +0000455 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800456 // We do not want anyone to modify this array from JS.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000457 DCHECK(*line_ends == isolate->heap()->empty_fixed_array() ||
Steve Block44f0eee2011-05-26 01:26:41 +0100458 line_ends->map() == isolate->heap()->fixed_cow_array_map());
459 Handle<JSArray> js_array =
460 isolate->factory()->NewJSArrayWithElements(line_ends);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000461 info.GetReturnValue().Set(Utils::ToLocal(js_array));
Steve Blocka7e24c12009-10-30 11:49:00 +0000462}
463
464
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000465Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
466 Isolate* isolate, PropertyAttributes attributes) {
467 Handle<String> name(isolate->factory()->InternalizeOneByteString(
468 STATIC_CHAR_VECTOR("line_ends")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100469 return MakeAccessor(isolate, name, &ScriptLineEndsGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000470 attributes);
471}
472
473
474//
475// Accessors::ScriptSourceUrl
476//
477
478
479void Accessors::ScriptSourceUrlGetter(
480 v8::Local<v8::Name> name,
481 const v8::PropertyCallbackInfo<v8::Value>& info) {
482 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
483 DisallowHeapAllocation no_allocation;
484 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100485 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000486 Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
487 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
488}
489
490
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000491Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
492 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100493 return MakeAccessor(isolate, isolate->factory()->source_url_string(),
494 &ScriptSourceUrlGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000495}
496
497
498//
499// Accessors::ScriptSourceMappingUrl
500//
501
502
503void Accessors::ScriptSourceMappingUrlGetter(
504 v8::Local<v8::Name> name,
505 const v8::PropertyCallbackInfo<v8::Value>& info) {
506 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
507 DisallowHeapAllocation no_allocation;
508 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100509 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000510 Object* url =
511 Script::cast(JSValue::cast(object)->value())->source_mapping_url();
512 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
513}
514
515
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000516Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
517 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100518 return MakeAccessor(isolate, isolate->factory()->source_mapping_url_string(),
519 &ScriptSourceMappingUrlGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000520}
Steve Blocka7e24c12009-10-30 11:49:00 +0000521
522
523//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000524// Accessors::ScriptIsEmbedderDebugScript
525//
526
527
528void Accessors::ScriptIsEmbedderDebugScriptGetter(
529 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
530 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
531 DisallowHeapAllocation no_allocation;
532 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100533 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000534 bool is_embedder_debug_script = Script::cast(JSValue::cast(object)->value())
535 ->origin_options()
536 .IsEmbedderDebugScript();
537 Object* res = *isolate->factory()->ToBoolean(is_embedder_debug_script);
538 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
539}
540
541
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000542Handle<AccessorInfo> Accessors::ScriptIsEmbedderDebugScriptInfo(
543 Isolate* isolate, PropertyAttributes attributes) {
544 Handle<String> name(isolate->factory()->InternalizeOneByteString(
545 STATIC_CHAR_VECTOR("is_debugger_script")));
546 return MakeAccessor(isolate, name, &ScriptIsEmbedderDebugScriptGetter,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100547 nullptr, attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000548}
549
550
551//
Steve Blocka7e24c12009-10-30 11:49:00 +0000552// Accessors::ScriptGetContextData
553//
554
555
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000556void Accessors::ScriptContextDataGetter(
557 v8::Local<v8::Name> name,
558 const v8::PropertyCallbackInfo<v8::Value>& info) {
559 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
560 DisallowHeapAllocation no_allocation;
561 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100562 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000563 Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
564 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000565}
566
567
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000568Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
569 Isolate* isolate, PropertyAttributes attributes) {
570 Handle<String> name(isolate->factory()->InternalizeOneByteString(
571 STATIC_CHAR_VECTOR("context_data")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100572 return MakeAccessor(isolate, name, &ScriptContextDataGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000573 attributes);
574}
Steve Blocka7e24c12009-10-30 11:49:00 +0000575
576
577//
Steve Blockd0582a62009-12-15 09:54:21 +0000578// Accessors::ScriptGetEvalFromScript
Steve Blocka7e24c12009-10-30 11:49:00 +0000579//
580
581
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000582void Accessors::ScriptEvalFromScriptGetter(
583 v8::Local<v8::Name> name,
584 const v8::PropertyCallbackInfo<v8::Value>& info) {
585 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
586 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100587 Handle<Object> object = Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000588 Handle<Script> script(
589 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
590 Handle<Object> result = isolate->factory()->undefined_value();
591 if (!script->eval_from_shared()->IsUndefined()) {
Steve Blockd0582a62009-12-15 09:54:21 +0000592 Handle<SharedFunctionInfo> eval_from_shared(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000593 SharedFunctionInfo::cast(script->eval_from_shared()));
Steve Blockd0582a62009-12-15 09:54:21 +0000594 if (eval_from_shared->script()->IsScript()) {
595 Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000596 result = Script::GetWrapper(eval_from_script);
Steve Blockd0582a62009-12-15 09:54:21 +0000597 }
598 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000599
600 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000601}
602
603
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000604Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
605 Isolate* isolate, PropertyAttributes attributes) {
606 Handle<String> name(isolate->factory()->InternalizeOneByteString(
607 STATIC_CHAR_VECTOR("eval_from_script")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100608 return MakeAccessor(isolate, name, &ScriptEvalFromScriptGetter, 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::ScriptGetEvalFromScriptPosition
Steve Blocka7e24c12009-10-30 11:49:00 +0000615//
616
617
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000618void Accessors::ScriptEvalFromScriptPositionGetter(
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);
Ben Murdochc5610432016-08-08 18:44:38 +0100623 Handle<Object> object = Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624 Handle<Script> script(
625 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
626 Handle<Object> result = isolate->factory()->undefined_value();
627 if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
Ben Murdochc5610432016-08-08 18:44:38 +0100628 result = Handle<Object>(Smi::FromInt(script->GetEvalPosition()), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000629 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000630 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000631}
632
633
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000634Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
635 Isolate* isolate, PropertyAttributes attributes) {
636 Handle<String> name(isolate->factory()->InternalizeOneByteString(
637 STATIC_CHAR_VECTOR("eval_from_script_position")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100638 return MakeAccessor(isolate, name, &ScriptEvalFromScriptPositionGetter,
639 nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000640}
Steve Blockd0582a62009-12-15 09:54:21 +0000641
642
643//
644// Accessors::ScriptGetEvalFromFunctionName
645//
646
647
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648void Accessors::ScriptEvalFromFunctionNameGetter(
649 v8::Local<v8::Name> name,
650 const v8::PropertyCallbackInfo<v8::Value>& info) {
651 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
652 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100653 Handle<Object> object = Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000654 Handle<Script> script(
655 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100656 Handle<Object> result = isolate->factory()->undefined_value();
657 if (!script->eval_from_shared()->IsUndefined()) {
658 Handle<SharedFunctionInfo> shared(
659 SharedFunctionInfo::cast(script->eval_from_shared()));
660 // Find the name of the function calling eval.
661 if (!shared->name()->IsUndefined()) {
662 result = Handle<Object>(shared->name(), isolate);
663 } else {
664 result = Handle<Object>(shared->inferred_name(), isolate);
665 }
Steve Blockd0582a62009-12-15 09:54:21 +0000666 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000667 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blockd0582a62009-12-15 09:54:21 +0000668}
669
670
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000671Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
672 Isolate* isolate, PropertyAttributes attributes) {
673 Handle<String> name(isolate->factory()->InternalizeOneByteString(
674 STATIC_CHAR_VECTOR("eval_from_function_name")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100675 return MakeAccessor(isolate, name, &ScriptEvalFromFunctionNameGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000676 attributes);
677}
Steve Blocka7e24c12009-10-30 11:49:00 +0000678
679
680//
681// Accessors::FunctionPrototype
682//
683
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000684static Handle<Object> GetFunctionPrototype(Isolate* isolate,
685 Handle<JSFunction> function) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000686 if (!function->has_prototype()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000687 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
688 JSFunction::SetPrototype(function, proto);
Steve Blocka7e24c12009-10-30 11:49:00 +0000689 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000690 return Handle<Object>(function->prototype(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000691}
692
693
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400694MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype(
695 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000696 JSFunction::SetPrototype(function, value);
697 DCHECK(function->prototype() == *value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000698 return function;
699}
700
701
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400702MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
703 Handle<Object> prototype) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000704 DCHECK(function->IsConstructor());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000705 Isolate* isolate = function->GetIsolate();
706 return SetFunctionPrototype(isolate, function, prototype);
707}
708
709
710void Accessors::FunctionPrototypeGetter(
711 v8::Local<v8::Name> name,
712 const v8::PropertyCallbackInfo<v8::Value>& info) {
713 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
714 HandleScope scope(isolate);
715 Handle<JSFunction> function =
716 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
717 Handle<Object> result = GetFunctionPrototype(isolate, function);
718 info.GetReturnValue().Set(Utils::ToLocal(result));
719}
720
721
722void Accessors::FunctionPrototypeSetter(
723 v8::Local<v8::Name> name,
724 v8::Local<v8::Value> val,
725 const v8::PropertyCallbackInfo<void>& info) {
726 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
727 HandleScope scope(isolate);
728 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000729 Handle<JSFunction> object =
730 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400731 if (SetFunctionPrototype(isolate, object, value).is_null()) {
732 isolate->OptionalRescheduleException(false);
733 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000734}
735
736
737Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
738 Isolate* isolate, PropertyAttributes attributes) {
739 return MakeAccessor(isolate,
740 isolate->factory()->prototype_string(),
741 &FunctionPrototypeGetter,
742 &FunctionPrototypeSetter,
743 attributes);
744}
Steve Blocka7e24c12009-10-30 11:49:00 +0000745
746
747//
748// Accessors::FunctionLength
749//
750
751
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000752void Accessors::FunctionLengthGetter(
753 v8::Local<v8::Name> name,
754 const v8::PropertyCallbackInfo<v8::Value>& info) {
755 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
756 HandleScope scope(isolate);
757 Handle<JSFunction> function =
758 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdochc5610432016-08-08 18:44:38 +0100759 Handle<Object> result;
760 if (!JSFunction::GetLength(isolate, function).ToHandle(&result)) {
761 result = handle(Smi::FromInt(0), isolate);
762 isolate->OptionalRescheduleException(false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000763 }
Ben Murdochc5610432016-08-08 18:44:38 +0100764
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000765 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000766}
767
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000768Handle<AccessorInfo> Accessors::FunctionLengthInfo(
769 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100770 return MakeAccessor(isolate, isolate->factory()->length_string(),
Ben Murdochc5610432016-08-08 18:44:38 +0100771 &FunctionLengthGetter, &ReconfigureToDataProperty,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000772 attributes);
773}
Steve Blocka7e24c12009-10-30 11:49:00 +0000774
775
776//
777// Accessors::FunctionName
778//
779
780
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000781void Accessors::FunctionNameGetter(
782 v8::Local<v8::Name> name,
783 const v8::PropertyCallbackInfo<v8::Value>& info) {
784 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
785 HandleScope scope(isolate);
786 Handle<JSFunction> function =
787 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdochc5610432016-08-08 18:44:38 +0100788 Handle<Object> result = JSFunction::GetName(isolate, function);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000789 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000790}
791
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000792Handle<AccessorInfo> Accessors::FunctionNameInfo(
793 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100794 return MakeAccessor(isolate, isolate->factory()->name_string(),
Ben Murdochc5610432016-08-08 18:44:38 +0100795 &FunctionNameGetter, &ReconfigureToDataProperty,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000796 attributes);
797}
Steve Blocka7e24c12009-10-30 11:49:00 +0000798
799
800//
801// Accessors::FunctionArguments
802//
803
Ben Murdochb0fe1622011-05-05 13:52:32 +0100804
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000805static Handle<Object> ArgumentsForInlinedFunction(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100806 JavaScriptFrame* frame,
807 Handle<JSFunction> inlined_function,
808 int inlined_frame_index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000809 Isolate* isolate = inlined_function->GetIsolate();
810 Factory* factory = isolate->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000811
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000812 TranslatedState translated_values(frame);
813 translated_values.Prepare(false, frame->fp());
814
815 int argument_count = 0;
816 TranslatedFrame* translated_frame =
817 translated_values.GetArgumentsInfoFromJSFrameIndex(inlined_frame_index,
818 &argument_count);
819 TranslatedFrame::iterator iter = translated_frame->begin();
820
821 // Skip the function.
822 iter++;
823
824 // Skip the receiver.
825 iter++;
826 argument_count--;
827
Ben Murdochb0fe1622011-05-05 13:52:32 +0100828 Handle<JSObject> arguments =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000829 factory->NewArgumentsObject(inlined_function, argument_count);
830 Handle<FixedArray> array = factory->NewFixedArray(argument_count);
831 bool should_deoptimize = false;
832 for (int i = 0; i < argument_count; ++i) {
833 // If we materialize any object, we should deopt because we might alias
834 // an object that was eliminated by escape analysis.
835 should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
836 Handle<Object> value = iter->GetValue();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100837 array->set(i, *value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000838 iter++;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100839 }
840 arguments->set_elements(*array);
841
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000842 if (should_deoptimize) {
843 translated_values.StoreMaterializedValuesAndDeopt();
844 }
845
Ben Murdochb0fe1622011-05-05 13:52:32 +0100846 // Return the freshly allocated arguments object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000847 return arguments;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100848}
849
Steve Blocka7e24c12009-10-30 11:49:00 +0000850
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000851static int FindFunctionInFrame(JavaScriptFrame* frame,
852 Handle<JSFunction> function) {
853 DisallowHeapAllocation no_allocation;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100854 List<JSFunction*> functions(2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000855 frame->GetFunctions(&functions);
856 for (int i = functions.length() - 1; i >= 0; i--) {
857 if (functions[i] == *function) return i;
858 }
859 return -1;
860}
861
862
Ben Murdoch097c5b22016-05-18 11:27:45 +0100863namespace {
864
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000865Handle<Object> GetFunctionArguments(Isolate* isolate,
866 Handle<JSFunction> function) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867 // Find the top invocation of the function by traversing frames.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100868 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000869 JavaScriptFrame* frame = it.frame();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000870 int function_index = FindFunctionInFrame(frame, function);
871 if (function_index < 0) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +0000872
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000873 if (function_index > 0) {
874 // The function in question was inlined. Inlined functions have the
875 // correct number of arguments and no allocated arguments object, so
876 // we can construct a fresh one by interpreting the function's
877 // deoptimization input data.
878 return ArgumentsForInlinedFunction(frame, function, function_index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000879 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000880
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000881 // Find the frame that holds the actual arguments passed to the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000882 it.AdvanceToArgumentsFrame();
883 frame = it.frame();
884
885 // Get the number of arguments and construct an arguments object
886 // mirror for the right frame.
887 const int length = frame->ComputeParametersCount();
888 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
889 function, length);
890 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
891
892 // Copy the parameters to the arguments object.
893 DCHECK(array->length() == length);
894 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
895 arguments->set_elements(*array);
896
897 // Return the freshly allocated arguments object.
898 return arguments;
Steve Blocka7e24c12009-10-30 11:49:00 +0000899 }
900
901 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000902 return isolate->factory()->null_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000903}
904
Ben Murdoch097c5b22016-05-18 11:27:45 +0100905} // namespace
Steve Blocka7e24c12009-10-30 11:49:00 +0000906
Ben Murdoch097c5b22016-05-18 11:27:45 +0100907
908Handle<JSObject> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
909 Handle<Object> arguments =
910 GetFunctionArguments(function->GetIsolate(), function);
911 CHECK(arguments->IsJSObject());
912 return Handle<JSObject>::cast(arguments);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000913}
914
915
916void Accessors::FunctionArgumentsGetter(
917 v8::Local<v8::Name> name,
918 const v8::PropertyCallbackInfo<v8::Value>& info) {
919 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
920 HandleScope scope(isolate);
921 Handle<JSFunction> function =
922 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100923 Handle<Object> result =
924 function->shared()->native()
925 ? Handle<Object>::cast(isolate->factory()->null_value())
926 : GetFunctionArguments(isolate, function);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000927 info.GetReturnValue().Set(Utils::ToLocal(result));
928}
929
930
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000931Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
932 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100933 return MakeAccessor(isolate, isolate->factory()->arguments_string(),
934 &FunctionArgumentsGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000935}
Steve Blocka7e24c12009-10-30 11:49:00 +0000936
937
938//
939// Accessors::FunctionCaller
940//
941
942
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000943static inline bool AllowAccessToFunction(Context* current_context,
944 JSFunction* function) {
945 return current_context->HasSameSecurityTokenAs(function->context());
Steve Block44f0eee2011-05-26 01:26:41 +0100946}
947
948
Ben Murdoch257744e2011-11-30 15:57:28 +0000949class FrameFunctionIterator {
950 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000951 FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
952 : isolate_(isolate),
953 frame_iterator_(isolate),
Ben Murdoch257744e2011-11-30 15:57:28 +0000954 functions_(2),
955 index_(0) {
956 GetFunctions();
957 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000958 JSFunction* next() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000959 while (true) {
960 if (functions_.length() == 0) return NULL;
961 JSFunction* next_function = functions_[index_];
962 index_--;
963 if (index_ < 0) {
964 GetFunctions();
965 }
966 // Skip functions from other origins.
967 if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
968 return next_function;
Ben Murdoch257744e2011-11-30 15:57:28 +0000969 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000970 }
971
972 // Iterate through functions until the first occurence of 'function'.
973 // Returns true if 'function' is found, and false if the iterator ends
974 // without finding it.
975 bool Find(JSFunction* function) {
976 JSFunction* next_function;
977 do {
978 next_function = next();
979 if (next_function == function) return true;
980 } while (next_function != NULL);
981 return false;
982 }
Ben Murdoch589d6972011-11-30 16:04:58 +0000983
Ben Murdoch257744e2011-11-30 15:57:28 +0000984 private:
985 void GetFunctions() {
986 functions_.Rewind(0);
987 if (frame_iterator_.done()) return;
988 JavaScriptFrame* frame = frame_iterator_.frame();
989 frame->GetFunctions(&functions_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000990 DCHECK(functions_.length() > 0);
Ben Murdoch257744e2011-11-30 15:57:28 +0000991 frame_iterator_.Advance();
992 index_ = functions_.length() - 1;
993 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000994 Isolate* isolate_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000995 JavaScriptFrameIterator frame_iterator_;
996 List<JSFunction*> functions_;
997 int index_;
998};
999
1000
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001001MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
1002 Handle<JSFunction> function) {
1003 DisallowHeapAllocation no_allocation;
1004 FrameFunctionIterator it(isolate, no_allocation);
1005 if (function->shared()->native()) {
1006 return MaybeHandle<JSFunction>();
1007 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001008 // Find the function from the frames.
1009 if (!it.Find(*function)) {
1010 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001011 return MaybeHandle<JSFunction>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001012 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001013 // Find previously called non-toplevel function.
1014 JSFunction* caller;
1015 do {
1016 caller = it.next();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001017 if (caller == NULL) return MaybeHandle<JSFunction>();
Ben Murdoch257744e2011-11-30 15:57:28 +00001018 } while (caller->shared()->is_toplevel());
1019
1020 // If caller is a built-in function and caller's caller is also built-in,
1021 // use that instead.
1022 JSFunction* potential_caller = caller;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001023 while (potential_caller != NULL && potential_caller->shared()->IsBuiltin()) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001024 caller = potential_caller;
1025 potential_caller = it.next();
1026 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001027 if (!caller->shared()->native() && potential_caller != NULL) {
1028 caller = potential_caller;
1029 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001030 // Censor if the caller is not a sloppy mode function.
1031 // Change from ES5, which used to throw, see:
1032 // https://bugs.ecmascript.org/show_bug.cgi?id=310
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001033 if (is_strict(caller->shared()->language_mode())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001034 return MaybeHandle<JSFunction>();
1035 }
1036 // Don't return caller from another security context.
1037 if (!AllowAccessToFunction(isolate->context(), caller)) {
1038 return MaybeHandle<JSFunction>();
1039 }
1040 return Handle<JSFunction>(caller);
Steve Blocka7e24c12009-10-30 11:49:00 +00001041}
1042
1043
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001044void Accessors::FunctionCallerGetter(
1045 v8::Local<v8::Name> name,
1046 const v8::PropertyCallbackInfo<v8::Value>& info) {
1047 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1048 HandleScope scope(isolate);
1049 Handle<JSFunction> function =
1050 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1051 Handle<Object> result;
1052 MaybeHandle<JSFunction> maybe_caller;
1053 maybe_caller = FindCaller(isolate, function);
1054 Handle<JSFunction> caller;
1055 if (maybe_caller.ToHandle(&caller)) {
1056 result = caller;
1057 } else {
1058 result = isolate->factory()->null_value();
1059 }
1060 info.GetReturnValue().Set(Utils::ToLocal(result));
1061}
1062
1063
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001064Handle<AccessorInfo> Accessors::FunctionCallerInfo(
1065 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001066 return MakeAccessor(isolate, isolate->factory()->caller_string(),
1067 &FunctionCallerGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001068}
Steve Blocka7e24c12009-10-30 11:49:00 +00001069
1070
1071//
Ben Murdochc5610432016-08-08 18:44:38 +01001072// Accessors::BoundFunctionLength
1073//
1074
1075void Accessors::BoundFunctionLengthGetter(
1076 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
1077 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1078 HandleScope scope(isolate);
1079 Handle<JSBoundFunction> function =
1080 Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder()));
1081
1082 Handle<Smi> target_length;
1083 Handle<JSFunction> target(JSFunction::cast(function->bound_target_function()),
1084 isolate);
1085 if (!JSFunction::GetLength(isolate, target).ToHandle(&target_length)) {
1086 target_length = handle(Smi::FromInt(0), isolate);
1087 isolate->OptionalRescheduleException(false);
1088 return;
1089 }
1090
1091 int bound_length = function->bound_arguments()->length();
1092 int length = Max(0, target_length->value() - bound_length);
1093
1094 Handle<Object> result(Smi::FromInt(length), isolate);
1095 info.GetReturnValue().Set(Utils::ToLocal(result));
1096}
1097
1098Handle<AccessorInfo> Accessors::BoundFunctionLengthInfo(
1099 Isolate* isolate, PropertyAttributes attributes) {
1100 return MakeAccessor(isolate, isolate->factory()->length_string(),
1101 &BoundFunctionLengthGetter, &ReconfigureToDataProperty,
1102 attributes);
1103}
1104
1105//
1106// Accessors::BoundFunctionName
1107//
1108
1109void Accessors::BoundFunctionNameGetter(
1110 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
1111 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1112 HandleScope scope(isolate);
1113 Handle<JSBoundFunction> function =
1114 Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder()));
1115 Handle<Object> result;
1116 if (!JSBoundFunction::GetName(isolate, function).ToHandle(&result)) {
1117 isolate->OptionalRescheduleException(false);
1118 return;
1119 }
1120 info.GetReturnValue().Set(Utils::ToLocal(result));
1121}
1122
1123Handle<AccessorInfo> Accessors::BoundFunctionNameInfo(
1124 Isolate* isolate, PropertyAttributes attributes) {
1125 return MakeAccessor(isolate, isolate->factory()->name_string(),
1126 &BoundFunctionNameGetter, &ReconfigureToDataProperty,
1127 attributes);
1128}
1129
1130//
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001131// Accessors::MakeModuleExport
Steve Blocka7e24c12009-10-30 11:49:00 +00001132//
1133
Ben Murdoch097c5b22016-05-18 11:27:45 +01001134static void ModuleGetExport(v8::Local<v8::Name> property,
1135 const v8::PropertyCallbackInfo<v8::Value>& info) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001136 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
1137 Context* context = Context::cast(instance->context());
1138 DCHECK(context->IsModuleContext());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001139 Isolate* isolate = instance->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001140 int slot = info.Data()
1141 ->Int32Value(info.GetIsolate()->GetCurrentContext())
1142 .FromMaybe(-1);
1143 if (slot < 0 || slot >= context->length()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001144 Handle<Name> name = v8::Utils::OpenHandle(*property);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001145
1146 Handle<Object> exception = isolate->factory()->NewReferenceError(
1147 MessageTemplate::kNotDefined, name);
1148 isolate->ScheduleThrow(*exception);
1149 return;
1150 }
1151 Object* value = context->get(slot);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001152 if (value->IsTheHole()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001153 Handle<Name> name = v8::Utils::OpenHandle(*property);
Steve Blocka7e24c12009-10-30 11:49:00 +00001154
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001155 Handle<Object> exception = isolate->factory()->NewReferenceError(
1156 MessageTemplate::kNotDefined, name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001157 isolate->ScheduleThrow(*exception);
1158 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001159 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001160 info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001161}
1162
1163
Ben Murdoch097c5b22016-05-18 11:27:45 +01001164static void ModuleSetExport(v8::Local<v8::Name> property,
1165 v8::Local<v8::Value> value,
1166 const v8::PropertyCallbackInfo<void>& info) {
1167 if (!info.ShouldThrowOnError()) return;
1168 Handle<Name> name = v8::Utils::OpenHandle(*property);
1169 Isolate* isolate = name->GetIsolate();
1170 Handle<Object> exception =
1171 isolate->factory()->NewTypeError(MessageTemplate::kNotDefined, name);
1172 isolate->ScheduleThrow(*exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00001173}
1174
1175
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001176Handle<AccessorInfo> Accessors::MakeModuleExport(
1177 Handle<String> name,
1178 int index,
1179 PropertyAttributes attributes) {
1180 Isolate* isolate = name->GetIsolate();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001181 Handle<AccessorInfo> info = MakeAccessor(isolate, name, &ModuleGetExport,
1182 &ModuleSetExport, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001183 info->set_data(Smi::FromInt(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001184 return info;
1185}
1186
Steve Blocka7e24c12009-10-30 11:49:00 +00001187
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001188} // namespace internal
1189} // namespace v8