yarv-diff:165
From: ko1 atdot.net
Date: 24 Dec 2005 22:44:13 -0000
Subject: [yarv-diff:165] r324 - in trunk: . rb
Author: ko1
Date: 2005-12-25 07:44:12 +0900 (Sun, 25 Dec 2005)
New Revision: 324
Modified:
trunk/ChangeLog
trunk/blockinlining.c
trunk/compile.c
trunk/rb/insns2vm.rb
trunk/test.rb
trunk/vm.h
trunk/vm_dump.c
Log:
* blockinlining.c, compile.c : fix block inlining
* rb/insns2vm.rb : fix to support tracing stack depth
with operands unification
* vm_dump.c : fix to print Qundef on stack dump
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-12-24 16:49:12 UTC (rev 323)
+++ trunk/ChangeLog 2005-12-24 22:44:12 UTC (rev 324)
@@ -4,6 +4,16 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-12-25(Sun) 07:40:08 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * blockinlining.c, compile.c : fix block inlining
+
+ * rb/insns2vm.rb : fix to support tracing stack depth
+ with operands unification
+
+ * vm_dump.c : fix to print Qundef on stack dump
+
+
2005-12-25(Sun) 01:45:55 +0900 Koichi Sasada <ko1 atdot.net>
* insns.def, compile.c, rb/insns2vm.rb, template/insns_info.inc.tmpl :
Modified: trunk/blockinlining.c
===================================================================
--- trunk/blockinlining.c 2005-12-24 16:49:12 UTC (rev 323)
+++ trunk/blockinlining.c 2005-12-24 22:44:12 UTC (rev 324)
@@ -63,8 +63,28 @@
return head;
}
+static NODE *
+new_assign(NODE *lnode, NODE *rhs)
+{
+ switch(nd_type(lnode)){
+ case NODE_LASGN:{
+ return NEW_NODE(NODE_LASGN, lnode->nd_vid, rhs, lnode->nd_cnt);
+ /* NEW_LASGN(lnode->nd_vid, rhs); */
+ }
+ case NODE_GASGN:{
+ return NEW_GASGN(lnode->nd_vid, rhs);
+ }
+ case NODE_DASGN:{
+ return NEW_DASGN(lnode->nd_vid, rhs);
+ }
+ default:
+ rb_bug("unimplemented");
+ }
+ return 0;
+}
+
static NODE*
-build_Integer_times_node(yarv_iseq_t *iseq, NODE *node,
+build_Integer_times_node(yarv_iseq_t *iseq, NODE *node, NODE *lnode,
VALUE param_vars, VALUE local_vars)
{
/* Special Block for Integer#times
@@ -104,17 +124,26 @@
else{
ID _e = rb_intern("#_e");
ID e = SYM2ID(rb_ary_entry(param_vars, 0));
+ NODE *assign;
+
rb_ary_push(param_vars, ID2SYM(_self));
rb_ary_push(local_vars, ID2SYM(_e));
iseq->argc++;
+ if(nd_type(lnode) == NODE_DASGN_CURR){
+ assign = NEW_DASGN(e, NEW_DVAR(_e));
+ }
+ else{
+ assign = new_assign(lnode, NEW_DVAR(_e));
+ }
+
node =
new_block(
NEW_DASGN(_e, NEW_DVAR(e)),
NEW_WHILE(
NEW_CALL(NEW_DVAR(_e), idLT, new_ary(NEW_DVAR(_self), 0)),
new_block(
- NEW_DASGN(e, NEW_DVAR(_e)),
+ assign,
new_block(NEW_OPTBLOCK(node),
NEW_DASGN(_e, NEW_CALL(NEW_DVAR(_e), idSucc, 0)))),
Qundef));
@@ -153,7 +182,7 @@
}
static NODE *
-build_Range_each_node(yarv_iseq_t *iseq, NODE *node,
+build_Range_each_node(yarv_iseq_t *iseq, NODE *node, NODE *lnode,
VALUE param_vars, VALUE local_vars, ID mid)
{
/* Special Block for Range#each
@@ -192,17 +221,26 @@
else{
ID _e = rb_intern("#_e");
ID e = SYM2ID(rb_ary_entry(param_vars, 0));
+ NODE *assign;
+
rb_ary_push(param_vars, ID2SYM(_last));
rb_ary_push(local_vars, ID2SYM(_e));
iseq->argc++;
+ if(nd_type(lnode) == NODE_DASGN_CURR){
+ assign = NEW_DASGN(e, NEW_DVAR(_e));
+ }
+ else{
+ assign = new_assign(lnode, NEW_DVAR(_e));
+ }
+
node =
new_block(
NEW_DASGN(_e, NEW_DVAR(e)),
NEW_WHILE(
NEW_CALL(NEW_DVAR(_e), mid, new_ary(NEW_DVAR(_last), 0)),
new_block(
- NEW_DASGN(e, NEW_DVAR(_e)),
+ assign,
new_block(NEW_OPTBLOCK(node),
NEW_DASGN(_e, NEW_CALL(NEW_DVAR(_e), idSucc, 0)))),
Qundef));
@@ -211,18 +249,18 @@
}
static NODE *
-build_Range_each_node_LE(yarv_iseq_t *iseq, NODE *node,
+build_Range_each_node_LE(yarv_iseq_t *iseq, NODE *node, NODE *lnode,
VALUE param_vars, VALUE local_vars)
{
- return build_Range_each_node(iseq, node,
+ return build_Range_each_node(iseq, node, lnode,
param_vars, local_vars, idLE);
}
static NODE *
-build_Range_each_node_LT(yarv_iseq_t *iseq, NODE *node,
+build_Range_each_node_LT(yarv_iseq_t *iseq, NODE *node, NODE *lnode,
VALUE param_vars, VALUE local_vars)
{
- return build_Range_each_node(iseq, node,
+ return build_Range_each_node(iseq, node, lnode,
param_vars, local_vars, idLT);
}
@@ -262,7 +300,7 @@
static NODE *
-build_Array_each_node(yarv_iseq_t *iseq, NODE *node,
+build_Array_each_node(yarv_iseq_t *iseq, NODE *node, NODE *lnode,
VALUE param_vars, VALUE local_vars)
{
/* Special block for Array#each
@@ -318,9 +356,20 @@
}
else{
ID e = SYM2ID(rb_ary_entry(param_vars, 0));
+ NODE *assign;
+
rb_ary_push(param_vars, ID2SYM(_self));
iseq->argc++;
rb_ary_push(local_vars, ID2SYM(_i));
+
+ if(nd_type(lnode) == NODE_DASGN_CURR){
+ assign = NEW_DASGN(e,
+ NEW_CALL(NEW_DVAR(_self), idAREF, new_ary(NEW_DVAR(_i), 0)));
+ }
+ else{
+ assign = new_assign(lnode,
+ NEW_CALL(NEW_DVAR(_self), idAREF, new_ary(NEW_DVAR(_i), 0)));
+ }
node =
new_block(
@@ -329,8 +378,7 @@
NEW_CALL(NEW_DVAR(_i), idLT,
new_ary(NEW_CALL(NEW_DVAR(_self), idLength, 0), 0)),
new_block(
- NEW_DASGN(e,
- NEW_CALL(NEW_DVAR(_self), idAREF, new_ary(NEW_DVAR(_i), 0))),
+ assign,
new_block(NEW_OPTBLOCK(node),
NEW_DASGN(_i, NEW_CALL(NEW_DVAR(_i), idSucc, 0)))),
Qundef));
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-12-24 16:49:12 UTC (rev 323)
+++ trunk/compile.c 2005-12-24 22:44:12 UTC (rev 324)
@@ -873,8 +873,9 @@
}
static NODE*
-search_block_local_parameters(yarv_iseq_t *iseq, NODE *node)
+search_block_local_parameters(yarv_iseq_t *iseq, NODE *lnode)
{
+ NODE *node = lnode;
NODE *nelem;
VALUE local_vars = rb_ary_new();
VALUE param_vars = rb_ary_new();
@@ -955,8 +956,8 @@
}
if(iseq->special_block_builder != 0){
- node = ((NODE *(*)(yarv_iseq_t *, NODE*, VALUE, VALUE))
- iseq->special_block_builder)(iseq, node, param_vars, local_vars);
+ node = ((NODE *(*)(yarv_iseq_t *, NODE*, NODE *, VALUE, VALUE))
+ iseq->special_block_builder)(iseq, node, lnode->nd_var, param_vars, local_vars);
}
rb_ary_concat(param_vars, local_vars);
Modified: trunk/rb/insns2vm.rb
===================================================================
--- trunk/rb/insns2vm.rb 2005-12-24 16:49:12 UTC (rev 323)
+++ trunk/rb/insns2vm.rb 2005-12-24 22:44:12 UTC (rev 324)
@@ -11,7 +11,7 @@
class InsnsDef
class InsnInfo
- def initialize name, opes, pops, rets, comm, body, tvars,
+ def initialize name, opes, pops, rets, comm, body, tvars, sp_inc,
orig = self, defopes = [], type = nil,
nsc = [], psc = [[], []]
@@ -33,7 +33,7 @@
@unifs = []
@optimized = []
@is_sc = false
- @sp_inc = nil
+ @sp_inc = sp_inc
end
def add_sc sci
@@ -49,8 +49,8 @@
attr_reader :unifs, :optimized
attr_reader :is_sc
attr_reader :tvars
- attr_accessor :sp_inc
-
+ attr_reader :sp_inc
+
def set_sc
@is_sc = true
end
@@ -67,14 +67,21 @@
if(pops.any?{|t, v| v == '...'} ||
rets.any?{|t, v| v == '...'})
# user definision
- raise "no sp increase definition" unless @sp_inc
+ raise "no sp increase definition" if @sp_inc.nil?
ret = "int inc = 0;\n"
+
@opes.each_with_index{|(t, v), i|
if t == 'ulong'
ret << " unsigned long #{v} = FIX2INT(opes[#{i}]);\n"
end
}
+ @defopes.each_with_index{|((t, var), val), i|
+ if t == 'ulong' && val != '*'
+ ret << " unsigned long #{var} = #{val};\n"
+ end
+ }
+
ret << " #{@sp_inc};\n"
ret << " return inc;"
ret
@@ -116,8 +123,8 @@
@insn_map[insn.name] = insn
end
- def make_insn name, opes, pops, rets, comm, body
- add_insn InsnInfo.new(name, opes, pops, rets, comm, body, [])
+ def make_insn name, opes, pops, rets, comm, body, sp_inc
+ add_insn InsnInfo.new(name, opes, pops, rets, comm, body, [], sp_inc)
end
@@ -211,8 +218,7 @@
# end instruction body
when /^\}/
if insn_in
- insn = make_insn(insn, opes, pops, rets, comment, body)
- insn.sp_inc = sp_inc if sp_inc
+ insn = make_insn(insn, opes, pops, rets, comment, body, sp_inc)
insn_in = false
comment = ''
end
@@ -273,7 +279,8 @@
comm[:c] = 'optimize'
add_insn insn = InsnInfo.new(
name, opes, orig_insn.pops, orig_insn.rets, comm,
- orig_insn.body, orig_insn.tvars, orig_insn, defopes)
+ orig_insn.body, orig_insn.tvars, orig_insn.sp_inc,
+ orig_insn, defopes)
orig_insn.add_optimized insn
end
@@ -367,6 +374,7 @@
passed = []
tvars = []
defopes = []
+ sp_inc = ''
insns.each_with_index{|insn, i|
names << insn.name
@@ -397,6 +405,7 @@
pops.concat e_pops
rets.concat e_rets
defopes.concat e_defs
+ sp_inc += "#{insn.sp_inc}"
body += #
"{ /* unif: #{i} */\n" +
@@ -432,7 +441,7 @@
}
add_insn insn = InsnInfo.new("UNIFIED_" + names.join('_'),
opes, pops, rets.reverse, comm, body,
- tvars_ary)
+ tvars_ary, sp_inc)
insn.defopes.replace defopes
insns[0].add_unif [insn, insns]
end
@@ -483,7 +492,8 @@
scinsn = InsnInfo.new(
name, opes, pops, rets, comm,
- orig_insn.body, orig_insn.tvars, orig_insn, orig_insn.defopes, :sc, nextsc, pushs)
+ orig_insn.body, orig_insn.tvars, orig_insn.sp_inc,
+ orig_insn, orig_insn.defopes, :sc, nextsc, pushs)
add_insn scinsn
#
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-12-24 16:49:12 UTC (rev 323)
+++ trunk/test.rb 2005-12-24 22:44:12 UTC (rev 324)
@@ -1 +1,287 @@
-require 'test/unit'
\ No newline at end of file
+require 'mkmf'
+
+case RUBY_PLATFORM
+when /(ms|bcc)win32|mingw/
+ test_func = "WSACleanup"
+ have_library("ws2_32", "WSACleanup")
+when /cygwin/
+ test_func = "socket"
+when /beos/
+ test_func = "socket"
+ have_library("net", "socket")
+when /i386-os2_emx/
+ test_func = "socket"
+ have_library("socket", "socket")
+else
+ test_func = "socket"
+ have_library("nsl", "t_open")
+ have_library("socket", "socket")
+end
+
+unless $mswin or $bccwin or $mingw
+ headers = %w<sys/types.h netdb.h string.h sys/socket.h netinet/in.h>
+end
+if /solaris/ =~ RUBY_PLATFORM and !try_compile("")
+ # bug of gcc 3.0 on Solaris 8 ?
+ headers << "sys/feature_tests.h"
+end
+
+$ipv6 = false
+default_ipv6 = /cygwin/ !~ RUBY_PLATFORM
+if enable_config("ipv6", default_ipv6)
+ if checking_for("ipv6") {try_link(<<EOF)}
+#include <sys/types.h>
+#include <sys/socket.h>
+main()
+{
+ socket(AF_INET6, SOCK_STREAM, 0);
+}
+EOF
+ $CPPFLAGS+=" -DENABLE_IPV6"
+ $ipv6 = true
+ end
+end
+
+$ipv6type = nil
+$ipv6lib = nil
+$ipv6libdir = nil
+$ipv6trylibc = nil
+if $ipv6
+ if have_macro("IPV6_INRIA_VERSION", "netinet/in.h")
+ $ipv6type = "inria"
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
+ elsif have_macro("__KAME__", "netinet/in.h")
+ $ipv6type = "kame"
+ $ipv6lib="inet6"
+ $ipv6libdir="/usr/local/v6/lib"
+ $ipv6trylibc=true
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
+ elsif File.directory? "/usr/inet6"
+ $ipv6type = "linux"
+ $ipv6lib="inet6"
+ $ipv6libdir="/usr/inet6/lib"
+ $CPPFLAGS="-DINET6 -I/usr/inet6/include "+$CPPFLAGS
+ elsif have_macro("_TOSHIBA_INET6", "sys/param.h")
+ $ipv6type = "toshiba"
+ $ipv6lib="inet6"
+ $ipv6libdir="/usr/local/v6/lib"
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
+ elsif have_macro("__V6D__", "/usr/local/v6/include/sys/v6config.h")
+ $ipv6type = "v6d"
+ $ipv6lib="v6"
+ $ipv6libdir="/usr/local/v6/lib"
+ $CFLAGS="-I/usr/local/v6/include "+$CFLAGS
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
+ elsif have_macro("_ZETA_MINAMI_INET6", "sys/param.h")
+ $ipv6type = "zeta"
+ $ipv6lib="inet6"
+ $ipv6libdir="/usr/local/v6/lib"
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
+ else
+ $ipv6lib=with_config("ipv6-lib", nil)
+ $ipv6libdir=with_config("ipv6-libdir", nil)
+ $CPPFLAGS="-DINET6 "+$CPPFLAGS
+ end
+
+ if $ipv6lib
+ if File.directory? $ipv6libdir and File.exist? "#{$ipv6libdir}/lib#{$ipv6lib}.a"
+ $LOCAL_LIBS = " -L#$ipv6libdir -l#$ipv6lib"
+ elsif !$ipv6trylibc
+ abort <<EOS
+Fatal: no #$ipv6lib library found. cannot continue.
+You need to fetch lib#{$ipv6lib}.a from appropriate
+ipv6 kit and compile beforehand.
+EOS
+ end
+ end
+end
+
+if have_struct_member("struct sockaddr_in", "sin_len", headers)
+ $defs[-1] = "-DHAVE_SIN_LEN"
+end
+
+# doug's fix, NOW add -Dss_family... only if required!
+doug = proc {have_struct_member("struct sockaddr_storage", "ss_family", headers)}
+if (doug[] or
+ with_cppflags($CPPFLAGS + " -Dss_family=__ss_family -Dss_len=__ss_len", &doug))
+ $defs[-1] = "-DHAVE_SOCKADDR_STORAGE"
+end
+
+if have_struct_member("struct sockaddr", "sa_len", headers)
+ $defs[-1] = "-DHAVE_SA_LEN "
+end
+
+have_header("netinet/tcp.h") if not /cygwin/ =~ RUBY_PLATFORM # for cygwin 1.1.5
+have_header("netinet/udp.h")
+
+if have_func("sendmsg") | have_func("recvmsg")
+ have_struct_member('struct msghdr', 'msg_control', ['sys/types.h', 'sys/socket.h'])
+ have_struct_member('struct msghdr', 'msg_accrights', ['sys/types.h', 'sys/socket.h'])
+end
+
+getaddr_info_ok = enable_config("wide-getaddrinfo") do
+ checking_for("wide getaddrinfo") {try_run(<<EOF)}
+#{cpp_include(headers)}
+#include <stdlib.h>
+
+#ifndef EXIT_SUCCESS
+#define EXIT_SUCCESS 0
+#endif
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+#ifndef AF_LOCAL
+#define AF_LOCAL AF_UNIX
+#endif
+
+main()
+{
+ int passive, gaierr, inet4 = 0, inet6 = 0;
+ struct addrinfo hints, *ai, *aitop;
+ char straddr[INET6_ADDRSTRLEN], strport[16];
+
+ for (passive = 0; passive <= 1; passive++) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_protocol = IPPROTO_TCP;
+ hints.ai_flags = passive ? AI_PASSIVE : 0;
+ hints.ai_socktype = SOCK_STREAM;
+ if ((gaierr = getaddrinfo(NULL, "54321", &hints, &aitop)) != 0) {
+ (void)gai_strerror(gaierr);
+ goto bad;
+ }
+ for (ai = aitop; ai; ai = ai->ai_next) {
+ if (ai->ai_family == AF_LOCAL) continue;
+ if (ai->ai_addr == NULL)
+ goto bad;
+#if defined(_AIX)
+ ai->ai_addr->sa_len = ai->ai_addrlen;
+ ai->ai_addr->sa_family = ai->ai_family;
+#endif
+ if (ai->ai_addrlen == 0 ||
+ getnameinfo(ai->ai_addr, ai->ai_addrlen,
+ straddr, sizeof(straddr), strport, sizeof(strport),
+ NI_NUMERICHOST|NI_NUMERICSERV) != 0) {
+ goto bad;
+ }
+ if (strcmp(strport, "54321") != 0) {
+ goto bad;
+ }
+ switch (ai->ai_family) {
+ case AF_INET:
+ if (passive) {
+ if (strcmp(straddr, "0.0.0.0") != 0) {
+ goto bad;
+ }
+ } else {
+ if (strcmp(straddr, "127.0.0.1") != 0) {
+ goto bad;
+ }
+ }
+ inet4++;
+ break;
+ case AF_INET6:
+ if (passive) {
+ if (strcmp(straddr, "::") != 0) {
+ goto bad;
+ }
+ } else {
+ if (strcmp(straddr, "::1") != 0) {
+ goto bad;
+ }
+ }
+ inet6++;
+ break;
+ case AF_UNSPEC:
+ goto bad;
+ break;
+ default:
+ /* another family support? */
+ break;
+ }
+ }
+ }
+
+ if (!(inet4 == 0 || inet4 == 2))
+ goto bad;
+ if (!(inet6 == 0 || inet6 == 2))
+ goto bad;
+
+ if (aitop)
+ freeaddrinfo(aitop);
+ exit(EXIT_SUCCESS);
+
+ bad:
+ if (aitop)
+ freeaddrinfo(aitop);
+ exit(EXIT_FAILURE);
+}
+EOF
+end
+if $ipv6 and not getaddr_info_ok
+ abort <<EOS
+
+Fatal: --enable-ipv6 is specified, and your OS seems to support IPv6 feature.
+But your getaddrinfo() and getnameinfo() are appeared to be broken. Sorry,
+you cannot compile IPv6 socket classes with broken these functions.
+You can try --enable-wide-getaddrinfo.
+EOS
+end
+
+case with_config("lookup-order-hack", "UNSPEC")
+when "INET"
+ $defs << "-DLOOKUP_ORDER_HACK_INET"
+when "INET6"
+ $defs << "-DLOOKUP_ORDER_HACK_INET6"
+when "UNSPEC"
+ # nothing special
+else
+ abort <<EOS
+
+Fatal: invalid value for --with-lookup-order-hack (expected INET, INET6 or UNSPEC)
+EOS
+end
+
+$objs = ["socket.#{$OBJEXT}"]
+
+unless getaddr_info_ok and have_func("getnameinfo", "netdb.h") and have_func("getaddrinfo", "netdb.h")
+ if have_struct_member("struct in6_addr", "s6_addr8", headers)
+ $defs[-1] = "-DHAVE_ADDR8"
+ end
+ $CPPFLAGS="-I. "+$CPPFLAGS
+ $objs += ["getaddrinfo.#{$OBJEXT}"]
+ $objs += ["getnameinfo.#{$OBJEXT}"]
+ have_func("inet_ntop") or have_func("inet_ntoa")
+ have_func("inet_pton") or have_func("inet_aton")
+ have_func("getservbyport")
+ have_header("arpa/inet.h")
+ have_header("arpa/nameser.h")
+ have_header("resolv.h")
+end
+
+unless have_type("socklen_t", headers)
+ $defs << "-Dsocklen_t=int"
+end
+
+have_header("sys/un.h")
+have_header("sys/uio.h")
+
+$distcleanfiles << "constants.h"
+
+if have_func(test_func)
+ have_func("hsterror")
+ have_func("getipnodebyname") or have_func("gethostbyname2")
+ have_func("socketpair")
+ unless have_func("gethostname")
+ have_func("uname")
+ end
+ if enable_config("socks", ENV["SOCKS_SERVER"])
+ if have_library("socks5", "SOCKSinit")
+ $defs << "-DSOCKS5" << "-DSOCKS"
+ elsif have_library("socks", "Rconnect")
+ $defs << "-DSOCKS"
+ end
+ end
+ create_makefile("socket")
+end
Modified: trunk/vm.h
===================================================================
--- trunk/vm.h 2005-12-24 16:49:12 UTC (rev 323)
+++ trunk/vm.h 2005-12-24 22:44:12 UTC (rev 324)
@@ -33,7 +33,7 @@
#if 0
#undef VMDEBUG
-#define VMDEBUG 1
+#define VMDEBUG 3
#endif
// #define COLLECT_USAGE_ANALYSIS
Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c 2005-12-24 16:49:12 UTC (rev 323)
+++ trunk/vm_dump.c 2005-12-24 22:44:12 UTC (rev 324)
@@ -207,7 +207,12 @@
ptr = cfp->bp;
for(; ptr < sp; ptr++, i++){
- rstr = rb_inspect(*ptr);
+ if(*ptr == Qundef){
+ rstr = rb_str_new2("undef");
+ }
+ else{
+ rstr = rb_inspect(*ptr);
+ }
printf(" stack %2d: %8s (%ld)\n", i, StringValueCStr(rstr), ptr - th->stack);
}
}
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml