mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/Win32API/Win32API.c: no longer use inline-asms.
* ext/Win32API/extconf.rb: no need to add gcc options. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@3560 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
6fda845565
commit
ea7b2dabcf
4 changed files with 82 additions and 163 deletions
|
|
@ -2,21 +2,20 @@
|
|||
Win32API - Ruby Win32 API Import Facility
|
||||
*/
|
||||
|
||||
#if !defined _MSC_VER && !defined NT
|
||||
#if !defined _MSC_VER && !defined _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_M_ALPHA)
|
||||
#ifdef __cplusplus
|
||||
extern "C" { long __asm(char *,...); };
|
||||
#else
|
||||
long __asm(char *,...);
|
||||
#ifndef SafeStringValue
|
||||
# define SafeStringValue Check_SafeStr
|
||||
#endif
|
||||
#pragma intrinsic(__asm)
|
||||
#ifndef StringValue
|
||||
# define StringValue(str) Check_Type(str, T_STRING)
|
||||
#endif
|
||||
#ifndef StringValuePtr
|
||||
# define StringValuePtr(str) RSTRING(str)->ptr
|
||||
#endif
|
||||
|
||||
#define _T_VOID 0
|
||||
|
|
@ -24,11 +23,6 @@ long __asm(char *,...);
|
|||
#define _T_POINTER 2
|
||||
#define _T_INTEGER 3
|
||||
|
||||
typedef char *ApiPointer(void);
|
||||
typedef long ApiNumber(void);
|
||||
typedef void ApiVoid(void);
|
||||
typedef int ApiInteger(void);
|
||||
|
||||
#include "ruby.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -62,10 +56,10 @@ Win32API_initialize(self, dllname, proc, import, export)
|
|||
char *s;
|
||||
int i;
|
||||
int len;
|
||||
int ex;
|
||||
int ex = _T_VOID;
|
||||
|
||||
Check_SafeStr(dllname);
|
||||
Check_SafeStr(proc);
|
||||
SafeStringValue(dllname);
|
||||
SafeStringValue(proc);
|
||||
hdll = LoadLibrary(RSTRING(dllname)->ptr);
|
||||
if (!hdll)
|
||||
rb_raise(rb_eRuntimeError, "LoadLibrary: %s\n", RSTRING(dllname)->ptr);
|
||||
|
|
@ -85,60 +79,65 @@ Win32API_initialize(self, dllname, proc, import, export)
|
|||
|
||||
a_import = rb_ary_new();
|
||||
switch (TYPE(import)) {
|
||||
case T_NIL:
|
||||
case T_NIL:
|
||||
break;
|
||||
case T_ARRAY:
|
||||
case T_ARRAY:
|
||||
ptr = RARRAY(import)->ptr;
|
||||
for (i = 0, len = RARRAY(import)->len; i < len; i++) {
|
||||
Check_SafeStr(ptr[i]);
|
||||
SafeStringValue(ptr[i]);
|
||||
switch (*(char *)RSTRING(ptr[i])->ptr) {
|
||||
case 'N': case 'n': case 'L': case 'l':
|
||||
case 'N': case 'n': case 'L': case 'l':
|
||||
rb_ary_push(a_import, INT2FIX(_T_NUMBER));
|
||||
break;
|
||||
case 'P': case 'p':
|
||||
case 'P': case 'p':
|
||||
rb_ary_push(a_import, INT2FIX(_T_POINTER));
|
||||
break;
|
||||
case 'I': case 'i':
|
||||
case 'I': case 'i':
|
||||
rb_ary_push(a_import, INT2FIX(_T_INTEGER));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Check_SafeStr(import);
|
||||
default:
|
||||
SafeStringValue(import);
|
||||
s = RSTRING(import)->ptr;
|
||||
for (i = 0, len = RSTRING(import)->len; i < len; i++) {
|
||||
switch (*s++) {
|
||||
case 'N': case 'n': case 'L': case 'l':
|
||||
case 'N': case 'n': case 'L': case 'l':
|
||||
rb_ary_push(a_import, INT2FIX(_T_NUMBER));
|
||||
break;
|
||||
case 'P': case 'p':
|
||||
case 'P': case 'p':
|
||||
rb_ary_push(a_import, INT2FIX(_T_POINTER));
|
||||
break;
|
||||
case 'I': case 'i':
|
||||
case 'I': case 'i':
|
||||
rb_ary_push(a_import, INT2FIX(_T_INTEGER));
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (16 < RARRAY(a_import)->len) {
|
||||
rb_raise(rb_eRuntimeError, "too many parameters: %d\n", RARRAY(a_import)->len);
|
||||
}
|
||||
|
||||
rb_iv_set(self, "__import__", a_import);
|
||||
|
||||
if (NIL_P(export)) {
|
||||
ex = _T_VOID;
|
||||
} else {
|
||||
Check_SafeStr(export);
|
||||
SafeStringValue(export);
|
||||
switch (*RSTRING(export)->ptr) {
|
||||
case 'V': case 'v':
|
||||
case 'V': case 'v':
|
||||
ex = _T_VOID;
|
||||
break;
|
||||
case 'N': case 'n': case 'L': case 'l':
|
||||
case 'N': case 'n': case 'L': case 'l':
|
||||
ex = _T_NUMBER;
|
||||
break;
|
||||
case 'P': case 'p':
|
||||
case 'P': case 'p':
|
||||
ex = _T_POINTER;
|
||||
break;
|
||||
case 'I': case 'i':
|
||||
case 'I': case 'i':
|
||||
ex = _T_INTEGER;
|
||||
break;
|
||||
}
|
||||
|
|
@ -155,146 +154,62 @@ Win32API_Call(argc, argv, obj)
|
|||
VALUE obj;
|
||||
{
|
||||
VALUE args;
|
||||
unsigned long ret;
|
||||
int i;
|
||||
struct {
|
||||
unsigned long params[16];
|
||||
} param;
|
||||
#define params param.params
|
||||
|
||||
FARPROC ApiFunction;
|
||||
VALUE obj_proc = rb_iv_get(obj, "__proc__");
|
||||
VALUE obj_import = rb_iv_get(obj, "__import__");
|
||||
VALUE obj_export = rb_iv_get(obj, "__export__");
|
||||
FARPROC ApiFunction = (FARPROC)NUM2ULONG(obj_proc);
|
||||
int items = rb_scan_args(argc, argv, "0*", &args);
|
||||
int nimport = RARRAY(obj_import)->len;
|
||||
|
||||
ApiPointer *ApiFunctionPointer;
|
||||
ApiNumber *ApiFunctionNumber;
|
||||
ApiVoid *ApiFunctionVoid;
|
||||
ApiInteger *ApiFunctionInteger;
|
||||
|
||||
long lParam;
|
||||
char *pParam;
|
||||
|
||||
VALUE Return;
|
||||
|
||||
VALUE obj_proc;
|
||||
VALUE obj_import;
|
||||
VALUE obj_export;
|
||||
VALUE import_type;
|
||||
int nimport, timport, texport, i;
|
||||
int items;
|
||||
int ret;
|
||||
|
||||
items = rb_scan_args(argc, argv, "0*", &args);
|
||||
|
||||
obj_proc = rb_iv_get(obj, "__proc__");
|
||||
|
||||
ApiFunction = (FARPROC)NUM2ULONG(obj_proc);
|
||||
|
||||
obj_import = rb_iv_get(obj, "__import__");
|
||||
obj_export = rb_iv_get(obj, "__export__");
|
||||
nimport = RARRAY(obj_import)->len;
|
||||
texport = FIX2INT(obj_export);
|
||||
|
||||
if (items != nimport)
|
||||
rb_raise(rb_eRuntimeError, "Wrong number of parameters: expected %d, got %d.\n",
|
||||
nimport, items);
|
||||
|
||||
if (0 < nimport) {
|
||||
for (i = nimport - 1; 0 <= i; i--) {
|
||||
for (i = 0; i < nimport; i++) {
|
||||
unsigned long lParam = 0;
|
||||
switch (FIX2INT(rb_ary_entry(obj_import, i))) {
|
||||
VALUE str;
|
||||
import_type = rb_ary_entry(obj_import, i);
|
||||
timport = FIX2INT(import_type);
|
||||
switch (timport) {
|
||||
case _T_NUMBER:
|
||||
case _T_INTEGER:
|
||||
lParam = NUM2ULONG(rb_ary_entry(args, i));
|
||||
#if defined(_MSC_VER) || defined(__LCC__)
|
||||
#if defined(_M_IX86)
|
||||
_asm {
|
||||
mov eax, lParam
|
||||
push eax
|
||||
}
|
||||
#elif defined(_M_ALPHA)
|
||||
__asm(
|
||||
"ldl r0, 0(%0);"
|
||||
"stq r0, -(sp);"
|
||||
, lParam
|
||||
);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
#elif defined __GNUC__
|
||||
asm volatile ("pushl %0" :: "g" (lParam));
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
break;
|
||||
case _T_POINTER:
|
||||
str = rb_ary_entry(args, i);
|
||||
if (NIL_P(str)) {
|
||||
pParam = 0;
|
||||
} else if (FIXNUM_P(str)){
|
||||
pParam = (char *)NUM2ULONG(str);
|
||||
} else {
|
||||
Check_Type(str, T_STRING);
|
||||
rb_str_modify(str);
|
||||
pParam = RSTRING(str)->ptr;
|
||||
}
|
||||
#if defined(_MSC_VER) || defined(__LCC__)
|
||||
#if defined(_M_IX86)
|
||||
_asm {
|
||||
mov eax, pParam
|
||||
push eax
|
||||
}
|
||||
#elif defined(_M_ALPHA)
|
||||
__asm(
|
||||
"ldl r0, 0(%0);"
|
||||
"stq r0, -(sp);"
|
||||
, pParam
|
||||
);
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
#elif defined __GNUC__
|
||||
asm volatile ("pushl %0" :: "g" (pParam));
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
break;
|
||||
case _T_NUMBER:
|
||||
case _T_INTEGER:
|
||||
default:
|
||||
lParam = NUM2ULONG(rb_ary_entry(args, i));
|
||||
break;
|
||||
case _T_POINTER:
|
||||
str = rb_ary_entry(args, i);
|
||||
if (NIL_P(str)) {
|
||||
lParam = 0;
|
||||
} else if (FIXNUM_P(str)) {
|
||||
lParam = NUM2ULONG(str);
|
||||
} else {
|
||||
StringValue(str);
|
||||
rb_str_modify(str);
|
||||
lParam = (unsigned long)StringValuePtr(str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
params[i] = lParam;
|
||||
}
|
||||
|
||||
#if defined __GNUC__
|
||||
asm volatile ("call *%1" : "=r" (ret) : "g" (ApiFunction));
|
||||
switch (texport) {
|
||||
ret = ApiFunction(param);
|
||||
|
||||
switch (FIX2INT(obj_export)) {
|
||||
case _T_NUMBER:
|
||||
case _T_INTEGER:
|
||||
Return = INT2NUM(ret);
|
||||
break;
|
||||
return INT2NUM(ret);
|
||||
case _T_POINTER:
|
||||
Return = rb_str_new2((char *)ret);
|
||||
break;
|
||||
return rb_str_new2((char *)ret);
|
||||
case _T_VOID:
|
||||
default:
|
||||
Return = INT2NUM(0);
|
||||
break;
|
||||
return INT2NUM(0);
|
||||
}
|
||||
#else
|
||||
switch (texport) {
|
||||
case _T_NUMBER:
|
||||
ApiFunctionNumber = (ApiNumber *) ApiFunction;
|
||||
Return = INT2NUM(ApiFunctionNumber());
|
||||
break;
|
||||
case _T_POINTER:
|
||||
ApiFunctionPointer = (ApiPointer *) ApiFunction;
|
||||
Return = rb_str_new2((char *)ApiFunctionPointer());
|
||||
break;
|
||||
case _T_INTEGER:
|
||||
ApiFunctionInteger = (ApiInteger *) ApiFunction;
|
||||
Return = INT2NUM(ApiFunctionInteger());
|
||||
break;
|
||||
case _T_VOID:
|
||||
default:
|
||||
ApiFunctionVoid = (ApiVoid *) ApiFunction;
|
||||
ApiFunctionVoid();
|
||||
Return = INT2NUM(0);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return Return;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue