mirror of
https://github.com/bellard/quickjs.git
synced 2025-05-09 18:15:43 +08:00
added JS_PrintValue() and use it in console.log(), print() and the REPL (#256)
This commit is contained in:
parent
30fe3de91d
commit
be06b3e92b
@ -1083,6 +1083,13 @@ static JSValue js_std_file_printf(JSContext *ctx, JSValueConst this_val,
|
||||
return js_printf_internal(ctx, argc, argv, f);
|
||||
}
|
||||
|
||||
static JSValue js_std_file_printObject(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
JS_PrintValue(ctx, stdout, argv[0], NULL);
|
||||
return JS_UNDEFINED;
|
||||
}
|
||||
|
||||
static JSValue js_std_file_flush(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
@ -1540,6 +1547,7 @@ static const JSCFunctionListEntry js_std_funcs[] = {
|
||||
JS_PROP_INT32_DEF("SEEK_CUR", SEEK_CUR, JS_PROP_CONFIGURABLE ),
|
||||
JS_PROP_INT32_DEF("SEEK_END", SEEK_END, JS_PROP_CONFIGURABLE ),
|
||||
JS_OBJECT_DEF("Error", js_std_error_props, countof(js_std_error_props), JS_PROP_CONFIGURABLE),
|
||||
JS_CFUNC_DEF("__printObject", 1, js_std_file_printObject ),
|
||||
};
|
||||
|
||||
static const JSCFunctionListEntry js_std_file_proto_funcs[] = {
|
||||
@ -3891,17 +3899,23 @@ static JSValue js_print(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int i;
|
||||
const char *str;
|
||||
size_t len;
|
||||
|
||||
JSValueConst v;
|
||||
|
||||
for(i = 0; i < argc; i++) {
|
||||
if (i != 0)
|
||||
putchar(' ');
|
||||
str = JS_ToCStringLen(ctx, &len, argv[i]);
|
||||
if (!str)
|
||||
return JS_EXCEPTION;
|
||||
fwrite(str, 1, len, stdout);
|
||||
JS_FreeCString(ctx, str);
|
||||
v = argv[i];
|
||||
if (JS_IsString(v)) {
|
||||
const char *str;
|
||||
size_t len;
|
||||
str = JS_ToCStringLen(ctx, &len, v);
|
||||
if (!str)
|
||||
return JS_EXCEPTION;
|
||||
fwrite(str, 1, len, stdout);
|
||||
JS_FreeCString(ctx, str);
|
||||
} else {
|
||||
JS_PrintValue(ctx, stdout, v, NULL);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
return JS_UNDEFINED;
|
||||
@ -4012,33 +4026,10 @@ void js_std_free_handlers(JSRuntime *rt)
|
||||
JS_SetRuntimeOpaque(rt, NULL); /* fail safe */
|
||||
}
|
||||
|
||||
static void js_dump_obj(JSContext *ctx, FILE *f, JSValueConst val)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
str = JS_ToCString(ctx, val);
|
||||
if (str) {
|
||||
fprintf(f, "%s\n", str);
|
||||
JS_FreeCString(ctx, str);
|
||||
} else {
|
||||
fprintf(f, "[exception]\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void js_std_dump_error1(JSContext *ctx, JSValueConst exception_val)
|
||||
{
|
||||
JSValue val;
|
||||
BOOL is_error;
|
||||
|
||||
is_error = JS_IsError(ctx, exception_val);
|
||||
js_dump_obj(ctx, stderr, exception_val);
|
||||
if (is_error) {
|
||||
val = JS_GetPropertyStr(ctx, exception_val, "stack");
|
||||
if (!JS_IsUndefined(val)) {
|
||||
js_dump_obj(ctx, stderr, val);
|
||||
}
|
||||
JS_FreeValue(ctx, val);
|
||||
}
|
||||
JS_PrintValue(ctx, stderr, exception_val, NULL);
|
||||
fputc('\n', stderr);
|
||||
}
|
||||
|
||||
void js_std_dump_error(JSContext *ctx)
|
||||
|
17
quickjs.h
17
quickjs.h
@ -1113,6 +1113,23 @@ int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *export_name,
|
||||
int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
|
||||
const JSCFunctionListEntry *tab, int len);
|
||||
|
||||
/* debug value output */
|
||||
|
||||
typedef struct {
|
||||
JS_BOOL show_hidden : 8; /* only show enumerable properties */
|
||||
JS_BOOL show_closure : 8; /* show closure variables */
|
||||
JS_BOOL raw_dump : 8; /* avoid doing autoinit and avoid any malloc() call (for internal use) */
|
||||
uint32_t max_depth; /* recurse up to this depth, 0 = no limit */
|
||||
uint32_t max_string_length; /* print no more than this length for
|
||||
strings, 0 = no limit */
|
||||
uint32_t max_item_count; /* print no more than this count for
|
||||
arrays or objects, 0 = no limit */
|
||||
} JSPrintValueOptions;
|
||||
|
||||
void JS_PrintValueSetDefaultOptions(JSPrintValueOptions *options);
|
||||
void JS_PrintValueRT(JSRuntime *rt, FILE *fo, JSValueConst val, const JSPrintValueOptions *options);
|
||||
void JS_PrintValue(JSContext *ctx, FILE *fo, JSValueConst val, const JSPrintValueOptions *options);
|
||||
|
||||
#undef js_unlikely
|
||||
#undef js_force_inline
|
||||
|
||||
|
149
repl.js
149
repl.js
@ -875,126 +875,19 @@ import * as os from "os";
|
||||
}
|
||||
|
||||
var hex_mode = false;
|
||||
var eval_mode = "std";
|
||||
|
||||
function number_to_string(a, radix) {
|
||||
function number_to_string_hex(a) {
|
||||
var s;
|
||||
if (!isFinite(a)) {
|
||||
/* NaN, Infinite */
|
||||
return a.toString();
|
||||
if (a < 0) {
|
||||
a = -a;
|
||||
s = "-";
|
||||
} else {
|
||||
if (a == 0) {
|
||||
if (1 / a < 0)
|
||||
s = "-0";
|
||||
else
|
||||
s = "0";
|
||||
} else {
|
||||
if (radix == 16 && a === Math.floor(a)) {
|
||||
var s;
|
||||
if (a < 0) {
|
||||
a = -a;
|
||||
s = "-";
|
||||
} else {
|
||||
s = "";
|
||||
}
|
||||
s += "0x" + a.toString(16);
|
||||
} else {
|
||||
s = a.toString();
|
||||
}
|
||||
}
|
||||
return s;
|
||||
s = "";
|
||||
}
|
||||
}
|
||||
|
||||
function bigint_to_string(a, radix) {
|
||||
var s;
|
||||
if (radix == 16) {
|
||||
var s;
|
||||
if (a < 0) {
|
||||
a = -a;
|
||||
s = "-";
|
||||
} else {
|
||||
s = "";
|
||||
}
|
||||
s += "0x" + a.toString(16);
|
||||
} else {
|
||||
s = a.toString();
|
||||
}
|
||||
if (eval_mode === "std")
|
||||
s += "n";
|
||||
s += "0x" + a.toString(16);
|
||||
return s;
|
||||
}
|
||||
|
||||
function print(a) {
|
||||
var stack = [];
|
||||
|
||||
function print_rec(a) {
|
||||
var n, i, keys, key, type, s;
|
||||
|
||||
type = typeof(a);
|
||||
if (type === "object") {
|
||||
if (a === null) {
|
||||
std.puts(a);
|
||||
} else if (stack.indexOf(a) >= 0) {
|
||||
std.puts("[circular]");
|
||||
} else if (a instanceof Date) {
|
||||
std.puts("Date " + a.toGMTString().__quote());
|
||||
} else {
|
||||
stack.push(a);
|
||||
if (Array.isArray(a)) {
|
||||
n = a.length;
|
||||
std.puts("[ ");
|
||||
for(i = 0; i < n; i++) {
|
||||
if (i !== 0)
|
||||
std.puts(", ");
|
||||
if (i in a) {
|
||||
print_rec(a[i]);
|
||||
} else {
|
||||
std.puts("<empty>");
|
||||
}
|
||||
if (i > 20) {
|
||||
std.puts("...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
std.puts(" ]");
|
||||
} else if (Object.__getClass(a) === "RegExp") {
|
||||
std.puts(a.toString());
|
||||
} else {
|
||||
keys = Object.keys(a);
|
||||
n = keys.length;
|
||||
std.puts("{ ");
|
||||
for(i = 0; i < n; i++) {
|
||||
if (i !== 0)
|
||||
std.puts(", ");
|
||||
key = keys[i];
|
||||
std.puts(key, ": ");
|
||||
print_rec(a[key]);
|
||||
}
|
||||
std.puts(" }");
|
||||
}
|
||||
stack.pop(a);
|
||||
}
|
||||
} else if (type === "string") {
|
||||
s = a.__quote();
|
||||
if (s.length > 79)
|
||||
s = s.substring(0, 75) + "...\"";
|
||||
std.puts(s);
|
||||
} else if (type === "number") {
|
||||
std.puts(number_to_string(a, hex_mode ? 16 : 10));
|
||||
} else if (type === "bigint") {
|
||||
std.puts(bigint_to_string(a, hex_mode ? 16 : 10));
|
||||
} else if (type === "symbol") {
|
||||
std.puts(String(a));
|
||||
} else if (type === "function") {
|
||||
std.puts("function " + a.name + "()");
|
||||
} else {
|
||||
std.puts(a);
|
||||
}
|
||||
}
|
||||
print_rec(a);
|
||||
}
|
||||
|
||||
|
||||
function extract_directive(a) {
|
||||
var pos;
|
||||
if (a[0] !== '\\')
|
||||
@ -1116,10 +1009,25 @@ import * as os from "os";
|
||||
}
|
||||
|
||||
function print_eval_result(result) {
|
||||
var default_print = true;
|
||||
|
||||
result = result.value;
|
||||
eval_time = os.now() - eval_start_time;
|
||||
std.puts(colors[styles.result]);
|
||||
print(result);
|
||||
if (hex_mode) {
|
||||
if (typeof result == "number" &&
|
||||
result === Math.floor(result)) {
|
||||
std.puts(number_to_string_hex(result));
|
||||
default_print = false;
|
||||
} else if (typeof result == "bigint") {
|
||||
std.puts(number_to_string_hex(result));
|
||||
std.puts("n");
|
||||
default_print = false;
|
||||
}
|
||||
}
|
||||
if (default_print) {
|
||||
std.__printObject(result);
|
||||
}
|
||||
std.puts("\n");
|
||||
std.puts(colors.none);
|
||||
/* set the last result */
|
||||
@ -1130,15 +1038,10 @@ import * as os from "os";
|
||||
|
||||
function print_eval_error(error) {
|
||||
std.puts(colors[styles.error_msg]);
|
||||
if (error instanceof Error) {
|
||||
console.log(error);
|
||||
if (error.stack) {
|
||||
std.puts(error.stack);
|
||||
}
|
||||
} else {
|
||||
if (!(error instanceof Error))
|
||||
std.puts("Throw: ");
|
||||
console.log(error);
|
||||
}
|
||||
std.__printObject(error);
|
||||
std.puts("\n");
|
||||
std.puts(colors.none);
|
||||
|
||||
handle_cmd_end();
|
||||
|
@ -376,22 +376,29 @@ static JSValue js_print(JSContext *ctx, JSValueConst this_val,
|
||||
int argc, JSValueConst *argv)
|
||||
{
|
||||
int i;
|
||||
const char *str;
|
||||
|
||||
JSValueConst v;
|
||||
|
||||
if (outfile) {
|
||||
for (i = 0; i < argc; i++) {
|
||||
if (i != 0)
|
||||
fputc(' ', outfile);
|
||||
str = JS_ToCString(ctx, argv[i]);
|
||||
if (!str)
|
||||
return JS_EXCEPTION;
|
||||
if (!strcmp(str, "Test262:AsyncTestComplete")) {
|
||||
async_done++;
|
||||
} else if (strstart(str, "Test262:AsyncTestFailure", NULL)) {
|
||||
async_done = 2; /* force an error */
|
||||
v = argv[i];
|
||||
if (JS_IsString(v)) {
|
||||
const char *str;
|
||||
size_t len;
|
||||
str = JS_ToCStringLen(ctx, &len, v);
|
||||
if (!str)
|
||||
return JS_EXCEPTION;
|
||||
if (!strcmp(str, "Test262:AsyncTestComplete")) {
|
||||
async_done++;
|
||||
} else if (strstart(str, "Test262:AsyncTestFailure", NULL)) {
|
||||
async_done = 2; /* force an error */
|
||||
}
|
||||
fwrite(str, 1, len, outfile);
|
||||
JS_FreeCString(ctx, str);
|
||||
} else {
|
||||
JS_PrintValue(ctx, outfile, v, NULL);
|
||||
}
|
||||
fputs(str, outfile);
|
||||
JS_FreeCString(ctx, str);
|
||||
}
|
||||
fputc('\n', outfile);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user