Skip to content
This repository has been archived by the owner on Feb 2, 2023. It is now read-only.

Commit

Permalink
WIP Duration
Browse files Browse the repository at this point in the history
Fix extern static warning

See rust-lang/rust#35112
  • Loading branch information
Godhuda authored and chancancode committed Feb 16, 2017
1 parent 4c45ec5 commit 9a67ce7
Show file tree
Hide file tree
Showing 20 changed files with 441 additions and 17 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
target
Cargo.lock
.vscode
*.o
*.a
*.so
*.dylib
*.bundle
16 changes: 13 additions & 3 deletions crates/libcruby-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ extern "C" {
#[link_name = "HELIX_RSTRING_PTR"]
pub fn RSTRING_PTR(string: VALUE) -> c_string;

#[link_name = "HELIX_rb_utf8_str_new"]
pub fn rb_utf8_str_new(string: c_string, len: libc::c_long) -> VALUE;

#[link_name = "HELIX_RARRAY_LEN"]
pub fn RARRAY_LEN(array: VALUE) -> isize;

#[link_name = "HELIX_RARRAY_PTR"]
pub fn RARRAY_PTR(array: VALUE) -> void_ptr;

#[link_name = "helix_rb_utf8_str_new"]
pub fn rb_utf8_str_new(string: c_string, len: libc::c_long) -> VALUE;

#[link_name = "HELIX_RB_TYPE_P"]
pub fn RB_TYPE_P(val: VALUE, rb_type: isize) -> bool;

Expand All @@ -88,11 +88,21 @@ extern "C" {
pub fn rb_define_module_under(namespace: VALUE, name: c_string) -> VALUE;
pub fn rb_define_class(name: c_string, superclass: VALUE) -> VALUE;
pub fn rb_define_class_under(namespace: VALUE, name: c_string, superclass: VALUE) -> VALUE;
pub fn rb_define_alloc_func(klass: VALUE, func: extern "C" fn(klass: VALUE) -> VALUE);
pub fn rb_define_method(class: VALUE, name: c_string, func: void_ptr, arity: isize);
pub fn rb_intern(string: c_string) -> ID;
pub fn rb_jump_tag(state: RubyException) -> !;
pub fn rb_protect(try: extern "C" fn(v: void_ptr) -> VALUE,
arg: void_ptr,
state: *mut RubyException)
-> VALUE;

#[link_name = "HELIX_Data_Wrap_Struct"]
pub fn Data_Wrap_Struct(klass: VALUE, mark: extern "C" fn(void_ptr), free: extern "C" fn(void_ptr), data: void_ptr) -> VALUE;

#[link_name = "HELIX_Data_Get_Struct_Value"]
pub fn Data_Get_Struct_Value(obj: VALUE) -> void_ptr;

#[link_name = "HELIX_Data_Set_Struct_Value"]
pub fn Data_Set_Struct_Value(obj: VALUE, data: void_ptr);
}
17 changes: 10 additions & 7 deletions examples/console/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions examples/duration/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target
*.bundle
*.gem
24 changes: 24 additions & 0 deletions examples/duration/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
[package]
name = "duration"
version = "0.1.0"
authors = ["Godfrey Chan <[email protected]>"]

[lib]

crate-type = ["staticlib"]

[dependencies]

libc = "*"

[dependencies.libcruby-sys]

path = "../../crates/libcruby-sys"

[dependencies.helix]

path = "../.."

[profile.release]

lto = true
5 changes: 5 additions & 0 deletions examples/duration/Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
source 'https://rubygems.org'

gemspec

gem 'helix_runtime', path: '../../ruby'
29 changes: 29 additions & 0 deletions examples/duration/Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
PATH
remote: ../../ruby
specs:
helix_runtime (0.5.0)

PATH
remote: .
specs:
duration (0.1.0)
helix_runtime

GEM
remote: https://rubygems.org/
specs:
minitest (5.8.3)
rake (10.5.0)

PLATFORMS
ruby

DEPENDENCIES
bundler (~> 1.11)
duration!
helix_runtime!
minitest (~> 5.0)
rake (~> 10.0)

BUNDLED WITH
1.12.5
34 changes: 34 additions & 0 deletions examples/duration/Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'rake/clean'
require 'rake/testtask'
require 'bundler/setup'
require 'bundler/gem_tasks'

directory 'target'
directory 'lib/duration'

task :cargo_build do
sh "cargo build --release"
end
CLEAN.include('target')

file "lib/duration/native.bundle" => ['lib/duration', :cargo_build] do
sh "gcc -Wl,-force_load,target/release/libduration.a --shared -Wl,-undefined,dynamic_lookup -o lib/duration/native.bundle"
end
CLOBBER.include('lib/duration/native.bundle')

task :irb => "lib/duration/native.bundle" do
exec "irb -Ilib -rduration"
end

task :benchmark => "lib/duration/native.bundle" do
exec "ruby -Ilib benchmark.rb"
end

Rake::TestTask.new(:test) do |t|
t.libs << "test"
t.libs << "lib"
t.test_files = FileList['test/**/*_test.rb']
end

task :test => "lib/duration/native.bundle"
task :default => :test
32 changes: 32 additions & 0 deletions examples/duration/duration.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'duration/version'

Gem::Specification.new do |spec|
spec.name = "duration"
spec.version = Duration::VERSION
spec.authors = ["Godfrey Chan"]
spec.email = ["[email protected]"]

spec.summary = "Rust ActiveSupport::Duration"
spec.license = "MIT"

# Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
# delete this section to allow pushing this gem to any host.
if spec.respond_to?(:metadata)
spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
else
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
end

spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.add_runtime_dependency "helix_runtime"
spec.add_development_dependency "bundler", "~> 1.11"
spec.add_development_dependency "rake", "~> 10.0"
spec.add_development_dependency "minitest", "~> 5.0"
end
2 changes: 2 additions & 0 deletions examples/duration/lib/duration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
require "helix_runtime"
require "duration/native"
3 changes: 3 additions & 0 deletions examples/duration/lib/duration/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Duration
VERSION = "0.1.0"
end
18 changes: 18 additions & 0 deletions examples/duration/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#[macro_use]
extern crate helix;

declare_types! {
class Duration {
struct {
inner: u32
}

def initialize() -> Duration {
Duration { inner: 0 }
}

def inspect(self) -> String {
format!("{}", self.inner)
}
}
}
7 changes: 7 additions & 0 deletions examples/duration/test/duration_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'test_helper'

class DurationTest < Minitest::Test
def test_blank
assert_equal 'zomg', Duration.new.inspect
end
end
4 changes: 4 additions & 0 deletions examples/duration/test/test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'duration'

require 'minitest/autorun'
20 changes: 19 additions & 1 deletion ruby/ext/helix_runtime/native/helix_runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,28 @@ VALUE HELIX_FIX2INT(VALUE v) {
return FIX2INT(v);
}

VALUE helix_rb_utf8_str_new(const char* str, long len) {
VALUE HELIX_rb_utf8_str_new(const char* str, long len) {
return rb_utf8_str_new(str, len);
}

VALUE HELIX_Data_Wrap_Struct(VALUE klass, HELIX_RUBY_DATA_FUNC mark, HELIX_RUBY_DATA_FUNC free, void* data) {
return Data_Wrap_Struct(klass, mark, free, data);
}

void* HELIX_Data_Get_Struct_Value(VALUE obj) {
void* data;
Data_Get_Struct(obj, void*, data);
return data;
}

void HELIX_Data_Set_Struct_Value(VALUE obj, void* data) {
DATA_PTR(obj) = data;
}

// void HELIX_rb_define_alloc_func(VALUE klass, HELIX_rb_alloc_func_t func) {
// rb_define_alloc_func(klass, func);
// }

int HELIX_TYPE(VALUE v) {
return TYPE(v);
}
Expand Down
11 changes: 10 additions & 1 deletion ruby/ext/helix_runtime/native/helix_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,16 @@ int HELIX_TYPE(VALUE v);
VALUE HELIX_INT2FIX(int c_int);
VALUE HELIX_FIX2INT(VALUE fix);

VALUE helix_rb_utf8_str_new(const char* str, long len);
VALUE HELIX_rb_utf8_str_new(const char* str, long len);

// typedef VALUE (*HELIX_rb_alloc_func_t)(VALUE);
// void HELIX_rb_define_alloc_func(VALUE klass, HELIX_rb_alloc_func_t func);

typedef void (*HELIX_RUBY_DATA_FUNC)(void*);

VALUE HELIX_Data_Wrap_Struct(VALUE klass, HELIX_RUBY_DATA_FUNC mark, HELIX_RUBY_DATA_FUNC free, void* data);
void* HELIX_Data_Get_Struct_Value(VALUE obj);
void HELIX_Data_Set_Struct_Value(VALUE obj, void* data);

extern int HELIX_T_NONE;
extern int HELIX_T_NIL;
Expand Down
47 changes: 47 additions & 0 deletions ruby/spec/helix_runtime_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,5 +113,52 @@ module TYPES
# expect(Dummy.TYPE({})).to eq(Dummy::T_HASH)
# expect(Dummy.TYPE([])).to_not eq(Dummy::T_OBJECT)
# end

describe "helix_rb_utf8_str_new" do
it "allocates a new string" do
str1 = "hello world"
str2 = Dummy.STR2STR(str1, 5)

expect(str2).to eq("hello")

str1[0...5] = "goodbye"

expect(str1).to eq("goodbye world")
expect(str2).to eq("hello")

str2 << " world!"

expect(str1).to eq("goodbye world")
expect(str2).to eq("hello world!")
end
end

describe "Data_{Wrap,Get,Set}_Struct" do
it "can allocate then change the data" do
wrapper = Dummy::Wrapper.new

expect(Dummy.get_data(wrapper)).to eq(0)

ptr = Dummy.get_data_ptr(wrapper)

expect(Dummy.set_data(wrapper, 1)).to eq(1)

expect(Dummy.get_data(wrapper)).to eq(1)
expect(Dummy.get_data_ptr(wrapper)).to eq(ptr)
end

it "can allocate then replace the data" do
wrapper = Dummy::Wrapper.new

expect(Dummy.get_data(wrapper)).to eq(0)

ptr = Dummy.get_data_ptr(wrapper)

expect(Dummy.replace_data(wrapper, 1)).to eq(1)

expect(Dummy.get_data(wrapper)).to eq(1)
expect(Dummy.get_data_ptr(wrapper)).not_to eq(ptr)
end
end
end

Loading

0 comments on commit 9a67ce7

Please sign in to comment.