diff --git a/gdb-port/parser-type-instrumentation-gdb.py b/gdb-port/parser-type-instrumentation-gdb.py
index 23fe25eebbf9432d5226cd0b0e92bb3204f310ac..5555e877ec0a374fce702de0ca997895ed9d87ed 100644
--- a/gdb-port/parser-type-instrumentation-gdb.py
+++ b/gdb-port/parser-type-instrumentation-gdb.py
@@ -57,6 +57,8 @@ class VTTypes:
 class HParserEnv:
 	def __init__(self, parser, top_level_parse):
 		self.top_level_parse = top_level_parse
+		self.hparser_t = gdb.lookup_type("HParser")
+		self.hparser_p_t = self.hparser_t.pointer()
 
 	# parser is expected to be a Parser object
 	def name_from_vtable(self, parser):
@@ -101,14 +103,21 @@ class AttrBoolEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
+		hattrbool_t = gdb.lookup_type("HAttrBool")
+		hattrbool_p_t = hattrbool_t.pointer()
+		p_env = parser_val['env'].cast(hattrbool_p_t).dereference()
 
-		member_parser_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->p")
-		parser_obj = top_level_parse.add_or_get_parser(member_parser_p)
+		#member_parser_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->p")
+		member_parser_p = p_env['p']
+		parser_obj = top_level_parse.add_or_get_parser(member_parser_p) # For clarity: parser_obj here is the Python object representing parser->env->p
 		if parser_obj.name is None:
 			parser_obj.name_parser( self.name_from_vtable(parser_obj) )
 		self.member_parser = parser_obj
-		self.predicate_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->pred")
-		self.user_data_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->user_data")
+		#self.predicate_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->pred")
+		self.predicate_p = p_env['pred']
+		#self.user_data_p = gdb.parse_and_eval("((HAttrBool *) parser->env)->user_data")
+		self.user_data_p = p_env['user_data']
 
 	def __str__(self):
 		return str(self.member_parser)
@@ -117,15 +126,22 @@ class BindEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
+		bindenv_t = gdb.lookup_type("BindEnv") # If performance becomes a problem, the type lookups could be factored out into a dict filled out ahead of time
+		bindenv_p_t = bindenv_t.pointer()
+		p_env = parser_val['env'].cast(bindenv_p_t).dereference()
 
-		member_parser_p = gdb.parse_and_eval("((BindEnv *) parser->env)->p")
+		#member_parser_p = gdb.parse_and_eval("((BindEnv *) parser->env)->p")
+		member_parser_p = p_env['p']
 		parser_obj = top_level_parse.add_or_get_parser(member_parser_p)
 		if parser_obj.name is None:
 			parser_obj.name_parser( self.name_from_vtable(parser_obj) )
 		self.member_parser = parser_obj
-		continuation_p = gdb.parse_and_eval("((BindEnv *) parser->env)->k")
-		self.continuation = int(continuation_p)
-		env_p = gdb.parse_and_eval("((BindEnv *) parser->env)->env")
+		#continuation_p = gdb.parse_and_eval("((BindEnv *) parser->env)->k")
+		continuation_p = p_env['k']
+		self.continuation = int(continuation_p) # TODO: stop casting to int and just store the gdb.Value
+		#env_p = gdb.parse_and_eval("((BindEnv *) parser->env)->env")
+		env_p = p_env['env']
 		self.env = int(env_p)
 
 	def __str__(self):
@@ -134,10 +150,16 @@ class BindEnv(HParserEnv):
 class BitsEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
-
-		self.length =  gdb.parse_and_eval("((struct bits_env *) parser->env)->length")
-		self.signedp =  gdb.parse_and_eval("((struct bits_env *) parser->env)->signedp")
 		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
+		bits_env_t = gdb.lookup_type("struct bits_env")
+		bits_env_p_t = bits_env_t.pointer()
+		p_env = parser_val['env'].cast(bits_env_p_t).dereference()
+
+		#self.length =  gdb.parse_and_eval("((struct bits_env *) parser->env)->length")
+		self.length = p_env['length']
+		#self.signedp =  gdb.parse_and_eval("((struct bits_env *) parser->env)->signedp")
+		self.signedp = p_env['signedp']
 
 	def __str__(self):
 		return str([str(self.length), str(self.signedp)])
@@ -146,12 +168,11 @@ class ButNotEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
-
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
 		htwoparsers_t = gdb.lookup_type("HTwoParsers")
 		htwoparsers_p_t = htwoparsers_t.pointer()
+		p_env = parser_val['env'].cast(htwoparsers_p_t).dereference()
 
-		parser_obj = gdb.parse_and_eval("*parser")
-		p_env = parser_obj['env'].cast(htwoparsers_p_t).dereference()
 		p1_p = p_env['p1']
 		p1_obj = top_level_parse.add_or_get_parser(p1_p)
 		if p1_obj.name is None:
@@ -170,20 +191,23 @@ class ActionEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
-		parser_t = gdb.lookup_type("HParser") # TODO: maybe move this into TopLevelParse
-		parser_p_t = parser_t.pointer()
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
+		hparseaction_t = gdb.lookup_type("HParseAction")
+		hparseaction_p_t = hparseaction_t.pointer()
+		p_env = parser_val['env'].cast(hparseaction_p_t).dereference()
 
 		#member_parser_p = gdb.parse_and_eval("((HParseAction*) parser->env)->p")
-		member_parser_p = gdb.Value(parser.address).cast(parser_p_t) #TODO: shuffling around pointers may not be necessary after all, if using Value objects
+		member_parser_p = p_env['p'] #TODO: shuffling around pointers may not be necessary after all, if using Value objects
 		parser_obj = top_level_parse.add_or_get_parser(member_parser_p)
 		if parser_obj.name is None:
 			parser_obj.name_parser( self.name_from_vtable(parser_obj) )
 		self.member_parser = parser_obj
 
-		# should return a HAction
-		action = gdb.parse_and_eval("((HParseAction*) parser->env)->action")
+		#action = gdb.parse_and_eval("((HParseAction*) parser->env)->action")
+		action = p_env['action']
 		self.action = int(action)
-		user_data_p = gdb.parse_and_eval("((HParseAction*) parser->env)->user_data")
+		#user_data_p = gdb.parse_and_eval("((HParseAction*) parser->env)->user_data")
+		user_data_p = p_env['user_data']
 		self.user_data_p = int(user_data_p)
 
 	def __str__(self):
@@ -192,13 +216,15 @@ class ActionEnv(HParserEnv):
 class AndEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
+		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
 
-		member_parser_p = gdb.parse_and_eval("(HParser*) parser->env")
+		#member_parser_p = gdb.parse_and_eval("(HParser*) parser->env")
+		member_parser_p = parser_val['env'].cast(self.hparser_p_t)
 		parser_obj = top_level_parse.add_or_get_parser(member_parser_p)
 		if parser_obj.name is None:
 			parser_obj.name_parser( self.name_from_vtable(parser_obj) )
 		self.member_parser = parser_obj
-		super().__init__(parser, top_level_parse)
 
 	def __str__(self):
 		return str([str(self.member_parser)])
@@ -206,10 +232,13 @@ class AndEnv(HParserEnv):
 class ChEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
+		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
+		uint8_t = gdb.lookup_type("uint8_t")
 
-		self.ch_arg = gdb.parse_and_eval("(uint8_t) parser->env")
+		#self.ch_arg = gdb.parse_and_eval("(uint8_t) parser->env")
+		self.ch_arg = parser_val['env'].cast(uint8_t)
 		self.ch_value = int(self.ch_arg)
-		super().__init__(parser, top_level_parse)
 
 	def __str__(self):
 		return str(self.ch_value)
@@ -217,28 +246,27 @@ class ChEnv(HParserEnv):
 class CharsetEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
-
-		self.charset_arg = gdb.parse_and_eval("(HCharset) parser->env")
 		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
+		hcharset_t = gdb.lookup_type("HCharset")
+
+		#self.charset_arg = gdb.parse_and_eval("(HCharset) parser->env")
+		self.charset_arg = parser_val['env'].cast(hcharset_t)
 
 	def __str__(self):
 		return str(self.charset_arg)
 
-# TODO: this assumes the parser parameter passed to init and the parser value returned by GDB are the same
-# they should be, but parse_and_eval could be removed entirely if the code just used the parameter
-# This would also make initialization independent of being at specific breakpoints when executing
 class ChoiceEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		super().__init__(parser, top_level_parse)
 		self.parser = parser
 		self.member_parsers = []
+		parser_obj = gdb.Value(parser).cast(self.hparser_p_t).dereference()
 
 		#frame = gdb.selected_frame()
 		h_sequence_t = gdb.lookup_type("HSequence")
 		h_sequence_p_t = h_sequence_t.pointer()
 
-		# Get the parser object
-		parser_obj = gdb.parse_and_eval("*parser")
 		# Get parser_obj.env, cast it to HSequence *, then dereference
 		p_env = parser_obj['env'].cast(h_sequence_p_t).dereference()
 		# Get length of HSequence
@@ -260,14 +288,20 @@ class DifferenceEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
+		htwoparsers_t = gdb.lookup_type("HTwoParsers")
+		htwoparsers_p_t = htwoparsers_t.pointer()
+		p_env = parser_val['env'].cast(htwoparsers_p_t).dereference()
 
 		#TODO: maybe have a class for HTwoParsers-based envs
-		p1_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p1")
+		#p1_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p1")
+		p1_p = p_env['p1']
 		p1_obj = top_level_parse.add_or_get_parser(p1_p)
 		if p1_obj.name is None:
 			p1_obj.name_parser( self.name_from_vtable(p1_obj) )
 		self.p1 = p1_obj
-		p2_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p2")
+		#p2_p = gdb.parse_and_eval("((HTwoParsers *) parser->env)->p2")
+		p2_p = p_env['p2']
 		p2_obj = top_level_parse.add_or_get_parser(p2_p)
 		if p2_obj.name is None:
 			p2_obj.name_parser( self.name_from_vtable(p2_obj) )
@@ -288,13 +322,19 @@ class EndiannessEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
+		hparseendianness_t = gdb.lookup_type("HParseEndianness")
+		hparseendianness_p_t = hparseendianness_t.pointer()
+		p_env = parser_val['env'].cast(hparseendianness_p_t).dereference()
 
-		member_parser_p = gdb.parse_and_eval("((HParseEndianness *) parser->env)->p")
+		#member_parser_p = gdb.parse_and_eval("((HParseEndianness *) parser->env)->p")
+		member_parser_p = p_env['p']
 		parser_obj = top_level_parse.add_or_get_parser(member_parser_p)
 		if parser_obj.name is None:
 			parser_obj.name_parser( self.name_from_vtable(parser_obj) )
 		self.member_parser = parser_obj
-		endianness_val = gdb.parse_and_eval("((HParseEndianness *) parser->env)->endianness")
+		#endianness_val = gdb.parse_and_eval("((HParseEndianness *) parser->env)->endianness")
+		endianness_val = p_env['endianness']
 		self.endianness = int(endianness_val)
 
 	def __str__(self):
@@ -312,8 +352,10 @@ class IgnoreEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		super().__init__(parser, top_level_parse)
+		parser_val = gdb.Value(parser).cast(self.hparser_p_t).dereference()
 
-		ignored_p = gdb.parse_and_eval("(HParser*) parser->env")
+		#ignored_p = gdb.parse_and_eval("(HParser*) parser->env")
+		ignored_p = parser_val['env'].cast(self.hparser_p_t)
 
 		ignore_obj = top_level_parse.add_or_get_parser(ignored_p)
 		if ignore_obj.name is None:
@@ -323,25 +365,24 @@ class IgnoreEnv(HParserEnv):
 	def __str__(self):
 		return str([str(self.member_parser)])
 
-# TODO: numeric parameter passed to parse_and_eval
 class IgnoreSeqEnv(HParserEnv):
 	def __init__(self, parser, top_level_parse):
 		self.parser = parser
 		self.member_parsers = []
+		super().__init__(parser, top_level_parse)
 
-		h_ignoreseq_t = gdb.lookup_type("HIgnoreSeq")
-		h_ignoreseq_p_t = h_ignoreseq_t.pointer()
+		hignoreseq_t = gdb.lookup_type("HIgnoreSeq")
+		hignoreseq_p_t = h_ignoreseq_t.pointer()
 
 		parser_obj = gdb.parse_and_eval("*parser")
-		p_env = parser_obj['env'].cast(h_ignoreseq_p_t).dereference()
-		ignoreseq_p = gdb.parse_and_eval("(HIgnoreSeq*) parser->env")
+		p_env = parser_obj['env'].cast(hignoreseq_p_t).dereference()
+		#ignoreseq_p = gdb.parse_and_eval("(HIgnoreSeq*) parser->env")
 		#seq_len = gdb.parse_and_eval("((HIgnoreSeq*) parser->env)->len")
 		seq_len = p_env['len']
 		#which = gdb.parse_and_eval("((HIgnoreSeq*) parser->env)->which")
 		which = p_env['which']
 		self.which = int(which)
 		parsers = p_env['parsers']
-		super().__init__(parser, top_level_parse)
 
 		for index in range(0, seq_len):
 			parser_p = parsers[index]