Support abort in the debugger. (#2273)
Aborts are not caught by catch/finally blocks, so it is possible to stop a script using the debugger. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -30,7 +30,7 @@
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (JERRY_DEBUGGER_MESSAGES_OUT_MAX_COUNT == 27
|
||||
&& JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT == 19
|
||||
&& JERRY_DEBUGGER_VERSION == 2,
|
||||
&& JERRY_DEBUGGER_VERSION == 3,
|
||||
debugger_version_correlates_to_message_type_count);
|
||||
|
||||
/**
|
||||
@@ -137,38 +137,51 @@ jerry_debugger_send_backtrace (uint8_t *recv_buffer_p) /**< pointer to the recei
|
||||
/**
|
||||
* Send result of evaluated expression or throw an error.
|
||||
*
|
||||
* @return true - if no error is occured
|
||||
* @return true - if execution should be resumed
|
||||
* false - otherwise
|
||||
*/
|
||||
static bool
|
||||
jerry_debugger_send_eval_or_throw (const lit_utf8_byte_t *eval_string_p, /**< evaluated string */
|
||||
size_t eval_string_size, /**< evaluated string size */
|
||||
bool *is_eval) /**< [in,out] throw or eval call */
|
||||
jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated string */
|
||||
size_t eval_string_size) /**< evaluated string size */
|
||||
{
|
||||
JERRY_ASSERT (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED);
|
||||
JERRY_ASSERT (!(JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_VM_IGNORE));
|
||||
|
||||
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
|
||||
ecma_value_t result = ecma_op_eval_chars_buffer (eval_string_p, eval_string_size, true, false);
|
||||
ecma_value_t result = ecma_op_eval_chars_buffer (eval_string_p + 1, eval_string_size - 1, true, false);
|
||||
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_IGNORE);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
if (!*is_eval)
|
||||
if (eval_string_p[0] != JERRY_DEBUGGER_EVAL_EVAL)
|
||||
{
|
||||
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_THROW_ERROR_FLAG);
|
||||
JERRY_CONTEXT (error_value) = result;
|
||||
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_STOP);
|
||||
|
||||
/* Stop where the error is caught. */
|
||||
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
|
||||
JERRY_CONTEXT (debugger_stop_context) = NULL;
|
||||
|
||||
if (eval_string_p[0] == JERRY_DEBUGGER_EVAL_THROW)
|
||||
{
|
||||
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ecma_value_t to_string_value = ecma_op_to_string (result);
|
||||
ecma_free_value (result);
|
||||
result = to_string_value;
|
||||
if (!ecma_is_value_string (result))
|
||||
{
|
||||
ecma_value_t to_string_value = ecma_op_to_string (result);
|
||||
ecma_free_value (result);
|
||||
result = to_string_value;
|
||||
}
|
||||
}
|
||||
|
||||
*is_eval = true;
|
||||
ecma_value_t message = result;
|
||||
uint8_t type = JERRY_DEBUGGER_EVAL_OK;
|
||||
|
||||
@@ -190,10 +203,11 @@ jerry_debugger_send_eval_or_throw (const lit_utf8_byte_t *eval_string_p, /**< ev
|
||||
ecma_free_value (result);
|
||||
|
||||
const lit_utf8_byte_t *string_p = lit_get_magic_string_utf8 (id);
|
||||
return jerry_debugger_send_string (JERRY_DEBUGGER_EVAL_RESULT,
|
||||
type,
|
||||
string_p,
|
||||
strlen ((const char *) string_p));
|
||||
jerry_debugger_send_string (JERRY_DEBUGGER_EVAL_RESULT,
|
||||
type,
|
||||
string_p,
|
||||
strlen ((const char *) string_p));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -209,13 +223,13 @@ jerry_debugger_send_eval_or_throw (const lit_utf8_byte_t *eval_string_p, /**< ev
|
||||
ecma_string_t *string_p = ecma_get_string_from_value (message);
|
||||
|
||||
ECMA_STRING_TO_UTF8_STRING (string_p, buffer_p, buffer_size);
|
||||
bool success = jerry_debugger_send_string (JERRY_DEBUGGER_EVAL_RESULT, type, buffer_p, buffer_size);
|
||||
jerry_debugger_send_string (JERRY_DEBUGGER_EVAL_RESULT, type, buffer_p, buffer_size);
|
||||
ECMA_FINALIZE_UTF8_STRING (buffer_p, buffer_size);
|
||||
|
||||
ecma_free_value (message);
|
||||
|
||||
return success;
|
||||
} /* jerry_debugger_send_eval_or_throw */
|
||||
return false;
|
||||
} /* jerry_debugger_send_eval */
|
||||
|
||||
/**
|
||||
* Suspend execution for a given time.
|
||||
@@ -264,7 +278,6 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
|
||||
if (*expected_message_type_p != 0)
|
||||
{
|
||||
JERRY_ASSERT (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART
|
||||
|| *expected_message_type_p == JERRY_DEBUGGER_THROW_PART
|
||||
|| *expected_message_type_p == JERRY_DEBUGGER_CLIENT_SOURCE_PART);
|
||||
|
||||
jerry_debugger_uint8_data_t *uint8_data_p = (jerry_debugger_uint8_data_t *) *message_data_p;
|
||||
@@ -310,20 +323,15 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
|
||||
return true;
|
||||
}
|
||||
|
||||
bool result = false;
|
||||
bool is_eval = true;
|
||||
bool result;
|
||||
|
||||
if (*expected_message_type_p == JERRY_DEBUGGER_EVAL_PART)
|
||||
{
|
||||
result = jerry_debugger_send_eval_or_throw (string_p, uint8_data_p->uint8_size, &is_eval);
|
||||
}
|
||||
else if (*expected_message_type_p == JERRY_DEBUGGER_THROW_PART)
|
||||
{
|
||||
is_eval = false;
|
||||
result = jerry_debugger_send_eval_or_throw (string_p, uint8_data_p->uint8_size, &is_eval);
|
||||
if (!is_eval)
|
||||
if (jerry_debugger_send_eval (string_p, uint8_data_p->uint8_size))
|
||||
{
|
||||
*resume_exec_p = true;
|
||||
}
|
||||
result = (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) != 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -520,7 +528,6 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
|
||||
}
|
||||
|
||||
case JERRY_DEBUGGER_EVAL:
|
||||
case JERRY_DEBUGGER_THROW:
|
||||
{
|
||||
if (message_size < sizeof (jerry_debugger_receive_eval_first_t) + 1)
|
||||
{
|
||||
@@ -533,7 +540,6 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
|
||||
|
||||
uint32_t eval_size;
|
||||
memcpy (&eval_size, eval_first_p->eval_size, sizeof (uint32_t));
|
||||
bool is_eval = (recv_buffer_p[0] == JERRY_DEBUGGER_EVAL);
|
||||
|
||||
if (eval_size <= JERRY_CONTEXT (debugger_max_receive_size) - sizeof (jerry_debugger_receive_eval_first_t))
|
||||
{
|
||||
@@ -543,13 +549,13 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
|
||||
jerry_debugger_close_connection ();
|
||||
return false;
|
||||
}
|
||||
bool ret_val = jerry_debugger_send_eval_or_throw ((lit_utf8_byte_t *) (eval_first_p + 1), eval_size, &is_eval);
|
||||
if (!is_eval)
|
||||
|
||||
if (jerry_debugger_send_eval ((lit_utf8_byte_t *) (eval_first_p + 1), eval_size))
|
||||
{
|
||||
*resume_exec_p = true;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
return (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED) != 0;
|
||||
}
|
||||
|
||||
jerry_debugger_uint8_data_t *eval_uint8_data_p;
|
||||
@@ -566,7 +572,7 @@ jerry_debugger_process_message (uint8_t *recv_buffer_p, /**< pointer to the rece
|
||||
message_size - sizeof (jerry_debugger_receive_eval_first_t));
|
||||
|
||||
*message_data_p = eval_uint8_data_p;
|
||||
*expected_message_type_p = is_eval ? JERRY_DEBUGGER_EVAL_PART : JERRY_DEBUGGER_THROW_PART;
|
||||
*expected_message_type_p = JERRY_DEBUGGER_EVAL_PART;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -703,7 +709,7 @@ jerry_debugger_breakpoint_hit (uint8_t message_type) /**< message type */
|
||||
return;
|
||||
}
|
||||
|
||||
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_BREAKPOINT_MODE);
|
||||
JERRY_DEBUGGER_UPDATE_FLAGS (JERRY_DEBUGGER_BREAKPOINT_MODE, JERRY_DEBUGGER_THROW_ERROR_FLAG);
|
||||
|
||||
jerry_debugger_uint8_data_t *uint8_data = NULL;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
/**
|
||||
* JerryScript debugger protocol version.
|
||||
*/
|
||||
#define JERRY_DEBUGGER_VERSION (2)
|
||||
#define JERRY_DEBUGGER_VERSION (3)
|
||||
|
||||
/**
|
||||
* Frequency of calling jerry_debugger_receive() by the VM.
|
||||
@@ -193,22 +193,30 @@ typedef enum
|
||||
JERRY_DEBUGGER_EVAL_PART = 18, /**< next message of evaluating a string */
|
||||
|
||||
JERRY_DEBUGGER_MESSAGES_IN_MAX_COUNT, /**< number of different type of input messages */
|
||||
JERRY_DEBUGGER_THROW = 19, /**< first message of the throw string */
|
||||
JERRY_DEBUGGER_THROW_PART = 20, /**< next part of the throw message */
|
||||
} jerry_debugger_header_type_t;
|
||||
|
||||
/**
|
||||
* Subtypes of eval_result.
|
||||
*/
|
||||
* Subtypes of eval.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_DEBUGGER_EVAL_EVAL = 0, /**< evaluate expression */
|
||||
JERRY_DEBUGGER_EVAL_THROW = 1, /**< evaluate expression and throw the result */
|
||||
JERRY_DEBUGGER_EVAL_ABORT = 2, /**< evaluate expression and abrot with the result */
|
||||
} jerry_debugger_eval_type_t;
|
||||
|
||||
/**
|
||||
* Subtypes of eval_result.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_DEBUGGER_EVAL_OK = 1, /**< eval result, no error */
|
||||
JERRY_DEBUGGER_EVAL_ERROR = 2, /**< eval result when an error has occurred */
|
||||
} jerry_debugger_eval_subtype_t;
|
||||
} jerry_debugger_eval_result_type_t;
|
||||
|
||||
/**
|
||||
* Subtypes of output_result.
|
||||
*/
|
||||
* Subtypes of output_result.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
JERRY_DEBUGGER_OUTPUT_OK = 1, /**< output result, no error */
|
||||
|
||||
+10
-4
@@ -2532,7 +2532,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT);
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_THROW_ERROR_FLAG)
|
||||
{
|
||||
result = JERRY_CONTEXT (error_value);
|
||||
result = ECMA_VALUE_ERROR;
|
||||
goto error;
|
||||
}
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
@@ -2559,7 +2559,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT);
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_THROW_ERROR_FLAG)
|
||||
{
|
||||
result = JERRY_CONTEXT (error_value);
|
||||
result = ECMA_VALUE_ERROR;
|
||||
goto error;
|
||||
}
|
||||
continue;
|
||||
@@ -2585,7 +2585,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_BREAKPOINT_HIT);
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_THROW_ERROR_FLAG)
|
||||
{
|
||||
result = JERRY_CONTEXT (error_value);
|
||||
result = ECMA_VALUE_ERROR;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -2723,16 +2723,22 @@ error:
|
||||
|
||||
stack_top_p = frame_ctx_p->registers_p + register_end + frame_ctx_p->context_depth;
|
||||
#ifdef JERRY_DEBUGGER
|
||||
const uint32_t dont_stop = (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION
|
||||
| JERRY_DEBUGGER_VM_IGNORE
|
||||
| JERRY_DEBUGGER_THROW_ERROR_FLAG);
|
||||
|
||||
if ((JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||
&& !(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE)
|
||||
&& !(JERRY_CONTEXT (debugger_flags) & (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION | JERRY_DEBUGGER_VM_IGNORE)))
|
||||
&& !(JERRY_CONTEXT (debugger_flags) & dont_stop))
|
||||
{
|
||||
/* Save the error to a local value, because the engine enters breakpoint mode after,
|
||||
therefore an evaluation error, or user-created error throw would overwrite it. */
|
||||
ecma_value_t current_error_value = JERRY_CONTEXT (error_value);
|
||||
|
||||
if (jerry_debugger_send_exception_string ())
|
||||
{
|
||||
jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_EXCEPTION_HIT);
|
||||
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_THROW_ERROR_FLAG)
|
||||
{
|
||||
ecma_free_value (current_error_value);
|
||||
|
||||
@@ -36,7 +36,7 @@ textarea {
|
||||
</div>
|
||||
<script>
|
||||
// Expected JerryScript debugger protocol version
|
||||
var JERRY_DEBUGGER_VERSION = 2;
|
||||
var JERRY_DEBUGGER_VERSION = 3;
|
||||
|
||||
// Messages sent by the server to client.
|
||||
var JERRY_DEBUGGER_CONFIGURATION = 1;
|
||||
@@ -67,6 +67,11 @@ var JERRY_DEBUGGER_OUTPUT_RESULT = 25;
|
||||
var JERRY_DEBUGGER_OUTPUT_RESULT_END = 26;
|
||||
|
||||
// Subtypes of eval
|
||||
JERRY_DEBUGGER_EVAL_EVAL = "\0"
|
||||
JERRY_DEBUGGER_EVAL_THROW = "\1"
|
||||
JERRY_DEBUGGER_EVAL_ABORT = "\2"
|
||||
|
||||
// Subtypes of eval result
|
||||
var JERRY_DEBUGGER_EVAL_OK = 1;
|
||||
var JERRY_DEBUGGER_EVAL_ERROR = 2;
|
||||
|
||||
@@ -1220,7 +1225,7 @@ function DebuggerClient(address)
|
||||
return;
|
||||
}
|
||||
|
||||
var array = stringToCesu8(str);
|
||||
var array = stringToCesu8(JERRY_DEBUGGER_EVAL_EVAL + str);
|
||||
var byteLength = array.byteLength;
|
||||
|
||||
if (byteLength <= maxMessageSize)
|
||||
|
||||
@@ -28,7 +28,7 @@ import math
|
||||
import time
|
||||
|
||||
# Expected debugger protocol version.
|
||||
JERRY_DEBUGGER_VERSION = 2
|
||||
JERRY_DEBUGGER_VERSION = 3
|
||||
|
||||
# Messages sent by the server to client.
|
||||
JERRY_DEBUGGER_CONFIGURATION = 1
|
||||
@@ -59,6 +59,11 @@ JERRY_DEBUGGER_OUTPUT_RESULT = 25
|
||||
JERRY_DEBUGGER_OUTPUT_RESULT_END = 26
|
||||
|
||||
# Subtypes of eval
|
||||
JERRY_DEBUGGER_EVAL_EVAL = "\0"
|
||||
JERRY_DEBUGGER_EVAL_THROW = "\1"
|
||||
JERRY_DEBUGGER_EVAL_ABORT = "\2"
|
||||
|
||||
# Subtypes of eval result
|
||||
JERRY_DEBUGGER_EVAL_OK = 1
|
||||
JERRY_DEBUGGER_EVAL_ERROR = 2
|
||||
|
||||
@@ -89,8 +94,6 @@ JERRY_DEBUGGER_FINISH = 15
|
||||
JERRY_DEBUGGER_GET_BACKTRACE = 16
|
||||
JERRY_DEBUGGER_EVAL = 17
|
||||
JERRY_DEBUGGER_EVAL_PART = 18
|
||||
JERRY_DEBUGGER_THROW = 19
|
||||
JERRY_DEBUGGER_THROW_PART = 20
|
||||
|
||||
MAX_BUFFER_SIZE = 128
|
||||
WEBSOCKET_BINARY_FRAME = 2
|
||||
@@ -426,8 +429,6 @@ class DebuggerPrompt(Cmd):
|
||||
|
||||
def _send_string(self, args, message_type):
|
||||
size = len(args)
|
||||
if size == 0:
|
||||
return
|
||||
|
||||
# 1: length of type byte
|
||||
# 4: length of an uint32 value
|
||||
@@ -451,8 +452,6 @@ class DebuggerPrompt(Cmd):
|
||||
|
||||
if message_type == JERRY_DEBUGGER_EVAL:
|
||||
message_type = JERRY_DEBUGGER_EVAL_PART
|
||||
elif message_type == JERRY_DEBUGGER_THROW:
|
||||
message_type = JERRY_DEBUGGER_THROW_PART
|
||||
else:
|
||||
message_type = JERRY_DEBUGGER_CLIENT_SOURCE_PART
|
||||
|
||||
@@ -477,13 +476,17 @@ class DebuggerPrompt(Cmd):
|
||||
|
||||
def do_eval(self, args):
|
||||
""" Evaluate JavaScript source code """
|
||||
self._send_string(args, JERRY_DEBUGGER_EVAL)
|
||||
self._send_string(JERRY_DEBUGGER_EVAL_EVAL + args, JERRY_DEBUGGER_EVAL)
|
||||
|
||||
do_e = do_eval
|
||||
|
||||
def do_throw(self, args):
|
||||
""" Throw an exception """
|
||||
self._send_string(args, JERRY_DEBUGGER_THROW)
|
||||
self._send_string(JERRY_DEBUGGER_EVAL_THROW + args, JERRY_DEBUGGER_EVAL)
|
||||
|
||||
def do_abort(self, args):
|
||||
""" Throw an exception """
|
||||
self._send_string(JERRY_DEBUGGER_EVAL_ABORT + args, JERRY_DEBUGGER_EVAL)
|
||||
|
||||
def do_exception(self, args):
|
||||
""" Config the exception handler module """
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
s
|
||||
s
|
||||
s
|
||||
s
|
||||
abort new Error('Fatal error :)')
|
||||
@@ -0,0 +1,12 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/do_abort.js:24
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_abort.js:25
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_abort.js:26
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_abort.js:20 (in g() at line:19, col:1)
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_abort.js:16 (in f() at line:15, col:1)
|
||||
(jerry-debugger) abort new Error('Fatal error :)')
|
||||
err: Script Error: Error: Fatal error :)
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright JS Foundation and other contributors, http://js.foundation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
function f() {
|
||||
return 32;
|
||||
}
|
||||
|
||||
function g() {
|
||||
f();
|
||||
}
|
||||
|
||||
// In regular JS, it is not possible to escape from this loop
|
||||
while (true) {
|
||||
try {
|
||||
g();
|
||||
} catch (e) {
|
||||
var s = "Don't stop here";
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,9 @@ Stopped at tests/debugger/do_help.js:15
|
||||
|
||||
Documented commands (type help <topic>):
|
||||
========================================
|
||||
b bt delete e f list n s src
|
||||
backtrace c display eval finish memstats next scroll step
|
||||
break continue dump exception help ms quit source throw
|
||||
abort bt display exception list next source
|
||||
b c dump f memstats quit src
|
||||
backtrace continue e finish ms s step
|
||||
break delete eval help n scroll throw
|
||||
|
||||
(jerry-debugger) quit
|
||||
|
||||
@@ -1 +1,9 @@
|
||||
s
|
||||
s
|
||||
s
|
||||
s
|
||||
s
|
||||
throw new Error('Escape')
|
||||
throw new Error('Once upon a time there lived in a certain village a little country girl, the prettiest creature who was ever seen. Her mother was excessively fond of her; and her grandmother doted on her still more. This good woman had a little red riding hood made for her. It suited the girl so extremely well that everybody called her Little Red Riding Hood. One day her mother, having made some cakes, said to her, "Go, my dear, and see how your grandmother is doing, for I hear she has been very ill. Take her a cake, and this little pot of butter."')
|
||||
eval e.message.length
|
||||
throw new Error('Exit')
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
Connecting to: localhost:5001
|
||||
Stopped at tests/debugger/do_throw.js:19
|
||||
Stopped at tests/debugger/do_throw.js:23
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_throw.js:24
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_throw.js:26
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_throw.js:27
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_throw.js:20 (in g() at line:19, col:1)
|
||||
(jerry-debugger) s
|
||||
Stopped at tests/debugger/do_throw.js:16 (in f() at line:15, col:1)
|
||||
(jerry-debugger) throw new Error('Escape')
|
||||
Stopped at tests/debugger/do_throw.js:31
|
||||
(jerry-debugger) throw new Error('Once upon a time there lived in a certain village a little country girl, the prettiest creature who was ever seen. Her mother was excessively fond of her; and her grandmother doted on her still more. This good woman had a little red riding hood made for her. It suited the girl so extremely well that everybody called her Little Red Riding Hood. One day her mother, having made some cakes, said to her, "Go, my dear, and see how your grandmother is doing, for I hear she has been very ill. Take her a cake, and this little pot of butter."')
|
||||
Stopped at tests/debugger/do_throw.js:34
|
||||
(jerry-debugger) eval e.message.length
|
||||
538
|
||||
(jerry-debugger) throw new Error('Exit')
|
||||
err: Script Error: Error: Exit
|
||||
|
||||
@@ -12,8 +12,24 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
function inevitable() {
|
||||
print("An error will be thrown.");
|
||||
function f() {
|
||||
return 32;
|
||||
}
|
||||
|
||||
inevitable();
|
||||
function g() {
|
||||
f();
|
||||
}
|
||||
|
||||
try {
|
||||
try {
|
||||
|
||||
while (true) {
|
||||
g();
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
var s = "Stop here";
|
||||
}
|
||||
} catch (e) {
|
||||
var s = "Stop here again";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user