1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/v8.h" 6 #include "src/accessors.h" 7 8 #include "src/compiler.h" 9 #include "src/contexts.h" 10 #include "src/deoptimizer.h" 11 #include "src/execution.h" 12 #include "src/factory.h" 13 #include "src/frames-inl.h" 14 #include "src/isolate.h" 15 #include "src/list-inl.h" 16 #include "src/property-details.h" 17 #include "src/api.h" 18 19 namespace v8 { 20 namespace internal { 21 22 23 // We have a slight impedance mismatch between the external API and the way we 24 // use callbacks internally: Externally, callbacks can only be used with 25 // v8::Object, but internally we even have callbacks on entities which are 26 // higher in the hierarchy, so we can only return i::Object here, not 27 // i::JSObject. 28 Handle<Object> GetThisFrom(const v8::PropertyCallbackInfo<v8::Value>& info) { 29 return Utils::OpenHandle(*v8::Local<v8::Value>(info.This())); 30 } 31 32 33 Handle<AccessorInfo> Accessors::MakeAccessor( 34 Isolate* isolate, 35 Handle<String> name, 36 AccessorGetterCallback getter, 37 AccessorSetterCallback setter, 38 PropertyAttributes attributes) { 39 Factory* factory = isolate->factory(); 40 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo(); 41 info->set_property_attributes(attributes); 42 info->set_all_can_read(false); 43 info->set_all_can_write(false); 44 info->set_name(*name); 45 Handle<Object> get = v8::FromCData(isolate, getter); 46 Handle<Object> set = v8::FromCData(isolate, setter); 47 info->set_getter(*get); 48 info->set_setter(*set); 49 return info; 50 } 51 52 53 Handle<ExecutableAccessorInfo> Accessors::CloneAccessor( 54 Isolate* isolate, 55 Handle<ExecutableAccessorInfo> accessor) { 56 Factory* factory = isolate->factory(); 57 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo(); 58 info->set_name(accessor->name()); 59 info->set_flag(accessor->flag()); 60 info->set_expected_receiver_type(accessor->expected_receiver_type()); 61 info->set_getter(accessor->getter()); 62 info->set_setter(accessor->setter()); 63 info->set_data(accessor->data()); 64 return info; 65 } 66 67 68 template <class C> 69 static C* FindInstanceOf(Isolate* isolate, Object* obj) { 70 for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype(isolate)) { 71 if (Is<C>(cur)) return C::cast(cur); 72 } 73 return NULL; 74 } 75 76 77 static V8_INLINE bool CheckForName(Handle<String> name, 78 Handle<String> property_name, 79 int offset, 80 int* object_offset) { 81 if (String::Equals(name, property_name)) { 82 *object_offset = offset; 83 return true; 84 } 85 return false; 86 } 87 88 89 // Returns true for properties that are accessors to object fields. 90 // If true, *object_offset contains offset of object field. 91 template <class T> 92 bool Accessors::IsJSObjectFieldAccessor(typename T::TypeHandle type, 93 Handle<String> name, 94 int* object_offset) { 95 Isolate* isolate = name->GetIsolate(); 96 97 if (type->Is(T::String())) { 98 return CheckForName(name, isolate->factory()->length_string(), 99 String::kLengthOffset, object_offset); 100 } 101 102 if (!type->IsClass()) return false; 103 Handle<Map> map = type->AsClass()->Map(); 104 105 switch (map->instance_type()) { 106 case JS_ARRAY_TYPE: 107 return 108 CheckForName(name, isolate->factory()->length_string(), 109 JSArray::kLengthOffset, object_offset); 110 case JS_TYPED_ARRAY_TYPE: 111 return 112 CheckForName(name, isolate->factory()->length_string(), 113 JSTypedArray::kLengthOffset, object_offset) || 114 CheckForName(name, isolate->factory()->byte_length_string(), 115 JSTypedArray::kByteLengthOffset, object_offset) || 116 CheckForName(name, isolate->factory()->byte_offset_string(), 117 JSTypedArray::kByteOffsetOffset, object_offset); 118 case JS_ARRAY_BUFFER_TYPE: 119 return 120 CheckForName(name, isolate->factory()->byte_length_string(), 121 JSArrayBuffer::kByteLengthOffset, object_offset); 122 case JS_DATA_VIEW_TYPE: 123 return 124 CheckForName(name, isolate->factory()->byte_length_string(), 125 JSDataView::kByteLengthOffset, object_offset) || 126 CheckForName(name, isolate->factory()->byte_offset_string(), 127 JSDataView::kByteOffsetOffset, object_offset); 128 default: 129 return false; 130 } 131 } 132 133 134 template 135 bool Accessors::IsJSObjectFieldAccessor<Type>(Type* type, 136 Handle<String> name, 137 int* object_offset); 138 139 140 template 141 bool Accessors::IsJSObjectFieldAccessor<HeapType>(Handle<HeapType> type, 142 Handle<String> name, 143 int* object_offset); 144 145 146 // 147 // Accessors::ArrayLength 148 // 149 150 151 // The helper function will 'flatten' Number objects. 152 Handle<Object> Accessors::FlattenNumber(Isolate* isolate, 153 Handle<Object> value) { 154 if (value->IsNumber() || !value->IsJSValue()) return value; 155 Handle<JSValue> wrapper = Handle<JSValue>::cast(value); 156 ASSERT(wrapper->GetIsolate()->context()->native_context()->number_function()-> 157 has_initial_map()); 158 if (wrapper->map() == 159 isolate->context()->native_context()->number_function()->initial_map()) { 160 return handle(wrapper->value(), isolate); 161 } 162 163 return value; 164 } 165 166 167 void Accessors::ArrayLengthGetter( 168 v8::Local<v8::String> name, 169 const v8::PropertyCallbackInfo<v8::Value>& info) { 170 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 171 DisallowHeapAllocation no_allocation; 172 HandleScope scope(isolate); 173 Object* object = *GetThisFrom(info); 174 // Traverse the prototype chain until we reach an array. 175 JSArray* holder = FindInstanceOf<JSArray>(isolate, object); 176 Object* result; 177 if (holder != NULL) { 178 result = holder->length(); 179 } else { 180 result = Smi::FromInt(0); 181 } 182 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); 183 } 184 185 186 void Accessors::ArrayLengthSetter( 187 v8::Local<v8::String> name, 188 v8::Local<v8::Value> val, 189 const v8::PropertyCallbackInfo<void>& info) { 190 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 191 HandleScope scope(isolate); 192 Handle<JSObject> object = Handle<JSObject>::cast( 193 Utils::OpenHandle(*info.This())); 194 Handle<Object> value = Utils::OpenHandle(*val); 195 // This means one of the object's prototypes is a JSArray and the 196 // object does not have a 'length' property. Calling SetProperty 197 // causes an infinite loop. 198 if (!object->IsJSArray()) { 199 MaybeHandle<Object> maybe_result = 200 JSObject::SetOwnPropertyIgnoreAttributes( 201 object, isolate->factory()->length_string(), value, NONE); 202 maybe_result.Check(); 203 return; 204 } 205 206 value = FlattenNumber(isolate, value); 207 208 Handle<JSArray> array_handle = Handle<JSArray>::cast(object); 209 MaybeHandle<Object> maybe; 210 Handle<Object> uint32_v; 211 maybe = Execution::ToUint32(isolate, value); 212 if (!maybe.ToHandle(&uint32_v)) { 213 isolate->OptionalRescheduleException(false); 214 return; 215 } 216 Handle<Object> number_v; 217 maybe = Execution::ToNumber(isolate, value); 218 if (!maybe.ToHandle(&number_v)) { 219 isolate->OptionalRescheduleException(false); 220 return; 221 } 222 223 if (uint32_v->Number() == number_v->Number()) { 224 maybe = JSArray::SetElementsLength(array_handle, uint32_v); 225 maybe.Check(); 226 return; 227 } 228 229 isolate->ScheduleThrow( 230 *isolate->factory()->NewRangeError("invalid_array_length", 231 HandleVector<Object>(NULL, 0))); 232 } 233 234 235 Handle<AccessorInfo> Accessors::ArrayLengthInfo( 236 Isolate* isolate, PropertyAttributes attributes) { 237 return MakeAccessor(isolate, 238 isolate->factory()->length_string(), 239 &ArrayLengthGetter, 240 &ArrayLengthSetter, 241 attributes); 242 } 243 244 245 246 // 247 // Accessors::StringLength 248 // 249 250 void Accessors::StringLengthGetter( 251 v8::Local<v8::String> name, 252 const v8::PropertyCallbackInfo<v8::Value>& info) { 253 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 254 DisallowHeapAllocation no_allocation; 255 HandleScope scope(isolate); 256 Object* value = *GetThisFrom(info); 257 Object* result; 258 if (value->IsJSValue()) value = JSValue::cast(value)->value(); 259 if (value->IsString()) { 260 result = Smi::FromInt(String::cast(value)->length()); 261 } else { 262 // If object is not a string we return 0 to be compatible with WebKit. 263 // Note: Firefox returns the length of ToString(object). 264 result = Smi::FromInt(0); 265 } 266 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(result, isolate))); 267 } 268 269 270 void Accessors::StringLengthSetter( 271 v8::Local<v8::String> name, 272 v8::Local<v8::Value> value, 273 const v8::PropertyCallbackInfo<void>& info) { 274 UNREACHABLE(); 275 } 276 277 278 Handle<AccessorInfo> Accessors::StringLengthInfo( 279 Isolate* isolate, PropertyAttributes attributes) { 280 return MakeAccessor(isolate, 281 isolate->factory()->length_string(), 282 &StringLengthGetter, 283 &StringLengthSetter, 284 attributes); 285 } 286 287 288 // 289 // Accessors::ScriptColumnOffset 290 // 291 292 293 void Accessors::ScriptColumnOffsetGetter( 294 v8::Local<v8::String> name, 295 const v8::PropertyCallbackInfo<v8::Value>& info) { 296 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 297 DisallowHeapAllocation no_allocation; 298 HandleScope scope(isolate); 299 Object* object = *Utils::OpenHandle(*info.This()); 300 Object* res = Script::cast(JSValue::cast(object)->value())->column_offset(); 301 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate))); 302 } 303 304 305 void Accessors::ScriptColumnOffsetSetter( 306 v8::Local<v8::String> name, 307 v8::Local<v8::Value> value, 308 const v8::PropertyCallbackInfo<void>& info) { 309 UNREACHABLE(); 310 } 311 312 313 Handle<AccessorInfo> Accessors::ScriptColumnOffsetInfo( 314 Isolate* isolate, PropertyAttributes attributes) { 315 Handle<String> name(isolate->factory()->InternalizeOneByteString( 316 STATIC_ASCII_VECTOR("column_offset"))); 317 return MakeAccessor(isolate, 318 name, 319 &ScriptColumnOffsetGetter, 320 &ScriptColumnOffsetSetter, 321 attributes); 322 } 323 324 325 // 326 // Accessors::ScriptId 327 // 328 329 330 void Accessors::ScriptIdGetter( 331 v8::Local<v8::String> name, 332 const v8::PropertyCallbackInfo<v8::Value>& info) { 333 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 334 DisallowHeapAllocation no_allocation; 335 HandleScope scope(isolate); 336 Object* object = *Utils::OpenHandle(*info.This()); 337 Object* id = Script::cast(JSValue::cast(object)->value())->id(); 338 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(id, isolate))); 339 } 340 341 342 void Accessors::ScriptIdSetter( 343 v8::Local<v8::String> name, 344 v8::Local<v8::Value> value, 345 const v8::PropertyCallbackInfo<void>& info) { 346 UNREACHABLE(); 347 } 348 349 350 Handle<AccessorInfo> Accessors::ScriptIdInfo( 351 Isolate* isolate, PropertyAttributes attributes) { 352 Handle<String> name(isolate->factory()->InternalizeOneByteString( 353 STATIC_ASCII_VECTOR("id"))); 354 return MakeAccessor(isolate, 355 name, 356 &ScriptIdGetter, 357 &ScriptIdSetter, 358 attributes); 359 } 360 361 362 // 363 // Accessors::ScriptName 364 // 365 366 367 void Accessors::ScriptNameGetter( 368 v8::Local<v8::String> name, 369 const v8::PropertyCallbackInfo<v8::Value>& info) { 370 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 371 DisallowHeapAllocation no_allocation; 372 HandleScope scope(isolate); 373 Object* object = *Utils::OpenHandle(*info.This()); 374 Object* source = Script::cast(JSValue::cast(object)->value())->name(); 375 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate))); 376 } 377 378 379 void Accessors::ScriptNameSetter( 380 v8::Local<v8::String> name, 381 v8::Local<v8::Value> value, 382 const v8::PropertyCallbackInfo<void>& info) { 383 UNREACHABLE(); 384 } 385 386 387 Handle<AccessorInfo> Accessors::ScriptNameInfo( 388 Isolate* isolate, PropertyAttributes attributes) { 389 return MakeAccessor(isolate, 390 isolate->factory()->name_string(), 391 &ScriptNameGetter, 392 &ScriptNameSetter, 393 attributes); 394 } 395 396 397 // 398 // Accessors::ScriptSource 399 // 400 401 402 void Accessors::ScriptSourceGetter( 403 v8::Local<v8::String> name, 404 const v8::PropertyCallbackInfo<v8::Value>& info) { 405 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 406 DisallowHeapAllocation no_allocation; 407 HandleScope scope(isolate); 408 Object* object = *Utils::OpenHandle(*info.This()); 409 Object* source = Script::cast(JSValue::cast(object)->value())->source(); 410 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(source, isolate))); 411 } 412 413 414 void Accessors::ScriptSourceSetter( 415 v8::Local<v8::String> name, 416 v8::Local<v8::Value> value, 417 const v8::PropertyCallbackInfo<void>& info) { 418 UNREACHABLE(); 419 } 420 421 422 Handle<AccessorInfo> Accessors::ScriptSourceInfo( 423 Isolate* isolate, PropertyAttributes attributes) { 424 return MakeAccessor(isolate, 425 isolate->factory()->source_string(), 426 &ScriptSourceGetter, 427 &ScriptSourceSetter, 428 attributes); 429 } 430 431 432 // 433 // Accessors::ScriptLineOffset 434 // 435 436 437 void Accessors::ScriptLineOffsetGetter( 438 v8::Local<v8::String> name, 439 const v8::PropertyCallbackInfo<v8::Value>& info) { 440 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 441 DisallowHeapAllocation no_allocation; 442 HandleScope scope(isolate); 443 Object* object = *Utils::OpenHandle(*info.This()); 444 Object* res = Script::cast(JSValue::cast(object)->value())->line_offset(); 445 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate))); 446 } 447 448 449 void Accessors::ScriptLineOffsetSetter( 450 v8::Local<v8::String> name, 451 v8::Local<v8::Value> value, 452 const v8::PropertyCallbackInfo<void>& info) { 453 UNREACHABLE(); 454 } 455 456 457 Handle<AccessorInfo> Accessors::ScriptLineOffsetInfo( 458 Isolate* isolate, PropertyAttributes attributes) { 459 Handle<String> name(isolate->factory()->InternalizeOneByteString( 460 STATIC_ASCII_VECTOR("line_offset"))); 461 return MakeAccessor(isolate, 462 name, 463 &ScriptLineOffsetGetter, 464 &ScriptLineOffsetSetter, 465 attributes); 466 } 467 468 469 // 470 // Accessors::ScriptType 471 // 472 473 474 void Accessors::ScriptTypeGetter( 475 v8::Local<v8::String> name, 476 const v8::PropertyCallbackInfo<v8::Value>& info) { 477 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 478 DisallowHeapAllocation no_allocation; 479 HandleScope scope(isolate); 480 Object* object = *Utils::OpenHandle(*info.This()); 481 Object* res = Script::cast(JSValue::cast(object)->value())->type(); 482 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate))); 483 } 484 485 486 void Accessors::ScriptTypeSetter( 487 v8::Local<v8::String> name, 488 v8::Local<v8::Value> value, 489 const v8::PropertyCallbackInfo<void>& info) { 490 UNREACHABLE(); 491 } 492 493 494 Handle<AccessorInfo> Accessors::ScriptTypeInfo( 495 Isolate* isolate, PropertyAttributes attributes) { 496 Handle<String> name(isolate->factory()->InternalizeOneByteString( 497 STATIC_ASCII_VECTOR("type"))); 498 return MakeAccessor(isolate, 499 name, 500 &ScriptTypeGetter, 501 &ScriptTypeSetter, 502 attributes); 503 } 504 505 506 // 507 // Accessors::ScriptCompilationType 508 // 509 510 511 void Accessors::ScriptCompilationTypeGetter( 512 v8::Local<v8::String> name, 513 const v8::PropertyCallbackInfo<v8::Value>& info) { 514 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 515 DisallowHeapAllocation no_allocation; 516 HandleScope scope(isolate); 517 Object* object = *Utils::OpenHandle(*info.This()); 518 Object* res = Smi::FromInt( 519 Script::cast(JSValue::cast(object)->value())->compilation_type()); 520 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate))); 521 } 522 523 524 void Accessors::ScriptCompilationTypeSetter( 525 v8::Local<v8::String> name, 526 v8::Local<v8::Value> value, 527 const v8::PropertyCallbackInfo<void>& info) { 528 UNREACHABLE(); 529 } 530 531 532 Handle<AccessorInfo> Accessors::ScriptCompilationTypeInfo( 533 Isolate* isolate, PropertyAttributes attributes) { 534 Handle<String> name(isolate->factory()->InternalizeOneByteString( 535 STATIC_ASCII_VECTOR("compilation_type"))); 536 return MakeAccessor(isolate, 537 name, 538 &ScriptCompilationTypeGetter, 539 &ScriptCompilationTypeSetter, 540 attributes); 541 } 542 543 544 // 545 // Accessors::ScriptGetLineEnds 546 // 547 548 549 void Accessors::ScriptLineEndsGetter( 550 v8::Local<v8::String> name, 551 const v8::PropertyCallbackInfo<v8::Value>& info) { 552 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 553 HandleScope scope(isolate); 554 Handle<Object> object = Utils::OpenHandle(*info.This()); 555 Handle<Script> script( 556 Script::cast(Handle<JSValue>::cast(object)->value()), isolate); 557 Script::InitLineEnds(script); 558 ASSERT(script->line_ends()->IsFixedArray()); 559 Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends())); 560 // We do not want anyone to modify this array from JS. 561 ASSERT(*line_ends == isolate->heap()->empty_fixed_array() || 562 line_ends->map() == isolate->heap()->fixed_cow_array_map()); 563 Handle<JSArray> js_array = 564 isolate->factory()->NewJSArrayWithElements(line_ends); 565 info.GetReturnValue().Set(Utils::ToLocal(js_array)); 566 } 567 568 569 void Accessors::ScriptLineEndsSetter( 570 v8::Local<v8::String> name, 571 v8::Local<v8::Value> value, 572 const v8::PropertyCallbackInfo<void>& info) { 573 UNREACHABLE(); 574 } 575 576 577 Handle<AccessorInfo> Accessors::ScriptLineEndsInfo( 578 Isolate* isolate, PropertyAttributes attributes) { 579 Handle<String> name(isolate->factory()->InternalizeOneByteString( 580 STATIC_ASCII_VECTOR("line_ends"))); 581 return MakeAccessor(isolate, 582 name, 583 &ScriptLineEndsGetter, 584 &ScriptLineEndsSetter, 585 attributes); 586 } 587 588 589 // 590 // Accessors::ScriptGetContextData 591 // 592 593 594 void Accessors::ScriptContextDataGetter( 595 v8::Local<v8::String> name, 596 const v8::PropertyCallbackInfo<v8::Value>& info) { 597 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 598 DisallowHeapAllocation no_allocation; 599 HandleScope scope(isolate); 600 Object* object = *Utils::OpenHandle(*info.This()); 601 Object* res = Script::cast(JSValue::cast(object)->value())->context_data(); 602 info.GetReturnValue().Set(Utils::ToLocal(Handle<Object>(res, isolate))); 603 } 604 605 606 void Accessors::ScriptContextDataSetter( 607 v8::Local<v8::String> name, 608 v8::Local<v8::Value> value, 609 const v8::PropertyCallbackInfo<void>& info) { 610 UNREACHABLE(); 611 } 612 613 614 Handle<AccessorInfo> Accessors::ScriptContextDataInfo( 615 Isolate* isolate, PropertyAttributes attributes) { 616 Handle<String> name(isolate->factory()->InternalizeOneByteString( 617 STATIC_ASCII_VECTOR("context_data"))); 618 return MakeAccessor(isolate, 619 name, 620 &ScriptContextDataGetter, 621 &ScriptContextDataSetter, 622 attributes); 623 } 624 625 626 // 627 // Accessors::ScriptGetEvalFromScript 628 // 629 630 631 void Accessors::ScriptEvalFromScriptGetter( 632 v8::Local<v8::String> name, 633 const v8::PropertyCallbackInfo<v8::Value>& info) { 634 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 635 HandleScope scope(isolate); 636 Handle<Object> object = Utils::OpenHandle(*info.This()); 637 Handle<Script> script( 638 Script::cast(Handle<JSValue>::cast(object)->value()), isolate); 639 Handle<Object> result = isolate->factory()->undefined_value(); 640 if (!script->eval_from_shared()->IsUndefined()) { 641 Handle<SharedFunctionInfo> eval_from_shared( 642 SharedFunctionInfo::cast(script->eval_from_shared())); 643 if (eval_from_shared->script()->IsScript()) { 644 Handle<Script> eval_from_script(Script::cast(eval_from_shared->script())); 645 result = Script::GetWrapper(eval_from_script); 646 } 647 } 648 649 info.GetReturnValue().Set(Utils::ToLocal(result)); 650 } 651 652 653 void Accessors::ScriptEvalFromScriptSetter( 654 v8::Local<v8::String> name, 655 v8::Local<v8::Value> value, 656 const v8::PropertyCallbackInfo<void>& info) { 657 UNREACHABLE(); 658 } 659 660 661 Handle<AccessorInfo> Accessors::ScriptEvalFromScriptInfo( 662 Isolate* isolate, PropertyAttributes attributes) { 663 Handle<String> name(isolate->factory()->InternalizeOneByteString( 664 STATIC_ASCII_VECTOR("eval_from_script"))); 665 return MakeAccessor(isolate, 666 name, 667 &ScriptEvalFromScriptGetter, 668 &ScriptEvalFromScriptSetter, 669 attributes); 670 } 671 672 673 // 674 // Accessors::ScriptGetEvalFromScriptPosition 675 // 676 677 678 void Accessors::ScriptEvalFromScriptPositionGetter( 679 v8::Local<v8::String> name, 680 const v8::PropertyCallbackInfo<v8::Value>& info) { 681 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 682 HandleScope scope(isolate); 683 Handle<Object> object = Utils::OpenHandle(*info.This()); 684 Handle<Script> script( 685 Script::cast(Handle<JSValue>::cast(object)->value()), isolate); 686 Handle<Object> result = isolate->factory()->undefined_value(); 687 if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) { 688 Handle<Code> code(SharedFunctionInfo::cast( 689 script->eval_from_shared())->code()); 690 result = Handle<Object>( 691 Smi::FromInt(code->SourcePosition(code->instruction_start() + 692 script->eval_from_instructions_offset()->value())), 693 isolate); 694 } 695 info.GetReturnValue().Set(Utils::ToLocal(result)); 696 } 697 698 699 void Accessors::ScriptEvalFromScriptPositionSetter( 700 v8::Local<v8::String> name, 701 v8::Local<v8::Value> value, 702 const v8::PropertyCallbackInfo<void>& info) { 703 UNREACHABLE(); 704 } 705 706 707 Handle<AccessorInfo> Accessors::ScriptEvalFromScriptPositionInfo( 708 Isolate* isolate, PropertyAttributes attributes) { 709 Handle<String> name(isolate->factory()->InternalizeOneByteString( 710 STATIC_ASCII_VECTOR("eval_from_script_position"))); 711 return MakeAccessor(isolate, 712 name, 713 &ScriptEvalFromScriptPositionGetter, 714 &ScriptEvalFromScriptPositionSetter, 715 attributes); 716 } 717 718 719 // 720 // Accessors::ScriptGetEvalFromFunctionName 721 // 722 723 724 void Accessors::ScriptEvalFromFunctionNameGetter( 725 v8::Local<v8::String> name, 726 const v8::PropertyCallbackInfo<v8::Value>& info) { 727 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 728 HandleScope scope(isolate); 729 Handle<Object> object = Utils::OpenHandle(*info.This()); 730 Handle<Script> script( 731 Script::cast(Handle<JSValue>::cast(object)->value()), isolate); 732 Handle<Object> result; 733 Handle<SharedFunctionInfo> shared( 734 SharedFunctionInfo::cast(script->eval_from_shared())); 735 // Find the name of the function calling eval. 736 if (!shared->name()->IsUndefined()) { 737 result = Handle<Object>(shared->name(), isolate); 738 } else { 739 result = Handle<Object>(shared->inferred_name(), isolate); 740 } 741 info.GetReturnValue().Set(Utils::ToLocal(result)); 742 } 743 744 745 void Accessors::ScriptEvalFromFunctionNameSetter( 746 v8::Local<v8::String> name, 747 v8::Local<v8::Value> value, 748 const v8::PropertyCallbackInfo<void>& info) { 749 UNREACHABLE(); 750 } 751 752 753 Handle<AccessorInfo> Accessors::ScriptEvalFromFunctionNameInfo( 754 Isolate* isolate, PropertyAttributes attributes) { 755 Handle<String> name(isolate->factory()->InternalizeOneByteString( 756 STATIC_ASCII_VECTOR("eval_from_function_name"))); 757 return MakeAccessor(isolate, 758 name, 759 &ScriptEvalFromFunctionNameGetter, 760 &ScriptEvalFromFunctionNameSetter, 761 attributes); 762 } 763 764 765 // 766 // Accessors::FunctionPrototype 767 // 768 769 static Handle<Object> GetFunctionPrototype(Isolate* isolate, 770 Handle<Object> receiver) { 771 Handle<JSFunction> function; 772 { 773 DisallowHeapAllocation no_allocation; 774 JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver); 775 if (function_raw == NULL) return isolate->factory()->undefined_value(); 776 while (!function_raw->should_have_prototype()) { 777 function_raw = FindInstanceOf<JSFunction>(isolate, 778 function_raw->GetPrototype()); 779 // There has to be one because we hit the getter. 780 ASSERT(function_raw != NULL); 781 } 782 function = Handle<JSFunction>(function_raw, isolate); 783 } 784 785 if (!function->has_prototype()) { 786 Handle<Object> proto = isolate->factory()->NewFunctionPrototype(function); 787 JSFunction::SetPrototype(function, proto); 788 } 789 return Handle<Object>(function->prototype(), isolate); 790 } 791 792 793 static Handle<Object> SetFunctionPrototype(Isolate* isolate, 794 Handle<JSObject> receiver, 795 Handle<Object> value) { 796 Handle<JSFunction> function; 797 { 798 DisallowHeapAllocation no_allocation; 799 JSFunction* function_raw = FindInstanceOf<JSFunction>(isolate, *receiver); 800 if (function_raw == NULL) return isolate->factory()->undefined_value(); 801 function = Handle<JSFunction>(function_raw, isolate); 802 } 803 804 if (!function->should_have_prototype()) { 805 // Since we hit this accessor, object will have no prototype property. 806 MaybeHandle<Object> maybe_result = 807 JSObject::SetOwnPropertyIgnoreAttributes( 808 receiver, isolate->factory()->prototype_string(), value, NONE); 809 return maybe_result.ToHandleChecked(); 810 } 811 812 Handle<Object> old_value; 813 bool is_observed = *function == *receiver && function->map()->is_observed(); 814 if (is_observed) { 815 if (function->has_prototype()) 816 old_value = handle(function->prototype(), isolate); 817 else 818 old_value = isolate->factory()->NewFunctionPrototype(function); 819 } 820 821 JSFunction::SetPrototype(function, value); 822 ASSERT(function->prototype() == *value); 823 824 if (is_observed && !old_value->SameValue(*value)) { 825 JSObject::EnqueueChangeRecord( 826 function, "update", isolate->factory()->prototype_string(), old_value); 827 } 828 829 return function; 830 } 831 832 833 Handle<Object> Accessors::FunctionGetPrototype(Handle<JSFunction> function) { 834 return GetFunctionPrototype(function->GetIsolate(), function); 835 } 836 837 838 Handle<Object> Accessors::FunctionSetPrototype(Handle<JSFunction> function, 839 Handle<Object> prototype) { 840 ASSERT(function->should_have_prototype()); 841 Isolate* isolate = function->GetIsolate(); 842 return SetFunctionPrototype(isolate, function, prototype); 843 } 844 845 846 void Accessors::FunctionPrototypeGetter( 847 v8::Local<v8::String> name, 848 const v8::PropertyCallbackInfo<v8::Value>& info) { 849 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 850 HandleScope scope(isolate); 851 Handle<Object> object = GetThisFrom(info); 852 Handle<Object> result = GetFunctionPrototype(isolate, object); 853 info.GetReturnValue().Set(Utils::ToLocal(result)); 854 } 855 856 857 void Accessors::FunctionPrototypeSetter( 858 v8::Local<v8::String> name, 859 v8::Local<v8::Value> val, 860 const v8::PropertyCallbackInfo<void>& info) { 861 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 862 HandleScope scope(isolate); 863 Handle<JSObject> object = 864 Handle<JSObject>::cast(Utils::OpenHandle(*info.This())); 865 Handle<Object> value = Utils::OpenHandle(*val); 866 867 SetFunctionPrototype(isolate, object, value); 868 } 869 870 871 Handle<AccessorInfo> Accessors::FunctionPrototypeInfo( 872 Isolate* isolate, PropertyAttributes attributes) { 873 return MakeAccessor(isolate, 874 isolate->factory()->prototype_string(), 875 &FunctionPrototypeGetter, 876 &FunctionPrototypeSetter, 877 attributes); 878 } 879 880 881 // 882 // Accessors::FunctionLength 883 // 884 885 886 void Accessors::FunctionLengthGetter( 887 v8::Local<v8::String> name, 888 const v8::PropertyCallbackInfo<v8::Value>& info) { 889 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 890 HandleScope scope(isolate); 891 Handle<Object> object = GetThisFrom(info); 892 MaybeHandle<JSFunction> maybe_function; 893 894 { 895 DisallowHeapAllocation no_allocation; 896 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object); 897 if (function != NULL) maybe_function = Handle<JSFunction>(function); 898 } 899 900 int length = 0; 901 Handle<JSFunction> function; 902 if (maybe_function.ToHandle(&function)) { 903 if (function->shared()->is_compiled()) { 904 length = function->shared()->length(); 905 } else { 906 // If the function isn't compiled yet, the length is not computed 907 // correctly yet. Compile it now and return the right length. 908 if (Compiler::EnsureCompiled(function, KEEP_EXCEPTION)) { 909 length = function->shared()->length(); 910 } 911 if (isolate->has_pending_exception()) { 912 isolate->OptionalRescheduleException(false); 913 } 914 } 915 } 916 Handle<Object> result(Smi::FromInt(length), isolate); 917 info.GetReturnValue().Set(Utils::ToLocal(result)); 918 } 919 920 921 void Accessors::FunctionLengthSetter( 922 v8::Local<v8::String> name, 923 v8::Local<v8::Value> val, 924 const v8::PropertyCallbackInfo<void>& info) { 925 // Do nothing. 926 } 927 928 929 Handle<AccessorInfo> Accessors::FunctionLengthInfo( 930 Isolate* isolate, PropertyAttributes attributes) { 931 return MakeAccessor(isolate, 932 isolate->factory()->length_string(), 933 &FunctionLengthGetter, 934 &FunctionLengthSetter, 935 attributes); 936 } 937 938 939 // 940 // Accessors::FunctionName 941 // 942 943 944 void Accessors::FunctionNameGetter( 945 v8::Local<v8::String> name, 946 const v8::PropertyCallbackInfo<v8::Value>& info) { 947 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 948 HandleScope scope(isolate); 949 Handle<Object> object = GetThisFrom(info); 950 MaybeHandle<JSFunction> maybe_function; 951 952 { 953 DisallowHeapAllocation no_allocation; 954 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object); 955 if (function != NULL) maybe_function = Handle<JSFunction>(function); 956 } 957 958 Handle<JSFunction> function; 959 Handle<Object> result; 960 if (maybe_function.ToHandle(&function)) { 961 result = Handle<Object>(function->shared()->name(), isolate); 962 } else { 963 result = isolate->factory()->undefined_value(); 964 } 965 info.GetReturnValue().Set(Utils::ToLocal(result)); 966 } 967 968 969 void Accessors::FunctionNameSetter( 970 v8::Local<v8::String> name, 971 v8::Local<v8::Value> val, 972 const v8::PropertyCallbackInfo<void>& info) { 973 // Do nothing. 974 } 975 976 977 Handle<AccessorInfo> Accessors::FunctionNameInfo( 978 Isolate* isolate, PropertyAttributes attributes) { 979 return MakeAccessor(isolate, 980 isolate->factory()->name_string(), 981 &FunctionNameGetter, 982 &FunctionNameSetter, 983 attributes); 984 } 985 986 987 // 988 // Accessors::FunctionArguments 989 // 990 991 992 static Handle<Object> ArgumentsForInlinedFunction( 993 JavaScriptFrame* frame, 994 Handle<JSFunction> inlined_function, 995 int inlined_frame_index) { 996 Isolate* isolate = inlined_function->GetIsolate(); 997 Factory* factory = isolate->factory(); 998 SlotRefValueBuilder slot_refs( 999 frame, 1000 inlined_frame_index, 1001 inlined_function->shared()->formal_parameter_count()); 1002 1003 int args_count = slot_refs.args_length(); 1004 Handle<JSObject> arguments = 1005 factory->NewArgumentsObject(inlined_function, args_count); 1006 Handle<FixedArray> array = factory->NewFixedArray(args_count); 1007 slot_refs.Prepare(isolate); 1008 for (int i = 0; i < args_count; ++i) { 1009 Handle<Object> value = slot_refs.GetNext(isolate, 0); 1010 array->set(i, *value); 1011 } 1012 slot_refs.Finish(isolate); 1013 arguments->set_elements(*array); 1014 1015 // Return the freshly allocated arguments object. 1016 return arguments; 1017 } 1018 1019 1020 static int FindFunctionInFrame(JavaScriptFrame* frame, 1021 Handle<JSFunction> function) { 1022 DisallowHeapAllocation no_allocation; 1023 List<JSFunction*> functions(2); 1024 frame->GetFunctions(&functions); 1025 for (int i = functions.length() - 1; i >= 0; i--) { 1026 if (functions[i] == *function) return i; 1027 } 1028 return -1; 1029 } 1030 1031 1032 Handle<Object> GetFunctionArguments(Isolate* isolate, 1033 Handle<JSFunction> function) { 1034 if (function->shared()->native()) return isolate->factory()->null_value(); 1035 1036 // Find the top invocation of the function by traversing frames. 1037 for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) { 1038 JavaScriptFrame* frame = it.frame(); 1039 int function_index = FindFunctionInFrame(frame, function); 1040 if (function_index < 0) continue; 1041 1042 if (function_index > 0) { 1043 // The function in question was inlined. Inlined functions have the 1044 // correct number of arguments and no allocated arguments object, so 1045 // we can construct a fresh one by interpreting the function's 1046 // deoptimization input data. 1047 return ArgumentsForInlinedFunction(frame, function, function_index); 1048 } 1049 1050 if (!frame->is_optimized()) { 1051 // If there is an arguments variable in the stack, we return that. 1052 Handle<ScopeInfo> scope_info(function->shared()->scope_info()); 1053 int index = scope_info->StackSlotIndex( 1054 isolate->heap()->arguments_string()); 1055 if (index >= 0) { 1056 Handle<Object> arguments(frame->GetExpression(index), isolate); 1057 if (!arguments->IsArgumentsMarker()) return arguments; 1058 } 1059 } 1060 1061 // If there is no arguments variable in the stack or we have an 1062 // optimized frame, we find the frame that holds the actual arguments 1063 // passed to the function. 1064 it.AdvanceToArgumentsFrame(); 1065 frame = it.frame(); 1066 1067 // Get the number of arguments and construct an arguments object 1068 // mirror for the right frame. 1069 const int length = frame->ComputeParametersCount(); 1070 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject( 1071 function, length); 1072 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length); 1073 1074 // Copy the parameters to the arguments object. 1075 ASSERT(array->length() == length); 1076 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); 1077 arguments->set_elements(*array); 1078 1079 // Return the freshly allocated arguments object. 1080 return arguments; 1081 } 1082 1083 // No frame corresponding to the given function found. Return null. 1084 return isolate->factory()->null_value(); 1085 } 1086 1087 1088 Handle<Object> Accessors::FunctionGetArguments(Handle<JSFunction> function) { 1089 return GetFunctionArguments(function->GetIsolate(), function); 1090 } 1091 1092 1093 void Accessors::FunctionArgumentsGetter( 1094 v8::Local<v8::String> name, 1095 const v8::PropertyCallbackInfo<v8::Value>& info) { 1096 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 1097 HandleScope scope(isolate); 1098 Handle<Object> object = GetThisFrom(info); 1099 MaybeHandle<JSFunction> maybe_function; 1100 1101 { 1102 DisallowHeapAllocation no_allocation; 1103 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object); 1104 if (function != NULL) maybe_function = Handle<JSFunction>(function); 1105 } 1106 1107 Handle<JSFunction> function; 1108 Handle<Object> result; 1109 if (maybe_function.ToHandle(&function)) { 1110 result = GetFunctionArguments(isolate, function); 1111 } else { 1112 result = isolate->factory()->undefined_value(); 1113 } 1114 info.GetReturnValue().Set(Utils::ToLocal(result)); 1115 } 1116 1117 1118 void Accessors::FunctionArgumentsSetter( 1119 v8::Local<v8::String> name, 1120 v8::Local<v8::Value> val, 1121 const v8::PropertyCallbackInfo<void>& info) { 1122 // Do nothing. 1123 } 1124 1125 1126 Handle<AccessorInfo> Accessors::FunctionArgumentsInfo( 1127 Isolate* isolate, PropertyAttributes attributes) { 1128 return MakeAccessor(isolate, 1129 isolate->factory()->arguments_string(), 1130 &FunctionArgumentsGetter, 1131 &FunctionArgumentsSetter, 1132 attributes); 1133 } 1134 1135 1136 // 1137 // Accessors::FunctionCaller 1138 // 1139 1140 1141 static inline bool AllowAccessToFunction(Context* current_context, 1142 JSFunction* function) { 1143 return current_context->HasSameSecurityTokenAs(function->context()); 1144 } 1145 1146 1147 class FrameFunctionIterator { 1148 public: 1149 FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise) 1150 : isolate_(isolate), 1151 frame_iterator_(isolate), 1152 functions_(2), 1153 index_(0) { 1154 GetFunctions(); 1155 } 1156 JSFunction* next() { 1157 while (true) { 1158 if (functions_.length() == 0) return NULL; 1159 JSFunction* next_function = functions_[index_]; 1160 index_--; 1161 if (index_ < 0) { 1162 GetFunctions(); 1163 } 1164 // Skip functions from other origins. 1165 if (!AllowAccessToFunction(isolate_->context(), next_function)) continue; 1166 return next_function; 1167 } 1168 } 1169 1170 // Iterate through functions until the first occurence of 'function'. 1171 // Returns true if 'function' is found, and false if the iterator ends 1172 // without finding it. 1173 bool Find(JSFunction* function) { 1174 JSFunction* next_function; 1175 do { 1176 next_function = next(); 1177 if (next_function == function) return true; 1178 } while (next_function != NULL); 1179 return false; 1180 } 1181 1182 private: 1183 void GetFunctions() { 1184 functions_.Rewind(0); 1185 if (frame_iterator_.done()) return; 1186 JavaScriptFrame* frame = frame_iterator_.frame(); 1187 frame->GetFunctions(&functions_); 1188 ASSERT(functions_.length() > 0); 1189 frame_iterator_.Advance(); 1190 index_ = functions_.length() - 1; 1191 } 1192 Isolate* isolate_; 1193 JavaScriptFrameIterator frame_iterator_; 1194 List<JSFunction*> functions_; 1195 int index_; 1196 }; 1197 1198 1199 MaybeHandle<JSFunction> FindCaller(Isolate* isolate, 1200 Handle<JSFunction> function) { 1201 DisallowHeapAllocation no_allocation; 1202 FrameFunctionIterator it(isolate, no_allocation); 1203 if (function->shared()->native()) { 1204 return MaybeHandle<JSFunction>(); 1205 } 1206 // Find the function from the frames. 1207 if (!it.Find(*function)) { 1208 // No frame corresponding to the given function found. Return null. 1209 return MaybeHandle<JSFunction>(); 1210 } 1211 // Find previously called non-toplevel function. 1212 JSFunction* caller; 1213 do { 1214 caller = it.next(); 1215 if (caller == NULL) return MaybeHandle<JSFunction>(); 1216 } while (caller->shared()->is_toplevel()); 1217 1218 // If caller is a built-in function and caller's caller is also built-in, 1219 // use that instead. 1220 JSFunction* potential_caller = caller; 1221 while (potential_caller != NULL && potential_caller->IsBuiltin()) { 1222 caller = potential_caller; 1223 potential_caller = it.next(); 1224 } 1225 if (!caller->shared()->native() && potential_caller != NULL) { 1226 caller = potential_caller; 1227 } 1228 // If caller is bound, return null. This is compatible with JSC, and 1229 // allows us to make bound functions use the strict function map 1230 // and its associated throwing caller and arguments. 1231 if (caller->shared()->bound()) { 1232 return MaybeHandle<JSFunction>(); 1233 } 1234 // Censor if the caller is not a sloppy mode function. 1235 // Change from ES5, which used to throw, see: 1236 // https://bugs.ecmascript.org/show_bug.cgi?id=310 1237 if (caller->shared()->strict_mode() == STRICT) { 1238 return MaybeHandle<JSFunction>(); 1239 } 1240 // Don't return caller from another security context. 1241 if (!AllowAccessToFunction(isolate->context(), caller)) { 1242 return MaybeHandle<JSFunction>(); 1243 } 1244 return Handle<JSFunction>(caller); 1245 } 1246 1247 1248 void Accessors::FunctionCallerGetter( 1249 v8::Local<v8::String> name, 1250 const v8::PropertyCallbackInfo<v8::Value>& info) { 1251 i::Isolate* isolate = reinterpret_cast<i::Isolate*>(info.GetIsolate()); 1252 HandleScope scope(isolate); 1253 Handle<Object> object = GetThisFrom(info); 1254 MaybeHandle<JSFunction> maybe_function; 1255 { 1256 DisallowHeapAllocation no_allocation; 1257 JSFunction* function = FindInstanceOf<JSFunction>(isolate, *object); 1258 if (function != NULL) maybe_function = Handle<JSFunction>(function); 1259 } 1260 Handle<JSFunction> function; 1261 Handle<Object> result; 1262 if (maybe_function.ToHandle(&function)) { 1263 MaybeHandle<JSFunction> maybe_caller; 1264 maybe_caller = FindCaller(isolate, function); 1265 Handle<JSFunction> caller; 1266 if (maybe_caller.ToHandle(&caller)) { 1267 result = caller; 1268 } else { 1269 result = isolate->factory()->null_value(); 1270 } 1271 } else { 1272 result = isolate->factory()->undefined_value(); 1273 } 1274 info.GetReturnValue().Set(Utils::ToLocal(result)); 1275 } 1276 1277 1278 void Accessors::FunctionCallerSetter( 1279 v8::Local<v8::String> name, 1280 v8::Local<v8::Value> val, 1281 const v8::PropertyCallbackInfo<void>& info) { 1282 // Do nothing. 1283 } 1284 1285 1286 Handle<AccessorInfo> Accessors::FunctionCallerInfo( 1287 Isolate* isolate, PropertyAttributes attributes) { 1288 return MakeAccessor(isolate, 1289 isolate->factory()->caller_string(), 1290 &FunctionCallerGetter, 1291 &FunctionCallerSetter, 1292 attributes); 1293 } 1294 1295 1296 // 1297 // Accessors::MakeModuleExport 1298 // 1299 1300 static void ModuleGetExport( 1301 v8::Local<v8::String> property, 1302 const v8::PropertyCallbackInfo<v8::Value>& info) { 1303 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder())); 1304 Context* context = Context::cast(instance->context()); 1305 ASSERT(context->IsModuleContext()); 1306 int slot = info.Data()->Int32Value(); 1307 Object* value = context->get(slot); 1308 Isolate* isolate = instance->GetIsolate(); 1309 if (value->IsTheHole()) { 1310 Handle<String> name = v8::Utils::OpenHandle(*property); 1311 isolate->ScheduleThrow( 1312 *isolate->factory()->NewReferenceError("not_defined", 1313 HandleVector(&name, 1))); 1314 return; 1315 } 1316 info.GetReturnValue().Set(v8::Utils::ToLocal(Handle<Object>(value, isolate))); 1317 } 1318 1319 1320 static void ModuleSetExport( 1321 v8::Local<v8::String> property, 1322 v8::Local<v8::Value> value, 1323 const v8::PropertyCallbackInfo<v8::Value>& info) { 1324 JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder())); 1325 Context* context = Context::cast(instance->context()); 1326 ASSERT(context->IsModuleContext()); 1327 int slot = info.Data()->Int32Value(); 1328 Object* old_value = context->get(slot); 1329 if (old_value->IsTheHole()) { 1330 Handle<String> name = v8::Utils::OpenHandle(*property); 1331 Isolate* isolate = instance->GetIsolate(); 1332 isolate->ScheduleThrow( 1333 *isolate->factory()->NewReferenceError("not_defined", 1334 HandleVector(&name, 1))); 1335 return; 1336 } 1337 context->set(slot, *v8::Utils::OpenHandle(*value)); 1338 } 1339 1340 1341 Handle<AccessorInfo> Accessors::MakeModuleExport( 1342 Handle<String> name, 1343 int index, 1344 PropertyAttributes attributes) { 1345 Isolate* isolate = name->GetIsolate(); 1346 Factory* factory = isolate->factory(); 1347 Handle<ExecutableAccessorInfo> info = factory->NewExecutableAccessorInfo(); 1348 info->set_property_attributes(attributes); 1349 info->set_all_can_read(true); 1350 info->set_all_can_write(true); 1351 info->set_name(*name); 1352 info->set_data(Smi::FromInt(index)); 1353 Handle<Object> getter = v8::FromCData(isolate, &ModuleGetExport); 1354 Handle<Object> setter = v8::FromCData(isolate, &ModuleSetExport); 1355 info->set_getter(*getter); 1356 if (!(attributes & ReadOnly)) info->set_setter(*setter); 1357 return info; 1358 } 1359 1360 1361 } } // namespace v8::internal 1362