pacak / cargo-show-asm Goto Github PK
View Code? Open in Web Editor NEWcargo subcommand showing the assembly, LLVM-IR and MIR generated for Rust code
License: Apache License 2.0
cargo subcommand showing the assembly, LLVM-IR and MIR generated for Rust code
License: Apache License 2.0
The code which locates the assembly file for an executable target uses same_file::is_same_file
to find the file in deps/
that is that same as the target binary. On Linux this works because cargo hard links the two (see the inode matching in the first column of the ls -li
output:
linux-box> ls -li target/thumbv6m-none-eabi/release/rp2040-project-template
43257897 -rwx------ 2 konkers primarygroup 462184 Oct 26 23:19 target/thumbv6m-none-eabi/release/rp2040-project-template
linux-box> ls -li target/thumbv6m-none-eabi/release/deps/rp2040_project_template-ada3da3d6c134605
43257897 -rwx------ 2 konkers primarygroup 462184 Oct 26 23:19 target/thumbv6m-none-eabi/release/deps/rp2040_project_template-ada3da3d6c134605
However, on MacOS, it appears that cargo is copying the file as they have different inodes:
mac-box> ls -li target/thumbv6m-none-eabi/release/deps/rp2040_project_template-230a92e91f598f68
64623547 -rwx------ 1 konkers primarygroup 433724 Oct 28 09:56 target/thumbv6m-none-eabi/release/deps/rp2040_project_template-230a92e91f598f68
mac-box> ls -li target/thumbv6m-none-eabi/release/rp2040-project-template
64629801 -rwx------ 1 konkers primarygroup 433724 Oct 28 09:56 target/thumbv6m-none-eabi/release/rp2040-project-template
Perhaps comparing the actual contents is needed on MacOS?
cargo install
fails on macOS 12.6 on an M2 macbook air with Rust 1.64. Once all the dependencies compile, I get a huge list of successful compilation (exit 0) messages and then the fun begins:
--- stderr
error occurred: Command "cc" "-O3" "-ffunction-sections" "-fdata-sections" "-fPIC" "-arch" "arm64" "-I" "/var/folders/ws/bntkf5_n1rjfl5gk0py4wqhw0000gn/T/cargo-installzOzfiA/release/build/libgit2-sys-9f995afbb98cc2a6/out/include" "-I" "libgit2/src/libgit2" "-I" "libgit2/src/util" "-I" "libgit2/deps/http-parser" "-I" "libgit2/deps/pcre" "-I" "/var/folders/ws/bntkf5_n1rjfl5gk0py4wqhw0000gn/T/cargo-installzOzfiA/release/build/libssh2-sys-e07d767d7ab8109f/out/include" "-fvisibility=hidden" "-DGIT_REGEX_BUILTIN=1" "-DHAVE_STDINT_H=1" "-DHAVE_MEMMOVE=1" "-DNO_RECURSE=1" "-DNEWLINE=10" "-DPOSIX_MALLOC_THRESHOLD=10" "-DLINK_SIZE=2" "-DPARENS_NEST_LIMIT=250" "-DMATCH_LIMIT=10000000" "-DMATCH_LIMIT_RECURSION=MATCH_LIMIT" "-DMAX_NAME_SIZE=32" "-DMAX_NAME_COUNT=10000" "-DSHA1DC_NO_STANDARD_INCLUDES=1" "-DSHA1DC_CUSTOM_INCLUDE_SHA1_C="common.h"" "-DSHA1DC_CUSTOM_INCLUDE_UBC_CHECK_C="common.h"" "-o" "/var/folders/ws/bntkf5_n1rjfl5gk0py4wqhw0000gn/T/cargo-installzOzfiA/release/build/libgit2-sys-9f995afbb98cc2a6/out/build/libgit2/src/libgit2/streams/stransport.o" "-c" "libgit2/src/libgit2/streams/stransport.c" with args "cc" did not execute successfully (status code exit status: 1).
</details>
Try the following:
cargo new whatever --lib
cd whatever
The default library template comes with a test called tests::it_works
.
cargo asm --test
shows "No tests available." Trying to specify the test:
cargo asm --test tests::it_works
doesn't work either, as it shows "no test target named tests::it_works
."
When using cargo asm
on the https://github.com/shadow/shadow respository with the --rust
flag, I get the following panic:
$ cargo asm --rust -p shadow-shim-helper-rs "shadow_shim_helper_rs::emulated_time::EmulatedTime::saturating_add"
shadow_shim_helper_rs::emulated_time::EmulatedTime::saturating_add:
.Lfunc_begin11:
// /tmp/shadow/src/lib/shadow-shim-helper-rs/src/emulated_time.rs : 99
pub fn saturating_add(&self, duration: SimulationTime) -> EmulatedTime {
.cfi_startproc
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 1500', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-show-asm-0.1.18/src/asm.rs:576:38
stack backtrace:
0: rust_begin_unwind
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/panicking.rs:142:14
2: core::panicking::panic_bounds_check
at /rustc/4b91a6ea7258a947e59c6522cd5898e7c0a6a88f/library/core/src/panicking.rs:84:5
3: cargo_show_asm::asm::dump_function
4: cargo_asm::main
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
--color is passed to rustc , but this doesn't affect the final output since its generated by this crate.
so currently --color translates to rustc --color always --metadata-format=json
which actually has no effect.
To actually force color the user currently needs to set FORCE_COLOR=1
to make owo-colors actually force the colors.
Currently CI simply runs the generation but the output was wrong on MacOS...
The idea is to run the tests with the output as deterministic as possible and compare the output test produces with golden output stored somewhere. Ideally with as little os specific code as possible
Sometimes it seems to be useful to look at the LLVM IR generated by Rust with optimizations enabled, but before any LLVM passes. One example is to look for whether an argument to a function that will be inlined has noalias
.
Implementation-wise, this can be done by passing -C no-prepopulate-passes
to rustc.
I think it would be convenient if cargo-show-asm could do this (and I can send a PR), but I'm not sure what would be the best way to expose the feature in the CLI:
--rust-llvm
or --llvm-input
?--llvm
flag, something like --llvm=rust
or --llvm=input
?no-prepopulate-passes
and passes
?EDIT: of course, this can already be done by passing -C no-prepopulate-passes
through RUSTFLAGS
. But that's quite unwieldy to type, and I'm guessing it's not that uncommon for those looking into LLVM IR to want to [also] see it before the LLVM passes.
When using the project below, I get Error: Compilation produced multiple matching files: [Ok("/home/<user>/tmp/hello/target/thumbv7em-none-eabihf/release/deps/hello-4b3303ff09815de6.s"), Ok("/home/<user>/tmp/hello/target/thumbv7em-none-eabihf/release/deps/hello-e1fd39ec783ba3fe.s")], this is a bug
In the sample project --bin works while --lib fails, though in my bigger project both fail. I am unsure what the difference is and will look at it later.
Requires the cross
branch.
Create project and enter
cargo new hello
cd hello
Modify main.rs
echo '#![no_main]
#![no_std]
use defmt_rtt as _;
use panic_halt as _;
#[inline(never)]
pub fn print() {
defmt::error!("idle loop");
}' > src/lib.rs
Add binary
mkdir -p src/bin &&
echo '#![no_main]
#![no_std]
use cortex_m_rt::entry;
use hello::print;
#[entry]
fn main() -> ! {
loop {
print();
}
}' > src/bin/hello.rs
Set-up Cargo.toml
echo 'cortex-m = "0.6.2"
cortex-m-rt = "0.6.11"
panic-halt = "0.2.0"
defmt = "0.3.0"
defmt-rtt = "0.3.0"' >> Cargo.toml
get necessary memory.x and set-up .cargo/config
wget https://raw.githubusercontent.com/stm32-rs/stm32g4xx-hal/master/memory.x
mkdir .cargo
echo '[target.thumbv7em-none-eabihf]
runner = "arm-none-eabi-gdb -q -x openocd.gdb"
rustflags = [
"-C", "linker=flip-link",
"-C", "link-arg=-Map=.linker.map",
"-C", "link-arg=-Tlink.x",
"-C", "link-arg=-Tdefmt.x",
]
[build]
target = "thumbv7em-none-eabihf"' > .cargo/config
cargo asm --lib hello::print
<-- Fails
cargo asm --bin hello hello::__cortex_m_rt_main
<-- Works
example: cargo asm -p project --bench teststuff main
some more info:
The example might be contrived or I'm doing something wrong, but I haven't gotten this to output the asm of benchmarks, let alone show me the actual functions when listing. I'm using criterion. It also doesn't work with a real, working criterion benchmark.
Please tell me what other info I should provide.
Code refers to .LCPI134_0
and .LCPI134_1
bpaf::roundaaa:
.Lfunc_begin134:
.cfi_startproc
movss xmm1, dword ptr [rip + .LCPI134_0]
.Ltmp4420:
maxss xmm1, xmm0
movss xmm0, dword ptr [rip + .LCPI134_1]
.Ltmp4421:
minss xmm0, xmm1
cvttss2si eax, xmm0
ret
.Ltmp4422:
.Lfunc_end134:
.size bpaf::roundaaa, .Lfunc_end134-bpaf::roundaaa
.cfi_endproc
those values are defined right before it
.section .rodata.cst4,"aM",@progbits,4
.p2align 2
.LCPI134_0:
.long 0xc3000000
.LCPI134_1:
.long 0x42fe0000
In shadow (an admittedly complex hybrid C/Rust project that uses build scripts, bindgen, and cbindgen...) I'm getting the following error:
# Use shadow's helper to initialize a cmake build dir
$ ./setup build debug
...
# Try using cargo asm:
$ (cd src && cargo asm -p shadow-rs --lib "shadow_rs::main::host::Host::default_ip")
...
Error: Cannot locate the path to the asm file
I tried on both Rust 1.63.0 and 1.65.0
OS: Windows 10
Cargo version: 1.64.0-nightly (a5e08c470 2022-06-23)
cargo-show-asm version: 0.2.8
Code:
fn main() {
let a = Box::<i32>::new(42);
println!("hi");
}
Command:
$ cargo asm --dev rust::main
Output:
[...]
.section .text,"xr",one_only,rust::main
.seh_endproc
.def "?dtor$3@?0?rust::main@4HA";
.scl 3;
.type 32;
.endef
.p2align 4, 0x90
"?dtor$3@?0?_ZN4rust4main17h90585feb19c01afdE@4HA":
.seh_proc "?dtor$3@?0?_ZN4rust4main17h90585feb19c01afdE@4HA"
mov qword ptr [rsp + 16], rdx
push rbp
.seh_pushreg rbp
sub rsp, 48
.seh_stackalloc 48
lea rbp, [rdx + 128]
.seh_endprologue
lea rcx, [rbp - 72]
.cv_loc 57 20 4 0
call core::ptr::drop_in_place<alloc::boxed::Box<i32>>
.cv_loc 57 20 1 0
nop
add rsp, 48
pop rbp
ret
Notice how this doesn't have anything resembling a println (core::fmt or std::io calls), and the .def
says "?dtor". This appears to be some auxiliary code that destroys the Box, not the full code of the main function.
For comparison, if we remove the Box (so that main()
has no destructors to call), everything makes sense:
fn main() {
println!("hi");
}
Output:
.section .text,"xr",one_only,rust::main
.p2align 4, 0x90
rust::main:
.cv_func_id 12
.cv_file 9 "C:\\Users\\al13n\\Dropbox\\coding\\rust\\src\\main.rs" "172D6E03251C33BB4189DFD109625F0A402180F6" 2
.cv_loc 12 9 1 0
.seh_proc _ZN4rust4main17h90585feb19c01afdE
sub rsp, 88
.seh_stackalloc 88
.seh_endprologue
.cv_loc 12 9 2 0
lea rcx, [rsp + 40]
lea rdx, [rip + __unnamed_5]
mov r8d, 1
lea r9, [rip + __unnamed_3]
xor eax, eax
mov qword ptr [rsp + 32], 0
call core::fmt::Arguments::new_v1
lea rcx, [rsp + 40]
call std::io::stdio::_print
.cv_loc 12 9 3 0
nop
add rsp, 88
ret
Perhaps this has something to do with Windows's SEH (which I don't know anything about, just guessing). Maybe the rust compiler produces these extra destructor "functions" on Windows, and cargo-show-asm's target function lookup logic gets confused by them?
Adding panic = 'abort'
in Cargo.toml fixes this, by removing all the "dtor" stuff from the generated code.
Hi! When I run cargo-show-asm
version 0.1.23
, I get an indexing panic.
Repro:
$ git clone https://github.com/rust-lang/rustc-perf
$ cd rustc-perf/collector/runtime-benchmarks
$ cargo asm --bin hashmap-bench "hashmap_bench::main" --rust
...
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 1674', /home/kobzol/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-show-asm-0.1.23/src/asm.rs:141:34
stack backtrace:
0: rust_begin_unwind
at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/std/src/panicking.rs:584:5
1: core::panicking::panic_fmt
at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/panicking.rs:142:14
2: core::panicking::panic_bounds_check
at /rustc/a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52/library/core/src/panicking.rs:84:5
3: cargo_show_asm::asm::dump_range
4: cargo_show_asm::asm::dump_function
5: cargo_asm::main
Rust version:
rustc 1.64.0 (a55dd71d5 2022-09-19)
binary: rustc
commit-hash: a55dd71d5fb0ec5a6a3a9e8c27b2127ba491ce52
commit-date: 2022-09-19
host: x86_64-unknown-linux-gnu
release: 1.64.0
LLVM version: 14.0.6
this should error out instead (when name nomangle_name
is not mangled)
% cargo asm nomangle_name 3232
In the cargo-show-asm project, run cargo asm --lib demangle
:
$ cargo asm --lib demangle
Finished release [optimized] target(s) in 0.02s
Try one of those by name or a sequence number
0 "<cargo_show_asm::demangle::CommentColorizer as regex::re_unicode::Replacer>::replace_append" [75]
1 "<cargo_show_asm::demangle::Demangler as regex::re_unicode::Replacer>::replace_append" [216]
2 "<cargo_show_asm::demangle::LabelColorizer as regex::re_unicode::Replacer>::replace_append" [75]
3 "<cargo_show_asm::demangle::LabelKind as core::fmt::Debug>::fmt" [47]
4 "cargo_show_asm::demangle::color_comment" [763]
5 "cargo_show_asm::demangle::color_local_labels" [763]
...
If I run cargo asm --lib demangle 4
, I expect to see the assembly for cargo_show_asm::demangle::color_comment
but instead I get the above list again.
This is a nightly-only rustc
config option that causes LLVM to preserve assembly comments. It can be useful for debugging in combination with core::arch::asm!("nop # Some Comment");
.
Currently if I attempt to apply this manually, it breaks:
$ RUSTFLAGS="-Z asm-comments" cargo +nightly asm ...
...
Finished release [optimized] target(s) in 0.01s
Error: Couldn't find any items to display
Right now, running
cargo asm foobar
is equivalent to
cargo asm --release foobar
and the dev profile requires
cargo asm --dev foobar
Eg, the release profile is the default. There are obvious benefits to this, since most of the time you want the assembly of your release binary, since it's the one you're likely trying to optimize. Having release be the default saves you from having to type --release
every time, makes the commands shorter, etc.
I'd still argue it's the wrong default.
As far as I know, absolutely every other cargo command assumes --dev
by default. Having a different for cargo-show-asm is unexpected; it's something you have to actively remind yourself of.
Well, cargo-show-asm is primarily a debugging / benchmarking tool, right?
Most of the time, you're going to be using it because your program doesn't exhibit the performance characteristics you expect, and you want to find out why.
But say you're an absolute idiot (like me).
You might then run your program with cargo run -- some args
, and have unexpected performance characteristics. You might then use cargo asm foobar
to check some function taking up most of your program's runtime, and see that the assembly is roughly what you expected, something that should run much faster than your program does.
What you might not realize for a while is that cargo asm
is not, in fact, examining the binary executed by cargo run
, because the latter will be in dev profile while the former will be in release profile.
And, okay, if I'm that idiot, part of that is on me for not realizing sooner that I was trying to benchmark an unoptimized version of my program.
But the process of realizing that requires me to use various tools to gain an understanding of my program and notice my obvious mistakes. When one of those tools, cargo-show-asm, behaves in a way that violates a basic expectation of mind that I didn't think to double-check (that cargo asm
would display the code executed by cargo run
), finding my root mistake takes much longer than it did if my tools kept to the principle of least expectation.
(I hope I'm not coming off as abrasive here. I'm belaboring the point a lot, not because I think it's obvious and the maintainers are stupid for not seeing it, but because I think it's subtle and I'm struggling to put it into words.)
Anyway, if genuinely think --dev
would be a better default, even if it makes everybody's commands a little longer.
Might be tricky with all the optimizations the compiler does...
Consider an example: crate contains two functions: bpaf::parse
and bpaf::parse_with
, currently to see the output of bpaf::parse_width
you need to enable the hashed names and dump bpaf::parse
with hash suffix. It might be better to always dump fully matching names and add something like "also there's those function that might match"...
"I have a small change in the code, but the Assembly difference is huge. Everything is re-arranged and jump labels are all different."
I have a project for which I would like to see the assembly output of a certain Cargo profile, given --profile bench
instead of using the usual --release
compilation.
Unfortunately this is not (yet) supported by the cargo-asm
tool.
Would it be possible to implement this?
When I enable lto = "thin"
in the release profile cargo asm
stops showing assembly output for my binary:
warning: ignoring emit path because multiple .s files were produced
Error: Cannot locate the path to the asm file
Today I wanted to try out this tool to examine the generated assembly of a particular function in my project.
However, the function that I was most interested in unfortunately did not even show up in the filters.
I tried to make it public and exported it etc but all that did not work. Also I could not find documentation about how to make a function in a crate displayable via this tool.
It would be neat to have this information available. :) And in case I missed information that is already available somewhere please point me to it.
update: I got cargo-asm
to show the function. The problem was that the function was generic and thus had no proper monomorphized instantiation. I fixed it by defining a new function with default generic parameters in place.
cargo
library is heavy and hard to compile (#50 #51). I don't think the main functionality, disassembling, has anything to do with openssl
and libgit
dependencies.
Since we are a cargo subcommand, the cargo binary is almost always available through CARGO
env var (which may be from package manager) . Could we just using the CLI interface of cargo
without pulling the library, or is there anything can only work with libcargo?
diff --git a/src/opts.rs b/src/opts.rs
index 52fbaa4..3772c7f 100644
--- a/src/opts.rs
+++ b/src/opts.rs
@@ -48,8 +48,8 @@ pub struct Options {
pub syntax: Syntax,
// what to display
- #[bpaf(external)]
- pub to_dump: ToDump,
+ #[bpaf(external, optional)]
+ pub to_dump: Option<ToDump>,
}
#[derive(Debug, Clone, Bpaf)]
@@ -101,8 +101,8 @@ pub enum ToDump {
Function {
/// Dump function with that specific name / filter functions containing this string
- #[bpaf(positional("FUNCTION"), optional)]
- function: Option<String>,
+ #[bpaf(positional("FUNCTION"))]
+ function: String,
/// Select specific function when there's several with the same name
#[bpaf(positional("INDEX"), fallback(0))]
this + corresponding cleanup
Issue:
Running cargo asm --rust --everything
panics and outputs this error:
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 210'
stack backtrace:
0: rust_begin_unwind
1: core::panicking::panic_fmt
2: core::panicking::panic_bounds_check
3: cargo_show_asm::asm::dump_range
4: cargo_show_asm::asm::dump_function
5: cargo_asm::main
Trying cargo asm --bin <project> <function_name>
on my project fails with the above error. The listed path is wrong since I'm cross-compiling for thumbv7em-none-eabihf.
The correct path should be /homedir/project/target/thumbv7em-none-eabihf/release/deps/project-*.s.
I tried the following but I only see function names. Are there more options that I need to specify?
cargo asm --lib --target=wasm32-unknown-unknown
# pwsh session
PS> $env:CARGO_TARGET_DIR
D:\.rust\target
PS> cargo asm
Finished release [optimized] target(s) in 0.00s
Error: Compilation produced no files satisfying .\deps\lib-*.s, this is a bug
PS> $env:CARGO_TARGET_DIR = $null
PS> cargo asm
Finished release [optimized] target(s) in 0.00s
lib::add:
.Lfunc_begin0:
.cv_func_id 0
.cv_file 1 "D:\\git\\cad97\\playground\\src\\lib.rs" "9D57490222A66006B2F72186655C847E190625EB" 2
.cv_loc 0 1 2 0
lea eax, [rcx + rdx]
.cv_loc 0 1 3 0
ret
.Ltmp0:
.Lfunc_end0:
Lines 361 to 363 in 171b205
nom
's many0
function just eats all errors, so you'll never see them. This means that if a file doesn't completely parse, then cargo-show-asm
will think that the function provided doesn't exist!
cargo version: cargo 1.62.0-nightly (dba5baf43 2022-04-13)
target: aarch64-apple-darwin
Existing code can find .s
files but not figure out their contents. --everything
works and cargo-show-asm
will suggest to use it in such cases.
I was unable to get something like the following to work in miniz_oxide git repo.
cargo asm -p miniz_oxide --lib "<miniz_oxide::deflate::core::CompressorOxide as core::default::Default>::default"
When I copied the miniz_oxide
subdirectory out of the workspace I was able to get it to work.
Trying to run on crossbeam's crossbeam-utils crate on windows gave me these errors:
crossbeam\crossbeam-utils> cargo asm --test subcrates
Error: Compilation produced no files satisfying .\deps\subcrates-*.s, this is a bug
crossbeam\crossbeam-utils> cargo asm --lib
Error: Compilation produced no files satisfying .\deps\crossbeam-*.s, this is a bug
I'm not sure if there's some dependency I'm missing or something, I just installed via cargo install cargo-show-asm
When decompiling a simple function, the output is something like
.section .text.poc::func,"ax",@progbits
.globl poc::func
.p2align 4, 0x90
.type poc::func,@function
poc::func:
.cfi_startproc
mov rax, rdi
mov byte ptr [rdi], 0
mov byte ptr [rdi + 2], 0
mov byte ptr [rdi + 4], 0
mov byte ptr [rdi + 6], 0
mov byte ptr [rdi + 8], 0
mov byte ptr [rdi + 10], 0
mov byte ptr [rdi + 12], 0
mov byte ptr [rdi + 14], 0
ret
.Lfunc_end0:
.size poc::func, .Lfunc_end0-poc::func
It would be useful to have an option to only output the generated assembly, (as well as any jump labels) to make comparing code easier - e.g.
poc::func:
mov rax, rdi
mov byte ptr [rdi], 0
mov byte ptr [rdi + 2], 0
mov byte ptr [rdi + 4], 0
mov byte ptr [rdi + 6], 0
mov byte ptr [rdi + 8], 0
mov byte ptr [rdi + 10], 0
mov byte ptr [rdi + 12], 0
mov byte ptr [rdi + 14], 0
ret
This seems similar to #65 but that was fixed in 0.1.24.
rust-src seems to be fine:
$ rustup component add rust-src
info: component 'rust-src' is up to date
I've attached the output from:
$ cargo asm --intel --lib 5 --rust -vvvv
I want check if my crate removes all calls to, e.g. memcpy.
For that I'd like to get the whole asm and then grep on it.
Finished release [optimized] target(s) in 0.35s
Error: Compilation produced no files satisfying .\target\release\deps\kubi-*.s, this is a bug
-Z unpretty=hir
And possibly other compiler flags
Hi, I'm using cargo asm --bench -p project .... function,
as I'd like to analyze a benchmark in package or crate . However, this only works if "function" also exists in the same crate as the benchmark. If I try to define function which exists in a different crate, then asm cannot find it. I have tried only part of the name as well as full path. Is it possible to dump out the asm from a function in a different crate than the bench or executable?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.