Version 0.6.1.0 .
svn merge -r 24454:24475 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
git-svn-id: http://dart.googlecode.com/svn/trunk@24479 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 3537e32..e45088f 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -53,6 +53,7 @@
V(File_Delete, 1) \
V(File_DeleteLink, 1) \
V(File_Rename, 2) \
+ V(File_RenameLink, 2) \
V(File_FullPath, 1) \
V(File_OpenStdio, 1) \
V(File_GetStdioHandleType, 1) \
diff --git a/runtime/bin/eventhandler_android.cc b/runtime/bin/eventhandler_android.cc
index c043c2d..bbc8acb 100644
--- a/runtime/bin/eventhandler_android.cc
+++ b/runtime/bin/eventhandler_android.cc
@@ -350,18 +350,18 @@
}
-intptr_t EventHandlerImplementation::GetTimeout() {
+int64_t EventHandlerImplementation::GetTimeout() {
if (timeout_ == kInfinityTimeout) {
return kInfinityTimeout;
}
- intptr_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
+ int64_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
return (millis < 0) ? 0 : millis;
}
void EventHandlerImplementation::HandleTimeout() {
if (timeout_ != kInfinityTimeout) {
- intptr_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
+ int64_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
if (millis <= 0) {
DartUtils::PostNull(timeout_port_);
timeout_ = kInfinityTimeout;
@@ -378,7 +378,9 @@
reinterpret_cast<EventHandlerImplementation*>(args);
ASSERT(handler != NULL);
while (!handler->shutdown_) {
- intptr_t millis = handler->GetTimeout();
+ int64_t millis = handler->GetTimeout();
+ ASSERT(millis == kInfinityTimeout || millis >= 0);
+ if (millis > kMaxInt32) millis = kMaxInt32;
intptr_t result = TEMP_FAILURE_RETRY(epoll_wait(handler->epoll_fd_,
events,
kMaxEvents,
diff --git a/runtime/bin/eventhandler_android.h b/runtime/bin/eventhandler_android.h
index a60beff..f127d6d 100644
--- a/runtime/bin/eventhandler_android.h
+++ b/runtime/bin/eventhandler_android.h
@@ -103,7 +103,7 @@
void Shutdown();
private:
- intptr_t GetTimeout();
+ int64_t GetTimeout();
bool GetInterruptMessage(InterruptMessage* msg);
void HandleEvents(struct epoll_event* events, int size);
void HandleTimeout();
diff --git a/runtime/bin/eventhandler_linux.cc b/runtime/bin/eventhandler_linux.cc
index e2e2746..aa852d1 100644
--- a/runtime/bin/eventhandler_linux.cc
+++ b/runtime/bin/eventhandler_linux.cc
@@ -355,18 +355,18 @@
}
-intptr_t EventHandlerImplementation::GetTimeout() {
+int64_t EventHandlerImplementation::GetTimeout() {
if (timeout_ == kInfinityTimeout) {
return kInfinityTimeout;
}
- intptr_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
+ int64_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
return (millis < 0) ? 0 : millis;
}
void EventHandlerImplementation::HandleTimeout() {
if (timeout_ != kInfinityTimeout) {
- intptr_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
+ int64_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
if (millis <= 0) {
DartUtils::PostNull(timeout_port_);
timeout_ = kInfinityTimeout;
@@ -383,7 +383,9 @@
EventHandlerImplementation* handler_impl = &handler->delegate_;
ASSERT(handler_impl != NULL);
while (!handler_impl->shutdown_) {
- intptr_t millis = handler_impl->GetTimeout();
+ int64_t millis = handler_impl->GetTimeout();
+ ASSERT(millis == kInfinityTimeout || millis >= 0);
+ if (millis > kMaxInt32) millis = kMaxInt32;
intptr_t result = TEMP_FAILURE_RETRY(epoll_wait(handler_impl->epoll_fd_,
events,
kMaxEvents,
diff --git a/runtime/bin/eventhandler_linux.h b/runtime/bin/eventhandler_linux.h
index 4c423f2..d8fc509 100644
--- a/runtime/bin/eventhandler_linux.h
+++ b/runtime/bin/eventhandler_linux.h
@@ -102,7 +102,7 @@
void Shutdown();
private:
- intptr_t GetTimeout();
+ int64_t GetTimeout();
bool GetInterruptMessage(InterruptMessage* msg);
void HandleEvents(struct epoll_event* events, int size);
void HandleTimeout();
diff --git a/runtime/bin/eventhandler_macos.cc b/runtime/bin/eventhandler_macos.cc
index 6823ef8..a6554c9 100644
--- a/runtime/bin/eventhandler_macos.cc
+++ b/runtime/bin/eventhandler_macos.cc
@@ -350,18 +350,18 @@
}
-intptr_t EventHandlerImplementation::GetTimeout() {
+int64_t EventHandlerImplementation::GetTimeout() {
if (timeout_ == kInfinityTimeout) {
return kInfinityTimeout;
}
- intptr_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
+ int64_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
return (millis < 0) ? 0 : millis;
}
void EventHandlerImplementation::HandleTimeout() {
if (timeout_ != kInfinityTimeout) {
- intptr_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
+ int64_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
if (millis <= 0) {
DartUtils::PostNull(timeout_port_);
timeout_ = kInfinityTimeout;
@@ -378,7 +378,9 @@
EventHandlerImplementation* handler_impl = &handler->delegate_;
ASSERT(handler_impl != NULL);
while (!handler_impl->shutdown_) {
- intptr_t millis = handler_impl->GetTimeout();
+ int64_t millis = handler_impl->GetTimeout();
+ ASSERT(millis == kInfinityTimeout || millis >= 0);
+ if (millis > kMaxInt32) millis = kMaxInt32;
// NULL pointer timespec for infinite timeout.
ASSERT(kInfinityTimeout < 0);
struct timespec* timeout = NULL;
diff --git a/runtime/bin/eventhandler_macos.h b/runtime/bin/eventhandler_macos.h
index 4303586..6bf4d61 100644
--- a/runtime/bin/eventhandler_macos.h
+++ b/runtime/bin/eventhandler_macos.h
@@ -115,7 +115,7 @@
void Shutdown();
private:
- intptr_t GetTimeout();
+ int64_t GetTimeout();
bool GetInterruptMessage(InterruptMessage* msg);
void HandleEvents(struct kevent* events, int size);
void HandleTimeout();
diff --git a/runtime/bin/eventhandler_win.cc b/runtime/bin/eventhandler_win.cc
index 6819fce..7c96ce8 100644
--- a/runtime/bin/eventhandler_win.cc
+++ b/runtime/bin/eventhandler_win.cc
@@ -906,11 +906,11 @@
}
-DWORD EventHandlerImplementation::GetTimeout() {
+int64_t EventHandlerImplementation::GetTimeout() {
if (timeout_ == kInfinityTimeout) {
return kInfinityTimeout;
}
- intptr_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
+ int64_t millis = timeout_ - TimerUtils::GetCurrentTimeMilliseconds();
return (millis < 0) ? 0 : millis;
}
@@ -938,12 +938,15 @@
DWORD bytes;
ULONG_PTR key;
OVERLAPPED* overlapped;
- intptr_t millis = handler_impl->GetTimeout();
+ int64_t millis = handler_impl->GetTimeout();
+ ASSERT(millis == kInfinityTimeout || millis >= 0);
+ if (millis > kMaxInt32) millis = kMaxInt32;
+ ASSERT(sizeof(int32_t) == sizeof(DWORD));
BOOL ok = GetQueuedCompletionStatus(handler_impl->completion_port(),
&bytes,
&key,
&overlapped,
- millis);
+ static_cast<DWORD>(millis));
if (!ok && overlapped == NULL) {
if (GetLastError() == ERROR_ABANDONED_WAIT_0) {
// The completion port should never be closed.
diff --git a/runtime/bin/eventhandler_win.h b/runtime/bin/eventhandler_win.h
index 30d229b..9bb0610 100644
--- a/runtime/bin/eventhandler_win.h
+++ b/runtime/bin/eventhandler_win.h
@@ -371,7 +371,7 @@
static void EventHandlerEntry(uword args);
- DWORD GetTimeout();
+ int64_t GetTimeout();
void HandleInterrupt(InterruptMessage* msg);
void HandleTimeout();
void HandleAccept(ListenSocket* listen_socket, IOBuffer* buffer);
diff --git a/runtime/bin/file.cc b/runtime/bin/file.cc
index c687cde..1785674 100644
--- a/runtime/bin/file.cc
+++ b/runtime/bin/file.cc
@@ -524,6 +524,24 @@
}
+void FUNCTION_NAME(File_RenameLink)(Dart_NativeArguments args) {
+ Dart_EnterScope();
+ const char* old_path =
+ DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
+ const char* new_path =
+ DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
+ bool result = File::RenameLink(old_path, new_path);
+ if (result) {
+ Dart_SetReturnValue(args, Dart_NewBoolean(result));
+ } else {
+ Dart_Handle err = DartUtils::NewDartOSError();
+ if (Dart_IsError(err)) Dart_PropagateError(err);
+ Dart_SetReturnValue(args, err);
+ }
+ Dart_ExitScope();
+}
+
+
void FUNCTION_NAME(File_FullPath)(Dart_NativeArguments args) {
Dart_EnterScope();
const char* str =
@@ -1107,6 +1125,20 @@
}
+static CObject* FileRenameLinkRequest(const CObjectArray& request) {
+ if (request.Length() == 3 &&
+ request[1]->IsString() &&
+ request[2]->IsString()) {
+ CObjectString old_path(request[1]);
+ CObjectString new_path(request[2]);
+ bool completed = File::RenameLink(old_path.CString(), new_path.CString());
+ if (completed) return CObject::True();
+ return CObject::NewOSError();
+ }
+ return CObject::IllegalArgumentError();
+}
+
+
static CObject* FileLinkTargetRequest(const CObjectArray& request) {
if (request.Length() == 2 && request[1]->IsString()) {
CObjectString link_path(request[1]);
@@ -1248,6 +1280,9 @@
case File::kDeleteLinkRequest:
response = FileDeleteLinkRequest(request);
break;
+ case File::kRenameLinkRequest:
+ response = FileRenameLinkRequest(request);
+ break;
case File::kCreateLinkRequest:
response = FileCreateLinkRequest(request);
break;
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index a2bf20d..3908154 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -83,10 +83,11 @@
kWriteFromRequest = 18,
kCreateLinkRequest = 19,
kDeleteLinkRequest = 20,
- kLinkTargetRequest = 21,
- kTypeRequest = 22,
- kIdenticalRequest = 23,
- kStatRequest = 24
+ kRenameLinkRequest = 21,
+ kLinkTargetRequest = 22,
+ kTypeRequest = 23,
+ kIdenticalRequest = 24,
+ kStatRequest = 25
};
enum FileStat {
@@ -154,6 +155,7 @@
static bool Delete(const char* path);
static bool DeleteLink(const char* path);
static bool Rename(const char* old_path, const char* new_path);
+ static bool RenameLink(const char* old_path, const char* new_path);
static off_t LengthFromPath(const char* path);
static void Stat(const char* path, int64_t* data);
static time_t LastModified(const char* path);
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 513f96e..9b5ff1b 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -205,6 +205,19 @@
}
+bool File::RenameLink(const char* old_path, const char* new_path) {
+ File::Type type = File::GetType(old_path, false);
+ if (type == kIsLink) {
+ return TEMP_FAILURE_RETRY(rename(old_path, new_path)) == 0;
+ } else if (type == kIsDirectory) {
+ errno = EISDIR;
+ } else {
+ errno = EINVAL;
+ }
+ return false;
+}
+
+
off_t File::LengthFromPath(const char* name) {
struct stat st;
if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) {
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index 840e6b9..b45ce04 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -206,6 +206,19 @@
}
+bool File::RenameLink(const char* old_path, const char* new_path) {
+ File::Type type = File::GetType(old_path, false);
+ if (type == kIsLink) {
+ return TEMP_FAILURE_RETRY(rename(old_path, new_path)) == 0;
+ } else if (type == kIsDirectory) {
+ errno = EISDIR;
+ } else {
+ errno = EINVAL;
+ }
+ return false;
+}
+
+
off_t File::LengthFromPath(const char* name) {
struct stat st;
if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) {
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index c2308b6..3cf40de 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -208,6 +208,19 @@
}
+bool File::RenameLink(const char* old_path, const char* new_path) {
+ File::Type type = File::GetType(old_path, false);
+ if (type == kIsLink) {
+ return TEMP_FAILURE_RETRY(rename(old_path, new_path)) == 0;
+ } else if (type == kIsDirectory) {
+ errno = EISDIR;
+ } else {
+ errno = EINVAL;
+ }
+ return false;
+}
+
+
off_t File::LengthFromPath(const char* name) {
struct stat st;
if (TEMP_FAILURE_RETRY(stat(name, &st)) == 0) {
diff --git a/runtime/bin/file_patch.dart b/runtime/bin/file_patch.dart
index e788a42..c9e4fcc 100644
--- a/runtime/bin/file_patch.dart
+++ b/runtime/bin/file_patch.dart
@@ -16,6 +16,8 @@
/* patch */ static _deleteLink(String path) native "File_DeleteLink";
/* patch */ static _rename(String oldPath, String newPath)
native "File_Rename";
+ /* patch */ static _renameLink(String oldPath, String newPath)
+ native "File_RenameLink";
/* patch */ static _lengthFromPath(String path) native "File_LengthFromPath";
/* patch */ static _lastModified(String path) native "File_LastModified";
/* patch */ static _open(String path, int mode) native "File_Open";
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index 723bd6c..08417ea 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -297,8 +297,24 @@
free(const_cast<wchar_t*>(system_old_path));
free(const_cast<wchar_t*>(system_new_path));
return (move_status != 0);
- } else if (type == kIsDirectory) {
+ } else {
SetLastError(ERROR_FILE_NOT_FOUND);
+ }
+ return false;
+}
+
+
+bool File::RenameLink(const char* old_path, const char* new_path) {
+ File::Type type = GetType(old_path, false);
+ if (type == kIsLink) {
+ const wchar_t* system_old_path = StringUtils::Utf8ToWide(old_path);
+ const wchar_t* system_new_path = StringUtils::Utf8ToWide(new_path);
+ DWORD flags = MOVEFILE_WRITE_THROUGH;
+ int move_status =
+ MoveFileExW(system_old_path, system_new_path, flags);
+ free(const_cast<wchar_t*>(system_old_path));
+ free(const_cast<wchar_t*>(system_new_path));
+ return (move_status != 0);
} else {
SetLastError(ERROR_FILE_NOT_FOUND);
}
diff --git a/runtime/bin/socket_android.cc b/runtime/bin/socket_android.cc
index d837892..748f33e 100644
--- a/runtime/bin/socket_android.cc
+++ b/runtime/bin/socket_android.cc
@@ -323,6 +323,17 @@
return -1;
}
+ // Test for invalid socket port 65535 (some browsers disallow it).
+ if (port == 0 && Socket::GetPort(fd) == 65535) {
+ // Don't close fd until we have created new. By doing that we ensure another
+ // port.
+ intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only);
+ int err = errno;
+ TEMP_FAILURE_RETRY(close(fd));
+ errno = err;
+ return new_fd;
+ }
+
if (TEMP_FAILURE_RETRY(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
TEMP_FAILURE_RETRY(close(fd));
return -1;
diff --git a/runtime/bin/socket_linux.cc b/runtime/bin/socket_linux.cc
index 3f97475..1aaba00 100644
--- a/runtime/bin/socket_linux.cc
+++ b/runtime/bin/socket_linux.cc
@@ -322,6 +322,17 @@
return -1;
}
+ // Test for invalid socket port 65535 (some browsers disallow it).
+ if (port == 0 && Socket::GetPort(fd) == 65535) {
+ // Don't close fd until we have created new. By doing that we ensure another
+ // port.
+ intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only);
+ int err = errno;
+ TEMP_FAILURE_RETRY(close(fd));
+ errno = err;
+ return new_fd;
+ }
+
if (TEMP_FAILURE_RETRY(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
TEMP_FAILURE_RETRY(close(fd));
return -1;
diff --git a/runtime/bin/socket_macos.cc b/runtime/bin/socket_macos.cc
index 528f5ab..b9c6298 100644
--- a/runtime/bin/socket_macos.cc
+++ b/runtime/bin/socket_macos.cc
@@ -322,6 +322,17 @@
return -1;
}
+ // Test for invalid socket port 65535 (some browsers disallow it).
+ if (port == 0 && Socket::GetPort(fd) == 65535) {
+ // Don't close fd until we have created new. By doing that we ensure another
+ // port.
+ intptr_t new_fd = CreateBindListen(addr, 0, backlog, v6_only);
+ int err = errno;
+ TEMP_FAILURE_RETRY(close(fd));
+ errno = err;
+ return new_fd;
+ }
+
if (TEMP_FAILURE_RETRY(listen(fd, backlog > 0 ? backlog : SOMAXCONN)) != 0) {
VOID_TEMP_FAILURE_RETRY(close(fd));
return -1;
diff --git a/runtime/bin/socket_win.cc b/runtime/bin/socket_win.cc
index f24cfc5..ef37ad2 100644
--- a/runtime/bin/socket_win.cc
+++ b/runtime/bin/socket_win.cc
@@ -375,15 +375,30 @@
return -1;
}
+ ListenSocket* listen_socket = new ListenSocket(s);
+
+ // Test for invalid socket port 65535 (some browsers disallow it).
+ if (port == 0 &&
+ Socket::GetPort(reinterpret_cast<intptr_t>(listen_socket)) == 65535) {
+ // Don't close fd until we have created new. By doing that we ensure another
+ // port.
+ intptr_t new_s = CreateBindListen(addr, 0, backlog, v6_only);
+ DWORD rc = WSAGetLastError();
+ closesocket(s);
+ delete listen_socket;
+ SetLastError(rc);
+ return new_s;
+ }
+
status = listen(s, backlog > 0 ? backlog : SOMAXCONN);
if (status == SOCKET_ERROR) {
DWORD rc = WSAGetLastError();
closesocket(s);
+ delete listen_socket;
SetLastError(rc);
return -1;
}
- ListenSocket* listen_socket = new ListenSocket(s);
return reinterpret_cast<intptr_t>(listen_socket);
}
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index c679d2a..0f2b66e 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -1583,7 +1583,6 @@
const LocalVariable* exception_var,
const LocalVariable* stacktrace_var)
: AstNode(token_pos),
- try_index_(kInvalidTryIndex),
catch_block_(catch_block),
handler_types_(handler_types),
context_var_(*context_var),
@@ -1596,12 +1595,6 @@
ASSERT(stacktrace_var != NULL);
}
- int try_index() const {
- ASSERT(try_index_ >= 0);
- return try_index_;
- }
- void set_try_index(int value) { try_index_ = value; }
-
const Array& handler_types() const { return handler_types_; }
const LocalVariable& context_var() const { return context_var_; }
const LocalVariable& exception_var() const { return exception_var_; }
@@ -1614,7 +1607,6 @@
DECLARE_COMMON_NODE_FUNCTIONS(CatchClauseNode);
private:
- int try_index_; // Running index of the try blocks seen in a function.
SequenceNode* catch_block_;
const Array& handler_types_;
const LocalVariable& context_var_;
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 91ed8eb..680fb33 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1169,13 +1169,10 @@
args.SetAt(0, receiver);
const Object& value = Object::Handle(DartEntry::InvokeFunction(getter, args));
- // 3. If the getter threw an exception, treat it as no such method.
- if (value.IsUnhandledException()) return false;
-
- // 4. If there was some other error, propagate it.
+ // 3. If there was some error, propagate it.
CheckResultError(value);
- // 5. Invoke the value as a closure.
+ // 4. Invoke the value as a closure.
Instance& instance = Instance::Handle();
instance ^= value.raw();
arguments.SetAt(0, instance);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 36088d9..2f96f61 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -3273,10 +3273,6 @@
CatchClauseNode* catch_block = node->catch_block();
if (catch_block != NULL) {
- // Set the corresponding try index for this catch block so
- // that we can set the appropriate handler pc when we generate
- // code for this catch block.
- catch_block->set_try_index(try_index);
EffectGraphVisitor for_catch_block(owner(), temp_index());
catch_block->Visit(&for_catch_block);
CatchBlockEntryInstr* catch_entry =
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index ce260cf..6e61549 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -894,16 +894,6 @@
}
__ Bind(&wrong_num_arguments);
- if (StackSize() != 0) {
- // We need to unwind the space we reserved for locals and copied parameters.
- // The NoSuchMethodFunction stub does not expect to see that area on the
- // stack.
- __ AddImmediate(SP, StackSize() * kWordSize);
- }
- // The call below has an empty stackmap because we have just
- // dropped the spill slots.
- BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
-
// Invoke noSuchMethod function passing the original name of the function.
// If the function is a closure function, use "call" as the original name.
const String& name = String::Handle(
@@ -913,26 +903,10 @@
ICData::New(function, name, Object::null_array(),
Isolate::kNoDeoptId, kNumArgsChecked));
__ LoadObject(R5, ic_data);
- // FP - 4 : saved PP, object pool pointer of caller.
- // FP + 0 : previous frame pointer.
- // FP + 4 : return address.
- // FP + 8 : PC marker, for easy identification of RawInstruction obj.
- // FP + 12: last argument (arg n-1).
- // SP + 0 : saved PP.
- // SP + 16 + 4*(n-1) : first argument (arg 0).
- // R5 : ic-data.
- // R4 : arguments descriptor array.
- __ BranchLink(&StubCode::CallNoSuchMethodFunctionLabel());
- // Emit descriptors in order to provide correct postion in stacktrace.
- AddCurrentDescriptor(PcDescriptors::kOther, -1, function.token_pos());
- if (is_optimizing()) {
- stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
- empty_stack_bitmap,
- 0); // No registers.
- }
- // The noSuchMethod call may return.
- __ LeaveDartFrame();
- __ Ret();
+ __ LeaveDartFrame(); // The arguments are still on the stack.
+ __ Branch(&StubCode::CallNoSuchMethodFunctionLabel());
+ // The noSuchMethod call may return to the caller, but not here.
+ __ bkpt(0);
__ Bind(&all_arguments_processed);
// Nullify originally passed arguments only after they have been copied and
@@ -1084,16 +1058,6 @@
__ b(&correct_num_arguments, EQ);
__ Bind(&wrong_num_arguments);
if (function.IsClosureFunction() || function.IsNoSuchMethodDispatcher()) {
- if (StackSize() != 0) {
- // We need to unwind the space we reserved for locals and copied
- // parameters. The NoSuchMethodFunction stub does not expect to see
- // that area on the stack.
- __ AddImmediate(SP, StackSize() * kWordSize);
- }
- // The call below has an empty stackmap because we have just
- // dropped the spill slots.
- BitmapBuilder* empty_stack_bitmap = new BitmapBuilder();
-
// Invoke noSuchMethod function passing the original function name.
// For closure functions, use "call" as the original name.
const String& name =
@@ -1105,26 +1069,10 @@
ICData::New(function, name, Object::null_array(),
Isolate::kNoDeoptId, kNumArgsChecked));
__ LoadObject(R5, ic_data);
- // FP - 4 : saved PP, object pool pointer of caller.
- // FP + 0 : previous frame pointer.
- // FP + 4 : return address.
- // FP + 8 : PC marker, for easy identification of RawInstruction obj.
- // FP + 12: last argument (arg n-1).
- // SP + 0 : saved PP.
- // SP + 16 + 4*(n-1) : first argument (arg 0).
- // R5 : ic-data.
- // R4 : arguments descriptor array.
- __ BranchLink(&StubCode::CallNoSuchMethodFunctionLabel());
- // Emit descriptors in order to provide correct postion in stacktrace.
- AddCurrentDescriptor(PcDescriptors::kOther, -1, function.token_pos());
- if (is_optimizing()) {
- stackmap_table_builder_->AddEntry(assembler()->CodeSize(),
- empty_stack_bitmap,
- 0); // No registers.
- }
- // The noSuchMethod call may return.
- __ LeaveDartFrame();
- __ Ret();
+ __ LeaveDartFrame(); // The arguments are still on the stack.
+ __ Branch(&StubCode::CallNoSuchMethodFunctionLabel());
+ // The noSuchMethod call may return to the caller, but not here.
+ __ bkpt(0);
} else {
__ Stop("Wrong number of arguments");
}
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 231b65d..8a66d91 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -4346,6 +4346,18 @@
}
+static bool HasSimpleTypeArguments(AllocateObjectInstr* alloc) {
+ if (alloc->ArgumentCount() == 0) return true;
+ ASSERT(alloc->ArgumentCount() == 2);
+ Value* arg1 = alloc->PushArgumentAt(1)->value();
+ if (!arg1->BindsToConstant()) return false;
+
+ const Object& obj = arg1->BoundConstant();
+ return obj.IsSmi()
+ && (Smi::Cast(obj).Value() == StubCode::kNoInstantiator);
+}
+
+
class LoadOptimizer : public ValueObject {
public:
LoadOptimizer(FlowGraph* graph,
@@ -4507,11 +4519,10 @@
// constructor invocation.
// TODO(vegorov): record null-values at least for not final fields of
// escaping object.
- // TODO(vegorov): enable forwarding of type arguments.
AllocateObjectInstr* alloc = instr->AsAllocateObject();
if ((alloc != NULL) &&
(alloc->identity() == AllocateObjectInstr::kNotAliased) &&
- (alloc->ArgumentCount() == 0)) {
+ HasSimpleTypeArguments(alloc)) {
for (Value* use = alloc->input_use_list();
use != NULL;
use = use->next_use()) {
@@ -4522,9 +4533,21 @@
LoadFieldInstr* load = use->instruction()->AsLoadField();
if (load != NULL) {
- // Found a load. Initialize current value of the field to null.
+ // Found a load. Initialize current value of the field to null for
+ // normal fields, or with type arguments.
gen->Add(load->place_id());
if (out_values == NULL) out_values = CreateBlockOutValues();
+
+ if (alloc->ArgumentCount() > 0) {
+ ASSERT(alloc->ArgumentCount() == 2);
+ const Class& cls = Class::Handle(alloc->constructor().Owner());
+ intptr_t type_args_offset = cls.type_arguments_field_offset();
+ if (load->offset_in_bytes() == type_args_offset) {
+ (*out_values)[load->place_id()] =
+ alloc->PushArgumentAt(0)->value()->definition();
+ continue;
+ }
+ }
(*out_values)[load->place_id()] = graph_->constant_null();
}
}
@@ -6877,10 +6900,7 @@
// instructions that write into fields of the allocated object.
// We do not support materialization of the object that has type arguments.
static bool IsAllocationSinkingCandidate(AllocateObjectInstr* alloc) {
- // TODO(vegorov): support AllocateObject with type arguments.
- if (alloc->ArgumentCount() > 0) {
- return false;
- }
+ if (!HasSimpleTypeArguments(alloc)) return false;
for (Value* use = alloc->input_use_list();
use != NULL;
@@ -6918,6 +6938,12 @@
ASSERT(alloc->env_use_list() == NULL);
ASSERT(alloc->input_use_list() == NULL);
alloc->RemoveFromGraph();
+ if (alloc->ArgumentCount() > 0) {
+ ASSERT(alloc->ArgumentCount() == 2);
+ for (intptr_t i = 0; i < alloc->ArgumentCount(); ++i) {
+ alloc->PushArgumentAt(i)->RemoveFromGraph();
+ }
+ }
}
@@ -6968,6 +6994,10 @@
// external effects from calls.
LoadOptimizer::OptimizeGraph(flow_graph_);
+ if (FLAG_trace_optimization) {
+ FlowGraphPrinter::PrintGraph("Sinking", flow_graph_);
+ }
+
// At this point we have computed the state of object at each deoptimization
// point and we can eliminate it. Loads inserted above were forwarded so there
// are no uses of the allocation just as in the begging of the pass.
@@ -7083,6 +7113,22 @@
AddField(fields, use->instruction()->AsStoreInstanceField()->field());
}
+ if (alloc->ArgumentCount() > 0) {
+ ASSERT(alloc->ArgumentCount() == 2);
+ const String& name = String::Handle(Symbols::New(":type_args"));
+ const Field& type_args_field =
+ Field::ZoneHandle(Field::New(
+ name,
+ false, // !static
+ false, // !final
+ false, // !const
+ Class::Handle(alloc->constructor().Owner()),
+ 0)); // No token position.
+ const Class& cls = Class::Handle(alloc->constructor().Owner());
+ type_args_field.SetOffset(cls.type_arguments_field_offset());
+ AddField(fields, type_args_field);
+ }
+
// Collect all instructions that mention this object in the environment.
GrowableArray<Instruction*> exits(10);
for (Value* use = alloc->env_use_list();
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 18b4744..74ab05b 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -1096,7 +1096,7 @@
__ mvn(R0, ShifterOperand(R0));
__ bic(R0, R0, ShifterOperand(kSmiTagMask)); // Remove inverted smi-tag.
__ Ret();
- return false;
+ return true;
}
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index cc08b23..1401625 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -760,7 +760,7 @@
// All double-precision registers are initialized to zero.
for (int i = 0; i < kNumberOfDRegisters; i++) {
- dregisters_[i] = 0.0;
+ dregisters_[i] = 0;
}
// Since VFP registers are overlapping, single-precision registers should
// already be initialized.
@@ -901,24 +901,48 @@
// Accessors for VFP register state.
void Simulator::set_sregister(SRegister reg, float value) {
ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
- sregisters_[reg] = value;
+ sregisters_[reg] = bit_cast<int32_t, float>(value);
}
float Simulator::get_sregister(SRegister reg) const {
ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
- return sregisters_[reg];
+ return bit_cast<float, int32_t>(sregisters_[reg]);
}
void Simulator::set_dregister(DRegister reg, double value) {
ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
- dregisters_[reg] = value;
+ dregisters_[reg] = bit_cast<int64_t, double>(value);
}
double Simulator::get_dregister(DRegister reg) const {
ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
+ return bit_cast<double, int64_t>(dregisters_[reg]);
+}
+
+
+void Simulator::set_sregister_bits(SRegister reg, int32_t value) {
+ ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
+ sregisters_[reg] = value;
+}
+
+
+int32_t Simulator::get_sregister_bits(SRegister reg) const {
+ ASSERT((reg >= 0) && (reg < kNumberOfSRegisters));
+ return sregisters_[reg];
+}
+
+
+void Simulator::set_dregister_bits(DRegister reg, int64_t value) {
+ ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
+ dregisters_[reg] = value;
+}
+
+
+int64_t Simulator::get_dregister_bits(DRegister reg) const {
+ ASSERT((reg >= 0) && (reg < kNumberOfDRegisters));
return dregisters_[reg];
}
@@ -2371,25 +2395,25 @@
ASSERT(sm1 < kNumberOfSRegisters);
if (instr->Bit(20) == 1) {
// Format(instr, "vmovrrs'cond 'rd, 'rn, {'sm', 'sm1}");
- set_register(rd, bit_cast<int32_t, float>(get_sregister(sm)));
- set_register(rn, bit_cast<int32_t, float>(get_sregister(sm1)));
+ set_register(rd, get_sregister_bits(sm));
+ set_register(rn, get_sregister_bits(sm1));
} else {
// Format(instr, "vmovsrr'cond {'sm, 'sm1}, 'rd', 'rn");
- set_sregister(sm, bit_cast<float, int32_t>(get_register(rd)));
- set_sregister(sm1, bit_cast<float, int32_t>(get_register(rn)));
+ set_sregister_bits(sm, get_register(rd));
+ set_sregister_bits(sm1, get_register(rn));
}
} else {
DRegister dm = instr->DmField();
if (instr->Bit(20) == 1) {
// Format(instr, "vmovrrd'cond 'rd, 'rn, 'dm");
- int64_t dm_val = bit_cast<int64_t, double>(get_dregister(dm));
+ int64_t dm_val = get_dregister_bits(dm);
set_register(rd, Utils::Low32Bits(dm_val));
set_register(rn, Utils::High32Bits(dm_val));
} else {
// Format(instr, "vmovdrr'cond 'dm, 'rd, 'rn");
int64_t dm_val = Utils::LowHighTo64Bits(get_register(rd),
get_register(rn));
- set_dregister(dm, bit_cast<double, int64_t>(dm_val));
+ set_dregister_bits(dm, dm_val);
}
}
} else if (instr-> IsVFPLoadStore()) {
@@ -2409,11 +2433,11 @@
if (instr->Bit(20) == 1) { // vldrs
// Format(instr, "vldrs'cond 'sd, ['rn, #+'off10]");
// Format(instr, "vldrs'cond 'sd, ['rn, #-'off10]");
- set_sregister(sd, bit_cast<float, int32_t>(ReadW(addr, instr)));
+ set_sregister_bits(sd, ReadW(addr, instr));
} else { // vstrs
// Format(instr, "vstrs'cond 'sd, ['rn, #+'off10]");
// Format(instr, "vstrs'cond 'sd, ['rn, #-'off10]");
- WriteW(addr, bit_cast<int32_t, float>(get_sregister(sd)), instr);
+ WriteW(addr, get_sregister_bits(sd), instr);
}
} else {
DRegister dd = instr->DdField();
@@ -2422,11 +2446,11 @@
// Format(instr, "vldrd'cond 'dd, ['rn, #-'off10]");
int64_t dd_val = Utils::LowHighTo64Bits(ReadW(addr, instr),
ReadW(addr + 4, instr));
- set_dregister(dd, bit_cast<double, int64_t>(dd_val));
+ set_dregister_bits(dd, dd_val);
} else { // vstrd
// Format(instr, "vstrd'cond 'dd, ['rn, #+'off10]");
// Format(instr, "vstrd'cond 'dd, ['rn, #-'off10]");
- int64_t dd_val = bit_cast<int64_t, double>(get_dregister(dd));
+ int64_t dd_val = get_dregister_bits(dd);
WriteW(addr, Utils::Low32Bits(dd_val), instr);
WriteW(addr + 4, Utils::High32Bits(dd_val), instr);
}
@@ -2456,10 +2480,10 @@
SRegister sd = static_cast<SRegister>(i);
if (instr->Bit(20) == 1) {
// Format(instr, "vldms'cond'pu 'rn'w, 'slist");
- set_sregister(sd, bit_cast<float, int32_t>(ReadW(addr, instr)));
+ set_sregister_bits(sd, ReadW(addr, instr));
} else {
// Format(instr, "vstms'cond'pu 'rn'w, 'slist");
- WriteW(addr, bit_cast<int32_t, float>(get_sregister(sd)), instr);
+ WriteW(addr, get_sregister_bits(sd), instr);
}
addr += 4;
}
@@ -2472,10 +2496,10 @@
// Format(instr, "vldmd'cond'pu 'rn'w, 'dlist");
int64_t dd_val = Utils::LowHighTo64Bits(ReadW(addr, instr),
ReadW(addr + 4, instr));
- set_dregister(dd, bit_cast<double, int64_t>(dd_val));
+ set_dregister_bits(dd, dd_val);
} else {
// Format(instr, "vstmd'cond'pu 'rn'w, 'dlist");
- int64_t dd_val = bit_cast<int64_t, double>(get_dregister(dd));
+ int64_t dd_val = get_dregister_bits(dd);
WriteW(addr, Utils::Low32Bits(dd_val), instr);
WriteW(addr + 4, Utils::High32Bits(dd_val), instr);
}
@@ -2726,13 +2750,13 @@
}
case 8: { // vcvt, vcvtr between floating-point and integer
sm = instr->SmField();
- float sm_val = get_sregister(sm);
+ int32_t sm_int = get_sregister_bits(sm);
uint32_t ud_val = 0;
int32_t id_val = 0;
if (instr->Bit(7) == 0) { // vcvtsu, vcvtdu
- ud_val = bit_cast<uint32_t, float>(sm_val);
+ ud_val = static_cast<uint32_t>(sm_int);
} else { // vcvtsi, vcvtdi
- id_val = bit_cast<int32_t, float>(sm_val);
+ id_val = sm_int;
}
if (instr->Bit(8) == 0) {
float sd_val;
@@ -2810,13 +2834,13 @@
ASSERT((id_val >= 0) || !(dm_val >= 0.0));
}
}
- float sd_val;
+ int32_t sd_val;
if (instr->Bit(16) == 0) {
- sd_val = bit_cast<float, uint32_t>(ud_val);
+ sd_val = static_cast<int32_t>(ud_val);
} else {
- sd_val = bit_cast<float, int32_t>(id_val);
+ sd_val = id_val;
}
- set_sregister(sd, sd_val);
+ set_sregister_bits(sd, sd_val);
break;
}
case 2: // vcvtb, vcvtt
@@ -2841,10 +2865,10 @@
SRegister sn = instr->SnField();
if (instr->Bit(20) == 0) {
// Format(instr, "vmovs'cond 'sn, 'rd");
- set_sregister(sn, bit_cast<float, int32_t>(get_register(rd)));
+ set_sregister_bits(sn, get_register(rd));
} else {
// Format(instr, "vmovr'cond 'rd, 'sn");
- set_register(rd, bit_cast<int32_t, float>(get_sregister(sn)));
+ set_register(rd, get_sregister_bits(sn));
}
} else if ((instr->Bits(20, 4) == 0xf) && (instr->Bit(8) == 0) &&
(instr->Bits(12, 4) == 0xf)) {
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 5ccfc09..3b4a5ca 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -51,6 +51,14 @@
void set_dregister(DRegister reg, double value);
double get_dregister(DRegister reg) const;
+ // When moving integer (rather than floating point) values to/from
+ // the FPU registers, use the _bits calls to avoid gcc taking liberties with
+ // integers that map to such things as NaN floating point values.
+ void set_sregister_bits(SRegister reg, int32_t value);
+ int32_t get_sregister_bits(SRegister reg) const;
+ void set_dregister_bits(DRegister reg, int64_t value);
+ int64_t get_dregister_bits(DRegister reg) const;
+
// Accessor to the internal simulator stack top.
uword StackTop() const;
@@ -119,8 +127,8 @@
// VFP state.
union { // S and D register banks are overlapping.
- float sregisters_[kNumberOfSRegisters];
- double dregisters_[kNumberOfDRegisters];
+ int32_t sregisters_[kNumberOfSRegisters];
+ int64_t dregisters_[kNumberOfDRegisters];
};
bool fp_n_flag_;
bool fp_z_flag_;
diff --git a/sdk/lib/_collection_dev/iterable.dart b/sdk/lib/_collection_dev/iterable.dart
index 53b297f..a33b4a0 100644
--- a/sdk/lib/_collection_dev/iterable.dart
+++ b/sdk/lib/_collection_dev/iterable.dart
@@ -694,7 +694,7 @@
class IterableMixinWorkaround {
static bool contains(Iterable iterable, var element) {
for (final e in iterable) {
- if (element == e) return true;
+ if (e == element) return true;
}
return false;
}
diff --git a/sdk/lib/_internal/compiler/compiler.dart b/sdk/lib/_internal/compiler/compiler.dart
index e0be239..8e5f77f 100644
--- a/sdk/lib/_internal/compiler/compiler.dart
+++ b/sdk/lib/_internal/compiler/compiler.dart
@@ -137,7 +137,7 @@
/**
* Any other warning that is not covered by [WARNING].
*/
- static const Diagnostic LINT = const Diagnostic(4, 'lint');
+ static const Diagnostic HINT = const Diagnostic(4, 'hint');
/**
* Informational messages.
diff --git a/sdk/lib/_internal/compiler/implementation/closure.dart b/sdk/lib/_internal/compiler/implementation/closure.dart
index 3815390..1863265 100644
--- a/sdk/lib/_internal/compiler/implementation/closure.dart
+++ b/sdk/lib/_internal/compiler/implementation/closure.dart
@@ -515,20 +515,6 @@
if (type != null && type.containsTypeVariables) {
registerNeedsThis();
}
- } else if (node.isParameterCheck) {
- Element parameter = elements[node.receiver];
- FunctionElement enclosing = parameter.enclosingElement;
- FunctionExpression function = enclosing.parseNode(compiler);
- ClosureClassMap cached = closureMappingCache[function];
- if (!cached.parametersWithSentinel.containsKey(parameter)) {
- SourceString parameterName = parameter.name;
- String name = '${parameterName.slowToString()}_check';
- Element newElement = new CheckVariableElement(new SourceString(name),
- parameter,
- enclosing);
- useLocal(newElement);
- cached.parametersWithSentinel[parameter] = newElement;
- }
} else if (node.isTypeTest) {
DartType type = elements.getType(node.typeAnnotationFromIsCheckOrCast);
analyzeType(type);
diff --git a/sdk/lib/_internal/compiler/implementation/colors.dart b/sdk/lib/_internal/compiler/implementation/colors.dart
index 42b3e7f..0c10085 100644
--- a/sdk/lib/_internal/compiler/implementation/colors.dart
+++ b/sdk/lib/_internal/compiler/implementation/colors.dart
@@ -4,12 +4,26 @@
library colors;
-const String GREEN_COLOR = '\u001b[32m';
-const String RED_COLOR = '\u001b[31m';
-const String MAGENTA_COLOR = '\u001b[35m';
-const String NO_COLOR = '\u001b[0m';
+// See http://en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes
+const String RESET = '\u001b[0m';
-String wrap(String string, String color) => "${color}$string${NO_COLOR}";
-String green(String string) => wrap(string, GREEN_COLOR);
+// See http://en.wikipedia.org/wiki/ANSI_escape_code#Colors
+const String BLACK_COLOR = '\u001b[30m';
+const String RED_COLOR = '\u001b[31m';
+const String GREEN_COLOR = '\u001b[32m';
+const String YELLOW_COLOR = '\u001b[33m';
+const String BLUE_COLOR = '\u001b[34m';
+const String MAGENTA_COLOR = '\u001b[35m';
+const String CYAN_COLOR = '\u001b[36m';
+const String WHITE_COLOR = '\u001b[37m';
+
+String wrap(String string, String color) => "${color}$string${RESET}";
+
+String black(String string) => wrap(string, BLACK_COLOR);
String red(String string) => wrap(string, RED_COLOR);
+String green(String string) => wrap(string, GREEN_COLOR);
+String yellow(String string) => wrap(string, YELLOW_COLOR);
+String blue(String string) => wrap(string, BLUE_COLOR);
String magenta(String string) => wrap(string, MAGENTA_COLOR);
+String cyan(String string) => wrap(string, CYAN_COLOR);
+String white(String string) => wrap(string, WHITE_COLOR);
diff --git a/sdk/lib/_internal/compiler/implementation/compiler.dart b/sdk/lib/_internal/compiler/implementation/compiler.dart
index a5ac2e0..e10326a 100644
--- a/sdk/lib/_internal/compiler/implementation/compiler.dart
+++ b/sdk/lib/_internal/compiler/implementation/compiler.dart
@@ -1147,6 +1147,13 @@
api.Diagnostic.INFO);
}
+ void reportHint(Spannable node, MessageKind errorCode,
+ [Map arguments = const {}]) {
+ reportMessage(spanFromSpannable(node),
+ errorCode.error(arguments),
+ api.Diagnostic.HINT);
+ }
+
void reportInternalError(Spannable node, String message) {
reportMessage(spanFromSpannable(node),
MessageKind.GENERIC.error({'text': message}),
diff --git a/sdk/lib/_internal/compiler/implementation/constants.dart b/sdk/lib/_internal/compiler/implementation/constants.dart
index 06e04fc..5e3a429 100644
--- a/sdk/lib/_internal/compiler/implementation/constants.dart
+++ b/sdk/lib/_internal/compiler/implementation/constants.dart
@@ -5,7 +5,6 @@
part of dart2js;
abstract class ConstantVisitor<R> {
- R visitSentinel(SentinelConstant constant);
R visitFunction(FunctionConstant constant);
R visitNull(NullConstant constant);
R visitInt(IntConstant constant);
@@ -53,22 +52,6 @@
accept(ConstantVisitor visitor);
}
-class SentinelConstant extends Constant {
- const SentinelConstant();
- static final SENTINEL = const SentinelConstant();
-
- List<Constant> getDependencies() => const <Constant>[];
-
- // Just use a random value.
- int get hashCode => 24297418;
-
- bool isSentinel() => true;
-
- accept(ConstantVisitor visitor) => visitor.visitSentinel(this);
-
- DartType computeType(Compiler compiler) => compiler.types.dynamicType;
-}
-
class FunctionConstant extends Constant {
Element element;
@@ -108,6 +91,8 @@
return value == otherPrimitive.value;
}
+ int get hashCode => throw new UnsupportedError('PrimitiveConstant.hashCode');
+
String toString() => value.toString();
// Primitive constants don't have dependencies.
List<Constant> getDependencies() => const <Constant>[];
diff --git a/sdk/lib/_internal/compiler/implementation/dart2js.dart b/sdk/lib/_internal/compiler/implementation/dart2js.dart
index ce1690b..635f8f0 100644
--- a/sdk/lib/_internal/compiler/implementation/dart2js.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart2js.dart
@@ -227,6 +227,8 @@
(_) => diagnosticHandler.throwOnError = true),
new OptionHandler('--suppress-warnings',
(_) => diagnosticHandler.showWarnings = false),
+ new OptionHandler('--suppress-hints',
+ (_) => diagnosticHandler.showHints = false),
new OptionHandler('--output-type=dart|--output-type=js', setOutputType),
new OptionHandler('--verbose', setVerbose),
new OptionHandler('--version', (_) => wantVersion = true),
@@ -479,6 +481,9 @@
--suppress-warnings
Do not display any warnings.
+ --suppress-hints
+ Do not display any hints.
+
--enable-diagnostic-colors
Add colors to diagnostic messages.
diff --git a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
index 83a067fe..01cdbe9 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_backend/placeholder_collector.dart
@@ -49,12 +49,6 @@
SendVisitor(this.collector, TreeElements elements) : super(elements);
visitOperatorSend(Send node) {
- if (node.isParameterCheck) {
- final element = elements[node.receiver];
- if (element != null) {
- collector.tryMakeLocalPlaceholder(element, node.receiver);
- }
- }
}
visitForeignSend(Send node) {}
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index d4fc525..fd9ed63 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -94,6 +94,8 @@
*/
bool forEachMalformedType(bool f(MalformedType type)) => true;
+ // TODO(ahe): This is implicitly inherited from Object. What is the purpose
+ // of duplicating it here?
bool operator ==(other);
/**
@@ -319,6 +321,9 @@
*/
final Link<DartType> typeArguments;
+ final int hashCode = (nextHash++) & 0x3fffffff;
+ static int nextHash = 43765;
+
MalformedType(this.element, this.userProvidedBadType,
[this.typeArguments = null]);
@@ -341,6 +346,8 @@
return visitor.visitMalformedType(this, argument);
}
+ // TODO(ahe): This is the default implementation that would be inherited if
+ // DartType didn't declare an abstract method. What is the purpose?
bool operator ==(other) => identical(this, other);
String toString() {
@@ -547,10 +554,18 @@
}
bool operator ==(other) {
+ // TODO(johnniwinther,karlklose): This is a bad implementation of
+ // operator==. This implementation is not compatible with the
+ // implementation in the superclass: another subclass of GenericType might
+ // compare equal to an instance of this class if the other subclass forgets
+ // to implement operator==. This is brittle and easy to avoid, ask ahe@
+ // for concrete suggestions.
if (other is !InterfaceType) return false;
return super == other;
}
+ int get hashCode => super.hashCode;
+
InterfaceType asRaw() => super.asRaw();
accept(DartTypeVisitor visitor, var argument) {
@@ -812,10 +827,13 @@
}
bool operator ==(other) {
+ // TODO(johnniwinther,karlklose): See InterfaceType.operator==.
if (other is !TypedefType) return false;
return super == other;
}
+ int get hashCode => super.hashCode;
+
TypedefType asRaw() => super.asRaw();
accept(DartTypeVisitor visitor, var argument) {
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index 3d90f47..0d78456 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -338,6 +338,8 @@
getLibrary() => enclosingElement.getLibrary();
+ computeTargetType(Compiler compiler, InterfaceType newType) => unsupported();
+
String toString() {
String n = name.slowToString();
return '<$n: ${messageKind.message(messageArguments)}>';
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
index c3cff04..ace154a 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/constant_emitter.dart
@@ -61,10 +61,6 @@
return constant.accept(this);
}
- jsAst.Expression visitSentinel(SentinelConstant constant) {
- return new jsAst.VariableUse(namer.CURRENT_ISOLATE);
- }
-
jsAst.Expression visitFunction(FunctionConstant constant) {
return new jsAst.VariableUse(
namer.isolateStaticClosureAccess(constant.element));
@@ -173,11 +169,6 @@
return referenceEmitter.generateInInitializationContext(constant);
}
- jsAst.Expression visitSentinel(SentinelConstant constant) {
- compiler.internalError(
- "The parameter sentinel constant does not need specific JS code");
- }
-
jsAst.Expression visitFunction(FunctionConstant constant) {
compiler.internalError(
"The function constant does not need specific JS code");
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
index 0a2f53a..e502f25 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart
@@ -1009,9 +1009,6 @@
argumentsBuffer[count] = js(jsName);
parametersBuffer[optionalParameterStart + index] =
new jsAst.Parameter(jsName);
- // Note that [elements] may be null for a synthesized [member].
- } else if (elements != null && elements.isParameterChecked(element)) {
- argumentsBuffer[count] = constantReference(SentinelConstant.SENTINEL);
} else {
Constant value = handler.initialVariableValues[element];
if (value == null) {
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
index a15f5e0..61f6d84 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/namer.dart
@@ -976,10 +976,6 @@
return constant.accept(this);
}
- visitSentinel(SentinelConstant constant) {
- add(r'$');
- }
-
visitFunction(FunctionConstant constant) {
add(constant.element.name.slowToString());
}
@@ -1094,10 +1090,9 @@
return hash;
}
- int visitSentinel(SentinelConstant constant) => 1;
- int visitNull(NullConstant constant) => 2;
- int visitTrue(TrueConstant constant) => 3;
- int visitFalse(FalseConstant constant) => 4;
+ int visitNull(NullConstant constant) => 1;
+ int visitTrue(TrueConstant constant) => 2;
+ int visitFalse(FalseConstant constant) => 3;
int visitFunction(FunctionConstant constant) {
return _hashString(1, constant.element.name.slowToString());
diff --git a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
index 76b9efc..3adbd63 100644
--- a/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_backend/runtime_types.dart
@@ -826,6 +826,8 @@
class TypeCheck {
final ClassElement cls;
final Substitution substitution;
+ final int hashCode = (nextHash++) & 0x3fffffff;
+ static int nextHash = 49;
TypeCheck(this.cls, this.substitution);
}
diff --git a/sdk/lib/_internal/compiler/implementation/mirrors/util.dart b/sdk/lib/_internal/compiler/implementation/mirrors/util.dart
index 72b05b9..db94f02 100644
--- a/sdk/lib/_internal/compiler/implementation/mirrors/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/mirrors/util.dart
@@ -10,10 +10,10 @@
* [:operator []:], [:forEach:] and [:length:] methods to provide a fully
* implemented immutable map.
*/
-abstract class AbstractMap<K,V> implements Map<K,V> {
+abstract class AbstractMap<K, V> implements Map<K, V> {
AbstractMap();
- AbstractMap.from(Map<K,V> other) {
+ AbstractMap.from(Map<K, V> other) {
other.forEach((k,v) => this[k] = v);
}
@@ -24,6 +24,10 @@
void clear() {
throw new UnsupportedError('clear() is not supported');
}
+
+ void addAll(Map<K, V> other) {
+ throw new UnsupportedError('addAll() is not supported');
+ }
bool containsKey(K key) {
var found = false;
@@ -77,8 +81,8 @@
* [ImmutableMapWrapper] wraps a (mutable) map as an immutable map where all
* mutating operations throw [UnsupportedError] upon invocation.
*/
-class ImmutableMapWrapper<K,V> extends AbstractMap<K,V> {
- final Map<K,V> _map;
+class ImmutableMapWrapper<K, V> extends AbstractMap<K, V> {
+ final Map<K, V> _map;
ImmutableMapWrapper(this._map);
@@ -104,10 +108,10 @@
/**
* An immutable map wrapper capable of filtering the input map.
*/
-class FilteredImmutableMap<K,V> extends ImmutableMapWrapper<K,V> {
+class FilteredImmutableMap<K, V> extends ImmutableMapWrapper<K, V> {
final Filter<V> _filter;
- FilteredImmutableMap(Map<K,V> map, this._filter) : super(map);
+ FilteredImmutableMap(Map<K, V> map, this._filter) : super(map);
int get length {
var count = 0;
diff --git a/sdk/lib/_internal/compiler/implementation/native_handler.dart b/sdk/lib/_internal/compiler/implementation/native_handler.dart
index c6f20a0..687003a 100644
--- a/sdk/lib/_internal/compiler/implementation/native_handler.dart
+++ b/sdk/lib/_internal/compiler/implementation/native_handler.dart
@@ -25,8 +25,9 @@
/// The type Object, but no subtypes:
static const JsObject = const SpecialType._('=Object');
-}
+ int get hashCode => name.hashCode;
+}
/**
* This could be an abstract class but we use it as a stub for the dart_backend.
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index 4f619ce..549a086 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -16,7 +16,6 @@
Selector getGetterSelectorInComplexSendSet(SendSet node);
Selector getOperatorSelectorInComplexSendSet(SendSet node);
DartType getType(Node node);
- bool isParameterChecked(Element element);
void setSelector(Node node, Selector selector);
void setGetterSelectorInComplexSendSet(SendSet node, Selector selector);
void setOperatorSelectorInComplexSendSet(SendSet node, Selector selector);
@@ -37,7 +36,6 @@
final Map<Spannable, Selector> selectors =
new LinkedHashMap<Spannable, Selector>();
final Map<Node, DartType> types = new LinkedHashMap<Node, DartType>();
- final Set<Element> checkedParameters = new LinkedHashSet<Element>();
final Set<Node> superUses = new LinkedHashSet<Node>();
final Set<Element> otherDependencies = new LinkedHashSet<Element>();
final int hashCode = ++hashCodeCounter;
@@ -134,10 +132,6 @@
return selectors[node.inToken];
}
- bool isParameterChecked(Element element) {
- return checkedParameters.contains(element);
- }
-
void registerDependency(Element element) {
otherDependencies.add(element.implementation);
}
@@ -778,6 +772,7 @@
} else if (isBinaryOperator(value)) {
messageKind = MessageKind.BINARY_OPERATOR_BAD_ARITY;
requiredParameterCount = 1;
+ if (identical(value, '==')) checkOverrideHashCode(member);
} else if (isTernaryOperator(value)) {
messageKind = MessageKind.TERNARY_OPERATOR_BAD_ARITY;
requiredParameterCount = 2;
@@ -788,6 +783,17 @@
checkArity(function, requiredParameterCount, messageKind, isMinus);
}
+ void checkOverrideHashCode(FunctionElement operatorEquals) {
+ if (operatorEquals.isAbstract(compiler)) return;
+ ClassElement cls = operatorEquals.getEnclosingClass();
+ Element hashCodeImplementation =
+ cls.lookupLocalMember(const SourceString('hashCode'));
+ if (hashCodeImplementation != null) return;
+ compiler.reportHint(
+ operatorEquals, MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
+ {'class': cls.name.slowToString()});
+ }
+
void checkArity(FunctionElement function,
int requiredParameterCount, MessageKind messageKind,
bool isMinus) {
@@ -2236,7 +2242,7 @@
sendIsMemberAccess = oldSendIsMemberAccess;
if (target != null && target == compiler.mirrorSystemGetNameFunction) {
- compiler.reportWarningCode(
+ compiler.reportHint(
node.selector, MessageKind.STATIC_FUNCTION_BLOAT,
{'class': compiler.mirrorSystemClass.name,
'name': compiler.mirrorSystemGetNameFunction.name});
@@ -2285,14 +2291,6 @@
compiler.enqueuer.resolution.registerAsCheck(type, mapping);
}
resolvedArguments = true;
- } else if (identical(operatorString, '?')) {
- Element parameter = mapping[node.receiver];
- if (parameter == null
- || !identical(parameter.kind, ElementKind.PARAMETER)) {
- error(node.receiver, MessageKind.PARAMETER_NAME_EXPECTED);
- } else {
- mapping.checkedParameters.add(parameter);
- }
}
}
@@ -2656,7 +2654,7 @@
}
}
} else {
- compiler.reportWarningCode(
+ compiler.reportHint(
node.newToken, MessageKind.NON_CONST_BLOAT,
{'name': compiler.symbolClass.name});
world.registerNewSymbol(mapping);
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
index 17f790c..5c69c08 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/listener.dart
@@ -11,12 +11,6 @@
* on parser errors.
*/
class Listener {
- void beginArgumentDefinitionTest(Token token) {
- }
-
- void endArgumentDefinitionTest(Token beginToken, Token endToken) {
- }
-
void beginArguments(Token token) {
}
@@ -1174,10 +1168,6 @@
pushNode(tag);
}
- void endArgumentDefinitionTest(Token beginToken, Token endToken) {
- pushNode(new Send.prefix(popNode(), new Operator(beginToken)));
- }
-
void endClassDeclaration(int interfacesCount, Token beginToken,
Token extendsKeyword, Token implementsKeyword,
Token endToken) {
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
index 7708cac..78329cc 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/parser.dart
@@ -1531,22 +1531,11 @@
(identical(kind, OPEN_CURLY_BRACKET_TOKEN)) ||
identical(token.stringValue, '[]')) {
return parseLiteralListOrMap(token);
- } else if (identical(kind, QUESTION_TOKEN)) {
- return parseArgumentDefinitionTest(token);
} else {
return listener.expectedExpression(token);
}
}
- Token parseArgumentDefinitionTest(Token token) {
- Token questionToken = token;
- listener.beginArgumentDefinitionTest(questionToken);
- assert(optional('?', token));
- token = parseIdentifier(token.next);
- listener.endArgumentDefinitionTest(questionToken, token);
- return token;
- }
-
Token parseParenthesizedExpressionOrFunctionLiteral(Token token) {
BeginGroupToken beginGroup = token;
int kind = beginGroup.endGroup.next.kind;
diff --git a/sdk/lib/_internal/compiler/implementation/scanner/token.dart b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
index 23b4f78..fb4a1e0 100644
--- a/sdk/lib/_internal/compiler/implementation/scanner/token.dart
+++ b/sdk/lib/_internal/compiler/implementation/scanner/token.dart
@@ -150,6 +150,8 @@
return slowToString().length;
}
}
+
+ int get hashCode => computeHashCode(charOffset, info, value);
}
/**
@@ -312,6 +314,8 @@
const PrecedenceInfo(this.value, this.precedence, this.kind);
toString() => 'PrecedenceInfo($value, $precedence, $kind)';
+
+ int get hashCode => computeHashCode(value, precedence, kind);
}
// TODO(ahe): The following are not tokens in Dart.
diff --git a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
index 9916c98..b990532 100644
--- a/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
+++ b/sdk/lib/_internal/compiler/implementation/source_file_provider.dart
@@ -53,10 +53,12 @@
class FormattingDiagnosticHandler {
final SourceFileProvider provider;
bool showWarnings = true;
+ bool showHints = true;
bool verbose = false;
bool isAborting = false;
bool enableColors = false;
bool throwOnError = false;
+ api.Diagnostic lastKind = null;
final int FATAL = api.Diagnostic.CRASH.ordinal | api.Diagnostic.ERROR.ordinal;
final int INFO =
@@ -67,7 +69,7 @@
(provider == null) ? new SourceFileProvider() : provider;
void info(var message, [api.Diagnostic kind = api.Diagnostic.VERBOSE_INFO]) {
- if (!verbose && identical(kind, api.Diagnostic.VERBOSE_INFO)) return;
+ if (!verbose && kind == api.Diagnostic.VERBOSE_INFO) return;
if (enableColors) {
print('${colors.green("info:")} $message');
} else {
@@ -81,33 +83,45 @@
if (identical(kind.name, 'source map')) return;
if (isAborting) return;
- isAborting = identical(kind, api.Diagnostic.CRASH);
+ isAborting = (kind == api.Diagnostic.CRASH);
bool fatal = (kind.ordinal & FATAL) != 0;
bool isInfo = (kind.ordinal & INFO) != 0;
- if (isInfo && uri == null && !identical(kind, api.Diagnostic.INFO)) {
+ if (isInfo && uri == null && kind != api.Diagnostic.INFO) {
info(message, kind);
return;
}
+ // [previousKind]/[lastKind] records the previous non-INFO kind we saw.
+ // This is used to suppress info about a warning when warnings are
+ // suppressed, and similar for hints.
+ var previousKind = lastKind;
+ if (previousKind != api.Diagnostic.INFO) {
+ lastKind = kind;
+ }
var color;
- if (!enableColors) {
- color = (x) => x;
- } else if (identical(kind, api.Diagnostic.ERROR)) {
+ if (kind == api.Diagnostic.ERROR) {
color = colors.red;
- } else if (identical(kind, api.Diagnostic.WARNING)) {
+ } else if (kind == api.Diagnostic.WARNING) {
+ if (!showWarnings) return;
color = colors.magenta;
- } else if (identical(kind, api.Diagnostic.LINT)) {
- color = colors.magenta;
- } else if (identical(kind, api.Diagnostic.CRASH)) {
+ } else if (kind == api.Diagnostic.HINT) {
+ if (!showHints) return;
+ color = colors.cyan;
+ } else if (kind == api.Diagnostic.CRASH) {
color = colors.red;
- } else if (identical(kind, api.Diagnostic.INFO)) {
+ } else if (kind == api.Diagnostic.INFO) {
+ if (lastKind == api.Diagnostic.WARNING && !showWarnings) return;
+ if (lastKind == api.Diagnostic.HINT && !showHints) return;
color = colors.green;
} else {
throw 'Unknown kind: $kind (${kind.ordinal})';
}
+ if (!enableColors) {
+ color = (x) => x;
+ }
if (uri == null) {
assert(fatal);
print(color(message));
- } else if (fatal || showWarnings) {
+ } else {
SourceFile file = provider.sourceFiles[uri.toString()];
if (file == null) {
throw '$uri: file is null';
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
index 3b3c999..a73f41c 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/builder.dart
@@ -1401,12 +1401,6 @@
compiler.closureToClassMapper.computeClosureToClassMapping(
constructor, node, elements);
localsHandler.closureData = newClosureData;
-
- params.orderedForEachParameter((Element parameterElement) {
- if (elements.isParameterChecked(parameterElement)) {
- addParameterCheckInstruction(parameterElement);
- }
- });
localsHandler.enterScope(node, constructor);
buildInitializers(constructor, constructors, fieldValues);
localsHandler.closureData = oldClosureData;
@@ -1623,18 +1617,6 @@
}
});
- // Provide the parameter checks to the generative constructor
- // body.
- functionSignature.orderedForEachParameter((parameter) {
- // If [parameter] is checked, we pass the already computed
- // boolean to the constructor body.
- if (elements.isParameterChecked(parameter)) {
- Element fieldCheck =
- parameterClosureData.parametersWithSentinel[parameter];
- bodyCallInputs.add(localsHandler.readLocal(fieldCheck));
- }
- });
-
ClassElement currentClass = constructor.getEnclosingClass();
if (backend.classNeedsRti(currentClass)) {
// If [currentClass] needs RTI, we add the type variables as
@@ -1670,56 +1652,6 @@
}
}
- void addParameterCheckInstruction(Element element) {
- HInstruction check;
- Element checkResultElement =
- localsHandler.closureData.parametersWithSentinel[element];
- if (currentElement.isGenerativeConstructorBody()) {
- // A generative constructor body receives extra parameters that
- // indicate if a parameter was passed to the factory.
- check = addParameter(checkResultElement);
- } else {
- // This is the code we emit for a parameter that is being checked
- // on whether it was given at value at the call site:
- //
- // foo([a = 42]) {
- // if (?a) print('parameter passed $a');
- // }
- //
- // foo([a = 42]) {
- // var t1 = identical(a, sentinel);
- // if (t1) a = 42;
- // if (!t1) print('parameter passed ' + a);
- // }
-
- // Fetch the original default value of [element];
- Constant constant = compileVariable(element);
- HConstant defaultValue = constant == null
- ? graph.addConstantNull(compiler)
- : graph.addConstant(constant, compiler);
-
- // Emit the equality check with the sentinel.
- HConstant sentinel =
- graph.addConstant(SentinelConstant.SENTINEL, compiler);
- HInstruction operand = parameters[element];
- check = new HIdentity(sentinel, operand);
- add(check);
-
- // If the check succeeds, we must update the parameter with the
- // default value.
- handleIf(element.parseNode(compiler),
- () => stack.add(check),
- () => localsHandler.updateLocal(element, defaultValue),
- null);
-
- // Create the instruction that parameter checks will use.
- check = new HNot(check);
- add(check);
- }
-
- localsHandler.updateLocal(checkResultElement, check);
- }
-
/**
* Documentation wanted -- johnniwinther
*
@@ -1750,11 +1682,6 @@
if (element is FunctionElement) {
FunctionElement functionElement = element;
FunctionSignature signature = functionElement.computeSignature(compiler);
- signature.orderedForEachParameter((Element parameterElement) {
- if (elements.isParameterChecked(parameterElement)) {
- addParameterCheckInstruction(parameterElement);
- }
- });
// Put the type checks in the first successor of the entry,
// because that is where the type guards will also be inserted.
@@ -2532,16 +2459,6 @@
}
void visitUnary(Send node, Operator op) {
- if (node.isParameterCheck) {
- Element element = elements[node.receiver];
- Node function = element.enclosingElement.parseNode(compiler);
- ClosureClassMap parameterClosureData =
- compiler.closureToClassMapper.getMappingForNestedFunction(function);
- Element fieldCheck =
- parameterClosureData.parametersWithSentinel[element];
- stack.add(localsHandler.readLocal(fieldCheck));
- return;
- }
assert(node.argumentsNode is Prefix);
visit(node.receiver);
assert(!identical(op.token.kind, PLUS_TOKEN));
@@ -2942,15 +2859,7 @@
}
HInstruction handleConstantForOptionalParameter(Element parameter) {
- Constant constant;
- Element element = parameter.enclosingElement;
- TreeElements calleeElements =
- compiler.enqueuer.resolution.getCachedElements(element);
- if (calleeElements.isParameterChecked(parameter)) {
- constant = SentinelConstant.SENTINEL;
- } else {
- constant = compileConstant(parameter);
- }
+ Constant constant = compileConstant(parameter);
return graph.addConstant(constant, compiler);
}
@@ -5231,10 +5140,6 @@
void visitSend(Send node) {
if (!registerNode()) return;
- if (node.isParameterCheck) {
- tooDifficult = true;
- return;
- }
node.visitChildren(this);
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/types.dart b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
index 38cc812..fd8d660 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/types.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/types.dart
@@ -533,12 +533,14 @@
return isIndexablePrimitive(compiler);
}
- bool operator ==(HType other) {
+ bool operator ==(other) {
if (other is !HBoundedType) return false;
HBoundedType bounded = other;
return mask == bounded.mask;
}
+ int get hashCode => mask.hashCode;
+
String toString() {
return 'BoundedType(mask=$mask)';
}
diff --git a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
index e067089..42560e0 100644
--- a/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
+++ b/sdk/lib/_internal/compiler/implementation/ssa/value_range_analyzer.dart
@@ -148,6 +148,8 @@
return this.value == other.value;
}
+ int get hashCode => throw new UnsupportedError('IntValue.hashCode');
+
String toString() => 'IntValue $value';
bool get isNegative => value < 0;
bool get isPositive => value >= 0;
@@ -214,6 +216,8 @@
return this.instruction == other.instruction;
}
+ int get hashCode => throw new UnsupportedError('InstructionValue.hashCode');
+
Value operator +(Value other) {
if (other.isZero) return this;
if (other is IntValue) {
@@ -283,6 +287,8 @@
|| (left == other.right && right == other.left);
}
+ int get hashCode => throw new UnsupportedError('AddValue.hashCode');
+
Value operator -() => -left - right;
Value operator +(Value other) {
@@ -328,6 +334,8 @@
return left == other.left && right == other.right;
}
+ int get hashCode => throw new UnsupportedError('SubtractValue.hashCode');
+
Value operator -() => right - left;
Value operator +(Value other) {
@@ -374,6 +382,8 @@
return value == other.value;
}
+ int get hashCode => throw new UnsupportedError('Negate.hashCode');
+
Value operator +(other) {
if (other.isZero) return this;
if (other == value) return info.intZero;
@@ -506,6 +516,8 @@
return other.lower == lower && other.upper == upper;
}
+ int get hashCode => throw new UnsupportedError('Range.hashCode');
+
bool operator <(Range other) {
return upper != other.lower && upper.min(other.lower) == upper;
}
diff --git a/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart b/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
index 8f962ad..80f2091 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/dartstring.dart
@@ -43,6 +43,9 @@
}
return true;
}
+
+ int get hashCode => throw new UnsupportedError('DartString.hashCode');
+
String toString() => "DartString#${length}:${slowToString()}";
SourceString get source;
}
diff --git a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
index 81a51d3..42899b8 100644
--- a/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
+++ b/sdk/lib/_internal/compiler/implementation/tree/nodes.dart
@@ -366,8 +366,6 @@
isOperator && identical(selector.asOperator().source.stringValue, '&&');
bool get isLogicalOr =>
isOperator && identical(selector.asOperator().source.stringValue, '||');
- bool get isParameterCheck =>
- isOperator && identical(selector.asOperator().source.stringValue, '?');
bool get isTypeCast {
return isOperator
diff --git a/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
index f74db6e..f9fc659 100644
--- a/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/container_type_mask.dart
@@ -10,6 +10,8 @@
class ElementTypeHolder {
// This field will be set after global analysis.
TypeMask elementType;
+
+ int get hashCode => elementType.hashCode;
}
/// A [ContainerTypeMask] is a [TypeMask] for a specific allocation
@@ -81,6 +83,8 @@
&& isNullable == other.isNullable;
}
+ int get hashCode => computeHashCode(allocationNode, isNullable);
+
String toString() {
return 'Container mask: $elementType';
}
diff --git a/sdk/lib/_internal/compiler/implementation/types/element_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/element_type_mask.dart
index 0ebb9f0..75e2345 100644
--- a/sdk/lib/_internal/compiler/implementation/types/element_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/element_type_mask.dart
@@ -31,6 +31,8 @@
return element == other.element && isNullable == other.isNullable;
}
+ int get hashCode => computeHashCode(element, isNullable);
+
bool equalsDisregardNull(other) {
if (other is! ElementTypeMask) return false;
return element == other.element;
diff --git a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
index 81d00bb..865c198 100644
--- a/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/inferrer_visitor.dart
@@ -418,9 +418,6 @@
TypeMask receiverType = visit(node.receiver);
DartType type = elements.getType(node.arguments.head);
return narrowType(receiverType, type, compiler);
- } else if (node.isParameterCheck) {
- node.visitChildren(this);
- return inferrer.boolType;
} else if (node.argumentsNode is Prefix) {
// Unary operator.
return visitDynamicSend(node);
diff --git a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
index e28ffaa..2473f80 100644
--- a/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/simple_types_inferrer.dart
@@ -1338,6 +1338,8 @@
return true;
}
+ int get hashCode => throw new UnsupportedError('ArgumentsTypes.hashCode');
+
bool hasNoArguments() => positional.isEmpty && named.isEmpty;
bool hasOnePositionalArgumentWithType(TypeMask type) {
diff --git a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
index 8f1a4ff..ed4eb2b 100644
--- a/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
+++ b/sdk/lib/_internal/compiler/implementation/types/union_type_mask.dart
@@ -266,4 +266,12 @@
&& other.disjointMasks.length == disjointMasks.length
&& other.disjointMasks.every((e) => disjointMasks.contains(e));
}
+
+ int get hashCode {
+ int hashCode = 43;
+ for (var mask in disjointMasks) {
+ hashCode = (hashCode ^ mask.hashCode) & 0x3fffffff;
+ }
+ return hashCode;
+ }
}
diff --git a/sdk/lib/_internal/compiler/implementation/universe/side_effects.dart b/sdk/lib/_internal/compiler/implementation/universe/side_effects.dart
index 1e27efa..d6b06ad 100644
--- a/sdk/lib/_internal/compiler/implementation/universe/side_effects.dart
+++ b/sdk/lib/_internal/compiler/implementation/universe/side_effects.dart
@@ -32,6 +32,8 @@
bool operator==(other) => flags == other.flags;
+ int get hashCode => throw new UnsupportedError('SideEffects.hashCode');
+
bool getFlag(int position) => (flags & (1 << position)) != 0;
void setFlag(int position) { flags |= (1 << position); }
void clearFlag(int position) { flags &= ~(1 << position); }
diff --git a/sdk/lib/_internal/compiler/implementation/util/link.dart b/sdk/lib/_internal/compiler/implementation/util/link.dart
index f46af2d..114d3bf 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link.dart
@@ -74,6 +74,8 @@
return other.isEmpty;
}
+ int get hashCode => throw new UnsupportedError('Link.hashCode');
+
String toString() => "[]";
get length {
diff --git a/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart b/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
index 6743738..1f85236 100644
--- a/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/link_implementation.dart
@@ -100,6 +100,8 @@
return myElements.isEmpty && other.isEmpty;
}
+ int get hashCode => throw new UnsupportedError('LinkEntry.hashCode');
+
int slowLength() => 1 + tail.slowLength();
}
diff --git a/sdk/lib/_internal/compiler/implementation/util/util.dart b/sdk/lib/_internal/compiler/implementation/util/util.dart
index 94a0ce0..c9c8399 100644
--- a/sdk/lib/_internal/compiler/implementation/util/util.dart
+++ b/sdk/lib/_internal/compiler/implementation/util/util.dart
@@ -110,3 +110,10 @@
}
buffer.write(string);
}
+
+int computeHashCode(part1, [part2, part3, part4]) {
+ return (part1.hashCode
+ ^ part2.hashCode
+ ^ part3.hashCode
+ ^ part4.hashCode) & 0x3fffffff;
+}
diff --git a/sdk/lib/_internal/compiler/implementation/warnings.dart b/sdk/lib/_internal/compiler/implementation/warnings.dart
index 8f9b9cb..ee72964 100644
--- a/sdk/lib/_internal/compiler/implementation/warnings.dart
+++ b/sdk/lib/_internal/compiler/implementation/warnings.dart
@@ -412,10 +412,10 @@
" a class.");
static const STATIC_FUNCTION_BLOAT = const MessageKind(
- 'Warning: Using "#{class}.#{name}" may result in larger output.');
+ 'Hint: Using "#{class}.#{name}" may result in larger output.');
static const NON_CONST_BLOAT = const MessageKind('''
-Warning: Using "new #{name}" may result in larger output.
+Hint: Using "new #{name}" may result in larger output.
Use "const #{name}" if possible.''');
static const STRING_EXPECTED = const MessageKind(
@@ -433,13 +433,17 @@
* a qualified non-private identifier followed by "." and a user-defined operator.''');
static const AMBIGUOUS_REEXPORT = const MessageKind(
- 'Info: "#{element}" is (re)exported by multiple libraries.');
+ 'Info: "#{element}" is (re)exported by multiple libraries.');
static const AMBIGUOUS_LOCATION = const MessageKind(
- 'Info: "#{element}" is defined here.');
+ 'Info: "#{element}" is defined here.');
static const IMPORTED_HERE = const MessageKind(
- 'Info: "#{element}" is imported here.');
+ 'Info: "#{element}" is imported here.');
+
+ static const OVERRIDE_EQUALS_NOT_HASH_CODE = const MessageKind(
+ 'Hint: The class "#{class}" overrides "operator==", '
+ 'but not "get hashCode".');
static const COMPILER_CRASHED = const MessageKind(
"Error: The compiler crashed when compiling this element.");
@@ -596,6 +600,8 @@
return (kind == other.kind) && (toString() == other.toString());
}
+ int get hashCode => throw new UnsupportedError('Message.hashCode');
+
String slowToString(object) {
if (object is SourceString) {
return object.slowToString();
diff --git a/sdk/lib/_internal/lib/core_patch.dart b/sdk/lib/_internal/lib/core_patch.dart
index dec98f1..08d4be4 100644
--- a/sdk/lib/_internal/lib/core_patch.dart
+++ b/sdk/lib/_internal/lib/core_patch.dart
@@ -184,7 +184,7 @@
// Patch for List implementation.
patch class List<E> {
patch factory List([int length]) {
- if (!?length) return Primitives.newGrowableList(0);
+ if (length == null) return Primitives.newGrowableList(0);
// Explicit type test is necessary to protect Primitives.newFixedList in
// unchecked mode.
if ((length is !int) || (length < 0)) {
diff --git a/sdk/lib/_internal/lib/io_patch.dart b/sdk/lib/_internal/lib/io_patch.dart
index 4967d94..c565064 100644
--- a/sdk/lib/_internal/lib/io_patch.dart
+++ b/sdk/lib/_internal/lib/io_patch.dart
@@ -91,7 +91,10 @@
throw new UnsupportedError("File._deleteLink");
}
patch static _rename(String oldPath, String newPath) {
- throw new UnsupportedError("File._delete");
+ throw new UnsupportedError("File._rename");
+ }
+ patch static _renameLink(String oldPath, String newPath) {
+ throw new UnsupportedError("File._renameLink");
}
patch static _lengthFromPath(String path) {
throw new UnsupportedError("File._lengthFromPath");
diff --git a/sdk/lib/async/event_loop.dart b/sdk/lib/async/event_loop.dart
index bc0a638..9462460 100644
--- a/sdk/lib/async/event_loop.dart
+++ b/sdk/lib/async/event_loop.dart
@@ -55,7 +55,8 @@
* }
*/
void runAsync(void callback()) {
- _Zone._current.runAsync(callback);
+ _Zone currentZone = _Zone._current;
+ currentZone.runAsync(callback, currentZone);
}
class _AsyncRun {
diff --git a/sdk/lib/async/zone.dart b/sdk/lib/async/zone.dart
index 1379128..5f9fce9 100644
--- a/sdk/lib/async/zone.dart
+++ b/sdk/lib/async/zone.dart
@@ -38,8 +38,8 @@
* Tells the zone that it needs to wait for one more callback before it is
* done.
*
- * Use [executeCallback] or [cancelCallbackExpectation] when the callback is executed
- * (or canceled).
+ * Use [executeCallback] or [cancelCallbackExpectation] when the callback is
+ * executed (or canceled).
*/
void expectCallback();
@@ -54,35 +54,51 @@
void cancelCallbackExpectation();
/**
- * Executes the given callback in this zone.
+ * Executes the given callback [f] in this zone.
*
* Decrements the number of callbacks this zone is waiting for (see
* [expectCallback]).
*/
- void executeCallback(void fun());
+ void executeCallback(void f());
/**
* Same as [executeCallback] but catches uncaught errors and gives them to
* [handleUncaughtError].
*/
- void executeCallbackGuarded(void fun());
+ void executeCallbackGuarded(void f());
/**
* Same as [executeCallback] but does not decrement the number of
* callbacks this zone is waiting for (see [expectCallback]).
*/
- void executePeriodicCallback(void fun());
+ void executePeriodicCallback(void f());
/**
* Same as [executePeriodicCallback] but catches uncaught errors and gives
* them to [handleUncaughtError].
*/
- void executePeriodicCallbackGuarded(void fun());
+ void executePeriodicCallbackGuarded(void f());
/**
- * Runs [fun] asynchronously in this zone.
+ * Executes [f] in `this` zone.
+ *
+ * The behavior of this method should be the same as
+ * [executePeriodicCallback] except that it can have a return value.
+ *
+ * Returns the result of the invocation.
*/
- void runAsync(void fun());
+ runFromChildZone(f());
+
+ /**
+ * Same as [runFromChildZone] but catches uncaught errors and gives them to
+ * [handleUncaughtError].
+ */
+ runFromChildZoneGuarded(f());
+
+ /**
+ * Runs [f] asynchronously in [zone].
+ */
+ void runAsync(void f(), _Zone zone);
/**
* Creates a Timer where the callback is executed in this zone.
@@ -185,47 +201,33 @@
}
}
- /**
- * Executes the given callback in this zone.
- *
- * Decrements the open-callback counter and checks (after the call) if the
- * zone is done.
- */
- void executeCallback(void fun()) {
+ void executeCallback(void f()) {
_openCallbacks--;
- this._runUnguarded(fun);
+ this._runUnguarded(f);
}
- /**
- * Same as [executeCallback] but catches uncaught errors and gives them to
- * [handleUncaughtError].
- */
- void executeCallbackGuarded(void fun()) {
+ void executeCallbackGuarded(void f()) {
_openCallbacks--;
- this._runGuarded(fun);
+ this._runGuarded(f);
}
- /**
- * Same as [executeCallback] but doesn't decrement the open-callback counter.
- */
- void executePeriodicCallback(void fun()) {
- this._runUnguarded(fun);
+ void executePeriodicCallback(void f()) {
+ this._runUnguarded(f);
}
- /**
- * Same as [executePeriodicCallback] but catches uncaught errors and gives
- * them to [handleUncaughtError].
- */
- void executePeriodicCallbackGuarded(void fun()) {
- this._runGuarded(fun);
+ void executePeriodicCallbackGuarded(void f()) {
+ this._runGuarded(f);
}
- _runInZone(fun(), bool handleUncaught) {
+ runFromChildZone(f()) => this._runUnguarded(f);
+ runFromChildZoneGuarded(f()) => this._runGuarded(f);
+
+ _runInZone(f(), bool handleUncaught) {
if (identical(_Zone._current, this)
&& !handleUncaught
&& _isExecutingCallback) {
// No need to go through a try/catch.
- return fun();
+ return f();
}
_Zone oldZone = _Zone._current;
@@ -240,7 +242,7 @@
// TODO(430): remove second try when VM bug is fixed.
try {
try {
- return fun();
+ return f();
} catch(e, s) {
if (handleUncaught) {
handleUncaughtError(_asyncError(e, s));
@@ -260,34 +262,34 @@
*
* Uncaught errors are given to [handleUncaughtError].
*/
- _runGuarded(void fun()) {
- return _runInZone(fun, true);
+ _runGuarded(void f()) {
+ return _runInZone(f, true);
}
/**
* Runs the function but doesn't catch uncaught errors.
*/
- _runUnguarded(void fun()) {
- return _runInZone(fun, false);
+ _runUnguarded(void f()) {
+ return _runInZone(f, false);
}
- runAsync(void fun()) {
- _openCallbacks++;
- _scheduleAsyncCallback(() {
- _openCallbacks--;
- _runGuarded(fun);
- });
- }
+ runAsync(void f(), _Zone zone) => _parentZone.runAsync(f, zone);
+ // TODO(floitsch): the zone should just forward to the parent zone. The
+ // default zone should then create the _ZoneTimer.
Timer createTimer(Duration duration, void callback()) {
return new _ZoneTimer(this, duration, callback);
}
+ // TODO(floitsch): the zone should just forward to the parent zone. The
+ // default zone should then create the _ZoneTimer.
Timer createPeriodicTimer(Duration duration, void callback(Timer timer)) {
return new _PeriodicZoneTimer(this, duration, callback);
}
void _addChild(_Zone child) {
+ // TODO(floitsch): the zone should just increment a counter, but not keep
+ // a reference to the child.
_children.add(child);
}
@@ -332,6 +334,18 @@
throw error;
});
}
+
+ void runAsync(void f(), _Zone zone) {
+ if (identical(this, zone)) {
+ // No need to go through the zone when it's the default zone anyways.
+ _scheduleAsyncCallback(f);
+ return;
+ }
+ zone.expectCallback();
+ _scheduleAsyncCallback(() {
+ zone.executeCallbackGuarded(f);
+ });
+ }
}
typedef void _CompletionCallback();
@@ -348,8 +362,8 @@
* Runs the given function asynchronously. Executes the [_onDone] callback
* when the zone is done.
*/
- runWaitForCompletion(void fun()) {
- return this._runUnguarded(fun);
+ runWaitForCompletion(void f()) {
+ return this._runUnguarded(f);
}
_dispose() {
@@ -370,7 +384,7 @@
final _HandleErrorCallback _handleError;
_CatchErrorsZone(_Zone parentZone, this._handleError, void onDone())
- : super(parentZone, onDone);
+ : super(parentZone, onDone);
_Zone get _errorZone => this;
@@ -390,11 +404,27 @@
* Runs the given function asynchronously. Executes the [_onDone] callback
* when the zone is done.
*/
- runWaitForCompletion(void fun()) {
- return this._runGuarded(fun);
+ runWaitForCompletion(void f()) {
+ return this._runGuarded(f);
}
- String toString() => "WithErrors ${super.toString()}";
+ String toString() => "CatchErrors ${super.toString()}";
+}
+
+typedef void _RunAsyncInterceptor(void callback());
+
+class _RunAsyncZone extends _ZoneBase {
+ final _RunAsyncInterceptor _runAsyncInterceptor;
+
+ _RunAsyncZone(_Zone parentZone, this._runAsyncInterceptor)
+ : super(parentZone);
+
+ void runAsync(void callback(), _Zone zone) {
+ zone.expectCallback();
+ _parentZone.runFromChildZone(() {
+ _runAsyncInterceptor(() => zone.executeCallbackGuarded(callback));
+ });
+ }
}
typedef void _TimerCallback();
@@ -460,8 +490,14 @@
* errors, synchronous or asynchronous, in the zone are caught and handled
* by the callback.
*
- * [onDone] (if non-null) is invoked when the zone has no more outstanding
- * callbacks.
+ * The [onDone] handler (if non-null) is invoked when the zone has no more
+ * outstanding callbacks.
+ *
+ * The [onRunAsync] handler (if non-null) is invoked when the [body] executes
+ * [runAsync]. The handler is invoked in the outer zone and can therefore
+ * execute [runAsync] without recursing. The given callback must be
+ * executed eventually. Otherwise the nested zone will not complete. It must be
+ * executed only once.
*
* Examples:
*
@@ -489,8 +525,27 @@
* }, onError: (e) { print("unused error handler"); });
* }, onError: (e) { print("catches error of first error-zone."); });
*
+ * The following example prints the stack trace whenever a callback is
+ * registered using [runAsync] (which is also used by [Completer]s and
+ * [StreamController]s.
+ *
+ * printStackTrace() { try { throw 0; } catch(e, s) { print(s); } }
+ * runZonedExperimental(body, onRunAsync: (callback) {
+ * printStackTrace();
+ * runAsync(callback);
+ * });
*/
-runZonedExperimental(body(), { void onError(error), void onDone() }) {
+runZonedExperimental(body(),
+ { void onRunAsync(void callback()),
+ void onError(error),
+ void onDone() }) {
+ if (onRunAsync != null) {
+ _RunAsyncZone zone = new _RunAsyncZone(_Zone._current, onRunAsync);
+ return zone._runUnguarded(() {
+ return runZonedExperimental(body, onError: onError, onDone: onDone);
+ });
+ }
+
// TODO(floitsch): we probably still want to install a new Zone.
if (onError == null && onDone == null) return body();
if (onError == null) {
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 9ad3001..6d15154 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -220,10 +220,11 @@
const int _WRITE_LIST_REQUEST = 18;
const int _CREATE_LINK_REQUEST = 19;
const int _DELETE_LINK_REQUEST = 20;
-const int _LINK_TARGET_REQUEST = 21;
-const int _TYPE_REQUEST = 22;
-const int _IDENTICAL_REQUEST = 23;
-const int _STAT_REQUEST = 24;
+const int _RENAME_LINK_REQUEST = 21;
+const int _LINK_TARGET_REQUEST = 22;
+const int _TYPE_REQUEST = 23;
+const int _IDENTICAL_REQUEST = 24;
+const int _STAT_REQUEST = 25;
// TODO(ager): The only reason for this class is that the patching
// mechanism doesn't seem to like patching a private top level
@@ -334,6 +335,8 @@
external static _rename(String oldPath, String newPath);
+ external static _renameLink(String oldPath, String newPath);
+
File renameSync(String newPath) {
var result = _rename(_path, newPath);
throwIfError(result, "Cannot rename file '$_path' to '$newPath'");
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index b045c11..29d561d 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -844,7 +844,10 @@
* [getUrl] and [open].
*
* When the HTTP response is ready a [HttpClientResponse] object is
- * provided which provides access to the headers and body of the response.
+ * provided which provides access to the headers and body of the response. The
+ * body is available as a stream implemented by [HttpClientResponse].
+ * If a body is present, it must be read. Otherwise, it'll lead to a resource
+ * leaks. Consider using [HttpClientResponse.drain] if the body is unused.
*
* HttpClient client = new HttpClient();
* client.getUrl(Uri.parse("http://www.example.com/"))
diff --git a/sdk/lib/io/link.dart b/sdk/lib/io/link.dart
index e8c4a49..0be5994 100644
--- a/sdk/lib/io/link.dart
+++ b/sdk/lib/io/link.dart
@@ -81,6 +81,26 @@
void deleteSync();
/**
+ * Renames this link. Returns a `Future<Link>` that completes
+ * with a [Link] instance for the renamed link.
+ *
+ * If [newPath] identifies an existing link, that link is
+ * replaced. If [newPath] identifies an existing file or directory,
+ * the operation fails and the future completes with an exception.
+ */
+ Future<Link> rename(String newPath);
+
+ /**
+ * Synchronously renames this link. Returns a [Link]
+ * instance for the renamed link.
+ *
+ * If [newPath] identifies an existing link, that link is
+ * replaced. If [newPath] identifies an existing file or directory
+ * the operation fails and an exception is thrown.
+ */
+ Link renameSync(String newPath);
+
+ /**
* Gets the target of the link. Returns a future that completes with
* the path to the target.
*
@@ -195,6 +215,27 @@
throwIfError(result, "Cannot delete link", path);
}
+ Future<Link> rename(String newPath) {
+ _ensureFileService();
+ List request = new List(3);
+ request[0] = _RENAME_LINK_REQUEST;
+ request[1] = path;
+ request[2] = newPath;
+ return _fileService.call(request).then((response) {
+ if (_isErrorResponse(response)) {
+ throw _exceptionFromResponse(
+ response, "Cannot rename link '$path' to '$newPath'");
+ }
+ return new Link(newPath);
+ });
+ }
+
+ Link renameSync(String newPath) {
+ var result = _File._renameLink(path, newPath);
+ throwIfError(result, "Cannot rename link '$path' to '$newPath'");
+ return new Link(newPath);
+ }
+
Future<String> target() {
_ensureFileService();
List request = new List(2);
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index dcbf037..41e881a 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -21,7 +21,6 @@
Language/11_Expressions/01_Constants_A18_t06: Fail # TODO(dart2dart-team): Please triage this failure.
Language/11_Expressions/11_Instance_Creation_A05_t02: Fail # TODO(dart2dart-team): Please triage this failure.
Language/11_Expressions/14_Function_Invocation/3_Unqualified_Invocation_A01_t10: Fail # TODO(dart2dart-team): Please triage this failure.
-Language/11_Expressions/33_Argument_Definition_Test_A02_t02: Fail # TODO(dart2dart-team): Please triage this failure.
Language/12_Statements/03_Variable_Declaration_A04_t07: Fail # TODO(dart2dart-team): Please triage this failure.
Language/12_Statements/03_Variable_Declaration_A04_t08: Fail # TODO(dart2dart-team): Please triage this failure.
Language/12_Statements/09_Switch_A04_t01: Fail # TODO(dart2dart-team): Please triage this failure.
@@ -606,3 +605,9 @@
LibTest/core/List/removeRange_A02_t01: Fail # Issue 400
LibTest/core/Set/isSubsetOf_A01_t01: Fail # Issue 400
LibTest/core/Set/isSubsetOf_A01_t02: Fail # Issue 400
+
+Language/11_Expressions/33_Argument_Definition_Test_A01_t02: Fail, OK # co19 issue 436
+Language/11_Expressions/33_Argument_Definition_Test_A02_t01: Fail, OK # co19 issue 436
+Language/11_Expressions/33_Argument_Definition_Test_A02_t02: Fail, OK # co19 issue 436
+Language/11_Expressions/33_Argument_Definition_Test_A03_t01: Fail, OK # co19 issue 436
+Language/11_Expressions/33_Argument_Definition_Test_A03_t02: Fail, OK # co19 issue 436
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 28e9415..11c8972 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -129,6 +129,7 @@
LibTest/collection/Queue/iterator_current_A01_t02: Fail # TODO(ahe): Please triage this failure.
LibTest/collection/Queue/iterator_moveNext_A01_t02: Fail # TODO(ahe): Please triage this failure.
LibTest/core/List/List_A01_t02: Fail # TODO(ahe): Please triage this failure.
+LibTest/core/List/List_A03_t01: Fail # TODO(kasperl): Please triage this failure.
LibTest/core/double/INFINITY_A01_t04: Fail # TODO(ahe): Please triage this failure.
LibTest/core/double/NEGATIVE_INFINITY_A01_t04: Fail # TODO(ahe): Please triage this failure.
LibTest/core/double/toStringAsExponential_A02_t01: Fail # TODO(ahe): Please triage this failure.
@@ -369,6 +370,12 @@
Language/03_Overview/1_Scoping_A01_t40: Fail, OK # co19 issue 188
Language/03_Overview/1_Scoping_A01_t41: Fail, OK # co19 issue 188
+Language/11_Expressions/33_Argument_Definition_Test_A01_t02: Fail, OK # co19 issue 436
+Language/11_Expressions/33_Argument_Definition_Test_A02_t01: Fail, OK # co19 issue 436
+Language/11_Expressions/33_Argument_Definition_Test_A02_t02: Fail, OK # co19 issue 436
+Language/11_Expressions/33_Argument_Definition_Test_A03_t01: Fail, OK # co19 issue 436
+Language/11_Expressions/33_Argument_Definition_Test_A03_t02: Fail, OK # co19 issue 436
+
Language/06_Functions/4_External_Functions_A01_t01: Fail, OK # http://dartbug.com/5021
Language/03_Overview/2_Privacy_A01_t09: Fail, OK # co19 issue 198
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 82e9361..9ec08cd 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -514,28 +514,20 @@
[ $compiler == none && $runtime == vm && $arch == arm && $mode == debug ]
-LibTest/core/Expect/throws_A01_t04: Crash
LibTest/core/List/sort_A01_t05: Crash
LibTest/core/List/sort_A01_t06: Crash
-LibTest/core/double/ceil_A01_t02: Fail
-LibTest/core/double/floor_A01_t02: Fail
-LibTest/core/double/truncate_A01_t01: Fail
[ $compiler == none && $runtime == vm && $arch == simarm && $mode == release ]
LibTest/math/tan_A01_t01: Fail
LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
LibTest/core/int/operator_unary_minus_A01_t01: Fail
-LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
[ $compiler == none && $runtime == vm && $arch == simarm && $mode == debug ]
LibTest/math/tan_A01_t01: Fail
LibTest/math/cos_A01_t01: Pass, Fail # Fail on Mac
LibTest/core/List/sort_A01_t05: Crash
LibTest/core/List/sort_A01_t06: Crash
-LibTest/core/double/ceil_A01_t02: Fail, Pass # Passes on Mac.
-LibTest/core/double/floor_A01_t02: Fail, Pass # Passes on Mac.
-LibTest/core/double/truncate_A01_t01: Fail, Pass # Passes on Mac.
LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
LibTest/core/int/operator_unary_minus_A01_t01: Fail
diff --git a/tests/compiler/dart2js/analyze_api_test.dart b/tests/compiler/dart2js/analyze_api_test.dart
index 5c6da03..e7d7e24 100644
--- a/tests/compiler/dart2js/analyze_api_test.dart
+++ b/tests/compiler/dart2js/analyze_api_test.dart
@@ -21,8 +21,16 @@
// values.
const Map<String, List<String>> WHITE_LIST = const {
'path_observer.dart':
- const ['Warning: Using "new Symbol"', // Issue 10565.
+ const ['Hint: Using "new Symbol"', // Issue 10565.
],
+ 'sdk/lib/html/dart2js/html_dart2js.dart':
+ const ['Hint: The class "Rect" overrides "operator==", '
+ 'but not "get hashCode".',
+ 'Hint: The class "Point" overrides "operator==", '
+ 'but not "get hashCode".',
+ 'Hint: The class "_ClientRect" overrides "operator==", '
+ 'but not "get hashCode".',
+ ],
};
void main() {
diff --git a/tests/compiler/dart2js/analyze_dart2js_test.dart b/tests/compiler/dart2js/analyze_dart2js_test.dart
index cb66fdf..8f2a641 100644
--- a/tests/compiler/dart2js/analyze_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_dart2js_test.dart
@@ -9,13 +9,13 @@
import 'analyze_helper.dart';
/**
- * Map of white-listed warnings and errors.
+ * Map of whitelisted warnings and errors.
*
- * Only add a white-listing together with a bug report to dartbug.com and add
- * the bug issue number as a comment on the white-listing.
+ * Only add a whitelisting together with a bug report to dartbug.com and add
+ * the bug issue number as a comment on the whitelisting.
*
* Use an identifiable suffix of the file uri as key. Use a fixed substring of
- * the error/warning message in the list of white-listings for each file.
+ * the error/warning message in the list of whitelistings for each file.
*/
// TODO(johnniwinther): Support canonical URIs as keys and message kinds as
// values.
diff --git a/tests/compiler/dart2js/analyze_helper.dart b/tests/compiler/dart2js/analyze_helper.dart
index c3e6729..a9c081d 100644
--- a/tests/compiler/dart2js/analyze_helper.dart
+++ b/tests/compiler/dart2js/analyze_helper.dart
@@ -14,19 +14,20 @@
import '../../../sdk/lib/_internal/compiler/implementation/source_file_provider.dart';
/**
- * Map of white-listed warnings and errors.
+ * Map of whitelisted warnings and errors.
*
- * Only add a white-listing together with a bug report to dartbug.com and add
- * the bug issue number as a comment on the white-listing.
+ * Only add a whitelisting together with a bug report to dartbug.com and add
+ * the bug issue number as a comment on the whitelisting.
*
* Use an identifiable suffix of the file uri as key. Use a fixed substring of
- * the error/warning message in the list of white-listings for each file.
+ * the error/warning message in the list of whitelistings for each file.
*/
// TODO(johnniwinther): Support canonical URIs as keys and message kinds as
// values.
class CollectingDiagnosticHandler extends FormattingDiagnosticHandler {
bool hasWarnings = false;
+ bool hasHint = false;
bool hasErrors = false;
Map<String, Map<String, int>> whiteListMap
@@ -46,6 +47,7 @@
void checkResults() {
Expect.isFalse(hasWarnings);
+ Expect.isFalse(hasHint);
Expect.isFalse(hasErrors);
Expect.isTrue(checkWhiteListUse());
reportWhiteListUse();
@@ -56,8 +58,8 @@
for (String file in whiteListMap.keys) {
for (String messagePart in whiteListMap[file].keys) {
if (whiteListMap[file][messagePart] == 0) {
- print("White-listing '$messagePart' is unused in '$file'. "
- "Remove the white-listing from the white list map.");
+ print("Whitelisting '$messagePart' is unused in '$file'. "
+ "Remove the whitelisting from the whitelist map.");
allUsed = false;
}
}
@@ -69,7 +71,7 @@
for (String file in whiteListMap.keys) {
for (String messagePart in whiteListMap[file].keys) {
int useCount = whiteListMap[file][messagePart];
- print("White-listed message '$messagePart' suppressed $useCount "
+ print("Whitelisted message '$messagePart' suppressed $useCount "
"time(s) in '$file'.");
}
}
@@ -97,14 +99,21 @@
api.Diagnostic kind) {
if (kind == api.Diagnostic.WARNING) {
if (checkWhiteList(uri, message)) {
- // Suppress white listed warnings.
+ // Suppress whitelisted warnings.
return;
}
hasWarnings = true;
}
+ if (kind == api.Diagnostic.HINT) {
+ if (checkWhiteList(uri, message)) {
+ // Suppress whitelisted hints.
+ return;
+ }
+ hasHint = true;
+ }
if (kind == api.Diagnostic.ERROR) {
if (checkWhiteList(uri, message)) {
- // Suppress white listed warnings.
+ // Suppress whitelisted errors.
return;
}
hasErrors = true;
diff --git a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
index 0e7b685..fa543ff 100644
--- a/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
+++ b/tests/compiler/dart2js/call_site_simple_type_inferer_test.dart
@@ -251,8 +251,8 @@
subclassOfInterceptor(inferrer),
inferrer.dynamicType.nonNullable()]);
runTest(TEST_9, (inferrer) => [inferrer.intType, inferrer.intType]);
- runTest(TEST_10, (inferrer) => [subclassOfInterceptor(inferrer),
- subclassOfInterceptor(inferrer)]);
+ // runTest(TEST_10, (inferrer) => [subclassOfInterceptor(inferrer),
+ // subclassOfInterceptor(inferrer)]);
runTest(TEST_11, (inferrer) => [subclassOfInterceptor(inferrer),
subclassOfInterceptor(inferrer)]);
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 4603ff8..f2965d5 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -12,4 +12,3 @@
[ $jscl || $runtime == drt || $runtime == dartium || $runtime == ff || $runtime == firefox || $runtime == chrome || $runtime == safari || $runtime == ie9 || $runtime == opera ]
*: Skip # dart2js uses #import('dart:io'); and it is not self-hosted (yet).
-
diff --git a/tests/compiler/dart2js/mirror_tree_shaking_test.dart b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
index 6287c12..c3c6393 100644
--- a/tests/compiler/dart2js/mirror_tree_shaking_test.dart
+++ b/tests/compiler/dart2js/mirror_tree_shaking_test.dart
@@ -24,7 +24,9 @@
var provider = new MemorySourceFileProvider();
void diagnosticHandler(Uri uri, int begin, int end,
String message, Diagnostic kind) {
- if (kind == Diagnostic.VERBOSE_INFO || kind == Diagnostic.WARNING) {
+ if (kind == Diagnostic.VERBOSE_INFO
+ || kind == Diagnostic.WARNING
+ || kind == Diagnostic.HINT) {
return;
}
throw '$uri:$begin:$end:$message:$kind';
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 1e9a796..2c95dec 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -96,6 +96,7 @@
class Interceptor {
toString() {}
bool operator==(other) => identical(this, other);
+ get hashCode => throw "Interceptor.hashCode not implemented.";
noSuchMethod(im) { throw im; }
}
abstract class JSIndexable {
@@ -137,6 +138,7 @@
operator <(other) => true;
operator <=(other) => true;
operator ==(other) => true;
+ get hashCode => throw "JSNumber.hashCode not implemented.";
abs() => (this is JSInt) ? 42 : 42.0;
remainder(other) => (this is JSInt) ? 42 : 42.0;
@@ -147,6 +149,7 @@
}
class JSNull extends Interceptor {
bool operator==(other) => identical(null, other);
+ get hashCode => throw "JSNull.hashCode not implemented.";
}
class JSBool extends Interceptor implements bool {
}
@@ -174,6 +177,7 @@
class String implements Pattern {}
class Object {
operator ==(other) { return true; }
+ get hashCode => throw "Object.hashCode not implemented.";
String toString() { return null; }
noSuchMethod(im) { throw im; }
}
diff --git a/tests/compiler/dart2js/resolver_test.dart b/tests/compiler/dart2js/resolver_test.dart
index dcdcc07..1902d65 100644
--- a/tests/compiler/dart2js/resolver_test.dart
+++ b/tests/compiler/dart2js/resolver_test.dart
@@ -74,6 +74,7 @@
testToString();
testIndexedOperator();
testIncrementsAndDecrements();
+ testOverrideHashCodeCheck();
}
testTypeVariables() {
@@ -845,3 +846,22 @@
checkMemberResolved(compiler, 'C', operatorName('-', false));
checkMemberResolved(compiler, 'D', operatorName('-', false));
}
+
+testOverrideHashCodeCheck() {
+ final script = r"""
+ class A {
+ operator==(other) => true;
+ }
+ class B {
+ operator==(other) => true;
+ get hashCode => 0;
+ }
+ main() {
+ new A() == new B();
+ }""";
+ final compiler = compileScript(script);
+ Expect.equals(1, compiler.warnings.length);
+ Expect.equals(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
+ compiler.warnings[0].message.kind);
+ Expect.equals(0, compiler.errors.length);
+}
diff --git a/tests/compiler/dart2js_extra/argument_definition_test.dart b/tests/compiler/dart2js_extra/argument_definition_test.dart
deleted file mode 100644
index d5243c5..0000000
--- a/tests/compiler/dart2js_extra/argument_definition_test.dart
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012, 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.
-
-// Test parsing and resolution of argument definition test.
-
-int test(int a, {int b: 2, int c: 3}) {
- int result = 0;
- print(?b);
- print(?result); /// 01: compile-time error
- print(?a);
- print(?b);
- print(?c);
- {
- var b;
- ?b; /// 02: compile-time error
- }
- print((!?a?!?b:!?c) == (?a??b:?c));
- print(!?a?!?b:!?c == ?a??b:?c);
-}
-
-closure_test(int a, {int b: 2, int c: 3}) {
- var x = 0;
- return () {
- int result = 0;
- print(?b);
- print(?result); /// 03: compile-time error
- print(?x); /// 04: compile-time error
- print(?a);
- print(?b);
- print(?c);
- {
- var b;
- ?b; /// 05: compile-time error
- }
- print((!?a?!?b:!?c) == (?a??b:?c));
- print(!?a?!?b:!?c == ?a??b:?c);
- };
-}
-
-main() {
- test(1);
- test(1, b: 2);
- test(1, b: 2, c: 3);
- test(1, c: 3);
-
- closure_test(1)();
- closure_test(1, b: 2)();
- closure_test(1, b: 2, c: 3)();
- closure_test(1, c: 3)();
-}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 9c67dd2..7a3c170 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -53,6 +53,10 @@
string_replace_func_test: Skip # Bug 6554 - doesn't terminate.
+[ $compiler == dart2js || $compiler == dart2dart ]
+apply_test: Fail, OK # Depends on ?parameter check.
+iterable_join_test: Fail, OK # Depends on ?parameter check.
+list_fill_range_test: Fail, OK # Depends on ?parameter check.
[ $compiler == dart2js && $runtime == none ]
*: Fail, Pass # TODO(ahe): Triage these tests.
diff --git a/tests/corelib/list_contains_argument_order_test.dart b/tests/corelib/list_contains_argument_order_test.dart
new file mode 100644
index 0000000..db97b2d
--- /dev/null
+++ b/tests/corelib/list_contains_argument_order_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+
+class A {
+ const A();
+ bool operator ==(Object other) {
+ return false;
+ }
+}
+
+class B {
+ bool operator ==(Object other) {
+ Expect.fail("Bad equality order.");
+ }
+}
+
+main() {
+
+ test(iterable) {
+ Expect.isFalse(iterable.contains(new B()));
+ }
+
+ var iterables = [
+ <A>[ new A() ],
+ new List<A>(1)..[0] = new A(),
+ new List<A>()..add(new A()),
+ const <A>[ const A() ],
+ new Set()..add(new A()),
+ (new Map()..[new A()] = 0).keys,
+ (new Map()..[0] = new A()).values
+ ];
+
+ for (var iterable in iterables) {
+ test(iterable);
+ test(iterable.map((x) => x));
+ test(iterable.take(1));
+ }
+}
diff --git a/tests/language/allocation_sinking_vm_test.dart b/tests/language/allocation_sinking_vm_test.dart
index d7bb7b9..2320df3 100644
--- a/tests/language/allocation_sinking_vm_test.dart
+++ b/tests/language/allocation_sinking_vm_test.dart
@@ -87,6 +87,22 @@
foo2() => new PointP<int>(1, 3) * new PointP<num>(5, 6);
+class A<T> {
+ var x, y;
+}
+
+foo3(x) {
+ // Test materialization of type arguments.
+ var a = new A<int>();
+ a.x = x;
+ a.y = x;
+ if (x is int) return a.x + a.y;
+ Expect.isFalse(a is A<double>);
+ Expect.isTrue(a is A<int>);
+ Expect.isTrue(a is A);
+ return a.x - a.y;
+}
+
main() {
var c = new C(new Point(0.1, 0.2));
@@ -101,7 +117,9 @@
testForwardingThroughEffects(c, i.toDouble(), i.toDouble());
testIdentity(c.p);
foo2();
+ Expect.equals(10, foo3(5));
}
+ Expect.equals(0.0, foo3(0.5));
// Test returned value after optimization.
final x1 = test1(c, 11.11, 22.22);
@@ -129,4 +147,4 @@
final z2 = testIdentity(new F(c.p));
Expect.equals(z0, z1);
Expect.equals(z0, z2);
-}
\ No newline at end of file
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index ad8bd91..34b57d0 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -572,8 +572,6 @@
[ $arch == simarm || $arch == arm ]
deopt_smi_op_test: Fail
gc_test: Crash
-invocation_mirror_test: Fail
-named_parameters_with_conversions_test: Pass, Crash # Passes on Mac.
stack_overflow_test: Crash, Pass # Passes on HW in release mode.
stack_overflow_stacktrace_test: Crash, Pass # Passes on HW in release mode.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index a21901b..2d90fec 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -27,6 +27,25 @@
class_literal_test/28: Fail # Class literals are expression now; delete this test.
class_literal_test/29: Fail # Class literals are expression now; delete this test.
+argument_definition2_test: Fail, OK # Depends on ?parameter check.
+argument_definition3_test: Fail, OK # Depends on ?parameter check.
+argument_definition4_test: Fail, OK # Depends on ?parameter check.
+argument_definition5_test: Fail, OK # Depends on ?parameter check.
+argument_definition6_test: Fail, OK # Depends on ?parameter check.
+argument_definition_test/none: Fail, OK # Depends on ?parameter check.
+constructor8_test: Fail, OK # Depends on ?parameter check.
+constructor_initializer_test: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/01: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/02: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/03: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/04: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/05: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/06: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/07: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/08: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/09: Fail, OK # Depends on ?parameter check.
+optional_named_parameters_test/none: Fail, OK # Depends on ?parameter check.
+
# Fails due to inlining. Not all expected frames are in the trace.
full_stacktrace1_test: Pass, Fail # issue 9895
full_stacktrace2_test: Pass, Fail # issue 9895
diff --git a/tests/language/method_invocation_test.dart b/tests/language/method_invocation_test.dart
index 393d2a6..896683e 100644
--- a/tests/language/method_invocation_test.dart
+++ b/tests/language/method_invocation_test.dart
@@ -14,6 +14,10 @@
}
}
+class B {
+ get f { throw 123; }
+}
+
class MethodInvocationTest {
static void testNullReceiver() {
A a = new A();
@@ -28,8 +32,18 @@
Expect.equals(true, exceptionCaught);
}
+ static testGetterMethodInvocation() {
+ var b = new B();
+ try {
+ b.f();
+ } catch (e) {
+ Expect.equals(123, e);
+ }
+ }
+
static void testMain() {
testNullReceiver();
+ testGetterMethodInvocation();
}
}
diff --git a/tests/lib/async/intercept_run_async1_test.dart b/tests/lib/async/intercept_run_async1_test.dart
new file mode 100644
index 0000000..c2bc9c1
--- /dev/null
+++ b/tests/lib/async/intercept_run_async1_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+
+main() {
+ // Test that runZoned returns the result of executing the body.
+ var result = runZonedExperimental(() => 499,
+ onRunAsync: (f) {
+ Expect.fail("Unexpected invocation.");
+ });
+ Expect.equals(499, result);
+}
diff --git a/tests/lib/async/intercept_run_async2_test.dart b/tests/lib/async/intercept_run_async2_test.dart
new file mode 100644
index 0000000..c75e458
--- /dev/null
+++ b/tests/lib/async/intercept_run_async2_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+
+var events = [];
+
+body() {
+ events.add("body entry");
+ runAsync(() {
+ events.add("run async body");
+ });
+ return 499;
+}
+
+handler(fun) {
+ events.add("handler");
+ fun();
+ events.add("handler done");
+}
+
+main() {
+ // Test that runAsync interception works.
+ var result = runZonedExperimental(body, onRunAsync: handler);
+ // No need for a ReceivePort: If the runZonedExperimental disbehaved we
+ // would have an [events] list that is different from what we expect.
+ Expect.listEquals(["body entry", "handler", "run async body", "handler done"],
+ events);
+}
diff --git a/tests/lib/async/intercept_run_async3_test.dart b/tests/lib/async/intercept_run_async3_test.dart
new file mode 100644
index 0000000..0dea800
--- /dev/null
+++ b/tests/lib/async/intercept_run_async3_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:isolate';
+
+var events = [];
+
+body() {
+ events.add("body entry");
+ runAsync(() {
+ events.add("run async body");
+ });
+ return 499;
+}
+
+handler(fun) {
+ events.add("handler");
+ runAsync(fun);
+ events.add("handler done");
+}
+
+main() {
+ // We keep a ReceivePort open until all tests are done. This way the VM will
+ // hang if the callbacks are not invoked and the test will time out.
+ var port = new ReceivePort();
+
+ // Test that runAsync inside the runAsync-handler goes to the parent zone.
+ var result = runZonedExperimental(body, onRunAsync: handler);
+ events.add("after");
+ runAsync(() {
+ Expect.listEquals(
+ ["body entry", "handler", "handler done", "after", "run async body"],
+ events);
+ port.close();
+ });
+}
diff --git a/tests/lib/async/intercept_run_async4_test.dart b/tests/lib/async/intercept_run_async4_test.dart
new file mode 100644
index 0000000..c935bdb
--- /dev/null
+++ b/tests/lib/async/intercept_run_async4_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:isolate';
+
+var events = [];
+
+body() {
+ events.add("body entry");
+ runAsync(() {
+ events.add("run async body");
+ runAsync(() {
+ events.add("run nested body");
+ });
+ });
+ return 499;
+}
+
+handler(fun) {
+ events.add("handler");
+ runAsync(fun);
+ events.add("handler done");
+}
+
+main() {
+ // We keep a ReceivePort open until all tests are done. This way the VM will
+ // hang if the callbacks are not invoked and the test will time out.
+ var port = new ReceivePort();
+
+ // Test that body of a runAsync goes to the zone it came from.
+ var result = runZonedExperimental(body, onRunAsync: handler);
+ events.add("after");
+ runAsync(() {
+ runAsync(() {
+ Expect.listEquals(
+ ["body entry",
+ "handler", "handler done",
+ "after",
+ "run async body",
+ "handler", "handler done",
+ "run nested body"],
+ events);
+ port.close();
+ });
+ });
+}
diff --git a/tests/lib/async/intercept_run_async5_test.dart b/tests/lib/async/intercept_run_async5_test.dart
new file mode 100644
index 0000000..acf17d0
--- /dev/null
+++ b/tests/lib/async/intercept_run_async5_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:isolate';
+
+var events = [];
+
+body() {
+ events.add("body entry");
+ runAsync(() {
+ events.add("run async body");
+ runAsync(() {
+ events.add("run nested body");
+ });
+ });
+ return 499;
+}
+
+handler(fun) {
+ events.add("handler");
+ runAsync(fun);
+ events.add("handler done");
+}
+
+handler2(fun) {
+ events.add("handler2");
+ runAsync(fun);
+ events.add("handler2 done");
+}
+
+main() {
+ // We keep a ReceivePort open until all tests are done. This way the VM will
+ // hang if the callbacks are not invoked and the test will time out.
+ var port = new ReceivePort();
+
+ // Test that nested runZonedExperimental go to the next outer zone.
+ var result = runZonedExperimental(
+ () => runZonedExperimental(body, onRunAsync: handler2),
+ onRunAsync: handler);
+ events.add("after");
+ Timer.run(() {
+ Expect.listEquals(
+ ["body entry",
+ "handler2", "handler", "handler done", "handler2 done",
+ "after",
+ "run async body",
+ "handler2", "handler", "handler done", "handler2 done",
+ "run nested body"],
+ events);
+ port.close();
+ });
+}
diff --git a/tests/lib/async/intercept_run_async6_test.dart b/tests/lib/async/intercept_run_async6_test.dart
new file mode 100644
index 0000000..8b49edf
--- /dev/null
+++ b/tests/lib/async/intercept_run_async6_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2013, 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.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+import 'dart:isolate';
+
+class A {
+ add(x) => print(x);
+}
+var events = [];
+
+body() {
+ events.add("body entry");
+ runAsync(() {
+ events.add("run async body");
+ throw "foo";
+ });
+ return 499;
+}
+
+onAsyncHandler(fun) {
+ events.add("async handler");
+ runAsync(fun);
+ events.add("async handler done");
+}
+
+onErrorHandler(e) {
+ events.add("error: $e");
+}
+
+onDoneHandler() {
+ events.add("done");
+}
+
+main() {
+ // We keep a ReceivePort open until all tests are done. This way the VM will
+ // hang if the callbacks are not invoked and the test will time out.
+ var port = new ReceivePort();
+
+ // Test that runZonedExperimental works when async, error and done are used.
+ var result = runZonedExperimental(
+ body,
+ onRunAsync: onAsyncHandler,
+ onError: onErrorHandler,
+ onDone: onDoneHandler);
+ events.add("after");
+ Timer.run(() {
+ Expect.listEquals(
+ ["body entry",
+ "async handler", "async handler done",
+ "after",
+ "run async body",
+ "error: foo",
+ "done"],
+ events);
+ port.close();
+ });
+}
diff --git a/tests/standalone/io/link_async_test.dart b/tests/standalone/io/link_async_test.dart
index 0cc4a7a..e691e32 100644
--- a/tests/standalone/io/link_async_test.dart
+++ b/tests/standalone/io/link_async_test.dart
@@ -164,6 +164,44 @@
}
+Future testRename() {
+ Future testRename(Path base, String target) {
+ Link link1;
+ Link link2;
+ return new Link.fromPath(base.append('c')).create(target)
+ .then((link) {
+ link1 = link;
+ Expect.isTrue(link1.existsSync());
+ return link1.rename(base.append('d').toNativePath());
+ })
+ .then((link) {
+ link2 = link;
+ Expect.isFalse(link1.existsSync());
+ Expect.isTrue(link2.existsSync());
+ return link2.delete();
+ })
+ .then((_) => Expect.isFalse(link2.existsSync()));
+ }
+
+ return new Directory('').createTemp().then((baseDir) {
+ Path base = new Path(baseDir.path);
+ var targetsFutures = [];
+ targetsFutures.add(new Directory.fromPath(base.append('a')).create());
+ if (Platform.isWindows) {
+ // Currently only links to directories are supported on Windows.
+ targetsFutures.add(
+ new Directory.fromPath(base.append('b')).create());
+ } else {
+ targetsFutures.add(new File.fromPath(base.append('b')).create());
+ }
+ return Future.wait(targetsFutures).then((targets) {
+ return testRename(base, targets[0].path)
+ .then((_) => testRename(base, targets[1].path))
+ .then((_) => baseDir.delete(recursive: true));
+ });
+ });
+}
+
Future testDirectoryListing(Path base, Directory baseDir) {
Map makeExpected(bool recursive, bool followLinks) {
Map expected = new Map();
@@ -219,5 +257,6 @@
ReceivePort keepAlive = new ReceivePort();
testCreate()
.then((_) => testCreateLoopingLink())
+ .then((_) => testRename())
.then((_) => keepAlive.close());
}
diff --git a/tests/standalone/io/link_test.dart b/tests/standalone/io/link_test.dart
index 7bef4c5..956e29f 100644
--- a/tests/standalone/io/link_test.dart
+++ b/tests/standalone/io/link_test.dart
@@ -173,6 +173,28 @@
new Directory.fromPath(base).delete(recursive: true));
}
+testRenameSync() {
+ testRename(Path base, String target) {
+ Link link1 = new Link.fromPath(base.append('c'))..createSync(target);
+ Expect.isTrue(link1.existsSync());
+ Link link2 = link1.renameSync(base.append('d').toNativePath());
+ Expect.isFalse(link1.existsSync());
+ Expect.isTrue(link2.existsSync());
+ link2.deleteSync();
+ Expect.isFalse(link2.existsSync());
+ }
+
+ Directory baseDir = new Directory('').createTempSync();
+ Path base = new Path(baseDir.path);
+ Directory dir = new Directory.fromPath(base.append('a'))..createSync();
+ File file = new File.fromPath(base.append('b'))..createSync();
+
+ testRename(base, file.path);
+ testRename(base, dir.path);
+
+ baseDir.deleteSync(recursive: true);
+}
+
void testLinkErrorSync() {
Expect.throws(() =>
new Link('some-dir-that-doent exist/some link file/bla/fisk').createSync(
@@ -183,5 +205,6 @@
main() {
testCreateSync();
testCreateLoopingLink();
+ testRenameSync();
testLinkErrorSync();
}
diff --git a/tests/utils/dummy_compiler_test.dart b/tests/utils/dummy_compiler_test.dart
index 7f80c39..74df9b2 100644
--- a/tests/utils/dummy_compiler_test.dart
+++ b/tests/utils/dummy_compiler_test.dart
@@ -17,61 +17,65 @@
source = "main() {}";
} else if (uri.scheme == "lib") {
if (uri.path.endsWith("/core.dart")) {
- source = """library core;
- class Object {
- operator==(other) {}
- }
- class Type {}
- class bool {}
- class num {}
- class int {}
- class double{}
- class String{}
- class Function{}
- class List {}
- class Map {}
- class Closure {}
- class BoundClosure {}
- class Dynamic_ {}
- class Null {}
- class StackTrace {}
- class LinkedHashMap {}
- identical(a, b) => true;
- getRuntimeTypeInfo(o) {}
- setRuntimeTypeInfo(o, i) {}
- eqNull(a) {}
- eqNullB(a) {}""";
+ source = """
+library core;
+class Object {
+ operator==(other) {}
+ get hashCode => throw 'Object.hashCode not implemented.';
+}
+class Type {}
+class bool {}
+class num {}
+class int {}
+class double{}
+class String{}
+class Function{}
+class List {}
+class Map {}
+class Closure {}
+class BoundClosure {}
+class Dynamic_ {}
+class Null {}
+class StackTrace {}
+class LinkedHashMap {}
+identical(a, b) => true;
+getRuntimeTypeInfo(o) {}
+setRuntimeTypeInfo(o, i) {}
+eqNull(a) {}
+eqNullB(a) {}""";
} else if (uri.path.endsWith('_patch.dart')) {
source = '';
} else if (uri.path.endsWith('interceptors.dart')) {
- source = """class Interceptor {
- operator==(other) {}
- }
- class JSIndexable {
- get length;
- }
- class JSMutableIndexable {}
- class JSArray implements JSIndexable {
- var removeLast;
- var add;
- }
- class JSMutableArray extends JSArray {}
- class JSFixedArray extends JSMutableArray {}
- class JSExtendableArray extends JSMutableArray {}
- class JSString implements JSIndexable {
- var split;
- var concat;
- var toString;
- }
- class JSFunction {}
- class JSInt {}
- class JSDouble {}
- class JSNumber {}
- class JSNull {}
- class JSBool {}
- getInterceptor(o){}
- getDispatchProperty(o) {}
- setDispatchProperty(o, v) {}""";
+ source = """
+class Interceptor {
+ operator==(other) {}
+ get hashCode => throw 'Interceptor.hashCode not implemented.';
+}
+class JSIndexable {
+ get length;
+}
+class JSMutableIndexable {}
+class JSArray implements JSIndexable {
+ var removeLast;
+ var add;
+}
+class JSMutableArray extends JSArray {}
+class JSFixedArray extends JSMutableArray {}
+class JSExtendableArray extends JSMutableArray {}
+class JSString implements JSIndexable {
+ var split;
+ var concat;
+ var toString;
+}
+class JSFunction {}
+class JSInt {}
+class JSDouble {}
+class JSNumber {}
+class JSNull {}
+class JSBool {}
+getInterceptor(o){}
+getDispatchProperty(o) {}
+setDispatchProperty(o, v) {}""";
} else if (uri.path.endsWith('js_helper.dart')) {
source = 'library jshelper; class JSInvocationMirror {} '
'class ConstantMap {} class TypeImpl {}';
diff --git a/tools/VERSION b/tools/VERSION
index 9ed370f..a18058b2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,4 +1,4 @@
MAJOR 0
MINOR 6
-BUILD 0
+BUILD 1
PATCH 0