Skip to content

Commit

Permalink
src: implement v8 inspect --array-length for large arrays (#105)
Browse files Browse the repository at this point in the history
* test: test --string-length
* src, test: add --array-length argument
* src, test: fix array length in inspect

Fix: #89
PR-URL: #105
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
  • Loading branch information
joyeecheung authored and hhellyer committed Jun 29, 2017
1 parent 628ad41 commit 9014fd4
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 5 deletions.
5 changes: 5 additions & 0 deletions src/llnode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ char** CommandBase::ParseInspectOptions(char** cmd,
static struct option opts[] = {
{"full-string", no_argument, nullptr, 'F'},
{"string-length", required_argument, nullptr, 0x1001},
{"array-length", required_argument, nullptr, 0x1002},
{"print-map", no_argument, nullptr, 'm'},
{"print-source", no_argument, nullptr, 's'},
{nullptr, 0, nullptr, 0}};
Expand Down Expand Up @@ -52,6 +53,9 @@ char** CommandBase::ParseInspectOptions(char** cmd,
case 0x1001:
options->string_length = strtol(optarg, nullptr, 10);
break;
case 0x1002:
options->array_length = strtol(optarg, nullptr, 10);
break;
case 's':
options->print_source = true;
break;
Expand Down Expand Up @@ -302,6 +306,7 @@ bool PluginInitialize(SBDebugger d) {
" * -m, --print-map - print object's map address\n"
" * -s, --print-source - print source code for function objects\n"
" * --string-length num - print maximum of `num` characters in string\n"
" * --array-length num - print maximum of `num` elements in array\n"
"\n"
"Syntax: v8 inspect [flags] expr\n");
interpreter.AddCommand("jsprint", new llnode::PrintCmd(true),
Expand Down
19 changes: 15 additions & 4 deletions src/llv8.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <assert.h>

#include <algorithm>
#include <cinttypes>

#include "llv8-inl.h"
Expand Down Expand Up @@ -1283,9 +1284,18 @@ std::string JSObject::InspectElements(Error& err) {
Smi length_smi = elements.Length(err);
if (err.Fail()) return std::string();

int64_t length = length_smi.GetValue();
return InspectElements(length, err);
}


std::string JSObject::InspectElements(int64_t length, Error& err) {
HeapObject elements_obj = Elements(err);
if (err.Fail()) return std::string();
FixedArray elements(elements_obj);

InspectOptions options;

int64_t length = length_smi.GetValue();
std::string res;
for (int64_t i = 0; i < length; i++) {
Value value = elements.Get<Value>(i, err);
Expand Down Expand Up @@ -1838,12 +1848,13 @@ v8::Value JSObject::GetArrayElement(int64_t pos, Error& err) {
}

std::string JSArray::Inspect(InspectOptions* options, Error& err) {
Smi length = Length(err);
int64_t length = GetArrayLength(err);
if (err.Fail()) return std::string();

std::string res = "<Array: length=" + length.ToString(err);
std::string res = "<Array: length=" + std::to_string(length);
if (options->detailed) {
std::string elems = InspectElements(err);
int64_t display_length = std::min<int64_t>(length, options->array_length);
std::string elems = InspectElements(display_length, err);
if (err.Fail()) return std::string();

if (!elems.empty()) res += " {\n" + elems + "}";
Expand Down
6 changes: 5 additions & 1 deletion src/llv8.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,17 @@ class Value {
: detailed(false),
print_map(false),
print_source(false),
string_length(kStringLength) {}
string_length(kStringLength),
array_length(kArrayLength) {}

static const unsigned int kStringLength = 16;
static const unsigned int kArrayLength = 16;

bool detailed;
bool print_map;
bool print_source;
unsigned int string_length;
unsigned int array_length;
};

Value(const Value& v) = default;
Expand Down Expand Up @@ -240,6 +243,7 @@ class JSObject : public HeapObject {
std::string InspectProperties(Error& err);

std::string InspectElements(Error& err);
std::string InspectElements(int64_t length, Error& err);
std::string InspectDictionary(Error& err);
std::string InspectDescriptors(Map map, Error& err);
void Keys(std::vector<std::string>& keys, Error& err);
Expand Down
3 changes: 3 additions & 0 deletions test/fixtures/inspect-scenario.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ function closure() {
c.hashmap['cons-string'] =
'this could be a bit smaller, but v8 wants big str.';
c.hashmap['cons-string'] += c.hashmap['cons-string'];
c.hashmap['array'] = [true, 1, undefined, null, 'test', Class];
c.hashmap['long-array'] = new Array(20).fill(5);

c.hashmap[0] = null;
c.hashmap[4] = undefined;
c.hashmap[23] = /regexp/;
Expand Down
46 changes: 46 additions & 0 deletions test/inspect-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ tape('v8 inspect', (t) => {
let regexp = null;
let cons = null;
let arrowFunc = null;
let array = null;
let longArray = null;

sess.wait(/Object/, (line) => {
t.notEqual(line.indexOf(hashmap), -1, 'addr of `Object` should match');
Expand All @@ -72,6 +74,16 @@ tape('v8 inspect', (t) => {
t.ok(/.other-key=[^\n]*<String: "ohai">/.test(lines),
'.other-key property');

const arrayMatch =
lines.match(/.array=(0x[0-9a-f]+):<Array: length=6>/);
t.ok(arrayMatch, '.array JSArray property');
array = arrayMatch[1];

const longArrayMatch =
lines.match(/.long-array=(0x[0-9a-f]+):<Array: length=20>/);
t.ok(longArrayMatch, '.array JSArray property');
longArray = longArrayMatch[1];

const consMatch = lines.match(
/.cons-string=(0x[0-9a-f]+):<String: "this could be a ...">/);
t.ok(consMatch, '.cons-string ConsString property');
Expand All @@ -96,6 +108,40 @@ tape('v8 inspect', (t) => {
-1,
'cons string content');

sess.send(`v8 inspect --string-length 20 ${cons}`);
});

sess.linesUntil(/">/, (lines) => {
lines = lines.join('\n');
t.notEqual(
lines.indexOf('this could be a bit ...'),
-1,
'--string-length truncates the string');

sess.send(`v8 inspect ${array}`);
});

sess.linesUntil(/}>/, (lines) => {
lines = lines.join('\n');
t.notEqual(
lines.indexOf('<Array: length=6'),
-1,
'array length');
t.ok(
lines.match(/\[5\]=0x[0-9a-f]+:<function: Class at .+\.js:\d+:\d+>}>$/),
'array content');
sess.send(`v8 inspect --array-length 10 ${longArray}`);
});

sess.linesUntil(/}>/, (lines) => {
lines = lines.join('\n');
t.notEqual(
lines.indexOf('<Array: length=20'),
-1,
'long array length');
t.ok(
lines.match(/\[9\]=<Smi: 5>}>$/),
'long array content');
sess.send(`v8 inspect -s ${arrowFunc}`);
});

Expand Down

0 comments on commit 9014fd4

Please sign in to comment.