v8  3.11.10(node0.8.26)
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* FindInPrototypeChain(Object* obj, bool* found_it) {
46  ASSERT(!*found_it);
47  Heap* heap = HEAP;
48  while (!Is<C>(obj)) {
49  if (obj == heap->null_value()) return NULL;
50  obj = obj->GetPrototype();
51  }
52  *found_it = true;
53  return C::cast(obj);
54 }
55 
56 
57 // Entry point that never should be called.
58 MaybeObject* Accessors::IllegalSetter(JSObject*, Object*, void*) {
59  UNREACHABLE();
60  return NULL;
61 }
62 
63 
64 Object* Accessors::IllegalGetAccessor(Object* object, void*) {
65  UNREACHABLE();
66  return object;
67 }
68 
69 
70 MaybeObject* Accessors::ReadOnlySetAccessor(JSObject*, Object* value, void*) {
71  // According to ECMA-262, section 8.6.2.2, page 28, setting
72  // read-only properties must be silently ignored.
73  return value;
74 }
75 
76 
77 //
78 // Accessors::ArrayLength
79 //
80 
81 
82 MaybeObject* Accessors::ArrayGetLength(Object* object, void*) {
83  // Traverse the prototype chain until we reach an array.
84  bool found_it = false;
85  JSArray* holder = FindInPrototypeChain<JSArray>(object, &found_it);
86  if (!found_it) return Smi::FromInt(0);
87  return holder->length();
88 }
89 
90 
91 // The helper function will 'flatten' Number objects.
92 Object* Accessors::FlattenNumber(Object* value) {
93  if (value->IsNumber() || !value->IsJSValue()) return value;
94  JSValue* wrapper = JSValue::cast(value);
95  ASSERT(Isolate::Current()->context()->global_context()->number_function()->
96  has_initial_map());
97  Map* number_map = Isolate::Current()->context()->global_context()->
98  number_function()->initial_map();
99  if (wrapper->map() == number_map) return wrapper->value();
100  return value;
101 }
102 
103 
104 MaybeObject* Accessors::ArraySetLength(JSObject* object, Object* value, void*) {
105  Isolate* isolate = object->GetIsolate();
106 
107  // This means one of the object's prototypes is a JSArray and the
108  // object does not have a 'length' property. Calling SetProperty
109  // causes an infinite loop.
110  if (!object->IsJSArray()) {
111  return object->SetLocalPropertyIgnoreAttributes(
112  isolate->heap()->length_symbol(), value, NONE);
113  }
114 
115  value = FlattenNumber(value);
116 
117  // Need to call methods that may trigger GC.
118  HandleScope scope(isolate);
119 
120  // Protect raw pointers.
121  Handle<JSObject> object_handle(object, isolate);
122  Handle<Object> value_handle(value, isolate);
123 
124  bool has_exception;
125  Handle<Object> uint32_v = Execution::ToUint32(value_handle, &has_exception);
126  if (has_exception) return Failure::Exception();
127  Handle<Object> number_v = Execution::ToNumber(value_handle, &has_exception);
128  if (has_exception) return Failure::Exception();
129 
130  if (uint32_v->Number() == number_v->Number()) {
131  return Handle<JSArray>::cast(object_handle)->SetElementsLength(*uint32_v);
132  }
133  return isolate->Throw(
134  *isolate->factory()->NewRangeError("invalid_array_length",
135  HandleVector<Object>(NULL, 0)));
136 }
137 
138 
139 const AccessorDescriptor Accessors::ArrayLength = {
140  ArrayGetLength,
141  ArraySetLength,
142  0
143 };
144 
145 
146 //
147 // Accessors::StringLength
148 //
149 
150 
151 MaybeObject* Accessors::StringGetLength(Object* object, void*) {
152  Object* value = object;
153  if (object->IsJSValue()) value = JSValue::cast(object)->value();
154  if (value->IsString()) return Smi::FromInt(String::cast(value)->length());
155  // If object is not a string we return 0 to be compatible with WebKit.
156  // Note: Firefox returns the length of ToString(object).
157  return Smi::FromInt(0);
158 }
159 
160 
161 const AccessorDescriptor Accessors::StringLength = {
162  StringGetLength,
163  IllegalSetter,
164  0
165 };
166 
167 
168 //
169 // Accessors::ScriptSource
170 //
171 
172 
173 MaybeObject* Accessors::ScriptGetSource(Object* object, void*) {
174  Object* script = JSValue::cast(object)->value();
175  return Script::cast(script)->source();
176 }
177 
178 
179 const AccessorDescriptor Accessors::ScriptSource = {
180  ScriptGetSource,
181  IllegalSetter,
182  0
183 };
184 
185 
186 //
187 // Accessors::ScriptName
188 //
189 
190 
191 MaybeObject* Accessors::ScriptGetName(Object* object, void*) {
192  Object* script = JSValue::cast(object)->value();
193  return Script::cast(script)->name();
194 }
195 
196 
197 const AccessorDescriptor Accessors::ScriptName = {
198  ScriptGetName,
199  IllegalSetter,
200  0
201 };
202 
203 
204 //
205 // Accessors::ScriptId
206 //
207 
208 
209 MaybeObject* Accessors::ScriptGetId(Object* object, void*) {
210  Object* script = JSValue::cast(object)->value();
211  return Script::cast(script)->id();
212 }
213 
214 
215 const AccessorDescriptor Accessors::ScriptId = {
216  ScriptGetId,
217  IllegalSetter,
218  0
219 };
220 
221 
222 //
223 // Accessors::ScriptLineOffset
224 //
225 
226 
227 MaybeObject* Accessors::ScriptGetLineOffset(Object* object, void*) {
228  Object* script = JSValue::cast(object)->value();
229  return Script::cast(script)->line_offset();
230 }
231 
232 
233 const AccessorDescriptor Accessors::ScriptLineOffset = {
234  ScriptGetLineOffset,
235  IllegalSetter,
236  0
237 };
238 
239 
240 //
241 // Accessors::ScriptColumnOffset
242 //
243 
244 
245 MaybeObject* Accessors::ScriptGetColumnOffset(Object* object, void*) {
246  Object* script = JSValue::cast(object)->value();
247  return Script::cast(script)->column_offset();
248 }
249 
250 
251 const AccessorDescriptor Accessors::ScriptColumnOffset = {
252  ScriptGetColumnOffset,
253  IllegalSetter,
254  0
255 };
256 
257 
258 //
259 // Accessors::ScriptData
260 //
261 
262 
263 MaybeObject* Accessors::ScriptGetData(Object* object, void*) {
264  Object* script = JSValue::cast(object)->value();
265  return Script::cast(script)->data();
266 }
267 
268 
269 const AccessorDescriptor Accessors::ScriptData = {
270  ScriptGetData,
271  IllegalSetter,
272  0
273 };
274 
275 
276 //
277 // Accessors::ScriptType
278 //
279 
280 
281 MaybeObject* Accessors::ScriptGetType(Object* object, void*) {
282  Object* script = JSValue::cast(object)->value();
283  return Script::cast(script)->type();
284 }
285 
286 
287 const AccessorDescriptor Accessors::ScriptType = {
288  ScriptGetType,
289  IllegalSetter,
290  0
291 };
292 
293 
294 //
295 // Accessors::ScriptCompilationType
296 //
297 
298 
299 MaybeObject* Accessors::ScriptGetCompilationType(Object* object, void*) {
300  Object* script = JSValue::cast(object)->value();
301  return Script::cast(script)->compilation_type();
302 }
303 
304 
305 const AccessorDescriptor Accessors::ScriptCompilationType = {
306  ScriptGetCompilationType,
307  IllegalSetter,
308  0
309 };
310 
311 
312 //
313 // Accessors::ScriptGetLineEnds
314 //
315 
316 
317 MaybeObject* Accessors::ScriptGetLineEnds(Object* object, void*) {
318  JSValue* wrapper = JSValue::cast(object);
319  Isolate* isolate = wrapper->GetIsolate();
320  HandleScope scope(isolate);
321  Handle<Script> script(Script::cast(wrapper->value()), isolate);
322  InitScriptLineEnds(script);
323  ASSERT(script->line_ends()->IsFixedArray());
324  Handle<FixedArray> line_ends(FixedArray::cast(script->line_ends()));
325  // We do not want anyone to modify this array from JS.
326  ASSERT(*line_ends == isolate->heap()->empty_fixed_array() ||
327  line_ends->map() == isolate->heap()->fixed_cow_array_map());
328  Handle<JSArray> js_array =
329  isolate->factory()->NewJSArrayWithElements(line_ends);
330  return *js_array;
331 }
332 
333 
334 const AccessorDescriptor Accessors::ScriptLineEnds = {
335  ScriptGetLineEnds,
336  IllegalSetter,
337  0
338 };
339 
340 
341 //
342 // Accessors::ScriptGetContextData
343 //
344 
345 
346 MaybeObject* Accessors::ScriptGetContextData(Object* object, void*) {
347  Object* script = JSValue::cast(object)->value();
348  return Script::cast(script)->context_data();
349 }
350 
351 
352 const AccessorDescriptor Accessors::ScriptContextData = {
353  ScriptGetContextData,
354  IllegalSetter,
355  0
356 };
357 
358 
359 //
360 // Accessors::ScriptGetEvalFromScript
361 //
362 
363 
364 MaybeObject* Accessors::ScriptGetEvalFromScript(Object* object, void*) {
365  Object* script = JSValue::cast(object)->value();
366  if (!Script::cast(script)->eval_from_shared()->IsUndefined()) {
367  Handle<SharedFunctionInfo> eval_from_shared(
368  SharedFunctionInfo::cast(Script::cast(script)->eval_from_shared()));
369 
370  if (eval_from_shared->script()->IsScript()) {
371  Handle<Script> eval_from_script(Script::cast(eval_from_shared->script()));
372  return *GetScriptWrapper(eval_from_script);
373  }
374  }
375  return HEAP->undefined_value();
376 }
377 
378 
379 const AccessorDescriptor Accessors::ScriptEvalFromScript = {
380  ScriptGetEvalFromScript,
381  IllegalSetter,
382  0
383 };
384 
385 
386 //
387 // Accessors::ScriptGetEvalFromScriptPosition
388 //
389 
390 
391 MaybeObject* Accessors::ScriptGetEvalFromScriptPosition(Object* object, void*) {
392  HandleScope scope;
393  Handle<Script> script(Script::cast(JSValue::cast(object)->value()));
394 
395  // If this is not a script compiled through eval there is no eval position.
396  int compilation_type = Smi::cast(script->compilation_type())->value();
397  if (compilation_type != Script::COMPILATION_TYPE_EVAL) {
398  return HEAP->undefined_value();
399  }
400 
401  // Get the function from where eval was called and find the source position
402  // from the instruction offset.
403  Handle<Code> code(SharedFunctionInfo::cast(
404  script->eval_from_shared())->code());
405  return Smi::FromInt(code->SourcePosition(code->instruction_start() +
406  script->eval_from_instructions_offset()->value()));
407 }
408 
409 
410 const AccessorDescriptor Accessors::ScriptEvalFromScriptPosition = {
411  ScriptGetEvalFromScriptPosition,
412  IllegalSetter,
413  0
414 };
415 
416 
417 //
418 // Accessors::ScriptGetEvalFromFunctionName
419 //
420 
421 
422 MaybeObject* Accessors::ScriptGetEvalFromFunctionName(Object* object, void*) {
423  Object* script = JSValue::cast(object)->value();
424  Handle<SharedFunctionInfo> shared(SharedFunctionInfo::cast(
425  Script::cast(script)->eval_from_shared()));
426 
427 
428  // Find the name of the function calling eval.
429  if (!shared->name()->IsUndefined()) {
430  return shared->name();
431  } else {
432  return shared->inferred_name();
433  }
434 }
435 
436 
437 const AccessorDescriptor Accessors::ScriptEvalFromFunctionName = {
438  ScriptGetEvalFromFunctionName,
439  IllegalSetter,
440  0
441 };
442 
443 
444 //
445 // Accessors::FunctionPrototype
446 //
447 
448 
449 MaybeObject* Accessors::FunctionGetPrototype(Object* object, void*) {
450  Heap* heap = Isolate::Current()->heap();
451  bool found_it = false;
452  JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
453  if (!found_it) return heap->undefined_value();
454  while (!function->should_have_prototype()) {
455  found_it = false;
456  function = FindInPrototypeChain<JSFunction>(object->GetPrototype(),
457  &found_it);
458  // There has to be one because we hit the getter.
459  ASSERT(found_it);
460  }
461 
462  if (!function->has_prototype()) {
463  Object* prototype;
464  { MaybeObject* maybe_prototype = heap->AllocateFunctionPrototype(function);
465  if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
466  }
467  Object* result;
468  { MaybeObject* maybe_result = function->SetPrototype(prototype);
469  if (!maybe_result->ToObject(&result)) return maybe_result;
470  }
471  }
472  return function->prototype();
473 }
474 
475 
477  Object* value,
478  void*) {
479  Heap* heap = object->GetHeap();
480  bool found_it = false;
481  JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
482  if (!found_it) return heap->undefined_value();
483  if (!function->should_have_prototype()) {
484  // Since we hit this accessor, object will have no prototype property.
485  return object->SetLocalPropertyIgnoreAttributes(heap->prototype_symbol(),
486  value,
487  NONE);
488  }
489 
490  Object* prototype;
491  { MaybeObject* maybe_prototype = function->SetPrototype(value);
492  if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
493  }
494  ASSERT(function->prototype() == value);
495  return function;
496 }
497 
498 
499 const AccessorDescriptor Accessors::FunctionPrototype = {
500  FunctionGetPrototype,
501  FunctionSetPrototype,
502  0
503 };
504 
505 
506 //
507 // Accessors::FunctionLength
508 //
509 
510 
511 MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
512  bool found_it = false;
513  JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
514  if (!found_it) return Smi::FromInt(0);
515  // Check if already compiled.
516  if (!function->shared()->is_compiled()) {
517  // If the function isn't compiled yet, the length is not computed
518  // correctly yet. Compile it now and return the right length.
519  HandleScope scope;
520  Handle<JSFunction> handle(function);
521  if (!JSFunction::CompileLazy(handle, KEEP_EXCEPTION)) {
522  return Failure::Exception();
523  }
524  return Smi::FromInt(handle->shared()->length());
525  } else {
526  return Smi::FromInt(function->shared()->length());
527  }
528 }
529 
530 
531 const AccessorDescriptor Accessors::FunctionLength = {
532  FunctionGetLength,
533  ReadOnlySetAccessor,
534  0
535 };
536 
537 
538 //
539 // Accessors::FunctionName
540 //
541 
542 
543 MaybeObject* Accessors::FunctionGetName(Object* object, void*) {
544  bool found_it = false;
545  JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
546  if (!found_it) return HEAP->undefined_value();
547  return holder->shared()->name();
548 }
549 
550 
551 const AccessorDescriptor Accessors::FunctionName = {
552  FunctionGetName,
553  ReadOnlySetAccessor,
554  0
555 };
556 
557 
558 //
559 // Accessors::FunctionArguments
560 //
561 
562 
563 static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
564  JavaScriptFrame* frame,
565  Handle<JSFunction> inlined_function,
566  int inlined_frame_index) {
567  Factory* factory = Isolate::Current()->factory();
568  Vector<SlotRef> args_slots =
569  SlotRef::ComputeSlotMappingForArguments(
570  frame,
571  inlined_frame_index,
572  inlined_function->shared()->formal_parameter_count());
573  int args_count = args_slots.length();
574  Handle<JSObject> arguments =
575  factory->NewArgumentsObject(inlined_function, args_count);
576  Handle<FixedArray> array = factory->NewFixedArray(args_count);
577  for (int i = 0; i < args_count; ++i) {
578  Handle<Object> value = args_slots[i].GetValue();
579  array->set(i, *value);
580  }
581  arguments->set_elements(*array);
582  args_slots.Dispose();
583 
584  // Return the freshly allocated arguments object.
585  return *arguments;
586 }
587 
588 
589 MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
590  Isolate* isolate = Isolate::Current();
591  HandleScope scope(isolate);
592  bool found_it = false;
593  JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
594  if (!found_it) return isolate->heap()->undefined_value();
595  Handle<JSFunction> function(holder, isolate);
596 
597  if (function->shared()->native()) return isolate->heap()->null_value();
598  // Find the top invocation of the function by traversing frames.
599  List<JSFunction*> functions(2);
600  for (JavaScriptFrameIterator it(isolate); !it.done(); it.Advance()) {
601  JavaScriptFrame* frame = it.frame();
602  frame->GetFunctions(&functions);
603  for (int i = functions.length() - 1; i >= 0; i--) {
604  // Skip all frames that aren't invocations of the given function.
605  if (functions[i] != *function) continue;
606 
607  if (i > 0) {
608  // The function in question was inlined. Inlined functions have the
609  // correct number of arguments and no allocated arguments object, so
610  // we can construct a fresh one by interpreting the function's
611  // deoptimization input data.
612  return ConstructArgumentsObjectForInlinedFunction(frame, function, i);
613  }
614 
615  if (!frame->is_optimized()) {
616  // If there is an arguments variable in the stack, we return that.
617  Handle<ScopeInfo> scope_info(function->shared()->scope_info());
618  int index = scope_info->StackSlotIndex(
619  isolate->heap()->arguments_symbol());
620  if (index >= 0) {
621  Handle<Object> arguments(frame->GetExpression(index), isolate);
622  if (!arguments->IsArgumentsMarker()) return *arguments;
623  }
624  }
625 
626  // If there is no arguments variable in the stack or we have an
627  // optimized frame, we find the frame that holds the actual arguments
628  // passed to the function.
629  it.AdvanceToArgumentsFrame();
630  frame = it.frame();
631 
632  // Get the number of arguments and construct an arguments object
633  // mirror for the right frame.
634  const int length = frame->ComputeParametersCount();
635  Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
636  function, length);
637  Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
638 
639  // Copy the parameters to the arguments object.
640  ASSERT(array->length() == length);
641  for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
642  arguments->set_elements(*array);
643 
644  // Return the freshly allocated arguments object.
645  return *arguments;
646  }
647  functions.Rewind(0);
648  }
649 
650  // No frame corresponding to the given function found. Return null.
651  return isolate->heap()->null_value();
652 }
653 
654 
655 const AccessorDescriptor Accessors::FunctionArguments = {
656  FunctionGetArguments,
657  ReadOnlySetAccessor,
658  0
659 };
660 
661 
662 //
663 // Accessors::FunctionCaller
664 //
665 
666 
667 static MaybeObject* CheckNonStrictCallerOrThrow(
668  Isolate* isolate,
669  JSFunction* caller) {
670  DisableAssertNoAllocation enable_allocation;
671  if (!caller->shared()->is_classic_mode()) {
672  return isolate->Throw(
673  *isolate->factory()->NewTypeError("strict_caller",
674  HandleVector<Object>(NULL, 0)));
675  }
676  return caller;
677 }
678 
679 
681  public:
683  : frame_iterator_(isolate),
684  functions_(2),
685  index_(0) {
686  GetFunctions();
687  }
689  if (functions_.length() == 0) return NULL;
690  JSFunction* next_function = functions_[index_];
691  index_--;
692  if (index_ < 0) {
693  GetFunctions();
694  }
695  return next_function;
696  }
697 
698  // Iterate through functions until the first occurence of 'function'.
699  // Returns true if 'function' is found, and false if the iterator ends
700  // without finding it.
701  bool Find(JSFunction* function) {
702  JSFunction* next_function;
703  do {
704  next_function = next();
705  if (next_function == function) return true;
706  } while (next_function != NULL);
707  return false;
708  }
709 
710  private:
711  void GetFunctions() {
712  functions_.Rewind(0);
713  if (frame_iterator_.done()) return;
714  JavaScriptFrame* frame = frame_iterator_.frame();
715  frame->GetFunctions(&functions_);
716  ASSERT(functions_.length() > 0);
717  frame_iterator_.Advance();
718  index_ = functions_.length() - 1;
719  }
720  JavaScriptFrameIterator frame_iterator_;
721  List<JSFunction*> functions_;
722  int index_;
723 };
724 
725 
726 MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
727  Isolate* isolate = Isolate::Current();
728  HandleScope scope(isolate);
729  AssertNoAllocation no_alloc;
730  bool found_it = false;
731  JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
732  if (!found_it) return isolate->heap()->undefined_value();
733  if (holder->shared()->native()) return isolate->heap()->null_value();
734  Handle<JSFunction> function(holder, isolate);
735 
736  FrameFunctionIterator it(isolate, no_alloc);
737 
738  // Find the function from the frames.
739  if (!it.Find(*function)) {
740  // No frame corresponding to the given function found. Return null.
741  return isolate->heap()->null_value();
742  }
743 
744  // Find previously called non-toplevel function.
745  JSFunction* caller;
746  do {
747  caller = it.next();
748  if (caller == NULL) return isolate->heap()->null_value();
749  } while (caller->shared()->is_toplevel());
750 
751  // If caller is a built-in function and caller's caller is also built-in,
752  // use that instead.
753  JSFunction* potential_caller = caller;
754  while (potential_caller != NULL && potential_caller->IsBuiltin()) {
755  caller = potential_caller;
756  potential_caller = it.next();
757  }
758  // If caller is bound, return null. This is compatible with JSC, and
759  // allows us to make bound functions use the strict function map
760  // and its associated throwing caller and arguments.
761  if (caller->shared()->bound()) {
762  return isolate->heap()->null_value();
763  }
764  return CheckNonStrictCallerOrThrow(isolate, caller);
765 }
766 
767 
768 const AccessorDescriptor Accessors::FunctionCaller = {
769  FunctionGetCaller,
770  ReadOnlySetAccessor,
771  0
772 };
773 
774 
775 //
776 // Accessors::ObjectPrototype
777 //
778 
779 
780 MaybeObject* Accessors::ObjectGetPrototype(Object* receiver, void*) {
781  Object* current = receiver->GetPrototype();
782  while (current->IsJSObject() &&
783  JSObject::cast(current)->map()->is_hidden_prototype()) {
784  current = current->GetPrototype();
785  }
786  return current;
787 }
788 
789 
790 MaybeObject* Accessors::ObjectSetPrototype(JSObject* receiver,
791  Object* value,
792  void*) {
793  const bool skip_hidden_prototypes = true;
794  // To be consistent with other Set functions, return the value.
795  return receiver->SetPrototype(value, skip_hidden_prototypes);
796 }
797 
798 
799 const AccessorDescriptor Accessors::ObjectPrototype = {
800  ObjectGetPrototype,
801  ObjectSetPrototype,
802  0
803 };
804 
805 } } // namespace v8::internal
static bool CompileLazy(Handle< JSFunction > function, ClearExceptionFlag flag)
Definition: objects.cc:7465
bool Find(JSFunction *function)
Definition: accessors.cc:701
static Handle< Object > ToUint32(Handle< Object > obj, bool *exc)
Definition: execution.cc:635
MUST_USE_RESULT MaybeObject * AllocateFunctionPrototype(JSFunction *function)
Definition: heap.cc:3661
bool is_hidden_prototype()
Definition: objects.h:4629
static String * cast(Object *obj)
static Smi * FromInt(int value)
Definition: objects-inl.h:973
static Handle< T > cast(Handle< S > that)
Definition: handles.h:81
static Failure * Exception()
Definition: objects-inl.h:1016
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 SharedFunctionInfo * cast(Object *obj)
Handle< JSObject > NewArgumentsObject(Handle< Object > callee, int length)
Definition: factory.cc:1266
Factory * factory()
Definition: isolate.h:977
int ComputeParametersCount() const
Definition: frames.h:499
static Smi * cast(Object *object)
#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
Definition: v8.h:104
static MaybeObject * FunctionGetArguments(Object *object, void *)
Definition: accessors.cc:589
static MUST_USE_RESULT MaybeObject * FunctionSetPrototype(JSObject *object, Object *value, void *)
Definition: accessors.cc:476
FrameFunctionIterator(Isolate *isolate, const AssertNoAllocation &promise)
Definition: accessors.cc:682
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
Definition: frames.h:773
virtual void GetFunctions(List< JSFunction * > *functions)
Definition: frames.cc:735
static MUST_USE_RESULT MaybeObject * FunctionGetPrototype(Object *object, void *)
Definition: accessors.cc:449
static JSValue * cast(Object *obj)
Definition: objects-inl.h:4327
#define HEAP
Definition: isolate.h:1408
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
static Handle< Object > ToNumber(Handle< Object > obj, bool *exc)
Definition: execution.cc:609
static FixedArray * cast(Object *obj)
Object * GetParameter(int index) const
Definition: frames-inl.h:211
static JSObject * cast(Object *obj)