| Index: src/runtime/runtime-debug.cc
|
| diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc
|
| index 9696b76264362664fcb10f98148684c082981aae..dd59c4fc5ee6b4f710b3a9149afaf358a4533523 100644
|
| --- a/src/runtime/runtime-debug.cc
|
| +++ b/src/runtime/runtime-debug.cc
|
| @@ -101,6 +101,183 @@ static Handle<Object> DebugGetProperty(LookupIterator* it,
|
| }
|
|
|
|
|
| +static Handle<Object> DebugGetProperty(Handle<Object> object,
|
| + Handle<Name> name) {
|
| + LookupIterator it(object, name);
|
| + return DebugGetProperty(&it);
|
| +}
|
| +
|
| +
|
| +template <class IteratorType>
|
| +static MaybeHandle<JSArray> GetIteratorInternalProperties(
|
| + Isolate* isolate, Handle<IteratorType> object) {
|
| + Factory* factory = isolate->factory();
|
| + Handle<IteratorType> iterator = Handle<IteratorType>::cast(object);
|
| + RUNTIME_ASSERT_HANDLIFIED(iterator->kind()->IsSmi(), JSArray);
|
| + const char* kind = NULL;
|
| + switch (Smi::cast(iterator->kind())->value()) {
|
| + case IteratorType::kKindKeys:
|
| + kind = "keys";
|
| + break;
|
| + case IteratorType::kKindValues:
|
| + kind = "values";
|
| + break;
|
| + case IteratorType::kKindEntries:
|
| + kind = "entries";
|
| + break;
|
| + default:
|
| + RUNTIME_ASSERT_HANDLIFIED(false, JSArray);
|
| + }
|
| +
|
| + Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
|
| + Handle<String> has_more =
|
| + factory->NewStringFromAsciiChecked("[[IteratorHasMore]]");
|
| + result->set(0, *has_more);
|
| + result->set(1, isolate->heap()->ToBoolean(iterator->HasMore()));
|
| +
|
| + Handle<String> index =
|
| + factory->NewStringFromAsciiChecked("[[IteratorIndex]]");
|
| + result->set(2, *index);
|
| + result->set(3, iterator->index());
|
| +
|
| + Handle<String> iterator_kind =
|
| + factory->NewStringFromAsciiChecked("[[IteratorKind]]");
|
| + result->set(4, *iterator_kind);
|
| + Handle<String> kind_str = factory->NewStringFromAsciiChecked(kind);
|
| + result->set(5, *kind_str);
|
| + return factory->NewJSArrayWithElements(result);
|
| +}
|
| +
|
| +
|
| +MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate,
|
| + Handle<Object> object) {
|
| + Factory* factory = isolate->factory();
|
| + if (object->IsJSFunction()) {
|
| + Handle<JSFunction> function = Handle<JSFunction>::cast(object);
|
| + if (function->shared()->bound()) {
|
| + RUNTIME_ASSERT_HANDLIFIED(function->function_bindings()->IsFixedArray(),
|
| + JSArray);
|
| +
|
| + Handle<FixedArray> bindings(function->function_bindings());
|
| +
|
| + Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
|
| + Handle<String> target =
|
| + factory->NewStringFromAsciiChecked("[[TargetFunction]]");
|
| + result->set(0, *target);
|
| + result->set(1, bindings->get(JSFunction::kBoundFunctionIndex));
|
| +
|
| + Handle<String> bound_this =
|
| + factory->NewStringFromAsciiChecked("[[BoundThis]]");
|
| + result->set(2, *bound_this);
|
| + result->set(3, bindings->get(JSFunction::kBoundThisIndex));
|
| +
|
| + Handle<FixedArray> arguments = factory->NewFixedArray(
|
| + bindings->length() - JSFunction::kBoundArgumentsStartIndex);
|
| + bindings->CopyTo(
|
| + JSFunction::kBoundArgumentsStartIndex, *arguments, 0,
|
| + bindings->length() - JSFunction::kBoundArgumentsStartIndex);
|
| + Handle<String> bound_args =
|
| + factory->NewStringFromAsciiChecked("[[BoundArgs]]");
|
| + result->set(4, *bound_args);
|
| + Handle<JSArray> arguments_array =
|
| + factory->NewJSArrayWithElements(arguments);
|
| + result->set(5, *arguments_array);
|
| + return factory->NewJSArrayWithElements(result);
|
| + }
|
| + } else if (object->IsJSMapIterator()) {
|
| + Handle<JSMapIterator> iterator = Handle<JSMapIterator>::cast(object);
|
| + return GetIteratorInternalProperties(isolate, iterator);
|
| + } else if (object->IsJSSetIterator()) {
|
| + Handle<JSSetIterator> iterator = Handle<JSSetIterator>::cast(object);
|
| + return GetIteratorInternalProperties(isolate, iterator);
|
| + } else if (object->IsJSGeneratorObject()) {
|
| + Handle<JSGeneratorObject> generator =
|
| + Handle<JSGeneratorObject>::cast(object);
|
| +
|
| + const char* status = "suspended";
|
| + if (generator->is_closed()) {
|
| + status = "closed";
|
| + } else if (generator->is_executing()) {
|
| + status = "running";
|
| + } else {
|
| + DCHECK(generator->is_suspended());
|
| + }
|
| +
|
| + Handle<FixedArray> result = factory->NewFixedArray(2 * 3);
|
| + Handle<String> generator_status =
|
| + factory->NewStringFromAsciiChecked("[[GeneratorStatus]]");
|
| + result->set(0, *generator_status);
|
| + Handle<String> status_str = factory->NewStringFromAsciiChecked(status);
|
| + result->set(1, *status_str);
|
| +
|
| + Handle<String> function =
|
| + factory->NewStringFromAsciiChecked("[[GeneratorFunction]]");
|
| + result->set(2, *function);
|
| + result->set(3, generator->function());
|
| +
|
| + Handle<String> receiver =
|
| + factory->NewStringFromAsciiChecked("[[GeneratorReceiver]]");
|
| + result->set(4, *receiver);
|
| + result->set(5, generator->receiver());
|
| + return factory->NewJSArrayWithElements(result);
|
| + } else if (Object::IsPromise(object)) {
|
| + Handle<JSObject> promise = Handle<JSObject>::cast(object);
|
| +
|
| + Handle<Object> status_obj =
|
| + DebugGetProperty(promise, isolate->promise_status());
|
| + RUNTIME_ASSERT_HANDLIFIED(status_obj->IsSmi(), JSArray);
|
| + const char* status = "rejected";
|
| + int status_val = Handle<Smi>::cast(status_obj)->value();
|
| + switch (status_val) {
|
| + case +1:
|
| + status = "resolved";
|
| + break;
|
| + case 0:
|
| + status = "pending";
|
| + break;
|
| + default:
|
| + DCHECK_EQ(-1, status_val);
|
| + }
|
| +
|
| + Handle<FixedArray> result = factory->NewFixedArray(2 * 2);
|
| + Handle<String> promise_status =
|
| + factory->NewStringFromAsciiChecked("[[PromiseStatus]]");
|
| + result->set(0, *promise_status);
|
| + Handle<String> status_str = factory->NewStringFromAsciiChecked(status);
|
| + result->set(1, *status_str);
|
| +
|
| + Handle<Object> value_obj =
|
| + DebugGetProperty(promise, isolate->promise_value());
|
| + Handle<String> promise_value =
|
| + factory->NewStringFromAsciiChecked("[[PromiseValue]]");
|
| + result->set(2, *promise_value);
|
| + result->set(3, *value_obj);
|
| + return factory->NewJSArrayWithElements(result);
|
| + } else if (object->IsJSValue()) {
|
| + Handle<JSValue> js_value = Handle<JSValue>::cast(object);
|
| +
|
| + Handle<FixedArray> result = factory->NewFixedArray(2);
|
| + Handle<String> primitive_value =
|
| + factory->NewStringFromAsciiChecked("[[PrimitiveValue]]");
|
| + result->set(0, *primitive_value);
|
| + result->set(1, js_value->value());
|
| + return factory->NewJSArrayWithElements(result);
|
| + }
|
| + return factory->NewJSArray(0);
|
| +}
|
| +
|
| +
|
| +RUNTIME_FUNCTION(Runtime_DebugGetInternalProperties) {
|
| + HandleScope scope(isolate);
|
| + DCHECK(args.length() == 1);
|
| + CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
|
| + Handle<JSArray> result;
|
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
| + isolate, result, Runtime::GetInternalProperties(isolate, obj));
|
| + return *result;
|
| +}
|
| +
|
| +
|
| // Get debugger related details for an object property, in the following format:
|
| // 0: Property value
|
| // 1: Property details
|
|
|