diff options
author | ttate <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-12-01 23:02:44 +0000 |
---|---|---|
committer | ttate <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-12-01 23:02:44 +0000 |
commit | a41f5816ddf971bc41ff46ec85b81d84c7d1250a (patch) | |
tree | 9ea77c24e315ede00856933d76f939fcbeec9f6b /ext/dl | |
parent | 6e4b8e19d77ee82f6759ef117c576df6d3d84320 (diff) |
Merged Tietew's patch of [ruby-dev:21991].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@5080 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/dl')
-rw-r--r-- | ext/dl/dl.h | 1 | ||||
-rw-r--r-- | ext/dl/sym.c | 91 |
2 files changed, 92 insertions, 0 deletions
diff --git a/ext/dl/dl.h b/ext/dl/dl.h index c390e18bbb..1faa316cf1 100644 --- a/ext/dl/dl.h +++ b/ext/dl/dl.h @@ -170,6 +170,7 @@ # endif #elif defined(USE_DLSTACK) # define DLSTACK +# define DLSTACK_GUARD # define DLSTACK_METHOD "dl" # define DLSTACK_PROTO long,long,long,long,long,\ long,long,long,long,long,\ diff --git a/ext/dl/sym.c b/ext/dl/sym.c index b839463016..adf6137edf 100644 --- a/ext/dl/sym.c +++ b/ext/dl/sym.c @@ -352,6 +352,90 @@ rb_dl_win32_set_last_error(VALUE self, VALUE val) } #endif +#ifdef DLSTACK_GUARD +# ifdef __MSVC_RUNTIME_CHECKS +# pragma runtime_checks("s", off) +# endif +#ifdef _MSC_VER +__declspec(noinline) +#endif +static int +rb_dlsym_guardcall(char type, ANY_TYPE *ret, long *stack, void *func) +{ + volatile char *guard = ALLOCA_N(char, 1); /* guard stack pointer */ + switch(type){ + case '0': + { + void (*f)(DLSTACK_PROTO) = func; + f(DLSTACK_ARGS); + } + break; + case 'P': + case 'p': + { + void * (*f)(DLSTACK_PROTO) = func; + ret->p = f(DLSTACK_ARGS); + } + break; + case 'C': + case 'c': + { + char (*f)(DLSTACK_PROTO) = func; + ret->c = f(DLSTACK_ARGS); + } + break; + case 'H': + case 'h': + { + short (*f)(DLSTACK_PROTO) = func; + ret->h = f(DLSTACK_ARGS); + } + break; + case 'I': + case 'i': + { + int (*f)(DLSTACK_PROTO) = func; + ret->i = f(DLSTACK_ARGS); + } + break; + case 'L': + case 'l': + { + long (*f)(DLSTACK_PROTO) = func; + ret->l = f(DLSTACK_ARGS); + } + break; + case 'F': + case 'f': + { + float (*f)(DLSTACK_PROTO) = func; + ret->f = f(DLSTACK_ARGS); + } + break; + case 'D': + case 'd': + { + double (*f)(DLSTACK_PROTO) = func; + ret->d = f(DLSTACK_ARGS); + } + break; + case 'S': + case 's': + { + char * (*f)(DLSTACK_PROTO) = func; + ret->s = f(DLSTACK_ARGS); + } + break; + default: + return 0; + } + return 1; +} +# ifdef __MSVC_RUNTIME_CHECKS +# pragma runtime_checks("s", restore) +# endif +#endif /* defined(DLSTACK_GUARD) */ + VALUE rb_dlsym_call(int argc, VALUE argv[], VALUE self) { @@ -642,6 +726,12 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) } DLSTACK_END(sym->type); +#ifdef DLSTACK_GUARD + if(!rb_dlsym_guardcall(sym->type[0], &ret, stack, func)) { + FREE_ARGS; + rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); + } +#else /* defined(DLSTACK_GUARD) */ { switch( sym->type[0] ){ case '0': @@ -711,6 +801,7 @@ rb_dlsym_call(int argc, VALUE argv[], VALUE self) rb_raise(rb_eDLTypeError, "unknown type `%c'", sym->type[0]); } } +#endif /* defubed(DLSTACK_GUARD) */ { /* |