blob: 74238eb168e832952a608d24f2da66fffcea172d [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 Murdochc5610432016-08-08 18:44:38 +010089namespace {
90
91MUST_USE_RESULT MaybeHandle<Object> ReplaceAccessorWithDataProperty(
92 Isolate* isolate, Handle<Object> receiver, Handle<JSObject> holder,
93 Handle<Name> name, Handle<Object> value) {
Ben Murdoch097c5b22016-05-18 11:27:45 +010094 LookupIterator it(receiver, name, holder,
95 LookupIterator::OWN_SKIP_INTERCEPTOR);
96 // Skip any access checks we might hit. This accessor should never hit in a
97 // situation where the caller does not have access.
98 if (it.state() == LookupIterator::ACCESS_CHECK) {
99 CHECK(it.HasAccess());
100 it.Next();
101 }
Ben Murdochc5610432016-08-08 18:44:38 +0100102 DCHECK(holder.is_identical_to(it.GetHolder<JSObject>()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100103 CHECK_EQ(LookupIterator::ACCESSOR, it.state());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100104 it.ReconfigureDataProperty(value, it.property_attributes());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100105 return value;
106}
107
Ben Murdochc5610432016-08-08 18:44:38 +0100108} // namespace
109
Ben Murdoch097c5b22016-05-18 11:27:45 +0100110void Accessors::ReconfigureToDataProperty(
111 v8::Local<v8::Name> key, v8::Local<v8::Value> val,
112 const v8::PropertyCallbackInfo<void>& info) {
113 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
114 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100115 Handle<Object> receiver = Utils::OpenHandle(*info.This());
Ben Murdoch097c5b22016-05-18 11:27:45 +0100116 Handle<JSObject> holder =
117 Handle<JSObject>::cast(Utils::OpenHandle(*info.Holder()));
118 Handle<Name> name = Utils::OpenHandle(*key);
119 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdochc5610432016-08-08 18:44:38 +0100120 MaybeHandle<Object> result =
121 ReplaceAccessorWithDataProperty(isolate, receiver, holder, name, value);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100122 if (result.is_null()) isolate->OptionalRescheduleException(false);
123}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000124
125//
126// Accessors::ArgumentsIterator
127//
128
129
130void Accessors::ArgumentsIteratorGetter(
131 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
132 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
133 DisallowHeapAllocation no_allocation;
134 HandleScope scope(isolate);
135 Object* result = isolate->native_context()->array_values_iterator();
136 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
137}
138
139
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
141 Isolate* isolate, PropertyAttributes attributes) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400142 Handle<Name> name = isolate->factory()->iterator_symbol();
Ben Murdoch097c5b22016-05-18 11:27:45 +0100143 return MakeAccessor(isolate, name, &ArgumentsIteratorGetter, nullptr,
144 attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000145}
146
147
148//
149// Accessors::ArrayLength
150//
151
152
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153void Accessors::ArrayLengthGetter(
154 v8::Local<v8::Name> name,
155 const v8::PropertyCallbackInfo<v8::Value>& info) {
156 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
157 DisallowHeapAllocation no_allocation;
Steve Block44f0eee2011-05-26 01:26:41 +0100158 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000159 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
160 Object* result = holder->length();
161 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000162}
163
164
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000165void Accessors::ArrayLengthSetter(
166 v8::Local<v8::Name> name,
167 v8::Local<v8::Value> val,
168 const v8::PropertyCallbackInfo<void>& info) {
169 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
170 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000171
Ben Murdochc5610432016-08-08 18:44:38 +0100172 Handle<JSReceiver> object = Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000173 Handle<JSArray> array = Handle<JSArray>::cast(object);
174 Handle<Object> length_obj = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 uint32_t length = 0;
177 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178 isolate->OptionalRescheduleException(false);
179 return;
180 }
181
Ben Murdochc5610432016-08-08 18:44:38 +0100182 JSArray::SetLength(array, length);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100183
184 if (info.ShouldThrowOnError()) {
185 uint32_t actual_new_len = 0;
186 CHECK(array->length()->ToArrayLength(&actual_new_len));
187 // Throw TypeError if there were non-deletable elements.
188 if (actual_new_len != length) {
189 Factory* factory = isolate->factory();
190 isolate->Throw(*factory->NewTypeError(
191 MessageTemplate::kStrictDeleteProperty,
192 factory->NewNumberFromUint(actual_new_len - 1), array));
193 isolate->OptionalRescheduleException(false);
194 }
195 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000196}
197
198
199Handle<AccessorInfo> Accessors::ArrayLengthInfo(
200 Isolate* isolate, PropertyAttributes attributes) {
201 return MakeAccessor(isolate,
202 isolate->factory()->length_string(),
203 &ArrayLengthGetter,
204 &ArrayLengthSetter,
205 attributes);
206}
207
Steve Blocka7e24c12009-10-30 11:49:00 +0000208
Steve Blocka7e24c12009-10-30 11:49:00 +0000209//
210// Accessors::StringLength
211//
212
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213void Accessors::StringLengthGetter(
214 v8::Local<v8::Name> name,
215 const v8::PropertyCallbackInfo<v8::Value>& info) {
216 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
217 DisallowHeapAllocation no_allocation;
218 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000219
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220 // We have a slight impedance mismatch between the external API and the way we
221 // use callbacks internally: Externally, callbacks can only be used with
222 // v8::Object, but internally we have callbacks on entities which are higher
223 // in the hierarchy, in this case for String values.
224
225 Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
226 if (!value->IsString()) {
227 // Not a string value. That means that we either got a String wrapper or
228 // a Value with a String wrapper in its prototype chain.
229 value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
230 }
231 Object* result = Smi::FromInt(String::cast(value)->length());
232 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000233}
234
235
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236Handle<AccessorInfo> Accessors::StringLengthInfo(
237 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100238 return MakeAccessor(isolate, isolate->factory()->length_string(),
239 &StringLengthGetter, nullptr, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000240}
241
242
Steve Blocka7e24c12009-10-30 11:49:00 +0000243//
244// Accessors::ScriptColumnOffset
245//
246
247
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000248void Accessors::ScriptColumnOffsetGetter(
249 v8::Local<v8::Name> name,
250 const v8::PropertyCallbackInfo<v8::Value>& info) {
251 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
252 DisallowHeapAllocation no_allocation;
253 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100254 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000255 Object* res = Smi::FromInt(
256 Script::cast(JSValue::cast(object)->value())->column_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000258}
259
260
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000261Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
262 Isolate* isolate, PropertyAttributes attributes) {
263 Handle<String> name(isolate->factory()->InternalizeOneByteString(
264 STATIC_CHAR_VECTOR("column_offset")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100265 return MakeAccessor(isolate, name, &ScriptColumnOffsetGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000266 attributes);
267}
268
269
270//
271// Accessors::ScriptId
272//
273
274
275void Accessors::ScriptIdGetter(
276 v8::Local<v8::Name> name,
277 const v8::PropertyCallbackInfo<v8::Value>& info) {
278 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
279 DisallowHeapAllocation no_allocation;
280 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100281 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000282 Object* id = Smi::FromInt(Script::cast(JSValue::cast(object)->value())->id());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000283 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate)));
284}
285
286
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000287Handle<AccessorInfo> Accessors::ScriptIdInfo(
288 Isolate* isolate, PropertyAttributes attributes) {
289 Handle<String> name(
290 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100291 return MakeAccessor(isolate, name, &ScriptIdGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000292}
293
294
295//
296// Accessors::ScriptName
297//
298
299
300void Accessors::ScriptNameGetter(
301 v8::Local<v8::Name> name,
302 const v8::PropertyCallbackInfo<v8::Value>& info) {
303 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
304 DisallowHeapAllocation no_allocation;
305 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100306 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000307 Object* source = Script::cast(JSValue::cast(object)->value())->name();
308 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
309}
310
311
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000312Handle<AccessorInfo> Accessors::ScriptNameInfo(
313 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100314 return MakeAccessor(isolate, isolate->factory()->name_string(),
315 &ScriptNameGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000316}
317
318
319//
320// Accessors::ScriptSource
321//
322
323
324void Accessors::ScriptSourceGetter(
325 v8::Local<v8::Name> name,
326 const v8::PropertyCallbackInfo<v8::Value>& info) {
327 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
328 DisallowHeapAllocation no_allocation;
329 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100330 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000331 Object* source = Script::cast(JSValue::cast(object)->value())->source();
332 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
333}
334
335
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000336Handle<AccessorInfo> Accessors::ScriptSourceInfo(
337 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100338 return MakeAccessor(isolate, isolate->factory()->source_string(),
339 &ScriptSourceGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000340}
341
342
343//
344// Accessors::ScriptLineOffset
345//
346
347
348void Accessors::ScriptLineOffsetGetter(
349 v8::Local<v8::Name> name,
350 const v8::PropertyCallbackInfo<v8::Value>& info) {
351 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
352 DisallowHeapAllocation no_allocation;
353 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100354 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000355 Object* res =
356 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->line_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000357 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
358}
359
360
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000361Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
362 Isolate* isolate, PropertyAttributes attributes) {
363 Handle<String> name(isolate->factory()->InternalizeOneByteString(
364 STATIC_CHAR_VECTOR("line_offset")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100365 return MakeAccessor(isolate, name, &ScriptLineOffsetGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000366 attributes);
367}
Steve Blocka7e24c12009-10-30 11:49:00 +0000368
369
370//
371// Accessors::ScriptType
372//
373
374
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000375void Accessors::ScriptTypeGetter(
376 v8::Local<v8::Name> name,
377 const v8::PropertyCallbackInfo<v8::Value>& info) {
378 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
379 DisallowHeapAllocation no_allocation;
380 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100381 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000382 Object* res =
383 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->type());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000384 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000385}
386
387
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000388Handle<AccessorInfo> Accessors::ScriptTypeInfo(
389 Isolate* isolate, PropertyAttributes attributes) {
390 Handle<String> name(
391 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100392 return MakeAccessor(isolate, name, &ScriptTypeGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393}
Steve Blocka7e24c12009-10-30 11:49:00 +0000394
395
396//
397// Accessors::ScriptCompilationType
398//
399
400
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000401void Accessors::ScriptCompilationTypeGetter(
402 v8::Local<v8::Name> name,
403 const v8::PropertyCallbackInfo<v8::Value>& info) {
404 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
405 DisallowHeapAllocation no_allocation;
406 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100407 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000408 Object* res = Smi::FromInt(
409 Script::cast(JSValue::cast(object)->value())->compilation_type());
410 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000411}
412
413
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000414Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
415 Isolate* isolate, PropertyAttributes attributes) {
416 Handle<String> name(isolate->factory()->InternalizeOneByteString(
417 STATIC_CHAR_VECTOR("compilation_type")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100418 return MakeAccessor(isolate, name, &ScriptCompilationTypeGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000419 attributes);
420}
Steve Blocka7e24c12009-10-30 11:49:00 +0000421
422
423//
424// Accessors::ScriptGetLineEnds
425//
426
427
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000428void Accessors::ScriptLineEndsGetter(
429 v8::Local<v8::Name> name,
430 const v8::PropertyCallbackInfo<v8::Value>& info) {
431 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
Steve Block44f0eee2011-05-26 01:26:41 +0100432 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100433 Handle<Object> object = Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000434 Handle<Script> script(
435 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
436 Script::InitLineEnds(script);
437 DCHECK(script->line_ends()->IsFixedArray());
Steve Blockd0582a62009-12-15 09:54:21 +0000438 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800439 // We do not want anyone to modify this array from JS.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000440 DCHECK(*line_ends == isolate->heap()->empty_fixed_array() ||
Steve Block44f0eee2011-05-26 01:26:41 +0100441 line_ends->map() == isolate->heap()->fixed_cow_array_map());
442 Handle<JSArray> js_array =
443 isolate->factory()->NewJSArrayWithElements(line_ends);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000444 info.GetReturnValue().Set(Utils::ToLocal(js_array));
Steve Blocka7e24c12009-10-30 11:49:00 +0000445}
446
447
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000448Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
449 Isolate* isolate, PropertyAttributes attributes) {
450 Handle<String> name(isolate->factory()->InternalizeOneByteString(
451 STATIC_CHAR_VECTOR("line_ends")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100452 return MakeAccessor(isolate, name, &ScriptLineEndsGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000453 attributes);
454}
455
456
457//
458// Accessors::ScriptSourceUrl
459//
460
461
462void Accessors::ScriptSourceUrlGetter(
463 v8::Local<v8::Name> name,
464 const v8::PropertyCallbackInfo<v8::Value>& info) {
465 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
466 DisallowHeapAllocation no_allocation;
467 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100468 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000469 Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
470 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
471}
472
473
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000474Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
475 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100476 return MakeAccessor(isolate, isolate->factory()->source_url_string(),
477 &ScriptSourceUrlGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000478}
479
480
481//
482// Accessors::ScriptSourceMappingUrl
483//
484
485
486void Accessors::ScriptSourceMappingUrlGetter(
487 v8::Local<v8::Name> name,
488 const v8::PropertyCallbackInfo<v8::Value>& info) {
489 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
490 DisallowHeapAllocation no_allocation;
491 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100492 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000493 Object* url =
494 Script::cast(JSValue::cast(object)->value())->source_mapping_url();
495 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
496}
497
498
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000499Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
500 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100501 return MakeAccessor(isolate, isolate->factory()->source_mapping_url_string(),
502 &ScriptSourceMappingUrlGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000503}
Steve Blocka7e24c12009-10-30 11:49:00 +0000504
505
506//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000507// Accessors::ScriptIsEmbedderDebugScript
508//
509
510
511void Accessors::ScriptIsEmbedderDebugScriptGetter(
512 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
513 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
514 DisallowHeapAllocation no_allocation;
515 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100516 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000517 bool is_embedder_debug_script = Script::cast(JSValue::cast(object)->value())
518 ->origin_options()
519 .IsEmbedderDebugScript();
520 Object* res = *isolate->factory()->ToBoolean(is_embedder_debug_script);
521 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
522}
523
524
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000525Handle<AccessorInfo> Accessors::ScriptIsEmbedderDebugScriptInfo(
526 Isolate* isolate, PropertyAttributes attributes) {
527 Handle<String> name(isolate->factory()->InternalizeOneByteString(
528 STATIC_CHAR_VECTOR("is_debugger_script")));
529 return MakeAccessor(isolate, name, &ScriptIsEmbedderDebugScriptGetter,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100530 nullptr, attributes);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000531}
532
533
534//
Steve Blocka7e24c12009-10-30 11:49:00 +0000535// Accessors::ScriptGetContextData
536//
537
538
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000539void Accessors::ScriptContextDataGetter(
540 v8::Local<v8::Name> name,
541 const v8::PropertyCallbackInfo<v8::Value>& info) {
542 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
543 DisallowHeapAllocation no_allocation;
544 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100545 Object* object = *Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000546 Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
547 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000548}
549
550
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000551Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
552 Isolate* isolate, PropertyAttributes attributes) {
553 Handle<String> name(isolate->factory()->InternalizeOneByteString(
554 STATIC_CHAR_VECTOR("context_data")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100555 return MakeAccessor(isolate, name, &ScriptContextDataGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000556 attributes);
557}
Steve Blocka7e24c12009-10-30 11:49:00 +0000558
559
560//
Steve Blockd0582a62009-12-15 09:54:21 +0000561// Accessors::ScriptGetEvalFromScript
Steve Blocka7e24c12009-10-30 11:49:00 +0000562//
563
564
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000565void Accessors::ScriptEvalFromScriptGetter(
566 v8::Local<v8::Name> name,
567 const v8::PropertyCallbackInfo<v8::Value>& info) {
568 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
569 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100570 Handle<Object> object = Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000571 Handle<Script> script(
572 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
573 Handle<Object> result = isolate->factory()->undefined_value();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100574 if (!script->eval_from_shared()->IsUndefined(isolate)) {
Steve Blockd0582a62009-12-15 09:54:21 +0000575 Handle<SharedFunctionInfo> eval_from_shared(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000576 SharedFunctionInfo::cast(script->eval_from_shared()));
Steve Blockd0582a62009-12-15 09:54:21 +0000577 if (eval_from_shared->script()->IsScript()) {
578 Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000579 result = Script::GetWrapper(eval_from_script);
Steve Blockd0582a62009-12-15 09:54:21 +0000580 }
581 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000582
583 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000584}
585
586
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000587Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
588 Isolate* isolate, PropertyAttributes attributes) {
589 Handle<String> name(isolate->factory()->InternalizeOneByteString(
590 STATIC_CHAR_VECTOR("eval_from_script")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100591 return MakeAccessor(isolate, name, &ScriptEvalFromScriptGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000592 attributes);
593}
Steve Blocka7e24c12009-10-30 11:49:00 +0000594
595
596//
Steve Blockd0582a62009-12-15 09:54:21 +0000597// Accessors::ScriptGetEvalFromScriptPosition
Steve Blocka7e24c12009-10-30 11:49:00 +0000598//
599
600
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000601void Accessors::ScriptEvalFromScriptPositionGetter(
602 v8::Local<v8::Name> name,
603 const v8::PropertyCallbackInfo<v8::Value>& info) {
604 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
605 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100606 Handle<Object> object = Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000607 Handle<Script> script(
608 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
609 Handle<Object> result = isolate->factory()->undefined_value();
610 if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
Ben Murdochc5610432016-08-08 18:44:38 +0100611 result = Handle<Object>(Smi::FromInt(script->GetEvalPosition()), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000612 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000613 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000614}
615
616
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000617Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
618 Isolate* isolate, PropertyAttributes attributes) {
619 Handle<String> name(isolate->factory()->InternalizeOneByteString(
620 STATIC_CHAR_VECTOR("eval_from_script_position")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100621 return MakeAccessor(isolate, name, &ScriptEvalFromScriptPositionGetter,
622 nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000623}
Steve Blockd0582a62009-12-15 09:54:21 +0000624
625
626//
627// Accessors::ScriptGetEvalFromFunctionName
628//
629
630
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000631void Accessors::ScriptEvalFromFunctionNameGetter(
632 v8::Local<v8::Name> name,
633 const v8::PropertyCallbackInfo<v8::Value>& info) {
634 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
635 HandleScope scope(isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100636 Handle<Object> object = Utils::OpenHandle(*info.Holder());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000637 Handle<Script> script(
638 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
Ben Murdochc5610432016-08-08 18:44:38 +0100639 Handle<Object> result = isolate->factory()->undefined_value();
Ben Murdoch61f157c2016-09-16 13:49:30 +0100640 if (!script->eval_from_shared()->IsUndefined(isolate)) {
Ben Murdochc5610432016-08-08 18:44:38 +0100641 Handle<SharedFunctionInfo> shared(
642 SharedFunctionInfo::cast(script->eval_from_shared()));
643 // Find the name of the function calling eval.
Ben Murdoch61f157c2016-09-16 13:49:30 +0100644 if (!shared->name()->IsUndefined(isolate)) {
Ben Murdochc5610432016-08-08 18:44:38 +0100645 result = Handle<Object>(shared->name(), isolate);
646 } else {
647 result = Handle<Object>(shared->inferred_name(), isolate);
648 }
Steve Blockd0582a62009-12-15 09:54:21 +0000649 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000650 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blockd0582a62009-12-15 09:54:21 +0000651}
652
653
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000654Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
655 Isolate* isolate, PropertyAttributes attributes) {
656 Handle<String> name(isolate->factory()->InternalizeOneByteString(
657 STATIC_CHAR_VECTOR("eval_from_function_name")));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100658 return MakeAccessor(isolate, name, &ScriptEvalFromFunctionNameGetter, nullptr,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000659 attributes);
660}
Steve Blocka7e24c12009-10-30 11:49:00 +0000661
662
663//
664// Accessors::FunctionPrototype
665//
666
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000667static Handle<Object> GetFunctionPrototype(Isolate* isolate,
668 Handle<JSFunction> function) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000669 if (!function->has_prototype()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000670 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
671 JSFunction::SetPrototype(function, proto);
Steve Blocka7e24c12009-10-30 11:49:00 +0000672 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000673 return Handle<Object>(function->prototype(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000674}
675
676
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400677MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype(
678 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679 JSFunction::SetPrototype(function, value);
680 DCHECK(function->prototype() == *value);
Steve Blocka7e24c12009-10-30 11:49:00 +0000681 return function;
682}
683
684
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400685MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
686 Handle<Object> prototype) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000687 DCHECK(function->IsConstructor());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000688 Isolate* isolate = function->GetIsolate();
689 return SetFunctionPrototype(isolate, function, prototype);
690}
691
692
693void Accessors::FunctionPrototypeGetter(
694 v8::Local<v8::Name> name,
695 const v8::PropertyCallbackInfo<v8::Value>& info) {
696 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
697 HandleScope scope(isolate);
698 Handle<JSFunction> function =
699 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
700 Handle<Object> result = GetFunctionPrototype(isolate, function);
701 info.GetReturnValue().Set(Utils::ToLocal(result));
702}
703
704
705void Accessors::FunctionPrototypeSetter(
706 v8::Local<v8::Name> name,
707 v8::Local<v8::Value> val,
708 const v8::PropertyCallbackInfo<void>& info) {
709 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
710 HandleScope scope(isolate);
711 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000712 Handle<JSFunction> object =
713 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400714 if (SetFunctionPrototype(isolate, object, value).is_null()) {
715 isolate->OptionalRescheduleException(false);
716 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717}
718
719
720Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
721 Isolate* isolate, PropertyAttributes attributes) {
722 return MakeAccessor(isolate,
723 isolate->factory()->prototype_string(),
724 &FunctionPrototypeGetter,
725 &FunctionPrototypeSetter,
726 attributes);
727}
Steve Blocka7e24c12009-10-30 11:49:00 +0000728
729
730//
731// Accessors::FunctionLength
732//
733
734
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735void Accessors::FunctionLengthGetter(
736 v8::Local<v8::Name> name,
737 const v8::PropertyCallbackInfo<v8::Value>& info) {
738 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
739 HandleScope scope(isolate);
740 Handle<JSFunction> function =
741 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdochc5610432016-08-08 18:44:38 +0100742 Handle<Object> result;
743 if (!JSFunction::GetLength(isolate, function).ToHandle(&result)) {
744 result = handle(Smi::FromInt(0), isolate);
745 isolate->OptionalRescheduleException(false);
Steve Blocka7e24c12009-10-30 11:49:00 +0000746 }
Ben Murdochc5610432016-08-08 18:44:38 +0100747
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000748 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000749}
750
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000751Handle<AccessorInfo> Accessors::FunctionLengthInfo(
752 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100753 return MakeAccessor(isolate, isolate->factory()->length_string(),
Ben Murdochc5610432016-08-08 18:44:38 +0100754 &FunctionLengthGetter, &ReconfigureToDataProperty,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000755 attributes);
756}
Steve Blocka7e24c12009-10-30 11:49:00 +0000757
758
759//
760// Accessors::FunctionName
761//
762
763
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000764void Accessors::FunctionNameGetter(
765 v8::Local<v8::Name> name,
766 const v8::PropertyCallbackInfo<v8::Value>& info) {
767 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
768 HandleScope scope(isolate);
769 Handle<JSFunction> function =
770 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdochc5610432016-08-08 18:44:38 +0100771 Handle<Object> result = JSFunction::GetName(isolate, function);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000772 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000773}
774
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000775Handle<AccessorInfo> Accessors::FunctionNameInfo(
776 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100777 return MakeAccessor(isolate, isolate->factory()->name_string(),
Ben Murdochc5610432016-08-08 18:44:38 +0100778 &FunctionNameGetter, &ReconfigureToDataProperty,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000779 attributes);
780}
Steve Blocka7e24c12009-10-30 11:49:00 +0000781
782
783//
784// Accessors::FunctionArguments
785//
786
Ben Murdochb0fe1622011-05-05 13:52:32 +0100787
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000788static Handle<Object> ArgumentsForInlinedFunction(
Ben Murdochb0fe1622011-05-05 13:52:32 +0100789 JavaScriptFrame* frame,
790 Handle<JSFunction> inlined_function,
791 int inlined_frame_index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000792 Isolate* isolate = inlined_function->GetIsolate();
793 Factory* factory = isolate->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000794
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000795 TranslatedState translated_values(frame);
796 translated_values.Prepare(false, frame->fp());
797
798 int argument_count = 0;
799 TranslatedFrame* translated_frame =
800 translated_values.GetArgumentsInfoFromJSFrameIndex(inlined_frame_index,
801 &argument_count);
802 TranslatedFrame::iterator iter = translated_frame->begin();
803
804 // Skip the function.
805 iter++;
806
807 // Skip the receiver.
808 iter++;
809 argument_count--;
810
Ben Murdochb0fe1622011-05-05 13:52:32 +0100811 Handle<JSObject> arguments =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000812 factory->NewArgumentsObject(inlined_function, argument_count);
813 Handle<FixedArray> array = factory->NewFixedArray(argument_count);
814 bool should_deoptimize = false;
815 for (int i = 0; i < argument_count; ++i) {
816 // If we materialize any object, we should deopt because we might alias
817 // an object that was eliminated by escape analysis.
818 should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
819 Handle<Object> value = iter->GetValue();
Ben Murdochb0fe1622011-05-05 13:52:32 +0100820 array->set(i, *value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000821 iter++;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100822 }
823 arguments->set_elements(*array);
824
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000825 if (should_deoptimize) {
826 translated_values.StoreMaterializedValuesAndDeopt();
827 }
828
Ben Murdochb0fe1622011-05-05 13:52:32 +0100829 // Return the freshly allocated arguments object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000830 return arguments;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100831}
832
Steve Blocka7e24c12009-10-30 11:49:00 +0000833
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000834static int FindFunctionInFrame(JavaScriptFrame* frame,
835 Handle<JSFunction> function) {
836 DisallowHeapAllocation no_allocation;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100837 List<JSFunction*> functions(2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000838 frame->GetFunctions(&functions);
839 for (int i = functions.length() - 1; i >= 0; i--) {
840 if (functions[i] == *function) return i;
841 }
842 return -1;
843}
844
845
Ben Murdoch097c5b22016-05-18 11:27:45 +0100846namespace {
847
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000848Handle<Object> GetFunctionArguments(Isolate* isolate,
849 Handle<JSFunction> function) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000850 // Find the top invocation of the function by traversing frames.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100851 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000852 JavaScriptFrame* frame = it.frame();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000853 int function_index = FindFunctionInFrame(frame, function);
854 if (function_index < 0) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +0000855
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000856 if (function_index > 0) {
857 // The function in question was inlined. Inlined functions have the
858 // correct number of arguments and no allocated arguments object, so
859 // we can construct a fresh one by interpreting the function's
860 // deoptimization input data.
861 return ArgumentsForInlinedFunction(frame, function, function_index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000862 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000863
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000864 // Find the frame that holds the actual arguments passed to the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000865 it.AdvanceToArgumentsFrame();
866 frame = it.frame();
867
868 // Get the number of arguments and construct an arguments object
869 // mirror for the right frame.
870 const int length = frame->ComputeParametersCount();
871 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
872 function, length);
873 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
874
875 // Copy the parameters to the arguments object.
876 DCHECK(array->length() == length);
877 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
878 arguments->set_elements(*array);
879
880 // Return the freshly allocated arguments object.
881 return arguments;
Steve Blocka7e24c12009-10-30 11:49:00 +0000882 }
883
884 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000885 return isolate->factory()->null_value();
Steve Blocka7e24c12009-10-30 11:49:00 +0000886}
887
Ben Murdoch097c5b22016-05-18 11:27:45 +0100888} // namespace
Steve Blocka7e24c12009-10-30 11:49:00 +0000889
Ben Murdoch097c5b22016-05-18 11:27:45 +0100890
891Handle<JSObject> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
892 Handle<Object> arguments =
893 GetFunctionArguments(function->GetIsolate(), function);
894 CHECK(arguments->IsJSObject());
895 return Handle<JSObject>::cast(arguments);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000896}
897
898
899void Accessors::FunctionArgumentsGetter(
900 v8::Local<v8::Name> name,
901 const v8::PropertyCallbackInfo<v8::Value>& info) {
902 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
903 HandleScope scope(isolate);
904 Handle<JSFunction> function =
905 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100906 Handle<Object> result =
907 function->shared()->native()
908 ? Handle<Object>::cast(isolate->factory()->null_value())
909 : GetFunctionArguments(isolate, function);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000910 info.GetReturnValue().Set(Utils::ToLocal(result));
911}
912
913
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000914Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
915 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100916 return MakeAccessor(isolate, isolate->factory()->arguments_string(),
917 &FunctionArgumentsGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000918}
Steve Blocka7e24c12009-10-30 11:49:00 +0000919
920
921//
922// Accessors::FunctionCaller
923//
924
925
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000926static inline bool AllowAccessToFunction(Context* current_context,
927 JSFunction* function) {
928 return current_context->HasSameSecurityTokenAs(function->context());
Steve Block44f0eee2011-05-26 01:26:41 +0100929}
930
931
Ben Murdoch257744e2011-11-30 15:57:28 +0000932class FrameFunctionIterator {
933 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000934 FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
935 : isolate_(isolate),
936 frame_iterator_(isolate),
Ben Murdoch257744e2011-11-30 15:57:28 +0000937 functions_(2),
938 index_(0) {
939 GetFunctions();
940 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000941 JSFunction* next() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000942 while (true) {
943 if (functions_.length() == 0) return NULL;
944 JSFunction* next_function = functions_[index_];
945 index_--;
946 if (index_ < 0) {
947 GetFunctions();
948 }
949 // Skip functions from other origins.
950 if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
951 return next_function;
Ben Murdoch257744e2011-11-30 15:57:28 +0000952 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000953 }
954
955 // Iterate through functions until the first occurence of 'function'.
956 // Returns true if 'function' is found, and false if the iterator ends
957 // without finding it.
958 bool Find(JSFunction* function) {
959 JSFunction* next_function;
960 do {
961 next_function = next();
962 if (next_function == function) return true;
963 } while (next_function != NULL);
964 return false;
965 }
Ben Murdoch589d6972011-11-30 16:04:58 +0000966
Ben Murdoch257744e2011-11-30 15:57:28 +0000967 private:
968 void GetFunctions() {
969 functions_.Rewind(0);
970 if (frame_iterator_.done()) return;
971 JavaScriptFrame* frame = frame_iterator_.frame();
972 frame->GetFunctions(&functions_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000973 DCHECK(functions_.length() > 0);
Ben Murdoch257744e2011-11-30 15:57:28 +0000974 frame_iterator_.Advance();
975 index_ = functions_.length() - 1;
976 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000977 Isolate* isolate_;
Ben Murdoch257744e2011-11-30 15:57:28 +0000978 JavaScriptFrameIterator frame_iterator_;
979 List<JSFunction*> functions_;
980 int index_;
981};
982
983
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000984MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
985 Handle<JSFunction> function) {
986 DisallowHeapAllocation no_allocation;
987 FrameFunctionIterator it(isolate, no_allocation);
988 if (function->shared()->native()) {
989 return MaybeHandle<JSFunction>();
990 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000991 // Find the function from the frames.
992 if (!it.Find(*function)) {
993 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000994 return MaybeHandle<JSFunction>();
Steve Blocka7e24c12009-10-30 11:49:00 +0000995 }
Ben Murdoch257744e2011-11-30 15:57:28 +0000996 // Find previously called non-toplevel function.
997 JSFunction* caller;
998 do {
999 caller = it.next();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001000 if (caller == NULL) return MaybeHandle<JSFunction>();
Ben Murdoch257744e2011-11-30 15:57:28 +00001001 } while (caller->shared()->is_toplevel());
1002
1003 // If caller is a built-in function and caller's caller is also built-in,
1004 // use that instead.
1005 JSFunction* potential_caller = caller;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001006 while (potential_caller != NULL && potential_caller->shared()->IsBuiltin()) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001007 caller = potential_caller;
1008 potential_caller = it.next();
1009 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001010 if (!caller->shared()->native() && potential_caller != NULL) {
1011 caller = potential_caller;
1012 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001013 // Censor if the caller is not a sloppy mode function.
1014 // Change from ES5, which used to throw, see:
1015 // https://bugs.ecmascript.org/show_bug.cgi?id=310
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001016 if (is_strict(caller->shared()->language_mode())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001017 return MaybeHandle<JSFunction>();
1018 }
1019 // Don't return caller from another security context.
1020 if (!AllowAccessToFunction(isolate->context(), caller)) {
1021 return MaybeHandle<JSFunction>();
1022 }
1023 return Handle<JSFunction>(caller);
Steve Blocka7e24c12009-10-30 11:49:00 +00001024}
1025
1026
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001027void Accessors::FunctionCallerGetter(
1028 v8::Local<v8::Name> name,
1029 const v8::PropertyCallbackInfo<v8::Value>& info) {
1030 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1031 HandleScope scope(isolate);
1032 Handle<JSFunction> function =
1033 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1034 Handle<Object> result;
1035 MaybeHandle<JSFunction> maybe_caller;
1036 maybe_caller = FindCaller(isolate, function);
1037 Handle<JSFunction> caller;
1038 if (maybe_caller.ToHandle(&caller)) {
1039 result = caller;
1040 } else {
1041 result = isolate->factory()->null_value();
1042 }
1043 info.GetReturnValue().Set(Utils::ToLocal(result));
1044}
1045
1046
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001047Handle<AccessorInfo> Accessors::FunctionCallerInfo(
1048 Isolate* isolate, PropertyAttributes attributes) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001049 return MakeAccessor(isolate, isolate->factory()->caller_string(),
1050 &FunctionCallerGetter, nullptr, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001051}
Steve Blocka7e24c12009-10-30 11:49:00 +00001052
1053
1054//
Ben Murdochc5610432016-08-08 18:44:38 +01001055// Accessors::BoundFunctionLength
1056//
1057
1058void Accessors::BoundFunctionLengthGetter(
1059 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
1060 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1061 HandleScope scope(isolate);
1062 Handle<JSBoundFunction> function =
1063 Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder()));
1064
1065 Handle<Smi> target_length;
1066 Handle<JSFunction> target(JSFunction::cast(function->bound_target_function()),
1067 isolate);
1068 if (!JSFunction::GetLength(isolate, target).ToHandle(&target_length)) {
1069 target_length = handle(Smi::FromInt(0), isolate);
1070 isolate->OptionalRescheduleException(false);
1071 return;
1072 }
1073
1074 int bound_length = function->bound_arguments()->length();
1075 int length = Max(0, target_length->value() - bound_length);
1076
1077 Handle<Object> result(Smi::FromInt(length), isolate);
1078 info.GetReturnValue().Set(Utils::ToLocal(result));
1079}
1080
1081Handle<AccessorInfo> Accessors::BoundFunctionLengthInfo(
1082 Isolate* isolate, PropertyAttributes attributes) {
1083 return MakeAccessor(isolate, isolate->factory()->length_string(),
1084 &BoundFunctionLengthGetter, &ReconfigureToDataProperty,
1085 attributes);
1086}
1087
1088//
1089// Accessors::BoundFunctionName
1090//
1091
1092void Accessors::BoundFunctionNameGetter(
1093 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
1094 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1095 HandleScope scope(isolate);
1096 Handle<JSBoundFunction> function =
1097 Handle<JSBoundFunction>::cast(Utils::OpenHandle(*info.Holder()));
1098 Handle<Object> result;
1099 if (!JSBoundFunction::GetName(isolate, function).ToHandle(&result)) {
1100 isolate->OptionalRescheduleException(false);
1101 return;
1102 }
1103 info.GetReturnValue().Set(Utils::ToLocal(result));
1104}
1105
1106Handle<AccessorInfo> Accessors::BoundFunctionNameInfo(
1107 Isolate* isolate, PropertyAttributes attributes) {
1108 return MakeAccessor(isolate, isolate->factory()->name_string(),
1109 &BoundFunctionNameGetter, &ReconfigureToDataProperty,
1110 attributes);
1111}
1112
1113//
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001114// Accessors::MakeModuleExport
Steve Blocka7e24c12009-10-30 11:49:00 +00001115//
1116
Ben Murdoch097c5b22016-05-18 11:27:45 +01001117static void ModuleGetExport(v8::Local<v8::Name> property,
1118 const v8::PropertyCallbackInfo<v8::Value>& info) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001119 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
1120 Context* context = Context::cast(instance->context());
1121 DCHECK(context->IsModuleContext());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001122 Isolate* isolate = instance->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001123 int slot = info.Data()
1124 ->Int32Value(info.GetIsolate()->GetCurrentContext())
1125 .FromMaybe(-1);
1126 if (slot < 0 || slot >= context->length()) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001127 Handle<Name> name = v8::Utils::OpenHandle(*property);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001128
1129 Handle<Object> exception = isolate->factory()->NewReferenceError(
1130 MessageTemplate::kNotDefined, name);
1131 isolate->ScheduleThrow(*exception);
1132 return;
1133 }
1134 Object* value = context->get(slot);
Ben Murdoch61f157c2016-09-16 13:49:30 +01001135 if (value->IsTheHole(isolate)) {
Ben Murdoch097c5b22016-05-18 11:27:45 +01001136 Handle<Name> name = v8::Utils::OpenHandle(*property);
Steve Blocka7e24c12009-10-30 11:49:00 +00001137
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001138 Handle<Object> exception = isolate->factory()->NewReferenceError(
1139 MessageTemplate::kNotDefined, name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001140 isolate->ScheduleThrow(*exception);
1141 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001142 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001143 info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001144}
1145
1146
Ben Murdoch097c5b22016-05-18 11:27:45 +01001147static void ModuleSetExport(v8::Local<v8::Name> property,
1148 v8::Local<v8::Value> value,
1149 const v8::PropertyCallbackInfo<void>& info) {
1150 if (!info.ShouldThrowOnError()) return;
1151 Handle<Name> name = v8::Utils::OpenHandle(*property);
1152 Isolate* isolate = name->GetIsolate();
1153 Handle<Object> exception =
1154 isolate->factory()->NewTypeError(MessageTemplate::kNotDefined, name);
1155 isolate->ScheduleThrow(*exception);
Steve Blocka7e24c12009-10-30 11:49:00 +00001156}
1157
1158
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001159Handle<AccessorInfo> Accessors::MakeModuleExport(
1160 Handle<String> name,
1161 int index,
1162 PropertyAttributes attributes) {
1163 Isolate* isolate = name->GetIsolate();
Ben Murdoch097c5b22016-05-18 11:27:45 +01001164 Handle<AccessorInfo> info = MakeAccessor(isolate, name, &ModuleGetExport,
1165 &ModuleSetExport, attributes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001166 info->set_data(Smi::FromInt(index));
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001167 return info;
1168}
1169
Steve Blocka7e24c12009-10-30 11:49:00 +00001170
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001171} // namespace internal
1172} // namespace v8