1# Copyright 2011 the V8 project authors. All rights reserved.
2# Redistribution and use in source and binary forms, with or without
3# modification, are permitted provided that the following conditions are
4# met:
5#
6#     * Redistributions of source code must retain the above copyright
7#       notice, this list of conditions and the following disclaimer.
8#     * Redistributions in binary form must reproduce the above
9#       copyright notice, this list of conditions and the following
10#       disclaimer in the documentation and/or other materials provided
11#       with the distribution.
12#     * Neither the name of Google Inc. nor the names of its
13#       contributors may be used to endorse or promote products derived
14#       from this software without specific prior written permission.
15#
16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
29kSmiTag = 0
30kSmiTagSize = 1
31kSmiTagMask = (1 << kSmiTagSize) - 1
32
33
34kHeapObjectTag = 1
35kHeapObjectTagSize = 2
36kHeapObjectTagMask = (1 << kHeapObjectTagSize) - 1
37
38
39kFailureTag = 3
40kFailureTagSize = 2
41kFailureTagMask = (1 << kFailureTagSize) - 1
42
43
44kSmiShiftSize32 = 0
45kSmiValueSize32 = 31
46kSmiShiftBits32 = kSmiTagSize + kSmiShiftSize32
47
48
49kSmiShiftSize64 = 31
50kSmiValueSize64 = 32
51kSmiShiftBits64 = kSmiTagSize + kSmiShiftSize64
52
53
54kAllBits = 0xFFFFFFFF
55kTopBit32 = 0x80000000
56kTopBit64 = 0x8000000000000000
57
58
59t_u32 = gdb.lookup_type('unsigned int')
60t_u64 = gdb.lookup_type('unsigned long long')
61
62
63def has_smi_tag(v):
64  return v & kSmiTagMask == kSmiTag
65
66
67def has_failure_tag(v):
68  return v & kFailureTagMask == kFailureTag
69
70
71def has_heap_object_tag(v):
72  return v & kHeapObjectTagMask == kHeapObjectTag
73
74
75def raw_heap_object(v):
76  return v - kHeapObjectTag
77
78
79def smi_to_int_32(v):
80  v = v & kAllBits
81  if (v & kTopBit32) == kTopBit32:
82    return ((v & kAllBits) >> kSmiShiftBits32) - 2147483648
83  else:
84    return (v & kAllBits) >> kSmiShiftBits32
85
86
87def smi_to_int_64(v):
88  return (v >> kSmiShiftBits64)
89
90
91def decode_v8_value(v, bitness):
92  base_str = 'v8[%x]' % v
93  if has_smi_tag(v):
94    if bitness == 32:
95      return base_str + (" SMI(%d)" % smi_to_int_32(v))
96    else:
97      return base_str + (" SMI(%d)" % smi_to_int_64(v))
98  elif has_failure_tag(v):
99    return base_str + " (failure)"
100  elif has_heap_object_tag(v):
101    return base_str + (" H(0x%x)" % raw_heap_object(v))
102  else:
103    return base_str
104
105
106class V8ValuePrinter(object):
107  "Print a v8value."
108  def __init__(self, val):
109    self.val = val
110  def to_string(self):
111    if self.val.type.sizeof == 4:
112      v_u32 = self.val.cast(t_u32)
113      return decode_v8_value(int(v_u32), 32)
114    elif self.val.type.sizeof == 8:
115      v_u64 = self.val.cast(t_u64)
116      return decode_v8_value(int(v_u64), 64)
117    else:
118      return 'v8value?'
119  def display_hint(self):
120    return 'v8value'
121
122
123def v8_pretty_printers(val):
124  lookup_tag = val.type.tag
125  if lookup_tag == None:
126    return None
127  elif lookup_tag == 'v8value':
128    return V8ValuePrinter(val)
129  return None
130gdb.pretty_printers.append(v8_pretty_printers)
131
132
133def v8_to_int(v):
134  if v.type.sizeof == 4:
135    return int(v.cast(t_u32))
136  elif v.type.sizeof == 8:
137    return int(v.cast(t_u64))
138  else:
139    return '?'
140
141
142def v8_get_value(vstring):
143  v = gdb.parse_and_eval(vstring)
144  return v8_to_int(v)
145
146
147class V8PrintObject (gdb.Command):
148  """Prints a v8 object."""
149  def __init__ (self):
150    super (V8PrintObject, self).__init__ ("v8print", gdb.COMMAND_DATA)
151  def invoke (self, arg, from_tty):
152    v = v8_get_value(arg)
153    gdb.execute('call __gdb_print_v8_object(%d)' % v)
154V8PrintObject()
155