Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(57)

Unified Diff: src/runtime.cc

Issue 7535004: Merge bleeding edge up to 8774 into the GC branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 8778)
+++ src/runtime.cc (working copy)
@@ -219,9 +219,21 @@
}
break;
}
- default:
- UNREACHABLE();
+ case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS:
+ UNIMPLEMENTED();
break;
+ case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+ case JSObject::EXTERNAL_BYTE_ELEMENTS:
+ case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+ case JSObject::EXTERNAL_SHORT_ELEMENTS:
+ case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
+ case JSObject::EXTERNAL_INT_ELEMENTS:
+ case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
+ case JSObject::EXTERNAL_FLOAT_ELEMENTS:
+ case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
+ case JSObject::FAST_DOUBLE_ELEMENTS:
+ // No contained objects, nothing to do.
+ break;
}
return copy;
}
@@ -615,6 +627,14 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Fix) {
+ ASSERT(args.length() == 1);
+ CONVERT_CHECKED(JSProxy, proxy, args[0]);
+ proxy->Fix();
+ return isolate->heap()->undefined_value();
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_ClassOf) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
@@ -1152,7 +1172,7 @@
return ThrowRedeclarationError(isolate, "const", name);
}
// Otherwise, we check for locally conflicting declarations.
- if (is_local && (is_read_only || is_const_property)) {
+ if (is_local && is_const_property) {
const char* type = (is_read_only) ? "const" : "var";
return ThrowRedeclarationError(isolate, type, name);
}
@@ -1386,12 +1406,11 @@
// make sure to introduce it.
found = false;
} else if ((intercepted & READ_ONLY) != 0) {
- // The property is present, but read-only. Since we're trying to
- // overwrite it with a variable declaration we must throw a
- // re-declaration error. However if we found readonly property
+ // The property is present, but read-only, so we ignore the
+ // redeclaration. However if we found readonly property
// on one of hidden prototypes, just shadow it.
if (real_holder != isolate->context()->global()) break;
- return ThrowRedeclarationError(isolate, "const", name);
+ return isolate->heap()->undefined_value();
}
}
@@ -1658,7 +1677,9 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpConstructResult) {
ASSERT(args.length() == 3);
CONVERT_SMI_ARG_CHECKED(elements_count, 0);
- if (elements_count > JSArray::kMaxFastElementsLength) {
+ if (elements_count < 0 ||
+ elements_count > FixedArray::kMaxLength ||
+ !Smi::IsValid(elements_count)) {
return isolate->ThrowIllegalOperation();
}
Object* new_object;
@@ -1960,6 +1981,61 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
+ NoHandleAllocation ha;
+ RUNTIME_ASSERT(args.length() == 1);
+ CONVERT_CHECKED(JSFunction, function, args[0]);
+
+ MaybeObject* maybe_name =
+ isolate->heap()->AllocateStringFromAscii(CStrVector("prototype"));
+ String* name;
+ if (!maybe_name->To(&name)) return maybe_name;
+
+ if (function->HasFastProperties()) {
+ // Construct a new field descriptor with updated attributes.
+ DescriptorArray* instance_desc = function->map()->instance_descriptors();
+ int index = instance_desc->Search(name);
+ ASSERT(index != DescriptorArray::kNotFound);
+ PropertyDetails details(instance_desc->GetDetails(index));
+ CallbacksDescriptor new_desc(name,
+ instance_desc->GetValue(index),
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
+ details.index());
+ // Construct a new field descriptors array containing the new descriptor.
+ Object* descriptors_unchecked;
+ { MaybeObject* maybe_descriptors_unchecked =
+ instance_desc->CopyInsert(&new_desc, REMOVE_TRANSITIONS);
+ if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) {
+ return maybe_descriptors_unchecked;
+ }
+ }
+ DescriptorArray* new_descriptors =
+ DescriptorArray::cast(descriptors_unchecked);
+ // Create a new map featuring the new field descriptors array.
+ Object* map_unchecked;
+ { MaybeObject* maybe_map_unchecked = function->map()->CopyDropDescriptors();
+ if (!maybe_map_unchecked->ToObject(&map_unchecked)) {
+ return maybe_map_unchecked;
+ }
+ }
+ Map* new_map = Map::cast(map_unchecked);
+ new_map->set_instance_descriptors(new_descriptors);
+ function->set_map(new_map);
+ } else { // Dictionary properties.
+ // Directly manipulate the property details.
+ int entry = function->property_dictionary()->FindEntry(name);
+ ASSERT(entry != StringDictionary::kNotFound);
+ PropertyDetails details = function->property_dictionary()->DetailsAt(entry);
+ PropertyDetails new_details(
+ static_cast<PropertyAttributes>(details.attributes() | READ_ONLY),
+ details.type(),
+ details.index());
+ function->property_dictionary()->DetailsAtPut(entry, new_details);
+ }
+ return function;
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionIsAPIFunction) {
NoHandleAllocation ha;
ASSERT(args.length() == 1);
@@ -3875,7 +3951,7 @@
|| result.type() == CONSTANT_FUNCTION)) {
Object* ok;
{ MaybeObject* maybe_ok =
- obj->DeleteProperty(name, JSObject::NORMAL_DELETION);
+ obj->DeleteProperty(name, JSReceiver::NORMAL_DELETION);
if (!maybe_ok->ToObject(&ok)) return maybe_ok;
}
}
@@ -4129,24 +4205,25 @@
MaybeObject* Runtime::ForceDeleteObjectProperty(Isolate* isolate,
- Handle<JSObject> js_object,
+ Handle<JSReceiver> receiver,
Handle<Object> key) {
HandleScope scope(isolate);
// Check if the given key is an array index.
uint32_t index;
- if (key->ToArrayIndex(&index)) {
+ if (receiver->IsJSObject() && key->ToArrayIndex(&index)) {
// In Firefox/SpiderMonkey, Safari and Opera you can access the
// characters of a string using [] notation. In the case of a
// String object we just need to redirect the deletion to the
// underlying string if the index is in range. Since the
// underlying string does nothing with the deletion, we can ignore
// such deletions.
- if (js_object->IsStringObjectWithCharacterAt(index)) {
+ if (receiver->IsStringObjectWithCharacterAt(index)) {
return isolate->heap()->true_value();
}
- return js_object->DeleteElement(index, JSObject::FORCE_DELETION);
+ return JSObject::cast(*receiver)->DeleteElement(
+ index, JSReceiver::FORCE_DELETION);
}
Handle<String> key_string;
@@ -4161,7 +4238,7 @@
}
key_string->TryFlatten();
- return js_object->DeleteProperty(*key_string, JSObject::FORCE_DELETION);
+ return receiver->DeleteProperty(*key_string, JSReceiver::FORCE_DELETION);
}
@@ -4240,12 +4317,12 @@
NoHandleAllocation ha;
ASSERT(args.length() == 3);
- CONVERT_CHECKED(JSObject, object, args[0]);
+ CONVERT_CHECKED(JSReceiver, object, args[0]);
CONVERT_CHECKED(String, key, args[1]);
CONVERT_SMI_ARG_CHECKED(strict, 2);
return object->DeleteProperty(key, (strict == kStrictMode)
- ? JSObject::STRICT_DELETION
- : JSObject::NORMAL_DELETION);
+ ? JSReceiver::STRICT_DELETION
+ : JSReceiver::NORMAL_DELETION);
}
@@ -4309,11 +4386,11 @@
NoHandleAllocation na;
ASSERT(args.length() == 2);
- // Only JS objects can have properties.
- if (args[0]->IsJSObject()) {
- JSObject* object = JSObject::cast(args[0]);
+ // Only JS receivers can have properties.
+ if (args[0]->IsJSReceiver()) {
+ JSReceiver* receiver = JSReceiver::cast(args[0]);
CONVERT_CHECKED(String, key, args[1]);
- if (object->HasProperty(key)) return isolate->heap()->true_value();
+ if (receiver->HasProperty(key)) return isolate->heap()->true_value();
}
return isolate->heap()->false_value();
}
@@ -4457,7 +4534,7 @@
for (int i = 0; i < length; i++) {
jsproto->GetLocalPropertyNames(*names,
i == 0 ? 0 : local_property_count[i - 1]);
- if (!GetHiddenProperties(jsproto, false)->IsUndefined()) {
+ if (jsproto->HasHiddenProperties()) {
proto_with_hidden_properties++;
}
if (i < length - 1) {
@@ -8201,9 +8278,9 @@
// index is non-negative.
Handle<JSObject> object = Handle<JSObject>::cast(holder);
if (index >= 0) {
- return object->DeleteElement(index, JSObject::NORMAL_DELETION);
+ return object->DeleteElement(index, JSReceiver::NORMAL_DELETION);
} else {
- return object->DeleteProperty(*name, JSObject::NORMAL_DELETION);
+ return object->DeleteProperty(*name, JSReceiver::NORMAL_DELETION);
}
}
@@ -9515,6 +9592,9 @@
if (new_elements->map() == isolate->heap()->fixed_array_map() ||
new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
maybe_new_map = to->map()->GetFastElementsMap();
+ } else if (new_elements->map() ==
+ isolate->heap()->fixed_double_array_map()) {
+ maybe_new_map = to->map()->GetFastDoubleElementsMap();
} else {
maybe_new_map = to->map()->GetSlowElementsMap();
}
@@ -9602,12 +9682,13 @@
}
return *isolate->factory()->NewJSArrayWithElements(keys);
} else {
- ASSERT(array->HasFastElements());
+ ASSERT(array->HasFastElements() || array->HasFastDoubleElements());
Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
// -1 means start of array.
single_interval->set(0, Smi::FromInt(-1));
+ FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
uint32_t actual_length =
- static_cast<uint32_t>(FixedArray::cast(array->elements())->length());
+ static_cast<uint32_t>(elements->length());
uint32_t min_length = actual_length < length ? actual_length : length;
Handle<Object> length_object =
isolate->factory()->NewNumber(static_cast<double>(min_length));
@@ -9979,6 +10060,71 @@
}
+class FrameInspector {
+ public:
+ FrameInspector(JavaScriptFrame* frame,
+ int inlined_frame_index,
+ Isolate* isolate)
+ : frame_(frame), deoptimized_frame_(NULL), isolate_(isolate) {
+ // Calculate the deoptimized frame.
+ if (frame->is_optimized()) {
+ deoptimized_frame_ = Deoptimizer::DebuggerInspectableFrame(
+ frame, inlined_frame_index, isolate);
+ }
+ has_adapted_arguments_ = frame_->has_adapted_arguments();
+ is_optimized_ = frame_->is_optimized();
+ }
+
+ ~FrameInspector() {
+ // Get rid of the calculated deoptimized frame if any.
+ if (deoptimized_frame_ != NULL) {
+ Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame_,
+ isolate_);
+ }
+ }
+
+ int GetParametersCount() {
+ return is_optimized_
+ ? deoptimized_frame_->parameters_count()
+ : frame_->ComputeParametersCount();
+ }
+ int expression_count() { return deoptimized_frame_->expression_count(); }
+ Object* GetFunction() {
+ return is_optimized_
+ ? deoptimized_frame_->GetFunction()
+ : frame_->function();
+ }
+ Object* GetParameter(int index) {
+ return is_optimized_
+ ? deoptimized_frame_->GetParameter(index)
+ : frame_->GetParameter(index);
+ }
+ Object* GetExpression(int index) {
+ return is_optimized_
+ ? deoptimized_frame_->GetExpression(index)
+ : frame_->GetExpression(index);
+ }
+
+ // To inspect all the provided arguments the frame might need to be
+ // replaced with the arguments frame.
+ void SetArgumentsFrame(JavaScriptFrame* frame) {
+ ASSERT(has_adapted_arguments_);
+ frame_ = frame;
+ is_optimized_ = frame_->is_optimized();
+ ASSERT(!is_optimized_);
+ }
+
+ private:
+ JavaScriptFrame* frame_;
+ DeoptimizedFrameInfo* deoptimized_frame_;
+ Isolate* isolate_;
+ bool is_optimized_;
+ bool has_adapted_arguments_;
+
+ DISALLOW_COPY_AND_ASSIGN(FrameInspector);
+};
+
+
static const int kFrameDetailsFrameIdIndex = 0;
static const int kFrameDetailsReceiverIndex = 1;
static const int kFrameDetailsFunctionIndex = 2;
@@ -10027,8 +10173,7 @@
return heap->undefined_value();
}
- int deoptimized_frame_index = -1; // Frame index in optimized frame.
- DeoptimizedFrameInfo* deoptimized_frame = NULL;
+ int inlined_frame_index = 0; // Inlined frame index in optimized frame.
int count = 0;
JavaScriptFrameIterator it(isolate, id);
@@ -10039,13 +10184,10 @@
if (it.done()) return heap->undefined_value();
if (it.frame()->is_optimized()) {
- deoptimized_frame_index =
+ inlined_frame_index =
it.frame()->GetInlineCount() - (index - count) - 1;
- deoptimized_frame = Deoptimizer::DebuggerInspectableFrame(
- it.frame(),
- deoptimized_frame_index,
- isolate);
}
+ FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate);
// Traverse the saved contexts chain to find the active context for the
// selected frame.
@@ -10064,12 +10206,13 @@
// Check for constructor frame. Inlined frames cannot be construct calls.
bool inlined_frame =
- it.frame()->is_optimized() && deoptimized_frame_index != 0;
+ it.frame()->is_optimized() && inlined_frame_index != 0;
bool constructor = !inlined_frame && it.frame()->IsConstructor();
// Get scope info and read from it for local variable information.
Handle<JSFunction> function(JSFunction::cast(it.frame()->function()));
- Handle<SerializedScopeInfo> scope_info(function->shared()->scope_info());
+ Handle<SharedFunctionInfo> shared(function->shared());
+ Handle<SerializedScopeInfo> scope_info(shared->scope_info());
ASSERT(*scope_info != SerializedScopeInfo::Empty());
ScopeInfo<> info(*scope_info);
@@ -10086,14 +10229,7 @@
for (; i < info.number_of_stack_slots(); ++i) {
// Use the value from the stack.
locals->set(i * 2, *info.LocalName(i));
- if (it.frame()->is_optimized()) {
- // Get the value from the deoptimized frame.
- locals->set(i * 2 + 1,
- deoptimized_frame->GetExpression(i));
- } else {
- // Get the value from the stack.
- locals->set(i * 2 + 1, it.frame()->GetExpression(i));
- }
+ locals->set(i * 2 + 1, frame_inspector.GetExpression(i));
}
if (i < info.NumberOfLocals()) {
// Get the context containing declarations.
@@ -10150,18 +10286,22 @@
// the provided parameters whereas the function frame always have the number
// of arguments matching the functions parameters. The rest of the
// information (except for what is collected above) is the same.
- it.AdvanceToArgumentsFrame();
+ if (it.frame()->has_adapted_arguments()) {
+ it.AdvanceToArgumentsFrame();
+ frame_inspector.SetArgumentsFrame(it.frame());
+ }
// Find the number of arguments to fill. At least fill the number of
// parameters for the function and fill more if more parameters are provided.
int argument_count = info.number_of_parameters();
+ if (argument_count < frame_inspector.GetParametersCount()) {
+ argument_count = frame_inspector.GetParametersCount();
+ }
+#ifdef DEBUG
if (it.frame()->is_optimized()) {
- ASSERT_EQ(argument_count, deoptimized_frame->parameters_count());
- } else {
- if (argument_count < it.frame()->ComputeParametersCount()) {
- argument_count = it.frame()->ComputeParametersCount();
- }
+ ASSERT_EQ(argument_count, frame_inspector.GetParametersCount());
}
+#endif
// Calculate the size of the result.
int details_size = kFrameDetailsFirstDynamicIndex +
@@ -10173,13 +10313,7 @@
details->set(kFrameDetailsFrameIdIndex, *frame_id);
// Add the function (same as in function frame).
- if (it.frame()->is_optimized()) {
- // Get the function from the deoptimized frame.
- details->set(kFrameDetailsFunctionIndex, deoptimized_frame->GetFunction());
- } else {
- // Get the function from the stack.
- details->set(kFrameDetailsFunctionIndex, it.frame()->function());
- }
+ details->set(kFrameDetailsFunctionIndex, frame_inspector.GetFunction());
// Add the arguments count.
details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
@@ -10211,9 +10345,7 @@
}
if (it.frame()->is_optimized()) {
flags |= 1 << 1;
- if (deoptimized_frame_index > 0) {
- flags |= 1 << 2;
- }
+ flags |= inlined_frame_index << 2;
}
details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
@@ -10230,16 +10362,11 @@
}
// Parameter value.
- if (it.frame()->is_optimized()) {
- // Get the value from the deoptimized frame.
- details->set(details_index++, deoptimized_frame->GetParameter(i));
+ if (i < it.frame()->ComputeParametersCount()) {
+ // Get the value from the stack.
+ details->set(details_index++, frame_inspector.GetParameter(i));
} else {
- if (i < it.frame()->ComputeParametersCount()) {
- // Get the value from the stack.
- details->set(details_index++, it.frame()->GetParameter(i));
- } else {
- details->set(details_index++, heap->undefined_value());
- }
+ details->set(details_index++, heap->undefined_value());
}
}
@@ -10257,10 +10384,11 @@
// THIS MUST BE DONE LAST SINCE WE MIGHT ADVANCE
// THE FRAME ITERATOR TO WRAP THE RECEIVER.
Handle<Object> receiver(it.frame()->receiver(), isolate);
- if (!receiver->IsJSObject()) {
- // If the receiver is NOT a JSObject we have hit an optimization
- // where a value object is not converted into a wrapped JS objects.
- // To hide this optimization from the debugger, we wrap the receiver
+ if (!receiver->IsJSObject() && !shared->strict_mode() && !shared->native()) {
+ // If the receiver is not a JSObject and the function is not a
+ // builtin or strict-mode we have hit an optimization where a
+ // value object is not converted into a wrapped JS objects. To
+ // hide this optimization from the debugger, we wrap the receiver
// by creating correct wrapper object based on the calling frame's
// global context.
it.Advance();
@@ -10271,12 +10399,6 @@
}
details->set(kFrameDetailsReceiverIndex, *receiver);
- // Get rid of the calculated deoptimized frame if any.
- if (deoptimized_frame != NULL) {
- Deoptimizer::DeleteDebuggerInspectableFrame(deoptimized_frame,
- isolate);
- }
-
ASSERT_EQ(details_size, details_index);
return *isolate->factory()->NewJSArrayWithElements(details);
}
@@ -10312,12 +10434,15 @@
// Create a plain JSObject which materializes the local scope for the specified
// frame.
-static Handle<JSObject> MaterializeLocalScope(Isolate* isolate,
- JavaScriptFrame* frame) {
+static Handle<JSObject> MaterializeLocalScope(
+ Isolate* isolate,
+ JavaScriptFrame* frame,
+ int inlined_frame_index) {
Handle<JSFunction> function(JSFunction::cast(frame->function()));
Handle<SharedFunctionInfo> shared(function->shared());
Handle<SerializedScopeInfo> serialized_scope_info(shared->scope_info());
ScopeInfo<> scope_info(*serialized_scope_info);
+ FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
// Allocate and initialize a JSObject with all the arguments, stack locals
// heap locals and extension properties of the debugged function.
@@ -10330,7 +10455,7 @@
isolate,
SetProperty(local_scope,
scope_info.parameter_name(i),
- Handle<Object>(frame->GetParameter(i), isolate),
+ Handle<Object>(frame_inspector.GetParameter(i)),
NONE,
kNonStrictMode),
Handle<JSObject>());
@@ -10342,7 +10467,7 @@
isolate,
SetProperty(local_scope,
scope_info.stack_slot_name(i),
- Handle<Object>(frame->GetExpression(i), isolate),
+ Handle<Object>(frame_inspector.GetExpression(i)),
NONE,
kNonStrictMode),
Handle<JSObject>());
@@ -10462,9 +10587,12 @@
ScopeTypeCatch
};
- ScopeIterator(Isolate* isolate, JavaScriptFrame* frame)
+ ScopeIterator(Isolate* isolate,
+ JavaScriptFrame* frame,
+ int inlined_frame_index)
: isolate_(isolate),
frame_(frame),
+ inlined_frame_index_(inlined_frame_index),
function_(JSFunction::cast(frame->function())),
context_(Context::cast(frame->context())),
local_done_(false),
@@ -10549,7 +10677,7 @@
return Handle<JSObject>(CurrentContext()->global());
case ScopeIterator::ScopeTypeLocal:
// Materialize the content of the local scope into a JSObject.
- return MaterializeLocalScope(isolate_, frame_);
+ return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_);
case ScopeIterator::ScopeTypeWith:
// Return the with object.
return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
@@ -10629,6 +10757,7 @@
private:
Isolate* isolate_;
JavaScriptFrame* frame_;
+ int inlined_frame_index_;
Handle<JSFunction> function_;
Handle<Context> context_;
bool local_done_;
@@ -10657,7 +10786,9 @@
// Count the visible scopes.
int n = 0;
- for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) {
+ for (ScopeIterator it(isolate, frame, 0);
+ !it.Done();
+ it.Next()) {
n++;
}
@@ -10672,14 +10803,15 @@
// Return an array with scope details
// args[0]: number: break id
// args[1]: number: frame index
-// args[2]: number: scope index
+// args[2]: number: inlined frame index
+// args[3]: number: scope index
//
// The array returned contains the following information:
// 0: Scope type
// 1: Scope object
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeDetails) {
HandleScope scope(isolate);
- ASSERT(args.length() == 3);
+ ASSERT(args.length() == 4);
// Check arguments.
Object* check;
@@ -10688,7 +10820,8 @@
if (!maybe_check->ToObject(&check)) return maybe_check;
}
CONVERT_CHECKED(Smi, wrapped_id, args[1]);
- CONVERT_NUMBER_CHECKED(int, index, Int32, args[2]);
+ CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
+ CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
// Get the frame where the debugging is performed.
StackFrame::Id id = UnwrapFrameId(wrapped_id);
@@ -10697,7 +10830,7 @@
// Find the requested scope.
int n = 0;
- ScopeIterator it(isolate, frame);
+ ScopeIterator it(isolate, frame, inlined_frame_index);
for (; !it.Done() && n < index; it.Next()) {
n++;
}
@@ -10727,7 +10860,9 @@
// Print the scopes for the top frame.
StackFrameLocator locator;
JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
- for (ScopeIterator it(isolate, frame); !it.Done(); it.Next()) {
+ for (ScopeIterator it(isolate, frame, 0);
+ !it.Done();
+ it.Next()) {
it.DebugPrint();
}
#endif
@@ -11124,6 +11259,7 @@
// Runtime_DebugEvaluate.
static Handle<Object> GetArgumentsObject(Isolate* isolate,
JavaScriptFrame* frame,
+ int inlined_frame_index,
Handle<JSFunction> function,
Handle<SerializedScopeInfo> scope_info,
const ScopeInfo<>* sinfo,
@@ -11147,7 +11283,9 @@
}
}
- const int length = frame->ComputeParametersCount();
+ FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
+
+ int length = frame_inspector.GetParametersCount();
Handle<JSObject> arguments =
isolate->factory()->NewArgumentsObject(function, length);
Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
@@ -11155,7 +11293,7 @@
AssertNoAllocation no_gc;
WriteBarrierMode mode = array->GetWriteBarrierMode(no_gc);
for (int i = 0; i < length; i++) {
- array->set(i, frame->GetParameter(i), mode);
+ array->set(i, frame_inspector.GetParameter(i), mode);
}
arguments->set_elements(*array);
return arguments;
@@ -11182,7 +11320,7 @@
// Check the execution state and decode arguments frame and source to be
// evaluated.
- ASSERT(args.length() == 5);
+ ASSERT(args.length() == 6);
Object* check_result;
{ MaybeObject* maybe_check_result = Runtime_CheckExecutionState(
RUNTIME_ARGUMENTS(isolate, args));
@@ -11191,9 +11329,10 @@
}
}
CONVERT_CHECKED(Smi, wrapped_id, args[1]);
- CONVERT_ARG_CHECKED(String, source, 2);
- CONVERT_BOOLEAN_CHECKED(disable_break, args[3]);
- Handle<Object> additional_context(args[4]);
+ CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
+ CONVERT_ARG_CHECKED(String, source, 3);
+ CONVERT_BOOLEAN_CHECKED(disable_break, args[4]);
+ Handle<Object> additional_context(args[5]);
// Handle the processing of break.
DisableBreak disable_break_save(disable_break);
@@ -11233,7 +11372,8 @@
#endif
// Materialize the content of the local scope into a JSObject.
- Handle<JSObject> local_scope = MaterializeLocalScope(isolate, frame);
+ Handle<JSObject> local_scope = MaterializeLocalScope(
+ isolate, frame, inlined_frame_index);
RETURN_IF_EMPTY_HANDLE(isolate, local_scope);
// Allocate a new context for the debug evaluation and set the extension
@@ -11282,7 +11422,8 @@
&has_pending_exception);
if (has_pending_exception) return Failure::Exception();
- Handle<Object> arguments = GetArgumentsObject(isolate, frame,
+ Handle<Object> arguments = GetArgumentsObject(isolate,
+ frame, inlined_frame_index,
function, scope_info,
&sinfo, function_context);
@@ -12187,7 +12328,6 @@
#endif // ENABLE_DEBUGGER_SUPPORT
-#ifdef ENABLE_LOGGING_AND_PROFILING
RUNTIME_FUNCTION(MaybeObject*, Runtime_ProfilerResume) {
NoHandleAllocation ha;
v8::V8::ResumeProfiler();
@@ -12201,7 +12341,6 @@
return isolate->heap()->undefined_value();
}
-#endif // ENABLE_LOGGING_AND_PROFILING
// Finds the script object from the script data. NOTE: This operation uses
// heap traversal to find the function generated for the source position
@@ -12259,8 +12398,9 @@
// call to this function is encountered it is skipped. The seen_caller
// in/out parameter is used to remember if the caller has been seen
// yet.
-static bool ShowFrameInStackTrace(StackFrame* raw_frame, Object* caller,
- bool* seen_caller) {
+static bool ShowFrameInStackTrace(StackFrame* raw_frame,
+ Object* caller,
+ bool* seen_caller) {
// Only display JS frames.
if (!raw_frame->is_java_script())
return false;
@@ -12273,11 +12413,25 @@
*seen_caller = true;
return false;
}
- // Skip all frames until we've seen the caller. Also, skip the most
- // obvious builtin calls. Some builtin calls (such as Number.ADD
- // which is invoked using 'call') are very difficult to recognize
- // so we're leaving them in for now.
- return *seen_caller && !frame->receiver()->IsJSBuiltinsObject();
+ // Skip all frames until we've seen the caller.
+ if (!(*seen_caller)) return false;
+ // Also, skip the most obvious builtin calls. We recognize builtins
+ // as (1) functions called with the builtins object as the receiver and
+ // as (2) functions from native scripts called with undefined as the
+ // receiver (direct calls to helper functions in the builtins
+ // code). Some builtin calls (such as Number.ADD which is invoked
+ // using 'call') are very difficult to recognize so we're leaving
+ // them in for now.
+ if (frame->receiver()->IsJSBuiltinsObject()) {
+ return false;
+ }
+ JSFunction* fun = JSFunction::cast(raw_fun);
+ Object* raw_script = fun->shared()->script();
+ if (frame->receiver()->IsUndefined() && raw_script->IsScript()) {
+ int script_type = Script::cast(raw_script)->type()->value();
+ return script_type != Script::TYPE_NATIVE;
+ }
+ return true;
}
Property changes on: src/runtime.cc
___________________________________________________________________
Modified: svn:mergeinfo
Merged /branches/bleeding_edge/src/runtime.cc:r8598-8774
« no previous file with comments | « src/runtime.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698