Skip to content

Commit

Permalink
Showing 9 changed files with 349 additions and 12 deletions.
60 changes: 54 additions & 6 deletions lib/ruby/truffle/cext/ruby.h
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ extern "C" {

#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
@@ -38,8 +39,8 @@ extern "C" {
#define xfree free
#define ALLOC_N(type, n) malloc(sizeof(type) * n)

typedef void* ID;
typedef void* VALUE;
typedef void *ID;
typedef void *VALUE;

#define NORETURN(X) __attribute__((__noreturn__)) X

@@ -124,6 +125,15 @@ struct rb_data_type_struct {
VALUE flags;
};

int rb_type(VALUE value);
#define TYPE(value) rb_type((VALUE) (value))
bool RB_TYPE_P(VALUE value, int type);

void rb_check_type(VALUE value, int type);
#define Check_Type(v,t) rb_check_type((VALUE)(v), (t))

VALUE rb_obj_is_kind_of(VALUE object, VALUE ruby_class);

// Constants

VALUE get_Qfalse(void);
@@ -149,8 +159,12 @@ VALUE get_rb_mKernel(void);
#define rb_mKernel get_rb_mKernel()

VALUE get_rb_eRuntimeError(void);
VALUE get_rb_eStandardError(void);
VALUE get_rb_eNoMemError(void);

#define rb_eRuntimeError get_rb_eRuntimeError()
#define rb_eStandardError get_rb_eStandardError()
#define rb_eNoMemError get_rb_eNoMemError()

// Conversions

@@ -192,14 +206,22 @@ double RFLOAT_VALUE(VALUE value);
// String

char *RSTRING_PTR(VALUE string);
int RSTRING_LEN(VALUE string);
int rb_str_len(VALUE string);
#define RSTRING_LEN(str) rb_str_len(str)
#define RSTRING_LENINT(str) rb_str_len(str)
VALUE rb_intern_str(VALUE string);
VALUE rb_str_new(const char *string, long length);
VALUE rb_str_new_cstr(const char *string);
#define rb_str_new2 rb_str_new_cstr
void rb_str_cat(VALUE string, const char *to_concat, long length);

VALUE rb_str_cat(VALUE string, const char *to_concat, long length);
VALUE rb_str_cat2(VALUE string, const char *to_concat);
VALUE rb_str_to_str(VALUE string);
#define StringValue(value) rb_string_value(&(value))
#define SafeStringValue StringValue
VALUE rb_string_value(VALUE *value_pointer);
VALUE rb_str_buf_new(long capacity);
VALUE rb_sprintf(const char *format, ...);
VALUE rb_vsprintf(const char *format, va_list args);

// Symbol

@@ -242,12 +264,18 @@ VALUE rb_proc_new(void *function, VALUE value);

// Utilities

void rb_warn(const char *fmt, ...);
void rb_warning(const char *fmt, ...);

int rb_scan_args(int argc, VALUE *argv, const char *format, ...);

// Calls

int rb_respond_to(VALUE object, ID name);

#define rb_funcall(object, name, ...) truffle_invoke(RUBY_CEXT, "rb_funcall", object, name, __VA_ARGS__)

int rb_block_given_p();
VALUE rb_yield(VALUE value);

// Instance variables
@@ -268,10 +296,18 @@ VALUE rb_const_set(VALUE module, ID name, VALUE value);
VALUE rb_define_const(VALUE module, const char *name, VALUE value);
void rb_define_global_const(const char *name, VALUE value);

// Raising exceptions
// Exceptions

VALUE rb_exc_new3(VALUE exception_class, VALUE message);

NORETURN(void rb_exc_raise(VALUE exception));
NORETURN(void rb_raise(VALUE exception, const char *format, ...));

VALUE rb_protect(VALUE (*function)(VALUE), VALUE data, int *status);
void rb_jump_tag(int status);

void rb_set_errinfo(VALUE error);

// Defining classes, modules and methods

VALUE rb_define_class(const char *name, VALUE superclass);
@@ -337,9 +373,21 @@ VALUE rb_complex_set_imag(VALUE complex, VALUE imag);
// GC

void rb_gc_register_address(VALUE *address);
#define rb_global_variable(address) ;
VALUE rb_gc_enable();
VALUE rb_gc_disable();

// Threads

typedef void *rb_nativethread_id_t;
typedef void *rb_nativethread_lock_t;

rb_nativethread_id_t rb_nativethread_self();
int rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock);
int rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock);
int rb_nativethread_lock_lock(rb_nativethread_lock_t *lock);
int rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock);

#if defined(__cplusplus)
}
#endif
1 change: 1 addition & 0 deletions lib/ruby/truffle/cext/ruby/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "../ruby.h"
1 change: 1 addition & 0 deletions lib/ruby/truffle/cext/ruby/io.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "../ruby.h"
1 change: 1 addition & 0 deletions lib/ruby/truffle/cext/ruby/thread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "../ruby.h"
1 change: 1 addition & 0 deletions lib/ruby/truffle/cext/ruby/thread_native.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "../ruby.h"
147 changes: 144 additions & 3 deletions truffle/src/main/c/cext/ruby.c
Original file line number Diff line number Diff line change
@@ -12,12 +12,34 @@
* as described in the file BSDL included with JRuby+Truffle.
*/

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>

#include <truffle.h>

#include <ruby.h>

#define RUBY_CEXT truffle_import_cached("ruby_cext")

// Types

int rb_type(VALUE value) {
return truffle_invoke_i(RUBY_CEXT, "rb_type", value);
}

bool RB_TYPE_P(VALUE value, int type) {
return truffle_invoke_i(RUBY_CEXT, "RB_TYPE_P", value, type);
}

void rb_check_type(VALUE value, int type) {
truffle_invoke(RUBY_CEXT, "rb_check_type", value);
}

VALUE rb_obj_is_kind_of(VALUE object, VALUE ruby_class) {
return truffle_invoke(object, "kind_of?", ruby_class);
}

// Constants

VALUE get_Qfalse() {
@@ -57,6 +79,14 @@ VALUE get_rb_eRuntimeError() {
return (VALUE) truffle_read(RUBY_CEXT, "rb_eRuntimeError");
}

VALUE get_rb_eStandardError(void) {
return (VALUE) truffle_read(RUBY_CEXT, "rb_eStandardError");
}

VALUE get_rb_eNoMemError(void) {
return (VALUE) truffle_read(RUBY_CEXT, "rb_eNoMemError");
}

// Conversions

VALUE CHR2FIX(char ch) {
@@ -157,7 +187,7 @@ char *RSTRING_PTR(VALUE string) {
return truffle_invoke(RUBY_CEXT, "CExtString", string);
}

int RSTRING_LEN(VALUE string) {
int rb_str_len(VALUE string) {
return truffle_invoke_i(string, "bytesize");
}

@@ -181,14 +211,48 @@ VALUE rb_intern_str(VALUE string) {
return (VALUE) truffle_invoke(RUBY_CEXT, "rb_intern_str", string);
}

void rb_str_cat(VALUE string, const char *to_concat, long length) {
VALUE rb_str_cat(VALUE string, const char *to_concat, long length) {
truffle_invoke(RUBY_CEXT, "rb_str_cat", string, rb_str_new_cstr(to_concat), length);
return string;
}

VALUE rb_str_cat2(VALUE string, const char *to_concat) {
truffle_invoke(string, "concat", rb_str_new_cstr(to_concat));
return string;
}

VALUE rb_str_to_str(VALUE string) {
return (VALUE) truffle_invoke(string, "to_str");
}

VALUE rb_string_value(VALUE *value_pointer) {
VALUE value = *value_pointer;

if (!RB_TYPE_P(value, T_STRING)) {
value = rb_str_to_str(value);
*value_pointer = value;
}

return value;
}

VALUE rb_str_buf_new(long capacity) {
return rb_str_new_cstr("");
}

VALUE rb_sprintf(const char *format, ...) {
va_list args;
va_start(args, format);
VALUE *string = rb_vsprintf(format, args);
va_end(args);
return string;
}

VALUE rb_vsprintf(const char *format, va_list args) {
fprintf(stderr, "rb_vsprintf not implemented\n");
abort();
}

// Symbol

ID rb_intern(const char *string) {
@@ -292,12 +356,34 @@ VALUE rb_proc_new(void *function, VALUE value) {

// Utilities

void rb_warn(const char *format, ...) {
if (!truffle_invoke_b(truffle_invoke(RUBY_CEXT, "verbose"), "nil?")) {
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
}
}

void rb_warning(const char *format, ...) {
if (truffle_invoke(RUBY_CEXT, "verbose") == Qtrue) {
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
}
}

int rb_scan_args(int argc, VALUE *argv, const char *format, ...) {
return truffle_invoke_i(RUBY_CEXT, "rb_scan_args", argc, argv, format /*, where to get args? */);
}

// Calls

int rb_respond_to(VALUE object, ID name) {
return truffle_invoke_b(object, "respond_to?", name);
}

VALUE rb_yield(VALUE value) {
return truffle_invoke(RUBY_CEXT, "rb_yield", value);
}
@@ -349,9 +435,38 @@ void rb_define_global_const(const char *name, VALUE value) {

// Raising exceptions

VALUE rb_exc_new3(VALUE exception_class, VALUE message) {
return truffle_invoke(exception_class, "new", message);
}

void rb_exc_raise(VALUE exception) {
truffle_invoke(RUBY_CEXT, "rb_exc_raise", exception);
abort();
}

void rb_raise(VALUE exception, const char *format, ...) {
fprintf(stderr, "rb_raise not implemented\n");
truffle_invoke(RUBY_CEXT, "rb_raise", format /*, where to get args? */);
exit(1); // To make the compiler happy
abort();
}

VALUE rb_protect(VALUE (*function)(VALUE), VALUE data, int *status) {
// TODO CS 23-Jul-16
return function(data);
}

void rb_jump_tag(int status) {
if (status) {
// TODO CS 23-Jul-16
fprintf(stderr, "rb_jump_tag not implemented\n");
abort();
}
}

void rb_set_errinfo(VALUE error) {
// TODO CS 23-Jul-16
fprintf(stderr, "rb_set_errinfo not implemented\n");
abort();
}

// Defining classes, modules and methods
@@ -514,3 +629,29 @@ VALUE rb_gc_enable() {
VALUE rb_gc_disable() {
return truffle_invoke(RUBY_CEXT, "rb_gc_disable");
}

// Threads

rb_nativethread_id_t rb_nativethread_self() {
return truffle_invoke(RUBY_CEXT, "rb_nativethread_self");
}

int rb_nativethread_lock_initialize(rb_nativethread_lock_t *lock) {
*lock = truffle_invoke(RUBY_CEXT, "rb_nativethread_lock_initialize");
return 0;
}

int rb_nativethread_lock_destroy(rb_nativethread_lock_t *lock) {
*lock = NULL;
return 0;
}

int rb_nativethread_lock_lock(rb_nativethread_lock_t *lock) {
truffle_invoke(lock, "lock");
return 0;
}

int rb_nativethread_lock_unlock(rb_nativethread_lock_t *lock) {
truffle_invoke(lock, "unlock");
return 0;
}
4 changes: 2 additions & 2 deletions truffle/src/main/c/openssl/ossl.c
Original file line number Diff line number Diff line change
@@ -77,7 +77,7 @@ STACK_OF(type) * \
ossl_protect_##name##_ary2sk(VALUE ary, int *status) \
{ \
return (STACK_OF(type)*)rb_protect( \
(VALUE(*)_((VALUE)))ossl_##name##_ary2sk0, \
(VALUE(*)((VALUE)))ossl_##name##_ary2sk0, \
ary, \
status); \
} \
@@ -136,7 +136,7 @@ ossl_buf2str(char *buf, int len)
VALUE str;
int status = 0;

str = rb_protect((VALUE(*)_((VALUE)))ossl_str_new, len, &status);
str = rb_protect((VALUE(*)((VALUE)))ossl_str_new, len, &status);
if(!NIL_P(str)) memcpy(RSTRING_PTR(str), buf, len);
OPENSSL_free(buf);
if(status) rb_jump_tag(status);
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@

import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.CreateCast;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
@@ -19,13 +20,16 @@
import com.oracle.truffle.api.frame.FrameInstance;
import com.oracle.truffle.api.frame.FrameInstance.FrameAccess;
import com.oracle.truffle.api.frame.FrameInstanceVisitor;
import com.oracle.truffle.api.frame.MaterializedFrame;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.jruby.truffle.builtins.CoreClass;
import org.jruby.truffle.builtins.CoreMethod;
import org.jruby.truffle.builtins.CoreMethodArrayArgumentsNode;
import org.jruby.truffle.builtins.CoreMethodNode;
import org.jruby.truffle.core.cast.NameToJavaStringNodeGen;
import org.jruby.truffle.language.NotProvided;
import org.jruby.truffle.language.RubyConstant;
import org.jruby.truffle.language.RubyNode;
import org.jruby.truffle.language.arguments.RubyArguments;
@@ -189,6 +193,23 @@ public DynamicObject toRubyString(DynamicObject string) {

}

@CoreMethod(names = "rb_block_given_p", isModuleFunction = true, needsCallerFrame = true)
public abstract static class BlockGivenNode extends CoreMethodArrayArgumentsNode {

@Specialization
public boolean blockGiven(MaterializedFrame callerFrame,
@Cached("createBinaryProfile()") ConditionProfile blockProfile) {
return blockProfile.profile(RubyArguments.getBlock(callerFrame) != null);
}

@TruffleBoundary
@Specialization
public boolean blockGiven(NotProvided noCallerFrame) {
return RubyArguments.getBlock(Truffle.getRuntime().getCallerFrame().getFrame(FrameInstance.FrameAccess.READ_ONLY, false)) != null;
}

}

@CoreMethod(names = "get_block", isModuleFunction = true)
public abstract static class GetBlockNode extends CoreMethodArrayArgumentsNode {

125 changes: 124 additions & 1 deletion truffle/src/main/ruby/core/truffle/cext.rb
Original file line number Diff line number Diff line change
@@ -7,12 +7,110 @@
# GNU Lesser General Public License version 2.1

module Truffle::CExt

T_NONE = 0x00

T_OBJECT = 0x01
T_CLASS = 0x02
T_MODULE = 0x03
T_FLOAT = 0x04
T_STRING = 0x05
T_REGEXP = 0x06
T_ARRAY = 0x07
T_HASH = 0x08
T_STRUCT = 0x09
T_BIGNUM = 0x0a
T_FILE = 0x0b
T_DATA = 0x0c
T_MATCH = 0x0d
T_COMPLEX = 0x0e
T_RATIONAL = 0x0f

T_NIL = 0x11
T_TRUE = 0x12
T_FALSE = 0x13
T_SYMBOL = 0x14
T_FIXNUM = 0x15
T_UNDEF = 0x16

T_IMEMO = 0x1a
T_NODE = 0x1b
T_ICLASS = 0x1c
T_ZOMBIE = 0x1d

T_MASK = 0x1f

module_function

def supported?
Interop.mime_type_supported?('application/x-sulong-library')
end

def rb_type(value)
# TODO CS 23-Jul-16 we could do with making this a kind of specialising case
# that puts never seen cases behind a transfer

case value
when Module
T_MODULE
when Class
T_CLASS
when Float
T_FLOAT
when String
T_STRING
when Regexp
T_REGEXP
when Array
T_ARRAY
when Hash
T_HASH
when Struct
T_STRUCT
when Bignum
T_BIGNUM
when File
T_FILE
when Complex
T_COMPLEX
when Rational
T_RATIONAL

when NilClass
T_NIL
when TrueClass
T_TRUE
when FalseClass
T_FALSE
when Symbol
T_SYMBOL
when Fixnum
T_FIXNUM

when Object
T_OBJECT

else
raise 'unknown type'
end
end

def RB_TYPE_P(value, type)
case type
when T_STRING
value.is_a?(String)
else
raise 'unknown type'
end
end

def rb_check_type(value, type)
# TODO CS 23-Jul-16 there's more to this method than this...
if rb_type(value) != type
raise 'unexpected type'
end
end

def Qfalse
false
end
@@ -46,7 +144,15 @@ def rb_mKernel
end

def rb_eRuntimeError
raise 'not implemented'
RuntimeError
end

def rb_eStandardError
StandardError
end

def rb_eNoMemError
NoMemError
end

def rb_fix2int(value)
@@ -143,6 +249,10 @@ def rb_proc_new(function, value)
}
end

def verbose
$VERBOSE
end

def rb_scan_args
raise 'not implemented'
end
@@ -152,6 +262,10 @@ def rb_yield(value)
block.call(value)
end

def rb_exc_raise(exception)
raise exception
end

def rb_raise(object, name)
raise 'not implemented'
end
@@ -304,6 +418,15 @@ def rb_gc_enable
def rb_gc_disable
GC.disable
end

def rb_nativethread_self
Thread.current
end

def rb_nativethread_lock_initialize
Mutex.new
end

end

Truffle::Interop.export(:ruby_cext, Truffle::CExt)

0 comments on commit 7e18032

Please sign in to comment.