Commit d281688a authored by yangguo's avatar yangguo Committed by Commit bot

Do not use js builtins object when constructing an error.

R=cbruni@chromium.org

Review URL: https://codereview.chromium.org/1295093002

Cr-Commit-Position: refs/heads/master@{#30189}
parent f0c21aa4
......@@ -1763,6 +1763,7 @@ void Bootstrapper::ImportNatives(Isolate* isolate, Handle<JSObject> container) {
INSTALL_NATIVE(JSFunction, "SyntaxError", syntax_error_function);
INSTALL_NATIVE(JSFunction, "TypeError", type_error_function);
INSTALL_NATIVE(JSFunction, "URIError", uri_error_function);
INSTALL_NATIVE(JSFunction, "MakeError", make_error_function);
INSTALL_NATIVE(Symbol, "promiseStatus", promise_status);
INSTALL_NATIVE(Symbol, "promiseValue", promise_value);
......
......@@ -159,6 +159,7 @@ enum BindingFlags {
V(SYNTAX_ERROR_FUNCTION_INDEX, JSFunction, syntax_error_function) \
V(TYPE_ERROR_FUNCTION_INDEX, JSFunction, type_error_function) \
V(URI_ERROR_FUNCTION_INDEX, JSFunction, uri_error_function) \
V(MAKE_ERROR_FUNCTION_INDEX, JSFunction, make_error_function) \
V(PROMISE_STATUS_INDEX, Symbol, promise_status) \
V(PROMISE_VALUE_INDEX, Symbol, promise_value) \
V(PROMISE_CREATE_INDEX, JSFunction, promise_create) \
......
......@@ -1103,35 +1103,31 @@ Handle<Bool8x16> Factory::NewBool8x16(bool lanes[16], PretenureFlag pretenure) {
}
Handle<Object> Factory::NewError(const char* maker,
Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2) {
HandleScope scope(isolate());
Handle<String> error_maker = InternalizeUtf8String(maker);
if (isolate()->bootstrapper()->IsActive()) {
// If this exception is being thrown during bootstrapping,
// js_builtins_object is unavailable. We return the error maker
// name's string as the exception since we have nothing better
// to do.
return scope.CloseAndEscape(error_maker);
// During bootstrapping we cannot construct error objects.
return scope.CloseAndEscape(NewStringFromAsciiChecked(
MessageTemplate::TemplateString(template_index)));
}
Handle<Object> fun_obj = Object::GetProperty(isolate()->js_builtins_object(),
error_maker).ToHandleChecked();
Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
Handle<JSFunction> fun = isolate()->make_error_function();
Handle<Object> message_type(Smi::FromInt(template_index), isolate());
if (arg0.is_null()) arg0 = undefined_value();
if (arg1.is_null()) arg1 = undefined_value();
if (arg2.is_null()) arg2 = undefined_value();
Handle<Object> argv[] = {message_type, arg0, arg1, arg2};
Handle<Object> argv[] = {constructor, message_type, arg0, arg1, arg2};
// Invoke the JavaScript factory method. If an exception is thrown while
// running the factory method, use the exception as the result.
Handle<Object> result;
MaybeHandle<Object> exception;
if (!Execution::TryCall(fun, isolate()->js_builtins_object(), arraysize(argv),
argv, &exception).ToHandle(&result)) {
if (!Execution::TryCall(fun, undefined_value(), arraysize(argv), argv,
&exception)
.ToHandle(&result)) {
Handle<Object> exception_obj;
if (exception.ToHandle(&exception_obj)) {
result = exception_obj;
......@@ -1143,113 +1139,6 @@ Handle<Object> Factory::NewError(const char* maker,
}
Handle<Object> Factory::NewError(MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2) {
return NewError("MakeError", template_index, arg0, arg1, arg2);
}
Handle<Object> Factory::NewTypeError(MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2) {
return NewError("MakeTypeError", template_index, arg0, arg1, arg2);
}
Handle<Object> Factory::NewSyntaxError(MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2) {
return NewError("MakeSyntaxError", template_index, arg0, arg1, arg2);
}
Handle<Object> Factory::NewReferenceError(
MessageTemplate::Template template_index, Handle<Object> arg0,
Handle<Object> arg1, Handle<Object> arg2) {
return NewError("MakeReferenceError", template_index, arg0, arg1, arg2);
}
Handle<Object> Factory::NewRangeError(MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2) {
return NewError("MakeRangeError", template_index, arg0, arg1, arg2);
}
Handle<Object> Factory::NewEvalError(MessageTemplate::Template template_index,
Handle<Object> arg0, Handle<Object> arg1,
Handle<Object> arg2) {
return NewError("MakeEvalError", template_index, arg0, arg1, arg2);
}
Handle<String> Factory::EmergencyNewError(const char* message,
Handle<JSArray> args) {
const int kBufferSize = 1000;
char buffer[kBufferSize];
size_t space = kBufferSize;
char* p = &buffer[0];
Vector<char> v(buffer, kBufferSize);
StrNCpy(v, message, space);
space -= Min(space, strlen(message));
p = &buffer[kBufferSize] - space;
for (int i = 0; i < Smi::cast(args->length())->value(); i++) {
if (space > 0) {
*p++ = ' ';
space--;
if (space > 0) {
Handle<String> arg_str = Handle<String>::cast(
Object::GetElement(isolate(), args, i).ToHandleChecked());
base::SmartArrayPointer<char> arg = arg_str->ToCString();
Vector<char> v2(p, static_cast<int>(space));
StrNCpy(v2, arg.get(), space);
space -= Min(space, strlen(arg.get()));
p = &buffer[kBufferSize] - space;
}
}
}
if (space > 0) {
*p = '\0';
} else {
buffer[kBufferSize - 1] = '\0';
}
return NewStringFromUtf8(CStrVector(buffer), TENURED).ToHandleChecked();
}
Handle<Object> Factory::NewError(const char* maker, const char* message,
Handle<JSArray> args) {
Handle<String> make_str = InternalizeUtf8String(maker);
Handle<Object> fun_obj = Object::GetProperty(
isolate()->js_builtins_object(), make_str).ToHandleChecked();
// If the builtins haven't been properly configured yet this error
// constructor may not have been defined. Bail out.
if (!fun_obj->IsJSFunction()) {
return EmergencyNewError(message, args);
}
Handle<JSFunction> fun = Handle<JSFunction>::cast(fun_obj);
Handle<Object> message_obj = InternalizeUtf8String(message);
Handle<Object> argv[] = { message_obj, args };
// Invoke the JavaScript factory method. If an exception is thrown while
// running the factory method, use the exception as the result.
Handle<Object> result;
MaybeHandle<Object> exception;
if (!Execution::TryCall(fun, undefined_value(), arraysize(argv), argv,
&exception)
.ToHandle(&result)) {
Handle<Object> exception_obj;
if (exception.ToHandle(&exception_obj)) return exception_obj;
return undefined_value();
}
return result;
}
Handle<Object> Factory::NewError(Handle<JSFunction> constructor,
Handle<String> message) {
Handle<Object> argv[] = { message };
......
......@@ -546,11 +546,6 @@ class Factory final {
Handle<Code> CopyCode(Handle<Code> code, Vector<byte> reloc_info);
// Interface for creating error objects.
Handle<Object> NewError(const char* maker, const char* message,
Handle<JSArray> args);
Handle<String> EmergencyNewError(const char* message, Handle<JSArray> args);
Handle<Object> NewError(Handle<JSFunction> constructor,
Handle<String> message);
......@@ -558,41 +553,28 @@ class Factory final {
return NewRangeError(MessageTemplate::kInvalidStringLength);
}
Handle<Object> NewError(const char* maker,
Handle<Object> NewError(Handle<JSFunction> constructor,
MessageTemplate::Template template_index,
Handle<Object> arg0 = Handle<Object>(),
Handle<Object> arg1 = Handle<Object>(),
Handle<Object> arg2 = Handle<Object>());
Handle<Object> NewError(MessageTemplate::Template template_index,
Handle<Object> arg0 = Handle<Object>(),
Handle<Object> arg1 = Handle<Object>(),
Handle<Object> arg2 = Handle<Object>());
#define DEFINE_ERROR(NAME, name) \
Handle<Object> New##NAME(MessageTemplate::Template template_index, \
Handle<Object> arg0 = Handle<Object>(), \
Handle<Object> arg1 = Handle<Object>(), \
Handle<Object> arg2 = Handle<Object>()) { \
return NewError(isolate()->name##_function(), template_index, arg0, arg1, \
arg2); \
}
Handle<Object> NewTypeError(MessageTemplate::Template template_index,
Handle<Object> arg0 = Handle<Object>(),
Handle<Object> arg1 = Handle<Object>(),
Handle<Object> arg2 = Handle<Object>());
Handle<Object> NewSyntaxError(MessageTemplate::Template template_index,
Handle<Object> arg0 = Handle<Object>(),
Handle<Object> arg1 = Handle<Object>(),
Handle<Object> arg2 = Handle<Object>());
Handle<Object> NewReferenceError(MessageTemplate::Template template_index,
Handle<Object> arg0 = Handle<Object>(),
Handle<Object> arg1 = Handle<Object>(),
Handle<Object> arg2 = Handle<Object>());
Handle<Object> NewRangeError(MessageTemplate::Template template_index,
Handle<Object> arg0 = Handle<Object>(),
Handle<Object> arg1 = Handle<Object>(),
Handle<Object> arg2 = Handle<Object>());
Handle<Object> NewEvalError(MessageTemplate::Template template_index,
Handle<Object> arg0 = Handle<Object>(),
Handle<Object> arg1 = Handle<Object>(),
Handle<Object> arg2 = Handle<Object>());
DEFINE_ERROR(Error, error)
DEFINE_ERROR(EvalError, eval_error)
DEFINE_ERROR(RangeError, range_error)
DEFINE_ERROR(ReferenceError, reference_error)
DEFINE_ERROR(SyntaxError, syntax_error)
DEFINE_ERROR(TypeError, type_error)
#undef DEFINE_ERROR
Handle<String> NumberToString(Handle<Object> number,
bool check_number_string_cache = true);
......
......@@ -322,23 +322,29 @@ Handle<String> MessageTemplate::FormatMessage(Isolate* isolate,
}
MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
Handle<String> arg0,
Handle<String> arg1,
Handle<String> arg2) {
Isolate* isolate = arg0->GetIsolate();
const char* template_string;
const char* MessageTemplate::TemplateString(int template_index) {
switch (template_index) {
#define CASE(NAME, STRING) \
case k##NAME: \
template_string = STRING; \
break;
#define CASE(NAME, STRING) \
case k##NAME: \
return STRING;
MESSAGE_TEMPLATES(CASE)
#undef CASE
case kLastMessage:
default:
isolate->ThrowIllegalOperation();
return MaybeHandle<String>();
return NULL;
}
}
MaybeHandle<String> MessageTemplate::FormatMessage(int template_index,
Handle<String> arg0,
Handle<String> arg1,
Handle<String> arg2) {
Isolate* isolate = arg0->GetIsolate();
const char* template_string = TemplateString(template_index);
if (template_string == NULL) {
isolate->ThrowIllegalOperation();
return MaybeHandle<String>();
}
IncrementalStringBuilder builder(isolate);
......
......@@ -413,6 +413,8 @@ class MessageTemplate {
kLastMessage
};
static const char* TemplateString(int template_index);
static MaybeHandle<String> FormatMessage(int template_index,
Handle<String> arg0,
Handle<String> arg1,
......
......@@ -172,7 +172,6 @@ function ToDetailString(obj) {
function MakeGenericError(constructor, type, arg0, arg1, arg2) {
if (IS_UNDEFINED(arg0) && IS_STRING(type)) arg0 = [];
var error = new constructor(FormatMessage(type, arg0, arg1, arg2));
error[$internalErrorSymbol] = true;
return error;
......@@ -1014,18 +1013,10 @@ 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);
}
MakeReferenceError = function(type, arg0, arg1, arg2) {
return MakeGenericError(GlobalReferenceError, type, arg0, arg1, arg2);
}
MakeSyntaxError = function(type, arg0, arg1, arg2) {
return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2);
}
......@@ -1067,6 +1058,7 @@ utils.ExportToRuntime(function(to) {
to.GetStackTraceLine = GetStackTraceLine;
to.NoSideEffectToString = NoSideEffectToString;
to.ToDetailString = ToDetailString;
to.MakeError = MakeGenericError;
});
});
......@@ -31,10 +31,10 @@ void PendingCompilationErrorHandler::ThrowPendingError(Isolate* isolate,
Handle<Object> error;
switch (error_type_) {
case kReferenceError:
error = factory->NewError("MakeReferenceError", message_, argument);
error = factory->NewReferenceError(message_, argument);
break;
case kSyntaxError:
error = factory->NewError("MakeSyntaxError", message_, argument);
error = factory->NewSyntaxError(message_, argument);
break;
default:
UNREACHABLE();
......
......@@ -25,8 +25,6 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Flags: --allow-natives-syntax
// Check that message and name are not enumerable on Error objects.
var desc = Object.getOwnPropertyDescriptor(Error.prototype, 'name');
assertFalse(desc['enumerable']);
......@@ -62,7 +60,12 @@ var e = new ReferenceError('123');
assertTrue(e.hasOwnProperty('message'));
assertTrue(e.hasOwnProperty('stack'));
var e = %MakeReferenceError("my_test_error", [0, 1]);
try {
eval("var error = reference");
} catch (error) {
e = error;
}
assertTrue(e.hasOwnProperty('stack'));
// Check that intercepting property access from toString is prevented for
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment