Make RUNTIME_ASSERT have more useful output in debug mode
Runtime asserts are were previously a bit annoying to debug, due to the lack of a useful error message, even in debug mode. This patch prints out some more information in debug mode for runtime assert failures while preserving their exception-throwing semantics. While we're at it, it requires a semicolon after RUNTIME_ASSERT macro invocations. ``` $ rlwrap out/Debug/d8 --allow-natives-syntax V8 version 5.1.0 (candidate) d8> %ArrayBufferNeuter(1) # # Runtime error in ../../src/runtime/runtime-typedarray.cc, line 52 # # args[0]->IsJSArrayBuffer() ==== C stack trace =============================== 1: 0xf70ab5 2: 0xadeebf 3: 0xadedd4 4: 0x2ef17630693b (d8):1: illegal access %ArrayBufferNeuter(1) ^ d8> ``` Also give the other 'illegal access' case (a special SyntaxError type) a more descriptive error message for its sole usage. R=adamk Review URL: https://codereview.chromium.org/1748183002 Cr-Commit-Position: refs/heads/master@{#34401}
This commit is contained in:
parent
503d589340
commit
78d845308f
@ -115,3 +115,14 @@ extern "C" void V8_Fatal(const char* file, int line, const char* format, ...) {
|
||||
fflush(stderr);
|
||||
v8::base::OS::Abort();
|
||||
}
|
||||
|
||||
extern "C" void V8_RuntimeError(const char* file, int line,
|
||||
const char* message) {
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
v8::base::OS::PrintError("\n\n#\n# Runtime error in %s, line %d\n# ", file,
|
||||
line);
|
||||
v8::base::OS::PrintError("\n# %s\n", message);
|
||||
v8::base::DumpBacktrace();
|
||||
fflush(stderr);
|
||||
}
|
||||
|
@ -14,6 +14,8 @@
|
||||
extern "C" V8_NORETURN void V8_Fatal(const char* file, int line,
|
||||
const char* format, ...);
|
||||
|
||||
extern "C" void V8_RuntimeError(const char* file, int line,
|
||||
const char* message);
|
||||
|
||||
// The FATAL, UNREACHABLE and UNIMPLEMENTED macros are useful during
|
||||
// development, but they should not be relied on in the final product.
|
||||
|
@ -379,7 +379,6 @@ class CallSite {
|
||||
"% loop variable declaration may not have an initializer.") \
|
||||
T(ForInOfLoopMultiBindings, \
|
||||
"Invalid left-hand side in % loop: Must have a single binding.") \
|
||||
T(IllegalAccess, "Illegal access") \
|
||||
T(IllegalBreak, "Illegal break statement") \
|
||||
T(IllegalContinue, "Illegal continue statement") \
|
||||
T(IllegalLanguageModeDirective, \
|
||||
@ -421,6 +420,7 @@ class CallSite {
|
||||
"Setter function argument must not be a rest parameter") \
|
||||
T(ParamDupe, "Duplicate parameter name not allowed in this context") \
|
||||
T(ParenthesisInArgString, "Function arg string contains parenthesis") \
|
||||
T(RuntimeWrongNumArgs, "Runtime function given wrong number of arguments") \
|
||||
T(SingleFunctionLiteral, "Single function literal required") \
|
||||
T(SloppyLexical, \
|
||||
"Block-scoped declarations (let, const, function, class) not yet " \
|
||||
|
@ -4993,7 +4993,7 @@ Expression* Parser::ParseV8Intrinsic(bool* ok) {
|
||||
|
||||
// Check that the expected number of arguments are being passed.
|
||||
if (function->nargs != -1 && function->nargs != args->length()) {
|
||||
ReportMessage(MessageTemplate::kIllegalAccess);
|
||||
ReportMessage(MessageTemplate::kRuntimeWrongNumArgs);
|
||||
*ok = false;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -317,7 +317,6 @@ RUNTIME_FUNCTION(Runtime_FormatMessageString) {
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
||||
#define CALLSITE_GET(NAME, RETURN) \
|
||||
RUNTIME_FUNCTION(Runtime_CallSite##NAME##RT) { \
|
||||
HandleScope scope(isolate); \
|
||||
@ -325,7 +324,7 @@ RUNTIME_FUNCTION(Runtime_FormatMessageString) {
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSObject, call_site_obj, 0); \
|
||||
Handle<String> result; \
|
||||
CallSite call_site(isolate, call_site_obj); \
|
||||
RUNTIME_ASSERT(call_site.IsValid()) \
|
||||
RUNTIME_ASSERT(call_site.IsValid()); \
|
||||
return RETURN(call_site.NAME(), isolate); \
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ RUNTIME_FUNCTION(Runtime_LiveEditPatchFunctionPositions) {
|
||||
DCHECK(args.length() == 2);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, shared_array, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSArray, position_change_array, 1);
|
||||
RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array))
|
||||
RUNTIME_ASSERT(SharedInfoWrapper::IsInstance(shared_array));
|
||||
|
||||
LiveEdit::PatchFunctionPositions(shared_array, position_change_array);
|
||||
return isolate->heap()->undefined_value();
|
||||
@ -207,8 +207,8 @@ RUNTIME_FUNCTION(Runtime_LiveEditCheckAndDropActivations) {
|
||||
USE(new_shared_array);
|
||||
RUNTIME_ASSERT(old_shared_array->length()->IsSmi());
|
||||
RUNTIME_ASSERT(new_shared_array->length() == old_shared_array->length());
|
||||
RUNTIME_ASSERT(old_shared_array->HasFastElements())
|
||||
RUNTIME_ASSERT(new_shared_array->HasFastElements())
|
||||
RUNTIME_ASSERT(old_shared_array->HasFastElements());
|
||||
RUNTIME_ASSERT(new_shared_array->HasFastElements());
|
||||
int array_length = Smi::cast(old_shared_array->length())->value();
|
||||
for (int i = 0; i < array_length; i++) {
|
||||
Handle<Object> old_element;
|
||||
|
@ -5,19 +5,49 @@
|
||||
#ifndef V8_RUNTIME_RUNTIME_UTILS_H_
|
||||
#define V8_RUNTIME_RUNTIME_UTILS_H_
|
||||
|
||||
#include "src/base/logging.h"
|
||||
#include "src/runtime/runtime.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
#define RUNTIME_ASSERT(value) \
|
||||
if (!(value)) return isolate->ThrowIllegalOperation();
|
||||
#ifdef DEBUG
|
||||
|
||||
#define RUNTIME_ASSERT(value) \
|
||||
do { \
|
||||
if (!(value)) { \
|
||||
V8_RuntimeError(__FILE__, __LINE__, #value); \
|
||||
return isolate->ThrowIllegalOperation(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RUNTIME_ASSERT_HANDLIFIED(value, T) \
|
||||
do { \
|
||||
if (!(value)) { \
|
||||
V8_RuntimeError(__FILE__, __LINE__, #value); \
|
||||
isolate->ThrowIllegalOperation(); \
|
||||
return MaybeHandle<T>(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
#define RUNTIME_ASSERT(value) \
|
||||
do { \
|
||||
if (!(value)) { \
|
||||
return isolate->ThrowIllegalOperation(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define RUNTIME_ASSERT_HANDLIFIED(value, T) \
|
||||
if (!(value)) { \
|
||||
isolate->ThrowIllegalOperation(); \
|
||||
return MaybeHandle<T>(); \
|
||||
}
|
||||
do { \
|
||||
if (!(value)) { \
|
||||
isolate->ThrowIllegalOperation(); \
|
||||
return MaybeHandle<T>(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
// Cast the given object to a value of the specified type and store
|
||||
// it in a variable with the given name. If the object is not of the
|
||||
|
Loading…
Reference in New Issue
Block a user