]> git.lizzy.rs Git - rust.git/commitdiff
auto merge of #8438 : cmr/rust/default, r=thestinger
authorbors <bors@rust-lang.org>
Tue, 27 Aug 2013 00:05:57 +0000 (17:05 -0700)
committerbors <bors@rust-lang.org>
Tue, 27 Aug 2013 00:05:57 +0000 (17:05 -0700)
23 files changed:
src/librustc/metadata/filesearch.rs
src/librustc/metadata/loader.rs
src/librustc/middle/trans/base.rs
src/librustpkg/path_util.rs
src/librustpkg/rustpkg.rs
src/librustpkg/search.rs
src/librustpkg/tests.rs
src/librustpkg/util.rs
src/librustpkg/version.rs
src/libstd/io.rs
src/libstd/libc.rs
src/libstd/os.rs
src/libstd/rt/context.rs
src/libstd/rt/thread_local_storage.rs
src/libstd/unstable/dynamic_lib.rs
src/libstd/vec.rs
src/rt/arch/x86_64/_context.S
src/rt/arch/x86_64/ccall.S
src/rt/arch/x86_64/morestack.S
src/rt/arch/x86_64/regs.h
src/rt/arch/x86_64/sp.h
src/rt/rust_upcall.cpp
src/rt/vg/valgrind.h

index 33d517f3981bb4f2f03d67b8a3ca7238311a83af..757c53354a24f20f1d05d9e9475f60e0a80115ae 100644 (file)
 use std::os;
 use std::hashmap::HashSet;
 
+pub enum FileMatch { FileMatches, FileDoesntMatch }
+
 // A module for searching for libraries
 // FIXME (#2658): I'm not happy how this module turned out. Should
 // probably just be folded into cstore.
 
 /// Functions with type `pick` take a parent directory as well as
 /// a file found in that directory.
-pub type pick<'self, T> = &'self fn(path: &Path) -> Option<T>;
+pub type pick<'self> = &'self fn(path: &Path) -> FileMatch;
 
 pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
     if path.file_path() == file {
@@ -31,7 +33,7 @@ pub fn pick_file(file: Path, path: &Path) -> Option<Path> {
 
 pub trait FileSearch {
     fn sysroot(&self) -> @Path;
-    fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool;
+    fn for_each_lib_search_path(&self, f: &fn(&Path) -> FileMatch);
     fn get_target_lib_path(&self) -> Path;
     fn get_target_lib_file_path(&self, file: &Path) -> Path;
 }
@@ -47,13 +49,17 @@ struct FileSearchImpl {
     }
     impl FileSearch for FileSearchImpl {
         fn sysroot(&self) -> @Path { self.sysroot }
-        fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool {
+        fn for_each_lib_search_path(&self, f: &fn(&Path) -> FileMatch) {
             let mut visited_dirs = HashSet::new();
+            let mut found = false;
 
             debug!("filesearch: searching additional lib search paths [%?]",
                    self.addl_lib_search_paths.len());
             for path in self.addl_lib_search_paths.iter() {
-                f(path);
+                match f(path) {
+                    FileMatches => found = true,
+                    FileDoesntMatch => ()
+                }
                 visited_dirs.insert(path.to_str());
             }
 
@@ -61,20 +67,33 @@ fn for_each_lib_search_path(&self, f: &fn(&Path) -> bool) -> bool {
             let tlib_path = make_target_lib_path(self.sysroot,
                                         self.target_triple);
             if !visited_dirs.contains(&tlib_path.to_str()) {
-                if !f(&tlib_path) {
-                    return false;
+                match f(&tlib_path) {
+                    FileMatches => found = true,
+                    FileDoesntMatch => ()
                 }
             }
             visited_dirs.insert(tlib_path.to_str());
             // Try RUST_PATH
-            let rustpath = rust_path();
-            for path in rustpath.iter() {
+            if !found {
+                let rustpath = rust_path();
+                for path in rustpath.iter() {
+                    debug!("is %s in visited_dirs? %?",
+                            path.push("lib").to_str(),
+                            visited_dirs.contains(&path.push("lib").to_str()));
+
                     if !visited_dirs.contains(&path.push("lib").to_str()) {
-                        f(&path.push("lib"));
                         visited_dirs.insert(path.push("lib").to_str());
+                        // Don't keep searching the RUST_PATH if one match turns up --
+                        // if we did, we'd get a "multiple matching crates" error
+                        match f(&path.push("lib")) {
+                           FileMatches => {
+                               break;
+                           }
+                           FileDoesntMatch => ()
+                        }
                     }
+                }
             }
-            true
         }
         fn get_target_lib_path(&self) -> Path {
             make_target_lib_path(self.sysroot, self.target_triple)
@@ -93,28 +112,26 @@ fn get_target_lib_file_path(&self, file: &Path) -> Path {
     } as @FileSearch
 }
 
-pub fn search<T>(filesearch: @FileSearch, pick: pick<T>) -> Option<T> {
-    let mut rslt = None;
+pub fn search(filesearch: @FileSearch, pick: pick) {
     do filesearch.for_each_lib_search_path() |lib_search_path| {
         debug!("searching %s", lib_search_path.to_str());
         let r = os::list_dir_path(lib_search_path);
+        let mut rslt = FileDoesntMatch;
         for path in r.iter() {
             debug!("testing %s", path.to_str());
             let maybe_picked = pick(path);
             match maybe_picked {
-                Some(_) => {
+                FileMatches => {
                     debug!("picked %s", path.to_str());
-                    rslt = maybe_picked;
-                    break;
+                    rslt = FileMatches;
                 }
-                None => {
+                FileDoesntMatch => {
                     debug!("rejected %s", path.to_str());
                 }
             }
         }
-        rslt.is_none()
+        rslt
     };
-    return rslt;
 }
 
 pub fn relative_target_lib_path(target_triple: &str) -> Path {
index d0060931a6607eca54c753346ff492fbf8146d20..fbf6e3fcff8a70820a55e8f89cf9a168ce02dc17 100644 (file)
@@ -14,7 +14,7 @@
 use lib::llvm::{False, llvm, mk_object_file, mk_section_iter};
 use metadata::decoder;
 use metadata::encoder;
-use metadata::filesearch::FileSearch;
+use metadata::filesearch::{FileSearch, FileMatch, FileMatches, FileDoesntMatch};
 use metadata::filesearch;
 use syntax::codemap::span;
 use syntax::diagnostic::span_handler;
@@ -92,10 +92,10 @@ fn find_library_crate_aux(
     // want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
     let prefix = fmt!("%s%s-", prefix, crate_name);
     let mut matches = ~[];
-    filesearch::search(filesearch, |path| -> Option<()> {
+    filesearch::search(filesearch, |path| -> FileMatch {
       let path_str = path.filename();
       match path_str {
-          None => None,
+          None => FileDoesntMatch,
           Some(path_str) =>
               if path_str.starts_with(prefix) && path_str.ends_with(suffix) {
                   debug!("%s is a candidate", path.to_str());
@@ -104,20 +104,20 @@ fn find_library_crate_aux(
                           if !crate_matches(cvec, cx.metas, cx.hash) {
                               debug!("skipping %s, metadata doesn't match",
                                   path.to_str());
-                              None
+                              FileDoesntMatch
                           } else {
                               debug!("found %s with matching metadata", path.to_str());
                               matches.push((path.to_str(), cvec));
-                              None
+                              FileMatches
                           },
                       _ => {
                           debug!("could not load metadata for %s", path.to_str());
-                          None
+                          FileDoesntMatch
                       }
                   }
                }
                else {
-                   None
+                   FileDoesntMatch
                }
       }
     });
index 634e339e03de068bf7ac9220f1ac2e2e944bbf70..1fc682912b35f38af8c22ec3bf9d056d6f6e9168 100644 (file)
@@ -2370,7 +2370,12 @@ fn create_entry_fn(ccx: @mut CrateContext,
             decl_cdecl_fn(ccx.llmod, "amain", llfty)
         } else {
             let main_name = match ccx.sess.targ_cfg.os {
-                session::os_win32 => ~"WinMain@16",
+                session::os_win32 => {
+                    match ccx.sess.targ_cfg.arch {
+                        X86 => ~"WinMain@16",
+                        _ => ~"WinMain",
+                    }
+                },
                 _ => ~"main",
             };
             decl_cdecl_fn(ccx.llmod, main_name, llfty)
index 2dbd054ef60bcbae27d49a3dedc30eca2b3201c3..467477ca479de6fe97e2aac3f2424a31c62f4ee7 100644 (file)
@@ -49,6 +49,9 @@ pub fn make_dir_rwx(p: &Path) -> bool { os::make_dir(p, U_RWX) }
 /// True if there's a directory in <workspace> with
 /// pkgid's short name
 pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
+    debug!("Checking in src dir of %s for %s",
+           workspace.to_str(), pkgid.to_str());
+
     let src_dir = workspace.push("src");
 
     let mut found = false;
@@ -81,6 +84,9 @@ pub fn workspace_contains_package_id(pkgid: &PkgId, workspace: &Path) -> bool {
         }
         true
     };
+
+    debug!(if found { fmt!("Found %s in %s", pkgid.to_str(), workspace.to_str()) }
+           else     { fmt!("Didn't find %s in %s", pkgid.to_str(), workspace.to_str()) });
     found
 }
 
index f5dc17851e5ccfca90696e771cf3ddafea019972..b78460dc2243b9538bee3a29bc51b8e33d06824a 100644 (file)
@@ -250,6 +250,8 @@ fn run(&self, cmd: &str, args: ~[~str]) {
                     // argument
                     let pkgid = PkgId::new(args[0]);
                     let workspaces = pkg_parent_workspaces(&pkgid);
+                    debug!("package ID = %s, found it in %? workspaces",
+                           pkgid.to_str(), workspaces.len());
                     if workspaces.is_empty() {
                         let rp = rust_path();
                         assert!(!rp.is_empty());
index ea0389fed7727a0810075dba598d388321717ea5..9862f870bcafb0a6d1afbe603c43837458d656c9 100644 (file)
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use path_util::installed_library_in_workspace;
+use path_util::{installed_library_in_workspace, rust_path};
+use version::Version;
 
 /// If a library with path `p` matching pkg_id's name exists under sroot_opt,
 /// return Some(p). Return None if there's no such path or if sroot_opt is None.
@@ -19,3 +20,18 @@ pub fn find_library_in_search_path(sroot_opt: Option<@Path>, short_name: &str) -
         installed_library_in_workspace(short_name, sroot)
     }
 }
+
+/// If some workspace `p` in the RUST_PATH contains a package matching short_name,
+/// return Some(p) (returns the first one of there are multiple matches.) Return
+/// None if there's no such path.
+/// FIXME #8711: This ignores the desired version.
+pub fn find_installed_library_in_rust_path(short_name: &str, _version: &Version) -> Option<Path> {
+    let rp = rust_path();
+    for p in rp.iter() {
+        match installed_library_in_workspace(short_name, p) {
+            Some(path) => return Some(path),
+            None => ()
+        }
+    }
+    None
+}
index 0efa0782da902629c87ac4173fc7a8b75a1ce57f..fc40c2cd5f79d839ea561c03cd681ca232b5e8f3 100644 (file)
@@ -686,7 +686,7 @@ fn package_script_with_default_build() {
         push("testsuite").push("pass").push("src").push("fancy-lib").push("pkg.rs");
     debug!("package_script_with_default_build: %s", source.to_str());
     if !os::copy_file(&source,
-                      & dir.push("src").push("fancy-lib-0.1").push("pkg.rs")) {
+                      &dir.push("src").push("fancy-lib-0.1").push("pkg.rs")) {
         fail!("Couldn't copy file");
     }
     command_line_test([~"install", ~"fancy-lib"], &dir);
@@ -890,20 +890,28 @@ fn no_rebuilding_dep() {
     assert!(bar_date < foo_date);
 }
 
+// n.b. The following two tests are ignored; they worked "accidentally" before,
+// when the behavior was "always rebuild libraries" (now it's "never rebuild
+// libraries if they already exist"). They can be un-ignored once #7075 is done.
 #[test]
+#[ignore(reason = "Workcache not yet implemented -- see #7075")]
 fn do_rebuild_dep_dates_change() {
     let p_id = PkgId::new("foo");
     let dep_id = PkgId::new("bar");
     let workspace = create_local_package_with_dep(&p_id, &dep_id);
     command_line_test([~"build", ~"foo"], &workspace);
-    let bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
+    let bar_lib_name = lib_output_file_name(&workspace, "build", "bar");
+    let bar_date = datestamp(&bar_lib_name);
+    debug!("Datestamp on %s is %?", bar_lib_name.to_str(), bar_date);
     touch_source_file(&workspace, &dep_id);
     command_line_test([~"build", ~"foo"], &workspace);
-    let new_bar_date = datestamp(&lib_output_file_name(&workspace, "build", "bar"));
+    let new_bar_date = datestamp(&bar_lib_name);
+    debug!("Datestamp on %s is %?", bar_lib_name.to_str(), new_bar_date);
     assert!(new_bar_date > bar_date);
 }
 
 #[test]
+#[ignore(reason = "Workcache not yet implemented -- see #7075")]
 fn do_rebuild_dep_only_contents_change() {
     let p_id = PkgId::new("foo");
     let dep_id = PkgId::new("bar");
@@ -1060,6 +1068,23 @@ fn test_macro_pkg_script() {
         os::EXE_SUFFIX))));
 }
 
+#[test]
+fn multiple_workspaces() {
+// Make a package foo; build/install in directory A
+// Copy the exact same package into directory B and install it
+// Set the RUST_PATH to A:B
+// Make a third package that uses foo, make sure we can build/install it
+    let a_loc = mk_temp_workspace(&Path("foo"), &NoVersion).pop().pop();
+    let b_loc = mk_temp_workspace(&Path("foo"), &NoVersion).pop().pop();
+    debug!("Trying to install foo in %s", a_loc.to_str());
+    command_line_test([~"install", ~"foo"], &a_loc);
+    debug!("Trying to install foo in %s", b_loc.to_str());
+    command_line_test([~"install", ~"foo"], &b_loc);
+    let env = Some(~[(~"RUST_PATH", fmt!("%s:%s", a_loc.to_str(), b_loc.to_str()))]);
+    let c_loc = create_local_package_with_dep(&PkgId::new("bar"), &PkgId::new("foo"));
+    command_line_test_with_env([~"install", ~"bar"], &c_loc, env);
+}
+
 /// Returns true if p exists and is executable
 fn is_executable(p: &Path) -> bool {
     use std::libc::consts::os::posix88::{S_IXUSR};
index 41c1c7e31aeff82eb7503c354e1ee3af0dc647c1..4bdb442c1e61920d98287fb985f3de1178e75dc8 100644 (file)
 use rustc::driver::session::{lib_crate, bin_crate};
 use context::{Ctx, in_target};
 use package_id::PkgId;
-use search::find_library_in_search_path;
+use search::{find_library_in_search_path, find_installed_library_in_rust_path};
 use path_util::{target_library_in_workspace, U_RWX};
 pub use target::{OutputType, Main, Lib, Bench, Test};
+use version::NoVersion;
 
 // It would be nice to have the list of commands in just one place -- for example,
 // you could update the match in rustpkg.rc but forget to update this list. I think
@@ -360,18 +361,32 @@ pub fn find_and_install_dependencies(ctxt: &Ctx,
                         debug!("It exists: %s", installed_path.to_str());
                     }
                     None => {
-                        // Try to install it
-                        let pkg_id = PkgId::new(lib_name);
-                        my_ctxt.install(&my_workspace, &pkg_id);
-                        // Also, add an additional search path
-                        debug!("let installed_path...")
-                        let installed_path = target_library_in_workspace(&pkg_id,
+                        // FIXME #8711: need to parse version out of path_opt
+                        match find_installed_library_in_rust_path(lib_name, &NoVersion) {
+                            Some(installed_path) => {
+                               debug!("Found library %s, not rebuilding it",
+                                      installed_path.to_str());
+                               // Once workcache is implemented, we'll actually check
+                               // whether or not the library at installed_path is fresh
+                               save(installed_path.pop());
+                            }
+                            None => {
+                               debug!("Trying to install library %s, rebuilding it",
+                                      lib_name.to_str());
+                               // Try to install it
+                               let pkg_id = PkgId::new(lib_name);
+                               my_ctxt.install(&my_workspace, &pkg_id);
+                               // Also, add an additional search path
+                               debug!("let installed_path...")
+                               let installed_path = target_library_in_workspace(&pkg_id,
                                                                          &my_workspace).pop();
-                        debug!("Great, I installed %s, and it's in %s",
-                               lib_name, installed_path.to_str());
-                        save(installed_path);
+                               debug!("Great, I installed %s, and it's in %s",
+                                   lib_name, installed_path.to_str());
+                               save(installed_path);
+                           }
                     }
                 }
+              }
             }
             // Ignore `use`s
             _ => ()
index f8658517cdff4d84b2590edb5bb618553cf711ad..4528a02db19785502de817c9483636c59d25f7c5 100644 (file)
@@ -213,11 +213,9 @@ fn is_url_like(p: &Path) -> bool {
 pub fn split_version<'a>(s: &'a str) -> Option<(&'a str, Version)> {
     // Check for extra '#' characters separately
     if s.split_iter('#').len() > 2 {
-        None
-    }
-    else {
-        split_version_general(s, '#')
+        return None;
     }
+    split_version_general(s, '#')
 }
 
 pub fn split_version_general<'a>(s: &'a str, sep: char) -> Option<(&'a str, Version)> {
index 2412ce9daf3c1a569ff929b1ee109249d46d6224..e3f88033bd06bc74296c46e91e9d7b9d97a571ee 100644 (file)
@@ -53,7 +53,7 @@
 use int;
 use iterator::Iterator;
 use libc::consts::os::posix88::*;
-use libc::{c_int, c_long, c_void, size_t, ssize_t};
+use libc::{c_int, c_void, size_t};
 use libc;
 use num;
 use ops::Drop;
@@ -970,7 +970,7 @@ fn seek(&self, offset: int, whence: SeekStyle) {
 
         unsafe {
             assert!(libc::fseek(*self,
-                                     offset as c_long,
+                                     offset as libc::c_long,
                                      convert_whence(whence)) == 0 as c_int);
         }
     }
@@ -1199,7 +1199,7 @@ fn seek(&self, offset: int, whence: SeekStyle) {
 
         unsafe {
             assert!(libc::fseek(*self,
-                                     offset as c_long,
+                                     offset as libc::c_long,
                                      convert_whence(whence)) == 0 as c_int);
         }
     }
@@ -1240,13 +1240,23 @@ impl Writer for fd_t {
     fn write(&self, v: &[u8]) {
         #[fixed_stack_segment]; #[inline(never)];
 
+        #[cfg(windows)]
+        type IoSize = libc::c_uint;
+        #[cfg(windows)]
+        type IoRet = c_int;
+
+        #[cfg(unix)]
+        type IoSize = size_t;
+        #[cfg(unix)]
+        type IoRet = libc::ssize_t;
+
         unsafe {
             let mut count = 0u;
             do v.as_imm_buf |vbuf, len| {
                 while count < len {
                     let vb = ptr::offset(vbuf, count as int) as *c_void;
-                    let nout = libc::write(*self, vb, len as size_t);
-                    if nout < 0 as ssize_t {
+                    let nout = libc::write(*self, vb, len as IoSize);
+                    if nout < 0 as IoRet {
                         error!("error writing buffer");
                         error!("%s", os::last_os_error());
                         fail!();
index 26b4f15f3e99f4d7fc31b9747d0c3ec800acfad4..790dc886c0497d94f010622fa53d78213ee8cf1e 100644 (file)
@@ -764,6 +764,172 @@ pub struct MEMORY_BASIC_INFORMATION {
                 pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
             }
         }
+
+        #[cfg(target_arch = "x86_64")]
+        pub mod arch {
+            pub mod c95 {
+                pub type c_char = i8;
+                pub type c_schar = i8;
+                pub type c_uchar = u8;
+                pub type c_short = i16;
+                pub type c_ushort = u16;
+                pub type c_int = i32;
+                pub type c_uint = u32;
+                pub type c_long = i32;
+                pub type c_ulong = u32;
+                pub type c_float = f32;
+                pub type c_double = f64;
+                pub type size_t = u64;
+                pub type ptrdiff_t = i64;
+                pub type clock_t = i32;
+                pub type time_t = i64;
+                pub type wchar_t = u16;
+            }
+            pub mod c99 {
+                pub type c_longlong = i64;
+                pub type c_ulonglong = u64;
+                pub type intptr_t = int;
+                pub type uintptr_t = uint;
+            }
+            pub mod posix88 {
+                pub type off_t = i32; // XXX unless _FILE_OFFSET_BITS == 64
+                pub type dev_t = u32;
+                pub type ino_t = i16;
+                pub type pid_t = i64;
+                pub type useconds_t = u32;
+                pub type mode_t = u16;
+                pub type ssize_t = i64;
+            }
+            pub mod posix01 {
+            }
+            pub mod posix08 {
+            }
+            pub mod bsd44 {
+            }
+            pub mod extra {
+                use ptr;
+                use libc::types::common::c95::c_void;
+                use libc::types::os::arch::c95::{c_char, c_int, c_uint, size_t};
+                use libc::types::os::arch::c95::{c_ulong};
+                use libc::types::os::arch::c95::{wchar_t};
+                use libc::types::os::arch::c99::{c_ulonglong};
+
+                pub type BOOL = c_int;
+                pub type BYTE = u8;
+                pub type CCHAR = c_char;
+                pub type CHAR = c_char;
+
+                pub type DWORD = c_ulong;
+                pub type DWORDLONG = c_ulonglong;
+
+                pub type HANDLE = LPVOID;
+                pub type HMODULE = c_uint;
+
+                pub type LONG_PTR = i64; // changed
+
+                pub type LPCWSTR = *WCHAR;
+                pub type LPCSTR = *CHAR;
+                pub type LPCTSTR = *CHAR;
+                pub type LPTCH = *CHAR;
+
+                pub type LPWSTR = *mut WCHAR;
+                pub type LPSTR = *mut CHAR;
+                pub type LPTSTR = *mut CHAR;
+
+                // Not really, but opaque to us.
+                pub type LPSECURITY_ATTRIBUTES = LPVOID;
+
+                pub type LPVOID = *mut c_void;
+                pub type LPCVOID = *c_void;
+                pub type LPBYTE = *mut BYTE;
+                pub type LPWORD = *mut WORD;
+                pub type LPDWORD = *mut DWORD;
+                pub type LPHANDLE = *mut HANDLE;
+
+                pub type LRESULT = LONG_PTR;
+                pub type PBOOL = *mut BOOL;
+                pub type WCHAR = wchar_t;
+                pub type WORD = u16;
+                pub type SIZE_T = size_t;
+
+                pub type time64_t = i64;
+                pub type int64 = i64;
+
+                pub struct STARTUPINFO {
+                    cb: DWORD,
+                    lpReserved: LPTSTR,
+                    lpDesktop: LPTSTR,
+                    lpTitle: LPTSTR,
+                    dwX: DWORD,
+                    dwY: DWORD,
+                    dwXSize: DWORD,
+                    dwYSize: DWORD,
+                    dwXCountChars: DWORD,
+                    dwYCountCharts: DWORD,
+                    dwFillAttribute: DWORD,
+                    dwFlags: DWORD,
+                    wShowWindow: WORD,
+                    cbReserved2: WORD,
+                    lpReserved2: LPBYTE,
+                    hStdInput: HANDLE,
+                    hStdOutput: HANDLE,
+                    hStdError: HANDLE
+                }
+                pub type LPSTARTUPINFO = *mut STARTUPINFO;
+
+                pub struct PROCESS_INFORMATION {
+                    hProcess: HANDLE,
+                    hThread: HANDLE,
+                    dwProcessId: DWORD,
+                    dwThreadId: DWORD
+                }
+                pub type LPPROCESS_INFORMATION = *mut PROCESS_INFORMATION;
+
+                pub struct SYSTEM_INFO {
+                    wProcessorArchitecture: WORD,
+                    wReserved: WORD,
+                    dwPageSize: DWORD,
+                    lpMinimumApplicationAddress: LPVOID,
+                    lpMaximumApplicationAddress: LPVOID,
+                    dwActiveProcessorMask: DWORD,
+                    dwNumberOfProcessors: DWORD,
+                    dwProcessorType: DWORD,
+                    dwAllocationGranularity: DWORD,
+                    wProcessorLevel: WORD,
+                    wProcessorRevision: WORD
+                }
+                pub type LPSYSTEM_INFO = *mut SYSTEM_INFO;
+
+                impl SYSTEM_INFO {
+                    pub fn new() -> SYSTEM_INFO {
+                        SYSTEM_INFO {
+                            wProcessorArchitecture: 0,
+                            wReserved: 0,
+                            dwPageSize: 0,
+                            lpMinimumApplicationAddress: ptr::mut_null(),
+                            lpMaximumApplicationAddress: ptr::mut_null(),
+                            dwActiveProcessorMask: 0,
+                            dwNumberOfProcessors: 0,
+                            dwProcessorType: 0,
+                            dwAllocationGranularity: 0,
+                            wProcessorLevel: 0,
+                            wProcessorRevision: 0
+                        }
+                    }
+                }
+
+                pub struct MEMORY_BASIC_INFORMATION {
+                    BaseAddress: LPVOID,
+                    AllocationBase: LPVOID,
+                    AllocationProtect: DWORD,
+                    RegionSize: SIZE_T,
+                    State: DWORD,
+                    Protect: DWORD,
+                    Type: DWORD
+                }
+                pub type LPMEMORY_BASIC_INFORMATION = *mut MEMORY_BASIC_INFORMATION;
+            }
+        }
     }
 
     #[cfg(target_os = "macos")]
@@ -3093,6 +3259,7 @@ pub mod kernel32 {
                                                LPSYSTEM_INFO};
             use libc::types::os::arch::extra::{HANDLE, LPHANDLE};
 
+            #[cfg(target_arch = "x86")]
             #[abi = "stdcall"]
             extern "stdcall" {
                 pub fn GetEnvironmentVariableW(n: LPCWSTR,
@@ -3197,6 +3364,111 @@ pub fn MapViewOfFile(hFileMappingObject: HANDLE,
                                      -> LPVOID;
                 pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL;
             }
+
+            #[cfg(target_arch = "x86_64")]
+            extern {
+                pub fn GetEnvironmentVariableW(n: LPCWSTR,
+                                               v: LPWSTR,
+                                               nsize: DWORD)
+                                               -> DWORD;
+                pub fn SetEnvironmentVariableW(n: LPCWSTR, v: LPCWSTR)
+                                               -> BOOL;
+                pub fn GetEnvironmentStringsA() -> LPTCH;
+                pub fn FreeEnvironmentStringsA(env_ptr: LPTCH) -> BOOL;
+                pub fn GetModuleFileNameW(hModule: HMODULE,
+                                          lpFilename: LPWSTR,
+                                          nSize: DWORD)
+                                          -> DWORD;
+                pub fn CreateDirectoryW(lpPathName: LPCWSTR,
+                                        lpSecurityAttributes:
+                                        LPSECURITY_ATTRIBUTES)
+                                        -> BOOL;
+                pub fn CopyFileW(lpExistingFileName: LPCWSTR,
+                                        lpNewFileName: LPCWSTR,
+                                        bFailIfExists: BOOL)
+                                        -> BOOL;
+                pub fn DeleteFileW(lpPathName: LPCWSTR) -> BOOL;
+                pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL;
+                pub fn SetCurrentDirectoryW(lpPathName: LPCWSTR) -> BOOL;
+                pub fn GetLastError() -> DWORD;
+                pub fn FindFirstFileW(fileName: *u16, findFileData: HANDLE)
+                                      -> HANDLE;
+                pub fn FindNextFileW(findFile: HANDLE, findFileData: HANDLE)
+                                     -> BOOL;
+                pub fn FindClose(findFile: HANDLE) -> BOOL;
+                pub fn DuplicateHandle(hSourceProcessHandle: HANDLE,
+                                       hSourceHandle: HANDLE,
+                                       hTargetProcessHandle: HANDLE,
+                                       lpTargetHandle: LPHANDLE,
+                                       dwDesiredAccess: DWORD,
+                                       bInheritHandle: BOOL,
+                                       dwOptions: DWORD)
+                                       -> BOOL;
+                pub fn CloseHandle(hObject: HANDLE) -> BOOL;
+                pub fn OpenProcess(dwDesiredAccess: DWORD,
+                                   bInheritHandle: BOOL,
+                                   dwProcessId: DWORD)
+                                   -> HANDLE;
+                pub fn GetCurrentProcess() -> HANDLE;
+                pub fn CreateProcessA(lpApplicationName: LPCTSTR,
+                                      lpCommandLine: LPTSTR,
+                                      lpProcessAttributes:
+                                      LPSECURITY_ATTRIBUTES,
+                                      lpThreadAttributes:
+                                      LPSECURITY_ATTRIBUTES,
+                                      bInheritHandles: BOOL,
+                                      dwCreationFlags: DWORD,
+                                      lpEnvironment: LPVOID,
+                                      lpCurrentDirectory: LPCTSTR,
+                                      lpStartupInfo: LPSTARTUPINFO,
+                                      lpProcessInformation:
+                                      LPPROCESS_INFORMATION)
+                                      -> BOOL;
+                pub fn WaitForSingleObject(hHandle: HANDLE,
+                                           dwMilliseconds: DWORD)
+                                           -> DWORD;
+                pub fn TerminateProcess(hProcess: HANDLE, uExitCode: c_uint)
+                                        -> BOOL;
+                pub fn GetExitCodeProcess(hProcess: HANDLE,
+                                          lpExitCode: LPDWORD)
+                                          -> BOOL;
+                pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO);
+                pub fn VirtualAlloc(lpAddress: LPVOID,
+                                    dwSize: SIZE_T,
+                                    flAllocationType: DWORD,
+                                    flProtect: DWORD)
+                                    -> LPVOID;
+                pub fn VirtualFree(lpAddress: LPVOID,
+                                   dwSize: SIZE_T,
+                                   dwFreeType: DWORD)
+                                   -> BOOL;
+                pub fn VirtualLock(lpAddress: LPVOID, dwSize: SIZE_T) -> BOOL;
+                pub fn VirtualUnlock(lpAddress: LPVOID, dwSize: SIZE_T)
+                                     -> BOOL;
+                pub fn VirtualProtect(lpAddress: LPVOID,
+                                      dwSize: SIZE_T,
+                                      flNewProtect: DWORD,
+                                      lpflOldProtect: LPDWORD)
+                                      -> BOOL;
+                pub fn VirtualQuery(lpAddress: LPCVOID,
+                                    lpBuffer: LPMEMORY_BASIC_INFORMATION,
+                                    dwLength: SIZE_T)
+                                    -> SIZE_T;
+                pub fn CreateFileMappingW(hFile: HANDLE,
+                                          lpAttributes: LPSECURITY_ATTRIBUTES,
+                                          flProtect: DWORD,
+                                          dwMaximumSizeHigh: DWORD,
+                                          dwMaximumSizeLow: DWORD,
+                                          lpName: LPCTSTR)
+                                          -> HANDLE;
+                pub fn MapViewOfFile(hFileMappingObject: HANDLE,
+                                     dwDesiredAccess: DWORD,
+                                     dwFileOffsetHigh: DWORD,
+                                     dwFileOffsetLow: DWORD,
+                                     dwNumberOfBytesToMap: SIZE_T)
+                                     -> LPVOID;
+                pub fn UnmapViewOfFile(lpBaseAddress: LPCVOID) -> BOOL;
+            }
         }
 
         pub mod msvcrt {
index 0b5f53dbf19e407b2fcdb6ccbeba28005ed285ab..e7caf3f23abae8697754909d85ea9a49cb5f23cf 100644 (file)
@@ -1042,12 +1042,19 @@ pub fn errno() -> uint {
     #[fixed_stack_segment]; #[inline(never)];
     use libc::types::os::arch::extra::DWORD;
 
+    #[cfg(target_arch = "x86")]
     #[link_name = "kernel32"]
     #[abi = "stdcall"]
     extern "stdcall" {
         fn GetLastError() -> DWORD;
     }
 
+    #[cfg(target_arch = "x86_64")]
+    #[link_name = "kernel32"]
+    extern {
+        fn GetLastError() -> DWORD;
+    }
+
     unsafe {
         GetLastError() as uint
     }
@@ -1113,6 +1120,7 @@ fn strerror() -> ~str {
         use libc::types::os::arch::extra::LPSTR;
         use libc::types::os::arch::extra::LPVOID;
 
+        #[cfg(target_arch = "x86")]
         #[link_name = "kernel32"]
         #[abi = "stdcall"]
         extern "stdcall" {
@@ -1126,6 +1134,19 @@ fn FormatMessageA(flags: DWORD,
                               -> DWORD;
         }
 
+        #[cfg(target_arch = "x86_64")]
+        #[link_name = "kernel32"]
+        extern {
+            fn FormatMessageA(flags: DWORD,
+                              lpSrc: LPVOID,
+                              msgId: DWORD,
+                              langId: DWORD,
+                              buf: LPSTR,
+                              nsize: DWORD,
+                              args: *c_void)
+                              -> DWORD;
+        }
+
         static FORMAT_MESSAGE_FROM_SYSTEM: DWORD = 0x00001000;
         static FORMAT_MESSAGE_IGNORE_INSERTS: DWORD = 0x00000200;
 
@@ -1241,7 +1262,7 @@ fn real_args() -> ~[~str] {
 
 type LPCWSTR = *u16;
 
-#[cfg(windows)]
+#[cfg(windows, target_arch = "x86")]
 #[link_name="kernel32"]
 #[abi="stdcall"]
 extern "stdcall" {
@@ -1249,13 +1270,26 @@ fn real_args() -> ~[~str] {
     fn LocalFree(ptr: *c_void);
 }
 
-#[cfg(windows)]
+#[cfg(windows, target_arch = "x86_64")]
+#[link_name="kernel32"]
+extern {
+    fn GetCommandLineW() -> LPCWSTR;
+    fn LocalFree(ptr: *c_void);
+}
+
+#[cfg(windows, target_arch = "x86")]
 #[link_name="shell32"]
 #[abi="stdcall"]
 extern "stdcall" {
     fn CommandLineToArgvW(lpCmdLine: LPCWSTR, pNumArgs: *mut c_int) -> **u16;
 }
 
+#[cfg(windows, target_arch = "x86_64")]
+#[link_name="shell32"]
+extern {
+    fn CommandLineToArgvW(lpCmdLine: LPCWSTR, pNumArgs: *mut c_int) -> **u16;
+}
+
 struct OverriddenArgs {
     val: ~[~str]
 }
index 5aaddc68383f1e34171aff4f29347f6970e275e0..476554bf7f7bec7801bf58332bc5ede4e700cbf2 100644 (file)
@@ -47,6 +47,7 @@ pub fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
 
         let fp: *c_void = task_start_wrapper as *c_void;
         let argp: *c_void = unsafe { transmute::<&~fn(), *c_void>(&*start) };
+        let stack_base: *uint = stack.start();
         let sp: *uint = stack.end();
         let sp: *mut uint = unsafe { transmute_mut_unsafe(sp) };
         // Save and then immediately load the current context,
@@ -56,7 +57,7 @@ pub fn new(start: ~fn(), stack: &mut StackSegment) -> Context {
             swap_registers(transmute_mut_region(&mut *regs), transmute_region(&*regs));
         };
 
-        initialize_call_frame(&mut *regs, fp, argp, sp);
+        initialize_call_frame(&mut *regs, fp, argp, sp, stack_base);
 
         return Context {
             start: Some(start),
@@ -107,7 +108,8 @@ fn new_regs() -> ~Registers {
 }
 
 #[cfg(target_arch = "x86")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
+                         sp: *mut uint, _stack_base: *uint) {
 
     let sp = align_down(sp);
     let sp = mut_offset(sp, -4);
@@ -123,14 +125,19 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp:
     regs.ebp = 0;
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(windows, target_arch = "x86_64")]
+type Registers = [uint, ..34];
+#[cfg(not(windows), target_arch = "x86_64")]
 type Registers = [uint, ..22];
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(windows, target_arch = "x86_64")]
+fn new_regs() -> ~Registers { ~([0, .. 34]) }
+#[cfg(not(windows), target_arch = "x86_64")]
 fn new_regs() -> ~Registers { ~([0, .. 22]) }
 
 #[cfg(target_arch = "x86_64")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
+                         sp: *mut uint, stack_base: *uint) {
 
     // Redefinitions from regs.h
     static RUSTRT_ARG0: uint = 3;
@@ -138,6 +145,21 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp:
     static RUSTRT_IP: uint = 8;
     static RUSTRT_RBP: uint = 2;
 
+    #[cfg(windows)]
+    fn initialize_tib(regs: &mut Registers, sp: *mut uint, stack_base: *uint) {
+        // Redefinitions from regs.h
+        static RUSTRT_ST1: uint = 11; // stack bottom
+        static RUSTRT_ST2: uint = 12; // stack top
+        regs[RUSTRT_ST1] = sp as uint;
+        regs[RUSTRT_ST2] = stack_base as uint;
+    }
+    #[cfg(not(windows))]
+    fn initialize_tib(_: &mut Registers, _: *mut uint, _: *uint) {
+    }
+
+    // Win64 manages stack range at TIB: %gs:0x08 (top) and %gs:0x10 (bottom)
+    initialize_tib(regs, sp, stack_base);
+
     let sp = align_down(sp);
     let sp = mut_offset(sp, -1);
 
@@ -164,7 +186,8 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp:
 fn new_regs() -> ~Registers { ~([0, .. 32]) }
 
 #[cfg(target_arch = "arm")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
+                         sp: *mut uint, _stack_base: *uint) {
     let sp = align_down(sp);
     // sp of arm eabi is 8-byte aligned
     let sp = mut_offset(sp, -2);
@@ -184,7 +207,8 @@ fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp:
 fn new_regs() -> ~Registers { ~([0, .. 32]) }
 
 #[cfg(target_arch = "mips")]
-fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void, sp: *mut uint) {
+fn initialize_call_frame(regs: &mut Registers, fptr: *c_void, arg: *c_void,
+                         sp: *mut uint, _stack_base: *uint) {
     let sp = align_down(sp);
     // sp of mips o32 is 8-byte aligned
     let sp = mut_offset(sp, -2);
index a9cd29c18c9652d58a2fbe10704d236bf6650ccb..b2c2c670b5558eec4482738cb44789622a9967b0 100644 (file)
@@ -86,7 +86,7 @@ pub unsafe fn get(key: Key) -> *mut c_void {
     TlsGetValue(key)
 }
 
-#[cfg(windows)]
+#[cfg(windows, target_arch = "x86")]
 #[abi = "stdcall"]
 extern "stdcall" {
        fn TlsAlloc() -> DWORD;
@@ -94,6 +94,13 @@ pub unsafe fn get(key: Key) -> *mut c_void {
        fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
 }
 
+#[cfg(windows, target_arch = "x86_64")]
+extern {
+       fn TlsAlloc() -> DWORD;
+       fn TlsSetValue(dwTlsIndex: DWORD, lpTlsvalue: LPVOID) -> BOOL;
+       fn TlsGetValue(dwTlsIndex: DWORD) -> LPVOID;
+}
+
 #[test]
 fn tls_smoke_test() {
     use cast::transmute;
index 6dbe68200b3b7fe23d28c62b72dc39083e7ec993..90cf49cad1ccf2a9553507091bfa31c925ee146b 100644 (file)
@@ -252,6 +252,7 @@ pub unsafe fn close(handle: *libc::c_void) {
         FreeLibrary(handle); ()
     }
 
+    #[cfg(target_arch = "x86")]
     #[link_name = "kernel32"]
     extern "stdcall" {
         fn SetLastError(error: u32);
@@ -261,4 +262,15 @@ fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
         fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
         fn FreeLibrary(handle: *libc::c_void);
     }
+
+    #[cfg(target_arch = "x86_64")]
+    #[link_name = "kernel32"]
+    extern {
+        fn SetLastError(error: u32);
+        fn LoadLibraryW(name: *u16) -> *libc::c_void;
+        fn GetModuleHandleExW(dwFlags: libc::DWORD, name: *u16,
+                              handle: **libc::c_void) -> *libc::c_void;
+        fn GetProcAddress(handle: *libc::c_void, name: *libc::c_char) -> *libc::c_void;
+        fn FreeLibrary(handle: *libc::c_void);
+    }
 }
index b743a17b4728d73130d5a1f53b9259a000b46cb5..976a3cafb3259d2950b5990da1c4c02bcf20880a 100644 (file)
@@ -75,6 +75,7 @@
 use sys;
 use sys::size_of;
 use uint;
+use unstable::finally::Finally;
 use unstable::intrinsics;
 use unstable::intrinsics::{get_tydesc, contains_managed};
 use unstable::raw::{Box, Repr, Slice, Vec};
@@ -97,11 +98,14 @@ pub fn from_fn<T>(n_elts: uint, op: &fn(uint) -> T) -> ~[T] {
         let mut v = with_capacity(n_elts);
         let p = raw::to_mut_ptr(v);
         let mut i: uint = 0u;
-        while i < n_elts {
-            intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)), op(i));
-            i += 1u;
+        do (|| {
+            while i < n_elts {
+                intrinsics::move_val_init(&mut(*ptr::mut_offset(p, i as int)), op(i));
+                i += 1u;
+            }
+        }).finally {
+            raw::set_len(&mut v, i);
         }
-        raw::set_len(&mut v, n_elts);
         v
     }
 }
index f718cac963470402a7844e36dfa34f1ff188fc36..857fe91c9141b85c1603cedf69433ffa78317eba 100644 (file)
@@ -54,7 +54,7 @@ First four arguments:
         anyhow.
 */
 
-#if defined(__APPLE__) || defined(_WIN32)
+#if defined(__APPLE__)
 #define SWAP_REGISTERS _swap_registers
 #else
 #define SWAP_REGISTERS swap_registers
@@ -86,16 +86,40 @@ SWAP_REGISTERS:
         mov %r14, (RUSTRT_R14*8)(ARG0)
         mov %r15, (RUSTRT_R15*8)(ARG0)
 
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        mov %rdi, (RUSTRT_RDI*8)(ARG0)
+        mov %rsi, (RUSTRT_RSI*8)(ARG0)
+
+        // Save stack range
+        mov %gs:0x08, %r8
+        mov %r8, (RUSTRT_ST1*8)(ARG0)
+        mov %gs:0x10, %r9
+        mov %r9, (RUSTRT_ST2*8)(ARG0)
+#endif
+
         // Save 0th argument register:
         mov ARG0, (RUSTRT_ARG0*8)(ARG0)
 
         // Save non-volatile XMM registers:
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        movapd %xmm6, (RUSTRT_XMM6*8)(ARG0)
+        movapd %xmm7, (RUSTRT_XMM7*8)(ARG0)
+        movapd %xmm8, (RUSTRT_XMM8*8)(ARG0)
+        movapd %xmm9, (RUSTRT_XMM9*8)(ARG0)
+        movapd %xmm10, (RUSTRT_XMM10*8)(ARG0)
+        movapd %xmm11, (RUSTRT_XMM11*8)(ARG0)
+        movapd %xmm12, (RUSTRT_XMM12*8)(ARG0)
+        movapd %xmm13, (RUSTRT_XMM13*8)(ARG0)
+        movapd %xmm14, (RUSTRT_XMM14*8)(ARG0)
+        movapd %xmm15, (RUSTRT_XMM15*8)(ARG0)
+#else
         movapd %xmm0, (RUSTRT_XMM0*8)(ARG0)
         movapd %xmm1, (RUSTRT_XMM1*8)(ARG0)
         movapd %xmm2, (RUSTRT_XMM2*8)(ARG0)
         movapd %xmm3, (RUSTRT_XMM3*8)(ARG0)
         movapd %xmm4, (RUSTRT_XMM4*8)(ARG0)
         movapd %xmm5, (RUSTRT_XMM5*8)(ARG0)
+#endif
 
         // Restore non-volatile integer registers:
         //   (including RSP)
@@ -107,16 +131,40 @@ SWAP_REGISTERS:
         mov (RUSTRT_R14*8)(ARG1), %r14
         mov (RUSTRT_R15*8)(ARG1), %r15
 
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        mov (RUSTRT_RDI*8)(ARG1), %rdi
+        mov (RUSTRT_RSI*8)(ARG1), %rsi
+
+        // Restore stack range
+        mov (RUSTRT_ST1*8)(ARG1), %r8
+        mov %r8, %gs:0x08
+        mov (RUSTRT_ST2*8)(ARG1), %r9
+        mov %r9, %gs:0x10
+#endif
+
         // Restore 0th argument register:
         mov (RUSTRT_ARG0*8)(ARG1), ARG0
 
         // Restore non-volatile XMM registers:
+#if defined(__MINGW32__) || defined(_WINDOWS)
+        movapd (RUSTRT_XMM6*8)(ARG1), %xmm6
+        movapd (RUSTRT_XMM7*8)(ARG1), %xmm7
+        movapd (RUSTRT_XMM8*8)(ARG1), %xmm8
+        movapd (RUSTRT_XMM9*8)(ARG1), %xmm9
+        movapd (RUSTRT_XMM10*8)(ARG1), %xmm10
+        movapd (RUSTRT_XMM11*8)(ARG1), %xmm11
+        movapd (RUSTRT_XMM12*8)(ARG1), %xmm12
+        movapd (RUSTRT_XMM13*8)(ARG1), %xmm13
+        movapd (RUSTRT_XMM14*8)(ARG1), %xmm14
+        movapd (RUSTRT_XMM15*8)(ARG1), %xmm15
+#else
         movapd (RUSTRT_XMM0*8)(ARG1), %xmm0
         movapd (RUSTRT_XMM1*8)(ARG1), %xmm1
         movapd (RUSTRT_XMM2*8)(ARG1), %xmm2
         movapd (RUSTRT_XMM3*8)(ARG1), %xmm3
         movapd (RUSTRT_XMM4*8)(ARG1), %xmm4
         movapd (RUSTRT_XMM5*8)(ARG1), %xmm5
+#endif
 
         // Jump to the instruction pointer
         // found in regs:
index d4bc37fee957d3f6ac62b43e4c6b7369693a3d5f..dbee5bcdc90a3222e518d9d6fee72391c3a4de82 100644 (file)
 
         .text
 
-#if defined(__APPLE__) || defined(_WIN32)
+#if defined(__APPLE__)
 .globl ___morestack
 .private_extern MORESTACK
 ___morestack:
+#elif defined(_WIN32)
+.globl __morestack
+__morestack:
 #else
 .globl __morestack
 .hidden __morestack
index 9d16afc0a1b3546cca2664f4b1d9acd0e6dc568a..b718c9121c57b8a3d30143c3f0c16508a49ce384 100644 (file)
@@ -11,7 +11,7 @@
 
 .text
 
-#if defined(__APPLE__) || defined(_WIN32)
+#if defined(__APPLE__)
 #define UPCALL_NEW_STACK        _upcall_new_stack
 #define UPCALL_DEL_STACK        _upcall_del_stack
 #define MORESTACK               ___morestack
index 1aca452df108b84e7fb0ccb77c54127e5d7c537c..cff47ac378af0e192a739b9382206865263ed52c 100644 (file)
 #define RUSTRT_R14   6
 #define RUSTRT_R15   7
 #define RUSTRT_IP    8
-// Not used, just padding
-#define RUSTRT_XXX   9
-#define RUSTRT_XMM0 10
-#define RUSTRT_XMM1 12
-#define RUSTRT_XMM2 14
-#define RUSTRT_XMM3 16
-#define RUSTRT_XMM4 18
-#define RUSTRT_XMM5 20
-#define RUSTRT_MAX  22
+#if defined(__MINGW32__) || defined(_WINDOWS)
+    #define RUSTRT_RDI   9
+    #define RUSTRT_RSI   10
+    #define RUSTRT_ST1   11
+    #define RUSTRT_ST2   12
+    #define RUSTRT_XMM6  14
+    #define RUSTRT_XMM7  16
+    #define RUSTRT_XMM8  18
+    #define RUSTRT_XMM9  20
+    #define RUSTRT_XMM10 22
+    #define RUSTRT_XMM11 24
+    #define RUSTRT_XMM12 26
+    #define RUSTRT_XMM13 28
+    #define RUSTRT_XMM14 30
+    #define RUSTRT_XMM15 32
+    #define RUSTRT_MAX   34
+#else
+    // Not used, just padding
+    #define RUSTRT_XXX   9
+    #define RUSTRT_XMM0 10
+    #define RUSTRT_XMM1 12
+    #define RUSTRT_XMM2 14
+    #define RUSTRT_XMM3 16
+    #define RUSTRT_XMM4 18
+    #define RUSTRT_XMM5 20
+    #define RUSTRT_MAX  22
+#endif
 
 // ARG0 is the register in which the first argument goes.
 // Naturally this depends on your operating system.
index bf011f4d01976aee960105858f1805aafa28e29b..764927759fe684bf17ca0996160340d21b5d5401 100644 (file)
@@ -43,6 +43,10 @@ extern "C" CDECL ALWAYS_INLINE uintptr_t get_sp_limit() {
     asm volatile (
         "movq %%fs:24, %0"
         : "=r"(limit));
+#elif defined(_WIN64)
+    asm volatile (
+        "movq %%gs:0x28, %0"
+        : "=r"(limit));
 #endif
 
     return limit;
@@ -65,6 +69,10 @@ extern "C" CDECL ALWAYS_INLINE void record_sp_limit(void *limit) {
     asm volatile (
         "movq %0, %%fs:24"
         :: "r"(limit));
+#elif defined(_WIN64)
+    asm volatile (
+        "movq %0, %%gs:0x28"
+        :: "r"(limit));
 #endif
 }
 
index 21c0d219242613d91a75518af7b2ae391404115c..7ccb06a3296f4ced2905c390e120e949e6b8f317 100644 (file)
@@ -54,8 +54,18 @@ upcall_call_shim_on_rust_stack(void *args, void *fn_ptr) {
 
 /**********************************************************************/
 
+#ifdef __SEH__
+#  define PERSONALITY_FUNC __gxx_personality_seh0
+#else
+#  ifdef __USING_SJLJ_EXCEPTIONS__
+#    define PERSONALITY_FUNC __gxx_personality_sjlj
+#  else
+#    define PERSONALITY_FUNC __gxx_personality_v0
+#  endif
+#endif
+
 extern "C" _Unwind_Reason_Code
-__gxx_personality_v0(int version,
+PERSONALITY_FUNC(int version,
                      _Unwind_Action actions,
                      uint64_t exception_class,
                      _Unwind_Exception *ue_header,
@@ -72,11 +82,11 @@ struct s_rust_personality_args {
 
 extern "C" void
 upcall_s_rust_personality(s_rust_personality_args *args) {
-    args->retval = __gxx_personality_v0(args->version,
-                                        args->actions,
-                                        args->exception_class,
-                                        args->ue_header,
-                                        args->context);
+    args->retval = PERSONALITY_FUNC(args->version,
+                                    args->actions,
+                                    args->exception_class,
+                                    args->ue_header,
+                                    args->context);
 }
 
 /**
index 222a58e156323c6c183db5856690d6fea8d55a09..c9aa0fd0328356b0d3b376fc575b2ad6420074d4 100644 (file)
 #undef PLAT_x86_darwin
 #undef PLAT_amd64_darwin
 #undef PLAT_x86_win32
+#undef PLAT_amd64_win64
 #undef PLAT_x86_linux
 #undef PLAT_amd64_linux
 #undef PLAT_ppc32_linux
 #  define PLAT_amd64_darwin 1
 #elif defined(__MINGW32__) || defined(__CYGWIN32__) \
       || (defined(_WIN32) && defined(_M_IX86))
-#  define PLAT_x86_win32 1
+#  if defined(__x86_64__)
+#    define PLAT_amd64_win64 1
+#  elif defined(__i386__)
+#    define PLAT_x86_win32 1
+#  endif
 #elif defined(__linux__) && defined(__i386__)
 #  define PLAT_x86_linux 1
 #elif defined(__linux__) && defined(__x86_64__)
@@ -349,7 +354,8 @@ valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
 
 /* ------------------------ amd64-{linux,darwin} --------------- */
 
-#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin)
+#if defined(PLAT_amd64_linux)  ||  defined(PLAT_amd64_darwin) \
+    || defined(PLAT_amd64_win64)
 
 typedef
    struct { 
@@ -3716,14 +3722,14 @@ VALGRIND_PRINTF(const char *format, ...)
 #if defined(NVALGRIND)
    return 0;
 #else /* NVALGRIND */
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(PLAT_amd64_win64)
    uintptr_t _qzz_res;
 #else
    unsigned long _qzz_res;
 #endif
    va_list vargs;
    va_start(vargs, format);
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(PLAT_amd64_win64)
    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                               VG_USERREQ__PRINTF_VALIST_BY_REF,
                               (uintptr_t)format,
@@ -3754,14 +3760,14 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
 #if defined(NVALGRIND)
    return 0;
 #else /* NVALGRIND */
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(PLAT_amd64_win64)
    uintptr_t _qzz_res;
 #else
    unsigned long _qzz_res;
 #endif
    va_list vargs;
    va_start(vargs, format);
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(PLAT_amd64_win64)
    _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
                               VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
                               (uintptr_t)format,