mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 00:20:56 +00:00
0e98d4ae64
============== Added Dart_SetPostMessageCallback and Dart_SetClosePortCallback. These allow the embedder to provide custom message/port behavior for their application. The vm provides standard implementations that work with the standard run loop. Added Dart_HandleMessage, which processes one message on the current isolate. Embedders can use this to write their own message processing loops. Rewrote code to use this internally. Added Isolate::StandardRunLoop() to share code between Dart_RunLoop and lib/isolate.cc Changed the interface to PortMap::PostMessage. PostMessage is now agnostic to message delivery mechanism. Note that PortMap is now out of the "ReceiveMessage" business entirely. Moved MessageQueue and friends out to message_queue.cc/h. Moved the monitor from the Isolate into the MessageQueue. No need for outsiders to mess. Added MessageQueue::Wait. Moved monitor locking from PortMap into MessageQueue itself, which was easier for me to reason about. Wrote some tests. Removed PortMessage::Handle. The code turned into Dart_HandleMessage. Regularized the nomenclature around ports. Type is now always Dart_Port instead of intptr_t. Variables end in _port instead of _id. Use the term "dest" instead of "target" or "send". Added a family of new tests to port_test. Added EXPECT_NE to the test framework. Review URL: http://codereview.chromium.org//8297004 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@516 260f80e4-7a28-3924-810f-c04153c831b5
279 lines
8.7 KiB
C++
279 lines
8.7 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_ASSERT_H_
|
|
#define VM_ASSERT_H_
|
|
|
|
// TODO(5411406): include sstream for now, once we have a Utils::toString()
|
|
// implemented for all the primitive types we can replace the usage of
|
|
// sstream by Utils::toString()
|
|
#if defined(TESTING)
|
|
#include <sstream>
|
|
#include <string>
|
|
#endif
|
|
|
|
#include "vm/globals.h"
|
|
|
|
#if !defined(DEBUG) && !defined(NDEBUG)
|
|
#error neither DEBUG nor NDEBUG defined
|
|
#elif defined(DEBUG) && defined(NDEBUG)
|
|
#error both DEBUG and NDEBUG defined
|
|
#endif
|
|
|
|
namespace dart {
|
|
|
|
class DynamicAssertionHelper {
|
|
public:
|
|
enum Kind {
|
|
ASSERT,
|
|
EXPECT
|
|
};
|
|
|
|
DynamicAssertionHelper(const char* file, int line, Kind kind)
|
|
: file_(file), line_(line), kind_(kind) { }
|
|
|
|
void Fail(const char* format, ...);
|
|
|
|
#if defined(TESTING)
|
|
template<typename E, typename A>
|
|
void Equals(const E& expected, const A& actual);
|
|
|
|
template<typename E, typename A>
|
|
void NotEquals(const E& not_expected, const A& actual);
|
|
|
|
template<typename E, typename A, typename T>
|
|
void FloatEquals(const E& expected, const A& actual, const T& tol);
|
|
|
|
template<typename E, typename A>
|
|
void StringEquals(const E& expected, const A& actual);
|
|
|
|
template<typename E, typename A>
|
|
void LessThan(const E& left, const A& right);
|
|
|
|
template<typename E, typename A>
|
|
void LessEqual(const E& left, const A& right);
|
|
|
|
template<typename E, typename A>
|
|
void GreaterThan(const E& left, const A& right);
|
|
|
|
template<typename E, typename A>
|
|
void GreaterEqual(const E& left, const A& right);
|
|
#endif
|
|
|
|
private:
|
|
const char* const file_;
|
|
const int line_;
|
|
const Kind kind_;
|
|
|
|
DISALLOW_IMPLICIT_CONSTRUCTORS(DynamicAssertionHelper);
|
|
};
|
|
|
|
|
|
class Assert: public DynamicAssertionHelper {
|
|
public:
|
|
Assert(const char* file, int line)
|
|
: DynamicAssertionHelper(file, line, ASSERT) { }
|
|
};
|
|
|
|
|
|
class Expect: public DynamicAssertionHelper {
|
|
public:
|
|
Expect(const char* file, int line)
|
|
: DynamicAssertionHelper(file, line, EXPECT) { }
|
|
};
|
|
|
|
|
|
#if defined(TESTING)
|
|
// Only allow the expensive (with respect to code size) assertions
|
|
// in testing code.
|
|
template<typename E, typename A>
|
|
void DynamicAssertionHelper::Equals(const E& expected, const A& actual) {
|
|
if (actual == expected) return;
|
|
std::stringstream ess, ass;
|
|
ess << expected;
|
|
ass << actual;
|
|
std::string es = ess.str(), as = ass.str();
|
|
Fail("expected: <%s> but was: <%s>", es.c_str(), as.c_str());
|
|
}
|
|
|
|
|
|
template<typename E, typename A>
|
|
void DynamicAssertionHelper::NotEquals(const E& not_expected,
|
|
const A& actual) {
|
|
if (actual != not_expected) return;
|
|
std::stringstream ness;
|
|
ness << not_expected;
|
|
std::string nes = ness.str();
|
|
Fail("did not expect: <%s>", nes.c_str());
|
|
}
|
|
|
|
|
|
template<typename E, typename A, typename T>
|
|
void DynamicAssertionHelper::FloatEquals(const E& expected,
|
|
const A& actual,
|
|
const T& tol) {
|
|
if (((expected - tol) <= actual) && (actual <= (expected + tol))) {
|
|
return;
|
|
}
|
|
std::stringstream ess, ass, tolss;
|
|
ess << expected;
|
|
ass << actual;
|
|
tolss << tol;
|
|
std::string es = ess.str(), as = ass.str(), tols = tolss.str();
|
|
Fail("expected: <%s> but was: <%s> (tolerance: <%s>)",
|
|
es.c_str(),
|
|
as.c_str(),
|
|
tols.c_str());
|
|
}
|
|
|
|
|
|
template<typename E, typename A>
|
|
void DynamicAssertionHelper::StringEquals(const E& expected, const A& actual) {
|
|
std::stringstream ess, ass;
|
|
ess << expected;
|
|
ass << actual;
|
|
std::string es = ess.str(), as = ass.str();
|
|
if (as == es) return;
|
|
Fail("expected: <\"%s\"> but was: <\"%s\">", es.c_str(), as.c_str());
|
|
}
|
|
|
|
|
|
template<typename E, typename A>
|
|
void DynamicAssertionHelper::LessThan(const E& left, const A& right) {
|
|
if (left < right) return;
|
|
std::stringstream ess, ass;
|
|
ess << left;
|
|
ass << right;
|
|
std::string es = ess.str(), as = ass.str();
|
|
Fail("expected: %s < %s", es.c_str(), as.c_str());
|
|
}
|
|
|
|
|
|
template<typename E, typename A>
|
|
void DynamicAssertionHelper::LessEqual(const E& left, const A& right) {
|
|
if (left <= right) return;
|
|
std::stringstream ess, ass;
|
|
ess << left;
|
|
ass << right;
|
|
std::string es = ess.str(), as = ass.str();
|
|
Fail("expected: %s <= %s", es.c_str(), as.c_str());
|
|
}
|
|
|
|
|
|
template<typename E, typename A>
|
|
void DynamicAssertionHelper::GreaterThan(const E& left, const A& right) {
|
|
if (left > right) return;
|
|
std::stringstream ess, ass;
|
|
ess << left;
|
|
ass << right;
|
|
std::string es = ess.str(), as = ass.str();
|
|
Fail("expected: %s > %s", es.c_str(), as.c_str());
|
|
}
|
|
|
|
|
|
template<typename E, typename A>
|
|
void DynamicAssertionHelper::GreaterEqual(const E& left, const A& right) {
|
|
if (left >= right) return;
|
|
std::stringstream ess, ass;
|
|
ess << left;
|
|
ass << right;
|
|
std::string es = ess.str(), as = ass.str();
|
|
Fail("expected: %s >= %s", es.c_str(), as.c_str());
|
|
}
|
|
#endif
|
|
|
|
} // namespace dart
|
|
|
|
|
|
#define FATAL(error) \
|
|
dart::Assert(__FILE__, __LINE__).Fail("%s", error)
|
|
|
|
#define FATAL1(format, p1) \
|
|
dart::Assert(__FILE__, __LINE__).Fail(format, (p1))
|
|
|
|
#define FATAL2(format, p1, p2) \
|
|
dart::Assert(__FILE__, __LINE__).Fail(format, (p1), (p2))
|
|
|
|
#define UNIMPLEMENTED() \
|
|
FATAL("unimplemented code")
|
|
|
|
#define UNREACHABLE() \
|
|
FATAL("unreachable code")
|
|
|
|
|
|
#if defined(DEBUG)
|
|
// DEBUG binaries use assertions in the code.
|
|
// Note: We wrap the if statement in a do-while so that we get a compile
|
|
// error if there is no semicolon after ASSERT(condition). This
|
|
// ensures that we get the same behavior on DEBUG and RELEASE builds.
|
|
|
|
#define ASSERT(cond) \
|
|
do { \
|
|
if (!(cond)) dart::Assert(__FILE__, __LINE__).Fail("expected: %s", #cond); \
|
|
} while (false)
|
|
|
|
// DEBUG_ASSERT allows identifiers in condition to be undeclared in release
|
|
// mode.
|
|
#define DEBUG_ASSERT(cond) \
|
|
if (!(cond)) dart::Assert(__FILE__, __LINE__).Fail("expected: %s", #cond);
|
|
|
|
#else // if defined(DEBUG)
|
|
|
|
// In order to avoid variable unused warnings for code that only uses
|
|
// a variable in an ASSERT or EXPECT, we make sure to use the macro
|
|
// argument.
|
|
#define ASSERT(condition) do {} while (false && (condition))
|
|
|
|
#define DEBUG_ASSERT(cond)
|
|
|
|
#endif // if defined(DEBUG)
|
|
|
|
|
|
#if defined(TESTING)
|
|
#define EXPECT(condition) \
|
|
if (!(condition)) { \
|
|
dart::Expect(__FILE__, __LINE__).Fail("expected: %s", #condition); \
|
|
}
|
|
|
|
#define EXPECT_EQ(expected, actual) \
|
|
dart::Expect(__FILE__, __LINE__).Equals((expected), (actual))
|
|
|
|
#define EXPECT_NE(not_expected, actual) \
|
|
dart::Expect(__FILE__, __LINE__).NotEquals((not_expected), (actual))
|
|
|
|
#define EXPECT_FLOAT_EQ(expected, actual, tol) \
|
|
dart::Expect(__FILE__, __LINE__).FloatEquals((expected), (actual), (tol))
|
|
|
|
#define EXPECT_STREQ(expected, actual) \
|
|
dart::Expect(__FILE__, __LINE__).StringEquals((expected), (actual))
|
|
|
|
#define EXPECT_LT(left, right) \
|
|
dart::Expect(__FILE__, __LINE__).LessThan((left), (right))
|
|
|
|
#define EXPECT_LE(left, right) \
|
|
dart::Expect(__FILE__, __LINE__).LessEqual((left), (right))
|
|
|
|
#define EXPECT_GT(left, right) \
|
|
dart::Expect(__FILE__, __LINE__).GreaterThan((left), (right))
|
|
|
|
#define EXPECT_GE(left, right) \
|
|
dart::Expect(__FILE__, __LINE__).GreaterEqual((left), (right))
|
|
#endif
|
|
|
|
// TODO(iposva): provide a better way to get extra info on an EXPECT
|
|
// fail - you suggested EXPECT_EQ(expected, actual, msg_format,
|
|
// parameters_for_msg...), I quite like the google3 method
|
|
// EXPECT_EQ(a, b) << "more stuff here...". (benl).
|
|
|
|
#define WARN(error) \
|
|
dart::Expect(__FILE__, __LINE__).Fail("%s", error)
|
|
|
|
#define WARN1(format, p1) \
|
|
dart::Expect(__FILE__, __LINE__).Fail(format, (p1))
|
|
|
|
#define WARN2(format, p1, p2) \
|
|
dart::Expect(__FILE__, __LINE__).Fail(format, (p1), (p2))
|
|
|
|
#endif // VM_ASSERT_H_
|