1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/builtins/builtins.h"
6 #include "src/builtins/builtins-utils.h"
7
8 #include "src/messages.h"
9 #include "src/property-descriptor.h"
10 #include "src/string-builder.h"
11
12 namespace v8 {
13 namespace internal {
14
15 // ES6 section 19.5.1.1 Error ( message )
BUILTIN(ErrorConstructor)16 BUILTIN(ErrorConstructor) {
17 HandleScope scope(isolate);
18
19 FrameSkipMode mode = SKIP_FIRST;
20 Handle<Object> caller;
21
22 // When we're passed a JSFunction as new target, we can skip frames until that
23 // specific function is seen instead of unconditionally skipping the first
24 // frame.
25 if (args.new_target()->IsJSFunction()) {
26 mode = SKIP_UNTIL_SEEN;
27 caller = args.new_target();
28 }
29
30 RETURN_RESULT_OR_FAILURE(
31 isolate, ErrorUtils::Construct(isolate, args.target(),
32 Handle<Object>::cast(args.new_target()),
33 args.atOrUndefined(isolate, 1), mode,
34 caller, false));
35 }
36
37 // static
BUILTIN(ErrorCaptureStackTrace)38 BUILTIN(ErrorCaptureStackTrace) {
39 HandleScope scope(isolate);
40 Handle<Object> object_obj = args.atOrUndefined(isolate, 1);
41 if (!object_obj->IsJSObject()) {
42 THROW_NEW_ERROR_RETURN_FAILURE(
43 isolate, NewTypeError(MessageTemplate::kInvalidArgument, object_obj));
44 }
45 Handle<JSObject> object = Handle<JSObject>::cast(object_obj);
46 Handle<Object> caller = args.atOrUndefined(isolate, 2);
47 FrameSkipMode mode = caller->IsJSFunction() ? SKIP_UNTIL_SEEN : SKIP_FIRST;
48
49 // Collect the stack trace.
50
51 RETURN_FAILURE_ON_EXCEPTION(isolate,
52 isolate->CaptureAndSetDetailedStackTrace(object));
53
54 // Eagerly format the stack trace and set the stack property.
55
56 Handle<Object> stack_trace =
57 isolate->CaptureSimpleStackTrace(object, mode, caller);
58 if (!stack_trace->IsJSArray()) return isolate->heap()->undefined_value();
59
60 Handle<Object> formatted_stack_trace;
61 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
62 isolate, formatted_stack_trace,
63 ErrorUtils::FormatStackTrace(isolate, object, stack_trace));
64
65 PropertyDescriptor desc;
66 desc.set_configurable(true);
67 desc.set_writable(true);
68 desc.set_value(formatted_stack_trace);
69 Maybe<bool> status = JSReceiver::DefineOwnProperty(
70 isolate, object, isolate->factory()->stack_string(), &desc,
71 Object::THROW_ON_ERROR);
72 if (!status.IsJust()) return isolate->heap()->exception();
73 CHECK(status.FromJust());
74 return isolate->heap()->undefined_value();
75 }
76
77 // ES6 section 19.5.3.4 Error.prototype.toString ( )
BUILTIN(ErrorPrototypeToString)78 BUILTIN(ErrorPrototypeToString) {
79 HandleScope scope(isolate);
80 RETURN_RESULT_OR_FAILURE(isolate,
81 ErrorUtils::ToString(isolate, args.receiver()));
82 }
83
84 namespace {
85
MakeGenericError(Isolate * isolate,BuiltinArguments args,Handle<JSFunction> constructor)86 Object* MakeGenericError(Isolate* isolate, BuiltinArguments args,
87 Handle<JSFunction> constructor) {
88 Handle<Object> template_index = args.atOrUndefined(isolate, 1);
89 Handle<Object> arg0 = args.atOrUndefined(isolate, 2);
90 Handle<Object> arg1 = args.atOrUndefined(isolate, 3);
91 Handle<Object> arg2 = args.atOrUndefined(isolate, 4);
92
93 DCHECK(template_index->IsSmi());
94
95 RETURN_RESULT_OR_FAILURE(
96 isolate, ErrorUtils::MakeGenericError(isolate, constructor,
97 Smi::cast(*template_index)->value(),
98 arg0, arg1, arg2, SKIP_NONE));
99 }
100
101 } // namespace
102
BUILTIN(MakeError)103 BUILTIN(MakeError) {
104 HandleScope scope(isolate);
105 return MakeGenericError(isolate, args, isolate->error_function());
106 }
107
BUILTIN(MakeRangeError)108 BUILTIN(MakeRangeError) {
109 HandleScope scope(isolate);
110 return MakeGenericError(isolate, args, isolate->range_error_function());
111 }
112
BUILTIN(MakeSyntaxError)113 BUILTIN(MakeSyntaxError) {
114 HandleScope scope(isolate);
115 return MakeGenericError(isolate, args, isolate->syntax_error_function());
116 }
117
BUILTIN(MakeTypeError)118 BUILTIN(MakeTypeError) {
119 HandleScope scope(isolate);
120 return MakeGenericError(isolate, args, isolate->type_error_function());
121 }
122
BUILTIN(MakeURIError)123 BUILTIN(MakeURIError) {
124 HandleScope scope(isolate);
125 Handle<JSFunction> constructor = isolate->uri_error_function();
126 Handle<Object> undefined = isolate->factory()->undefined_value();
127 const int template_index = MessageTemplate::kURIMalformed;
128 RETURN_RESULT_OR_FAILURE(
129 isolate,
130 ErrorUtils::MakeGenericError(isolate, constructor, template_index,
131 undefined, undefined, undefined, SKIP_NONE));
132 }
133
134 } // namespace internal
135 } // namespace v8
136