v8  3.14.5(node0.10.28)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
accessors.cc
Go to the documentation of this file.
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #include "v8.h"
29 #include "accessors.h"
30 
31 #include "contexts.h"
32 #include "deoptimizer.h"
33 #include "execution.h"
34 #include "factory.h"
35 #include "frames-inl.h"
36 #include "isolate.h"
37 #include "list-inl.h"
38 #include "property-details.h"
39 
40 namespace v8 {
41 namespace internal {
42 
43 
44 template <class C>
45 static C* FindInstanceOf(Object* obj) {
46  for (Object* cur = obj; !cur->IsNull(); cur = cur->GetPrototype()) {
47  if (Is<C>(cur)) return C::cast(cur);
48  }
49  return NULL;
50 }
51 
52 
53 // Entry point that never should be called.
54 MaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) {
55  UNREACHABLE();
56  return NULL;
57 }
58 
59 
60 Object* Accessors::IllegalGetAccessor(Object* object, void*) {
61  UNREACHABLE();
62  return object;
63 }
64 
65 
66 MaybeObject* Accessors::ReadOnlySetAccessor(JSObject*, Object* value, void*) {
67  // According to ECMA-262, section 8.6.2.2, page 28, setting
68  // read-only properties must be silently ignored.
69  return value;
70 }
71 
72 
73 //
74 // Accessors::ArrayLength
75 //
76 
77 
78 MaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
79  // Traverse the prototype chain until we reach an array.
80  JSArray* holder = FindInstanceOf<JSArray>(object);
81  return holder == NULL ? Smi::FromInt(0) : holder->length();
82 }
83 
84 
85 // The helper function will 'flatten' Number objects.
86 Object* Accessors::FlattenNumber(Object* value) {
87  if (value->IsNumber() || !value->IsJSValue()) return value;
88  JSValue* wrapper = JSValue::cast(value);
89  ASSERT(Isolate::Current()->context()->native_context()->number_function()->
90  has_initial_map());
91  Map* number_map = Isolate::Current()->context()->native_context()->
92  number_function()->initial_map();
93  if (wrapper->map() == number_map) return wrapper->value();
94  return value;
95 }
96 
97 
98 MaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) {
99  Isolate* isolate = object->GetIsolate();
100 
101  // This means one of the object's prototypes is a JSArray and the
102  // object does not have a 'length' property. Calling SetProperty
103  // causes an infinite loop.
104  if (!object->IsJSArray()) {
105  return object->SetLocalPropertyIgnoreAttributes(
106  isolate->heap()->length_symbol(), value, NONE);
107  }
108 
109  value = FlattenNumber(value);
110 
111  // Need to call methods that may trigger GC.
112  HandleScope scope(isolate);
113 
114  // Protect raw pointers.
115  Handle<JSObject> object_handle(object, isolate);
116  Handle<Object> value_handle(value, isolate);
117 
118  bool has_exception;
119  Handle<Object> uint32_v = Execution::ToUint32(value_handle, &has_exception);
120  if (has_exception) return Failure::Exception();
121  Handle<Object> number_v = Execution::ToNumber(value_handle, &has_exception);
122  if (has_exception) return Failure::Exception();
123 
124  if (uint32_v->Number() == number_v->Number()) {
125  return Handle<JSArray>::cast(object_handle)->SetElementsLength(*uint32_v);
126  }
127  return isolate->Throw(
128  *isolate->factory()->NewRangeError("invalid_array_length",
129  HandleVector<Object>(NULL, 0)));
130 }
131 
132 
133 const AccessorDescriptor Accessors::ArrayLength = {
134  ArrayGetLength,
135  ArraySetLength,
136  0
137 };
138 
139 
140 //
141 // Accessors::StringLength
142 //
143 
144 
145 MaybeObject* Accessors::StringGetLength(Object* object, void*) {
146  Object* value = object;
147  if (object->IsJSValue()) value = JSValue::cast(object)->value();
148  if (value->IsString()) return Smi::FromInt(String::cast(value)->length());
149  // If object is not a string we return 0 to be compatible with WebKit.
150  // Note: Firefox returns the length of ToString(object).
151  return Smi::FromInt(0);
152 }
153 
154 
155 const AccessorDescriptor Accessors::StringLength = {
156  StringGetLength,
157  IllegalSetter,
158  0
159 };
160 
161 
162 //
163 // Accessors::ScriptSource
164 //
165 
166 
167 MaybeObject* Accessors::ScriptGetSource(Object* object, void*) {
168  Object* script = JSValue::cast(object)->value();
169  return Script::cast(script)->source();
170 }
171 
172 
173 const AccessorDescriptor Accessors::ScriptSource = {
174  ScriptGetSource,
175  IllegalSetter,
176  0
177 };
178 
179 
180 //
181 // Accessors::ScriptName
182 //
183 
184 
185 MaybeObject* Accessors::ScriptGetName(Object* object, void*) {
186  Object* script = JSValue::cast(object)->value();
187  return Script::cast(script)->name();
188 }
189 
190 
191 const AccessorDescriptor Accessors::ScriptName = {
192  ScriptGetName,
193  IllegalSetter,
194  0
195 };
196 
197 
198 //
199 // Accessors::ScriptId
200 //
201 
202 
203 MaybeObject* Accessors::ScriptGetId(Object* object, void*) {
204  Object* script = JSValue::cast(object)->value();
205  return Script::cast(script)->id();
206 }
207 
208 
209 const AccessorDescriptor Accessors::ScriptId = {
210  ScriptGetId,
211  IllegalSetter,
212  0
213 };
214 
215 
216 //
217 // Accessors::ScriptLineOffset
218 //
219 
220 
221 MaybeObject* Accessors::ScriptGetLineOffset(Object* object, void*) {
222  Object* script = JSValue::cast(object)->value();
223  return Script::cast(script)->line_offset();
224 }
225 
226 
227 const AccessorDescriptor Accessors::ScriptLineOffset = {
228  ScriptGetLineOffset,
229  IllegalSetter,
230  0
231 };
232 
233 
234 //
235 // Accessors::ScriptColumnOffset
236 //
237 
238 
239 MaybeObject* Accessors::ScriptGetColumnOffset(Object* object, void*) {
240  Object* script = JSValue::cast(object)->value();
241  return Script::cast(script)->column_offset();
242 }
243 
244 
245 const AccessorDescriptor Accessors::ScriptColumnOffset = {
246  ScriptGetColumnOffset,
247  IllegalSetter,
248  0
249 };
250 
251 
252 //
253 // Accessors::ScriptData
254 //
255 
256 
257 MaybeObject* Accessors::ScriptGetData(Object* object, void*) {
258  Object* script = JSValue::cast(object)->value();
259  return Script::cast(script)->data();
260 }
261 
262 
263 const AccessorDescriptor Accessors::ScriptData = {
264  ScriptGetData,
265  IllegalSetter,
266  0
267 };
268 
269 
270 //
271 // Accessors::ScriptType
272 //
273 
274 
275 MaybeObject* Accessors::ScriptGetType(Object* object, void*) {
276  Object* script = JSValue::cast(object)->value();
277  return Script::cast(script)->type();
278 }
279 
280 
281 const AccessorDescriptor Accessors::ScriptType = {
282  ScriptGetType,
283  IllegalSetter,
284  0
285 };
286 
287 
288 //
289 // Accessors::ScriptCompilationType
290 //
291 
292 
293 MaybeObject* Accessors::ScriptGetCompilationType(Object* object, void*) {
294  Object* script = JSValue::cast(object)->value();
295  return Script::cast(script)->compilation_type();
296 }
297 
298 
299 const AccessorDescriptor Accessors::ScriptCompilationType = {
300  ScriptGetCompilationType,
301  IllegalSetter,
302  0
303 };
304 
305 
306 //
307 // Accessors::ScriptGetLineEnds
308 //
309 
310 
311 MaybeObject* Accessors::ScriptGetLineEnds(Object* object, void*) {
312  JSValue* wrapper = JSValue::cast(object);
313  Isolate* isolate = wrapper->GetIsolate();
314  HandleScope scope(isolate);
315  Handle<Script> script(Script::cast(wrapper->value()), isolate);
316  InitScriptLineEnds(script);
317  ASSERT(script->line_ends()->IsFixedArray());
318  Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
319  // We do not want anyone to modify this array from JS.
320  ASSERT(*line_ends == isolate->heap()->empty_fixed_array() ||
321  line_ends->map() == isolate->heap()->fixed_cow_array_map());
322  Handle<JSArray> js_array =
323  isolate->factory()->NewJSArrayWithElements(line_ends);
324  return *js_array;
325 }
326 
327 
328 const AccessorDescriptor Accessors::ScriptLineEnds = {
329  ScriptGetLineEnds,
330  IllegalSetter,
331  0
332 };
333 
334 
335 //
336 // Accessors::ScriptGetContextData
337 //
338 
339 
340 MaybeObject* Accessors::ScriptGetContextData(Object* object, void*) {
341  Object* script = JSValue::cast(object)->value();
342  return Script::cast(script)->context_data();
343 }
344 
345 
346 const AccessorDescriptor Accessors::ScriptContextData = {
347  ScriptGetContextData,
348  IllegalSetter,
349  0
350 };
351 
352 
353 //
354 // Accessors::ScriptGetEvalFromScript
355 //
356 
357 
358 MaybeObject* Accessors::ScriptGetEvalFromScript(Object* object, void*) {
359  Object* script = JSValue::cast(object)->value();
360  if (!Script::cast(script)->eval_from_shared()->IsUndefined()) {
361  Handle<SharedFunctionInfo> eval_from_shared(
362  SharedFunctionInfo::cast(Script::cast(script)->eval_from_shared()));
363 
364  if (eval_from_shared->script()->IsScript()) {
365  Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
366  return *GetScriptWrapper(eval_from_script);
367  }
368  }
369  return HEAP->undefined_value();
370 }
371 
372 
373 const AccessorDescriptor Accessors::ScriptEvalFromScript = {
374  ScriptGetEvalFromScript,
375  IllegalSetter,
376  0
377 };
378 
379 
380 //
381 // Accessors::ScriptGetEvalFromScriptPosition
382 //
383 
384 
385 MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Object* object, void*) {
386  HandleScope scope;
387  Handle<Script> script(Script::cast(JSValue::cast(object)->value()));
388 
389  // If this is not a script compiled through eval there is no eval position.
390  int compilation_type = Smi::cast(script->compilation_type())->value();
391  if (compilation_type != Script::COMPILATION_TYPE_EVAL) {
392  return HEAP->undefined_value();
393  }
394 
395  // Get the function from where eval was called and find the source position
396  // from the instruction offset.
397  Handle<Code> code(SharedFunctionInfo::cast(
398  script->eval_from_shared())->code());
399  return Smi::FromInt(code->SourcePosition(code->instruction_start() +
400  script->eval_from_instructions_offset()->value()));
401 }
402 
403 
404 const AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
405  ScriptGetEvalFromScriptPosition,
406  IllegalSetter,
407  0
408 };
409 
410 
411 //
412 // Accessors::ScriptGetEvalFromFunctionName
413 //
414 
415 
416 MaybeObject* Accessors::ScriptGetEvalFromFunctionName(Object* object, void*) {
417  Object* script = JSValue::cast(object)->value();
418  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(
419  Script::cast(script)->eval_from_shared()));
420 
421 
422  // Find the name of the function calling eval.
423  if (!shared->name()->IsUndefined()) {
424  return shared->name();
425  } else {
426  return shared->inferred_name();
427  }
428 }
429 
430 
431 const AccessorDescriptor Accessors::ScriptEvalFromFunctionName = {
432  ScriptGetEvalFromFunctionName,
433  IllegalSetter,
434  0
435 };
436 
437 
438 //
439 // Accessors::FunctionPrototype
440 //
441 
442 
443 MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
444  Heap* heap = Isolate::Current()->heap();
445  JSFunction* function = FindInstanceOf<JSFunction>(object);
446  if (function == NULL) return heap->undefined_value();
447  while (!function->should_have_prototype()) {
448  function = FindInstanceOf<JSFunction>(function->GetPrototype());
449  // There has to be one because we hit the getter.
450  ASSERT(function != NULL);
451  }
452 
453  if (!function->has_prototype()) {
454  Object* prototype;
455  { MaybeObject* maybe_prototype = heap->AllocateFunctionPrototype(function);
456  if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
457  }
458  Object* result;
459  { MaybeObject* maybe_result = function->SetPrototype(prototype);
460  if (!maybe_result->ToObject(&result)) return maybe_result;
461  }
462  }
463  return function->prototype();
464 }
465 
466 
468  Object* value,
469  void*) {
470  Heap* heap = object->GetHeap();
471  JSFunction* function = FindInstanceOf<JSFunction>(object);
472  if (function == NULL) return heap->undefined_value();
473  if (!function->should_have_prototype()) {
474  // Since we hit this accessor, object will have no prototype property.
475  return object->SetLocalPropertyIgnoreAttributes(heap->prototype_symbol(),
476  value,
477  NONE);
478  }
479 
480  Object* prototype;
481  { MaybeObject* maybe_prototype = function->SetPrototype(value);
482  if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
483  }
484  ASSERT(function->prototype() == value);
485  return function;
486 }
487 
488 
489 const AccessorDescriptor Accessors::FunctionPrototype = {
490  FunctionGetPrototype,
491  FunctionSetPrototype,
492  0
493 };
494 
495 
496 //
497 // Accessors::FunctionLength
498 //
499 
500 
501 MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
502  JSFunction* function = FindInstanceOf<JSFunction>(object);
503  if (function == NULL) return Smi::FromInt(0);
504  // Check if already compiled.
505  if (function->shared()->is_compiled()) {
506  return Smi::FromInt(function->shared()->length());
507  }
508  // If the function isn't compiled yet, the length is not computed correctly
509  // yet. Compile it now and return the right length.
510  HandleScope scope;
511  Handle<JSFunction> handle(function);
513  return Smi::FromInt(handle->shared()->length());
514  }
515  return Failure::Exception();
516 }
517 
518 
519 const AccessorDescriptor Accessors::FunctionLength = {
520  FunctionGetLength,
521  ReadOnlySetAccessor,
522  0
523 };
524 
525 
526 //
527 // Accessors::FunctionName
528 //
529 
530 
531 MaybeObject* Accessors::FunctionGetName(Object* object, void*) {
532  JSFunction* holder = FindInstanceOf<JSFunction>(object);
533  return holder == NULL ? HEAP->undefined_value() : holder->shared()->name();
534 }
535 
536 
537 const AccessorDescriptor Accessors::FunctionName = {
538  FunctionGetName,
539  ReadOnlySetAccessor,
540  0
541 };
542 
543 
544 //
545 // Accessors::FunctionArguments
546 //
547 
548 
549 static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
550  JavaScriptFrame* frame,
551  Handle<JSFunction> inlined_function,
552  int inlined_frame_index) {
553  Factory* factory = Isolate::Current()->factory();
554  Vector<SlotRef> args_slots =
555  SlotRef::ComputeSlotMappingForArguments(
556  frame,
557  inlined_frame_index,
558  inlined_function->shared()->formal_parameter_count());
559  int args_count = args_slots.length();
560  Handle<JSObject> arguments =
561  factory->NewArgumentsObject(inlined_function, args_count);
562  Handle<FixedArray> array = factory->NewFixedArray(args_count);
563  for (int i = 0; i < args_count; ++i) {
564  Handle<Object> value = args_slots[i].GetValue();
565  array->set(i, *value);
566  }
567  arguments->set_elements(*array);
568  args_slots.Dispose();
569 
570  // Return the freshly allocated arguments object.
571  return *arguments;
572 }
573 
574 
575 MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
576  Isolate* isolate = Isolate::Current();
577  HandleScope scope(isolate);
578  JSFunction* holder = FindInstanceOf<JSFunction>(object);
579  if (holder == NULL) return isolate->heap()->undefined_value();
580  Handle<JSFunction> function(holder, isolate);
581 
582  if (function->shared()->native()) return isolate->heap()->null_value();
583  // Find the top invocation of the function by traversing frames.
584  List<JSFunction*> functions(2);
585  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
586  JavaScriptFrame* frame = it.frame();
587  frame->GetFunctions(&functions);
588  for (int i = functions.length() - 1; i >= 0; i--) {
589  // Skip all frames that aren't invocations of the given function.
590  if (functions[i] != *function) continue;
591 
592  if (i > 0) {
593  // The function in question was inlined. Inlined functions have the
594  // correct number of arguments and no allocated arguments object, so
595  // we can construct a fresh one by interpreting the function's
596  // deoptimization input data.
597  return ConstructArgumentsObjectForInlinedFunction(frame, function, i);
598  }
599 
600  if (!frame->is_optimized()) {
601  // If there is an arguments variable in the stack, we return that.
602  Handle<ScopeInfo> scope_info(function->shared()->scope_info());
603  int index = scope_info->StackSlotIndex(
604  isolate->heap()->arguments_symbol());
605  if (index >= 0) {
606  Handle<Object> arguments(frame->GetExpression(index), isolate);
607  if (!arguments->IsArgumentsMarker()) return *arguments;
608  }
609  }
610 
611  // If there is no arguments variable in the stack or we have an
612  // optimized frame, we find the frame that holds the actual arguments
613  // passed to the function.
614  it.AdvanceToArgumentsFrame();
615  frame = it.frame();
616 
617  // Get the number of arguments and construct an arguments object
618  // mirror for the right frame.
619  const int length = frame->ComputeParametersCount();
620  Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
621  function, length);
622  Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
623 
624  // Copy the parameters to the arguments object.
625  ASSERT(array->length() == length);
626  for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
627  arguments->set_elements(*array);
628 
629  // Return the freshly allocated arguments object.
630  return *arguments;
631  }
632  functions.Rewind(0);
633  }
634 
635  // No frame corresponding to the given function found. Return null.
636  return isolate->heap()->null_value();
637 }
638 
639 
640 const AccessorDescriptor Accessors::FunctionArguments = {
641  FunctionGetArguments,
642  ReadOnlySetAccessor,
643  0
644 };
645 
646 
647 //
648 // Accessors::FunctionCaller
649 //
650 
651 
652 static MaybeObject* CheckNonStrictCallerOrThrow(
653  Isolate* isolate,
654  JSFunction* caller) {
655  DisableAssertNoAllocation enable_allocation;
656  if (!caller->shared()->is_classic_mode()) {
657  return isolate->Throw(
658  *isolate->factory()->NewTypeError("strict_caller",
659  HandleVector<Object>(NULL, 0)));
660  }
661  return caller;
662 }
663 
664 
666  public:
668  : frame_iterator_(isolate),
669  functions_(2),
670  index_(0) {
671  GetFunctions();
672  }
674  if (functions_.length() == 0) return NULL;
675  JSFunction* next_function = functions_[index_];
676  index_--;
677  if (index_ < 0) {
678  GetFunctions();
679  }
680  return next_function;
681  }
682 
683  // Iterate through functions until the first occurence of 'function'.
684  // Returns true if 'function' is found, and false if the iterator ends
685  // without finding it.
686  bool Find(JSFunction* function) {
687  JSFunction* next_function;
688  do {
689  next_function = next();
690  if (next_function == function) return true;
691  } while (next_function != NULL);
692  return false;
693  }
694 
695  private:
696  void GetFunctions() {
697  functions_.Rewind(0);
698  if (frame_iterator_.done()) return;
699  JavaScriptFrame* frame = frame_iterator_.frame();
700  frame->GetFunctions(&functions_);
701  ASSERT(functions_.length() > 0);
702  frame_iterator_.Advance();
703  index_ = functions_.length() - 1;
704  }
705  JavaScriptFrameIterator frame_iterator_;
706  List<JSFunction*> functions_;
707  int index_;
708 };
709 
710 
711 MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
712  Isolate* isolate = Isolate::Current();
713  HandleScope scope(isolate);
714  AssertNoAllocation no_alloc;
715  JSFunction* holder = FindInstanceOf<JSFunction>(object);
716  if (holder == NULL) return isolate->heap()->undefined_value();
717  if (holder->shared()->native()) return isolate->heap()->null_value();
718  Handle<JSFunction> function(holder, isolate);
719 
720  FrameFunctionIterator it(isolate, no_alloc);
721 
722  // Find the function from the frames.
723  if (!it.Find(*function)) {
724  // No frame corresponding to the given function found. Return null.
725  return isolate->heap()->null_value();
726  }
727 
728  // Find previously called non-toplevel function.
729  JSFunction* caller;
730  do {
731  caller = it.next();
732  if (caller == NULL) return isolate->heap()->null_value();
733  } while (caller->shared()->is_toplevel());
734 
735  // If caller is a built-in function and caller's caller is also built-in,
736  // use that instead.
737  JSFunction* potential_caller = caller;
738  while (potential_caller != NULL && potential_caller->IsBuiltin()) {
739  caller = potential_caller;
740  potential_caller = it.next();
741  }
742  if (!caller->shared()->native() && potential_caller != NULL) {
743  caller = potential_caller;
744  }
745  // If caller is bound, return null. This is compatible with JSC, and
746  // allows us to make bound functions use the strict function map
747  // and its associated throwing caller and arguments.
748  if (caller->shared()->bound()) {
749  return isolate->heap()->null_value();
750  }
751  return CheckNonStrictCallerOrThrow(isolate, caller);
752 }
753 
754 
755 const AccessorDescriptor Accessors::FunctionCaller = {
756  FunctionGetCaller,
757  ReadOnlySetAccessor,
758  0
759 };
760 
761 
762 //
763 // Accessors::ObjectPrototype
764 //
765 
766 
767 MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
768  Object* current = receiver->GetPrototype();
769  while (current->IsJSObject() &&
770  JSObject::cast(current)->map()->is_hidden_prototype()) {
771  current = current->GetPrototype();
772  }
773  return current;
774 }
775 
776 
777 MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver,
778  Object* value,
779  void*) {
780  const bool skip_hidden_prototypes = true;
781  // To be consistent with other Set functions, return the value.
782  return receiver->SetPrototype(value, skip_hidden_prototypes);
783 }
784 
785 
786 const AccessorDescriptor Accessors::ObjectPrototype = {
787  ObjectGetPrototype,
788  ObjectSetPrototype,
789  0
790 };
791 
792 
793 //
794 // Accessors::MakeModuleExport
795 //
796 
797 static v8::Handle<v8::Value> ModuleGetExport(
798  v8::Local<v8::String> property,
799  const v8::AccessorInfo& info) {
800  JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
801  Context* context = Context::cast(instance->context());
802  ASSERT(context->IsModuleContext());
803  int slot = info.Data()->Int32Value();
804  Object* value = context->get(slot);
805  if (value->IsTheHole()) {
806  Handle<String> name = v8::Utils::OpenHandle(*property);
807  Isolate* isolate = instance->GetIsolate();
808  isolate->ScheduleThrow(
809  *isolate->factory()->NewReferenceError("not_defined",
810  HandleVector(&name, 1)));
811  return v8::Handle<v8::Value>();
812  }
813  return v8::Utils::ToLocal(Handle<Object>(value));
814 }
815 
816 
817 static void ModuleSetExport(
818  v8::Local<v8::String> property,
819  v8::Local<v8::Value> value,
820  const v8::AccessorInfo& info) {
821  JSModule* instance = JSModule::cast(*v8::Utils::OpenHandle(*info.Holder()));
822  Context* context = Context::cast(instance->context());
823  ASSERT(context->IsModuleContext());
824  int slot = info.Data()->Int32Value();
825  Object* old_value = context->get(slot);
826  if (old_value->IsTheHole()) {
827  Handle<String> name = v8::Utils::OpenHandle(*property);
828  Isolate* isolate = instance->GetIsolate();
829  isolate->ScheduleThrow(
830  *isolate->factory()->NewReferenceError("not_defined",
831  HandleVector(&name, 1)));
832  return;
833  }
834  context->set(slot, *v8::Utils::OpenHandle(*value));
835 }
836 
837 
839  Handle<String> name,
840  int index,
841  PropertyAttributes attributes) {
842  Factory* factory = name->GetIsolate()->factory();
843  Handle<AccessorInfo> info = factory->NewAccessorInfo();
844  info->set_property_attributes(attributes);
845  info->set_all_can_read(true);
846  info->set_all_can_write(true);
847  info->set_name(*name);
848  info->set_data(Smi::FromInt(index));
849  Handle<Object> getter = v8::FromCData(&ModuleGetExport);
850  Handle<Object> setter = v8::FromCData(&ModuleSetExport);
851  info->set_getter(*getter);
852  if (!(attributes & ReadOnly)) info->set_setter(*setter);
853  return info;
854 }
855 
856 
857 } } // namespace v8::internal
static bool CompileLazy(Handle< JSFunction > function, ClearExceptionFlag flag)
Definition: objects.cc:7643
bool Find(JSFunction *function)
Definition: accessors.cc:686
static Handle< Object > ToUint32(Handle< Object > obj, bool *exc)
Definition: execution.cc:660
MUST_USE_RESULT MaybeObject * AllocateFunctionPrototype(JSFunction *function)
Definition: heap.cc:3782
bool is_hidden_prototype()
Definition: objects.h:4725
static String * cast(Object *obj)
static Smi * FromInt(int value)
Definition: objects-inl.h:981
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
Handle< AccessorInfo > NewAccessorInfo()
Definition: factory.cc:366
static Failure * Exception()
Definition: objects-inl.h:1024
Object * GetExpression(int index) const
Definition: frames-inl.h:153
void InitScriptLineEnds(Handle< Script > script)
Definition: handles.cc:394
#define ASSERT(condition)
Definition: checks.h:270
static Script * cast(Object *obj)
static Context * cast(Object *context)
Definition: contexts.h:212
static SharedFunctionInfo * cast(Object *obj)
Handle< JSObject > NewArgumentsObject(Handle< Object > callee, int length)
Definition: factory.cc:1198
Factory * factory()
Definition: isolate.h:992
PropertyAttributes
int ComputeParametersCount() const
Definition: frames.h:499
static Smi * cast(Object *object)
Local< Object > Holder() const
Definition: v8.h:4628
#define UNREACHABLE()
Definition: checks.h:50
Handle< JSValue > GetScriptWrapper(Handle< Script > script)
Definition: handles.cc:366
Handle< FixedArray > NewFixedArray(int size, PretenureFlag pretenure=NOT_TENURED)
Definition: factory.cc:44
static MaybeObject * FunctionGetArguments(Object *object, void *)
Definition: accessors.cc:575
static Local< Context > ToLocal(v8::internal::Handle< v8::internal::Context > obj)
static Handle< AccessorInfo > MakeModuleExport(Handle< String > name, int index, PropertyAttributes attributes)
Definition: accessors.cc:838
static MUST_USE_RESULT MaybeObject * FunctionSetPrototype(JSObject *object, Object *value, void *)
Definition: accessors.cc:467
FrameFunctionIterator(Isolate *isolate, const AssertNoAllocation &promise)
Definition: accessors.cc:667
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
Definition: frames.h:775
virtual void GetFunctions(List< JSFunction * > *functions)
Definition: frames.cc:735
static MUST_USE_RESULT MaybeObject * FunctionGetPrototype(Object *object, void *)
Definition: accessors.cc:443
v8::internal::Handle< v8::internal::Object > FromCData(T obj)
Definition: api.h:128
static JSValue * cast(Object *obj)
Definition: objects-inl.h:4600
#define HEAP
Definition: isolate.h:1433
static Handle< Object > ToNumber(Handle< Object > obj, bool *exc)
Definition: execution.cc:634
static FixedArray * cast(Object *obj)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
Local< Value > Data() const
Definition: v8.h:4618
Vector< Handle< Object > > HandleVector(v8::internal::Handle< T > *elms, int length)
Definition: v8utils.h:117
static JSModule * cast(Object *obj)
Definition: objects-inl.h:4590
Definition: v8.h:106
Object * GetParameter(int index) const
Definition: frames-inl.h:211
static JSObject * cast(Object *obj)