Browse Source

add a prototype implementation for a stack traceback getter (implemented as an actual function for now)

pull/1/head
Sami Vaarala 11 years ago
parent
commit
ff15e493ab
  1. 94
      src/duk_builtin_error.c
  2. 1
      src/duk_builtin_protos.h
  3. 5
      src/genbuiltins.py
  4. 2
      src/genstrings.py

94
src/duk_builtin_error.c

@ -105,3 +105,97 @@ int duk_builtin_error_prototype_to_string(duk_context *ctx) {
return DUK_RET_TYPE_ERROR;
}
/* FIXME: This needs to actually be a getter/setter pair, this is
* for prototyping traceback formatting. The resulting code is
* also way too large, so needs rework.
*/
int duk_builtin_error_prototype_stack(duk_context *ctx) {
int idx_td;
int i;
const char *str_tailcalled = " tailcalled";
const char *str_strict = " strict";
const char *str_construct = " construct";
const char *str_empty = "";
duk_push_this(ctx);
duk_get_prop_stridx(ctx, -1, DUK_STRIDX_TRACEDATA);
idx_td = duk_get_top_index(ctx);
duk_push_hstring_stridx(ctx, DUK_STRIDX_NEWLINE_TAB);
duk_push_this(ctx);
duk_to_string(ctx, -1);
/* [ ... this tracedata sep ToString(this) ] */
/* FIXME: filename missing */
/* FIXME: native / C function */
/* FIXME: indicate truncated traceback */
if (duk_check_type(ctx, idx_td, DUK_TYPE_OBJECT)) {
int t;
for (i = 0; ; i += 2) {
int pc;
int line;
int flags;
double d;
duk_hobject *h;
duk_hbuffer_fixed *pc2line;
duk_require_stack(ctx, 5);
duk_get_prop_index(ctx, idx_td, i);
duk_get_prop_index(ctx, idx_td, i + 1);
d = duk_to_number(ctx, -1);
t = duk_get_type(ctx, -2);
if (t == DUK_TYPE_OBJECT) {
h = duk_get_hobject(ctx, -2);
DUK_ASSERT(h != NULL);
pc = (int) fmod(d, DUK_DOUBLE_2TO32);
flags = (int) floor(d / DUK_DOUBLE_2TO32);
duk_get_prop_stridx(ctx, -2, DUK_STRIDX_NAME);
duk_get_prop_stridx(ctx, -3, DUK_STRIDX_INT_FILENAME);
duk_get_prop_stridx(ctx, -4, DUK_STRIDX_INT_PC2LINE);
if (duk_is_buffer(ctx, -1)) {
pc2line = (duk_hbuffer_fixed *) duk_get_hbuffer(ctx, -1);
DUK_ASSERT(!DUK_HBUFFER_HAS_DYNAMIC(pc2line));
line = duk_hobject_pc2line_query(pc2line, pc);
} else {
line = 0;
}
duk_pop(ctx);
if (DUK_HOBJECT_HAS_NATIVEFUNCTION(h)) {
duk_push_sprintf(ctx, "%s %s native%s%s%s",
duk_get_string(ctx, -2), duk_get_string(ctx, -1),
(flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty,
(flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcalled : str_empty,
(flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty);
} else {
duk_push_sprintf(ctx, "%s %s:%d%s%s%s",
duk_get_string(ctx, -2), duk_get_string(ctx, -1), line,
(flags & DUK_ACT_FLAG_STRICT) ? str_strict : str_empty,
(flags & DUK_ACT_FLAG_TAILCALLED) ? str_tailcalled : str_empty,
(flags & DUK_ACT_FLAG_CONSTRUCT) ? str_construct : str_empty);
}
duk_replace(ctx, -5); /* [ ... v1 v2 name filename str ] -> [ ... str v2 name filename ] */
duk_pop_n(ctx, 3); /* -> [ ... str ] */
} else if (t == DUK_TYPE_STRING) {
duk_push_sprintf(ctx, "%s:%d",
duk_get_string(ctx, -2), (int) d);
duk_replace(ctx, -3); /* [ ... v1 v2 str ] -> [ ... str v2 ] */
duk_pop(ctx); /* -> [ ... str ] */
} else {
duk_pop_2(ctx);
break;
}
}
}
/* [ ... this tracedata sep ToString(this) str1 ... strN ] */
duk_join(ctx, duk_get_top(ctx) - (idx_td + 2) /*count, not including sep*/);
return 1;
}

1
src/duk_builtin_protos.h

@ -101,6 +101,7 @@ int duk_builtin_duk_object_sleep(duk_context *ctx);
int duk_builtin_error_constructor(duk_context *ctx);
int duk_builtin_error_prototype_to_string(duk_context *ctx);
int duk_builtin_error_prototype_stack(duk_context *ctx); /* FIXME: placeholder */
int duk_builtin_eval_error_constructor(duk_context *ctx);
int duk_builtin_range_error_constructor(duk_context *ctx);
int duk_builtin_reference_error_constructor(duk_context *ctx);

5
src/genbuiltins.py

@ -770,12 +770,13 @@ bi_error_prototype = {
# Custom properties
{ 'name': 'stack', 'value': '' },
# FIXME: custom properties
# FIXME: stack getter/setter
],
'functions': [
{ 'name': 'toString', 'native': 'duk_builtin_error_prototype_to_string', 'length': 0 },
# FIXME: placeholder
{ 'name': 'stack', 'native': 'duk_builtin_error_prototype_stack', 'length': 0 },
],
}

2
src/genstrings.py

@ -451,6 +451,7 @@ standard_other_string_list = [
mkstr("", class_name=True), # used as a class name for unused/invalid class
mkstr(","), # for array joining
mkstr(" "), # for print()
mkstr("\n\t"), # for tracebacks
mkstr("Invalid Date"), # for invalid Date instances
# arguments object (E5 Section 10.6)
mkstr("arguments"),
@ -710,6 +711,7 @@ special_define_names = {
'': 'EMPTY_STRING',
',': 'COMMA',
' ': 'SPACE',
'\n\t': 'NEWLINE_TAB',
'{"_undefined":true}': 'JSON_EXT_UNDEFINED',
'{"_nan":true}': 'JSON_EXT_NAN',

Loading…
Cancel
Save