index e0a9bf6..fb89e5a 100644
--- a/vm/builtin/nativemethod.cpp
+++ b/vm/builtin/nativemethod.cpp
@@ -14,6 +14,8 @@
#include "builtin/string.hpp"
#include "builtin/tuple.hpp"

+#include "capi/capi.hpp"
+
namespace rubinius {

typedef TypedRoot<Object*> RootHandle;
@@ -58,6 +60,8 @@ namespace rubinius {
return Qnil;
case cCApiHandleQundef:
return Qundef;
+ case cCApiSignatureHandle:
+ return Qnil;
default:
// @todo: throw if this handle pulls 0 out
return global_handles_[cGlobalHandleStart - handle - cHandleOffset]->get();
@@ -89,7 +93,9 @@ namespace rubinius {
}

void NativeMethod::init_thread(STATE) {
- native_method_environment.set(new NativeMethodEnvironment);
+ NativeMethodEnvironment* env = new NativeMethodEnvironment;
+ env->set_state(state);
+ native_method_environment.set(env);
}

NativeMethod* NativeMethod::allocate(STATE) {
@@ -126,6 +132,8 @@ namespace rubinius {
NativeMethod* NativeMethod::load_extension_entry_point(STATE, String* path, String* name) {
void* func = NativeLibrary::find_symbol(state, name, path);

+ capi::set_global_constants(state);
+
NativeMethod* m = NativeMethod::create(state,
path,
state->globals.rubinius.get(),
diff --git a/vm/builtin/nativemethod.hpp b/vm/builtin/nativemethod.hpp
index aea57b8..c394c1e 100644
--- a/vm/builtin/nativemethod.hpp
+++ b/vm/builtin/nativemethod.hpp
@@ -49,13 +49,14 @@ namespace rubinius {
#define cCApiHandleQtrue (-1)
#define cCApiHandleQnil (-2)
#define cCApiHandleQundef (-3)
+#define cCApiSignatureHandle (-4)

/**
* Constants for navigating around the fixed values
* of the immediates like Qfalse above.
*/
-#define cHandleOffset ( 1)
-#define cGlobalHandleStart (-4)
+#define cHandleOffset ( 1)
+#define cGlobalHandleStart (-5)

public: /* Interface methods */

diff --git a/vm/capi/capi.cpp b/vm/capi/capi.cpp
index 3bd81da..48ae543 100644
--- a/vm/capi/capi.cpp
+++ b/vm/capi/capi.cpp
@@ -11,6 +11,7 @@
#include "exception_point.hpp"
#include "global_cache.hpp"
#include "message.hpp"
+#include "vm.hpp"

#include "capi/capi.hpp"
#include "capi/ruby.h"
@@ -22,75 +23,71 @@
namespace rubinius {
namespace capi {

- typedef std::vector<std::string> CApiConstantNameMap;
- typedef std::tr1::unordered_map<int, Handle> CApiConstantHandleMap;
-
- std::string& capi_get_constant_name(CApiConstant type) {
- static CApiConstantNameMap map;
-
- if(map.empty()) {
- map.resize(cCApiMaxConstant + 1);
-
- map[cCApiArray] = "Array";
- map[cCApiBignum] = "Bignum";
- map[cCApiClass] = "Class";
- map[cCApiComparable] = "Comparable";
- map[cCApiData] = "Data";
- map[cCApiEnumerable] = "Enumerable";
- map[cCApiFalse] = "FalseClass";
- map[cCApiFixnum] = "Fixnum";
- map[cCApiFloat] = "Float";
- map[cCApiHash] = "Hash";
- map[cCApiInteger] = "Integer";
- map[cCApiIO] = "IO";
- map[cCApiKernel] = "Kernel";
- map[cCApiModule] = "Module";
- map[cCApiNil] = "NilClass";
- map[cCApiObject] = "Object";
- map[cCApiRegexp] = "Regexp";
- map[cCApiString] = "String";
- map[cCApiSymbol] = "Symbol";
- map[cCApiThread] = "Thread";
- map[cCApiTrue] = "TrueClass";
-
- map[cCApiArgumentError] = "ArgumentError";
- map[cCApiEOFError] = "EOFError";
- map[cCApiErrno] = "Errno";
- map[cCApiException] = "Exception";
- map[cCApiFatal] = "Fatal";
- map[cCApiFloatDomainError] = "FloatDomainError";
- map[cCApiIndexError] = "IndexError";
- map[cCApiInterrupt] = "Interrupt";
- map[cCApiIOError] = "IOError";
- map[cCApiLoadError] = "LoadError";
- map[cCApiLocalJumpError] = "LocalJumpError";
- map[cCApiNameError] = "NameError";
- map[cCApiNoMemoryError] = "NoMemoryError";
- map[cCApiNoMethodError] = "NoMethodError";
- map[cCApiNotImplementedError] = "NotImplementedError";
- map[cCApiRangeError] = "RangeError";
- map[cCApiRegexpError] = "RegexpError";
- map[cCApiRuntimeError] = "RuntimeError";
- map[cCApiScriptError] = "ScriptError";
- map[cCApiSecurityError] = "SecurityError";
- map[cCApiSignalException] = "SignalException";
- map[cCApiStandardError] = "StandardError";
- map[cCApiSyntaxError] = "SyntaxError";
- map[cCApiSystemCallError] = "SystemCallError";
- map[cCApiSystemExit] = "SystemExit";
- map[cCApiSystemStackError] = "SystemStackError";
- map[cCApiTypeError] = "TypeError";
- map[cCApiThreadError] = "ThreadError";
- map[cCApiZeroDivisionError] = "ZeroDivisionError";
- }
+ static VALUE get_global_constant(VM* state, std::string name) {
+ Class* object = state->globals.object.get();
+ Object* constant = object->get_const(state, name.c_str());

- if(type < 0 || type >= cCApiMaxConstant) {
- NativeMethodEnvironment* env = NativeMethodEnvironment::get();
- rb_raise(env->get_handle_global(env->state()->globals.exception.get()),
- "C-API: invalid constant index");
- }
+ NativeMethodEnvironment* env = NativeMethodEnvironment::get();
+ return env->get_handle_global(constant);
+ }

- return map[type];
+ void set_global_constants(VM* state) {
+ if(rb_RubiniusCApiSignature == cCApiSignatureHandle) return;
+
+ rb_cArray = get_global_constant(state, "Array");
+ rb_cBignum = get_global_constant(state, "Bignum");
+ rb_cClass = get_global_constant(state, "Class");
+ rb_cData = get_global_constant(state, "Data");
+ rb_cFalseClass = get_global_constant(state, "FalseClass");
+ rb_cFixnum = get_global_constant(state, "Fixnum");
+ rb_cFloat = get_global_constant(state, "Float");
+ rb_cHash = get_global_constant(state, "Hash");
+ rb_cInteger = get_global_constant(state, "Integer");
+ rb_cIO = get_global_constant(state, "IO");
+ rb_cModule = get_global_constant(state, "Module");
+ rb_cNilClass = get_global_constant(state, "NilClass");
+ rb_cObject = get_global_constant(state, "Object");
+ rb_cRegexp = get_global_constant(state, "Regexp");
+ rb_cString = get_global_constant(state, "String");
+ rb_cSymbol = get_global_constant(state, "Symbol");
+ rb_cThread = get_global_constant(state, "Thread");
+ rb_cTrueClass = get_global_constant(state, "TrueClass");
+
+ rb_mComparable = get_global_constant(state, "Comparable");
+ rb_mEnumerable = get_global_constant(state, "Enumerable");
+ rb_mKernel = get_global_constant(state, "Kernel");
+
+ rb_eArgError = get_global_constant(state, "ArgError");
+ rb_eEOFError = get_global_constant(state, "EOFError");
+ rb_mErrno = get_global_constant(state, "Errno");
+ rb_eException = get_global_constant(state, "Exception");
+ rb_eFatal = get_global_constant(state, "Fatal");
+ rb_eFloatDomainError = get_global_constant(state, "FloatDomainError");
+ rb_eIndexError = get_global_constant(state, "IndexError");
+ rb_eInterrupt = get_global_constant(state, "Interrupt");
+ rb_eIOError = get_global_constant(state, "IOError");
+ rb_eLoadError = get_global_constant(state, "LoadError");
+ rb_eLocalJumpError = get_global_constant(state, "LocalJumpError");
+ rb_eNameError = get_global_constant(state, "NameError");
+ rb_eNoMemError = get_global_constant(state, "NoMemError");
+ rb_eNoMethodError = get_global_constant(state, "NoMethodError");
+ rb_eNotImpError = get_global_constant(state, "NotImpError");
+ rb_eRangeError = get_global_constant(state, "RangeError");
+ rb_eRegexpError = get_global_constant(state, "RegexpError");
+ rb_eRuntimeError = get_global_constant(state, "RuntimeError");
+ rb_eScriptError = get_global_constant(state, "ScriptError");
+ rb_eSecurityError = get_global_constant(state, "SecurityError");
+ rb_eSignal = get_global_constant(state, "Signal");
+ rb_eStandardError = get_global_constant(state, "StandardError");
+ rb_eSyntaxError = get_global_constant(state, "SyntaxError");
+ rb_eSystemCallError = get_global_constant(state, "SystemCallError");
+ rb_eSystemExit = get_global_constant(state, "SystemExit");
+ rb_eSysStackError = get_global_constant(state, "SysStackError");
+ rb_eTypeError = get_global_constant(state, "TypeError");
+ rb_eThreadError = get_global_constant(state, "ThreadError");
+ rb_eZeroDivError = get_global_constant(state, "ZeroDivError");
+
+ rb_RubiniusCApiSignature = cCApiSignatureHandle;
}

/**
@@ -156,22 +153,60 @@ using namespace rubinius::capi;

extern "C" {

- VALUE capi_get_constant(CApiConstant type) {
- static CApiConstantHandleMap map;
-
- CApiConstantHandleMap::iterator entry = map.find(type);
- if(entry == map.end()) {
- NativeMethodEnvironment* env = NativeMethodEnvironment::get();
- Object* obj = env->state()->globals.object.get()->get_const(env->state(),
- capi_get_constant_name(type).c_str());
-
- Handle handle = env->get_handle_global(obj);
- map[type] = handle;
- return handle;
- } else {
- return entry->second;
- }
- }
+ VALUE rb_cArray;
+ VALUE rb_cBignum;
+ VALUE rb_cClass;
+ VALUE rb_cData;
+ VALUE rb_cFalseClass;
+ VALUE rb_cFixnum;
+ VALUE rb_cFloat;
+ VALUE rb_cHash;
+ VALUE rb_cInteger;
+ VALUE rb_cIO;
+ VALUE rb_cModule;
+ VALUE rb_cNilClass;
+ VALUE rb_cObject;
+ VALUE rb_cRegexp;
+ VALUE rb_cString;
+ VALUE rb_cSymbol;
+ VALUE rb_cThread;
+ VALUE rb_cTrueClass;
+
+ VALUE rb_mComparable;
+ VALUE rb_mEnumerable;
+ VALUE rb_mKernel;
+
+ VALUE rb_eArgError;
+ VALUE rb_eEOFError;
+ VALUE rb_mErrno;
+ VALUE rb_eException;
+ VALUE rb_eFatal;
+ VALUE rb_eFloatDomainError;
+ VALUE rb_eIndexError;
+ VALUE rb_eInterrupt;
+ VALUE rb_eIOError;
+ VALUE rb_eLoadError;
+ VALUE rb_eLocalJumpError;
+ VALUE rb_eNameError;
+ VALUE rb_eNoMemError;
+ VALUE rb_eNoMethodError;
+ VALUE rb_eNotImpError;
+ VALUE rb_eRangeError;
+ VALUE rb_eRegexpError;
+ VALUE rb_eRuntimeError;
+ VALUE rb_eScriptError;
+ VALUE rb_eSecurityError;
+ VALUE rb_eSignal;
+ VALUE rb_eStandardError;
+ VALUE rb_eSyntaxError;
+ VALUE rb_eSystemCallError;
+ VALUE rb_eSystemExit;
+ VALUE rb_eSysStackError;
+ VALUE rb_eTypeError;
+ VALUE rb_eThreadError;
+ VALUE rb_eZeroDivError;
+
+ VALUE rb_RubiniusCApiSignature;

VALUE capi_rb_funcall(const char* file, int line,
VALUE receiver, ID method_name, int arg_count, ...) {
diff --git a/vm/capi/capi.hpp b/vm/capi/capi.hpp
index 425759d..376cd38 100644
--- a/vm/capi/capi.hpp
+++ b/vm/capi/capi.hpp
@@ -16,6 +16,7 @@ namespace rubinius {
class Integer;
class Object;
class Symbol;
+ class VM;

namespace capi {

@@ -26,6 +27,8 @@ namespace rubinius {
#define VALUE intptr_t
#define ID intptr_t

+ void set_global_constants(VM* state);
+
Symbol* prefixed_by(std::string prefix, std::string name);
Symbol* prefixed_by(std::string prefix, ID name);

diff --git a/vm/capi/ruby.h b/vm/capi/ruby.h
index b8e12c2..a407687 100644
--- a/vm/capi/ruby.h
+++ b/vm/capi/ruby.h
@@ -148,69 +148,6 @@ extern "C" {
#endif

/**
- * Global object abstraction.
- *
- * @internal.
- */
- typedef enum {
- cCApiArray = 0,
- cCApiBignum,
- cCApiClass,
- cCApiComparable,
- cCApiData,
- cCApiEnumerable,
- cCApiFalse,
- cCApiFixnum,
- cCApiFloat,
- cCApiHash,
- cCApiInteger,
- cCApiIO,
- cCApiKernel,
- cCApiModule,
- cCApiNil,
- cCApiObject,
- cCApiRegexp,
- cCApiString,
- cCApiSymbol,
- cCApiThread,
- cCApiTrue,
-
- cCApiArgumentError,
- cCApiEOFError,
- cCApiErrno,
- cCApiException,
- cCApiFatal,
- cCApiFloatDomainError,
- cCApiIndexError,
- cCApiInterrupt,
- cCApiIOError,
- cCApiLoadError,
- cCApiLocalJumpError,
- cCApiNameError,
- cCApiNoMemoryError,
- cCApiNoMethodError,
- cCApiNotImplementedError,
- cCApiRangeError,
- cCApiRegexpError,
- cCApiRuntimeError,
- cCApiScriptError,
- cCApiSecurityError,
- cCApiSignalException,
- cCApiStandardError,
- cCApiSyntaxError,
- cCApiSystemCallError,
- cCApiSystemExit,
- cCApiSystemStackError,
- cCApiTypeError,
- cCApiThreadError,
- cCApiZeroDivisionError,
-
- // MUST be last
- cCApiMaxConstant
- } CApiConstant;
-
-
- /**
* Integral type map for MRI's types.
*
* Rubinius does not implement all of these,
@@ -289,65 +226,67 @@ extern "C" {

/* Global Class objects */

-#define rb_cArray (capi_get_constant(cCApiArray))
-#define rb_cBignum (capi_get_constant(cCApiBignum))
-#define rb_cClass (capi_get_constant(cCApiClass))
-#define rb_cData (capi_get_constant(cCApiData))
-#define rb_cFalseClass (capi_get_constant(cCApiFalse))
-#define rb_cFixnum (capi_get_constant(cCApiFixnum))
-#define rb_cFloat (capi_get_constant(cCApiFloat))
-#define rb_cHash (capi_get_constant(cCApiHash))
-#define rb_cInteger (capi_get_constant(cCApiInteger))
-#define rb_cIO (capi_get_constant(cCApiIO))
-#define rb_cModule (capi_get_constant(cCApiModule))
-#define rb_cNilClass (capi_get_constant(cCApiNil))
-#define rb_cObject (capi_get_constant(cCApiObject))
-#define rb_cRegexp (capi_get_constant(cCApiRegexp))
-#define rb_cString (capi_get_constant(cCApiString))
-#define rb_cSymbol (capi_get_constant(cCApiSymbol))
-#define rb_cThread (capi_get_constant(cCApiThread))
-#define rb_cTrueClass (capi_get_constant(cCApiTrue))
+extern VALUE rb_cArray;
+extern VALUE rb_cBignum;
+extern VALUE rb_cClass;
+extern VALUE rb_cData;
+extern VALUE rb_cFalseClass;
+extern VALUE rb_cFixnum;
+extern VALUE rb_cFloat;
+extern VALUE rb_cHash;
+extern VALUE rb_cInteger;
+extern VALUE rb_cIO;
+extern VALUE rb_cModule;
+extern VALUE rb_cNilClass;
+extern VALUE rb_cObject;
+extern VALUE rb_cRegexp;
+extern VALUE rb_cString;
+extern VALUE rb_cSymbol;
+extern VALUE rb_cThread;
+extern VALUE rb_cTrueClass;


/* Global Module objects. */

-#define rb_mComparable (capi_get_constant(cCApiComparable))
-#define rb_mEnumerable (capi_get_constant(cCApiEnumerable))
-#define rb_mKernel (capi_get_constant(cCApiKernel))
+extern VALUE rb_mComparable;
+extern VALUE rb_mEnumerable;
+extern VALUE rb_mKernel;


/* Exception classes. */

-#define rb_eArgError (capi_get_constant(cCApiArgumentError))
-#define rb_eEOFError (capi_get_constant(cCApiEOFError))
-#define rb_mErrno (capi_get_constant(cCApiErrno))
-#define rb_eException (capi_get_constant(cCApiException))
-#define rb_eFatal (capi_get_constant(cCApiFatal))
-#define rb_eFloatDomainError (capi_get_constant(cCApiFloatDomainError))
-#define rb_eIndexError (capi_get_constant(cCApiIndexError))
-#define rb_eInterrupt (capi_get_constant(cCApiInterrupt))
-#define rb_eIOError (capi_get_constant(cCApiIOError))
-#define rb_eLoadError (capi_get_constant(cCApiLoadError))
-#define rb_eLocalJumpError (capi_get_constant(cCApiLocalJumpError))
-#define rb_eNameError (capi_get_constant(cCApiNameError))
-#define rb_eNoMemError (capi_get_constant(cCApiNoMemoryError))
-#define rb_eNoMethodError (capi_get_constant(cCApiNoMethodError))
-#define rb_eNotImpError (capi_get_constant(cCApiNotImplementedError))
-#define rb_eRangeError (capi_get_constant(cCApiRangeError))
-#define rb_eRegexpError (capi_get_constant(cCApiRegexpError))
-#define rb_eRuntimeError (capi_get_constant(cCApiRuntimeError))
-#define rb_eScriptError (capi_get_constant(cCApiScriptError))
-#define rb_eSecurityError (capi_get_constant(cCApiSecurityError))
-#define rb_eSignal (capi_get_constant(cCApiSignalException))
-#define rb_eStandardError (capi_get_constant(cCApiStandardError))
-#define rb_eSyntaxError (capi_get_constant(cCApiSyntaxError))
-#define rb_eSystemCallError (capi_get_constant(cCApiSystemCallError))
-#define rb_eSystemExit (capi_get_constant(cCApiSystemExit))
-#define rb_eSysStackError (capi_get_constant(cCApiSystemStackError))
-#define rb_eTypeError (capi_get_constant(cCApiTypeError))
-#define rb_eThreadError (capi_get_constant(cCApiThreadError))
-#define rb_eZeroDivError (capi_get_constant(cCApiZeroDivisionError))
-
+extern VALUE rb_eArgError;
+extern VALUE rb_eEOFError;
+extern VALUE rb_mErrno;
+extern VALUE rb_eException;
+extern VALUE rb_eFatal;
+extern VALUE rb_eFloatDomainError;
+extern VALUE rb_eIndexError;
+extern VALUE rb_eInterrupt;
+extern VALUE rb_eIOError;
+extern VALUE rb_eLoadError;
+extern VALUE rb_eLocalJumpError;
+extern VALUE rb_eNameError;
+extern VALUE rb_eNoMemError;
+extern VALUE rb_eNoMethodError;
+extern VALUE rb_eNotImpError;
+extern VALUE rb_eRangeError;
+extern VALUE rb_eRegexpError;
+extern VALUE rb_eRuntimeError;
+extern VALUE rb_eScriptError;
+extern VALUE rb_eSecurityError;
+extern VALUE rb_eSignal;
+extern VALUE rb_eStandardError;
+extern VALUE rb_eSyntaxError;
+extern VALUE rb_eSystemCallError;
+extern VALUE rb_eSystemExit;
+extern VALUE rb_eSysStackError;
+extern VALUE rb_eTypeError;
+extern VALUE rb_eThreadError;
+extern VALUE rb_eZeroDivError;
+
+/* Sentinel value for initializing global references. */
+extern VALUE rb_RubiniusCApiSignature;

/* Interface macros */

@@ -461,9 +400,6 @@ extern "C" {
VALUE receiver, ID method_name,
int arg_count, VALUE* args);

- /** Retrieve a Handle to a globally available object. @internal. */
- VALUE capi_get_constant(CApiConstant type);
-
/** Symbol Handle for an ID. @internal. */
VALUE capi_id2sym(ID id);

gauss:rubinius brian$