blob: 2094cdb20db7648f926ec11f5ef0b06e49f700b5 [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();
30 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
31 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 Murdochb8a8cc12014-11-26 15:28:44 +000035 info->set_name(*name);
36 Handle<Object> get = v8::FromCData(isolate, getter);
37 Handle<Object> set = v8::FromCData(isolate, setter);
38 info->set_getter(*get);
39 info->set_setter(*set);
40 return info;
Steve Blocka7e24c12009-10-30 11:49:00 +000041}
42
43
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044Handle<ExecutableAccessorInfo> Accessors::CloneAccessor(
45 Isolate* isolate,
46 Handle<ExecutableAccessorInfo> accessor) {
47 Factory* factory = isolate->factory();
48 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
49 info->set_name(accessor->name());
50 info->set_flag(accessor->flag());
51 info->set_expected_receiver_type(accessor->expected_receiver_type());
52 info->set_getter(accessor->getter());
53 info->set_setter(accessor->setter());
54 info->set_data(accessor->data());
55 return info;
56}
57
58
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059static V8_INLINE bool CheckForName(Handle<Name> name,
60 Handle<String> property_name,
61 int offset,
62 int* object_offset) {
63 if (Name::Equals(name, property_name)) {
64 *object_offset = offset;
65 return true;
66 }
67 return false;
Steve Blocka7e24c12009-10-30 11:49:00 +000068}
69
70
Ben Murdochb8a8cc12014-11-26 15:28:44 +000071// Returns true for properties that are accessors to object fields.
72// If true, *object_offset contains offset of object field.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000073bool Accessors::IsJSObjectFieldAccessor(Handle<Map> map, Handle<Name> name,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000074 int* object_offset) {
75 Isolate* isolate = name->GetIsolate();
76
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077 switch (map->instance_type()) {
78 case JS_ARRAY_TYPE:
79 return
80 CheckForName(name, isolate->factory()->length_string(),
81 JSArray::kLengthOffset, object_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000082 case JS_ARRAY_BUFFER_TYPE:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000083 return CheckForName(name, isolate->factory()->byte_length_string(),
84 JSArrayBuffer::kByteLengthOffset, object_offset);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000085 default:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000086 if (map->instance_type() < FIRST_NONSTRING_TYPE) {
87 return CheckForName(name, isolate->factory()->length_string(),
88 String::kLengthOffset, object_offset);
89 }
90
Ben Murdochb8a8cc12014-11-26 15:28:44 +000091 return false;
92 }
93}
94
95
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000096bool Accessors::IsJSArrayBufferViewFieldAccessor(Handle<Map> map,
97 Handle<Name> name,
98 int* object_offset) {
99 Isolate* isolate = name->GetIsolate();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 switch (map->instance_type()) {
102 case JS_TYPED_ARRAY_TYPE: {
103 if (!CheckForName(name, isolate->factory()->length_string(),
104 JSTypedArray::kLengthOffset, object_offset) &&
105 !CheckForName(name, isolate->factory()->byte_length_string(),
106 JSTypedArray::kByteLengthOffset, object_offset) &&
107 !CheckForName(name, isolate->factory()->byte_offset_string(),
108 JSTypedArray::kByteOffsetOffset, object_offset)) {
109 return false;
110 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 if (map->is_dictionary_map()) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000114 // Check if the property is overridden on the instance.
115 DescriptorArray* descriptors = map->instance_descriptors();
116 int descriptor = descriptors->SearchWithCache(*name, *map);
117 if (descriptor != DescriptorArray::kNotFound) return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119 Handle<Object> proto = Handle<Object>(map->prototype(), isolate);
120 if (!proto->IsJSReceiver()) return false;
121
122 // Check if the property is defined in the prototype chain.
123 LookupIterator it(proto, name);
124 if (!it.IsFound()) return false;
125
126 Object* original_proto =
127 JSFunction::cast(map->GetConstructor())->prototype();
128
129 // Property is not configurable. It is enough to verify that
130 // the holder is the same.
131 return *it.GetHolder<Object>() == original_proto;
132 }
133 case JS_DATA_VIEW_TYPE:
134 return CheckForName(name, isolate->factory()->byte_length_string(),
135 JSDataView::kByteLengthOffset, object_offset) ||
136 CheckForName(name, isolate->factory()->byte_offset_string(),
137 JSDataView::kByteOffsetOffset, object_offset);
138 default:
139 return false;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000140 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141}
142
143
144//
145// Accessors::ArgumentsIterator
146//
147
148
149void Accessors::ArgumentsIteratorGetter(
150 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
151 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
152 DisallowHeapAllocation no_allocation;
153 HandleScope scope(isolate);
154 Object* result = isolate->native_context()->array_values_iterator();
155 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
156}
157
158
159void Accessors::ArgumentsIteratorSetter(
160 v8::Local<v8::Name> name, v8::Local<v8::Value> val,
161 const v8::PropertyCallbackInfo<void>& info) {
162 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
163 HandleScope scope(isolate);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000164 Handle<JSObject> object_handle =
165 Handle<JSObject>::cast(Utils::OpenHandle(*info.This()));
166 Handle<Object> value_handle = Utils::OpenHandle(*val);
167 Handle<Name> name_handle = Utils::OpenHandle(*name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000168
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000169 if (JSObject::DefinePropertyOrElementIgnoreAttributes(
170 object_handle, name_handle, value_handle, NONE)
171 .is_null()) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400172 isolate->OptionalRescheduleException(false);
173 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000174}
175
176
177Handle<AccessorInfo> Accessors::ArgumentsIteratorInfo(
178 Isolate* isolate, PropertyAttributes attributes) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400179 Handle<Name> name = isolate->factory()->iterator_symbol();
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 return MakeAccessor(isolate, name, &ArgumentsIteratorGetter,
181 &ArgumentsIteratorSetter, attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000182}
183
184
185//
186// Accessors::ArrayLength
187//
188
189
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000190void Accessors::ArrayLengthGetter(
191 v8::Local<v8::Name> name,
192 const v8::PropertyCallbackInfo<v8::Value>& info) {
193 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
194 DisallowHeapAllocation no_allocation;
Steve Block44f0eee2011-05-26 01:26:41 +0100195 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000196 JSArray* holder = JSArray::cast(*Utils::OpenHandle(*info.Holder()));
197 Object* result = holder->length();
198 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000199}
200
201
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000202void Accessors::ArrayLengthSetter(
203 v8::Local<v8::Name> name,
204 v8::Local<v8::Value> val,
205 const v8::PropertyCallbackInfo<void>& info) {
206 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
207 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209 Handle<JSReceiver> object = Utils::OpenHandle(*info.This());
210 Handle<JSArray> array = Handle<JSArray>::cast(object);
211 Handle<Object> length_obj = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000212
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000213 uint32_t length = 0;
214 if (!JSArray::AnythingToArrayLength(isolate, length_obj, &length)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000215 isolate->OptionalRescheduleException(false);
216 return;
217 }
218
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 if (JSArray::ObservableSetLength(array, length).is_null()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000220 isolate->OptionalRescheduleException(false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000221 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000222}
223
224
225Handle<AccessorInfo> Accessors::ArrayLengthInfo(
226 Isolate* isolate, PropertyAttributes attributes) {
227 return MakeAccessor(isolate,
228 isolate->factory()->length_string(),
229 &ArrayLengthGetter,
230 &ArrayLengthSetter,
231 attributes);
232}
233
Steve Blocka7e24c12009-10-30 11:49:00 +0000234
Steve Blocka7e24c12009-10-30 11:49:00 +0000235//
236// Accessors::StringLength
237//
238
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000239void Accessors::StringLengthGetter(
240 v8::Local<v8::Name> name,
241 const v8::PropertyCallbackInfo<v8::Value>& info) {
242 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
243 DisallowHeapAllocation no_allocation;
244 HandleScope scope(isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000245
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000246 // We have a slight impedance mismatch between the external API and the way we
247 // use callbacks internally: Externally, callbacks can only be used with
248 // v8::Object, but internally we have callbacks on entities which are higher
249 // in the hierarchy, in this case for String values.
250
251 Object* value = *Utils::OpenHandle(*v8::Local<v8::Value>(info.This()));
252 if (!value->IsString()) {
253 // Not a string value. That means that we either got a String wrapper or
254 // a Value with a String wrapper in its prototype chain.
255 value = JSValue::cast(*Utils::OpenHandle(*info.Holder()))->value();
256 }
257 Object* result = Smi::FromInt(String::cast(value)->length());
258 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000259}
260
261
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000262void Accessors::StringLengthSetter(
263 v8::Local<v8::Name> name,
264 v8::Local<v8::Value> value,
265 const v8::PropertyCallbackInfo<void>& info) {
266 UNREACHABLE();
Steve Blocka7e24c12009-10-30 11:49:00 +0000267}
268
269
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000270Handle<AccessorInfo> Accessors::StringLengthInfo(
271 Isolate* isolate, PropertyAttributes attributes) {
272 return MakeAccessor(isolate,
273 isolate->factory()->length_string(),
274 &StringLengthGetter,
275 &StringLengthSetter,
276 attributes);
Steve Blocka7e24c12009-10-30 11:49:00 +0000277}
278
279
Steve Blocka7e24c12009-10-30 11:49:00 +0000280//
281// Accessors::ScriptColumnOffset
282//
283
284
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000285void Accessors::ScriptColumnOffsetGetter(
286 v8::Local<v8::Name> name,
287 const v8::PropertyCallbackInfo<v8::Value>& info) {
288 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
289 DisallowHeapAllocation no_allocation;
290 HandleScope scope(isolate);
291 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000292 Object* res = Smi::FromInt(
293 Script::cast(JSValue::cast(object)->value())->column_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000294 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000295}
296
297
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000298void Accessors::ScriptColumnOffsetSetter(
299 v8::Local<v8::Name> name,
300 v8::Local<v8::Value> value,
301 const v8::PropertyCallbackInfo<void>& info) {
302 UNREACHABLE();
Steve Blocka7e24c12009-10-30 11:49:00 +0000303}
304
305
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000306Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo(
307 Isolate* isolate, PropertyAttributes attributes) {
308 Handle<String> name(isolate->factory()->InternalizeOneByteString(
309 STATIC_CHAR_VECTOR("column_offset")));
310 return MakeAccessor(isolate,
311 name,
312 &ScriptColumnOffsetGetter,
313 &ScriptColumnOffsetSetter,
314 attributes);
315}
316
317
318//
319// Accessors::ScriptId
320//
321
322
323void Accessors::ScriptIdGetter(
324 v8::Local<v8::Name> name,
325 const v8::PropertyCallbackInfo<v8::Value>& info) {
326 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
327 DisallowHeapAllocation no_allocation;
328 HandleScope scope(isolate);
329 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000330 Object* id = Smi::FromInt(Script::cast(JSValue::cast(object)->value())->id());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000331 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate)));
332}
333
334
335void Accessors::ScriptIdSetter(
336 v8::Local<v8::Name> name,
337 v8::Local<v8::Value> value,
338 const v8::PropertyCallbackInfo<void>& info) {
339 UNREACHABLE();
340}
341
342
343Handle<AccessorInfo> Accessors::ScriptIdInfo(
344 Isolate* isolate, PropertyAttributes attributes) {
345 Handle<String> name(
346 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("id")));
347 return MakeAccessor(isolate,
348 name,
349 &ScriptIdGetter,
350 &ScriptIdSetter,
351 attributes);
352}
353
354
355//
356// Accessors::ScriptName
357//
358
359
360void Accessors::ScriptNameGetter(
361 v8::Local<v8::Name> name,
362 const v8::PropertyCallbackInfo<v8::Value>& info) {
363 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
364 DisallowHeapAllocation no_allocation;
365 HandleScope scope(isolate);
366 Object* object = *Utils::OpenHandle(*info.This());
367 Object* source = Script::cast(JSValue::cast(object)->value())->name();
368 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
369}
370
371
372void Accessors::ScriptNameSetter(
373 v8::Local<v8::Name> name,
374 v8::Local<v8::Value> value,
375 const v8::PropertyCallbackInfo<void>& info) {
376 UNREACHABLE();
377}
378
379
380Handle<AccessorInfo> Accessors::ScriptNameInfo(
381 Isolate* isolate, PropertyAttributes attributes) {
382 return MakeAccessor(isolate,
383 isolate->factory()->name_string(),
384 &ScriptNameGetter,
385 &ScriptNameSetter,
386 attributes);
387}
388
389
390//
391// Accessors::ScriptSource
392//
393
394
395void Accessors::ScriptSourceGetter(
396 v8::Local<v8::Name> name,
397 const v8::PropertyCallbackInfo<v8::Value>& info) {
398 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
399 DisallowHeapAllocation no_allocation;
400 HandleScope scope(isolate);
401 Object* object = *Utils::OpenHandle(*info.This());
402 Object* source = Script::cast(JSValue::cast(object)->value())->source();
403 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate)));
404}
405
406
407void Accessors::ScriptSourceSetter(
408 v8::Local<v8::Name> name,
409 v8::Local<v8::Value> value,
410 const v8::PropertyCallbackInfo<void>& info) {
411 UNREACHABLE();
412}
413
414
415Handle<AccessorInfo> Accessors::ScriptSourceInfo(
416 Isolate* isolate, PropertyAttributes attributes) {
417 return MakeAccessor(isolate,
418 isolate->factory()->source_string(),
419 &ScriptSourceGetter,
420 &ScriptSourceSetter,
421 attributes);
422}
423
424
425//
426// Accessors::ScriptLineOffset
427//
428
429
430void Accessors::ScriptLineOffsetGetter(
431 v8::Local<v8::Name> name,
432 const v8::PropertyCallbackInfo<v8::Value>& info) {
433 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
434 DisallowHeapAllocation no_allocation;
435 HandleScope scope(isolate);
436 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000437 Object* res =
438 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->line_offset());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000439 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
440}
441
442
443void Accessors::ScriptLineOffsetSetter(
444 v8::Local<v8::Name> name,
445 v8::Local<v8::Value> value,
446 const v8::PropertyCallbackInfo<void>& info) {
447 UNREACHABLE();
448}
449
450
451Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo(
452 Isolate* isolate, PropertyAttributes attributes) {
453 Handle<String> name(isolate->factory()->InternalizeOneByteString(
454 STATIC_CHAR_VECTOR("line_offset")));
455 return MakeAccessor(isolate,
456 name,
457 &ScriptLineOffsetGetter,
458 &ScriptLineOffsetSetter,
459 attributes);
460}
Steve Blocka7e24c12009-10-30 11:49:00 +0000461
462
463//
464// Accessors::ScriptType
465//
466
467
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000468void Accessors::ScriptTypeGetter(
469 v8::Local<v8::Name> name,
470 const v8::PropertyCallbackInfo<v8::Value>& info) {
471 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
472 DisallowHeapAllocation no_allocation;
473 HandleScope scope(isolate);
474 Object* object = *Utils::OpenHandle(*info.This());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000475 Object* res =
476 Smi::FromInt(Script::cast(JSValue::cast(object)->value())->type());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000477 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000478}
479
480
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000481void Accessors::ScriptTypeSetter(
482 v8::Local<v8::Name> name,
483 v8::Local<v8::Value> value,
484 const v8::PropertyCallbackInfo<void>& info) {
485 UNREACHABLE();
486}
487
488
489Handle<AccessorInfo> Accessors::ScriptTypeInfo(
490 Isolate* isolate, PropertyAttributes attributes) {
491 Handle<String> name(
492 isolate->factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("type")));
493 return MakeAccessor(isolate,
494 name,
495 &ScriptTypeGetter,
496 &ScriptTypeSetter,
497 attributes);
498}
Steve Blocka7e24c12009-10-30 11:49:00 +0000499
500
501//
502// Accessors::ScriptCompilationType
503//
504
505
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000506void Accessors::ScriptCompilationTypeGetter(
507 v8::Local<v8::Name> name,
508 const v8::PropertyCallbackInfo<v8::Value>& info) {
509 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
510 DisallowHeapAllocation no_allocation;
511 HandleScope scope(isolate);
512 Object* object = *Utils::OpenHandle(*info.This());
513 Object* res = Smi::FromInt(
514 Script::cast(JSValue::cast(object)->value())->compilation_type());
515 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000516}
517
518
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000519void Accessors::ScriptCompilationTypeSetter(
520 v8::Local<v8::Name> name,
521 v8::Local<v8::Value> value,
522 const v8::PropertyCallbackInfo<void>& info) {
523 UNREACHABLE();
524}
525
526
527Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo(
528 Isolate* isolate, PropertyAttributes attributes) {
529 Handle<String> name(isolate->factory()->InternalizeOneByteString(
530 STATIC_CHAR_VECTOR("compilation_type")));
531 return MakeAccessor(isolate,
532 name,
533 &ScriptCompilationTypeGetter,
534 &ScriptCompilationTypeSetter,
535 attributes);
536}
Steve Blocka7e24c12009-10-30 11:49:00 +0000537
538
539//
540// Accessors::ScriptGetLineEnds
541//
542
543
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000544void Accessors::ScriptLineEndsGetter(
545 v8::Local<v8::Name> name,
546 const v8::PropertyCallbackInfo<v8::Value>& info) {
547 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
Steve Block44f0eee2011-05-26 01:26:41 +0100548 HandleScope scope(isolate);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000549 Handle<Object> object = Utils::OpenHandle(*info.This());
550 Handle<Script> script(
551 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
552 Script::InitLineEnds(script);
553 DCHECK(script->line_ends()->IsFixedArray());
Steve Blockd0582a62009-12-15 09:54:21 +0000554 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800555 // We do not want anyone to modify this array from JS.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000556 DCHECK(*line_ends == isolate->heap()->empty_fixed_array() ||
Steve Block44f0eee2011-05-26 01:26:41 +0100557 line_ends->map() == isolate->heap()->fixed_cow_array_map());
558 Handle<JSArray> js_array =
559 isolate->factory()->NewJSArrayWithElements(line_ends);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000560 info.GetReturnValue().Set(Utils::ToLocal(js_array));
Steve Blocka7e24c12009-10-30 11:49:00 +0000561}
562
563
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000564void Accessors::ScriptLineEndsSetter(
565 v8::Local<v8::Name> name,
566 v8::Local<v8::Value> value,
567 const v8::PropertyCallbackInfo<void>& info) {
568 UNREACHABLE();
569}
570
571
572Handle<AccessorInfo> Accessors::ScriptLineEndsInfo(
573 Isolate* isolate, PropertyAttributes attributes) {
574 Handle<String> name(isolate->factory()->InternalizeOneByteString(
575 STATIC_CHAR_VECTOR("line_ends")));
576 return MakeAccessor(isolate,
577 name,
578 &ScriptLineEndsGetter,
579 &ScriptLineEndsSetter,
580 attributes);
581}
582
583
584//
585// Accessors::ScriptSourceUrl
586//
587
588
589void Accessors::ScriptSourceUrlGetter(
590 v8::Local<v8::Name> name,
591 const v8::PropertyCallbackInfo<v8::Value>& info) {
592 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
593 DisallowHeapAllocation no_allocation;
594 HandleScope scope(isolate);
595 Object* object = *Utils::OpenHandle(*info.This());
596 Object* url = Script::cast(JSValue::cast(object)->value())->source_url();
597 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
598}
599
600
601void Accessors::ScriptSourceUrlSetter(
602 v8::Local<v8::Name> name,
603 v8::Local<v8::Value> value,
604 const v8::PropertyCallbackInfo<void>& info) {
605 UNREACHABLE();
606}
607
608
609Handle<AccessorInfo> Accessors::ScriptSourceUrlInfo(
610 Isolate* isolate, PropertyAttributes attributes) {
611 return MakeAccessor(isolate,
612 isolate->factory()->source_url_string(),
613 &ScriptSourceUrlGetter,
614 &ScriptSourceUrlSetter,
615 attributes);
616}
617
618
619//
620// Accessors::ScriptSourceMappingUrl
621//
622
623
624void Accessors::ScriptSourceMappingUrlGetter(
625 v8::Local<v8::Name> name,
626 const v8::PropertyCallbackInfo<v8::Value>& info) {
627 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
628 DisallowHeapAllocation no_allocation;
629 HandleScope scope(isolate);
630 Object* object = *Utils::OpenHandle(*info.This());
631 Object* url =
632 Script::cast(JSValue::cast(object)->value())->source_mapping_url();
633 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(url, isolate)));
634}
635
636
637void Accessors::ScriptSourceMappingUrlSetter(
638 v8::Local<v8::Name> name,
639 v8::Local<v8::Value> value,
640 const v8::PropertyCallbackInfo<void>& info) {
641 UNREACHABLE();
642}
643
644
645Handle<AccessorInfo> Accessors::ScriptSourceMappingUrlInfo(
646 Isolate* isolate, PropertyAttributes attributes) {
647 return MakeAccessor(isolate,
648 isolate->factory()->source_mapping_url_string(),
649 &ScriptSourceMappingUrlGetter,
650 &ScriptSourceMappingUrlSetter,
651 attributes);
652}
Steve Blocka7e24c12009-10-30 11:49:00 +0000653
654
655//
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000656// Accessors::ScriptIsEmbedderDebugScript
657//
658
659
660void Accessors::ScriptIsEmbedderDebugScriptGetter(
661 v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
662 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
663 DisallowHeapAllocation no_allocation;
664 HandleScope scope(isolate);
665 Object* object = *Utils::OpenHandle(*info.This());
666 bool is_embedder_debug_script = Script::cast(JSValue::cast(object)->value())
667 ->origin_options()
668 .IsEmbedderDebugScript();
669 Object* res = *isolate->factory()->ToBoolean(is_embedder_debug_script);
670 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
671}
672
673
674void Accessors::ScriptIsEmbedderDebugScriptSetter(
675 v8::Local<v8::Name> name, v8::Local<v8::Value> value,
676 const v8::PropertyCallbackInfo<void>& info) {
677 UNREACHABLE();
678}
679
680
681Handle<AccessorInfo> Accessors::ScriptIsEmbedderDebugScriptInfo(
682 Isolate* isolate, PropertyAttributes attributes) {
683 Handle<String> name(isolate->factory()->InternalizeOneByteString(
684 STATIC_CHAR_VECTOR("is_debugger_script")));
685 return MakeAccessor(isolate, name, &ScriptIsEmbedderDebugScriptGetter,
686 &ScriptIsEmbedderDebugScriptSetter, attributes);
687}
688
689
690//
Steve Blocka7e24c12009-10-30 11:49:00 +0000691// Accessors::ScriptGetContextData
692//
693
694
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000695void Accessors::ScriptContextDataGetter(
696 v8::Local<v8::Name> name,
697 const v8::PropertyCallbackInfo<v8::Value>& info) {
698 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
699 DisallowHeapAllocation no_allocation;
700 HandleScope scope(isolate);
701 Object* object = *Utils::OpenHandle(*info.This());
702 Object* res = Script::cast(JSValue::cast(object)->value())->context_data();
703 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +0000704}
705
706
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000707void Accessors::ScriptContextDataSetter(
708 v8::Local<v8::Name> name,
709 v8::Local<v8::Value> value,
710 const v8::PropertyCallbackInfo<void>& info) {
711 UNREACHABLE();
712}
713
714
715Handle<AccessorInfo> Accessors::ScriptContextDataInfo(
716 Isolate* isolate, PropertyAttributes attributes) {
717 Handle<String> name(isolate->factory()->InternalizeOneByteString(
718 STATIC_CHAR_VECTOR("context_data")));
719 return MakeAccessor(isolate,
720 name,
721 &ScriptContextDataGetter,
722 &ScriptContextDataSetter,
723 attributes);
724}
Steve Blocka7e24c12009-10-30 11:49:00 +0000725
726
727//
Steve Blockd0582a62009-12-15 09:54:21 +0000728// Accessors::ScriptGetEvalFromScript
Steve Blocka7e24c12009-10-30 11:49:00 +0000729//
730
731
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000732void Accessors::ScriptEvalFromScriptGetter(
733 v8::Local<v8::Name> name,
734 const v8::PropertyCallbackInfo<v8::Value>& info) {
735 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
736 HandleScope scope(isolate);
737 Handle<Object> object = Utils::OpenHandle(*info.This());
738 Handle<Script> script(
739 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
740 Handle<Object> result = isolate->factory()->undefined_value();
741 if (!script->eval_from_shared()->IsUndefined()) {
Steve Blockd0582a62009-12-15 09:54:21 +0000742 Handle<SharedFunctionInfo> eval_from_shared(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000743 SharedFunctionInfo::cast(script->eval_from_shared()));
Steve Blockd0582a62009-12-15 09:54:21 +0000744 if (eval_from_shared->script()->IsScript()) {
745 Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000746 result = Script::GetWrapper(eval_from_script);
Steve Blockd0582a62009-12-15 09:54:21 +0000747 }
748 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000749
750 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000751}
752
753
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000754void Accessors::ScriptEvalFromScriptSetter(
755 v8::Local<v8::Name> name,
756 v8::Local<v8::Value> value,
757 const v8::PropertyCallbackInfo<void>& info) {
758 UNREACHABLE();
759}
760
761
762Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo(
763 Isolate* isolate, PropertyAttributes attributes) {
764 Handle<String> name(isolate->factory()->InternalizeOneByteString(
765 STATIC_CHAR_VECTOR("eval_from_script")));
766 return MakeAccessor(isolate,
767 name,
768 &ScriptEvalFromScriptGetter,
769 &ScriptEvalFromScriptSetter,
770 attributes);
771}
Steve Blocka7e24c12009-10-30 11:49:00 +0000772
773
774//
Steve Blockd0582a62009-12-15 09:54:21 +0000775// Accessors::ScriptGetEvalFromScriptPosition
Steve Blocka7e24c12009-10-30 11:49:00 +0000776//
777
778
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000779void Accessors::ScriptEvalFromScriptPositionGetter(
780 v8::Local<v8::Name> name,
781 const v8::PropertyCallbackInfo<v8::Value>& info) {
782 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
783 HandleScope scope(isolate);
784 Handle<Object> object = Utils::OpenHandle(*info.This());
785 Handle<Script> script(
786 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
787 Handle<Object> result = isolate->factory()->undefined_value();
788 if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
789 Handle<Code> code(SharedFunctionInfo::cast(
790 script->eval_from_shared())->code());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000791 result = Handle<Object>(Smi::FromInt(code->SourcePosition(
792 code->instruction_start() +
793 script->eval_from_instructions_offset())),
794 isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000795 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000796 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000797}
798
799
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000800void Accessors::ScriptEvalFromScriptPositionSetter(
801 v8::Local<v8::Name> name,
802 v8::Local<v8::Value> value,
803 const v8::PropertyCallbackInfo<void>& info) {
804 UNREACHABLE();
805}
806
807
808Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo(
809 Isolate* isolate, PropertyAttributes attributes) {
810 Handle<String> name(isolate->factory()->InternalizeOneByteString(
811 STATIC_CHAR_VECTOR("eval_from_script_position")));
812 return MakeAccessor(isolate,
813 name,
814 &ScriptEvalFromScriptPositionGetter,
815 &ScriptEvalFromScriptPositionSetter,
816 attributes);
817}
Steve Blockd0582a62009-12-15 09:54:21 +0000818
819
820//
821// Accessors::ScriptGetEvalFromFunctionName
822//
823
824
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825void Accessors::ScriptEvalFromFunctionNameGetter(
826 v8::Local<v8::Name> name,
827 const v8::PropertyCallbackInfo<v8::Value>& info) {
828 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
829 HandleScope scope(isolate);
830 Handle<Object> object = Utils::OpenHandle(*info.This());
831 Handle<Script> script(
832 Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
833 Handle<Object> result;
834 Handle<SharedFunctionInfo> shared(
835 SharedFunctionInfo::cast(script->eval_from_shared()));
Steve Blockd0582a62009-12-15 09:54:21 +0000836 // Find the name of the function calling eval.
837 if (!shared->name()->IsUndefined()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000838 result = Handle<Object>(shared->name(), isolate);
Steve Blockd0582a62009-12-15 09:54:21 +0000839 } else {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000840 result = Handle<Object>(shared->inferred_name(), isolate);
Steve Blockd0582a62009-12-15 09:54:21 +0000841 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000842 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blockd0582a62009-12-15 09:54:21 +0000843}
844
845
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000846void Accessors::ScriptEvalFromFunctionNameSetter(
847 v8::Local<v8::Name> name,
848 v8::Local<v8::Value> value,
849 const v8::PropertyCallbackInfo<void>& info) {
850 UNREACHABLE();
851}
852
853
854Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo(
855 Isolate* isolate, PropertyAttributes attributes) {
856 Handle<String> name(isolate->factory()->InternalizeOneByteString(
857 STATIC_CHAR_VECTOR("eval_from_function_name")));
858 return MakeAccessor(isolate,
859 name,
860 &ScriptEvalFromFunctionNameGetter,
861 &ScriptEvalFromFunctionNameSetter,
862 attributes);
863}
Steve Blocka7e24c12009-10-30 11:49:00 +0000864
865
866//
867// Accessors::FunctionPrototype
868//
869
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000870static Handle<Object> GetFunctionPrototype(Isolate* isolate,
871 Handle<JSFunction> function) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000872 if (!function->has_prototype()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000873 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function);
874 JSFunction::SetPrototype(function, proto);
Steve Blocka7e24c12009-10-30 11:49:00 +0000875 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000876 return Handle<Object>(function->prototype(), isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000877}
878
879
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400880MUST_USE_RESULT static MaybeHandle<Object> SetFunctionPrototype(
881 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000882 Handle<Object> old_value;
883 bool is_observed = function->map()->is_observed();
884 if (is_observed) {
885 if (function->has_prototype())
886 old_value = handle(function->prototype(), isolate);
887 else
888 old_value = isolate->factory()->NewFunctionPrototype(function);
Ben Murdoche0cee9b2011-05-25 10:26:03 +0100889 }
890
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000891 JSFunction::SetPrototype(function, value);
892 DCHECK(function->prototype() == *value);
893
894 if (is_observed && !old_value->SameValue(*value)) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400895 MaybeHandle<Object> result = JSObject::EnqueueChangeRecord(
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000896 function, "update", isolate->factory()->prototype_string(), old_value);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400897 if (result.is_null()) return MaybeHandle<Object>();
John Reck59135872010-11-02 12:39:01 -0700898 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000899
Steve Blocka7e24c12009-10-30 11:49:00 +0000900 return function;
901}
902
903
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400904MaybeHandle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function,
905 Handle<Object> prototype) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000906 DCHECK(function->IsConstructor());
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000907 Isolate* isolate = function->GetIsolate();
908 return SetFunctionPrototype(isolate, function, prototype);
909}
910
911
912void Accessors::FunctionPrototypeGetter(
913 v8::Local<v8::Name> name,
914 const v8::PropertyCallbackInfo<v8::Value>& info) {
915 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
916 HandleScope scope(isolate);
917 Handle<JSFunction> function =
918 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
919 Handle<Object> result = GetFunctionPrototype(isolate, function);
920 info.GetReturnValue().Set(Utils::ToLocal(result));
921}
922
923
924void Accessors::FunctionPrototypeSetter(
925 v8::Local<v8::Name> name,
926 v8::Local<v8::Value> val,
927 const v8::PropertyCallbackInfo<void>& info) {
928 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
929 HandleScope scope(isolate);
930 Handle<Object> value = Utils::OpenHandle(*val);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000931 Handle<JSFunction> object =
932 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400933 if (SetFunctionPrototype(isolate, object, value).is_null()) {
934 isolate->OptionalRescheduleException(false);
935 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000936}
937
938
939Handle<AccessorInfo> Accessors::FunctionPrototypeInfo(
940 Isolate* isolate, PropertyAttributes attributes) {
941 return MakeAccessor(isolate,
942 isolate->factory()->prototype_string(),
943 &FunctionPrototypeGetter,
944 &FunctionPrototypeSetter,
945 attributes);
946}
Steve Blocka7e24c12009-10-30 11:49:00 +0000947
948
949//
950// Accessors::FunctionLength
951//
952
953
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000954void Accessors::FunctionLengthGetter(
955 v8::Local<v8::Name> name,
956 const v8::PropertyCallbackInfo<v8::Value>& info) {
957 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
958 HandleScope scope(isolate);
959 Handle<JSFunction> function =
960 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
961
962 int length = 0;
963 if (function->shared()->is_compiled()) {
964 length = function->shared()->length();
965 } else {
Steve Blocka7e24c12009-10-30 11:49:00 +0000966 // If the function isn't compiled yet, the length is not computed
967 // correctly yet. Compile it now and return the right length.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000968 if (Compiler::Compile(function, KEEP_EXCEPTION)) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000969 length = function->shared()->length();
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100970 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000971 if (isolate->has_pending_exception()) {
972 isolate->OptionalRescheduleException(false);
973 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000974 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000975 Handle<Object> result(Smi::FromInt(length), isolate);
976 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +0000977}
978
979
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000980MUST_USE_RESULT static MaybeHandle<Object> ReplaceAccessorWithDataProperty(
981 Isolate* isolate, Handle<JSObject> object, Handle<Name> name,
982 Handle<Object> value, bool is_observed, Handle<Object> old_value) {
983 LookupIterator it(object, name);
984 CHECK_EQ(LookupIterator::ACCESSOR, it.state());
985 DCHECK(it.HolderIsReceiverOrHiddenPrototype());
986 it.ReconfigureDataProperty(value, it.property_details().attributes());
987
988 if (is_observed && !old_value->SameValue(*value)) {
989 return JSObject::EnqueueChangeRecord(object, "update", name, old_value);
990 }
991
992 return value;
993}
994
995
996MUST_USE_RESULT static MaybeHandle<Object> SetFunctionLength(
997 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
998 Handle<Object> old_value;
999 bool is_observed = function->map()->is_observed();
1000 if (is_observed) {
1001 old_value = handle(Smi::FromInt(function->shared()->length()), isolate);
1002 }
1003
1004 return ReplaceAccessorWithDataProperty(isolate, function,
1005 isolate->factory()->length_string(),
1006 value, is_observed, old_value);
1007}
1008
1009
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001010void Accessors::FunctionLengthSetter(
1011 v8::Local<v8::Name> name,
1012 v8::Local<v8::Value> val,
1013 const v8::PropertyCallbackInfo<void>& info) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001014 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1015 HandleScope scope(isolate);
1016 Handle<Object> value = Utils::OpenHandle(*val);
1017
1018 Handle<JSFunction> object =
1019 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1020 if (SetFunctionLength(isolate, object, value).is_null()) {
1021 isolate->OptionalRescheduleException(false);
1022 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001023}
1024
1025
1026Handle<AccessorInfo> Accessors::FunctionLengthInfo(
1027 Isolate* isolate, PropertyAttributes attributes) {
1028 return MakeAccessor(isolate,
1029 isolate->factory()->length_string(),
1030 &FunctionLengthGetter,
1031 &FunctionLengthSetter,
1032 attributes);
1033}
Steve Blocka7e24c12009-10-30 11:49:00 +00001034
1035
1036//
1037// Accessors::FunctionName
1038//
1039
1040
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001041void Accessors::FunctionNameGetter(
1042 v8::Local<v8::Name> name,
1043 const v8::PropertyCallbackInfo<v8::Value>& info) {
1044 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1045 HandleScope scope(isolate);
1046 Handle<JSFunction> function =
1047 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001048 Handle<Object> result;
1049 if (function->shared()->name_should_print_as_anonymous()) {
1050 result = isolate->factory()->anonymous_string();
1051 } else {
1052 result = handle(function->shared()->name(), isolate);
1053 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001054 info.GetReturnValue().Set(Utils::ToLocal(result));
Steve Blocka7e24c12009-10-30 11:49:00 +00001055}
1056
1057
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001058MUST_USE_RESULT static MaybeHandle<Object> SetFunctionName(
1059 Isolate* isolate, Handle<JSFunction> function, Handle<Object> value) {
1060 Handle<Object> old_value;
1061 bool is_observed = function->map()->is_observed();
1062 if (is_observed) {
1063 old_value = handle(function->shared()->name(), isolate);
1064 }
1065
1066 return ReplaceAccessorWithDataProperty(isolate, function,
1067 isolate->factory()->name_string(),
1068 value, is_observed, old_value);
1069}
1070
1071
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001072void Accessors::FunctionNameSetter(
1073 v8::Local<v8::Name> name,
1074 v8::Local<v8::Value> val,
1075 const v8::PropertyCallbackInfo<void>& info) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001076 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1077 HandleScope scope(isolate);
1078 Handle<Object> value = Utils::OpenHandle(*val);
1079
1080 Handle<JSFunction> object =
1081 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1082 if (SetFunctionName(isolate, object, value).is_null()) {
1083 isolate->OptionalRescheduleException(false);
1084 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001085}
1086
1087
1088Handle<AccessorInfo> Accessors::FunctionNameInfo(
1089 Isolate* isolate, PropertyAttributes attributes) {
1090 return MakeAccessor(isolate,
1091 isolate->factory()->name_string(),
1092 &FunctionNameGetter,
1093 &FunctionNameSetter,
1094 attributes);
1095}
Steve Blocka7e24c12009-10-30 11:49:00 +00001096
1097
1098//
1099// Accessors::FunctionArguments
1100//
1101
Ben Murdochb0fe1622011-05-05 13:52:32 +01001102
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001103static Handle<Object> ArgumentsForInlinedFunction(
Ben Murdochb0fe1622011-05-05 13:52:32 +01001104 JavaScriptFrame* frame,
1105 Handle<JSFunction> inlined_function,
1106 int inlined_frame_index) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001107 Isolate* isolate = inlined_function->GetIsolate();
1108 Factory* factory = isolate->factory();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001109
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001110 TranslatedState translated_values(frame);
1111 translated_values.Prepare(false, frame->fp());
1112
1113 int argument_count = 0;
1114 TranslatedFrame* translated_frame =
1115 translated_values.GetArgumentsInfoFromJSFrameIndex(inlined_frame_index,
1116 &argument_count);
1117 TranslatedFrame::iterator iter = translated_frame->begin();
1118
1119 // Skip the function.
1120 iter++;
1121
1122 // Skip the receiver.
1123 iter++;
1124 argument_count--;
1125
Ben Murdochb0fe1622011-05-05 13:52:32 +01001126 Handle<JSObject> arguments =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001127 factory->NewArgumentsObject(inlined_function, argument_count);
1128 Handle<FixedArray> array = factory->NewFixedArray(argument_count);
1129 bool should_deoptimize = false;
1130 for (int i = 0; i < argument_count; ++i) {
1131 // If we materialize any object, we should deopt because we might alias
1132 // an object that was eliminated by escape analysis.
1133 should_deoptimize = should_deoptimize || iter->IsMaterializedObject();
1134 Handle<Object> value = iter->GetValue();
Ben Murdochb0fe1622011-05-05 13:52:32 +01001135 array->set(i, *value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001136 iter++;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001137 }
1138 arguments->set_elements(*array);
1139
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001140 if (should_deoptimize) {
1141 translated_values.StoreMaterializedValuesAndDeopt();
1142 }
1143
Ben Murdochb0fe1622011-05-05 13:52:32 +01001144 // Return the freshly allocated arguments object.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001145 return arguments;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001146}
1147
Steve Blocka7e24c12009-10-30 11:49:00 +00001148
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001149static int FindFunctionInFrame(JavaScriptFrame* frame,
1150 Handle<JSFunction> function) {
1151 DisallowHeapAllocation no_allocation;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001152 List<JSFunction*> functions(2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001153 frame->GetFunctions(&functions);
1154 for (int i = functions.length() - 1; i >= 0; i--) {
1155 if (functions[i] == *function) return i;
1156 }
1157 return -1;
1158}
1159
1160
1161Handle<Object> GetFunctionArguments(Isolate* isolate,
1162 Handle<JSFunction> function) {
1163 if (function->shared()->native()) return isolate->factory()->null_value();
1164
1165 // Find the top invocation of the function by traversing frames.
Ben Murdoch8b112d22011-06-08 16:22:53 +01001166 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001167 JavaScriptFrame* frame = it.frame();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001168 int function_index = FindFunctionInFrame(frame, function);
1169 if (function_index < 0) continue;
Steve Blocka7e24c12009-10-30 11:49:00 +00001170
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001171 if (function_index > 0) {
1172 // The function in question was inlined. Inlined functions have the
1173 // correct number of arguments and no allocated arguments object, so
1174 // we can construct a fresh one by interpreting the function's
1175 // deoptimization input data.
1176 return ArgumentsForInlinedFunction(frame, function, function_index);
Steve Blocka7e24c12009-10-30 11:49:00 +00001177 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001178
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001179 // Find the frame that holds the actual arguments passed to the function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001180 it.AdvanceToArgumentsFrame();
1181 frame = it.frame();
1182
1183 // Get the number of arguments and construct an arguments object
1184 // mirror for the right frame.
1185 const int length = frame->ComputeParametersCount();
1186 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
1187 function, length);
1188 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
1189
1190 // Copy the parameters to the arguments object.
1191 DCHECK(array->length() == length);
1192 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
1193 arguments->set_elements(*array);
1194
1195 // Return the freshly allocated arguments object.
1196 return arguments;
Steve Blocka7e24c12009-10-30 11:49:00 +00001197 }
1198
1199 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001200 return isolate->factory()->null_value();
Steve Blocka7e24c12009-10-30 11:49:00 +00001201}
1202
1203
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001204Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) {
1205 return GetFunctionArguments(function->GetIsolate(), function);
1206}
1207
1208
1209void Accessors::FunctionArgumentsGetter(
1210 v8::Local<v8::Name> name,
1211 const v8::PropertyCallbackInfo<v8::Value>& info) {
1212 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1213 HandleScope scope(isolate);
1214 Handle<JSFunction> function =
1215 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1216 Handle<Object> result = GetFunctionArguments(isolate, function);
1217 info.GetReturnValue().Set(Utils::ToLocal(result));
1218}
1219
1220
1221void Accessors::FunctionArgumentsSetter(
1222 v8::Local<v8::Name> name,
1223 v8::Local<v8::Value> val,
1224 const v8::PropertyCallbackInfo<void>& info) {
1225 // Function arguments is non writable, non configurable.
1226 UNREACHABLE();
1227}
1228
1229
1230Handle<AccessorInfo> Accessors::FunctionArgumentsInfo(
1231 Isolate* isolate, PropertyAttributes attributes) {
1232 return MakeAccessor(isolate,
1233 isolate->factory()->arguments_string(),
1234 &FunctionArgumentsGetter,
1235 &FunctionArgumentsSetter,
1236 attributes);
1237}
Steve Blocka7e24c12009-10-30 11:49:00 +00001238
1239
1240//
1241// Accessors::FunctionCaller
1242//
1243
1244
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001245static inline bool AllowAccessToFunction(Context* current_context,
1246 JSFunction* function) {
1247 return current_context->HasSameSecurityTokenAs(function->context());
Steve Block44f0eee2011-05-26 01:26:41 +01001248}
1249
1250
Ben Murdoch257744e2011-11-30 15:57:28 +00001251class FrameFunctionIterator {
1252 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001253 FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
1254 : isolate_(isolate),
1255 frame_iterator_(isolate),
Ben Murdoch257744e2011-11-30 15:57:28 +00001256 functions_(2),
1257 index_(0) {
1258 GetFunctions();
1259 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001260 JSFunction* next() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001261 while (true) {
1262 if (functions_.length() == 0) return NULL;
1263 JSFunction* next_function = functions_[index_];
1264 index_--;
1265 if (index_ < 0) {
1266 GetFunctions();
1267 }
1268 // Skip functions from other origins.
1269 if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
1270 return next_function;
Ben Murdoch257744e2011-11-30 15:57:28 +00001271 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001272 }
1273
1274 // Iterate through functions until the first occurence of 'function'.
1275 // Returns true if 'function' is found, and false if the iterator ends
1276 // without finding it.
1277 bool Find(JSFunction* function) {
1278 JSFunction* next_function;
1279 do {
1280 next_function = next();
1281 if (next_function == function) return true;
1282 } while (next_function != NULL);
1283 return false;
1284 }
Ben Murdoch589d6972011-11-30 16:04:58 +00001285
Ben Murdoch257744e2011-11-30 15:57:28 +00001286 private:
1287 void GetFunctions() {
1288 functions_.Rewind(0);
1289 if (frame_iterator_.done()) return;
1290 JavaScriptFrame* frame = frame_iterator_.frame();
1291 frame->GetFunctions(&functions_);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001292 DCHECK(functions_.length() > 0);
Ben Murdoch257744e2011-11-30 15:57:28 +00001293 frame_iterator_.Advance();
1294 index_ = functions_.length() - 1;
1295 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001296 Isolate* isolate_;
Ben Murdoch257744e2011-11-30 15:57:28 +00001297 JavaScriptFrameIterator frame_iterator_;
1298 List<JSFunction*> functions_;
1299 int index_;
1300};
1301
1302
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001303MaybeHandle<JSFunction> FindCaller(Isolate* isolate,
1304 Handle<JSFunction> function) {
1305 DisallowHeapAllocation no_allocation;
1306 FrameFunctionIterator it(isolate, no_allocation);
1307 if (function->shared()->native()) {
1308 return MaybeHandle<JSFunction>();
1309 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001310 // Find the function from the frames.
1311 if (!it.Find(*function)) {
1312 // No frame corresponding to the given function found. Return null.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001313 return MaybeHandle<JSFunction>();
Steve Blocka7e24c12009-10-30 11:49:00 +00001314 }
Ben Murdoch257744e2011-11-30 15:57:28 +00001315 // Find previously called non-toplevel function.
1316 JSFunction* caller;
1317 do {
1318 caller = it.next();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001319 if (caller == NULL) return MaybeHandle<JSFunction>();
Ben Murdoch257744e2011-11-30 15:57:28 +00001320 } while (caller->shared()->is_toplevel());
1321
1322 // If caller is a built-in function and caller's caller is also built-in,
1323 // use that instead.
1324 JSFunction* potential_caller = caller;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001325 while (potential_caller != NULL && potential_caller->shared()->IsBuiltin()) {
Ben Murdoch257744e2011-11-30 15:57:28 +00001326 caller = potential_caller;
1327 potential_caller = it.next();
1328 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001329 if (!caller->shared()->native() && potential_caller != NULL) {
1330 caller = potential_caller;
1331 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001332 // Censor if the caller is not a sloppy mode function.
1333 // Change from ES5, which used to throw, see:
1334 // https://bugs.ecmascript.org/show_bug.cgi?id=310
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001335 if (is_strict(caller->shared()->language_mode())) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001336 return MaybeHandle<JSFunction>();
1337 }
1338 // Don't return caller from another security context.
1339 if (!AllowAccessToFunction(isolate->context(), caller)) {
1340 return MaybeHandle<JSFunction>();
1341 }
1342 return Handle<JSFunction>(caller);
Steve Blocka7e24c12009-10-30 11:49:00 +00001343}
1344
1345
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001346void Accessors::FunctionCallerGetter(
1347 v8::Local<v8::Name> name,
1348 const v8::PropertyCallbackInfo<v8::Value>& info) {
1349 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate());
1350 HandleScope scope(isolate);
1351 Handle<JSFunction> function =
1352 Handle<JSFunction>::cast(Utils::OpenHandle(*info.Holder()));
1353 Handle<Object> result;
1354 MaybeHandle<JSFunction> maybe_caller;
1355 maybe_caller = FindCaller(isolate, function);
1356 Handle<JSFunction> caller;
1357 if (maybe_caller.ToHandle(&caller)) {
1358 result = caller;
1359 } else {
1360 result = isolate->factory()->null_value();
1361 }
1362 info.GetReturnValue().Set(Utils::ToLocal(result));
1363}
1364
1365
1366void Accessors::FunctionCallerSetter(
1367 v8::Local<v8::Name> name,
1368 v8::Local<v8::Value> val,
1369 const v8::PropertyCallbackInfo<void>& info) {
1370 // Function caller is non writable, non configurable.
1371 UNREACHABLE();
1372}
1373
1374
1375Handle<AccessorInfo> Accessors::FunctionCallerInfo(
1376 Isolate* isolate, PropertyAttributes attributes) {
1377 return MakeAccessor(isolate,
1378 isolate->factory()->caller_string(),
1379 &FunctionCallerGetter,
1380 &FunctionCallerSetter,
1381 attributes);
1382}
Steve Blocka7e24c12009-10-30 11:49:00 +00001383
1384
1385//
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001386// Accessors::MakeModuleExport
Steve Blocka7e24c12009-10-30 11:49:00 +00001387//
1388
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001389static void ModuleGetExport(
1390 v8::Local<v8::String> property,
1391 const v8::PropertyCallbackInfo<v8::Value>& info) {
1392 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
1393 Context* context = Context::cast(instance->context());
1394 DCHECK(context->IsModuleContext());
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001395 Isolate* isolate = instance->GetIsolate();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001396 int slot = info.Data()
1397 ->Int32Value(info.GetIsolate()->GetCurrentContext())
1398 .FromMaybe(-1);
1399 if (slot < 0 || slot >= context->length()) {
1400 Handle<String> name = v8::Utils::OpenHandle(*property);
1401
1402 Handle<Object> exception = isolate->factory()->NewReferenceError(
1403 MessageTemplate::kNotDefined, name);
1404 isolate->ScheduleThrow(*exception);
1405 return;
1406 }
1407 Object* value = context->get(slot);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001408 if (value->IsTheHole()) {
1409 Handle<String> name = v8::Utils::OpenHandle(*property);
Steve Blocka7e24c12009-10-30 11:49:00 +00001410
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001411 Handle<Object> exception = isolate->factory()->NewReferenceError(
1412 MessageTemplate::kNotDefined, name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001413 isolate->ScheduleThrow(*exception);
1414 return;
Steve Blocka7e24c12009-10-30 11:49:00 +00001415 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001416 info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate)));
Steve Blocka7e24c12009-10-30 11:49:00 +00001417}
1418
1419
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001420static void ModuleSetExport(
1421 v8::Local<v8::String> property,
1422 v8::Local<v8::Value> value,
1423 const v8::PropertyCallbackInfo<v8::Value>& info) {
1424 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
1425 Context* context = Context::cast(instance->context());
1426 DCHECK(context->IsModuleContext());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001427 Isolate* isolate = instance->GetIsolate();
1428 int slot = info.Data()
1429 ->Int32Value(info.GetIsolate()->GetCurrentContext())
1430 .FromMaybe(-1);
1431 if (slot < 0 || slot >= context->length()) {
1432 Handle<String> name = v8::Utils::OpenHandle(*property);
1433 Handle<Object> exception = isolate->factory()->NewReferenceError(
1434 MessageTemplate::kNotDefined, name);
1435 isolate->ScheduleThrow(*exception);
1436 return;
1437 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001438 Object* old_value = context->get(slot);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001439 if (old_value->IsTheHole()) {
1440 Handle<String> name = v8::Utils::OpenHandle(*property);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001441 Handle<Object> exception = isolate->factory()->NewReferenceError(
1442 MessageTemplate::kNotDefined, name);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001443 isolate->ScheduleThrow(*exception);
1444 return;
1445 }
1446 context->set(slot, *v8::Utils::OpenHandle(*value));
Steve Blocka7e24c12009-10-30 11:49:00 +00001447}
1448
1449
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001450Handle<AccessorInfo> Accessors::MakeModuleExport(
1451 Handle<String> name,
1452 int index,
1453 PropertyAttributes attributes) {
1454 Isolate* isolate = name->GetIsolate();
1455 Factory* factory = isolate->factory();
1456 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo();
1457 info->set_property_attributes(attributes);
1458 info->set_all_can_read(true);
1459 info->set_all_can_write(true);
1460 info->set_name(*name);
1461 info->set_data(Smi::FromInt(index));
1462 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport);
1463 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport);
1464 info->set_getter(*getter);
1465 if (!(attributes & ReadOnly)) info->set_setter(*setter);
1466 return info;
1467}
1468
Steve Blocka7e24c12009-10-30 11:49:00 +00001469
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001470} // namespace internal
1471} // namespace v8