Skip to content

Commit

Permalink
Merge pull request #7 from ruby/pz-dont-clone-ruby
Browse files Browse the repository at this point in the history
Use rake-compiler to compile
  • Loading branch information
peterzhu2118 authored Dec 6, 2024
2 parents 9e0c20c + d716a4e commit a8d0c50
Show file tree
Hide file tree
Showing 12 changed files with 1,611 additions and 83 deletions.
6 changes: 1 addition & 5 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
.ruby-version
Gemfile.lock

# ignore resources directory, where temp build artifacts are placed
res

# ignore the gc module build directory
mod_gc
tmp
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
source "https://rubygems.org"

gem "rake"
gem "rake-compiler"
52 changes: 27 additions & 25 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -1,34 +1,36 @@
# frozen_string_literal: true

$LOAD_PATH << File.expand_path("tool", __dir__)
require "fileutils"
require "net/http"
require "rbconfig"
require "rake/extensiontask"

require 'fileutils'
require 'tempfile'
require 'net/http'
require 'digest'
require 'etc'
require 'mmtk_support'
task default: [:compile, :install]

task default: %i[compile install]

desc <<~DESC
Install the MMTk GC shared object into the Shared GC dir for the currently
running Ruby
DESC
task :install, :compile do
install_mmtk
Rake::ExtensionTask.new do |ext|
ext.name = "librubygc.mmtk"
ext.ext_dir = "gc/mmtk"
ext.lib_dir = "tmp/binaries"
end

desc <<~DESC
Build the MMTk GC implementation shared object
DESC
task :compile do
MMTkSupport.new.build
task :install do
FileUtils.mv(Dir.glob("tmp/binaries/*"), RbConfig::CONFIG["modular_gc_dir"])
end

desc <<~DESC
Remove all generated build artifacts
DESC
task :clean do
system("git clean -ffdx")
RUBY_HEADERS = %w[
ccan/check_type/check_type.h ccan/container_of/container_of.h ccan/list/list.h ccan/str/str.h
gc/gc_impl.h gc/gc.h gc/extconf_base.rb
darray.h
]
task :vendor_ruby_headers do
RUBY_HEADERS.each do |file|
Net::HTTP.start("raw.githubusercontent.com", 443, use_ssl: true) do |http|
resp = http.get("ruby/ruby/refs/heads/master/#{file}")

FileUtils.mkdir_p(File.dirname(file))
open(file, "wb") do |file|
file.write(resp.body)
end
end
end
end
63 changes: 63 additions & 0 deletions ccan/check_type/check_type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
#ifndef CCAN_CHECK_TYPE_H
#define CCAN_CHECK_TYPE_H

/**
* ccan_check_type - issue a warning or build failure if type is not correct.
* @expr: the expression whose type we should check (not evaluated).
* @type: the exact type we expect the expression to be.
*
* This macro is usually used within other macros to try to ensure that a macro
* argument is of the expected type. No type promotion of the expression is
* done: an unsigned int is not the same as an int!
*
* ccan_check_type() always evaluates to 0.
*
* If your compiler does not support typeof, then the best we can do is fail
* to compile if the sizes of the types are unequal (a less complete check).
*
* Example:
* // They should always pass a 64-bit value to _set_some_value!
* #define set_some_value(expr) \
* _set_some_value((ccan_check_type((expr), uint64_t), (expr)))
*/

/**
* ccan_check_types_match - issue a warning or build failure if types are not same.
* @expr1: the first expression (not evaluated).
* @expr2: the second expression (not evaluated).
*
* This macro is usually used within other macros to try to ensure that
* arguments are of identical types. No type promotion of the expressions is
* done: an unsigned int is not the same as an int!
*
* ccan_check_types_match() always evaluates to 0.
*
* If your compiler does not support typeof, then the best we can do is fail
* to compile if the sizes of the types are unequal (a less complete check).
*
* Example:
* // Do subtraction to get to enclosing type, but make sure that
* // pointer is of correct type for that member.
* #define ccan_container_of(mbr_ptr, encl_type, mbr) \
* (ccan_check_types_match((mbr_ptr), &((encl_type *)0)->mbr), \
* ((encl_type *) \
* ((char *)(mbr_ptr) - offsetof(enclosing_type, mbr))))
*/
#if defined(HAVE_TYPEOF) && HAVE_TYPEOF
#define ccan_check_type(expr, type) \
((typeof(expr) *)0 != (type *)0)

#define ccan_check_types_match(expr1, expr2) \
((typeof(expr1) *)0 != (typeof(expr2) *)0)
#else
#include "ccan/build_assert/build_assert.h"
/* Without typeof, we can only test the sizes. */
#define ccan_check_type(expr, type) \
CCAN_BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type))

#define ccan_check_types_match(expr1, expr2) \
CCAN_BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2))
#endif /* HAVE_TYPEOF */

#endif /* CCAN_CHECK_TYPE_H */
142 changes: 142 additions & 0 deletions ccan/container_of/container_of.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/* CC0 (Public domain) - see ccan/licenses/CC0 file for details */
#ifndef CCAN_CONTAINER_OF_H
#define CCAN_CONTAINER_OF_H
#include "ccan/check_type/check_type.h"

/**
* ccan_container_of - get pointer to enclosing structure
* @member_ptr: pointer to the structure member
* @containing_type: the type this member is within
* @member: the name of this member within the structure.
*
* Given a pointer to a member of a structure, this macro does pointer
* subtraction to return the pointer to the enclosing type.
*
* Example:
* struct foo {
* int fielda, fieldb;
* // ...
* };
* struct info {
* int some_other_field;
* struct foo my_foo;
* };
*
* static struct info *foo_to_info(struct foo *foo)
* {
* return ccan_container_of(foo, struct info, my_foo);
* }
*/
#define ccan_container_of(member_ptr, containing_type, member) \
((containing_type *) \
((char *)(member_ptr) \
- ccan_container_off(containing_type, member)) \
+ ccan_check_types_match(*(member_ptr), ((containing_type *)0)->member))


/**
* ccan_container_of_or_null - get pointer to enclosing structure, or NULL
* @member_ptr: pointer to the structure member
* @containing_type: the type this member is within
* @member: the name of this member within the structure.
*
* Given a pointer to a member of a structure, this macro does pointer
* subtraction to return the pointer to the enclosing type, unless it
* is given NULL, in which case it also returns NULL.
*
* Example:
* struct foo {
* int fielda, fieldb;
* // ...
* };
* struct info {
* int some_other_field;
* struct foo my_foo;
* };
*
* static struct info *foo_to_info_allowing_null(struct foo *foo)
* {
* return ccan_container_of_or_null(foo, struct info, my_foo);
* }
*/
static inline char *container_of_or_null_(void *member_ptr, size_t offset)
{
return member_ptr ? (char *)member_ptr - offset : NULL;
}
#define ccan_container_of_or_null(member_ptr, containing_type, member) \
((containing_type *) \
ccan_container_of_or_null_(member_ptr, \
ccan_container_off(containing_type, member)) \
+ ccan_check_types_match(*(member_ptr), ((containing_type *)0)->member))

/**
* ccan_container_off - get offset to enclosing structure
* @containing_type: the type this member is within
* @member: the name of this member within the structure.
*
* Given a pointer to a member of a structure, this macro does
* typechecking and figures out the offset to the enclosing type.
*
* Example:
* struct foo {
* int fielda, fieldb;
* // ...
* };
* struct info {
* int some_other_field;
* struct foo my_foo;
* };
*
* static struct info *foo_to_info(struct foo *foo)
* {
* size_t off = ccan_container_off(struct info, my_foo);
* return (void *)((char *)foo - off);
* }
*/
#define ccan_container_off(containing_type, member) \
offsetof(containing_type, member)

/**
* ccan_container_of_var - get pointer to enclosing structure using a variable
* @member_ptr: pointer to the structure member
* @container_var: a pointer of same type as this member's container
* @member: the name of this member within the structure.
*
* Given a pointer to a member of a structure, this macro does pointer
* subtraction to return the pointer to the enclosing type.
*
* Example:
* static struct info *foo_to_i(struct foo *foo)
* {
* struct info *i = ccan_container_of_var(foo, i, my_foo);
* return i;
* }
*/
#if defined(HAVE_TYPEOF) && HAVE_TYPEOF
#define ccan_container_of_var(member_ptr, container_var, member) \
ccan_container_of(member_ptr, typeof(*container_var), member)
#else
#define ccan_container_of_var(member_ptr, container_var, member) \
((void *)((char *)(member_ptr) - \
ccan_container_off_var(container_var, member)))
#endif

/**
* ccan_container_off_var - get offset of a field in enclosing structure
* @container_var: a pointer to a container structure
* @member: the name of a member within the structure.
*
* Given (any) pointer to a structure and a its member name, this
* macro does pointer subtraction to return offset of member in a
* structure memory layout.
*
*/
#if defined(HAVE_TYPEOF) && HAVE_TYPEOF
#define ccan_container_off_var(var, member) \
ccan_container_off(typeof(*var), member)
#else
#define ccan_container_off_var(var, member) \
((const char *)&(var)->member - (const char *)(var))
#endif

#endif /* CCAN_CONTAINER_OF_H */
Loading

0 comments on commit a8d0c50

Please sign in to comment.