Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: inspcet arguments from an Error object stack #271

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 47 additions & 12 deletions src/llv8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1259,15 +1259,10 @@ StackTrace::StackTrace(JSArray frame_array, Error& err)

len_ = v8::Smi(maybe_stack_len).GetValue();

multiplier_ = 5;
// On Node.js v8.x, the first array element is the stack size, and each
// stack frame use 5 elements.
if ((len_ * multiplier_ + 1) != frame_array_.GetArrayLength(err)) {
// On Node.js v6.x, the first array element is zero, and each stack frame
// use 4 element.
multiplier_ = 4;
if ((len_ != 0) ||
((frame_array_.GetArrayLength(err) - 1) % multiplier_ != 0)) {
// On Node.js v6.x, the first array element is zero, and each stack frame
// use 4 element.
if (len_ == 0) {
if ((frame_array_.GetArrayLength(err) - 1) % multiplier_ != 0) {
Error::PrintInDebugMode(
"JSArray doesn't look like a Stack Frames array. stack_len: %lld "
"array_len: %lld",
Expand All @@ -1276,7 +1271,24 @@ StackTrace::StackTrace(JSArray frame_array, Error& err)
multiplier_ = -1;
return;
}
multiplier_ = 4;
len_ = (frame_array_.GetArrayLength(err) - 1) / multiplier_;
} else {
// On Node.js v8.x and later, the first array element is the stack size,
// and each stack frame use 5 or 6 elements.
multiplier_ = (frame_array_.GetArrayLength(err) - 1) / len_;
if (multiplier_ == 6) {
// If stack frame has 6 elements, it has parameters information
has_parameters_ = true;
} else if (multiplier_ != 5) {
Error::PrintInDebugMode(
"JSArray doesn't look like a Stack Frames array. stack_len: %lld "
"array_len: %lld",
len_, frame_array_.GetArrayLength(err));
len_ = -1;
multiplier_ = -1;
return;
}
}
}

Expand All @@ -1294,17 +1306,40 @@ StackFrame::StackFrame(StackTrace* stack_trace, int index)
: stack_trace_(stack_trace), index_(index) {}

JSFunction StackFrame::GetFunction(Error& err) {
int js_function_pos = frame_array_index() + 1;
JSArray frame_array = stack_trace_->frame_array_;
v8::Value maybe_fn = frame_array.GetArrayElement(frame_array_index(), err);
v8::Value maybe_fn = frame_array.GetArrayElement(js_function_pos, err);
if (err.Fail()) return JSFunction();
return JSFunction(maybe_fn);
}

Value StackFrame::GetReceiver(Error& err) {
int receiver_pos = frame_array_index();
JSArray frame_array = stack_trace_->frame_array_;
v8::Value maybe_receiver = frame_array.GetArrayElement(receiver_pos, err);
if (err.Fail()) return Value();
return maybe_receiver;
}

bool StackFrame::HasParameters(Error& err) {
return stack_trace_->has_parameters_;
}

FixedArray StackFrame::GetParameters(Error& err) {
if (!HasParameters(err)) {
return FixedArray();
}
const int parameters_pos = frame_array_index() + 5;
JSArray frame_array = stack_trace_->frame_array_;
v8::Value maybe_parameters = frame_array.GetArrayElement(parameters_pos, err);
if (err.Fail()) return FixedArray();
return FixedArray(maybe_parameters);
}

int StackFrame::frame_array_index() {
int multiplier = stack_trace_->multiplier_;
const int js_function_pos = 1;
const int begin_offset = 1;
return begin_offset + js_function_pos + (index_ * multiplier);
return begin_offset + (index_ * multiplier);
}


Expand Down
6 changes: 6 additions & 0 deletions src/llv8.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,9 +290,14 @@ class JSError : public JSObject {
inline std::string stack_trace_property();
};

class FixedArray;
class StackFrame {
public:
Value GetReceiver(Error& err);
JSFunction GetFunction(Error& err);
FixedArray GetParameters(Error& err);

bool HasParameters(Error& err);

private:
friend StackTrace;
Expand Down Expand Up @@ -346,6 +351,7 @@ class StackTrace {
JSArray frame_array_;
int multiplier_ = -1;
int len_ = -1;
int has_parameters_ = false;
};


Expand Down
17 changes: 15 additions & 2 deletions src/printer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -559,14 +559,27 @@ std::string Printer::Stringify(v8::JSError js_error, Error& err) {
Printer printer(llv8_);
for (v8::StackFrame frame : stack_trace) {
v8::JSFunction js_function = frame.GetFunction(err);
v8::Value receiver = frame.GetReceiver(err);
if (err.Fail()) {
error_stack << rang::fg::gray << " <unknown>" << std::endl;
continue;
}

error_stack << " "
error_stack << " { fn="
<< printer.Stringify<v8::HeapObject>(js_function, err)
<< std::endl;
<< ", this=" << printer.Stringify(receiver, err);
if (frame.HasParameters(err)) {
v8::FixedArray parameters = frame.GetParameters(err);
int64_t param_len = parameters.Length(err).GetValue();
error_stack << ", args=[";
for(int64_t p = 0; p < param_len; p++) {
v8::Value param = parameters.Get<v8::Value>(p, err);
error_stack << printer.Stringify(param, err);
if (p < param_len - 1) error_stack << ", ";
}
error_stack << "]";
}
error_stack << " }" << std::endl;
}
error_stack << " }";
output << error_stack.str();
Expand Down