Author: Armin Rigo <ar...@tunes.org>
Branch: reverse-debugger
Changeset: r86167:c46e5f55f170
Date: 2016-08-12 11:34 +0200
http://bitbucket.org/pypy/pypy/changeset/c46e5f55f170/

Log:    When entering debugger commands, make floating-point results
        approximately work

diff --git a/rpython/rlib/rdtoa.py b/rpython/rlib/rdtoa.py
--- a/rpython/rlib/rdtoa.py
+++ b/rpython/rlib/rdtoa.py
@@ -3,7 +3,7 @@
 from rpython.translator.tool.cbuild import ExternalCompilationInfo
 from rpython.translator import cdir
 from rpython.rtyper.lltypesystem import lltype, rffi
-from rpython.rlib import jit
+from rpython.rlib import jit, revdb
 from rpython.rlib.rstring import StringBuilder
 import py, sys
 
@@ -54,6 +54,8 @@
 def strtod(input):
     if len(input) > _INT_LIMIT:
         raise MemoryError
+    if revdb.flag_io_disabled():
+        return revdb.emulate_strtod(input)
     end_ptr = lltype.malloc(rffi.CCHARPP.TO, 1, flavor='raw')
     try:
         ll_input = rffi.str2charp(input)
@@ -236,6 +238,8 @@
          special_strings=lower_special_strings, upper=False):
     if precision > _INT_LIMIT:
         raise MemoryError
+    if revdb.flag_io_disabled():
+        return revdb.emulate_dtoa(value)
     decpt_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
     try:
         sign_ptr = lltype.malloc(rffi.INTP.TO, 1, flavor='raw')
diff --git a/rpython/rlib/revdb.py b/rpython/rlib/revdb.py
--- a/rpython/rlib/revdb.py
+++ b/rpython/rlib/revdb.py
@@ -7,7 +7,7 @@
 from rpython.rtyper.extregistry import ExtRegistryEntry
 from rpython.rtyper.annlowlevel import llhelper, hlstr
 from rpython.rtyper.annlowlevel import cast_gcref_to_instance
-from rpython.rtyper.lltypesystem import rffi
+from rpython.rtyper.lltypesystem import lltype, rffi
 
 
 CMD_PRINT       = 1
@@ -81,6 +81,14 @@
     """
     return llop.revdb_get_value(lltype.Signed, 'p')
 
+def flag_io_disabled():
+    """Returns True if we're in the debugger typing commands."""
+    if we_are_translated():
+        if fetch_translated_config().translation.reverse_debugger:
+            flag = llop.revdb_get_value(lltype.Signed, 'i')
+            return flag != ord('R')  # FID_REGULAR_MODE
+    return False
+
 ## @specialize.arg(1)
 ## def go_forward(time_delta, callback):
 ##     """For RPython debug commands: tells that after this function finishes,
@@ -203,3 +211,22 @@
 
     def specialize_call(self, hop):
         hop.exception_cannot_occur()
+
+
+# ____________________________________________________________
+
+# Emulation for strtod() and dtoa() when running debugger commands
+# (we can't easily just call C code there).  The emulation can return
+# a crude result.  Hack hack hack.
+
+_INVALID_STRTOD = -3.46739514239368e+113
+
+def emulate_strtod(input):
+    d = llop.revdb_strtod(lltype.Float, input)
+    if d == _INVALID_STRTOD:
+        raise ValueError
+    return d
+
+def emulate_dtoa(value):
+    s = llop.revdb_dtoa(lltype.Ptr(rstr.STR), value)
+    return hlstr(s)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py 
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -584,6 +584,8 @@
     'revdb_weakref_deref':  LLOp(),
     'revdb_call_destructor': LLOp(),
     'revdb_set_thread_breakpoint': LLOp(),
+    'revdb_strtod':         LLOp(sideeffects=False),
+    'revdb_dtoa':           LLOp(sideeffects=False),
 }
 # ***** Run test_lloperation after changes. *****
 
diff --git a/rpython/translator/revdb/src-revdb/revdb.c 
b/rpython/translator/revdb/src-revdb/revdb.c
--- a/rpython/translator/revdb/src-revdb/revdb.c
+++ b/rpython/translator/revdb/src-revdb/revdb.c
@@ -1523,6 +1523,8 @@
                 saved_state.unique_id_seen);
     case 'p':       /* current_place() */
         return current_place;
+    case 'i':       /* flag_io_disabled() */
+        return flag_io_disabled;
     default:
         return -1;
     }
@@ -1734,6 +1736,39 @@
     break_thread_num = (uint64_t)tnum;
 }
 
+#define INVALID_STRTOD  (-3.46739514239368e+113)
+
+RPY_EXTERN
+double rpy_reverse_db_strtod(RPyString *s)
+{
+    /* approximate hacks only */
+    double result;
+    char *endptr = NULL;
+    char buffer[8192];
+    size_t size = RPyString_Size(s);
+
+    if (size >= sizeof(buffer))
+        return INVALID_STRTOD;
+    memcpy(buffer, _RPyString_AsString(s), size);
+    buffer[size] = '\0';
+    result = strtod(buffer, &endptr);
+    if (endptr == NULL || *endptr != '\0')
+        return INVALID_STRTOD;
+    return result;
+}
+
+RPY_EXTERN RPyString *rpy_reverse_db_dtoa(double d)
+{
+    char buffer[128];
+    RPyString *result;
+    int size;
+    size = snprintf(buffer, sizeof(buffer), "%g", d);
+    if (size < 0) size = 0;   /* XXX? */
+    result = make_rpy_string(size);
+    memcpy(_RPyString_AsString(result), buffer, size);
+    return result;
+}
+
 
 /* ------------------------------------------------------------ */
 
diff --git a/rpython/translator/revdb/src-revdb/revdb_include.h 
b/rpython/translator/revdb/src-revdb/revdb_include.h
--- a/rpython/translator/revdb/src-revdb/revdb_include.h
+++ b/rpython/translator/revdb/src-revdb/revdb_include.h
@@ -230,6 +230,12 @@
 #define OP_REVDB_SET_THREAD_BREAKPOINT(tnum, r)                         \
     rpy_reverse_db_set_thread_breakpoint(tnum)
 
+#define OP_REVDB_STRTOD(s, r)                                           \
+    r = rpy_reverse_db_strtod(s)
+
+#define OP_REVDB_DTOA(d, r)                                             \
+    r = rpy_reverse_db_dtoa(d)
+
 
 RPY_EXTERN void rpy_reverse_db_flush(void);  /* must be called with the lock */
 RPY_EXTERN void rpy_reverse_db_fetch(const char *file, int line);
@@ -253,5 +259,7 @@
 RPY_EXTERN void rpy_reverse_db_lock_acquire(bool_t lock_contention);
 RPY_EXTERN void rpy_reverse_db_bad_acquire_gil(void);
 RPY_EXTERN void rpy_reverse_db_set_thread_breakpoint(int64_t tnum);
+RPY_EXTERN double rpy_reverse_db_strtod(RPyString *s);
+RPY_EXTERN RPyString *rpy_reverse_db_dtoa(double d);
 
 /* ------------------------------------------------------------ */
diff --git a/rpython/translator/revdb/test/test_process.py 
b/rpython/translator/revdb/test/test_process.py
--- a/rpython/translator/revdb/test/test_process.py
+++ b/rpython/translator/revdb/test/test_process.py
@@ -1,6 +1,6 @@
 import py, sys
 from cStringIO import StringIO
-from rpython.rlib import revdb
+from rpython.rlib import revdb, rdtoa
 from rpython.rlib.debug import debug_print, ll_assert
 from rpython.rtyper.annlowlevel import cast_gcref_to_instance
 from rpython.translator.revdb.message import *
@@ -47,6 +47,10 @@
                 stuff = dbstate.stuff
             elif extra == '$0':
                 stuff = dbstate.metavar
+            elif extra == '2.35':
+                val = rdtoa.strtod('2.35')
+                revdb.send_output(rdtoa.dtoa(val))
+                return
             else:
                 assert False
             uid = revdb.get_unique_id(stuff)
@@ -199,3 +203,9 @@
         group = self.test_print_cmd()
         group.jump_in_time(2)
         self._check_watchpoint_expr(group, must_exist=1)
+
+    def test_rdtoa(self):
+        group = ReplayProcessGroup(str(self.exename), self.rdbname)
+        with stdout_capture() as buf:
+            group.print_cmd('2.35')
+        assert buf.getvalue() == "2.35"
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to