Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
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$
This paste will be private.
From the Design Piracy series on my blog: