Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial emscripten work #30453

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -1290,6 +1290,12 @@ $ pacman -R cmake && pacman -S mingw-w64-x86_64-cmake
putvar CFG_DISABLE_JEMALLOC
;;

*-emscripten)
step_msg "targeting emscripten, disabling jemalloc"
CFG_DISABLE_JEMALLOC=1
putvar CFG_DISABLE_JEMALLOC
;;

*)
;;
esac
Expand Down
27 changes: 27 additions & 0 deletions mk/cfg/asmjs-unknown-emscripten.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# asmjs-unknown-emscripten configuration
CC_asmjs-unknown-emscripten=emcc
CXX_asmjs-unknown-emscripten=em++
CPP_asmjs-unknown-emscripten=$(CPP)
AR_asmjs-unknown-emscripten=emar
CFG_LIB_NAME_asmjs-unknown-emscripten=lib$(1).so
CFG_STATIC_LIB_NAME_asmjs-unknown-emscripten=lib$(1).a
CFG_LIB_GLOB_asmjs-unknown-emscripten=lib$(1)-*.so
CFG_LIB_DSYM_GLOB_asmjs-unknown-emscripten=lib$(1)-*.dylib.dSYM
CFG_JEMALLOC_CFLAGS_asmjs-unknown-emscripten := -m32 $(CFLAGS)
# NB: The EMSCRIPTEN environment variable is set by the emscripten SDK.
# This is only needed here to so the compiler-rt build can find unwind.h,
# but the asmjs target *doesn't even link to compiler-rt*.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a custom target option to disable compiler-rt, so perhaps we could avoid building compiler-rt and avoid linking it entirely?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh wait it looks like no_compiler_rt is already set, I wonder if we could avoid building compiler-rt like libbacktrace is avoided?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll look into it. I punted on it last time I looked at rt.mk just because that file was so difficult.

CFG_GCCISH_CFLAGS_asmjs-unknown-emscripten := -Wall -Werror -g -fPIC -m32 $(CFLAGS) \
-I$(EMSCRIPTEN)/system/lib/libcxxabi/include
CFG_GCCISH_CXXFLAGS_asmjs-unknown-emscripten := -fno-rtti $(CXXFLAGS)
CFG_GCCISH_LINK_FLAGS_asmjs-unknown-emscripten := -shared -fPIC -ldl -pthread -lrt -g -m32
CFG_GCCISH_DEF_FLAG_asmjs-unknown-emscripten := -Wl,--export-dynamic,--dynamic-list=
CFG_LLC_FLAGS_asmjs-unknown-emscripten :=
CFG_INSTALL_NAME_asmjs-unknown-emscripten =
CFG_EXE_SUFFIX_asmjs-unknown-emscripten =
CFG_WINDOWSY_asmjs-unknown-emscripten :=
CFG_UNIXY_asmjs-unknown-emscripten := 1
CFG_LDPATH_asmjs-unknown-emscripten :=
CFG_RUN_asmjs-unknown-emscripten=$(2)
CFG_RUN_TARG_asmjs-unknown-emscripten=$(call CFG_RUN_asmjs-unknown-emscripten,,$(2))
CFG_GNU_TRIPLE_asmjs-unknown-emscripten := asmjs-unknown-emscripten
7 changes: 7 additions & 0 deletions mk/rt.mk
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,12 @@ $$(BACKTRACE_LIB_$(1)):
touch $$@
else

ifeq ($$(findstring emscripten,$(1)),emscripten)
# FIXME: libbacktrace doesn't understand the emscripten triple
$$(BACKTRACE_LIB_$(1)):
touch $$@
else

ifdef CFG_ENABLE_FAST_MAKE
BACKTRACE_DEPS := $(S)/.gitmodules
else
Expand Down Expand Up @@ -348,6 +354,7 @@ $$(BACKTRACE_LIB_$(1)): $$(BACKTRACE_BUILD_DIR_$(1))/Makefile $$(MKFILE_DEPS)
INCDIR=$(S)src/libbacktrace
$$(Q)cp $$(BACKTRACE_BUILD_DIR_$(1))/.libs/libbacktrace.a $$@

endif # endif for emscripten
endif # endif for msvc
endif # endif for ios
endif # endif for darwin
Expand Down
2 changes: 1 addition & 1 deletion src/jemalloc
Submodule jemalloc updated 102 files
3 changes: 2 additions & 1 deletion src/liballoc_system/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ extern crate libc;
target_arch = "arm",
target_arch = "mips",
target_arch = "mipsel",
target_arch = "powerpc")))]
target_arch = "powerpc",
target_arch = "asmjs")))]
const MIN_ALIGN: usize = 8;
#[cfg(all(any(target_arch = "x86_64",
target_arch = "aarch64")))]
Expand Down
2 changes: 1 addition & 1 deletion src/liblibc
38 changes: 38 additions & 0 deletions src/librustc_back/target/asmjs_unknown_emscripten.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use super::{Target, TargetOptions};

pub fn target() -> Target {
let opts = TargetOptions {
linker: "emcc".to_string(),
ar: "emar".to_string(),

dynamic_linking: false,
executables: true,
exe_suffix: ".js".to_string(),
no_compiler_rt: true,
linker_is_gnu: true,
allow_asm: false,
archive_format: "gnu".to_string(),
obj_is_bitcode: true,
.. Default::default()
};
Target {
llvm_target: "asmjs-unknown-emscripten".to_string(),
target_endian: "little".to_string(),
target_pointer_width: "32".to_string(),
target_os: "emscripten".to_string(),
target_env: "".to_string(),
target_vendor: "unknown".to_string(),
arch: "asmjs".to_string(),
options: opts,
}
}
8 changes: 7 additions & 1 deletion src/librustc_back/target/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,10 @@ pub struct TargetOptions {
/// Flag indicating whether ELF TLS (e.g. #[thread_local]) is available for
/// this target.
pub has_elf_tls: bool,
// This is mainly for easy compatibility with emscripten.
// If we give emcc .o files that are actually .bc files it
// will 'just work'.
pub obj_is_bitcode: bool,
}

impl Default for TargetOptions {
Expand Down Expand Up @@ -245,6 +249,7 @@ impl Default for TargetOptions {
exe_allocation_crate: "alloc_system".to_string(),
allow_asm: true,
has_elf_tls: false,
obj_is_bitcode: false,
}
}
}
Expand Down Expand Up @@ -448,7 +453,8 @@ impl Target {
x86_64_pc_windows_msvc,
i686_pc_windows_msvc,

le32_unknown_nacl
le32_unknown_nacl,
asmjs_unknown_emscripten
);


Expand Down
48 changes: 38 additions & 10 deletions src/librustc_trans/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,6 @@ pub struct ModuleConfig {
emit_ir: bool,
emit_asm: bool,
emit_obj: bool,

// Miscellaneous flags. These are mostly copied from command-line
// options.
no_verify: bool,
Expand All @@ -262,7 +261,11 @@ pub struct ModuleConfig {
vectorize_loop: bool,
vectorize_slp: bool,
merge_functions: bool,
inline_threshold: Option<usize>
inline_threshold: Option<usize>,
// Instead of creating an object file by doing LLVM codegen, just
// make the object file bitcode. Provides easy compatibility with
// emscripten's ecc compiler, when used as the linker.
obj_is_bitcode: bool,
}

unsafe impl Send for ModuleConfig { }
Expand All @@ -280,6 +283,7 @@ impl ModuleConfig {
emit_ir: false,
emit_asm: false,
emit_obj: false,
obj_is_bitcode: false,

no_verify: false,
no_prepopulate_passes: false,
Expand All @@ -298,6 +302,7 @@ impl ModuleConfig {
self.no_builtins = trans.no_builtins;
self.time_passes = sess.time_passes();
self.inline_threshold = sess.opts.cg.inline_threshold;
self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode;

// Copy what clang does by turning on loop vectorization at O2 and
// slp vectorization at O3. Otherwise configure other optimization aspects
Expand Down Expand Up @@ -524,11 +529,21 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
f(cpm);
}

if config.emit_bc {
let ext = format!("{}.bc", name_extra);
let out = output_names.with_extension(&ext);
let out = path2cstr(&out);
llvm::LLVMWriteBitcodeToFile(llmod, out.as_ptr());
// Change what we write and cleanup based on whether obj files are
// just llvm bitcode. In that case write bitcode, and possibly
// delete the bitcode if it wasn't requisted. Don't generate the
// machine code, instead copy the .o file from the .bc
let write_bc = config.emit_bc || config.obj_is_bitcode;
let rm_bc = !config.emit_bc && config.obj_is_bitcode;
let write_obj = config.emit_obj && !config.obj_is_bitcode;
let copy_bc_to_obj = config.emit_obj && config.obj_is_bitcode;

let bc_out = output_names.with_extension(&format!("{}.bc", name_extra));
let obj_out = output_names.with_extension(&format!("{}.o", name_extra));

if write_bc {
let bc_out_c = path2cstr(&bc_out);
llvm::LLVMWriteBitcodeToFile(llmod, bc_out_c.as_ptr());
}

time(config.time_passes, &format!("codegen passes [{}]", cgcx.worker), || {
Expand Down Expand Up @@ -562,14 +577,27 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
}
}

if config.emit_obj {
let path = output_names.with_extension(&format!("{}.o", name_extra));
if write_obj {
with_codegen(tm, llmod, config.no_builtins, |cpm| {
write_output_file(cgcx.handler, tm, cpm, llmod, &path, llvm::ObjectFileType);
write_output_file(cgcx.handler, tm, cpm, llmod, &obj_out, llvm::ObjectFileType);
});
}
});

if copy_bc_to_obj {
debug!("copying bitcode {:?} to obj {:?}", bc_out, obj_out);
if let Err(e) = fs::copy(&bc_out, &obj_out) {
cgcx.handler.err(&format!("failed to copy bitcode to object file: {}", e));
}
}

if rm_bc {
debug!("removing_bitcode {:?}", bc_out);
if let Err(e) = fs::remove_file(&bc_out) {
cgcx.handler.err(&format!("failed to remove bitcode: {}", e));
}
}

llvm::LLVMDisposeModule(llmod);
llvm::LLVMContextDispose(llcx);
llvm::LLVMRustDisposeTargetMachine(tm);
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_trans/trans/cabi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use trans::cabi_arm;
use trans::cabi_aarch64;
use trans::cabi_powerpc;
use trans::cabi_mips;
use trans::cabi_asmjs;
use trans::type_::Type;

#[derive(Clone, Copy, PartialEq)]
Expand Down Expand Up @@ -127,6 +128,7 @@ pub fn compute_abi_info(ccx: &CrateContext,
},
"mips" => cabi_mips::compute_abi_info(ccx, atys, rty, ret_def),
"powerpc" => cabi_powerpc::compute_abi_info(ccx, atys, rty, ret_def),
"asmjs" => cabi_asmjs::compute_abi_info(ccx, atys, rty, ret_def),
a => ccx.sess().fatal(&format!("unrecognized arch \"{}\" in target specification", a)
),
}
Expand Down
22 changes: 22 additions & 0 deletions src/librustc_trans/trans/cabi_asmjs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use trans::cabi::FnType;
use trans::cabi_arm;
use trans::context::CrateContext;
use trans::type_::Type;

pub fn compute_abi_info(ccx: &CrateContext,
atys: &[Type],
rty: Type,
ret_def: bool) -> FnType {
cabi_arm::compute_abi_info(ccx, atys, rty, ret_def,
cabi_arm::Flavor::General)
}
1 change: 1 addition & 0 deletions src/librustc_trans/trans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ mod builder;
mod cabi;
mod cabi_aarch64;
mod cabi_arm;
mod cabi_asmjs;
mod cabi_mips;
mod cabi_powerpc;
mod cabi_x86;
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/dynamic_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ mod tests {
target_os = "dragonfly",
target_os = "bitrig",
target_os = "netbsd",
target_os = "openbsd"))]
target_os = "openbsd",
target_os = "emscripten"))]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't wait to remove this file...

mod dl {
use prelude::v1::*;

Expand Down
16 changes: 16 additions & 0 deletions src/libstd/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,17 @@ mod os {
pub const EXE_EXTENSION: &'static str = "pexe";
}

#[cfg(target_os = "emscripten")]
mod os {
pub const FAMILY: &'static str = "unix";
pub const OS: &'static str = "emscripten";
pub const DLL_PREFIX: &'static str = "lib";
pub const DLL_SUFFIX: &'static str = ".so";
pub const DLL_EXTENSION: &'static str = "so";
pub const EXE_SUFFIX: &'static str = ".js";
pub const EXE_EXTENSION: &'static str = "js";
}

#[cfg(target_arch = "x86")]
mod arch {
pub const ARCH: &'static str = "x86";
Expand Down Expand Up @@ -872,6 +883,11 @@ mod arch {
pub const ARCH: &'static str = "le32";
}

#[cfg(target_arch = "asmjs")]
mod arch {
pub const ARCH: &'static str = "asmjs";
}

#[cfg(test)]
mod tests {
use prelude::v1::*;
Expand Down
9 changes: 9 additions & 0 deletions src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,10 @@
#![feature(vec_push_all)]
#![feature(wrapping)]
#![feature(zero_one)]
// Snapshots are configured to link jemalloc by default, which makes
// CFG_DISABLE_JEMALLOC break in stage0 because alloc_jemalloc doesn't exist.
// This forces stage0 to always use the system allocator.
#![cfg_attr(stage0, feature(alloc_system))]

// Don't link to std. We are std.
#![no_std]
Expand All @@ -285,6 +289,11 @@
unreachable, unimplemented, write, writeln, try)]
extern crate core as __core;

// Snapshots are configured to link jemalloc by default, which makes
// CFG_DISABLE_JEMALLOC break in stage0 because alloc_jemalloc doesn't exist.
// This forces stage0 to always use the system allocator.
#[cfg(stage0)] extern crate alloc_system;

#[macro_use]
#[macro_reexport(vec, format)]
extern crate collections as core_collections;
Expand Down
3 changes: 2 additions & 1 deletion src/libstd/os/linux/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ pub use self::arch::{off_t, ino_t, nlink_t, blksize_t, blkcnt_t, stat, time_t};
#[cfg(any(target_arch = "x86",
target_arch = "le32",
target_arch = "powerpc",
target_arch = "arm"))]
target_arch = "arm",
target_arch = "asmjs"))]
mod arch {
use super::{dev_t, mode_t};
use os::raw::{c_long, c_short};
Expand Down
5 changes: 5 additions & 0 deletions src/libstd/os/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@ pub use sys::ext as windows;
#[cfg(target_os = "netbsd")] pub mod netbsd;
#[cfg(target_os = "openbsd")] pub mod openbsd;

// Emscripten is just like linux
#[cfg(target_os = "emscripten")]
#[path = "linux/mod.rs"]
pub mod emscripten;

pub mod raw;
3 changes: 2 additions & 1 deletion src/libstd/sys/common/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ pub fn clone() -> Option<Vec<Vec<u8>>> { imp::clone() }
target_os = "dragonfly",
target_os = "bitrig",
target_os = "netbsd",
target_os = "openbsd"))]
target_os = "openbsd",
target_os = "emscripten"))]
mod imp {
use prelude::v1::*;

Expand Down
4 changes: 4 additions & 0 deletions src/libstd/sys/common/libunwind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ pub const unwinder_private_data_size: usize = 2;
#[cfg(target_arch = "powerpc")]
pub const unwinder_private_data_size: usize = 2;

#[cfg(target_arch = "asmjs")]
// FIXME: Copied from arm. Need to confirm.
pub const unwinder_private_data_size: usize = 20;

#[repr(C)]
pub struct _Unwind_Exception {
pub exception_class: _Unwind_Exception_Class,
Expand Down
Loading