* 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/trunk@3558 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eban 2003-03-06 15:45:14 +00:00
parent 2b214ff6a3
commit 280039eb20
4 changed files with 61 additions and 192 deletions

View File

@ -1,3 +1,9 @@
Fri Mar 7 00:30:33 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* ext/Win32API/Win32API.c: no longer use inline-asms.
* ext/Win32API/extconf.rb: no need to add gcc options.
Wed Mar 5 12:13:21 2003 WATANABE Hirofumi <eban@ruby-lang.org> Wed Mar 5 12:13:21 2003 WATANABE Hirofumi <eban@ruby-lang.org>
* configure.in: better YACC support on HP-UX. * configure.in: better YACC support on HP-UX.

View File

@ -8,27 +8,11 @@
#include <stdio.h> #include <stdio.h>
#endif #endif
#if defined(_MSC_VER)
#if defined(_M_ALPHA)
#ifdef __cplusplus
extern "C" { long __asm(char *,...); };
#else
long __asm(char *,...);
#endif
#pragma intrinsic(__asm)
#endif
#endif
#define _T_VOID 0 #define _T_VOID 0
#define _T_NUMBER 1 #define _T_NUMBER 1
#define _T_POINTER 2 #define _T_POINTER 2
#define _T_INTEGER 3 #define _T_INTEGER 3
typedef char *ApiPointer(void);
typedef long ApiNumber(void);
typedef void ApiVoid(void);
typedef int ApiInteger(void);
#include "ruby.h" #include "ruby.h"
typedef struct { typedef struct {
@ -62,7 +46,7 @@ Win32API_initialize(self, dllname, proc, import, export)
char *s; char *s;
int i; int i;
int len; int len;
int ex; int ex = _T_VOID;
SafeStringValue(dllname); SafeStringValue(dllname);
SafeStringValue(proc); SafeStringValue(proc);
@ -85,37 +69,37 @@ Win32API_initialize(self, dllname, proc, import, export)
a_import = rb_ary_new(); a_import = rb_ary_new();
switch (TYPE(import)) { switch (TYPE(import)) {
case T_NIL: case T_NIL:
break; break;
case T_ARRAY: case T_ARRAY:
ptr = RARRAY(import)->ptr; ptr = RARRAY(import)->ptr;
for (i = 0, len = RARRAY(import)->len; i < len; i++) { for (i = 0, len = RARRAY(import)->len; i < len; i++) {
SafeStringValue(ptr[i]); SafeStringValue(ptr[i]);
switch (*(char *)RSTRING(ptr[i])->ptr) { 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)); rb_ary_push(a_import, INT2FIX(_T_NUMBER));
break; break;
case 'P': case 'p': case 'P': case 'p':
rb_ary_push(a_import, INT2FIX(_T_POINTER)); rb_ary_push(a_import, INT2FIX(_T_POINTER));
break; break;
case 'I': case 'i': case 'I': case 'i':
rb_ary_push(a_import, INT2FIX(_T_INTEGER)); rb_ary_push(a_import, INT2FIX(_T_INTEGER));
break; break;
} }
} }
break; break;
default: default:
SafeStringValue(import); SafeStringValue(import);
s = RSTRING(import)->ptr; s = RSTRING(import)->ptr;
for (i = 0, len = RSTRING(import)->len; i < len; i++) { for (i = 0, len = RSTRING(import)->len; i < len; i++) {
switch (*s++) { 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)); rb_ary_push(a_import, INT2FIX(_T_NUMBER));
break; break;
case 'P': case 'p': case 'P': case 'p':
rb_ary_push(a_import, INT2FIX(_T_POINTER)); rb_ary_push(a_import, INT2FIX(_T_POINTER));
break; break;
case 'I': case 'i': case 'I': case 'i':
rb_ary_push(a_import, INT2FIX(_T_INTEGER)); rb_ary_push(a_import, INT2FIX(_T_INTEGER));
break; break;
} }
@ -129,16 +113,16 @@ Win32API_initialize(self, dllname, proc, import, export)
} else { } else {
SafeStringValue(export); SafeStringValue(export);
switch (*RSTRING(export)->ptr) { switch (*RSTRING(export)->ptr) {
case 'V': case 'v': case 'V': case 'v':
ex = _T_VOID; ex = _T_VOID;
break; break;
case 'N': case 'n': case 'L': case 'l': case 'N': case 'n': case 'L': case 'l':
ex = _T_NUMBER; ex = _T_NUMBER;
break; break;
case 'P': case 'p': case 'P': case 'p':
ex = _T_POINTER; ex = _T_POINTER;
break; break;
case 'I': case 'i': case 'I': case 'i':
ex = _T_INTEGER; ex = _T_INTEGER;
break; break;
} }
@ -148,15 +132,6 @@ Win32API_initialize(self, dllname, proc, import, export)
return Qnil; return Qnil;
} }
#ifdef __BORLANDC__
int c_m( FARPROC api, long* p )
{
long pp[16];
memcpy( pp, p, 16*sizeof(long) );
return api();
}
#endif
static VALUE static VALUE
Win32API_Call(argc, argv, obj) Win32API_Call(argc, argv, obj)
int argc; int argc;
@ -164,171 +139,62 @@ Win32API_Call(argc, argv, obj)
VALUE obj; VALUE obj;
{ {
VALUE args; 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;
#ifdef __BORLANDC__
long* ptr;
long p[16];
#endif
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) if (items != nimport)
rb_raise(rb_eRuntimeError, "Wrong number of parameters: expected %d, got %d.\n", rb_raise(rb_eRuntimeError, "Wrong number of parameters: expected %d, got %d.\n",
nimport, items); nimport, items);
if (0 < nimport) { for (i = 0; i < nimport; i++) {
#ifdef __BORLANDC__ unsigned long lParam = 0;
ptr = p + ( nimport - 1 ); switch (FIX2INT(rb_ary_entry(obj_import, i))) {
#endif
for (i = nimport - 1; 0 <= i; i--) {
VALUE str; VALUE str;
import_type = rb_ary_entry(obj_import, i); case _T_NUMBER:
timport = FIX2INT(import_type); case _T_INTEGER:
switch (timport) { default:
case _T_NUMBER: lParam = NUM2ULONG(rb_ary_entry(args, i));
case _T_INTEGER: break;
lParam = NUM2ULONG(rb_ary_entry(args, i)); case _T_POINTER:
#if defined(_MSC_VER) || defined(__LCC__) str = rb_ary_entry(args, i);
#if defined(_M_IX86) if (NIL_P(str)) {
_asm { lParam = 0;
mov eax, lParam } else if (FIXNUM_P(str)) {
push eax lParam = NUM2ULONG(str);
} } else {
#elif defined(_M_ALPHA) StringValue(str);
__asm( rb_str_modify(str);
"ldl r0, 0(%0);" lParam = (unsigned long)StringValuePtr(str);
"stq r0, -(sp);"
, lParam
);
#else
#error
#endif
#elif defined(__BORLANDC__)
*ptr = lParam;
--ptr;
#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 {
StringValue(str);
rb_str_modify(str);
pParam = StringValuePtr(str);
}
#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(__BORLANDC__)
*ptr = (long)pParam;
--ptr;
#elif defined __GNUC__
asm volatile ("pushl %0" :: "g" (pParam));
#else
#error
#endif
break;
} }
break;
} }
params[i] = lParam;
} }
#if defined __GNUC__ ret = ApiFunction(param);
asm volatile ("call *%1" : "=r" (ret) : "g" (ApiFunction));
switch (texport) { switch (FIX2INT(obj_export)) {
case _T_NUMBER: case _T_NUMBER:
case _T_INTEGER: case _T_INTEGER:
Return = INT2NUM(ret); return INT2NUM(ret);
break;
case _T_POINTER: case _T_POINTER:
Return = rb_str_new2((char *)ret); return rb_str_new2((char *)ret);
break;
case _T_VOID: case _T_VOID:
default: default:
Return = INT2NUM(0); return INT2NUM(0);
break;
} }
#else
switch (texport) {
case _T_NUMBER:
#if defined(__BORLANDC__)
Return = INT2NUM((long)c_m(ApiFunction, p));
#else
ApiFunctionNumber = (ApiNumber *) ApiFunction;
Return = INT2NUM(ApiFunctionNumber());
#endif
break;
case _T_POINTER:
#if defined(__BORLANDC__)
Return = rb_str_new2((char *)c_m(ApiFunction, p));
#else
ApiFunctionPointer = (ApiPointer *) ApiFunction;
Return = rb_str_new2((char *)ApiFunctionPointer());
#endif
break;
case _T_INTEGER:
#if defined(__BORLANDC__)
Return = INT2NUM((int)c_m(ApiFunction, p));
#else
ApiFunctionInteger = (ApiInteger *) ApiFunction;
Return = INT2NUM(ApiFunctionInteger());
#endif
break;
case _T_VOID:
default:
ApiFunctionVoid = (ApiVoid *) ApiFunction;
ApiFunctionVoid();
Return = INT2NUM(0);
break;
}
#endif
return Return;
} }
void void

View File

@ -1,8 +1,5 @@
require 'mkmf' require 'mkmf'
if have_header("windows.h") and have_library("kernel32") if have_header("windows.h") and have_library("kernel32")
if Config::CONFIG["CC"] =~ /gcc/
$CFLAGS += " -fno-defer-pop -fno-omit-frame-pointer"
end
create_makefile("Win32API") create_makefile("Win32API")
end end

View File

@ -1,11 +1,11 @@
#define RUBY_VERSION "1.8.0" #define RUBY_VERSION "1.8.0"
#define RUBY_RELEASE_DATE "2003-03-05" #define RUBY_RELEASE_DATE "2003-03-07"
#define RUBY_VERSION_CODE 180 #define RUBY_VERSION_CODE 180
#define RUBY_RELEASE_CODE 20030305 #define RUBY_RELEASE_CODE 20030307
#define RUBY_VERSION_MAJOR 1 #define RUBY_VERSION_MAJOR 1
#define RUBY_VERSION_MINOR 8 #define RUBY_VERSION_MINOR 8
#define RUBY_VERSION_TEENY 0 #define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2003 #define RUBY_RELEASE_YEAR 2003
#define RUBY_RELEASE_MONTH 03 #define RUBY_RELEASE_MONTH 03
#define RUBY_RELEASE_DAY 05 #define RUBY_RELEASE_DAY 07