dart-sdk/runtime/vm/exceptions.h
Matthias Hausner 3e0d13bc28 Make compile-time errors catchable
If an error happens during the compilation of a function body, an Error is thrown which can be intercepted, and ensures that finally blocks are executed before the isolate is terminated.

The language spec is vague about compilation errors. A doc describing the intentions behind this CL is at
https://docs.google.com/document/d/1_MWOgwJadLCQSBps0zD6Rj5dG4iP1UBuiDvTMH-WMzI/edit#

Example:
     1	void bad() {
     2	    return 5
     3	}
     4
     5	void main(args) {
     6	    bad();
     7	}

Before this CL:
$ dart ~/tmp/e.dart
'file:///Users/hausner/tmp/e.dart': error: line 2 pos 11: semicolon expected
  return 5
          ^
$

After this change:
$ dart ~/tmp/e.dart
Unhandled exception:
'file:///Users/hausner/tmp/e.dart': error: line 2 pos 11: semicolon expected
  return 5
          ^

#0      main (file:///Users/hausner/tmp/e.dart:6:3)
#1      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:259)
#2      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:148)
$

Notice that the stack trace points to the call site of bad(), not the text location of the syntax error. That's not a bug. The location of the syntax error is given in the error message.

BUG= https://github.com/dart-lang/sdk/issues/23684
R=asiva@google.com, lrn@google.com

Review URL: https://codereview.chromium.org/2044753002 .
2016-09-16 10:10:38 -07:00

89 lines
2.6 KiB
C++

// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef VM_EXCEPTIONS_H_
#define VM_EXCEPTIONS_H_
#include "vm/allocation.h"
#include "vm/token_position.h"
namespace dart {
// Forward declarations.
class AbstractType;
class Array;
class DartFrameIterator;
class Error;
class LanguageError;
class Instance;
class Integer;
class RawInstance;
class RawObject;
class RawScript;
class RawStacktrace;
class String;
class Thread;
class Exceptions : AllStatic {
public:
static void Throw(Thread* thread, const Instance& exception);
static void ReThrow(Thread* thread,
const Instance& exception,
const Instance& stacktrace);
static void PropagateError(const Error& error);
// Helpers to create and throw errors.
static RawStacktrace* CurrentStacktrace();
static RawScript* GetCallerScript(DartFrameIterator* iterator);
static RawInstance* NewInstance(const char* class_name);
static void CreateAndThrowTypeError(TokenPosition location,
const AbstractType& src_type,
const AbstractType& dst_type,
const String& dst_name,
const String& bound_error_msg);
enum ExceptionType {
kNone,
kRange,
kArgument,
kArgumentValue,
kNoSuchMethod,
kFormat,
kUnsupported,
kStackOverflow,
kOutOfMemory,
kNullThrown,
kIsolateSpawn,
kAssertion,
kCast,
kType,
kFallThrough,
kAbstractClassInstantiation,
kCyclicInitializationError,
kCompileTimeError,
};
static void ThrowByType(ExceptionType type, const Array& arguments);
// Uses the preallocated out of memory exception to avoid calling
// into Dart code or allocating any code.
static void ThrowOOM();
static void ThrowStackOverflow();
static void ThrowArgumentError(const Instance& arg);
static void ThrowRangeError(const char* argument_name,
const Integer& argument_value,
intptr_t expected_from,
intptr_t expected_to);
static void ThrowCompileTimeError(const LanguageError& error);
// Returns a RawInstance if the exception is successfully created,
// otherwise returns a RawError.
static RawObject* Create(ExceptionType type, const Array& arguments);
private:
DISALLOW_COPY_AND_ASSIGN(Exceptions);
};
} // namespace dart
#endif // VM_EXCEPTIONS_H_