diff --git a/rakelib/configure.rake b/rakelib/configure.rake
index db56213..9168e6b 100644
--- a/rakelib/configure.rake
+++ b/rakelib/configure.rake
@@ -279,7 +279,11 @@ def write_rbconfig
f.puts ' CONFIG["LIBRUBYARG_SHARED"] = "-l$(RUBY_SO_NAME)"'
f.puts ' CONFIG["configure_args"] = ""'
f.puts ' CONFIG["ALLOCA"] = ""'
+ if HOST =~ /darwin/ then
f.puts ' CONFIG["DLEXT"] = "bundle"'
+ else
+ f.puts ' CONFIG["DLEXT"] = "so"'
+ end
f.puts ' CONFIG["LIBEXT"] = "a"'
f.puts ' CONFIG["LINK_SO"] = ""'
f.puts ' CONFIG["LIBPATHFLAG"] = " -L%s"'
@@ -296,8 +300,13 @@ def write_rbconfig
f.puts ' CONFIG["PACKAGE_BUGREPORT"] = ""'
# HACK: we need something equivalent, but I'm cheating for now - zenspider
- f.puts ' CONFIG["LDSHARED"] = "cc -dynamic -bundle -undefined suppress -flat_namespace"'
- f.puts ' CONFIG["LIBRUBY_LDSHARED"] = "cc -dynamic -bundle -undefined suppress -flat_namespace"'
+ if HOST =~ /darwin/ then
+ f.puts ' CONFIG["LDSHARED"] = "cc -dynamic -bundle -undefined suppress -flat_namespace"'
+ f.puts ' CONFIG["LIBRUBY_LDSHARED"] = "cc -dynamic -bundle -undefined suppress -flat_namespace"'
+ else
+ f.puts ' CONFIG["LDSHARED"] = "cc -dynamic -shared"'
+ f.puts ' CONFIG["LIBRUBY_LDSHARED"] = "cc -dynamic -shared"'
+ end
f.puts
f.puts <<-EOC
# Adapted from MRI's' rbconfig.rb
diff --git a/rakelib/spec.rake b/rakelib/spec.rake
index 4fdfed1..07b9928 100644
--- a/rakelib/spec.rake
+++ b/rakelib/spec.rake
@@ -119,7 +119,7 @@ namespace :spec do
desc "Run subtend (Rubinius C API) examples"
task :subtend => "spec:setup:subtend" do
- sh "bin/mspec spec/rubinius/subtend"
+ sh "bin/mspec spec/subtend"
end
# Specdiffs to make it easier to see what your changes have affected :)
diff --git a/shotgun/lib/subtend/ruby.c b/shotgun/lib/subtend/ruby.c
index 0b0917c..a407fc1 100644
--- a/shotgun/lib/subtend/ruby.c
+++ b/shotgun/lib/subtend/ruby.c
@@ -142,6 +142,16 @@ VALUE subtend_get_global(int which) {
return NEW_HANDLE(ctx, val);
}
+void subtend_set_tainted(VALUE val) {
+ CTX;
+ object_set_tainted(ctx->state, HNDL(val));
+}
+
+int subtend_check_tainted(VALUE val) {
+ CTX;
+ return object_tainted_p(ctx->state, HNDL(val));
+}
+
void rb_global_object(VALUE val) {
handle_make_global(AS_HNDL(val));
}
@@ -170,7 +180,7 @@ static VALUE _push_and_call(VALUE recv, ID meth, int args, VALUE *ary) {
volatile int swapped;
OBJECT tmp;
ctx = subtend_retrieve_context();
-
+
if(!ctx->nmc) {
printf("ERROR: tried to do rb_funcall, but there is no context!\n");
return 0;
@@ -212,11 +222,11 @@ VALUE rb_funcall(VALUE recv, ID meth, int args, ...) {
}
va_end(ar);
-
+
ret = _push_and_call(recv, meth, args, arg_array);
XFREE(arg_array);
return ret;
-
+
}
VALUE rb_funcall2(VALUE recv, ID meth, int args, VALUE* array) {
@@ -280,9 +290,9 @@ int rb_const_defined(VALUE klass, ID id) {
VALUE rb_ivar_get(VALUE obj, ID sym) {
CTX;
OBJECT val;
-
+
val = object_get_ivar(ctx->state, HNDL(obj), HNDL(sym));
-
+
return NEW_HANDLE(ctx, val);
}
@@ -311,6 +321,18 @@ VALUE rb_iv_set(VALUE obj, char *name, VALUE val) {
return rb_ivar_set(obj, rb_intern(name), val);
}
+VALUE rb_ivar_defined(VALUE obj, ID sym) {
+ CTX;
+
+ if(object_has_ivars(ctx->state, HNDL(obj))) {
+ if (object_get_ivar(ctx->state, HNDL(obj), HNDL(sym) != Qundef)) {
+ return Qtrue;
+ }
+ }
+
+ return Qfalse;
+}
+
void rb_define_method_(const char *file, VALUE vmod, const char *name, void *func, int args, int kind) {
OBJECT meth, sym, mod;
CTX;
@@ -348,8 +370,8 @@ void rb_define_global_function(const char *name, void *func, int args) {
const char *rb_id2name(ID sym) {
OBJECT obj;
CTX;
-
obj = (OBJECT)sym;
+
if(!RBX_SYMBOL_P(obj)) return NULL;
return rbs_symbol_to_cstring(ctx->state, obj);
}
@@ -469,6 +491,14 @@ VALUE rb_class_new_instance(int nargs, VALUE *args, VALUE klass) {
return obj;
}
+VALUE rb_singleton_class(VALUE obj) {
+ OBJECT val;
+ CTX;
+
+ val = object_metaclass(ctx->state, HNDL(obj));
+ return NEW_HANDLE(ctx, val);
+}
+
void rb_thread_schedule() {
rb_funcall2(rb_const_get(rb_cObject, rb_intern("Thread")), rb_intern("pass"), 0, NULL);
}
@@ -526,6 +556,24 @@ VALUE rb_ary_new2(long length) {
return NEW_HANDLE(ctx, ary);
}
+VALUE rb_ary_new3(long length, ...) {
+ OBJECT ary;
+ CTX;
+
+ va_list ar;
+ long i;
+
+ ary = array_new(ctx->state, length);
+
+ va_start(ar, length);
+ for(i = 0; i < length; i++) {
+ array_append(ctx->state, ary, HNDL(va_arg(ar, VALUE)));
+ }
+ va_end(ar);
+
+ return NEW_HANDLE(ctx, ary);
+}
+
VALUE rb_ary_push(VALUE array, VALUE val) {
CTX;
OBJECT ary = HNDL(array);
diff --git a/shotgun/lib/subtend/ruby.h b/shotgun/lib/subtend/ruby.h
index eb9eea6..5587a1e 100644
--- a/shotgun/lib/subtend/ruby.h
+++ b/shotgun/lib/subtend/ruby.h
@@ -28,6 +28,10 @@
#define Qnil ((VALUE)14L)
#define Qundef ((VALUE)18L)
+/* NOOP for OBJ_TAINT and OBJ_TAINTED */
+#define OBJ_TAINT(val) (subtend_set_tainted(val))
+#define OBJ_TAINTED(val) (subtend_check_tainted(val))
+
#undef RTEST
#undef NIL_P
#define RTEST(v) (((uintptr_t)(v) & 0x7) != 0x6)
@@ -45,10 +49,12 @@ int SYMBOL_P(VALUE obj);
extern VALUE rb_funcall(VALUE, ID, int cnt, ...);
extern VALUE rb_funcall2(VALUE, ID, int cnt, VALUE*);
-
extern VALUE subtend_get_global(int which);
extern VALUE subtend_get_exception(int which);
+void subtend_set_tainted(VALUE val);
+int subtend_check_tainted(VALUE val);
+
void rb_global_variable(VALUE* address);
void rb_define_method_(const char *file, VALUE vmod, const char *name, void *func, int args, int kind);
@@ -76,6 +82,8 @@ VALUE rb_ivar_get(VALUE obj, ID sym);
VALUE rb_iv_get(VALUE obj, char *name);
VALUE rb_ivar_set(VALUE obj, ID sym, VALUE val);
VALUE rb_iv_set(VALUE obj, char *name, VALUE val);
+VALUE rb_ivar_defined(VALUE obj, ID sym);
+
void rb_define_attr(VALUE klass, const char* id, int read, int write);
VALUE rb_attr_get(VALUE obj, ID sym);
@@ -168,6 +176,8 @@ VALUE rb_convert_type(VALUE val, int type, const char* tname, const char* method
VALUE rb_class_new_instance(int nargs, VALUE *args, VALUE klass);
+VALUE rb_singleton_class(VALUE obj);
+
void rb_thread_schedule();
#define CHECK_INTS
void rb_secure(int);
@@ -184,6 +194,7 @@ VALUE INT2NUM(int num);
VALUE rb_Array(VALUE val);
VALUE rb_ary_new(void);
VALUE rb_ary_new2(long length);
+VALUE rb_ary_new3(long length, ...);
int rb_ary_size(VALUE self);
VALUE rb_ary_push(VALUE array, VALUE val);
VALUE rb_ary_pop(VALUE array);