From 77e37028c6cad6cc31de975d392e2f820b608ec4 Mon Sep 17 00:00:00 2001 From: yangguo Date: Mon, 27 Apr 2015 05:33:58 -0700 Subject: [PATCH] Wrap messages implementation in a function. R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/1106633002 Cr-Commit-Position: refs/heads/master@{#28074} --- src/api.cc | 18 +-- src/bootstrapper.cc | 6 +- src/heap/heap.h | 2 +- src/messages.cc | 2 +- src/messages.js | 297 +++++++++++++++++++++++++------------------- src/mirror-debugger.js | 2 +- test/cctest/test-parsing.cc | 5 +- tools/js2c.py | 5 +- 8 files changed, 189 insertions(+), 148 deletions(-) diff --git a/src/api.cc b/src/api.cc index 3a89095..a811404 100644 --- a/src/api.cc +++ b/src/api.cc @@ -2271,8 +2271,8 @@ Maybe Message::GetLineNumber(Local context) const { PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetLineNumber()", int); i::Handle result; has_pending_exception = - !CallV8HeapFunction(isolate, "GetLineNumber", Utils::OpenHandle(this)) - .ToHandle(&result); + !CallV8HeapFunction(isolate, "$messageGetLineNumber", + Utils::OpenHandle(this)).ToHandle(&result); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int); return Just(static_cast(result->Number())); } @@ -2301,8 +2301,9 @@ Maybe Message::GetStartColumn(Local context) const { int); auto self = Utils::OpenHandle(this); i::Handle start_col_obj; - has_pending_exception = !CallV8HeapFunction(isolate, "GetPositionInLine", - self).ToHandle(&start_col_obj); + has_pending_exception = + !CallV8HeapFunction(isolate, "$messageGetPositionInLine", self) + .ToHandle(&start_col_obj); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int); return Just(static_cast(start_col_obj->Number())); } @@ -2319,8 +2320,9 @@ Maybe Message::GetEndColumn(Local context) const { PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Message::GetEndColumn()", int); auto self = Utils::OpenHandle(this); i::Handle start_col_obj; - has_pending_exception = !CallV8HeapFunction(isolate, "GetPositionInLine", - self).ToHandle(&start_col_obj); + has_pending_exception = + !CallV8HeapFunction(isolate, "$messageGetPositionInLine", self) + .ToHandle(&start_col_obj); RETURN_ON_FAILED_EXECUTION_PRIMITIVE(int); int start = self->start_position(); int end = self->end_position(); @@ -2349,8 +2351,8 @@ MaybeLocal Message::GetSourceLine(Local context) const { PREPARE_FOR_EXECUTION(context, "v8::Message::GetSourceLine()", String); i::Handle result; has_pending_exception = - !CallV8HeapFunction(isolate, "GetSourceLine", Utils::OpenHandle(this)) - .ToHandle(&result); + !CallV8HeapFunction(isolate, "$messageGetSourceLine", + Utils::OpenHandle(this)).ToHandle(&result); RETURN_ON_FAILED_EXECUTION(String); Local str; if (result->IsString()) { diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 1fbbcb9..555080f 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1544,7 +1544,7 @@ void Genesis::InstallNativeFunctions() { INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun); INSTALL_NATIVE(JSFunction, "ToString", to_string_fun); - INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun); + INSTALL_NATIVE(JSFunction, "$toDetailString", to_detail_string_fun); INSTALL_NATIVE(JSFunction, "ToObject", to_object_fun); INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun); INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun); @@ -1552,7 +1552,7 @@ void Genesis::InstallNativeFunctions() { INSTALL_NATIVE(JSFunction, "ToLength", to_length_fun); INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun); - INSTALL_NATIVE(JSFunction, "GetStackTraceLine", get_stack_trace_line_fun); + INSTALL_NATIVE(JSFunction, "$getStackTraceLine", get_stack_trace_line_fun); INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor", to_complete_property_descriptor); @@ -2475,7 +2475,7 @@ bool Genesis::InstallSpecialObjects(Handle native_context) { JSObject::SetOwnPropertyIgnoreAttributes( handle(native_context->builtins(), isolate), factory->InternalizeOneByteString( - STATIC_CHAR_VECTOR("stack_trace_symbol")), + STATIC_CHAR_VECTOR("$stackTraceSymbol")), factory->stack_trace_symbol(), NONE), false); diff --git a/src/heap/heap.h b/src/heap/heap.h index dcf7bde..06f9304 100644 --- a/src/heap/heap.h +++ b/src/heap/heap.h @@ -261,7 +261,7 @@ namespace internal { V(toJSON_string, "toJSON") \ V(KeyedLoadMonomorphic_string, "KeyedLoadMonomorphic") \ V(KeyedStoreMonomorphic_string, "KeyedStoreMonomorphic") \ - V(stack_overflow_string, "kStackOverflowBoilerplate") \ + V(stack_overflow_string, "$stackOverflowBoilerplate") \ V(illegal_access_string, "illegal access") \ V(cell_value_string, "%cell_value") \ V(illegal_argument_string, "illegal argument") \ diff --git a/src/messages.cc b/src/messages.cc index bdfc518..1c07854 100644 --- a/src/messages.cc +++ b/src/messages.cc @@ -131,7 +131,7 @@ Handle MessageHandler::GetMessage(Isolate* isolate, Handle data) { Factory* factory = isolate->factory(); Handle fmt_str = - factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("FormatMessage")); + factory->InternalizeOneByteString(STATIC_CHAR_VECTOR("$formatMessage")); Handle fun = Handle::cast(Object::GetProperty( isolate->js_builtins_object(), fmt_str).ToHandleChecked()); Handle message = Handle::cast(data); diff --git a/src/messages.js b/src/messages.js index e997061..eadc880 100644 --- a/src/messages.js +++ b/src/messages.js @@ -4,6 +4,48 @@ // ------------------------------------------------------------------- +var $errorToString; +var $formatMessage; +var $getStackTraceLine; +var $messageGetPositionInLine; +var $messageGetLineNumber; +var $messageGetSourceLine; +var $stackOverflowBoilerplate; +var $stackTraceSymbol; +var $toDetailString; +var $Error; +var $EvalError; +var $RangeError; +var $ReferenceError; +var $SyntaxError; +var $TypeError; +var $URIError; +var MakeError; +var MakeEvalError; +var MakeRangeError; +var MakeReferenceError; +var MakeSyntaxError; +var MakeTypeError; +var MakeURIError; +var MakeReferenceErrorEmbedded; +var MakeSyntaxErrorEmbedded; +var MakeTypeErrorEmbedded; + +(function() { + +%CheckIsBootstrapping(); + +var GlobalObject = global.Object; +var GlobalError; +var GlobalTypeError; +var GlobalRangeError; +var GlobalURIError; +var GlobalSyntaxError; +var GlobalReferenceError; +var GlobalEvalError; + +// ------------------------------------------------------------------- + var kMessages = { // Error constructor_is_generator: ["Class constructor may not be a generator"], @@ -234,7 +276,7 @@ function NoSideEffectToString(obj) { // To determine whether we can safely stringify an object using ErrorToString // without the risk of side-effects, we need to check whether the object is -// either an instance of a native error type (via '%_ClassOf'), or has $Error +// either an instance of a native error type (via '%_ClassOf'), or has Error // in its prototype chain and hasn't overwritten 'toString' with something // strange and unusual. function CanBeSafelyTreatedAsAnErrorObject(obj) { @@ -250,7 +292,7 @@ function CanBeSafelyTreatedAsAnErrorObject(obj) { } var objToString = %GetDataProperty(obj, "toString"); - return obj instanceof $Error && objToString === ErrorToString; + return obj instanceof GlobalError && objToString === ErrorToString; } @@ -338,57 +380,6 @@ function GetSourceLine(message) { return location.sourceText(); } - -function MakeError(type, arg0, arg1, arg2) { - return MakeGenericError($Error, type, arg0, arg1, arg2); -} - - -function MakeTypeError(type, arg0, arg1, arg2) { - return MakeGenericError($TypeError, type, arg0, arg1, arg2); -} - - -function MakeRangeError(type, arg0, arg1, arg2) { - return MakeGenericError($RangeError, type, arg0, arg1, arg2); -} - - -function MakeSyntaxError(type, arg0, arg1, arg2) { - return MakeGenericError($SyntaxError, type, arg0, arg1, arg2); -} - - -function MakeReferenceError(type, arg0, arg1, arg2) { - return MakeGenericError($ReferenceError, type, arg0, arg1, arg2); -} - - -function MakeEvalError(type, arg0, arg1, arg2) { - return MakeGenericError($EvalError, type, arg0, arg1, arg2); -} - - -function MakeURIError() { - return MakeGenericError($URIError, kURIMalformed); -} - -// The embedded versions are called from unoptimized code, with embedded -// arguments. Those arguments cannot be arrays, which are context-dependent. -function MakeTypeErrorEmbedded(type, arg) { - return MakeGenericError($TypeError, type, [arg]); -} - - -function MakeSyntaxErrorEmbedded(type, arg) { - return MakeGenericError($SyntaxError, type, [arg]); -} - - -function MakeReferenceErrorEmbedded(type, arg) { - return MakeGenericError($ReferenceError, type, [arg]); -} - /** * Find a line number given a specific source position. * @param {number} position The source position. @@ -1032,13 +1023,14 @@ var formatting_custom_stack_trace = false; function FormatStackTrace(obj, raw_stack) { var frames = GetStackFrames(raw_stack); - if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) { + if (IS_FUNCTION(GlobalError.prepareStackTrace) && + !formatting_custom_stack_trace) { var array = []; %MoveArrayContents(frames, array); formatting_custom_stack_trace = true; var stack_trace = UNDEFINED; try { - stack_trace = $Error.prepareStackTrace(obj, array); + stack_trace = GlobalError.prepareStackTrace(obj, array); } catch (e) { throw e; // The custom formatting function threw. Rethrow. } finally { @@ -1082,8 +1074,6 @@ function GetTypeName(receiver, requireConstructor) { return constructorName; } - -var stack_trace_symbol; // Set during bootstrapping. var formatted_stack_trace_symbol = NEW_PRIVATE_OWN("formatted stack trace"); @@ -1097,7 +1087,7 @@ var StackTraceGetter = function() { GET_PRIVATE(holder, formatted_stack_trace_symbol); if (IS_UNDEFINED(formatted_stack_trace)) { // No formatted stack trace available. - var stack_trace = GET_PRIVATE(holder, stack_trace_symbol); + var stack_trace = GET_PRIVATE(holder, $stackTraceSymbol); if (IS_UNDEFINED(stack_trace)) { // Neither formatted nor structured stack trace available. // Look further up the prototype chain. @@ -1105,7 +1095,7 @@ var StackTraceGetter = function() { continue; } formatted_stack_trace = FormatStackTrace(holder, stack_trace); - SET_PRIVATE(holder, stack_trace_symbol, UNDEFINED); + SET_PRIVATE(holder, $stackTraceSymbol, UNDEFINED); SET_PRIVATE(holder, formatted_stack_trace_symbol, formatted_stack_trace); } return formatted_stack_trace; @@ -1117,8 +1107,8 @@ var StackTraceGetter = function() { // If the receiver equals the holder, set the formatted stack trace that the // getter returns. var StackTraceSetter = function(v) { - if (HAS_PRIVATE(this, stack_trace_symbol)) { - SET_PRIVATE(this, stack_trace_symbol, UNDEFINED); + if (HAS_PRIVATE(this, $stackTraceSymbol)) { + SET_PRIVATE(this, $stackTraceSymbol, UNDEFINED); SET_PRIVATE(this, formatted_stack_trace_symbol, v); } }; @@ -1135,72 +1125,67 @@ var captureStackTrace = function captureStackTrace(obj, cons_opt) { } -function SetUpError() { - // Define special error type constructors. - - var DefineError = function(f) { - // Store the error function in both the global object - // and the runtime object. The function is fetched - // from the runtime object when throwing errors from - // within the runtime system to avoid strange side - // effects when overwriting the error functions from - // user code. - var name = f.name; - %AddNamedProperty(global, name, f, DONT_ENUM); - %AddNamedProperty(builtins, '$' + name, f, - DONT_ENUM | DONT_DELETE | READ_ONLY); - // Configure the error function. - if (name == 'Error') { - // The prototype of the Error object must itself be an error. - // However, it can't be an instance of the Error object because - // it hasn't been properly configured yet. Instead we create a - // special not-a-true-error-but-close-enough object. - var ErrorPrototype = function() {}; - %FunctionSetPrototype(ErrorPrototype, $Object.prototype); - %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); - %FunctionSetPrototype(f, new ErrorPrototype()); +// Define special error type constructors. +function DefineError(f) { + // Store the error function in both the global object + // and the runtime object. The function is fetched + // from the runtime object when throwing errors from + // within the runtime system to avoid strange side + // effects when overwriting the error functions from + // user code. + var name = f.name; + %AddNamedProperty(global, name, f, DONT_ENUM); + // Configure the error function. + if (name == 'Error') { + // The prototype of the Error object must itself be an error. + // However, it can't be an instance of the Error object because + // it hasn't been properly configured yet. Instead we create a + // special not-a-true-error-but-close-enough object. + var ErrorPrototype = function() {}; + %FunctionSetPrototype(ErrorPrototype, GlobalObject.prototype); + %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); + %FunctionSetPrototype(f, new ErrorPrototype()); + } else { + %FunctionSetPrototype(f, new GlobalError()); + %InternalSetPrototype(f, GlobalError); + } + %FunctionSetInstanceClassName(f, 'Error'); + %AddNamedProperty(f.prototype, 'constructor', f, DONT_ENUM); + %AddNamedProperty(f.prototype, 'name', name, DONT_ENUM); + %SetCode(f, function(m) { + if (%_IsConstructCall()) { + try { captureStackTrace(this, f); } catch (e) { } + // Define all the expected properties directly on the error + // object. This avoids going through getters and setters defined + // on prototype objects. + if (!IS_UNDEFINED(m)) { + %AddNamedProperty(this, 'message', ToString(m), DONT_ENUM); + } } else { - %FunctionSetPrototype(f, new $Error()); - %InternalSetPrototype(f, $Error); + return new f(m); } - %FunctionSetInstanceClassName(f, 'Error'); - %AddNamedProperty(f.prototype, 'constructor', f, DONT_ENUM); - %AddNamedProperty(f.prototype, 'name', name, DONT_ENUM); - %SetCode(f, function(m) { - if (%_IsConstructCall()) { - try { captureStackTrace(this, f); } catch (e) { } - // Define all the expected properties directly on the error - // object. This avoids going through getters and setters defined - // on prototype objects. - if (!IS_UNDEFINED(m)) { - %AddNamedProperty(this, 'message', ToString(m), DONT_ENUM); - } - } else { - return new f(m); - } - }); - %SetNativeFlag(f); - }; - - DefineError(function Error() { }); - DefineError(function TypeError() { }); - DefineError(function RangeError() { }); - DefineError(function SyntaxError() { }); - DefineError(function ReferenceError() { }); - DefineError(function EvalError() { }); - DefineError(function URIError() { }); -} + }); + %SetNativeFlag(f); + return f; +}; -SetUpError(); +GlobalError = DefineError(function Error() { }); +GlobalEvalError = DefineError(function EvalError() { }); +GlobalRangeError = DefineError(function RangeError() { }); +GlobalReferenceError = DefineError(function ReferenceError() { }); +GlobalSyntaxError = DefineError(function SyntaxError() { }); +GlobalTypeError = DefineError(function TypeError() { }); +GlobalURIError = DefineError(function URIError() { }); -$Error.captureStackTrace = captureStackTrace; -%AddNamedProperty($Error.prototype, 'message', '', DONT_ENUM); +GlobalError.captureStackTrace = captureStackTrace; + +%AddNamedProperty(GlobalError.prototype, 'message', '', DONT_ENUM); // Global list of error objects visited during ErrorToString. This is // used to detect cycles in error toString formatting. var visited_errors = new InternalArray(); -var cyclic_error_marker = new $Object(); +var cyclic_error_marker = new GlobalObject(); function GetPropertyWithoutInvokingMonkeyGetters(error, name) { var current = error; @@ -1216,11 +1201,11 @@ function GetPropertyWithoutInvokingMonkeyGetters(error, name) { var desc = %GetOwnProperty(current, name); if (desc && desc[IS_ACCESSOR_INDEX]) { var isName = name === "name"; - if (current === $ReferenceError.prototype) + if (current === GlobalReferenceError.prototype) return isName ? "ReferenceError" : UNDEFINED; - if (current === $SyntaxError.prototype) + if (current === GlobalSyntaxError.prototype) return isName ? "SyntaxError" : UNDEFINED; - if (current === $TypeError.prototype) + if (current === GlobalTypeError.prototype) return isName ? "TypeError" : UNDEFINED; } // Otherwise, read normally. @@ -1259,18 +1244,70 @@ function ErrorToString() { } } +InstallFunctions(GlobalError.prototype, DONT_ENUM, ['toString', ErrorToString]); + +$errorToString = ErrorToString; +$formatMessage = FormatMessage; +$getStackTraceLine = GetStackTraceLine; +$messageGetPositionInLine = GetPositionInLine; +$messageGetLineNumber = GetLineNumber; +$messageGetSourceLine = GetSourceLine; +$toDetailString = ToDetailString; + +$Error = GlobalError; +$EvalError = GlobalEvalError; +$RangeError = GlobalRangeError; +$ReferenceError = GlobalReferenceError; +$SyntaxError = GlobalSyntaxError; +$TypeError = GlobalTypeError; +$URIError = GlobalURIError; + +MakeError = function(type, arg0, arg1, arg2) { + return MakeGenericError(GlobalError, type, arg0, arg1, arg2); +} + +MakeEvalError = function(type, arg0, arg1, arg2) { + return MakeGenericError(GlobalEvalError, type, arg0, arg1, arg2); +} + +MakeRangeError = function(type, arg0, arg1, arg2) { + return MakeGenericError(GlobalRangeError, type, arg0, arg1, arg2); +} -InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]); +MakeReferenceError = function(type, arg0, arg1, arg2) { + return MakeGenericError(GlobalReferenceError, type, arg0, arg1, arg2); +} -// Boilerplate for exceptions for stack overflows. Used from -// Isolate::StackOverflow(). -function SetUpStackOverflowBoilerplate() { - var boilerplate = MakeRangeError(kStackOverflow); +MakeSyntaxError = function(type, arg0, arg1, arg2) { + return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2); +} - %DefineAccessorPropertyUnchecked( - boilerplate, 'stack', StackTraceGetter, StackTraceSetter, DONT_ENUM); +MakeTypeError = function(type, arg0, arg1, arg2) { + return MakeGenericError(GlobalTypeError, type, arg0, arg1, arg2); +} - return boilerplate; +MakeURIError = function() { + return MakeGenericError(GlobalURIError, kURIMalformed); } -var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); +// The embedded versions are called from unoptimized code, with embedded +// arguments. Those arguments cannot be arrays, which are context-dependent. +MakeSyntaxErrorEmbedded = function(type, arg) { + return MakeGenericError(GlobalSyntaxError, type, [arg]); +} + +MakeReferenceErrorEmbedded = function(type, arg) { + return MakeGenericError(GlobalReferenceError, type, [arg]); +} + +MakeTypeErrorEmbedded = function(type, arg) { + return MakeGenericError(GlobalTypeError, type, [arg]); +} + +//Boilerplate for exceptions for stack overflows. Used from +//Isolate::StackOverflow(). +$stackOverflowBoilerplate = MakeRangeError(kStackOverflow); +%DefineAccessorPropertyUnchecked($stackOverflowBoilerplate, 'stack', + StackTraceGetter, StackTraceSetter, DONT_ENUM); + +})(); diff --git a/src/mirror-debugger.js b/src/mirror-debugger.js index 0fffd61..87a1feb 100644 --- a/src/mirror-debugger.js +++ b/src/mirror-debugger.js @@ -1314,7 +1314,7 @@ ErrorMirror.prototype.toText = function() { // Use the same text representation as in messages.js. var text; try { - text = %_CallFunction(this.value_, builtins.ErrorToString); + text = %_CallFunction(this.value_, builtins.$errorToString); } catch (e) { text = '#'; } diff --git a/test/cctest/test-parsing.cc b/test/cctest/test-parsing.cc index ba84258..bd3247e 100644 --- a/test/cctest/test-parsing.cc +++ b/test/cctest/test-parsing.cc @@ -1356,8 +1356,9 @@ i::Handle FormatMessage(i::Vector data) { } i::Handle builtins(isolate->js_builtins_object()); - i::Handle format_fun = i::Object::GetProperty( - isolate, builtins, "FormatMessage").ToHandleChecked(); + i::Handle format_fun = + i::Object::GetProperty(isolate, builtins, "$formatMessage") + .ToHandleChecked(); i::Handle arg_handles[] = { format, args_array }; i::Handle result = i::Execution::Call( isolate, format_fun, builtins, 2, arg_handles).ToHandleChecked(); diff --git a/tools/js2c.py b/tools/js2c.py index e913ca1..6a29fbe 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -69,8 +69,9 @@ def ReadFile(filename): EVAL_PATTERN = re.compile(r'\beval\s*\(') WITH_PATTERN = re.compile(r'\bwith\s*\(') -INVALID_ERROR_MESSAGE_PATTERN = re.compile(r'Make\w*Error\(([kA-Z]\w+)') -NEW_ERROR_PATTERN = re.compile(r'new \$\w*Error\((?!\))'); +INVALID_ERROR_MESSAGE_PATTERN = re.compile( + r'Make(?!Generic)\w*Error\(([kA-Z]\w+)') +NEW_ERROR_PATTERN = re.compile(r'new \$\w*Error\((?!\))') def Validate(lines): # Because of simplified context setup, eval and with is not -- 2.7.4