builtins-error.cc 4.47 KB
Newer Older
jgruber's avatar
jgruber committed
1 2 3 4 5 6 7
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/builtins/builtins.h"
#include "src/builtins/builtins-utils.h"

8
#include "src/counters.h"
9
#include "src/messages.h"
10
#include "src/objects-inl.h"
jgruber's avatar
jgruber committed
11 12 13 14 15 16 17 18 19
#include "src/property-descriptor.h"
#include "src/string-builder.h"

namespace v8 {
namespace internal {

// ES6 section 19.5.1.1 Error ( message )
BUILTIN(ErrorConstructor) {
  HandleScope scope(isolate);
20 21 22 23 24 25 26 27 28 29 30 31

  FrameSkipMode mode = SKIP_FIRST;
  Handle<Object> caller;

  // When we're passed a JSFunction as new target, we can skip frames until that
  // specific function is seen instead of unconditionally skipping the first
  // frame.
  if (args.new_target()->IsJSFunction()) {
    mode = SKIP_UNTIL_SEEN;
    caller = args.new_target();
  }

32
  RETURN_RESULT_OR_FAILURE(
33
      isolate, ErrorUtils::Construct(isolate, args.target(),
34 35 36
                                     Handle<Object>::cast(args.new_target()),
                                     args.atOrUndefined(isolate, 1), mode,
                                     caller, false));
jgruber's avatar
jgruber committed
37 38 39 40 41 42 43 44 45 46 47 48
}

// static
BUILTIN(ErrorCaptureStackTrace) {
  HandleScope scope(isolate);
  Handle<Object> object_obj = args.atOrUndefined(isolate, 1);
  if (!object_obj->IsJSObject()) {
    THROW_NEW_ERROR_RETURN_FAILURE(
        isolate, NewTypeError(MessageTemplate::kInvalidArgument, object_obj));
  }
  Handle<JSObject> object = Handle<JSObject>::cast(object_obj);
  Handle<Object> caller = args.atOrUndefined(isolate, 2);
49
  FrameSkipMode mode = caller->IsJSFunction() ? SKIP_UNTIL_SEEN : SKIP_FIRST;
jgruber's avatar
jgruber committed
50

51
  // Collect the stack trace.
jgruber's avatar
jgruber committed
52

53 54
  RETURN_FAILURE_ON_EXCEPTION(isolate,
                              isolate->CaptureAndSetDetailedStackTrace(object));
jgruber's avatar
jgruber committed
55

56
  // Eagerly format the stack trace and set the stack property.
jgruber's avatar
jgruber committed
57

58 59
  Handle<Object> stack_trace =
      isolate->CaptureSimpleStackTrace(object, mode, caller);
60
  if (!stack_trace->IsJSArray()) return isolate->heap()->undefined_value();
jgruber's avatar
jgruber committed
61

62 63 64
  Handle<Object> formatted_stack_trace;
  ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
      isolate, formatted_stack_trace,
65
      ErrorUtils::FormatStackTrace(isolate, object, stack_trace));
jgruber's avatar
jgruber committed
66

67 68
  PropertyDescriptor desc;
  desc.set_configurable(true);
69
  desc.set_writable(true);
70 71 72 73 74 75 76
  desc.set_value(formatted_stack_trace);
  Maybe<bool> status = JSReceiver::DefineOwnProperty(
      isolate, object, isolate->factory()->stack_string(), &desc,
      Object::THROW_ON_ERROR);
  if (!status.IsJust()) return isolate->heap()->exception();
  CHECK(status.FromJust());
  return isolate->heap()->undefined_value();
jgruber's avatar
jgruber committed
77 78 79 80 81
}

// ES6 section 19.5.3.4 Error.prototype.toString ( )
BUILTIN(ErrorPrototypeToString) {
  HandleScope scope(isolate);
jgruber's avatar
jgruber committed
82 83
  RETURN_RESULT_OR_FAILURE(isolate,
                           ErrorUtils::ToString(isolate, args.receiver()));
jgruber's avatar
jgruber committed
84 85
}

86
namespace {
87

88 89 90 91 92 93
Object* MakeGenericError(Isolate* isolate, BuiltinArguments args,
                         Handle<JSFunction> constructor) {
  Handle<Object> template_index = args.atOrUndefined(isolate, 1);
  Handle<Object> arg0 = args.atOrUndefined(isolate, 2);
  Handle<Object> arg1 = args.atOrUndefined(isolate, 3);
  Handle<Object> arg2 = args.atOrUndefined(isolate, 4);
94 95 96

  DCHECK(template_index->IsSmi());

97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
  RETURN_RESULT_OR_FAILURE(
      isolate, ErrorUtils::MakeGenericError(isolate, constructor,
                                            Smi::cast(*template_index)->value(),
                                            arg0, arg1, arg2, SKIP_NONE));
}

}  // namespace

BUILTIN(MakeError) {
  HandleScope scope(isolate);
  return MakeGenericError(isolate, args, isolate->error_function());
}

BUILTIN(MakeRangeError) {
  HandleScope scope(isolate);
  return MakeGenericError(isolate, args, isolate->range_error_function());
}

BUILTIN(MakeSyntaxError) {
  HandleScope scope(isolate);
  return MakeGenericError(isolate, args, isolate->syntax_error_function());
}

BUILTIN(MakeTypeError) {
  HandleScope scope(isolate);
  return MakeGenericError(isolate, args, isolate->type_error_function());
}

BUILTIN(MakeURIError) {
  HandleScope scope(isolate);
  Handle<JSFunction> constructor = isolate->uri_error_function();
  Handle<Object> undefined = isolate->factory()->undefined_value();
  const int template_index = MessageTemplate::kURIMalformed;
130 131
  RETURN_RESULT_OR_FAILURE(
      isolate,
132 133
      ErrorUtils::MakeGenericError(isolate, constructor, template_index,
                                   undefined, undefined, undefined, SKIP_NONE));
134 135
}

jgruber's avatar
jgruber committed
136 137
}  // namespace internal
}  // namespace v8