563e80804f5429f4a4fabf48f964b91fd036e948
[platform/upstream/nodejs.git] / deps / v8 / src / runtime / runtime-debug.cc
1 // Copyright 2014 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
7 #include "src/accessors.h"
8 #include "src/arguments.h"
9 #include "src/debug.h"
10 #include "src/deoptimizer.h"
11 #include "src/isolate-inl.h"
12 #include "src/parser.h"
13 #include "src/runtime/runtime.h"
14 #include "src/runtime/runtime-utils.h"
15
16 namespace v8 {
17 namespace internal {
18
19 RUNTIME_FUNCTION(Runtime_DebugBreak) {
20   SealHandleScope shs(isolate);
21   DCHECK(args.length() == 0);
22   isolate->debug()->HandleDebugBreak();
23   return isolate->heap()->undefined_value();
24 }
25
26
27 // Helper functions for wrapping and unwrapping stack frame ids.
28 static Smi* WrapFrameId(StackFrame::Id id) {
29   DCHECK(IsAligned(OffsetFrom(id), static_cast<intptr_t>(4)));
30   return Smi::FromInt(id >> 2);
31 }
32
33
34 static StackFrame::Id UnwrapFrameId(int wrapped) {
35   return static_cast<StackFrame::Id>(wrapped << 2);
36 }
37
38
39 // Adds a JavaScript function as a debug event listener.
40 // args[0]: debug event listener function to set or null or undefined for
41 //          clearing the event listener function
42 // args[1]: object supplied during callback
43 RUNTIME_FUNCTION(Runtime_SetDebugEventListener) {
44   SealHandleScope shs(isolate);
45   DCHECK(args.length() == 2);
46   RUNTIME_ASSERT(args[0]->IsJSFunction() || args[0]->IsUndefined() ||
47                  args[0]->IsNull());
48   CONVERT_ARG_HANDLE_CHECKED(Object, callback, 0);
49   CONVERT_ARG_HANDLE_CHECKED(Object, data, 1);
50   isolate->debug()->SetEventListener(callback, data);
51
52   return isolate->heap()->undefined_value();
53 }
54
55
56 RUNTIME_FUNCTION(Runtime_Break) {
57   SealHandleScope shs(isolate);
58   DCHECK(args.length() == 0);
59   isolate->stack_guard()->RequestDebugBreak();
60   return isolate->heap()->undefined_value();
61 }
62
63
64 static Handle<Object> DebugGetProperty(LookupIterator* it,
65                                        bool* has_caught = NULL) {
66   for (; it->IsFound(); it->Next()) {
67     switch (it->state()) {
68       case LookupIterator::NOT_FOUND:
69       case LookupIterator::TRANSITION:
70         UNREACHABLE();
71       case LookupIterator::ACCESS_CHECK:
72         // Ignore access checks.
73         break;
74       case LookupIterator::INTERCEPTOR:
75       case LookupIterator::JSPROXY:
76         return it->isolate()->factory()->undefined_value();
77       case LookupIterator::ACCESSOR: {
78         Handle<Object> accessors = it->GetAccessors();
79         if (!accessors->IsAccessorInfo()) {
80           return it->isolate()->factory()->undefined_value();
81         }
82         MaybeHandle<Object> maybe_result = JSObject::GetPropertyWithAccessor(
83             it->GetReceiver(), it->name(), it->GetHolder<JSObject>(),
84             accessors);
85         Handle<Object> result;
86         if (!maybe_result.ToHandle(&result)) {
87           result = handle(it->isolate()->pending_exception(), it->isolate());
88           it->isolate()->clear_pending_exception();
89           if (has_caught != NULL) *has_caught = true;
90         }
91         return result;
92       }
93
94       case LookupIterator::DATA:
95         return it->GetDataValue();
96     }
97   }
98
99   return it->isolate()->factory()->undefined_value();
100 }
101
102
103 // Get debugger related details for an object property, in the following format:
104 // 0: Property value
105 // 1: Property details
106 // 2: Property value is exception
107 // 3: Getter function if defined
108 // 4: Setter function if defined
109 // Items 2-4 are only filled if the property has either a getter or a setter.
110 RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
111   HandleScope scope(isolate);
112
113   DCHECK(args.length() == 2);
114
115   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
116   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
117
118   // Make sure to set the current context to the context before the debugger was
119   // entered (if the debugger is entered). The reason for switching context here
120   // is that for some property lookups (accessors and interceptors) callbacks
121   // into the embedding application can occour, and the embedding application
122   // could have the assumption that its own native context is the current
123   // context and not some internal debugger context.
124   SaveContext save(isolate);
125   if (isolate->debug()->in_debug_scope()) {
126     isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
127   }
128
129   // Check if the name is trivially convertible to an index and get the element
130   // if so.
131   uint32_t index;
132   if (name->AsArrayIndex(&index)) {
133     Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
134     Handle<Object> element_or_char;
135     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
136         isolate, element_or_char,
137         Runtime::GetElementOrCharAt(isolate, obj, index));
138     details->set(0, *element_or_char);
139     details->set(1, PropertyDetails(NONE, DATA, 0).AsSmi());
140     return *isolate->factory()->NewJSArrayWithElements(details);
141   }
142
143   LookupIterator it(obj, name, LookupIterator::HIDDEN);
144   bool has_caught = false;
145   Handle<Object> value = DebugGetProperty(&it, &has_caught);
146   if (!it.IsFound()) return isolate->heap()->undefined_value();
147
148   Handle<Object> maybe_pair;
149   if (it.state() == LookupIterator::ACCESSOR) {
150     maybe_pair = it.GetAccessors();
151   }
152
153   // If the callback object is a fixed array then it contains JavaScript
154   // getter and/or setter.
155   bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
156   Handle<FixedArray> details =
157       isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
158   details->set(0, *value);
159   // TODO(verwaest): Get rid of this random way of handling interceptors.
160   PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
161                           ? PropertyDetails(NONE, DATA, 0)
162                           : it.property_details();
163   details->set(1, d.AsSmi());
164   details->set(
165       2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
166   if (has_js_accessors) {
167     AccessorPair* accessors = AccessorPair::cast(*maybe_pair);
168     details->set(3, isolate->heap()->ToBoolean(has_caught));
169     details->set(4, accessors->GetComponent(ACCESSOR_GETTER));
170     details->set(5, accessors->GetComponent(ACCESSOR_SETTER));
171   }
172
173   return *isolate->factory()->NewJSArrayWithElements(details);
174 }
175
176
177 RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
178   HandleScope scope(isolate);
179
180   DCHECK(args.length() == 2);
181
182   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
183   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
184
185   LookupIterator it(obj, name);
186   return *DebugGetProperty(&it);
187 }
188
189
190 // Return the property type calculated from the property details.
191 // args[0]: smi with property details.
192 RUNTIME_FUNCTION(Runtime_DebugPropertyTypeFromDetails) {
193   SealHandleScope shs(isolate);
194   DCHECK(args.length() == 1);
195   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
196   return Smi::FromInt(static_cast<int>(details.type()));
197 }
198
199
200 // Return the property attribute calculated from the property details.
201 // args[0]: smi with property details.
202 RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
203   SealHandleScope shs(isolate);
204   DCHECK(args.length() == 1);
205   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
206   return Smi::FromInt(static_cast<int>(details.attributes()));
207 }
208
209
210 // Return the property insertion index calculated from the property details.
211 // args[0]: smi with property details.
212 RUNTIME_FUNCTION(Runtime_DebugPropertyIndexFromDetails) {
213   SealHandleScope shs(isolate);
214   DCHECK(args.length() == 1);
215   CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
216   // TODO(verwaest): Works only for dictionary mode holders.
217   return Smi::FromInt(details.dictionary_index());
218 }
219
220
221 // Return property value from named interceptor.
222 // args[0]: object
223 // args[1]: property name
224 RUNTIME_FUNCTION(Runtime_DebugNamedInterceptorPropertyValue) {
225   HandleScope scope(isolate);
226   DCHECK(args.length() == 2);
227   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
228   RUNTIME_ASSERT(obj->HasNamedInterceptor());
229   CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
230
231   Handle<Object> result;
232   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
233                                      JSObject::GetProperty(obj, name));
234   return *result;
235 }
236
237
238 // Return element value from indexed interceptor.
239 // args[0]: object
240 // args[1]: index
241 RUNTIME_FUNCTION(Runtime_DebugIndexedInterceptorElementValue) {
242   HandleScope scope(isolate);
243   DCHECK(args.length() == 2);
244   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
245   RUNTIME_ASSERT(obj->HasIndexedInterceptor());
246   CONVERT_NUMBER_CHECKED(uint32_t, index, Uint32, args[1]);
247   Handle<Object> result;
248   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
249       isolate, result,
250       JSObject::GetElementWithInterceptor(obj, obj, index, true));
251   return *result;
252 }
253
254
255 RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
256   SealHandleScope shs(isolate);
257   DCHECK(args.length() == 1);
258   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
259   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
260   return isolate->heap()->true_value();
261 }
262
263
264 RUNTIME_FUNCTION(Runtime_GetFrameCount) {
265   HandleScope scope(isolate);
266   DCHECK(args.length() == 1);
267   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
268   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
269
270   // Count all frames which are relevant to debugging stack trace.
271   int n = 0;
272   StackFrame::Id id = isolate->debug()->break_frame_id();
273   if (id == StackFrame::NO_ID) {
274     // If there is no JavaScript stack frame count is 0.
275     return Smi::FromInt(0);
276   }
277
278   for (JavaScriptFrameIterator it(isolate, id); !it.done(); it.Advance()) {
279     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
280     it.frame()->Summarize(&frames);
281     for (int i = frames.length() - 1; i >= 0; i--) {
282       // Omit functions from native scripts.
283       if (!frames[i].function()->IsFromNativeScript()) n++;
284     }
285   }
286   return Smi::FromInt(n);
287 }
288
289
290 class FrameInspector {
291  public:
292   FrameInspector(JavaScriptFrame* frame, int inlined_jsframe_index,
293                  Isolate* isolate)
294       : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
295     // Calculate the deoptimized frame.
296     if (frame->is_optimized()) {
297       deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
298           frame, inlined_jsframe_index, isolate);
299     }
300     has_adapted_arguments_ = frame_->has_adapted_arguments();
301     is_bottommost_ = inlined_jsframe_index == 0;
302     is_optimized_ = frame_->is_optimized();
303   }
304
305   ~FrameInspector() {
306     // Get rid of the calculated deoptimized frame if any.
307     if (deoptimized_frame_ != NULL) {
308       Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_, isolate_);
309     }
310   }
311
312   int GetParametersCount() {
313     return is_optimized_ ? deoptimized_frame_->parameters_count()
314                          : frame_->ComputeParametersCount();
315   }
316   int expression_count() { return deoptimized_frame_->expression_count(); }
317   Object* GetFunction() {
318     return is_optimized_ ? deoptimized_frame_->GetFunction()
319                          : frame_->function();
320   }
321   Object* GetParameter(int index) {
322     return is_optimized_ ? deoptimized_frame_->GetParameter(index)
323                          : frame_->GetParameter(index);
324   }
325   Object* GetExpression(int index) {
326     return is_optimized_ ? deoptimized_frame_->GetExpression(index)
327                          : frame_->GetExpression(index);
328   }
329   int GetSourcePosition() {
330     return is_optimized_ ? deoptimized_frame_->GetSourcePosition()
331                          : frame_->LookupCode()->SourcePosition(frame_->pc());
332   }
333   bool IsConstructor() {
334     return is_optimized_ && !is_bottommost_
335                ? deoptimized_frame_->HasConstructStub()
336                : frame_->IsConstructor();
337   }
338   Object* GetContext() {
339     return is_optimized_ ? deoptimized_frame_->GetContext() : frame_->context();
340   }
341
342   // To inspect all the provided arguments the frame might need to be
343   // replaced with the arguments frame.
344   void SetArgumentsFrame(JavaScriptFrame* frame) {
345     DCHECK(has_adapted_arguments_);
346     frame_ = frame;
347     is_optimized_ = frame_->is_optimized();
348     DCHECK(!is_optimized_);
349   }
350
351  private:
352   JavaScriptFrame* frame_;
353   DeoptimizedFrameInfo* deoptimized_frame_;
354   Isolate* isolate_;
355   bool is_optimized_;
356   bool is_bottommost_;
357   bool has_adapted_arguments_;
358
359   DISALLOW_COPY_AND_ASSIGN(FrameInspector);
360 };
361
362
363 static const int kFrameDetailsFrameIdIndex = 0;
364 static const int kFrameDetailsReceiverIndex = 1;
365 static const int kFrameDetailsFunctionIndex = 2;
366 static const int kFrameDetailsArgumentCountIndex = 3;
367 static const int kFrameDetailsLocalCountIndex = 4;
368 static const int kFrameDetailsSourcePositionIndex = 5;
369 static const int kFrameDetailsConstructCallIndex = 6;
370 static const int kFrameDetailsAtReturnIndex = 7;
371 static const int kFrameDetailsFlagsIndex = 8;
372 static const int kFrameDetailsFirstDynamicIndex = 9;
373
374
375 static SaveContext* FindSavedContextForFrame(Isolate* isolate,
376                                              JavaScriptFrame* frame) {
377   SaveContext* save = isolate->save_context();
378   while (save != NULL && !save->IsBelowFrame(frame)) {
379     save = save->prev();
380   }
381   DCHECK(save != NULL);
382   return save;
383 }
384
385
386 // Advances the iterator to the frame that matches the index and returns the
387 // inlined frame index, or -1 if not found.  Skips native JS functions.
388 int Runtime::FindIndexedNonNativeFrame(JavaScriptFrameIterator* it, int index) {
389   int count = -1;
390   for (; !it->done(); it->Advance()) {
391     List<FrameSummary> frames(FLAG_max_inlining_levels + 1);
392     it->frame()->Summarize(&frames);
393     for (int i = frames.length() - 1; i >= 0; i--) {
394       // Omit functions from native scripts.
395       if (frames[i].function()->IsFromNativeScript()) continue;
396       if (++count == index) return i;
397     }
398   }
399   return -1;
400 }
401
402
403 // Return an array with frame details
404 // args[0]: number: break id
405 // args[1]: number: frame index
406 //
407 // The array returned contains the following information:
408 // 0: Frame id
409 // 1: Receiver
410 // 2: Function
411 // 3: Argument count
412 // 4: Local count
413 // 5: Source position
414 // 6: Constructor call
415 // 7: Is at return
416 // 8: Flags
417 // Arguments name, value
418 // Locals name, value
419 // Return value if any
420 RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
421   HandleScope scope(isolate);
422   DCHECK(args.length() == 2);
423   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
424   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
425
426   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
427   Heap* heap = isolate->heap();
428
429   // Find the relevant frame with the requested index.
430   StackFrame::Id id = isolate->debug()->break_frame_id();
431   if (id == StackFrame::NO_ID) {
432     // If there are no JavaScript stack frames return undefined.
433     return heap->undefined_value();
434   }
435
436   JavaScriptFrameIterator it(isolate, id);
437   // Inlined frame index in optimized frame, starting from outer function.
438   int inlined_jsframe_index = Runtime::FindIndexedNonNativeFrame(&it, index);
439   if (inlined_jsframe_index == -1) return heap->undefined_value();
440
441   FrameInspector frame_inspector(it.frame(), inlined_jsframe_index, isolate);
442   bool is_optimized = it.frame()->is_optimized();
443
444   // Traverse the saved contexts chain to find the active context for the
445   // selected frame.
446   SaveContext* save = FindSavedContextForFrame(isolate, it.frame());
447
448   // Get the frame id.
449   Handle<Object> frame_id(WrapFrameId(it.frame()->id()), isolate);
450
451   // Find source position in unoptimized code.
452   int position = frame_inspector.GetSourcePosition();
453
454   // Check for constructor frame.
455   bool constructor = frame_inspector.IsConstructor();
456
457   // Get scope info and read from it for local variable information.
458   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
459   Handle<SharedFunctionInfo> shared(function->shared());
460   Handle<ScopeInfo> scope_info(shared->scope_info());
461   DCHECK(*scope_info != ScopeInfo::Empty(isolate));
462
463   // Get the locals names and values into a temporary array.
464   int local_count = scope_info->LocalCount();
465   for (int slot = 0; slot < scope_info->LocalCount(); ++slot) {
466     // Hide compiler-introduced temporary variables, whether on the stack or on
467     // the context.
468     if (scope_info->LocalIsSynthetic(slot)) local_count--;
469   }
470
471   Handle<FixedArray> locals =
472       isolate->factory()->NewFixedArray(local_count * 2);
473
474   // Fill in the values of the locals.
475   int local = 0;
476   int i = 0;
477   for (; i < scope_info->StackLocalCount(); ++i) {
478     // Use the value from the stack.
479     if (scope_info->LocalIsSynthetic(i)) continue;
480     locals->set(local * 2, scope_info->LocalName(i));
481     locals->set(local * 2 + 1, frame_inspector.GetExpression(i));
482     local++;
483   }
484   if (local < local_count) {
485     // Get the context containing declarations.
486     Handle<Context> context(
487         Context::cast(frame_inspector.GetContext())->declaration_context());
488     for (; i < scope_info->LocalCount(); ++i) {
489       if (scope_info->LocalIsSynthetic(i)) continue;
490       Handle<String> name(scope_info->LocalName(i));
491       VariableMode mode;
492       InitializationFlag init_flag;
493       MaybeAssignedFlag maybe_assigned_flag;
494       locals->set(local * 2, *name);
495       int context_slot_index = ScopeInfo::ContextSlotIndex(
496           scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
497       Object* value = context->get(context_slot_index);
498       locals->set(local * 2 + 1, value);
499       local++;
500     }
501   }
502
503   // Check whether this frame is positioned at return. If not top
504   // frame or if the frame is optimized it cannot be at a return.
505   bool at_return = false;
506   if (!is_optimized && index == 0) {
507     at_return = isolate->debug()->IsBreakAtReturn(it.frame());
508   }
509
510   // If positioned just before return find the value to be returned and add it
511   // to the frame information.
512   Handle<Object> return_value = isolate->factory()->undefined_value();
513   if (at_return) {
514     StackFrameIterator it2(isolate);
515     Address internal_frame_sp = NULL;
516     while (!it2.done()) {
517       if (it2.frame()->is_internal()) {
518         internal_frame_sp = it2.frame()->sp();
519       } else {
520         if (it2.frame()->is_java_script()) {
521           if (it2.frame()->id() == it.frame()->id()) {
522             // The internal frame just before the JavaScript frame contains the
523             // value to return on top. A debug break at return will create an
524             // internal frame to store the return value (eax/rax/r0) before
525             // entering the debug break exit frame.
526             if (internal_frame_sp != NULL) {
527               return_value =
528                   Handle<Object>(Memory::Object_at(internal_frame_sp), isolate);
529               break;
530             }
531           }
532         }
533
534         // Indicate that the previous frame was not an internal frame.
535         internal_frame_sp = NULL;
536       }
537       it2.Advance();
538     }
539   }
540
541   // Now advance to the arguments adapter frame (if any). It contains all
542   // the provided parameters whereas the function frame always have the number
543   // of arguments matching the functions parameters. The rest of the
544   // information (except for what is collected above) is the same.
545   if ((inlined_jsframe_index == 0) && it.frame()->has_adapted_arguments()) {
546     it.AdvanceToArgumentsFrame();
547     frame_inspector.SetArgumentsFrame(it.frame());
548   }
549
550   // Find the number of arguments to fill. At least fill the number of
551   // parameters for the function and fill more if more parameters are provided.
552   int argument_count = scope_info->ParameterCount();
553   if (argument_count < frame_inspector.GetParametersCount()) {
554     argument_count = frame_inspector.GetParametersCount();
555   }
556
557   // Calculate the size of the result.
558   int details_size = kFrameDetailsFirstDynamicIndex +
559                      2 * (argument_count + local_count) + (at_return ? 1 : 0);
560   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
561
562   // Add the frame id.
563   details->set(kFrameDetailsFrameIdIndex, *frame_id);
564
565   // Add the function (same as in function frame).
566   details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
567
568   // Add the arguments count.
569   details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
570
571   // Add the locals count
572   details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count));
573
574   // Add the source position.
575   if (position != RelocInfo::kNoPosition) {
576     details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
577   } else {
578     details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
579   }
580
581   // Add the constructor information.
582   details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
583
584   // Add the at return information.
585   details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
586
587   // Add flags to indicate information on whether this frame is
588   //   bit 0: invoked in the debugger context.
589   //   bit 1: optimized frame.
590   //   bit 2: inlined in optimized frame
591   int flags = 0;
592   if (*save->context() == *isolate->debug()->debug_context()) {
593     flags |= 1 << 0;
594   }
595   if (is_optimized) {
596     flags |= 1 << 1;
597     flags |= inlined_jsframe_index << 2;
598   }
599   details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
600
601   // Fill the dynamic part.
602   int details_index = kFrameDetailsFirstDynamicIndex;
603
604   // Add arguments name and value.
605   for (int i = 0; i < argument_count; i++) {
606     // Name of the argument.
607     if (i < scope_info->ParameterCount()) {
608       details->set(details_index++, scope_info->ParameterName(i));
609     } else {
610       details->set(details_index++, heap->undefined_value());
611     }
612
613     // Parameter value.
614     if (i < frame_inspector.GetParametersCount()) {
615       // Get the value from the stack.
616       details->set(details_index++, frame_inspector.GetParameter(i));
617     } else {
618       details->set(details_index++, heap->undefined_value());
619     }
620   }
621
622   // Add locals name and value from the temporary copy from the function frame.
623   for (int i = 0; i < local_count * 2; i++) {
624     details->set(details_index++, locals->get(i));
625   }
626
627   // Add the value being returned.
628   if (at_return) {
629     details->set(details_index++, *return_value);
630   }
631
632   // Add the receiver (same as in function frame).
633   // THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
634   // THE FRAME ITERATOR TO WRAP THE RECEIVER.
635   Handle<Object> receiver(it.frame()->receiver(), isolate);
636   if (!receiver->IsJSObject() && is_sloppy(shared->language_mode()) &&
637       !function->IsBuiltin()) {
638     // If the receiver is not a JSObject and the function is not a
639     // builtin or strict-mode we have hit an optimization where a
640     // value object is not converted into a wrapped JS objects. To
641     // hide this optimization from the debugger, we wrap the receiver
642     // by creating correct wrapper object based on the calling frame's
643     // native context.
644     it.Advance();
645     if (receiver->IsUndefined()) {
646       receiver = handle(function->global_proxy());
647     } else {
648       Context* context = Context::cast(it.frame()->context());
649       Handle<Context> native_context(Context::cast(context->native_context()));
650       if (!Object::ToObject(isolate, receiver, native_context)
651                .ToHandle(&receiver)) {
652         // This only happens if the receiver is forcibly set in %_CallFunction.
653         return heap->undefined_value();
654       }
655     }
656   }
657   details->set(kFrameDetailsReceiverIndex, *receiver);
658
659   DCHECK_EQ(details_size, details_index);
660   return *isolate->factory()->NewJSArrayWithElements(details);
661 }
662
663
664 static bool ParameterIsShadowedByContextLocal(Handle<ScopeInfo> info,
665                                               Handle<String> parameter_name) {
666   VariableMode mode;
667   InitializationFlag init_flag;
668   MaybeAssignedFlag maybe_assigned_flag;
669   return ScopeInfo::ContextSlotIndex(info, parameter_name, &mode, &init_flag,
670                                      &maybe_assigned_flag) != -1;
671 }
672
673
674 // Create a plain JSObject which materializes the local scope for the specified
675 // frame.
676 MUST_USE_RESULT
677 static MaybeHandle<JSObject> MaterializeStackLocalsWithFrameInspector(
678     Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function,
679     FrameInspector* frame_inspector) {
680   Handle<SharedFunctionInfo> shared(function->shared());
681   Handle<ScopeInfo> scope_info(shared->scope_info());
682
683   // First fill all parameters.
684   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
685     // Do not materialize the parameter if it is shadowed by a context local.
686     Handle<String> name(scope_info->ParameterName(i));
687     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
688
689     HandleScope scope(isolate);
690     Handle<Object> value(i < frame_inspector->GetParametersCount()
691                              ? frame_inspector->GetParameter(i)
692                              : isolate->heap()->undefined_value(),
693                          isolate);
694     DCHECK(!value->IsTheHole());
695
696     RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
697                                      isolate, target, name, value, SLOPPY),
698                         JSObject);
699   }
700
701   // Second fill all stack locals.
702   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
703     if (scope_info->LocalIsSynthetic(i)) continue;
704     Handle<String> name(scope_info->StackLocalName(i));
705     Handle<Object> value(frame_inspector->GetExpression(i), isolate);
706     if (value->IsTheHole()) continue;
707
708     RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
709                                      isolate, target, name, value, SLOPPY),
710                         JSObject);
711   }
712
713   return target;
714 }
715
716
717 static void UpdateStackLocalsFromMaterializedObject(Isolate* isolate,
718                                                     Handle<JSObject> target,
719                                                     Handle<JSFunction> function,
720                                                     JavaScriptFrame* frame,
721                                                     int inlined_jsframe_index) {
722   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
723     // Optimized frames are not supported.
724     // TODO(yangguo): make sure all code deoptimized when debugger is active
725     //                and assert that this cannot happen.
726     return;
727   }
728
729   Handle<SharedFunctionInfo> shared(function->shared());
730   Handle<ScopeInfo> scope_info(shared->scope_info());
731
732   // Parameters.
733   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
734     // Shadowed parameters were not materialized.
735     Handle<String> name(scope_info->ParameterName(i));
736     if (ParameterIsShadowedByContextLocal(scope_info, name)) continue;
737
738     DCHECK(!frame->GetParameter(i)->IsTheHole());
739     HandleScope scope(isolate);
740     Handle<Object> value =
741         Object::GetPropertyOrElement(target, name).ToHandleChecked();
742     frame->SetParameterValue(i, *value);
743   }
744
745   // Stack locals.
746   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
747     if (scope_info->LocalIsSynthetic(i)) continue;
748     if (frame->GetExpression(i)->IsTheHole()) continue;
749     HandleScope scope(isolate);
750     Handle<Object> value = Object::GetPropertyOrElement(
751                                target, handle(scope_info->StackLocalName(i),
752                                               isolate)).ToHandleChecked();
753     frame->SetExpression(i, *value);
754   }
755 }
756
757
758 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalContext(
759     Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function,
760     JavaScriptFrame* frame) {
761   HandleScope scope(isolate);
762   Handle<SharedFunctionInfo> shared(function->shared());
763   Handle<ScopeInfo> scope_info(shared->scope_info());
764
765   if (!scope_info->HasContext()) return target;
766
767   // Third fill all context locals.
768   Handle<Context> frame_context(Context::cast(frame->context()));
769   Handle<Context> function_context(frame_context->declaration_context());
770   if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, function_context,
771                                                  target)) {
772     return MaybeHandle<JSObject>();
773   }
774
775   // Finally copy any properties from the function context extension.
776   // These will be variables introduced by eval.
777   if (function_context->closure() == *function) {
778     if (function_context->has_extension() &&
779         !function_context->IsNativeContext()) {
780       Handle<JSObject> ext(JSObject::cast(function_context->extension()));
781       Handle<FixedArray> keys;
782       ASSIGN_RETURN_ON_EXCEPTION(
783           isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
784           JSObject);
785
786       for (int i = 0; i < keys->length(); i++) {
787         // Names of variables introduced by eval are strings.
788         DCHECK(keys->get(i)->IsString());
789         Handle<String> key(String::cast(keys->get(i)));
790         Handle<Object> value;
791         ASSIGN_RETURN_ON_EXCEPTION(
792             isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
793         RETURN_ON_EXCEPTION(isolate, Runtime::SetObjectProperty(
794                                          isolate, target, key, value, SLOPPY),
795                             JSObject);
796       }
797     }
798   }
799
800   return target;
801 }
802
803
804 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScriptScope(
805     Handle<GlobalObject> global) {
806   Isolate* isolate = global->GetIsolate();
807   Handle<ScriptContextTable> script_contexts(
808       global->native_context()->script_context_table());
809
810   Handle<JSObject> script_scope =
811       isolate->factory()->NewJSObject(isolate->object_function());
812
813   for (int context_index = 0; context_index < script_contexts->used();
814        context_index++) {
815     Handle<Context> context =
816         ScriptContextTable::GetContext(script_contexts, context_index);
817     Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
818     if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
819                                                    script_scope)) {
820       return MaybeHandle<JSObject>();
821     }
822   }
823   return script_scope;
824 }
825
826
827 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeLocalScope(
828     Isolate* isolate, JavaScriptFrame* frame, int inlined_jsframe_index) {
829   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
830   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
831
832   Handle<JSObject> local_scope =
833       isolate->factory()->NewJSObject(isolate->object_function());
834   ASSIGN_RETURN_ON_EXCEPTION(
835       isolate, local_scope,
836       MaterializeStackLocalsWithFrameInspector(isolate, local_scope, function,
837                                                &frame_inspector),
838       JSObject);
839
840   return MaterializeLocalContext(isolate, local_scope, function, frame);
841 }
842
843
844 // Set the context local variable value.
845 static bool SetContextLocalValue(Isolate* isolate, Handle<ScopeInfo> scope_info,
846                                  Handle<Context> context,
847                                  Handle<String> variable_name,
848                                  Handle<Object> new_value) {
849   for (int i = 0; i < scope_info->ContextLocalCount(); i++) {
850     Handle<String> next_name(scope_info->ContextLocalName(i));
851     if (String::Equals(variable_name, next_name)) {
852       VariableMode mode;
853       InitializationFlag init_flag;
854       MaybeAssignedFlag maybe_assigned_flag;
855       int context_index = ScopeInfo::ContextSlotIndex(
856           scope_info, next_name, &mode, &init_flag, &maybe_assigned_flag);
857       context->set(context_index, *new_value);
858       return true;
859     }
860   }
861
862   return false;
863 }
864
865
866 static bool SetLocalVariableValue(Isolate* isolate, JavaScriptFrame* frame,
867                                   int inlined_jsframe_index,
868                                   Handle<String> variable_name,
869                                   Handle<Object> new_value) {
870   if (inlined_jsframe_index != 0 || frame->is_optimized()) {
871     // Optimized frames are not supported.
872     return false;
873   }
874
875   Handle<JSFunction> function(frame->function());
876   Handle<SharedFunctionInfo> shared(function->shared());
877   Handle<ScopeInfo> scope_info(shared->scope_info());
878
879   bool default_result = false;
880
881   // Parameters.
882   for (int i = 0; i < scope_info->ParameterCount(); ++i) {
883     HandleScope scope(isolate);
884     if (String::Equals(handle(scope_info->ParameterName(i)), variable_name)) {
885       frame->SetParameterValue(i, *new_value);
886       // Argument might be shadowed in heap context, don't stop here.
887       default_result = true;
888     }
889   }
890
891   // Stack locals.
892   for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
893     HandleScope scope(isolate);
894     if (String::Equals(handle(scope_info->StackLocalName(i)), variable_name)) {
895       frame->SetExpression(i, *new_value);
896       return true;
897     }
898   }
899
900   if (scope_info->HasContext()) {
901     // Context locals.
902     Handle<Context> frame_context(Context::cast(frame->context()));
903     Handle<Context> function_context(frame_context->declaration_context());
904     if (SetContextLocalValue(isolate, scope_info, function_context,
905                              variable_name, new_value)) {
906       return true;
907     }
908
909     // Function context extension. These are variables introduced by eval.
910     if (function_context->closure() == *function) {
911       if (function_context->has_extension() &&
912           !function_context->IsNativeContext()) {
913         Handle<JSObject> ext(JSObject::cast(function_context->extension()));
914
915         Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
916         DCHECK(maybe.has_value);
917         if (maybe.value) {
918           // We don't expect this to do anything except replacing
919           // property value.
920           Runtime::SetObjectProperty(isolate, ext, variable_name, new_value,
921                                      SLOPPY).Assert();
922           return true;
923         }
924       }
925     }
926   }
927
928   return default_result;
929 }
930
931
932 // Create a plain JSObject which materializes the closure content for the
933 // context.
934 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeClosure(
935     Isolate* isolate, Handle<Context> context) {
936   DCHECK(context->IsFunctionContext());
937
938   Handle<SharedFunctionInfo> shared(context->closure()->shared());
939   Handle<ScopeInfo> scope_info(shared->scope_info());
940
941   // Allocate and initialize a JSObject with all the content of this function
942   // closure.
943   Handle<JSObject> closure_scope =
944       isolate->factory()->NewJSObject(isolate->object_function());
945
946   // Fill all context locals to the context extension.
947   if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
948                                                  closure_scope)) {
949     return MaybeHandle<JSObject>();
950   }
951
952   // Finally copy any properties from the function context extension. This will
953   // be variables introduced by eval.
954   if (context->has_extension()) {
955     Handle<JSObject> ext(JSObject::cast(context->extension()));
956     Handle<FixedArray> keys;
957     ASSIGN_RETURN_ON_EXCEPTION(
958         isolate, keys, JSReceiver::GetKeys(ext, JSReceiver::INCLUDE_PROTOS),
959         JSObject);
960
961     for (int i = 0; i < keys->length(); i++) {
962       HandleScope scope(isolate);
963       // Names of variables introduced by eval are strings.
964       DCHECK(keys->get(i)->IsString());
965       Handle<String> key(String::cast(keys->get(i)));
966       Handle<Object> value;
967       ASSIGN_RETURN_ON_EXCEPTION(
968           isolate, value, Object::GetPropertyOrElement(ext, key), JSObject);
969       RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
970                                        closure_scope, key, value, NONE),
971                           JSObject);
972     }
973   }
974
975   return closure_scope;
976 }
977
978
979 // This method copies structure of MaterializeClosure method above.
980 static bool SetClosureVariableValue(Isolate* isolate, Handle<Context> context,
981                                     Handle<String> variable_name,
982                                     Handle<Object> new_value) {
983   DCHECK(context->IsFunctionContext());
984
985   Handle<SharedFunctionInfo> shared(context->closure()->shared());
986   Handle<ScopeInfo> scope_info(shared->scope_info());
987
988   // Context locals to the context extension.
989   if (SetContextLocalValue(isolate, scope_info, context, variable_name,
990                            new_value)) {
991     return true;
992   }
993
994   // Properties from the function context extension. This will
995   // be variables introduced by eval.
996   if (context->has_extension()) {
997     Handle<JSObject> ext(JSObject::cast(context->extension()));
998     Maybe<bool> maybe = JSReceiver::HasProperty(ext, variable_name);
999     DCHECK(maybe.has_value);
1000     if (maybe.value) {
1001       // We don't expect this to do anything except replacing property value.
1002       Runtime::DefineObjectProperty(ext, variable_name, new_value, NONE)
1003           .Assert();
1004       return true;
1005     }
1006   }
1007
1008   return false;
1009 }
1010
1011
1012 static bool SetBlockContextVariableValue(Handle<Context> block_context,
1013                                          Handle<String> variable_name,
1014                                          Handle<Object> new_value) {
1015   DCHECK(block_context->IsBlockContext());
1016   Handle<ScopeInfo> scope_info(ScopeInfo::cast(block_context->extension()));
1017
1018   return SetContextLocalValue(block_context->GetIsolate(), scope_info,
1019                               block_context, variable_name, new_value);
1020 }
1021
1022
1023 static bool SetScriptVariableValue(Handle<Context> context,
1024                                    Handle<String> variable_name,
1025                                    Handle<Object> new_value) {
1026   Handle<ScriptContextTable> script_contexts(
1027       context->global_object()->native_context()->script_context_table());
1028   ScriptContextTable::LookupResult lookup_result;
1029   if (ScriptContextTable::Lookup(script_contexts, variable_name,
1030                                  &lookup_result)) {
1031     Handle<Context> script_context = ScriptContextTable::GetContext(
1032         script_contexts, lookup_result.context_index);
1033     script_context->set(lookup_result.slot_index, *new_value);
1034     return true;
1035   }
1036
1037   return false;
1038 }
1039
1040
1041 // Create a plain JSObject which materializes the scope for the specified
1042 // catch context.
1043 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeCatchScope(
1044     Isolate* isolate, Handle<Context> context) {
1045   DCHECK(context->IsCatchContext());
1046   Handle<String> name(String::cast(context->extension()));
1047   Handle<Object> thrown_object(context->get(Context::THROWN_OBJECT_INDEX),
1048                                isolate);
1049   Handle<JSObject> catch_scope =
1050       isolate->factory()->NewJSObject(isolate->object_function());
1051   RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
1052                                    catch_scope, name, thrown_object, NONE),
1053                       JSObject);
1054   return catch_scope;
1055 }
1056
1057
1058 static bool SetCatchVariableValue(Isolate* isolate, Handle<Context> context,
1059                                   Handle<String> variable_name,
1060                                   Handle<Object> new_value) {
1061   DCHECK(context->IsCatchContext());
1062   Handle<String> name(String::cast(context->extension()));
1063   if (!String::Equals(name, variable_name)) {
1064     return false;
1065   }
1066   context->set(Context::THROWN_OBJECT_INDEX, *new_value);
1067   return true;
1068 }
1069
1070
1071 // Create a plain JSObject which materializes the block scope for the specified
1072 // block context.
1073 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeBlockScope(
1074     Isolate* isolate, Handle<Context> context) {
1075   DCHECK(context->IsBlockContext());
1076   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
1077
1078   // Allocate and initialize a JSObject with all the arguments, stack locals
1079   // heap locals and extension properties of the debugged function.
1080   Handle<JSObject> block_scope =
1081       isolate->factory()->NewJSObject(isolate->object_function());
1082
1083   // Fill all context locals.
1084   if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
1085                                                  block_scope)) {
1086     return MaybeHandle<JSObject>();
1087   }
1088
1089   return block_scope;
1090 }
1091
1092
1093 // Create a plain JSObject which materializes the module scope for the specified
1094 // module context.
1095 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeModuleScope(
1096     Isolate* isolate, Handle<Context> context) {
1097   DCHECK(context->IsModuleContext());
1098   Handle<ScopeInfo> scope_info(ScopeInfo::cast(context->extension()));
1099
1100   // Allocate and initialize a JSObject with all the members of the debugged
1101   // module.
1102   Handle<JSObject> module_scope =
1103       isolate->factory()->NewJSObject(isolate->object_function());
1104
1105   // Fill all context locals.
1106   if (!ScopeInfo::CopyContextLocalsToScopeObject(scope_info, context,
1107                                                  module_scope)) {
1108     return MaybeHandle<JSObject>();
1109   }
1110
1111   return module_scope;
1112 }
1113
1114
1115 // Iterate over the actual scopes visible from a stack frame or from a closure.
1116 // The iteration proceeds from the innermost visible nested scope outwards.
1117 // All scopes are backed by an actual context except the local scope,
1118 // which is inserted "artificially" in the context chain.
1119 class ScopeIterator {
1120  public:
1121   enum ScopeType {
1122     ScopeTypeGlobal = 0,
1123     ScopeTypeLocal,
1124     ScopeTypeWith,
1125     ScopeTypeClosure,
1126     ScopeTypeCatch,
1127     ScopeTypeBlock,
1128     ScopeTypeScript,
1129     ScopeTypeModule
1130   };
1131
1132   ScopeIterator(Isolate* isolate, JavaScriptFrame* frame,
1133                 int inlined_jsframe_index, bool ignore_nested_scopes = false)
1134       : isolate_(isolate),
1135         frame_(frame),
1136         inlined_jsframe_index_(inlined_jsframe_index),
1137         function_(frame->function()),
1138         context_(Context::cast(frame->context())),
1139         nested_scope_chain_(4),
1140         seen_script_scope_(false),
1141         failed_(false) {
1142     // Catch the case when the debugger stops in an internal function.
1143     Handle<SharedFunctionInfo> shared_info(function_->shared());
1144     Handle<ScopeInfo> scope_info(shared_info->scope_info());
1145     if (shared_info->script() == isolate->heap()->undefined_value()) {
1146       while (context_->closure() == *function_) {
1147         context_ = Handle<Context>(context_->previous(), isolate_);
1148       }
1149       return;
1150     }
1151
1152     // Get the debug info (create it if it does not exist).
1153     if (!isolate->debug()->EnsureDebugInfo(shared_info, function_)) {
1154       // Return if ensuring debug info failed.
1155       return;
1156     }
1157
1158     // Currently it takes too much time to find nested scopes due to script
1159     // parsing. Sometimes we want to run the ScopeIterator as fast as possible
1160     // (for example, while collecting async call stacks on every
1161     // addEventListener call), even if we drop some nested scopes.
1162     // Later we may optimize getting the nested scopes (cache the result?)
1163     // and include nested scopes into the "fast" iteration case as well.
1164     if (!ignore_nested_scopes) {
1165       Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared_info);
1166
1167       // Find the break point where execution has stopped.
1168       BreakLocationIterator break_location_iterator(debug_info,
1169                                                     ALL_BREAK_LOCATIONS);
1170       // pc points to the instruction after the current one, possibly a break
1171       // location as well. So the "- 1" to exclude it from the search.
1172       break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
1173
1174       // Within the return sequence at the moment it is not possible to
1175       // get a source position which is consistent with the current scope chain.
1176       // Thus all nested with, catch and block contexts are skipped and we only
1177       // provide the function scope.
1178       ignore_nested_scopes = break_location_iterator.IsExit();
1179     }
1180
1181     if (ignore_nested_scopes) {
1182       if (scope_info->HasContext()) {
1183         context_ = Handle<Context>(context_->declaration_context(), isolate_);
1184       } else {
1185         while (context_->closure() == *function_) {
1186           context_ = Handle<Context>(context_->previous(), isolate_);
1187         }
1188       }
1189       if (scope_info->scope_type() == FUNCTION_SCOPE ||
1190           scope_info->scope_type() == ARROW_SCOPE) {
1191         nested_scope_chain_.Add(scope_info);
1192       }
1193     } else {
1194       // Reparse the code and analyze the scopes.
1195       Handle<Script> script(Script::cast(shared_info->script()));
1196       Scope* scope = NULL;
1197
1198       // Check whether we are in global, eval or function code.
1199       Handle<ScopeInfo> scope_info(shared_info->scope_info());
1200       if (scope_info->scope_type() != FUNCTION_SCOPE &&
1201           scope_info->scope_type() != ARROW_SCOPE) {
1202         // Global or eval code.
1203         CompilationInfoWithZone info(script);
1204         if (scope_info->scope_type() == SCRIPT_SCOPE) {
1205           info.MarkAsGlobal();
1206         } else {
1207           DCHECK(scope_info->scope_type() == EVAL_SCOPE);
1208           info.MarkAsEval();
1209           info.SetContext(Handle<Context>(function_->context()));
1210         }
1211         if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) {
1212           scope = info.function()->scope();
1213         }
1214         RetrieveScopeChain(scope, shared_info);
1215       } else {
1216         // Function code
1217         CompilationInfoWithZone info(shared_info);
1218         if (Parser::ParseStatic(&info) && Scope::Analyze(&info)) {
1219           scope = info.function()->scope();
1220         }
1221         RetrieveScopeChain(scope, shared_info);
1222       }
1223     }
1224   }
1225
1226   ScopeIterator(Isolate* isolate, Handle<JSFunction> function)
1227       : isolate_(isolate),
1228         frame_(NULL),
1229         inlined_jsframe_index_(0),
1230         function_(function),
1231         context_(function->context()),
1232         seen_script_scope_(false),
1233         failed_(false) {
1234     if (function->IsBuiltin()) {
1235       context_ = Handle<Context>();
1236     }
1237   }
1238
1239   // More scopes?
1240   bool Done() {
1241     DCHECK(!failed_);
1242     return context_.is_null();
1243   }
1244
1245   bool Failed() { return failed_; }
1246
1247   // Move to the next scope.
1248   void Next() {
1249     DCHECK(!failed_);
1250     ScopeType scope_type = Type();
1251     if (scope_type == ScopeTypeGlobal) {
1252       // The global scope is always the last in the chain.
1253       DCHECK(context_->IsNativeContext());
1254       context_ = Handle<Context>();
1255       return;
1256     }
1257     if (scope_type == ScopeTypeScript) seen_script_scope_ = true;
1258     if (nested_scope_chain_.is_empty()) {
1259       if (scope_type == ScopeTypeScript) {
1260         if (context_->IsScriptContext()) {
1261           context_ = Handle<Context>(context_->previous(), isolate_);
1262         }
1263         CHECK(context_->IsNativeContext());
1264       } else {
1265         context_ = Handle<Context>(context_->previous(), isolate_);
1266       }
1267     } else {
1268       if (nested_scope_chain_.last()->HasContext()) {
1269         DCHECK(context_->previous() != NULL);
1270         context_ = Handle<Context>(context_->previous(), isolate_);
1271       }
1272       nested_scope_chain_.RemoveLast();
1273     }
1274   }
1275
1276   // Return the type of the current scope.
1277   ScopeType Type() {
1278     DCHECK(!failed_);
1279     if (!nested_scope_chain_.is_empty()) {
1280       Handle<ScopeInfo> scope_info = nested_scope_chain_.last();
1281       switch (scope_info->scope_type()) {
1282         case FUNCTION_SCOPE:
1283         case ARROW_SCOPE:
1284           DCHECK(context_->IsFunctionContext() || !scope_info->HasContext());
1285           return ScopeTypeLocal;
1286         case MODULE_SCOPE:
1287           DCHECK(context_->IsModuleContext());
1288           return ScopeTypeModule;
1289         case SCRIPT_SCOPE:
1290           DCHECK(context_->IsScriptContext() || context_->IsNativeContext());
1291           return ScopeTypeScript;
1292         case WITH_SCOPE:
1293           DCHECK(context_->IsWithContext());
1294           return ScopeTypeWith;
1295         case CATCH_SCOPE:
1296           DCHECK(context_->IsCatchContext());
1297           return ScopeTypeCatch;
1298         case BLOCK_SCOPE:
1299           DCHECK(!scope_info->HasContext() || context_->IsBlockContext());
1300           return ScopeTypeBlock;
1301         case EVAL_SCOPE:
1302           UNREACHABLE();
1303       }
1304     }
1305     if (context_->IsNativeContext()) {
1306       DCHECK(context_->global_object()->IsGlobalObject());
1307       // If we are at the native context and have not yet seen script scope,
1308       // fake it.
1309       return seen_script_scope_ ? ScopeTypeGlobal : ScopeTypeScript;
1310     }
1311     if (context_->IsFunctionContext()) {
1312       return ScopeTypeClosure;
1313     }
1314     if (context_->IsCatchContext()) {
1315       return ScopeTypeCatch;
1316     }
1317     if (context_->IsBlockContext()) {
1318       return ScopeTypeBlock;
1319     }
1320     if (context_->IsModuleContext()) {
1321       return ScopeTypeModule;
1322     }
1323     if (context_->IsScriptContext()) {
1324       return ScopeTypeScript;
1325     }
1326     DCHECK(context_->IsWithContext());
1327     return ScopeTypeWith;
1328   }
1329
1330   // Return the JavaScript object with the content of the current scope.
1331   MaybeHandle<JSObject> ScopeObject() {
1332     DCHECK(!failed_);
1333     switch (Type()) {
1334       case ScopeIterator::ScopeTypeGlobal:
1335         return Handle<JSObject>(CurrentContext()->global_object());
1336       case ScopeIterator::ScopeTypeScript:
1337         return MaterializeScriptScope(
1338             Handle<GlobalObject>(CurrentContext()->global_object()));
1339       case ScopeIterator::ScopeTypeLocal:
1340         // Materialize the content of the local scope into a JSObject.
1341         DCHECK(nested_scope_chain_.length() == 1);
1342         return MaterializeLocalScope(isolate_, frame_, inlined_jsframe_index_);
1343       case ScopeIterator::ScopeTypeWith:
1344         // Return the with object.
1345         return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
1346       case ScopeIterator::ScopeTypeCatch:
1347         return MaterializeCatchScope(isolate_, CurrentContext());
1348       case ScopeIterator::ScopeTypeClosure:
1349         // Materialize the content of the closure scope into a JSObject.
1350         return MaterializeClosure(isolate_, CurrentContext());
1351       case ScopeIterator::ScopeTypeBlock:
1352         return MaterializeBlockScope(isolate_, CurrentContext());
1353       case ScopeIterator::ScopeTypeModule:
1354         return MaterializeModuleScope(isolate_, CurrentContext());
1355     }
1356     UNREACHABLE();
1357     return Handle<JSObject>();
1358   }
1359
1360   bool SetVariableValue(Handle<String> variable_name,
1361                         Handle<Object> new_value) {
1362     DCHECK(!failed_);
1363     switch (Type()) {
1364       case ScopeIterator::ScopeTypeGlobal:
1365         break;
1366       case ScopeIterator::ScopeTypeLocal:
1367         return SetLocalVariableValue(isolate_, frame_, inlined_jsframe_index_,
1368                                      variable_name, new_value);
1369       case ScopeIterator::ScopeTypeWith:
1370         break;
1371       case ScopeIterator::ScopeTypeCatch:
1372         return SetCatchVariableValue(isolate_, CurrentContext(), variable_name,
1373                                      new_value);
1374       case ScopeIterator::ScopeTypeClosure:
1375         return SetClosureVariableValue(isolate_, CurrentContext(),
1376                                        variable_name, new_value);
1377       case ScopeIterator::ScopeTypeScript:
1378         return SetScriptVariableValue(CurrentContext(), variable_name,
1379                                       new_value);
1380       case ScopeIterator::ScopeTypeBlock:
1381         return SetBlockContextVariableValue(CurrentContext(), variable_name,
1382                                             new_value);
1383       case ScopeIterator::ScopeTypeModule:
1384         // TODO(2399): should we implement it?
1385         break;
1386     }
1387     return false;
1388   }
1389
1390   Handle<ScopeInfo> CurrentScopeInfo() {
1391     DCHECK(!failed_);
1392     if (!nested_scope_chain_.is_empty()) {
1393       return nested_scope_chain_.last();
1394     } else if (context_->IsBlockContext()) {
1395       return Handle<ScopeInfo>(ScopeInfo::cast(context_->extension()));
1396     } else if (context_->IsFunctionContext()) {
1397       return Handle<ScopeInfo>(context_->closure()->shared()->scope_info());
1398     }
1399     return Handle<ScopeInfo>::null();
1400   }
1401
1402   // Return the context for this scope. For the local context there might not
1403   // be an actual context.
1404   Handle<Context> CurrentContext() {
1405     DCHECK(!failed_);
1406     if (Type() == ScopeTypeGlobal || Type() == ScopeTypeScript ||
1407         nested_scope_chain_.is_empty()) {
1408       return context_;
1409     } else if (nested_scope_chain_.last()->HasContext()) {
1410       return context_;
1411     } else {
1412       return Handle<Context>();
1413     }
1414   }
1415
1416 #ifdef DEBUG
1417   // Debug print of the content of the current scope.
1418   void DebugPrint() {
1419     OFStream os(stdout);
1420     DCHECK(!failed_);
1421     switch (Type()) {
1422       case ScopeIterator::ScopeTypeGlobal:
1423         os << "Global:\n";
1424         CurrentContext()->Print(os);
1425         break;
1426
1427       case ScopeIterator::ScopeTypeLocal: {
1428         os << "Local:\n";
1429         function_->shared()->scope_info()->Print();
1430         if (!CurrentContext().is_null()) {
1431           CurrentContext()->Print(os);
1432           if (CurrentContext()->has_extension()) {
1433             Handle<Object> extension(CurrentContext()->extension(), isolate_);
1434             if (extension->IsJSContextExtensionObject()) {
1435               extension->Print(os);
1436             }
1437           }
1438         }
1439         break;
1440       }
1441
1442       case ScopeIterator::ScopeTypeWith:
1443         os << "With:\n";
1444         CurrentContext()->extension()->Print(os);
1445         break;
1446
1447       case ScopeIterator::ScopeTypeCatch:
1448         os << "Catch:\n";
1449         CurrentContext()->extension()->Print(os);
1450         CurrentContext()->get(Context::THROWN_OBJECT_INDEX)->Print(os);
1451         break;
1452
1453       case ScopeIterator::ScopeTypeClosure:
1454         os << "Closure:\n";
1455         CurrentContext()->Print(os);
1456         if (CurrentContext()->has_extension()) {
1457           Handle<Object> extension(CurrentContext()->extension(), isolate_);
1458           if (extension->IsJSContextExtensionObject()) {
1459             extension->Print(os);
1460           }
1461         }
1462         break;
1463
1464       case ScopeIterator::ScopeTypeScript:
1465         os << "Script:\n";
1466         CurrentContext()
1467             ->global_object()
1468             ->native_context()
1469             ->script_context_table()
1470             ->Print(os);
1471         break;
1472
1473       default:
1474         UNREACHABLE();
1475     }
1476     PrintF("\n");
1477   }
1478 #endif
1479
1480  private:
1481   Isolate* isolate_;
1482   JavaScriptFrame* frame_;
1483   int inlined_jsframe_index_;
1484   Handle<JSFunction> function_;
1485   Handle<Context> context_;
1486   List<Handle<ScopeInfo> > nested_scope_chain_;
1487   bool seen_script_scope_;
1488   bool failed_;
1489
1490   void RetrieveScopeChain(Scope* scope,
1491                           Handle<SharedFunctionInfo> shared_info) {
1492     if (scope != NULL) {
1493       int source_position = shared_info->code()->SourcePosition(frame_->pc());
1494       scope->GetNestedScopeChain(isolate_, &nested_scope_chain_,
1495                                  source_position);
1496     } else {
1497       // A failed reparse indicates that the preparser has diverged from the
1498       // parser or that the preparse data given to the initial parse has been
1499       // faulty. We fail in debug mode but in release mode we only provide the
1500       // information we get from the context chain but nothing about
1501       // completely stack allocated scopes or stack allocated locals.
1502       // Or it could be due to stack overflow.
1503       DCHECK(isolate_->has_pending_exception());
1504       failed_ = true;
1505     }
1506   }
1507
1508   DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
1509 };
1510
1511
1512 RUNTIME_FUNCTION(Runtime_GetScopeCount) {
1513   HandleScope scope(isolate);
1514   DCHECK(args.length() == 2);
1515   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
1516   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
1517
1518   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
1519
1520   // Get the frame where the debugging is performed.
1521   StackFrame::Id id = UnwrapFrameId(wrapped_id);
1522   JavaScriptFrameIterator it(isolate, id);
1523   JavaScriptFrame* frame = it.frame();
1524
1525   // Count the visible scopes.
1526   int n = 0;
1527   for (ScopeIterator it(isolate, frame, 0); !it.Done(); it.Next()) {
1528     n++;
1529   }
1530
1531   return Smi::FromInt(n);
1532 }
1533
1534
1535 // Returns the list of step-in positions (text offset) in a function of the
1536 // stack frame in a range from the current debug break position to the end
1537 // of the corresponding statement.
1538 RUNTIME_FUNCTION(Runtime_GetStepInPositions) {
1539   HandleScope scope(isolate);
1540   DCHECK(args.length() == 2);
1541   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
1542   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
1543
1544   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
1545
1546   // Get the frame where the debugging is performed.
1547   StackFrame::Id id = UnwrapFrameId(wrapped_id);
1548   JavaScriptFrameIterator frame_it(isolate, id);
1549   RUNTIME_ASSERT(!frame_it.done());
1550
1551   JavaScriptFrame* frame = frame_it.frame();
1552
1553   Handle<JSFunction> fun = Handle<JSFunction>(frame->function());
1554   Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo>(fun->shared());
1555
1556   if (!isolate->debug()->EnsureDebugInfo(shared, fun)) {
1557     return isolate->heap()->undefined_value();
1558   }
1559
1560   Handle<DebugInfo> debug_info = Debug::GetDebugInfo(shared);
1561
1562   int len = 0;
1563   Handle<JSArray> array(isolate->factory()->NewJSArray(10));
1564   // Find the break point where execution has stopped.
1565   BreakLocationIterator break_location_iterator(debug_info,
1566                                                 ALL_BREAK_LOCATIONS);
1567
1568   break_location_iterator.FindBreakLocationFromAddress(frame->pc() - 1);
1569   int current_statement_pos = break_location_iterator.statement_position();
1570
1571   while (!break_location_iterator.Done()) {
1572     bool accept;
1573     if (break_location_iterator.pc() > frame->pc()) {
1574       accept = true;
1575     } else {
1576       StackFrame::Id break_frame_id = isolate->debug()->break_frame_id();
1577       // The break point is near our pc. Could be a step-in possibility,
1578       // that is currently taken by active debugger call.
1579       if (break_frame_id == StackFrame::NO_ID) {
1580         // We are not stepping.
1581         accept = false;
1582       } else {
1583         JavaScriptFrameIterator additional_frame_it(isolate, break_frame_id);
1584         // If our frame is a top frame and we are stepping, we can do step-in
1585         // at this place.
1586         accept = additional_frame_it.frame()->id() == id;
1587       }
1588     }
1589     if (accept) {
1590       if (break_location_iterator.IsStepInLocation(isolate)) {
1591         Smi* position_value = Smi::FromInt(break_location_iterator.position());
1592         RETURN_FAILURE_ON_EXCEPTION(
1593             isolate, JSObject::SetElement(
1594                          array, len, Handle<Object>(position_value, isolate),
1595                          NONE, SLOPPY));
1596         len++;
1597       }
1598     }
1599     // Advance iterator.
1600     break_location_iterator.Next();
1601     if (current_statement_pos != break_location_iterator.statement_position()) {
1602       break;
1603     }
1604   }
1605   return *array;
1606 }
1607
1608
1609 static const int kScopeDetailsTypeIndex = 0;
1610 static const int kScopeDetailsObjectIndex = 1;
1611 static const int kScopeDetailsSize = 2;
1612
1613
1614 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeScopeDetails(
1615     Isolate* isolate, ScopeIterator* it) {
1616   // Calculate the size of the result.
1617   int details_size = kScopeDetailsSize;
1618   Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
1619
1620   // Fill in scope details.
1621   details->set(kScopeDetailsTypeIndex, Smi::FromInt(it->Type()));
1622   Handle<JSObject> scope_object;
1623   ASSIGN_RETURN_ON_EXCEPTION(isolate, scope_object, it->ScopeObject(),
1624                              JSObject);
1625   details->set(kScopeDetailsObjectIndex, *scope_object);
1626
1627   return isolate->factory()->NewJSArrayWithElements(details);
1628 }
1629
1630
1631 // Return an array with scope details
1632 // args[0]: number: break id
1633 // args[1]: number: frame index
1634 // args[2]: number: inlined frame index
1635 // args[3]: number: scope index
1636 //
1637 // The array returned contains the following information:
1638 // 0: Scope type
1639 // 1: Scope object
1640 RUNTIME_FUNCTION(Runtime_GetScopeDetails) {
1641   HandleScope scope(isolate);
1642   DCHECK(args.length() == 4);
1643   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
1644   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
1645
1646   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
1647   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
1648   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
1649
1650   // Get the frame where the debugging is performed.
1651   StackFrame::Id id = UnwrapFrameId(wrapped_id);
1652   JavaScriptFrameIterator frame_it(isolate, id);
1653   JavaScriptFrame* frame = frame_it.frame();
1654
1655   // Find the requested scope.
1656   int n = 0;
1657   ScopeIterator it(isolate, frame, inlined_jsframe_index);
1658   for (; !it.Done() && n < index; it.Next()) {
1659     n++;
1660   }
1661   if (it.Done()) {
1662     return isolate->heap()->undefined_value();
1663   }
1664   Handle<JSObject> details;
1665   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
1666                                      MaterializeScopeDetails(isolate, &it));
1667   return *details;
1668 }
1669
1670
1671 // Return an array of scope details
1672 // args[0]: number: break id
1673 // args[1]: number: frame index
1674 // args[2]: number: inlined frame index
1675 // args[3]: boolean: ignore nested scopes
1676 //
1677 // The array returned contains arrays with the following information:
1678 // 0: Scope type
1679 // 1: Scope object
1680 RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
1681   HandleScope scope(isolate);
1682   DCHECK(args.length() == 3 || args.length() == 4);
1683   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
1684   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
1685
1686   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
1687   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
1688
1689   bool ignore_nested_scopes = false;
1690   if (args.length() == 4) {
1691     CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
1692     ignore_nested_scopes = flag;
1693   }
1694
1695   // Get the frame where the debugging is performed.
1696   StackFrame::Id id = UnwrapFrameId(wrapped_id);
1697   JavaScriptFrameIterator frame_it(isolate, id);
1698   JavaScriptFrame* frame = frame_it.frame();
1699
1700   List<Handle<JSObject> > result(4);
1701   ScopeIterator it(isolate, frame, inlined_jsframe_index, ignore_nested_scopes);
1702   for (; !it.Done(); it.Next()) {
1703     Handle<JSObject> details;
1704     ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
1705                                        MaterializeScopeDetails(isolate, &it));
1706     result.Add(details);
1707   }
1708
1709   Handle<FixedArray> array = isolate->factory()->NewFixedArray(result.length());
1710   for (int i = 0; i < result.length(); ++i) {
1711     array->set(i, *result[i]);
1712   }
1713   return *isolate->factory()->NewJSArrayWithElements(array);
1714 }
1715
1716
1717 RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
1718   HandleScope scope(isolate);
1719   DCHECK(args.length() == 1);
1720
1721   // Check arguments.
1722   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
1723
1724   // Count the visible scopes.
1725   int n = 0;
1726   for (ScopeIterator it(isolate, fun); !it.Done(); it.Next()) {
1727     n++;
1728   }
1729
1730   return Smi::FromInt(n);
1731 }
1732
1733
1734 RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
1735   HandleScope scope(isolate);
1736   DCHECK(args.length() == 2);
1737
1738   // Check arguments.
1739   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
1740   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
1741
1742   // Find the requested scope.
1743   int n = 0;
1744   ScopeIterator it(isolate, fun);
1745   for (; !it.Done() && n < index; it.Next()) {
1746     n++;
1747   }
1748   if (it.Done()) {
1749     return isolate->heap()->undefined_value();
1750   }
1751
1752   Handle<JSObject> details;
1753   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
1754                                      MaterializeScopeDetails(isolate, &it));
1755   return *details;
1756 }
1757
1758
1759 static bool SetScopeVariableValue(ScopeIterator* it, int index,
1760                                   Handle<String> variable_name,
1761                                   Handle<Object> new_value) {
1762   for (int n = 0; !it->Done() && n < index; it->Next()) {
1763     n++;
1764   }
1765   if (it->Done()) {
1766     return false;
1767   }
1768   return it->SetVariableValue(variable_name, new_value);
1769 }
1770
1771
1772 // Change variable value in closure or local scope
1773 // args[0]: number or JsFunction: break id or function
1774 // args[1]: number: frame index (when arg[0] is break id)
1775 // args[2]: number: inlined frame index (when arg[0] is break id)
1776 // args[3]: number: scope index
1777 // args[4]: string: variable name
1778 // args[5]: object: new value
1779 //
1780 // Return true if success and false otherwise
1781 RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
1782   HandleScope scope(isolate);
1783   DCHECK(args.length() == 6);
1784
1785   // Check arguments.
1786   CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
1787   CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
1788   CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
1789
1790   bool res;
1791   if (args[0]->IsNumber()) {
1792     CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
1793     RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
1794
1795     CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
1796     CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
1797
1798     // Get the frame where the debugging is performed.
1799     StackFrame::Id id = UnwrapFrameId(wrapped_id);
1800     JavaScriptFrameIterator frame_it(isolate, id);
1801     JavaScriptFrame* frame = frame_it.frame();
1802
1803     ScopeIterator it(isolate, frame, inlined_jsframe_index);
1804     res = SetScopeVariableValue(&it, index, variable_name, new_value);
1805   } else {
1806     CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
1807     ScopeIterator it(isolate, fun);
1808     res = SetScopeVariableValue(&it, index, variable_name, new_value);
1809   }
1810
1811   return isolate->heap()->ToBoolean(res);
1812 }
1813
1814
1815 RUNTIME_FUNCTION(Runtime_DebugPrintScopes) {
1816   HandleScope scope(isolate);
1817   DCHECK(args.length() == 0);
1818
1819 #ifdef DEBUG
1820   // Print the scopes for the top frame.
1821   StackFrameLocator locator(isolate);
1822   JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
1823   for (ScopeIterator it(isolate, frame, 0); !it.Done(); it.Next()) {
1824     it.DebugPrint();
1825   }
1826 #endif
1827   return isolate->heap()->undefined_value();
1828 }
1829
1830
1831 RUNTIME_FUNCTION(Runtime_GetThreadCount) {
1832   HandleScope scope(isolate);
1833   DCHECK(args.length() == 1);
1834   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
1835   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
1836
1837   // Count all archived V8 threads.
1838   int n = 0;
1839   for (ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse();
1840        thread != NULL; thread = thread->Next()) {
1841     n++;
1842   }
1843
1844   // Total number of threads is current thread and archived threads.
1845   return Smi::FromInt(n + 1);
1846 }
1847
1848
1849 static const int kThreadDetailsCurrentThreadIndex = 0;
1850 static const int kThreadDetailsThreadIdIndex = 1;
1851 static const int kThreadDetailsSize = 2;
1852
1853 // Return an array with thread details
1854 // args[0]: number: break id
1855 // args[1]: number: thread index
1856 //
1857 // The array returned contains the following information:
1858 // 0: Is current thread?
1859 // 1: Thread id
1860 RUNTIME_FUNCTION(Runtime_GetThreadDetails) {
1861   HandleScope scope(isolate);
1862   DCHECK(args.length() == 2);
1863   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
1864   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
1865
1866   CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
1867
1868   // Allocate array for result.
1869   Handle<FixedArray> details =
1870       isolate->factory()->NewFixedArray(kThreadDetailsSize);
1871
1872   // Thread index 0 is current thread.
1873   if (index == 0) {
1874     // Fill the details.
1875     details->set(kThreadDetailsCurrentThreadIndex,
1876                  isolate->heap()->true_value());
1877     details->set(kThreadDetailsThreadIdIndex,
1878                  Smi::FromInt(ThreadId::Current().ToInteger()));
1879   } else {
1880     // Find the thread with the requested index.
1881     int n = 1;
1882     ThreadState* thread = isolate->thread_manager()->FirstThreadStateInUse();
1883     while (index != n && thread != NULL) {
1884       thread = thread->Next();
1885       n++;
1886     }
1887     if (thread == NULL) {
1888       return isolate->heap()->undefined_value();
1889     }
1890
1891     // Fill the details.
1892     details->set(kThreadDetailsCurrentThreadIndex,
1893                  isolate->heap()->false_value());
1894     details->set(kThreadDetailsThreadIdIndex,
1895                  Smi::FromInt(thread->id().ToInteger()));
1896   }
1897
1898   // Convert to JS array and return.
1899   return *isolate->factory()->NewJSArrayWithElements(details);
1900 }
1901
1902
1903 // Sets the disable break state
1904 // args[0]: disable break state
1905 RUNTIME_FUNCTION(Runtime_SetDisableBreak) {
1906   HandleScope scope(isolate);
1907   DCHECK(args.length() == 1);
1908   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 0);
1909   isolate->debug()->set_disable_break(disable_break);
1910   return isolate->heap()->undefined_value();
1911 }
1912
1913
1914 static bool IsPositionAlignmentCodeCorrect(int alignment) {
1915   return alignment == STATEMENT_ALIGNED || alignment == BREAK_POSITION_ALIGNED;
1916 }
1917
1918
1919 RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
1920   HandleScope scope(isolate);
1921   DCHECK(args.length() == 2);
1922
1923   CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
1924   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[1]);
1925
1926   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
1927     return isolate->ThrowIllegalOperation();
1928   }
1929   BreakPositionAlignment alignment =
1930       static_cast<BreakPositionAlignment>(statement_aligned_code);
1931
1932   Handle<SharedFunctionInfo> shared(fun->shared());
1933   // Find the number of break points
1934   Handle<Object> break_locations =
1935       Debug::GetSourceBreakLocations(shared, alignment);
1936   if (break_locations->IsUndefined()) return isolate->heap()->undefined_value();
1937   // Return array as JS array
1938   return *isolate->factory()->NewJSArrayWithElements(
1939       Handle<FixedArray>::cast(break_locations));
1940 }
1941
1942
1943 // Set a break point in a function.
1944 // args[0]: function
1945 // args[1]: number: break source position (within the function source)
1946 // args[2]: number: break point object
1947 RUNTIME_FUNCTION(Runtime_SetFunctionBreakPoint) {
1948   HandleScope scope(isolate);
1949   DCHECK(args.length() == 3);
1950   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
1951   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
1952   RUNTIME_ASSERT(source_position >= function->shared()->start_position() &&
1953                  source_position <= function->shared()->end_position());
1954   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 2);
1955
1956   // Set break point.
1957   RUNTIME_ASSERT(isolate->debug()->SetBreakPoint(
1958       function, break_point_object_arg, &source_position));
1959
1960   return Smi::FromInt(source_position);
1961 }
1962
1963
1964 // Changes the state of a break point in a script and returns source position
1965 // where break point was set. NOTE: Regarding performance see the NOTE for
1966 // GetScriptFromScriptData.
1967 // args[0]: script to set break point in
1968 // args[1]: number: break source position (within the script source)
1969 // args[2]: number, breakpoint position alignment
1970 // args[3]: number: break point object
1971 RUNTIME_FUNCTION(Runtime_SetScriptBreakPoint) {
1972   HandleScope scope(isolate);
1973   DCHECK(args.length() == 4);
1974   CONVERT_ARG_HANDLE_CHECKED(JSValue, wrapper, 0);
1975   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
1976   RUNTIME_ASSERT(source_position >= 0);
1977   CONVERT_NUMBER_CHECKED(int32_t, statement_aligned_code, Int32, args[2]);
1978   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 3);
1979
1980   if (!IsPositionAlignmentCodeCorrect(statement_aligned_code)) {
1981     return isolate->ThrowIllegalOperation();
1982   }
1983   BreakPositionAlignment alignment =
1984       static_cast<BreakPositionAlignment>(statement_aligned_code);
1985
1986   // Get the script from the script wrapper.
1987   RUNTIME_ASSERT(wrapper->value()->IsScript());
1988   Handle<Script> script(Script::cast(wrapper->value()));
1989
1990   // Set break point.
1991   if (!isolate->debug()->SetBreakPointForScript(script, break_point_object_arg,
1992                                                 &source_position, alignment)) {
1993     return isolate->heap()->undefined_value();
1994   }
1995
1996   return Smi::FromInt(source_position);
1997 }
1998
1999
2000 // Clear a break point
2001 // args[0]: number: break point object
2002 RUNTIME_FUNCTION(Runtime_ClearBreakPoint) {
2003   HandleScope scope(isolate);
2004   DCHECK(args.length() == 1);
2005   CONVERT_ARG_HANDLE_CHECKED(Object, break_point_object_arg, 0);
2006
2007   // Clear break point.
2008   isolate->debug()->ClearBreakPoint(break_point_object_arg);
2009
2010   return isolate->heap()->undefined_value();
2011 }
2012
2013
2014 // Change the state of break on exceptions.
2015 // args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
2016 // args[1]: Boolean indicating on/off.
2017 RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
2018   HandleScope scope(isolate);
2019   DCHECK(args.length() == 2);
2020   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
2021   CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
2022
2023   // If the number doesn't match an enum value, the ChangeBreakOnException
2024   // function will default to affecting caught exceptions.
2025   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
2026   // Update break point state.
2027   isolate->debug()->ChangeBreakOnException(type, enable);
2028   return isolate->heap()->undefined_value();
2029 }
2030
2031
2032 // Returns the state of break on exceptions
2033 // args[0]: boolean indicating uncaught exceptions
2034 RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
2035   HandleScope scope(isolate);
2036   DCHECK(args.length() == 1);
2037   CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
2038
2039   ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
2040   bool result = isolate->debug()->IsBreakOnException(type);
2041   return Smi::FromInt(result);
2042 }
2043
2044
2045 // Prepare for stepping
2046 // args[0]: break id for checking execution state
2047 // args[1]: step action from the enumeration StepAction
2048 // args[2]: number of times to perform the step, for step out it is the number
2049 //          of frames to step down.
2050 RUNTIME_FUNCTION(Runtime_PrepareStep) {
2051   HandleScope scope(isolate);
2052   DCHECK(args.length() == 4);
2053   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
2054   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
2055
2056   if (!args[1]->IsNumber() || !args[2]->IsNumber()) {
2057     return isolate->Throw(isolate->heap()->illegal_argument_string());
2058   }
2059
2060   CONVERT_NUMBER_CHECKED(int, wrapped_frame_id, Int32, args[3]);
2061
2062   StackFrame::Id frame_id;
2063   if (wrapped_frame_id == 0) {
2064     frame_id = StackFrame::NO_ID;
2065   } else {
2066     frame_id = UnwrapFrameId(wrapped_frame_id);
2067   }
2068
2069   // Get the step action and check validity.
2070   StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
2071   if (step_action != StepIn && step_action != StepNext &&
2072       step_action != StepOut && step_action != StepInMin &&
2073       step_action != StepMin && step_action != StepFrame) {
2074     return isolate->Throw(isolate->heap()->illegal_argument_string());
2075   }
2076
2077   if (frame_id != StackFrame::NO_ID && step_action != StepNext &&
2078       step_action != StepMin && step_action != StepOut) {
2079     return isolate->ThrowIllegalOperation();
2080   }
2081
2082   // Get the number of steps.
2083   int step_count = NumberToInt32(args[2]);
2084   if (step_count < 1) {
2085     return isolate->Throw(isolate->heap()->illegal_argument_string());
2086   }
2087
2088   // Clear all current stepping setup.
2089   isolate->debug()->ClearStepping();
2090
2091   // Prepare step.
2092   isolate->debug()->PrepareStep(static_cast<StepAction>(step_action),
2093                                 step_count, frame_id);
2094   return isolate->heap()->undefined_value();
2095 }
2096
2097
2098 // Clear all stepping set by PrepareStep.
2099 RUNTIME_FUNCTION(Runtime_ClearStepping) {
2100   HandleScope scope(isolate);
2101   DCHECK(args.length() == 0);
2102   isolate->debug()->ClearStepping();
2103   return isolate->heap()->undefined_value();
2104 }
2105
2106
2107 // Helper function to find or create the arguments object for
2108 // Runtime_DebugEvaluate.
2109 MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
2110     Isolate* isolate, Handle<JSObject> target, Handle<JSFunction> function) {
2111   // Do not materialize the arguments object for eval or top-level code.
2112   // Skip if "arguments" is already taken.
2113   if (!function->shared()->is_function()) return target;
2114   Maybe<bool> maybe = JSReceiver::HasOwnProperty(
2115       target, isolate->factory()->arguments_string());
2116   if (!maybe.has_value) return MaybeHandle<JSObject>();
2117   if (maybe.value) return target;
2118
2119   // FunctionGetArguments can't throw an exception.
2120   Handle<JSObject> arguments =
2121       Handle<JSObject>::cast(Accessors::FunctionGetArguments(function));
2122   Handle<String> arguments_str = isolate->factory()->arguments_string();
2123   RETURN_ON_EXCEPTION(isolate, Runtime::DefineObjectProperty(
2124                                    target, arguments_str, arguments, NONE),
2125                       JSObject);
2126   return target;
2127 }
2128
2129
2130 // Compile and evaluate source for the given context.
2131 static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
2132                                          Handle<SharedFunctionInfo> outer_info,
2133                                          Handle<Context> context,
2134                                          Handle<Object> context_extension,
2135                                          Handle<Object> receiver,
2136                                          Handle<String> source) {
2137   if (context_extension->IsJSObject()) {
2138     Handle<JSObject> extension = Handle<JSObject>::cast(context_extension);
2139     Handle<JSFunction> closure(context->closure(), isolate);
2140     context = isolate->factory()->NewWithContext(closure, context, extension);
2141   }
2142
2143   Handle<JSFunction> eval_fun;
2144   ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_fun,
2145                              Compiler::GetFunctionFromEval(
2146                                  source, outer_info, context, SLOPPY,
2147                                  NO_PARSE_RESTRICTION, RelocInfo::kNoPosition),
2148                              Object);
2149
2150   Handle<Object> result;
2151   ASSIGN_RETURN_ON_EXCEPTION(
2152       isolate, result, Execution::Call(isolate, eval_fun, receiver, 0, NULL),
2153       Object);
2154
2155   // Skip the global proxy as it has no properties and always delegates to the
2156   // real global object.
2157   if (result->IsJSGlobalProxy()) {
2158     PrototypeIterator iter(isolate, result);
2159     // TODO(verwaest): This will crash when the global proxy is detached.
2160     result = Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter));
2161   }
2162
2163   // Clear the oneshot breakpoints so that the debugger does not step further.
2164   isolate->debug()->ClearStepping();
2165   return result;
2166 }
2167
2168
2169 static Handle<JSObject> NewJSObjectWithNullProto(Isolate* isolate) {
2170   Handle<JSObject> result =
2171       isolate->factory()->NewJSObject(isolate->object_function());
2172   Handle<Map> new_map =
2173       Map::Copy(Handle<Map>(result->map()), "ObjectWithNullProto");
2174   new_map->SetPrototype(isolate->factory()->null_value());
2175   JSObject::MigrateToMap(result, new_map);
2176   return result;
2177 }
2178
2179
2180 // Evaluate a piece of JavaScript in the context of a stack frame for
2181 // debugging.  Things that need special attention are:
2182 // - Parameters and stack-allocated locals need to be materialized.  Altered
2183 //   values need to be written back to the stack afterwards.
2184 // - The arguments object needs to materialized.
2185 RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
2186   HandleScope scope(isolate);
2187
2188   // Check the execution state and decode arguments frame and source to be
2189   // evaluated.
2190   DCHECK(args.length() == 6);
2191   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
2192   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
2193
2194   CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
2195   CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
2196   CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
2197   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 4);
2198   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 5);
2199
2200   // Handle the processing of break.
2201   DisableBreak disable_break_scope(isolate->debug(), disable_break);
2202
2203   // Get the frame where the debugging is performed.
2204   StackFrame::Id id = UnwrapFrameId(wrapped_id);
2205   JavaScriptFrameIterator it(isolate, id);
2206   JavaScriptFrame* frame = it.frame();
2207   FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
2208   Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
2209   Handle<SharedFunctionInfo> outer_info(function->shared());
2210
2211   // Traverse the saved contexts chain to find the active context for the
2212   // selected frame.
2213   SaveContext* save = FindSavedContextForFrame(isolate, frame);
2214
2215   SaveContext savex(isolate);
2216   isolate->set_context(*(save->context()));
2217
2218   // Materialize stack locals and the arguments object.
2219   Handle<JSObject> materialized = NewJSObjectWithNullProto(isolate);
2220
2221   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2222       isolate, materialized,
2223       MaterializeStackLocalsWithFrameInspector(isolate, materialized, function,
2224                                                &frame_inspector));
2225
2226   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2227       isolate, materialized,
2228       MaterializeArgumentsObject(isolate, materialized, function));
2229
2230   // At this point, the lookup chain may look like this:
2231   // [inner context] -> [function stack]+[function context] -> [outer context]
2232   // The function stack is not an actual context, it complements the function
2233   // context. In order to have the same lookup chain when debug-evaluating,
2234   // we materialize the stack and insert it into the context chain as a
2235   // with-context before the function context.
2236   // [inner context] -> [with context] -> [function context] -> [outer context]
2237   // Ordering the with-context before the function context forces a dynamic
2238   // lookup instead of a static lookup that could fail as the scope info is
2239   // outdated and may expect variables to still be stack-allocated.
2240   // Afterwards, we write changes to the with-context back to the stack
2241   // and remove it from the context chain.
2242   // This could cause lookup failures if debug-evaluate creates a closure that
2243   // uses this temporary context chain.
2244
2245   Handle<Context> eval_context(Context::cast(frame_inspector.GetContext()));
2246   DCHECK(!eval_context.is_null());
2247   Handle<Context> function_context = eval_context;
2248   Handle<Context> outer_context(function->context(), isolate);
2249   Handle<Context> inner_context;
2250   // We iterate to find the function's context. If the function has no
2251   // context-allocated variables, we iterate until we hit the outer context.
2252   while (!function_context->IsFunctionContext() &&
2253          !function_context->IsScriptContext() &&
2254          !function_context.is_identical_to(outer_context)) {
2255     inner_context = function_context;
2256     function_context = Handle<Context>(function_context->previous(), isolate);
2257   }
2258
2259   Handle<Context> materialized_context = isolate->factory()->NewWithContext(
2260       function, function_context, materialized);
2261
2262   if (inner_context.is_null()) {
2263     // No inner context. The with-context is now inner-most.
2264     eval_context = materialized_context;
2265   } else {
2266     inner_context->set_previous(*materialized_context);
2267   }
2268
2269   Handle<Object> receiver(frame->receiver(), isolate);
2270   MaybeHandle<Object> maybe_result = DebugEvaluate(
2271       isolate, outer_info, eval_context, context_extension, receiver, source);
2272
2273   // Remove with-context if it was inserted in between.
2274   if (!inner_context.is_null()) inner_context->set_previous(*function_context);
2275
2276   Handle<Object> result;
2277   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
2278
2279   // Write back potential changes to materialized stack locals to the stack.
2280   UpdateStackLocalsFromMaterializedObject(isolate, materialized, function,
2281                                           frame, inlined_jsframe_index);
2282
2283   return *result;
2284 }
2285
2286
2287 RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
2288   HandleScope scope(isolate);
2289
2290   // Check the execution state and decode arguments frame and source to be
2291   // evaluated.
2292   DCHECK(args.length() == 4);
2293   CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
2294   RUNTIME_ASSERT(isolate->debug()->CheckExecutionState(break_id));
2295
2296   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
2297   CONVERT_BOOLEAN_ARG_CHECKED(disable_break, 2);
2298   CONVERT_ARG_HANDLE_CHECKED(Object, context_extension, 3);
2299
2300   // Handle the processing of break.
2301   DisableBreak disable_break_scope(isolate->debug(), disable_break);
2302
2303   // Enter the top context from before the debugger was invoked.
2304   SaveContext save(isolate);
2305   SaveContext* top = &save;
2306   while (top != NULL && *top->context() == *isolate->debug()->debug_context()) {
2307     top = top->prev();
2308   }
2309   if (top != NULL) {
2310     isolate->set_context(*top->context());
2311   }
2312
2313   // Get the native context now set to the top context from before the
2314   // debugger was invoked.
2315   Handle<Context> context = isolate->native_context();
2316   Handle<JSObject> receiver(context->global_proxy());
2317   Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
2318   Handle<Object> result;
2319   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2320       isolate, result, DebugEvaluate(isolate, outer_info, context,
2321                                      context_extension, receiver, source));
2322   return *result;
2323 }
2324
2325
2326 RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
2327   HandleScope scope(isolate);
2328   DCHECK(args.length() == 0);
2329
2330   DebugScope debug_scope(isolate->debug());
2331   // Fill the script objects.
2332   Handle<FixedArray> instances = isolate->debug()->GetLoadedScripts();
2333
2334   // Convert the script objects to proper JS objects.
2335   for (int i = 0; i < instances->length(); i++) {
2336     Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
2337     // Get the script wrapper in a local handle before calling GetScriptWrapper,
2338     // because using
2339     //   instances->set(i, *GetScriptWrapper(script))
2340     // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
2341     // already have dereferenced the instances handle.
2342     Handle<JSObject> wrapper = Script::GetWrapper(script);
2343     instances->set(i, *wrapper);
2344   }
2345
2346   // Return result as a JS array.
2347   Handle<JSObject> result =
2348       isolate->factory()->NewJSObject(isolate->array_function());
2349   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
2350   return *result;
2351 }
2352
2353
2354 // Helper function used by Runtime_DebugReferencedBy below.
2355 static int DebugReferencedBy(HeapIterator* iterator, JSObject* target,
2356                              Object* instance_filter, int max_references,
2357                              FixedArray* instances, int instances_size,
2358                              JSFunction* arguments_function) {
2359   Isolate* isolate = target->GetIsolate();
2360   SealHandleScope shs(isolate);
2361   DisallowHeapAllocation no_allocation;
2362
2363   // Iterate the heap.
2364   int count = 0;
2365   JSObject* last = NULL;
2366   HeapObject* heap_obj = NULL;
2367   while (((heap_obj = iterator->next()) != NULL) &&
2368          (max_references == 0 || count < max_references)) {
2369     // Only look at all JSObjects.
2370     if (heap_obj->IsJSObject()) {
2371       // Skip context extension objects and argument arrays as these are
2372       // checked in the context of functions using them.
2373       JSObject* obj = JSObject::cast(heap_obj);
2374       if (obj->IsJSContextExtensionObject() ||
2375           obj->map()->constructor() == arguments_function) {
2376         continue;
2377       }
2378
2379       // Check if the JS object has a reference to the object looked for.
2380       if (obj->ReferencesObject(target)) {
2381         // Check instance filter if supplied. This is normally used to avoid
2382         // references from mirror objects (see Runtime_IsInPrototypeChain).
2383         if (!instance_filter->IsUndefined()) {
2384           for (PrototypeIterator iter(isolate, obj); !iter.IsAtEnd();
2385                iter.Advance()) {
2386             if (iter.GetCurrent() == instance_filter) {
2387               obj = NULL;  // Don't add this object.
2388               break;
2389             }
2390           }
2391         }
2392
2393         if (obj != NULL) {
2394           // Valid reference found add to instance array if supplied an update
2395           // count.
2396           if (instances != NULL && count < instances_size) {
2397             instances->set(count, obj);
2398           }
2399           last = obj;
2400           count++;
2401         }
2402       }
2403     }
2404   }
2405
2406   // Check for circular reference only. This can happen when the object is only
2407   // referenced from mirrors and has a circular reference in which case the
2408   // object is not really alive and would have been garbage collected if not
2409   // referenced from the mirror.
2410   if (count == 1 && last == target) {
2411     count = 0;
2412   }
2413
2414   // Return the number of referencing objects found.
2415   return count;
2416 }
2417
2418
2419 // Scan the heap for objects with direct references to an object
2420 // args[0]: the object to find references to
2421 // args[1]: constructor function for instances to exclude (Mirror)
2422 // args[2]: the the maximum number of objects to return
2423 RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
2424   HandleScope scope(isolate);
2425   DCHECK(args.length() == 3);
2426
2427   // Check parameters.
2428   CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
2429   CONVERT_ARG_HANDLE_CHECKED(Object, instance_filter, 1);
2430   RUNTIME_ASSERT(instance_filter->IsUndefined() ||
2431                  instance_filter->IsJSObject());
2432   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
2433   RUNTIME_ASSERT(max_references >= 0);
2434
2435
2436   // Get the constructor function for context extension and arguments array.
2437   Handle<JSFunction> arguments_function(
2438       JSFunction::cast(isolate->sloppy_arguments_map()->constructor()));
2439
2440   // Get the number of referencing objects.
2441   int count;
2442   // First perform a full GC in order to avoid dead objects and to make the heap
2443   // iterable.
2444   Heap* heap = isolate->heap();
2445   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
2446   {
2447     HeapIterator heap_iterator(heap);
2448     count = DebugReferencedBy(&heap_iterator, *target, *instance_filter,
2449                               max_references, NULL, 0, *arguments_function);
2450   }
2451
2452   // Allocate an array to hold the result.
2453   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
2454
2455   // Fill the referencing objects.
2456   {
2457     HeapIterator heap_iterator(heap);
2458     count = DebugReferencedBy(&heap_iterator, *target, *instance_filter,
2459                               max_references, *instances, count,
2460                               *arguments_function);
2461   }
2462
2463   // Return result as JS array.
2464   Handle<JSFunction> constructor = isolate->array_function();
2465
2466   Handle<JSObject> result = isolate->factory()->NewJSObject(constructor);
2467   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
2468   return *result;
2469 }
2470
2471
2472 // Helper function used by Runtime_DebugConstructedBy below.
2473 static int DebugConstructedBy(HeapIterator* iterator, JSFunction* constructor,
2474                               int max_references, FixedArray* instances,
2475                               int instances_size) {
2476   DisallowHeapAllocation no_allocation;
2477
2478   // Iterate the heap.
2479   int count = 0;
2480   HeapObject* heap_obj = NULL;
2481   while (((heap_obj = iterator->next()) != NULL) &&
2482          (max_references == 0 || count < max_references)) {
2483     // Only look at all JSObjects.
2484     if (heap_obj->IsJSObject()) {
2485       JSObject* obj = JSObject::cast(heap_obj);
2486       if (obj->map()->constructor() == constructor) {
2487         // Valid reference found add to instance array if supplied an update
2488         // count.
2489         if (instances != NULL && count < instances_size) {
2490           instances->set(count, obj);
2491         }
2492         count++;
2493       }
2494     }
2495   }
2496
2497   // Return the number of referencing objects found.
2498   return count;
2499 }
2500
2501
2502 // Scan the heap for objects constructed by a specific function.
2503 // args[0]: the constructor to find instances of
2504 // args[1]: the the maximum number of objects to return
2505 RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
2506   HandleScope scope(isolate);
2507   DCHECK(args.length() == 2);
2508
2509
2510   // Check parameters.
2511   CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
2512   CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
2513   RUNTIME_ASSERT(max_references >= 0);
2514
2515   // Get the number of referencing objects.
2516   int count;
2517   // First perform a full GC in order to avoid dead objects and to make the heap
2518   // iterable.
2519   Heap* heap = isolate->heap();
2520   heap->CollectAllGarbage(Heap::kMakeHeapIterableMask, "%DebugConstructedBy");
2521   {
2522     HeapIterator heap_iterator(heap);
2523     count = DebugConstructedBy(&heap_iterator, *constructor, max_references,
2524                                NULL, 0);
2525   }
2526
2527   // Allocate an array to hold the result.
2528   Handle<FixedArray> instances = isolate->factory()->NewFixedArray(count);
2529
2530   // Fill the referencing objects.
2531   {
2532     HeapIterator heap_iterator2(heap);
2533     count = DebugConstructedBy(&heap_iterator2, *constructor, max_references,
2534                                *instances, count);
2535   }
2536
2537   // Return result as JS array.
2538   Handle<JSFunction> array_function = isolate->array_function();
2539   Handle<JSObject> result = isolate->factory()->NewJSObject(array_function);
2540   JSArray::SetContent(Handle<JSArray>::cast(result), instances);
2541   return *result;
2542 }
2543
2544
2545 // Find the effective prototype object as returned by __proto__.
2546 // args[0]: the object to find the prototype for.
2547 RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
2548   HandleScope shs(isolate);
2549   DCHECK(args.length() == 1);
2550   CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
2551   return *Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
2552 }
2553
2554
2555 // Patches script source (should be called upon BeforeCompile event).
2556 RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
2557   HandleScope scope(isolate);
2558   DCHECK(args.length() == 2);
2559
2560   CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
2561   CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
2562
2563   RUNTIME_ASSERT(script_wrapper->value()->IsScript());
2564   Handle<Script> script(Script::cast(script_wrapper->value()));
2565
2566   int compilation_state = script->compilation_state();
2567   RUNTIME_ASSERT(compilation_state == Script::COMPILATION_STATE_INITIAL);
2568   script->set_source(*source);
2569
2570   return isolate->heap()->undefined_value();
2571 }
2572
2573
2574 RUNTIME_FUNCTION(Runtime_DebugDisassembleFunction) {
2575   HandleScope scope(isolate);
2576 #ifdef DEBUG
2577   DCHECK(args.length() == 1);
2578   // Get the function and make sure it is compiled.
2579   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
2580   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
2581     return isolate->heap()->exception();
2582   }
2583   OFStream os(stdout);
2584   func->code()->Print(os);
2585   os << std::endl;
2586 #endif  // DEBUG
2587   return isolate->heap()->undefined_value();
2588 }
2589
2590
2591 RUNTIME_FUNCTION(Runtime_DebugDisassembleConstructor) {
2592   HandleScope scope(isolate);
2593 #ifdef DEBUG
2594   DCHECK(args.length() == 1);
2595   // Get the function and make sure it is compiled.
2596   CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
2597   if (!Compiler::EnsureCompiled(func, KEEP_EXCEPTION)) {
2598     return isolate->heap()->exception();
2599   }
2600   OFStream os(stdout);
2601   func->shared()->construct_stub()->Print(os);
2602   os << std::endl;
2603 #endif  // DEBUG
2604   return isolate->heap()->undefined_value();
2605 }
2606
2607
2608 RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
2609   SealHandleScope shs(isolate);
2610   DCHECK(args.length() == 1);
2611
2612   CONVERT_ARG_CHECKED(JSFunction, f, 0);
2613   return f->shared()->inferred_name();
2614 }
2615
2616
2617 // A testing entry. Returns statement position which is the closest to
2618 // source_position.
2619 RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
2620   HandleScope scope(isolate);
2621   CHECK(isolate->debug()->live_edit_enabled());
2622   DCHECK(args.length() == 2);
2623   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
2624   CONVERT_NUMBER_CHECKED(int32_t, source_position, Int32, args[1]);
2625
2626   Handle<Code> code(function->code(), isolate);
2627
2628   if (code->kind() != Code::FUNCTION &&
2629       code->kind() != Code::OPTIMIZED_FUNCTION) {
2630     return isolate->heap()->undefined_value();
2631   }
2632
2633   RelocIterator it(*code, RelocInfo::ModeMask(RelocInfo::STATEMENT_POSITION));
2634   int closest_pc = 0;
2635   int distance = kMaxInt;
2636   while (!it.done()) {
2637     int statement_position = static_cast<int>(it.rinfo()->data());
2638     // Check if this break point is closer that what was previously found.
2639     if (source_position <= statement_position &&
2640         statement_position - source_position < distance) {
2641       closest_pc =
2642           static_cast<int>(it.rinfo()->pc() - code->instruction_start());
2643       distance = statement_position - source_position;
2644       // Check whether we can't get any closer.
2645       if (distance == 0) break;
2646     }
2647     it.next();
2648   }
2649
2650   return Smi::FromInt(closest_pc);
2651 }
2652
2653
2654 // Calls specified function with or without entering the debugger.
2655 // This is used in unit tests to run code as if debugger is entered or simply
2656 // to have a stack with C++ frame in the middle.
2657 RUNTIME_FUNCTION(Runtime_ExecuteInDebugContext) {
2658   HandleScope scope(isolate);
2659   DCHECK(args.length() == 2);
2660   CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
2661   CONVERT_BOOLEAN_ARG_CHECKED(without_debugger, 1);
2662
2663   MaybeHandle<Object> maybe_result;
2664   if (without_debugger) {
2665     maybe_result = Execution::Call(isolate, function,
2666                                    handle(function->global_proxy()), 0, NULL);
2667   } else {
2668     DebugScope debug_scope(isolate->debug());
2669     maybe_result = Execution::Call(isolate, function,
2670                                    handle(function->global_proxy()), 0, NULL);
2671   }
2672   Handle<Object> result;
2673   ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, maybe_result);
2674   return *result;
2675 }
2676
2677
2678 RUNTIME_FUNCTION(Runtime_GetDebugContext) {
2679   HandleScope scope(isolate);
2680   DCHECK(args.length() == 0);
2681   Handle<Context> context = isolate->debug()->GetDebugContext();
2682   context->set_security_token(isolate->native_context()->security_token());
2683   return context->global_proxy();
2684 }
2685
2686
2687 // Performs a GC.
2688 // Presently, it only does a full GC.
2689 RUNTIME_FUNCTION(Runtime_CollectGarbage) {
2690   SealHandleScope shs(isolate);
2691   DCHECK(args.length() == 1);
2692   isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, "%CollectGarbage");
2693   return isolate->heap()->undefined_value();
2694 }
2695
2696
2697 // Gets the current heap usage.
2698 RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
2699   SealHandleScope shs(isolate);
2700   DCHECK(args.length() == 0);
2701   int usage = static_cast<int>(isolate->heap()->SizeOfObjects());
2702   if (!Smi::IsValid(usage)) {
2703     return *isolate->factory()->NewNumberFromInt(usage);
2704   }
2705   return Smi::FromInt(usage);
2706 }
2707
2708
2709 // Finds the script object from the script data. NOTE: This operation uses
2710 // heap traversal to find the function generated for the source position
2711 // for the requested break point. For lazily compiled functions several heap
2712 // traversals might be required rendering this operation as a rather slow
2713 // operation. However for setting break points which is normally done through
2714 // some kind of user interaction the performance is not crucial.
2715 RUNTIME_FUNCTION(Runtime_GetScript) {
2716   HandleScope scope(isolate);
2717   DCHECK(args.length() == 1);
2718   CONVERT_ARG_HANDLE_CHECKED(String, script_name, 0);
2719
2720   Handle<Script> found;
2721   Heap* heap = isolate->heap();
2722   {
2723     HeapIterator iterator(heap);
2724     HeapObject* obj = NULL;
2725     while ((obj = iterator.next()) != NULL) {
2726       if (!obj->IsScript()) continue;
2727       Script* script = Script::cast(obj);
2728       if (!script->name()->IsString()) continue;
2729       String* name = String::cast(script->name());
2730       if (name->Equals(*script_name)) {
2731         found = Handle<Script>(script, isolate);
2732         break;
2733       }
2734     }
2735   }
2736
2737   if (found.is_null()) return heap->undefined_value();
2738   return *Script::GetWrapper(found);
2739 }
2740
2741
2742 // Check whether debugger and is about to step into the callback that is passed
2743 // to a built-in function such as Array.forEach.
2744 RUNTIME_FUNCTION(Runtime_DebugCallbackSupportsStepping) {
2745   DCHECK(args.length() == 1);
2746   Debug* debug = isolate->debug();
2747   if (!debug->is_active() || !debug->IsStepping() ||
2748       debug->last_step_action() != StepIn) {
2749     return isolate->heap()->false_value();
2750   }
2751   CONVERT_ARG_CHECKED(Object, callback, 0);
2752   // We do not step into the callback if it's a builtin or not even a function.
2753   return isolate->heap()->ToBoolean(callback->IsJSFunction() &&
2754                                     !JSFunction::cast(callback)->IsBuiltin());
2755 }
2756
2757
2758 // Set one shot breakpoints for the callback function that is passed to a
2759 // built-in function such as Array.forEach to enable stepping into the callback.
2760 RUNTIME_FUNCTION(Runtime_DebugPrepareStepInIfStepping) {
2761   DCHECK(args.length() == 1);
2762   Debug* debug = isolate->debug();
2763   if (!debug->IsStepping()) return isolate->heap()->undefined_value();
2764
2765   HandleScope scope(isolate);
2766   CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
2767   RUNTIME_ASSERT(object->IsJSFunction() || object->IsJSGeneratorObject());
2768   Handle<JSFunction> fun;
2769   if (object->IsJSFunction()) {
2770     fun = Handle<JSFunction>::cast(object);
2771   } else {
2772     fun = Handle<JSFunction>(
2773         Handle<JSGeneratorObject>::cast(object)->function(), isolate);
2774   }
2775   // When leaving the function, step out has been activated, but not performed
2776   // if we do not leave the builtin.  To be able to step into the function
2777   // again, we need to clear the step out at this point.
2778   debug->ClearStepOut();
2779   debug->FloodWithOneShot(fun);
2780   return isolate->heap()->undefined_value();
2781 }
2782
2783
2784 RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
2785   DCHECK(args.length() == 1);
2786   HandleScope scope(isolate);
2787   CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
2788   isolate->PushPromise(promise);
2789   return isolate->heap()->undefined_value();
2790 }
2791
2792
2793 RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
2794   DCHECK(args.length() == 0);
2795   SealHandleScope shs(isolate);
2796   isolate->PopPromise();
2797   return isolate->heap()->undefined_value();
2798 }
2799
2800
2801 RUNTIME_FUNCTION(Runtime_DebugPromiseEvent) {
2802   DCHECK(args.length() == 1);
2803   HandleScope scope(isolate);
2804   CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
2805   isolate->debug()->OnPromiseEvent(data);
2806   return isolate->heap()->undefined_value();
2807 }
2808
2809
2810 RUNTIME_FUNCTION(Runtime_DebugAsyncTaskEvent) {
2811   DCHECK(args.length() == 1);
2812   HandleScope scope(isolate);
2813   CONVERT_ARG_HANDLE_CHECKED(JSObject, data, 0);
2814   isolate->debug()->OnAsyncTaskEvent(data);
2815   return isolate->heap()->undefined_value();
2816 }
2817
2818
2819 RUNTIME_FUNCTION(RuntimeReference_DebugIsActive) {
2820   SealHandleScope shs(isolate);
2821   return Smi::FromInt(isolate->debug()->is_active());
2822 }
2823
2824
2825 RUNTIME_FUNCTION(RuntimeReference_DebugBreakInOptimizedCode) {
2826   UNIMPLEMENTED();
2827   return NULL;
2828 }
2829 }
2830 }  // namespace v8::internal