mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Support this binding retrieval for backtrace frames (#4669)
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
parent
a67f198134
commit
67a61bc211
@ -10606,6 +10606,7 @@ main (void)
|
|||||||
- [jerry_backtrace_get_frame_type](#jerry_backtrace_get_frame_type)
|
- [jerry_backtrace_get_frame_type](#jerry_backtrace_get_frame_type)
|
||||||
- [jerry_backtrace_get_location](#jerry_backtrace_get_location)
|
- [jerry_backtrace_get_location](#jerry_backtrace_get_location)
|
||||||
- [jerry_backtrace_get_function](#jerry_backtrace_get_function)
|
- [jerry_backtrace_get_function](#jerry_backtrace_get_function)
|
||||||
|
- [jerry_backtrace_get_this](#jerry_backtrace_get_this)
|
||||||
- [jerry_backtrace_is_strict](#jerry_backtrace_is_strict)
|
- [jerry_backtrace_is_strict](#jerry_backtrace_is_strict)
|
||||||
|
|
||||||
|
|
||||||
@ -10785,6 +10786,63 @@ backtrace_callback (jerry_backtrace_frame_t *frame_p,
|
|||||||
- [jerry_backtrace_capture](#jerry_backtrace_capture)
|
- [jerry_backtrace_capture](#jerry_backtrace_capture)
|
||||||
|
|
||||||
|
|
||||||
|
## jerry_backtrace_get_this
|
||||||
|
|
||||||
|
**Summary**
|
||||||
|
|
||||||
|
Initialize and return with the 'this' binding private field of a backtrace frame.
|
||||||
|
The 'this' binding is a hidden value passed to the called function. As for arrow
|
||||||
|
functions, the 'this' binding is assigned at function creation. This getter
|
||||||
|
function can only be called from the callback function of
|
||||||
|
[jerry_backtrace_capture](#jerry_backtrace_capture), and the value becomes invalid
|
||||||
|
after the callback returns.
|
||||||
|
|
||||||
|
*Notes*:
|
||||||
|
- The returned data must not be modified, and does not need to be freed.
|
||||||
|
Any cleanup is done automatically after the callback is returned.
|
||||||
|
|
||||||
|
**Prototype**
|
||||||
|
|
||||||
|
```c
|
||||||
|
const jerry_value_t *
|
||||||
|
jerry_backtrace_get_this (jerry_backtrace_frame_t *frame_p);
|
||||||
|
```
|
||||||
|
|
||||||
|
- `frame_p` - a frame passed to the [jerry_backtrace_callback_t](#jerry_backtrace_callback_t) callback
|
||||||
|
- return value
|
||||||
|
- pointer to the 'this' binding if the binding is available,
|
||||||
|
- NULL otherwise
|
||||||
|
|
||||||
|
*New in version [[NEXT_RELEASE]]*.
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
|
||||||
|
See the example of [jerry_backtrace_capture](#jerry_backtrace_capture)
|
||||||
|
with the following callback function:
|
||||||
|
|
||||||
|
```c
|
||||||
|
static bool
|
||||||
|
backtrace_callback (jerry_backtrace_frame_t *frame_p,
|
||||||
|
void *user_p)
|
||||||
|
{
|
||||||
|
jerry_value_t *this_p = jerry_backtrace_get_this (frame_p);
|
||||||
|
|
||||||
|
if (this_p != NULL)
|
||||||
|
{
|
||||||
|
printf ("The 'this' binding is available");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("The 'this' binding is NOT available");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**See also**
|
||||||
|
|
||||||
|
- [jerry_backtrace_capture](#jerry_backtrace_capture)
|
||||||
|
|
||||||
|
|
||||||
## jerry_backtrace_is_strict
|
## jerry_backtrace_is_strict
|
||||||
|
|
||||||
**Summary**
|
**Summary**
|
||||||
|
|||||||
@ -5276,6 +5276,26 @@ jerry_backtrace_get_function (jerry_backtrace_frame_t *frame_p) /**< frame point
|
|||||||
return NULL;
|
return NULL;
|
||||||
} /* jerry_backtrace_get_function */
|
} /* jerry_backtrace_get_function */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize and return with the 'this' binding private field of a backtrace frame.
|
||||||
|
* The 'this' binding is a hidden value passed to the called function. As for arrow
|
||||||
|
* functions, the 'this' binding is assigned at function creation.
|
||||||
|
*
|
||||||
|
* @return pointer to the 'this' binding - if the binding is available,
|
||||||
|
* NULL - otherwise
|
||||||
|
*/
|
||||||
|
const jerry_value_t *
|
||||||
|
jerry_backtrace_get_this (jerry_backtrace_frame_t *frame_p) /**< frame pointer */
|
||||||
|
{
|
||||||
|
if (frame_p->frame_type == JERRY_BACKTRACE_FRAME_JS)
|
||||||
|
{
|
||||||
|
frame_p->this_binding = frame_p->context_p->this_binding;
|
||||||
|
return &frame_p->this_binding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
} /* jerry_backtrace_get_this */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true, if the code bound to the backtrace frame is strict mode code.
|
* Returns true, if the code bound to the backtrace frame is strict mode code.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -350,6 +350,7 @@ void jerry_backtrace_capture (jerry_backtrace_callback_t callback, void *user_p)
|
|||||||
jerry_backtrace_frame_types_t jerry_backtrace_get_frame_type (jerry_backtrace_frame_t *frame_p);
|
jerry_backtrace_frame_types_t jerry_backtrace_get_frame_type (jerry_backtrace_frame_t *frame_p);
|
||||||
const jerry_backtrace_location_t *jerry_backtrace_get_location (jerry_backtrace_frame_t *frame_p);
|
const jerry_backtrace_location_t *jerry_backtrace_get_location (jerry_backtrace_frame_t *frame_p);
|
||||||
const jerry_value_t *jerry_backtrace_get_function (jerry_backtrace_frame_t *frame_p);
|
const jerry_value_t *jerry_backtrace_get_function (jerry_backtrace_frame_t *frame_p);
|
||||||
|
const jerry_value_t *jerry_backtrace_get_this (jerry_backtrace_frame_t *frame_p);
|
||||||
bool jerry_backtrace_is_strict (jerry_backtrace_frame_t *frame_p);
|
bool jerry_backtrace_is_strict (jerry_backtrace_frame_t *frame_p);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -157,6 +157,7 @@ struct jerry_backtrace_frame_internal_t
|
|||||||
uint8_t frame_type; /**< frame type */
|
uint8_t frame_type; /**< frame type */
|
||||||
jerry_backtrace_location_t location; /**< location information */
|
jerry_backtrace_location_t location; /**< location information */
|
||||||
ecma_value_t function; /**< function reference */
|
ecma_value_t function; /**< function reference */
|
||||||
|
ecma_value_t this_binding; /**< this binding passed to the function */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -61,9 +61,11 @@ backtrace_callback (jerry_backtrace_frame_t *frame_p, /* frame information */
|
|||||||
|
|
||||||
const jerry_backtrace_location_t *location_p = jerry_backtrace_get_location (frame_p);
|
const jerry_backtrace_location_t *location_p = jerry_backtrace_get_location (frame_p);
|
||||||
const jerry_value_t *function_p = jerry_backtrace_get_function (frame_p);
|
const jerry_value_t *function_p = jerry_backtrace_get_function (frame_p);
|
||||||
|
const jerry_value_t *this_p = jerry_backtrace_get_this (frame_p);
|
||||||
|
|
||||||
TEST_ASSERT (location_p != NULL);
|
TEST_ASSERT (location_p != NULL);
|
||||||
TEST_ASSERT (function_p != NULL);
|
TEST_ASSERT (function_p != NULL);
|
||||||
|
TEST_ASSERT (this_p != NULL);
|
||||||
|
|
||||||
compare_string (location_p->resource_name, "capture_test.js");
|
compare_string (location_p->resource_name, "capture_test.js");
|
||||||
|
|
||||||
@ -75,6 +77,7 @@ backtrace_callback (jerry_backtrace_frame_t *frame_p, /* frame information */
|
|||||||
TEST_ASSERT (location_p->line == 2);
|
TEST_ASSERT (location_p->line == 2);
|
||||||
TEST_ASSERT (location_p->column == 1);
|
TEST_ASSERT (location_p->column == 1);
|
||||||
TEST_ASSERT (handler_args_p[0] == *function_p);
|
TEST_ASSERT (handler_args_p[0] == *function_p);
|
||||||
|
TEST_ASSERT (handler_args_p[1] == *this_p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,15 +86,21 @@ backtrace_callback (jerry_backtrace_frame_t *frame_p, /* frame information */
|
|||||||
TEST_ASSERT (jerry_backtrace_is_strict (frame_p));
|
TEST_ASSERT (jerry_backtrace_is_strict (frame_p));
|
||||||
TEST_ASSERT (location_p->line == 7);
|
TEST_ASSERT (location_p->line == 7);
|
||||||
TEST_ASSERT (location_p->column == 1);
|
TEST_ASSERT (location_p->column == 1);
|
||||||
TEST_ASSERT (handler_args_p[1] == *function_p);
|
TEST_ASSERT (handler_args_p[2] == *function_p);
|
||||||
|
TEST_ASSERT (jerry_value_is_undefined (*this_p));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jerry_value_t global = jerry_get_global_object ();
|
||||||
|
|
||||||
TEST_ASSERT (frame_index == 3);
|
TEST_ASSERT (frame_index == 3);
|
||||||
TEST_ASSERT (!jerry_backtrace_is_strict (frame_p));
|
TEST_ASSERT (!jerry_backtrace_is_strict (frame_p));
|
||||||
TEST_ASSERT (location_p->line == 11);
|
TEST_ASSERT (location_p->line == 11);
|
||||||
TEST_ASSERT (location_p->column == 1);
|
TEST_ASSERT (location_p->column == 1);
|
||||||
TEST_ASSERT (handler_args_p[2] == *function_p);
|
TEST_ASSERT (handler_args_p[3] == *function_p);
|
||||||
|
TEST_ASSERT (global == *this_p);
|
||||||
|
|
||||||
|
jerry_release_value (global);
|
||||||
return false;
|
return false;
|
||||||
} /* backtrace_callback */
|
} /* backtrace_callback */
|
||||||
|
|
||||||
@ -170,7 +179,7 @@ capture_handler (const jerry_call_info_t *call_info_p, /**< call information */
|
|||||||
JERRY_UNUSED (args_p);
|
JERRY_UNUSED (args_p);
|
||||||
JERRY_UNUSED (args_count);
|
JERRY_UNUSED (args_count);
|
||||||
|
|
||||||
TEST_ASSERT (args_count == 0 || args_count == 2 || args_count == 3);
|
TEST_ASSERT (args_count == 0 || args_count == 2 || args_count == 4);
|
||||||
TEST_ASSERT (args_count == 0 || frame_index == 0);
|
TEST_ASSERT (args_count == 0 || frame_index == 0);
|
||||||
|
|
||||||
jerry_backtrace_callback_t callback = backtrace_callback;
|
jerry_backtrace_callback_t callback = backtrace_callback;
|
||||||
@ -187,7 +196,7 @@ capture_handler (const jerry_call_info_t *call_info_p, /**< call information */
|
|||||||
handler_args_p = args_p;
|
handler_args_p = args_p;
|
||||||
jerry_backtrace_capture (callback, (void *) args_p);
|
jerry_backtrace_capture (callback, (void *) args_p);
|
||||||
|
|
||||||
TEST_ASSERT (args_count == 0 || frame_index == (int) args_count);
|
TEST_ASSERT (args_count == 0 || frame_index == (args_count == 4 ? 3 : 2));
|
||||||
|
|
||||||
return jerry_create_undefined ();
|
return jerry_create_undefined ();
|
||||||
} /* capture_handler */
|
} /* capture_handler */
|
||||||
@ -323,13 +332,13 @@ test_get_backtrace_api_call (void)
|
|||||||
/* Test frame capturing. */
|
/* Test frame capturing. */
|
||||||
|
|
||||||
frame_index = 0;
|
frame_index = 0;
|
||||||
source_p = ("function f() {\n"
|
source_p = ("var o = { f:function() {\n"
|
||||||
" return capture(f, g, h);\n"
|
" return capture(o.f, o, g, h);\n"
|
||||||
"}\n"
|
"} }\n"
|
||||||
"\n"
|
"\n"
|
||||||
"function g() {\n"
|
"function g() {\n"
|
||||||
" 'use strict';\n"
|
" 'use strict';\n"
|
||||||
" return f();\n"
|
" return o.f();\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"\n"
|
"\n"
|
||||||
"function h() {\n"
|
"function h() {\n"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user