summaryrefslogtreecommitdiff
path: root/deps/v8/src/runtime/runtime-debug.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2018-09-07 17:07:13 +0200
committerMichaël Zasso <targos@protonmail.com>2018-09-07 20:59:13 +0200
commit586db2414a338e1bf6eaf6e672a3adc7ce309f6a (patch)
tree139fa972aef648481ddee22a3a85b99707d28df5 /deps/v8/src/runtime/runtime-debug.cc
parent12ed7c94e5160aa6d38e3d2cb2a73dae0a6f9342 (diff)
downloadandroid-node-v8-586db2414a338e1bf6eaf6e672a3adc7ce309f6a.tar.gz
android-node-v8-586db2414a338e1bf6eaf6e672a3adc7ce309f6a.tar.bz2
android-node-v8-586db2414a338e1bf6eaf6e672a3adc7ce309f6a.zip
deps: update V8 to 6.9.427.22
PR-URL: https://github.com/nodejs/node/pull/21983 Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Ujjwal Sharma <usharma1998@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Diffstat (limited to 'deps/v8/src/runtime/runtime-debug.cc')
-rw-r--r--deps/v8/src/runtime/runtime-debug.cc1301
1 files changed, 136 insertions, 1165 deletions
diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc
index fabb1a80da..9711ffad54 100644
--- a/deps/v8/src/runtime/runtime-debug.cc
+++ b/deps/v8/src/runtime/runtime-debug.cc
@@ -21,6 +21,8 @@
#include "src/interpreter/interpreter.h"
#include "src/isolate-inl.h"
#include "src/objects/debug-objects-inl.h"
+#include "src/objects/js-collection-inl.h"
+#include "src/objects/js-promise-inl.h"
#include "src/runtime/runtime.h"
#include "src/snapshot/snapshot.h"
#include "src/wasm/wasm-objects-inl.h"
@@ -45,7 +47,8 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_DebugBreakOnBytecode) {
// Get the top-most JavaScript frame.
JavaScriptFrameIterator it(isolate);
if (isolate->debug_execution_mode() == DebugInfo::kBreakpoints) {
- isolate->debug()->Break(it.frame(), handle(it.frame()->function()));
+ isolate->debug()->Break(it.frame(),
+ handle(it.frame()->function(), isolate));
}
// Return the handler from the original bytecode array.
@@ -81,7 +84,7 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_DebugBreakOnBytecode) {
operand_scale);
if (side_effect_check_failed) {
- return MakePair(isolate->heap()->exception(),
+ return MakePair(ReadOnlyRoots(isolate).exception(),
Smi::FromInt(static_cast<uint8_t>(bytecode)));
}
Object* interrupt_object = isolate->stack_guard()->HandleInterrupts();
@@ -107,15 +110,7 @@ RUNTIME_FUNCTION(Runtime_DebugBreakAtEntry) {
DCHECK_EQ(*function, it.frame()->function());
isolate->debug()->Break(it.frame(), function);
- return isolate->heap()->undefined_value();
-}
-
-RUNTIME_FUNCTION(Runtime_DebugApplyInstrumentation) {
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- isolate->debug()->ApplyInstrumentation(handle(function->shared()));
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
@@ -127,50 +122,13 @@ RUNTIME_FUNCTION(Runtime_HandleDebuggerStatement) {
return isolate->stack_guard()->HandleInterrupts();
}
-
RUNTIME_FUNCTION(Runtime_ScheduleBreak) {
SealHandleScope shs(isolate);
DCHECK_EQ(0, args.length());
- isolate->stack_guard()->RequestDebugBreak();
- return isolate->heap()->undefined_value();
-}
-
-static Handle<Object> DebugGetProperty(LookupIterator* it,
- bool* has_caught = nullptr) {
- for (; it->IsFound(); it->Next()) {
- switch (it->state()) {
- case LookupIterator::NOT_FOUND:
- case LookupIterator::TRANSITION:
- UNREACHABLE();
- case LookupIterator::ACCESS_CHECK:
- // Ignore access checks.
- break;
- case LookupIterator::INTEGER_INDEXED_EXOTIC:
- case LookupIterator::INTERCEPTOR:
- case LookupIterator::JSPROXY:
- return it->isolate()->factory()->undefined_value();
- case LookupIterator::ACCESSOR: {
- Handle<Object> accessors = it->GetAccessors();
- if (!accessors->IsAccessorInfo()) {
- return it->isolate()->factory()->undefined_value();
- }
- MaybeHandle<Object> maybe_result =
- JSObject::GetPropertyWithAccessor(it);
- Handle<Object> result;
- if (!maybe_result.ToHandle(&result)) {
- result = handle(it->isolate()->pending_exception(), it->isolate());
- it->isolate()->clear_pending_exception();
- if (has_caught != nullptr) *has_caught = true;
- }
- return result;
- }
-
- case LookupIterator::DATA:
- return it->GetDataValue();
- }
- }
-
- return it->isolate()->factory()->undefined_value();
+ isolate->RequestInterrupt(
+ [](v8::Isolate* isolate, void*) { v8::debug::BreakRightNow(isolate); },
+ nullptr);
+ return ReadOnlyRoots(isolate).undefined_value();
}
template <class IteratorType>
@@ -288,7 +246,7 @@ MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate,
result->set(1, *status_str);
Handle<Object> value_obj(promise->status() == Promise::kPending
- ? isolate->heap()->undefined_value()
+ ? ReadOnlyRoots(isolate).undefined_value()
: promise->result(),
isolate);
Handle<String> promise_value =
@@ -328,627 +286,6 @@ MaybeHandle<JSArray> Runtime::GetInternalProperties(Isolate* isolate,
return factory->NewJSArray(0);
}
-
-RUNTIME_FUNCTION(Runtime_DebugGetInternalProperties) {
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
- RETURN_RESULT_OR_FAILURE(isolate,
- Runtime::GetInternalProperties(isolate, obj));
-}
-
-
-// Get debugger related details for an object property, in the following format:
-// 0: Property value
-// 1: Property details
-// 2: Property value is exception
-// 3: Getter function if defined
-// 4: Setter function if defined
-// Items 2-4 are only filled if the property has either a getter or a setter.
-RUNTIME_FUNCTION(Runtime_DebugGetPropertyDetails) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, name_obj, 1);
-
- // Convert the {name_obj} to a Name.
- Handle<Name> name;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name,
- Object::ToName(isolate, name_obj));
-
- // Make sure to set the current context to the context before the debugger was
- // entered (if the debugger is entered). The reason for switching context here
- // is that for some property lookups (accessors and interceptors) callbacks
- // into the embedding application can occur, and the embedding application
- // could have the assumption that its own native context is the current
- // context and not some internal debugger context.
- SaveContext save(isolate);
- if (isolate->debug()->in_debug_scope()) {
- isolate->set_context(*isolate->debug()->debugger_entry()->GetContext());
- }
-
- // Check if the name is trivially convertible to an index and get the element
- // if so.
- uint32_t index;
- // TODO(verwaest): Make sure DebugGetProperty can handle arrays, and remove
- // this special case.
- if (name->AsArrayIndex(&index)) {
- Handle<FixedArray> details = isolate->factory()->NewFixedArray(2);
- Handle<Object> element_or_char;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, element_or_char, JSReceiver::GetElement(isolate, obj, index));
- details->set(0, *element_or_char);
- details->set(1, PropertyDetails::Empty().AsSmi());
- return *isolate->factory()->NewJSArrayWithElements(details);
- }
-
- LookupIterator it(obj, name, LookupIterator::OWN);
- bool has_caught = false;
- Handle<Object> value = DebugGetProperty(&it, &has_caught);
- if (!it.IsFound()) return isolate->heap()->undefined_value();
-
- Handle<Object> maybe_pair;
- if (it.state() == LookupIterator::ACCESSOR) {
- maybe_pair = it.GetAccessors();
- }
-
- // If the callback object is a fixed array then it contains JavaScript
- // getter and/or setter.
- bool has_js_accessors = !maybe_pair.is_null() && maybe_pair->IsAccessorPair();
- Handle<FixedArray> details =
- isolate->factory()->NewFixedArray(has_js_accessors ? 6 : 3);
- details->set(0, *value);
- // TODO(verwaest): Get rid of this random way of handling interceptors.
- PropertyDetails d = it.state() == LookupIterator::INTERCEPTOR
- ? PropertyDetails::Empty()
- : it.property_details();
- details->set(1, d.AsSmi());
- details->set(
- 2, isolate->heap()->ToBoolean(it.state() == LookupIterator::INTERCEPTOR));
- if (has_js_accessors) {
- Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(maybe_pair);
- details->set(3, isolate->heap()->ToBoolean(has_caught));
- Handle<Object> getter =
- AccessorPair::GetComponent(accessors, ACCESSOR_GETTER);
- Handle<Object> setter =
- AccessorPair::GetComponent(accessors, ACCESSOR_SETTER);
- details->set(4, *getter);
- details->set(5, *setter);
- }
-
- return *isolate->factory()->NewJSArrayWithElements(details);
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugGetProperty) {
- HandleScope scope(isolate);
-
- DCHECK_EQ(2, args.length());
-
- CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
-
- LookupIterator it(obj, name);
- return *DebugGetProperty(&it);
-}
-
-// Return the property kind calculated from the property details.
-// args[0]: smi with property details.
-RUNTIME_FUNCTION(Runtime_DebugPropertyKindFromDetails) {
- SealHandleScope shs(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
- return Smi::FromInt(static_cast<int>(details.kind()));
-}
-
-
-// Return the property attribute calculated from the property details.
-// args[0]: smi with property details.
-RUNTIME_FUNCTION(Runtime_DebugPropertyAttributesFromDetails) {
- SealHandleScope shs(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_PROPERTY_DETAILS_CHECKED(details, 0);
- return Smi::FromInt(static_cast<int>(details.attributes()));
-}
-
-
-RUNTIME_FUNCTION(Runtime_CheckExecutionState) {
- SealHandleScope shs(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
- return isolate->heap()->true_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetFrameCount) {
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- // Count all frames which are relevant to debugging stack trace.
- int n = 0;
- StackFrame::Id id = isolate->debug()->break_frame_id();
- if (id == StackFrame::NO_ID) {
- // If there is no JavaScript stack frame count is 0.
- return Smi::kZero;
- }
-
- std::vector<FrameSummary> frames;
- for (StackTraceFrameIterator it(isolate, id); !it.done(); it.Advance()) {
- frames.clear();
- it.frame()->Summarize(&frames);
- for (size_t i = frames.size(); i != 0; i--) {
- // Omit functions from native and extension scripts.
- if (frames[i - 1].is_subject_to_debugging()) n++;
- }
- }
- return Smi::FromInt(n);
-}
-
-static const int kFrameDetailsFrameIdIndex = 0;
-static const int kFrameDetailsReceiverIndex = 1;
-static const int kFrameDetailsFunctionIndex = 2;
-static const int kFrameDetailsScriptIndex = 3;
-static const int kFrameDetailsArgumentCountIndex = 4;
-static const int kFrameDetailsLocalCountIndex = 5;
-static const int kFrameDetailsSourcePositionIndex = 6;
-static const int kFrameDetailsConstructCallIndex = 7;
-static const int kFrameDetailsAtReturnIndex = 8;
-static const int kFrameDetailsFlagsIndex = 9;
-static const int kFrameDetailsFirstDynamicIndex = 10;
-
-// Return an array with frame details
-// args[0]: number: break id
-// args[1]: number: frame index
-//
-// The array returned contains the following information:
-// 0: Frame id
-// 1: Receiver
-// 2: Function
-// 3: Script
-// 4: Argument count
-// 5: Local count
-// 6: Source position
-// 7: Constructor call
-// 8: Is at return
-// 9: Flags
-// Arguments name, value
-// Locals name, value
-// Return value if any
-RUNTIME_FUNCTION(Runtime_GetFrameDetails) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
- Heap* heap = isolate->heap();
-
- // Find the relevant frame with the requested index.
- StackFrame::Id id = isolate->debug()->break_frame_id();
- if (id == StackFrame::NO_ID) {
- // If there are no JavaScript stack frames return undefined.
- return heap->undefined_value();
- }
-
- StackTraceFrameIterator it(isolate, id);
- // Inlined frame index in optimized frame, starting from outer function.
- int inlined_frame_index =
- DebugFrameHelper::FindIndexedNonNativeFrame(&it, index);
- if (inlined_frame_index == -1) return heap->undefined_value();
-
- FrameInspector frame_inspector(it.frame(), inlined_frame_index, isolate);
-
- // Traverse the saved contexts chain to find the active context for the
- // selected frame.
- SaveContext* save =
- DebugFrameHelper::FindSavedContextForFrame(isolate, it.frame());
-
- // Get the frame id.
- Handle<Object> frame_id(DebugFrameHelper::WrapFrameId(it.frame()->id()),
- isolate);
-
- if (frame_inspector.IsWasm()) {
- // Create the details array (no dynamic information for wasm).
- Handle<FixedArray> details =
- isolate->factory()->NewFixedArray(kFrameDetailsFirstDynamicIndex);
-
- // Add the frame id.
- details->set(kFrameDetailsFrameIdIndex, *frame_id);
-
- // Add the function name.
- Handle<String> func_name = frame_inspector.GetFunctionName();
- details->set(kFrameDetailsFunctionIndex, *func_name);
-
- // Add the script wrapper
- Handle<Object> script_wrapper =
- Script::GetWrapper(frame_inspector.GetScript());
- details->set(kFrameDetailsScriptIndex, *script_wrapper);
-
- // Add the arguments count.
- details->set(kFrameDetailsArgumentCountIndex, Smi::kZero);
-
- // Add the locals count
- details->set(kFrameDetailsLocalCountIndex, Smi::kZero);
-
- // Add the source position.
- int position = frame_inspector.GetSourcePosition();
- details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
-
- // Add the constructor information.
- details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(false));
-
- // Add the at return information.
- details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(false));
-
- // Add flags to indicate information on whether this frame is
- // bit 0: invoked in the debugger context.
- // bit 1: optimized frame.
- // bit 2: inlined in optimized frame
- int flags = inlined_frame_index << 2;
- if (*save->context() == *isolate->debug()->debug_context()) {
- flags |= 1 << 0;
- }
- details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
-
- return *isolate->factory()->NewJSArrayWithElements(details);
- }
-
- // Find source position in unoptimized code.
- int position = frame_inspector.GetSourcePosition();
-
- // Handle JavaScript frames.
- bool is_optimized = it.frame()->is_optimized();
-
- // Check for constructor frame.
- bool constructor = frame_inspector.IsConstructor();
-
- // Get scope info and read from it for local variable information.
- Handle<JSFunction> function =
- Handle<JSFunction>::cast(frame_inspector.GetFunction());
- CHECK(function->shared()->IsSubjectToDebugging());
- Handle<SharedFunctionInfo> shared(function->shared());
- Handle<ScopeInfo> scope_info(shared->scope_info());
- DCHECK(*scope_info != ScopeInfo::Empty(isolate));
-
- // Get the locals names and values into a temporary array.
- Handle<Object> maybe_context = frame_inspector.GetContext();
- const int local_count_with_synthetic = maybe_context->IsContext()
- ? scope_info->LocalCount()
- : scope_info->StackLocalCount();
- int local_count = local_count_with_synthetic;
- for (int slot = 0; slot < local_count_with_synthetic; ++slot) {
- // Hide compiler-introduced temporary variables, whether on the stack or on
- // the context.
- if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(slot))) {
- local_count--;
- }
- }
-
- std::vector<Handle<Object>> locals;
- // Fill in the values of the locals.
- int i = 0;
- for (; i < scope_info->StackLocalCount(); ++i) {
- // Use the value from the stack.
- if (ScopeInfo::VariableIsSynthetic(scope_info->LocalName(i))) continue;
- locals.emplace_back(scope_info->LocalName(i), isolate);
- Handle<Object> value =
- frame_inspector.GetExpression(scope_info->StackLocalIndex(i));
- // TODO(yangguo): We convert optimized out values to {undefined} when they
- // are passed to the debugger. Eventually we should handle them somehow.
- if (value->IsOptimizedOut(isolate)) {
- value = isolate->factory()->undefined_value();
- }
- locals.push_back(value);
- }
- if (static_cast<int>(locals.size()) < local_count * 2) {
- // Get the context containing declarations.
- DCHECK(maybe_context->IsContext());
- Handle<Context> context(Context::cast(*maybe_context)->closure_context());
-
- for (; i < scope_info->LocalCount(); ++i) {
- Handle<String> name(scope_info->LocalName(i));
- if (ScopeInfo::VariableIsSynthetic(*name)) continue;
- VariableMode mode;
- InitializationFlag init_flag;
- MaybeAssignedFlag maybe_assigned_flag;
- locals.push_back(name);
- int context_slot_index = ScopeInfo::ContextSlotIndex(
- scope_info, name, &mode, &init_flag, &maybe_assigned_flag);
- Object* value = context->get(context_slot_index);
- locals.emplace_back(value, isolate);
- }
- }
-
- // Check whether this frame is positioned at return. If not top
- // frame or if the frame is optimized it cannot be at a return.
- bool at_return = false;
- if (!is_optimized && index == 0) {
- at_return = isolate->debug()->IsBreakAtReturn(it.javascript_frame());
- }
-
- // If positioned just before return find the value to be returned and add it
- // to the frame information.
- Handle<Object> return_value = isolate->factory()->undefined_value();
- if (at_return) {
- return_value = handle(isolate->debug()->return_value(), isolate);
- }
-
- // Now advance to the arguments adapter frame (if any). It contains all
- // 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.
- if ((inlined_frame_index == 0) &&
- it.javascript_frame()->has_adapted_arguments()) {
- it.AdvanceOneFrame();
- DCHECK(it.frame()->is_arguments_adaptor());
- 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 = scope_info->ParameterCount();
- if (argument_count < frame_inspector.GetParametersCount()) {
- argument_count = frame_inspector.GetParametersCount();
- }
-
- // Calculate the size of the result.
- int details_size = kFrameDetailsFirstDynamicIndex +
- 2 * (argument_count + local_count) + (at_return ? 1 : 0);
- Handle<FixedArray> details = isolate->factory()->NewFixedArray(details_size);
-
- // Add the frame id.
- details->set(kFrameDetailsFrameIdIndex, *frame_id);
-
- // Add the function (same as in function frame).
- details->set(kFrameDetailsFunctionIndex, *(frame_inspector.GetFunction()));
-
- // Add the script wrapper
- Handle<Object> script_wrapper =
- Script::GetWrapper(frame_inspector.GetScript());
- details->set(kFrameDetailsScriptIndex, *script_wrapper);
-
- // Add the arguments count.
- details->set(kFrameDetailsArgumentCountIndex, Smi::FromInt(argument_count));
-
- // Add the locals count
- details->set(kFrameDetailsLocalCountIndex, Smi::FromInt(local_count));
-
- // Add the source position.
- if (position != kNoSourcePosition) {
- details->set(kFrameDetailsSourcePositionIndex, Smi::FromInt(position));
- } else {
- details->set(kFrameDetailsSourcePositionIndex, heap->undefined_value());
- }
-
- // Add the constructor information.
- details->set(kFrameDetailsConstructCallIndex, heap->ToBoolean(constructor));
-
- // Add the at return information.
- details->set(kFrameDetailsAtReturnIndex, heap->ToBoolean(at_return));
-
- // Add flags to indicate information on whether this frame is
- // bit 0: invoked in the debugger context.
- // bit 1: optimized frame.
- // bit 2: inlined in optimized frame
- int flags = 0;
- if (*save->context() == *isolate->debug()->debug_context()) {
- flags |= 1 << 0;
- }
- if (is_optimized) {
- flags |= 1 << 1;
- flags |= inlined_frame_index << 2;
- }
- details->set(kFrameDetailsFlagsIndex, Smi::FromInt(flags));
-
- // Fill the dynamic part.
- int details_index = kFrameDetailsFirstDynamicIndex;
-
- // Add arguments name and value.
- for (int i = 0; i < argument_count; i++) {
- // Name of the argument.
- if (i < scope_info->ParameterCount()) {
- details->set(details_index++, scope_info->ParameterName(i));
- } else {
- details->set(details_index++, heap->undefined_value());
- }
-
- // Parameter value.
- if (i < frame_inspector.GetParametersCount()) {
- // Get the value from the stack.
- details->set(details_index++, *(frame_inspector.GetParameter(i)));
- } else {
- details->set(details_index++, heap->undefined_value());
- }
- }
-
- // Add locals name and value from the temporary copy from the function frame.
- for (const auto& local : locals) details->set(details_index++, *local);
-
- // Add the value being returned.
- if (at_return) {
- details->set(details_index++, *return_value);
- }
-
- // Add the receiver (same as in function frame).
- Handle<Object> receiver = frame_inspector.GetReceiver();
- DCHECK(function->shared()->IsUserJavaScript());
- // Optimized frames only restore the receiver as best-effort (see
- // OptimizedFrame::Summarize).
- DCHECK_IMPLIES(!is_optimized && is_sloppy(shared->language_mode()),
- receiver->IsJSReceiver());
- details->set(kFrameDetailsReceiverIndex, *receiver);
-
- DCHECK_EQ(details_size, details_index);
- return *isolate->factory()->NewJSArrayWithElements(details);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetScopeCount) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
-
- // Get the frame where the debugging is performed.
- StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
- StackTraceFrameIterator it(isolate, id);
- StandardFrame* frame = it.frame();
- if (it.frame()->is_wasm()) return 0;
-
- FrameInspector frame_inspector(frame, 0, isolate);
-
- // Count the visible scopes.
- int n = 0;
- for (ScopeIterator it(isolate, &frame_inspector); !it.Done(); it.Next()) {
- n++;
- }
-
- return Smi::FromInt(n);
-}
-
-
-// Return an array with scope details
-// args[0]: number: break id
-// args[1]: number: frame 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(Runtime_GetScopeDetails) {
- HandleScope scope(isolate);
- DCHECK_EQ(4, args.length());
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
- CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
- CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
-
- // Get the frame where the debugging is performed.
- StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
- StackTraceFrameIterator frame_it(isolate, id);
- // Wasm has no scopes, this must be javascript.
- JavaScriptFrame* frame = JavaScriptFrame::cast(frame_it.frame());
- FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
-
- // Find the requested scope.
- int n = 0;
- ScopeIterator it(isolate, &frame_inspector);
- for (; !it.Done() && n < index; it.Next()) {
- n++;
- }
- if (it.Done()) {
- return isolate->heap()->undefined_value();
- }
- RETURN_RESULT_OR_FAILURE(isolate, it.MaterializeScopeDetails());
-}
-
-
-// Return an array of scope details
-// args[0]: number: break id
-// args[1]: number: frame index
-// args[2]: number: inlined frame index
-// args[3]: boolean: ignore nested scopes
-//
-// The array returned contains arrays with the following information:
-// 0: Scope type
-// 1: Scope object
-RUNTIME_FUNCTION(Runtime_GetAllScopesDetails) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 3 || args.length() == 4);
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
- CONVERT_NUMBER_CHECKED(int, inlined_frame_index, Int32, args[2]);
-
- ScopeIterator::Option option = ScopeIterator::DEFAULT;
- if (args.length() == 4) {
- CONVERT_BOOLEAN_ARG_CHECKED(flag, 3);
- if (flag) option = ScopeIterator::IGNORE_NESTED_SCOPES;
- }
-
- // Get the frame where the debugging is performed.
- StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
- StackTraceFrameIterator frame_it(isolate, id);
- StandardFrame* frame = frame_it.frame();
-
- // Handle wasm frames specially. They provide exactly two scopes (global /
- // local).
- if (frame->is_wasm_interpreter_entry()) {
- Handle<WasmDebugInfo> debug_info(
- WasmInterpreterEntryFrame::cast(frame)->debug_info(), isolate);
- return *WasmDebugInfo::GetScopeDetails(debug_info, frame->fp(),
- inlined_frame_index);
- }
-
- FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
- std::vector<Handle<JSObject>> result;
- ScopeIterator it(isolate, &frame_inspector, option);
- for (; !it.Done(); it.Next()) {
- Handle<JSObject> details;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, details,
- it.MaterializeScopeDetails());
- result.push_back(details);
- }
-
- int result_size = static_cast<int>(result.size());
- Handle<FixedArray> array = isolate->factory()->NewFixedArray(result_size);
- for (int i = 0; i < result_size; ++i) {
- array->set(i, *result[i]);
- }
- return *isolate->factory()->NewJSArrayWithElements(array);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetFunctionScopeCount) {
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
-
- // Check arguments.
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
-
- // Count the visible scopes.
- int n = 0;
- if (function->IsJSFunction()) {
- for (ScopeIterator it(isolate, Handle<JSFunction>::cast(function));
- !it.Done(); it.Next()) {
- n++;
- }
- }
-
- return Smi::FromInt(n);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetFunctionScopeDetails) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
-
- // Check arguments.
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
- CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
-
- // Find the requested scope.
- int n = 0;
- ScopeIterator it(isolate, fun);
- for (; !it.Done() && n < index; it.Next()) {
- n++;
- }
- if (it.Done()) {
- return isolate->heap()->undefined_value();
- }
-
- RETURN_RESULT_OR_FAILURE(isolate, it.MaterializeScopeDetails());
-}
-
RUNTIME_FUNCTION(Runtime_GetGeneratorScopeCount) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
@@ -977,7 +314,7 @@ RUNTIME_FUNCTION(Runtime_GetGeneratorScopeDetails) {
DCHECK_EQ(2, args.length());
if (!args[0]->IsJSGeneratorObject()) {
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
// Check arguments.
@@ -986,7 +323,7 @@ RUNTIME_FUNCTION(Runtime_GetGeneratorScopeDetails) {
// Only inspect suspended generator scopes.
if (!gen->is_suspended()) {
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
// Find the requested scope.
@@ -996,10 +333,10 @@ RUNTIME_FUNCTION(Runtime_GetGeneratorScopeDetails) {
n++;
}
if (it.Done()) {
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
- RETURN_RESULT_OR_FAILURE(isolate, it.MaterializeScopeDetails());
+ return *it.MaterializeScopeDetails();
}
static bool SetScopeVariableValue(ScopeIterator* it, int index,
@@ -1014,52 +351,22 @@ static bool SetScopeVariableValue(ScopeIterator* it, int index,
return it->SetVariableValue(variable_name, new_value);
}
-
// Change variable value in closure or local scope
// args[0]: number or JsFunction: break id or function
-// args[1]: number: frame index (when arg[0] is break id)
-// args[2]: number: inlined frame index (when arg[0] is break id)
-// args[3]: number: scope index
-// args[4]: string: variable name
-// args[5]: object: new value
+// args[1]: number: scope index
+// args[2]: string: variable name
+// args[3]: object: new value
//
// Return true if success and false otherwise
-RUNTIME_FUNCTION(Runtime_SetScopeVariableValue) {
+RUNTIME_FUNCTION(Runtime_SetGeneratorScopeVariableValue) {
HandleScope scope(isolate);
- DCHECK_EQ(6, args.length());
-
- // Check arguments.
- CONVERT_NUMBER_CHECKED(int, index, Int32, args[3]);
- CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 4);
- CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 5);
-
- bool res;
- if (args[0]->IsNumber()) {
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
- CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
-
- // Get the frame where the debugging is performed.
- StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
- StackTraceFrameIterator frame_it(isolate, id);
- // Wasm has no scopes, this must be javascript.
- JavaScriptFrame* frame = JavaScriptFrame::cast(frame_it.frame());
- FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
-
- ScopeIterator it(isolate, &frame_inspector);
- res = SetScopeVariableValue(&it, index, variable_name, new_value);
- } else if (args[0]->IsJSFunction()) {
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
- ScopeIterator it(isolate, fun);
- res = SetScopeVariableValue(&it, index, variable_name, new_value);
- } else {
- CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
- ScopeIterator it(isolate, gen);
- res = SetScopeVariableValue(&it, index, variable_name, new_value);
- }
-
+ DCHECK_EQ(4, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSGeneratorObject, gen, 0);
+ CONVERT_NUMBER_CHECKED(int, index, Int32, args[1]);
+ CONVERT_ARG_HANDLE_CHECKED(String, variable_name, 2);
+ CONVERT_ARG_HANDLE_CHECKED(Object, new_value, 3);
+ ScopeIterator it(isolate, gen);
+ bool res = SetScopeVariableValue(&it, index, variable_name, new_value);
return isolate->heap()->ToBoolean(res);
}
@@ -1070,11 +377,12 @@ RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
CHECK(isolate->debug()->is_active());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, fun, 0);
- Handle<SharedFunctionInfo> shared(fun->shared());
+ Handle<SharedFunctionInfo> shared(fun->shared(), isolate);
// Find the number of break points
- Handle<Object> break_locations = Debug::GetSourceBreakLocations(shared);
+ Handle<Object> break_locations =
+ Debug::GetSourceBreakLocations(isolate, shared);
if (break_locations->IsUndefined(isolate)) {
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
// Return array as JS array
return *isolate->factory()->NewJSArrayWithElements(
@@ -1082,24 +390,6 @@ RUNTIME_FUNCTION(Runtime_GetBreakLocations) {
}
-// Change the state of break on exceptions.
-// args[0]: Enum value indicating whether to affect caught/uncaught exceptions.
-// args[1]: Boolean indicating on/off.
-RUNTIME_FUNCTION(Runtime_ChangeBreakOnException) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_NUMBER_CHECKED(uint32_t, type_arg, Uint32, args[0]);
- CONVERT_BOOLEAN_ARG_CHECKED(enable, 1);
-
- // If the number doesn't match an enum value, the ChangeBreakOnException
- // function will default to affecting caught exceptions.
- ExceptionBreakType type = static_cast<ExceptionBreakType>(type_arg);
- // Update break point state.
- isolate->debug()->ChangeBreakOnException(type, enable);
- return isolate->heap()->undefined_value();
-}
-
-
// Returns the state of break on exceptions
// args[0]: boolean indicating uncaught exceptions
RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
@@ -1112,256 +402,36 @@ RUNTIME_FUNCTION(Runtime_IsBreakOnException) {
return Smi::FromInt(result);
}
-
-// Prepare for stepping
-// args[0]: break id for checking execution state
-// args[1]: step action from the enumeration StepAction
-// args[2]: number of times to perform the step, for step out it is the number
-// of frames to step down.
-RUNTIME_FUNCTION(Runtime_PrepareStep) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- if (!args[1]->IsNumber()) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
-
- // Get the step action and check validity.
- StepAction step_action = static_cast<StepAction>(NumberToInt32(args[1]));
- if (step_action != StepIn && step_action != StepNext &&
- step_action != StepOut) {
- return isolate->Throw(isolate->heap()->illegal_argument_string());
- }
-
- // Clear all current stepping setup.
- isolate->debug()->ClearStepping();
-
- // Prepare step.
- isolate->debug()->PrepareStep(static_cast<StepAction>(step_action));
- return isolate->heap()->undefined_value();
-}
-
// Clear all stepping set by PrepareStep.
RUNTIME_FUNCTION(Runtime_ClearStepping) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
CHECK(isolate->debug()->is_active());
isolate->debug()->ClearStepping();
- return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
- HandleScope scope(isolate);
-
- // Check the execution state and decode arguments frame and source to be
- // evaluated.
- DCHECK_EQ(5, args.length());
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- CONVERT_SMI_ARG_CHECKED(wrapped_id, 1);
- CONVERT_NUMBER_CHECKED(int, inlined_jsframe_index, Int32, args[2]);
- CONVERT_ARG_HANDLE_CHECKED(String, source, 3);
- CONVERT_BOOLEAN_ARG_CHECKED(throw_on_side_effect, 4);
-
- StackFrame::Id id = DebugFrameHelper::UnwrapFrameId(wrapped_id);
-
- RETURN_RESULT_OR_FAILURE(
- isolate, DebugEvaluate::Local(isolate, id, inlined_jsframe_index, source,
- throw_on_side_effect));
+ return ReadOnlyRoots(isolate).undefined_value();
}
-
-RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
- HandleScope scope(isolate);
-
- // Check the execution state and decode arguments frame and source to be
- // evaluated.
- DCHECK_EQ(2, args.length());
- CONVERT_NUMBER_CHECKED(int, break_id, Int32, args[0]);
- CHECK(isolate->debug()->CheckExecutionState(break_id));
-
- CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
-
- RETURN_RESULT_OR_FAILURE(isolate,
- DebugEvaluate::Global(isolate, source, false));
-}
-
-
-RUNTIME_FUNCTION(Runtime_DebugGetLoadedScripts) {
+RUNTIME_FUNCTION(Runtime_DebugGetLoadedScriptIds) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
Handle<FixedArray> instances;
{
DebugScope debug_scope(isolate->debug());
- if (debug_scope.failed()) {
- DCHECK(isolate->has_pending_exception());
- return isolate->heap()->exception();
- }
// Fill the script objects.
instances = isolate->debug()->GetLoadedScripts();
}
// Convert the script objects to proper JS objects.
for (int i = 0; i < instances->length(); i++) {
- Handle<Script> script = Handle<Script>(Script::cast(instances->get(i)));
- // Get the script wrapper in a local handle before calling GetScriptWrapper,
- // because using
- // instances->set(i, *GetScriptWrapper(script))
- // is unsafe as GetScriptWrapper might call GC and the C++ compiler might
- // already have dereferenced the instances handle.
- Handle<JSObject> wrapper = Script::GetWrapper(script);
- instances->set(i, *wrapper);
+ Handle<Script> script(Script::cast(instances->get(i)), isolate);
+ instances->set(i, Smi::FromInt(script->id()));
}
// Return result as a JS array.
return *isolate->factory()->NewJSArrayWithElements(instances);
}
-static bool HasInPrototypeChainIgnoringProxies(Isolate* isolate,
- JSObject* object,
- Object* proto) {
- PrototypeIterator iter(isolate, object, kStartAtReceiver);
- while (true) {
- iter.AdvanceIgnoringProxies();
- if (iter.IsAtEnd()) return false;
- if (iter.GetCurrent() == proto) return true;
- }
-}
-
-
-// Scan the heap for objects with direct references to an object
-// args[0]: the object to find references to
-// args[1]: constructor function for instances to exclude (Mirror)
-// args[2]: the the maximum number of objects to return
-RUNTIME_FUNCTION(Runtime_DebugReferencedBy) {
- HandleScope scope(isolate);
- DCHECK_EQ(3, args.length());
- CONVERT_ARG_HANDLE_CHECKED(JSObject, target, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, filter, 1);
- CHECK(filter->IsUndefined(isolate) || filter->IsJSObject());
- CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[2]);
- CHECK_GE(max_references, 0);
-
- std::vector<Handle<JSObject>> instances;
- Heap* heap = isolate->heap();
- {
- HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
- // Get the constructor function for context extension and arguments array.
- Object* arguments_fun = isolate->sloppy_arguments_map()->GetConstructor();
- HeapObject* heap_obj;
- while ((heap_obj = iterator.next()) != nullptr) {
- if (!heap_obj->IsJSObject()) continue;
- JSObject* obj = JSObject::cast(heap_obj);
- if (obj->IsJSContextExtensionObject()) continue;
- if (obj->map()->GetConstructor() == arguments_fun) continue;
- if (!obj->ReferencesObject(*target)) continue;
- // Check filter if supplied. This is normally used to avoid
- // references from mirror objects.
- if (!filter->IsUndefined(isolate) &&
- HasInPrototypeChainIgnoringProxies(isolate, obj, *filter)) {
- continue;
- }
- if (obj->IsJSGlobalObject()) {
- obj = JSGlobalObject::cast(obj)->global_proxy();
- }
- instances.emplace_back(obj);
- if (static_cast<int32_t>(instances.size()) == max_references) break;
- }
- // Iterate the rest of the heap to satisfy HeapIterator constraints.
- while (iterator.next()) {
- }
- }
-
- Handle<FixedArray> result;
- if (instances.size() == 1 && instances.back().is_identical_to(target)) {
- // Check for circular reference only. This can happen when the object is
- // only referenced from mirrors and has a circular reference in which case
- // the object is not really alive and would have been garbage collected if
- // not referenced from the mirror.
- result = isolate->factory()->empty_fixed_array();
- } else {
- int instances_size = static_cast<int>(instances.size());
- result = isolate->factory()->NewFixedArray(instances_size);
- for (int i = 0; i < instances_size; ++i) result->set(i, *instances[i]);
- }
- return *isolate->factory()->NewJSArrayWithElements(result);
-}
-
-
-// Scan the heap for objects constructed by a specific function.
-// args[0]: the constructor to find instances of
-// args[1]: the the maximum number of objects to return
-RUNTIME_FUNCTION(Runtime_DebugConstructedBy) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 0);
- CONVERT_NUMBER_CHECKED(int32_t, max_references, Int32, args[1]);
- CHECK_GE(max_references, 0);
-
- std::vector<Handle<JSObject>> instances;
- Heap* heap = isolate->heap();
- {
- HeapIterator iterator(heap, HeapIterator::kFilterUnreachable);
- HeapObject* heap_obj;
- while ((heap_obj = iterator.next()) != nullptr) {
- if (!heap_obj->IsJSObject()) continue;
- JSObject* obj = JSObject::cast(heap_obj);
- if (obj->map()->GetConstructor() != *constructor) continue;
- instances.emplace_back(obj);
- if (static_cast<int32_t>(instances.size()) == max_references) break;
- }
- // Iterate the rest of the heap to satisfy HeapIterator constraints.
- while (iterator.next()) {
- }
- }
-
- int instances_size = static_cast<int>(instances.size());
- Handle<FixedArray> result = isolate->factory()->NewFixedArray(instances_size);
- for (int i = 0; i < instances_size; ++i) result->set(i, *instances[i]);
- return *isolate->factory()->NewJSArrayWithElements(result);
-}
-
-
-// Find the effective prototype object as returned by __proto__.
-// args[0]: the object to find the prototype for.
-RUNTIME_FUNCTION(Runtime_DebugGetPrototype) {
- HandleScope shs(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- // TODO(1543): Come up with a solution for clients to handle potential errors
- // thrown by an intermediate proxy.
- RETURN_RESULT_OR_FAILURE(isolate, JSReceiver::GetPrototype(isolate, obj));
-}
-
-
-// Patches script source (should be called upon BeforeCompile event).
-// TODO(5530): Remove once uses in debug.js are gone.
-RUNTIME_FUNCTION(Runtime_DebugSetScriptSource) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
-
- CONVERT_ARG_HANDLE_CHECKED(JSValue, script_wrapper, 0);
- CONVERT_ARG_HANDLE_CHECKED(String, source, 1);
-
- CHECK(script_wrapper->value()->IsScript());
- Handle<Script> script(Script::cast(script_wrapper->value()));
-
- // The following condition is not guaranteed to hold and a failure is also
- // propagated to callers. Hence we fail gracefully here and don't crash.
- if (script->compilation_state() != Script::COMPILATION_STATE_INITIAL) {
- return isolate->ThrowIllegalOperation();
- }
-
- script->set_source(*source);
-
- return isolate->heap()->undefined_value();
-}
-
RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
SealHandleScope shs(isolate);
@@ -1371,41 +441,7 @@ RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
if (f->IsJSFunction()) {
return JSFunction::cast(f)->shared()->inferred_name();
}
- return isolate->heap()->empty_string();
-}
-
-
-RUNTIME_FUNCTION(Runtime_FunctionGetDebugName) {
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
-
- CONVERT_ARG_HANDLE_CHECKED(JSReceiver, function, 0);
-
- if (function->IsJSBoundFunction()) {
- RETURN_RESULT_OR_FAILURE(
- isolate, JSBoundFunction::GetName(
- isolate, Handle<JSBoundFunction>::cast(function)));
- } else {
- return *JSFunction::GetDebugName(Handle<JSFunction>::cast(function));
- }
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetDebugContext) {
- HandleScope scope(isolate);
- DCHECK_EQ(0, args.length());
- Handle<Context> context;
- {
- DebugScope debug_scope(isolate->debug());
- if (debug_scope.failed()) {
- DCHECK(isolate->has_pending_exception());
- return isolate->heap()->exception();
- }
- context = isolate->debug()->GetDebugContext();
- }
- if (context.is_null()) return isolate->heap()->undefined_value();
- context->set_security_token(isolate->native_context()->security_token());
- return context->global_proxy();
+ return ReadOnlyRoots(isolate).empty_string();
}
@@ -1416,7 +452,7 @@ RUNTIME_FUNCTION(Runtime_CollectGarbage) {
DCHECK_EQ(1, args.length());
isolate->heap()->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask,
GarbageCollectionReason::kRuntime);
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1431,56 +467,6 @@ RUNTIME_FUNCTION(Runtime_GetHeapUsage) {
return Smi::FromInt(usage);
}
-
-// Finds the script object from the script data. NOTE: This operation uses
-// heap traversal to find the function generated for the source position
-// for the requested break point. For lazily compiled functions several heap
-// traversals might be required rendering this operation as a rather slow
-// operation. However for setting break points which is normally done through
-// some kind of user interaction the performance is not crucial.
-RUNTIME_FUNCTION(Runtime_GetScript) {
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_ARG_HANDLE_CHECKED(String, script_name, 0);
-
- Handle<Script> found;
- {
- Script::Iterator iterator(isolate);
- Script* script = nullptr;
- while ((script = iterator.Next()) != nullptr) {
- if (!script->name()->IsString()) continue;
- String* name = String::cast(script->name());
- if (name->Equals(*script_name)) {
- found = Handle<Script>(script, isolate);
- break;
- }
- }
- }
-
- if (found.is_null()) return isolate->heap()->undefined_value();
- return *Script::GetWrapper(found);
-}
-
-// TODO(5530): Remove once uses in debug.js are gone.
-RUNTIME_FUNCTION(Runtime_ScriptLineCount) {
- HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
- CONVERT_ARG_CHECKED(JSValue, script, 0);
-
- CHECK(script->value()->IsScript());
- Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
-
- if (script_handle->type() == Script::TYPE_WASM) {
- // Return 0 for now; this function will disappear soon anyway.
- return Smi::FromInt(0);
- }
-
- Script::InitLineEnds(script_handle);
-
- FixedArray* line_ends_array = FixedArray::cast(script_handle->line_ends());
- return Smi::FromInt(line_ends_array->length());
-}
-
namespace {
int ScriptLinePosition(Handle<Script> script, int line) {
@@ -1488,7 +474,6 @@ int ScriptLinePosition(Handle<Script> script, int line) {
if (script->type() == Script::TYPE_WASM) {
return WasmModuleObject::cast(script->wasm_module_object())
- ->shared()
->GetFunctionOffset(line);
}
@@ -1504,11 +489,24 @@ int ScriptLinePosition(Handle<Script> script, int line) {
return Smi::ToInt(line_ends_array->get(line - 1)) + 1;
}
-} // namespace
+int ScriptLinePositionWithOffset(Handle<Script> script, int line, int offset) {
+ if (line < 0 || offset < 0) return -1;
+
+ if (line == 0 || offset == 0)
+ return ScriptLinePosition(script, line) + offset;
+
+ Script::PositionInfo info;
+ if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET)) {
+ return -1;
+ }
-static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
- Script::OffsetFlag offset_flag,
- Isolate* isolate) {
+ const int total_line = info.line + line;
+ return ScriptLinePosition(script, total_line);
+}
+
+Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
+ Script::OffsetFlag offset_flag,
+ Isolate* isolate) {
Script::PositionInfo info;
if (!Script::GetPositionInfo(script, position, &info, offset_flag)) {
return isolate->factory()->null_value();
@@ -1523,37 +521,21 @@ static Handle<Object> GetJSPositionInfo(Handle<Script> script, int position,
Handle<JSObject> jsinfo =
isolate->factory()->NewJSObject(isolate->object_function());
- JSObject::AddProperty(jsinfo, isolate->factory()->script_string(), script,
- NONE);
- JSObject::AddProperty(jsinfo, isolate->factory()->position_string(),
+ JSObject::AddProperty(isolate, jsinfo, isolate->factory()->script_string(),
+ script, NONE);
+ JSObject::AddProperty(isolate, jsinfo, isolate->factory()->position_string(),
handle(Smi::FromInt(position), isolate), NONE);
- JSObject::AddProperty(jsinfo, isolate->factory()->line_string(),
+ JSObject::AddProperty(isolate, jsinfo, isolate->factory()->line_string(),
handle(Smi::FromInt(info.line), isolate), NONE);
- JSObject::AddProperty(jsinfo, isolate->factory()->column_string(),
+ JSObject::AddProperty(isolate, jsinfo, isolate->factory()->column_string(),
handle(Smi::FromInt(info.column), isolate), NONE);
- JSObject::AddProperty(jsinfo, isolate->factory()->sourceText_string(),
- sourceText, NONE);
+ JSObject::AddProperty(isolate, jsinfo,
+ isolate->factory()->sourceText_string(), sourceText,
+ NONE);
return jsinfo;
}
-namespace {
-
-int ScriptLinePositionWithOffset(Handle<Script> script, int line, int offset) {
- if (line < 0 || offset < 0) return -1;
-
- if (line == 0 || offset == 0)
- return ScriptLinePosition(script, line) + offset;
-
- Script::PositionInfo info;
- if (!Script::GetPositionInfo(script, offset, &info, Script::NO_OFFSET)) {
- return -1;
- }
-
- const int total_line = info.line + line;
- return ScriptLinePosition(script, total_line);
-}
-
Handle<Object> ScriptLocationFromLine(Isolate* isolate, Handle<Script> script,
Handle<Object> opt_line,
Handle<Object> opt_column,
@@ -1587,7 +569,7 @@ bool GetScriptById(Isolate* isolate, int needle, Handle<Script>* result) {
Script* script = nullptr;
while ((script = iterator.Next()) != nullptr) {
if (script->id() == needle) {
- *result = handle(script);
+ *result = handle(script, isolate);
return true;
}
}
@@ -1597,30 +579,6 @@ bool GetScriptById(Isolate* isolate, int needle, Handle<Script>* result) {
} // namespace
-// Get information on a specific source line and column possibly offset by a
-// fixed source position. This function is used to find a source position from
-// a line and column position. The fixed source position offset is typically
-// used to find a source position in a function based on a line and column in
-// the source for the function alone. The offset passed will then be the
-// start position of the source for the function within the full script source.
-// Note that incoming line and column parameters may be undefined, and are
-// assumed to be passed *with* offsets.
-// TODO(5530): Remove once uses in debug.js are gone.
-RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine) {
- HandleScope scope(isolate);
- DCHECK_EQ(4, args.length());
- CONVERT_ARG_HANDLE_CHECKED(JSValue, script, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, opt_line, 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, opt_column, 2);
- CONVERT_NUMBER_CHECKED(int32_t, offset, Int32, args[3]);
-
- CHECK(script->value()->IsScript());
- Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
-
- return *ScriptLocationFromLine(isolate, script_handle, opt_line, opt_column,
- offset);
-}
-
// TODO(5530): Rename once conflicting function has been deleted.
RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine2) {
HandleScope scope(isolate);
@@ -1636,38 +594,6 @@ RUNTIME_FUNCTION(Runtime_ScriptLocationFromLine2) {
return *ScriptLocationFromLine(isolate, script, opt_line, opt_column, offset);
}
-// TODO(5530): Remove once uses in debug.js are gone.
-RUNTIME_FUNCTION(Runtime_ScriptPositionInfo) {
- HandleScope scope(isolate);
- DCHECK_EQ(3, args.length());
- CONVERT_ARG_CHECKED(JSValue, script, 0);
- CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]);
- CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2);
-
- CHECK(script->value()->IsScript());
- Handle<Script> script_handle = Handle<Script>(Script::cast(script->value()));
-
- const Script::OffsetFlag offset_flag =
- with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET;
- return *GetJSPositionInfo(script_handle, position, offset_flag, isolate);
-}
-
-// TODO(5530): Rename once conflicting function has been deleted.
-RUNTIME_FUNCTION(Runtime_ScriptPositionInfo2) {
- HandleScope scope(isolate);
- DCHECK_EQ(3, args.length());
- CONVERT_NUMBER_CHECKED(int32_t, scriptid, Int32, args[0]);
- CONVERT_NUMBER_CHECKED(int32_t, position, Int32, args[1]);
- CONVERT_BOOLEAN_ARG_CHECKED(with_offset, 2);
-
- Handle<Script> script;
- CHECK(GetScriptById(isolate, scriptid, &script));
-
- const Script::OffsetFlag offset_flag =
- with_offset ? Script::WITH_OFFSET : Script::NO_OFFSET;
- return *GetJSPositionInfo(script, position, offset_flag, isolate);
-}
-
// On function call, depending on circumstances, prepare for stepping in,
// or perform a side effect check.
RUNTIME_FUNCTION(Runtime_DebugOnFunctionCall) {
@@ -1678,16 +604,17 @@ RUNTIME_FUNCTION(Runtime_DebugOnFunctionCall) {
if (isolate->debug()->needs_check_on_function_call()) {
// Ensure that the callee will perform debug check on function call too.
Deoptimizer::DeoptimizeFunction(*fun);
- if (isolate->debug()->last_step_action() >= StepIn) {
+ if (isolate->debug()->last_step_action() >= StepIn ||
+ isolate->debug()->break_on_next_function_call()) {
DCHECK_EQ(isolate->debug_execution_mode(), DebugInfo::kBreakpoints);
isolate->debug()->PrepareStepIn(fun);
}
if (isolate->debug_execution_mode() == DebugInfo::kSideEffects &&
!isolate->debug()->PerformSideEffectCheck(fun, receiver)) {
- return isolate->heap()->exception();
+ return ReadOnlyRoots(isolate).exception();
}
}
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
// Set one shot breakpoints for the suspended generator object.
@@ -1695,7 +622,7 @@ RUNTIME_FUNCTION(Runtime_DebugPrepareStepInSuspendedGenerator) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
isolate->debug()->PrepareStepInSuspendedGenerator();
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
@@ -1703,7 +630,7 @@ RUNTIME_FUNCTION(Runtime_DebugPushPromise) {
HandleScope scope(isolate);
CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
isolate->PushPromise(promise);
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
@@ -1711,22 +638,7 @@ RUNTIME_FUNCTION(Runtime_DebugPopPromise) {
DCHECK_EQ(0, args.length());
SealHandleScope shs(isolate);
isolate->PopPromise();
- return isolate->heap()->undefined_value();
-}
-
-RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionPromiseCreated) {
- DCHECK_EQ(1, args.length());
- HandleScope scope(isolate);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, promise, 0);
- isolate->PushPromise(promise);
- int id = isolate->debug()->NextAsyncTaskId(promise);
- Handle<Symbol> async_stack_id_symbol =
- isolate->factory()->promise_async_stack_id_symbol();
- JSObject::SetProperty(promise, async_stack_id_symbol,
- handle(Smi::FromInt(id), isolate),
- LanguageMode::kStrict)
- .Assert();
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugIsActive) {
@@ -1743,11 +655,11 @@ Handle<JSObject> MakeRangeObject(Isolate* isolate, const CoverageBlock& range) {
Handle<String> count_string = factory->InternalizeUtf8String("count");
Handle<JSObject> range_obj = factory->NewJSObjectWithNullProto();
- JSObject::AddProperty(range_obj, start_string,
+ JSObject::AddProperty(isolate, range_obj, start_string,
factory->NewNumberFromInt(range.start), NONE);
- JSObject::AddProperty(range_obj, end_string,
+ JSObject::AddProperty(isolate, range_obj, end_string,
factory->NewNumberFromInt(range.end), NONE);
- JSObject::AddProperty(range_obj, count_string,
+ JSObject::AddProperty(isolate, range_obj, count_string,
factory->NewNumberFromUint(range.count), NONE);
return range_obj;
@@ -1796,8 +708,8 @@ RUNTIME_FUNCTION(Runtime_DebugCollectCoverage) {
Handle<JSArray> script_obj =
factory->NewJSArrayWithElements(ranges_array, PACKED_ELEMENTS);
- Handle<JSObject> wrapper = Script::GetWrapper(script_data.script);
- JSObject::AddProperty(script_obj, script_string, wrapper, NONE);
+ JSObject::AddProperty(isolate, script_obj, script_string,
+ handle(script_data.script->source(), isolate), NONE);
scripts_array->set(i, *script_obj);
}
return *factory->NewJSArrayWithElements(scripts_array, PACKED_ELEMENTS);
@@ -1808,7 +720,7 @@ RUNTIME_FUNCTION(Runtime_DebugTogglePreciseCoverage) {
CONVERT_BOOLEAN_ARG_CHECKED(enable, 0);
Coverage::SelectMode(isolate, enable ? debug::Coverage::kPreciseCount
: debug::Coverage::kBestEffort);
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_DebugToggleBlockCoverage) {
@@ -1816,7 +728,7 @@ RUNTIME_FUNCTION(Runtime_DebugToggleBlockCoverage) {
CONVERT_BOOLEAN_ARG_CHECKED(enable, 0);
Coverage::SelectMode(isolate, enable ? debug::Coverage::kBlockCount
: debug::Coverage::kBestEffort);
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
RUNTIME_FUNCTION(Runtime_IncBlockCounter) {
@@ -1836,8 +748,67 @@ RUNTIME_FUNCTION(Runtime_IncBlockCounter) {
coverage_info->IncrementBlockCount(coverage_array_slot_index);
}
- return isolate->heap()->undefined_value();
+ return ReadOnlyRoots(isolate).undefined_value();
}
+RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionSuspended) {
+ DCHECK_EQ(1, args.length());
+ HandleScope scope(isolate);
+ CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 0);
+ isolate->OnAsyncFunctionStateChanged(promise, debug::kAsyncFunctionSuspended);
+ return ReadOnlyRoots(isolate).undefined_value();
+}
+
+RUNTIME_FUNCTION(Runtime_DebugAsyncFunctionFinished) {
+ DCHECK_EQ(2, args.length());
+ HandleScope scope(isolate);
+ CONVERT_BOOLEAN_ARG_CHECKED(has_suspend, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSPromise, promise, 1);
+ isolate->PopPromise();
+ if (has_suspend) {
+ isolate->OnAsyncFunctionStateChanged(promise,
+ debug::kAsyncFunctionFinished);
+ }
+ return ReadOnlyRoots(isolate).undefined_value();
+}
+
+RUNTIME_FUNCTION(Runtime_LiveEditPatchScript) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ CONVERT_ARG_HANDLE_CHECKED(JSFunction, script_function, 0);
+ CONVERT_ARG_HANDLE_CHECKED(String, new_source, 1);
+
+ Handle<Script> script(Script::cast(script_function->shared()->script()),
+ isolate);
+ v8::debug::LiveEditResult result;
+ LiveEdit::PatchScript(isolate, script, new_source, false, &result);
+ switch (result.status) {
+ case v8::debug::LiveEditResult::COMPILE_ERROR:
+ return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
+ "LiveEdit failed: COMPILE_ERROR"));
+ case v8::debug::LiveEditResult::BLOCKED_BY_RUNNING_GENERATOR:
+ return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
+ "LiveEdit failed: BLOCKED_BY_RUNNING_GENERATOR"));
+ case v8::debug::LiveEditResult::BLOCKED_BY_FUNCTION_ABOVE_BREAK_FRAME:
+ return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
+ "LiveEdit failed: BLOCKED_BY_FUNCTION_ABOVE_BREAK_FRAME"));
+ case v8::debug::LiveEditResult::
+ BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME:
+ return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
+ "LiveEdit failed: BLOCKED_BY_FUNCTION_BELOW_NON_DROPPABLE_FRAME"));
+ case v8::debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION:
+ return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
+ "LiveEdit failed: BLOCKED_BY_ACTIVE_FUNCTION"));
+ case v8::debug::LiveEditResult::BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME:
+ return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
+ "LiveEdit failed: BLOCKED_BY_NEW_TARGET_IN_RESTART_FRAME"));
+ case v8::debug::LiveEditResult::FRAME_RESTART_IS_NOT_SUPPORTED:
+ return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
+ "LiveEdit failed: FRAME_RESTART_IS_NOT_SUPPORTED"));
+ case v8::debug::LiveEditResult::OK:
+ return ReadOnlyRoots(isolate).undefined_value();
+ }
+ return ReadOnlyRoots(isolate).undefined_value();
+}
} // namespace internal
} // namespace v8