Skip to content

Commit

Permalink
Fix generation of some packets
Browse files Browse the repository at this point in the history
There are more lambdas used in serialization now.  Unfortunately this approach doesn't seem to work too well, and I will probably want to change stringify_invokedynamic further.
  • Loading branch information
Pokechu22 committed Feb 17, 2022
1 parent b8ba24a commit 9b9ace8
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
22 changes: 21 additions & 1 deletion burger/toppings/packetinstructions.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,26 @@ def operations(classloader, classname, classes, verbose, args=None,
operations.append(Operation(instruction.pos, "write",
type="nbtcompound",
field=field))
elif arg_type == "java/util/Collection" and \
descriptor.args[1].name == "java/util/function/BiConsumer":
# Loop that calls the consumer with the packetbuffer
# and value for each value in collection
operations.append(Operation(instruction.pos, "store",
type="Iterator",
var="it",
value=field.value + ".iterator()"))
# TODO: inline the referenced function - would require
# changing how stringify_invokedynamic works
target = arguments[1][:arguments[1].find(":")]
name2 = arguments[1][arguments[1].rfind(":")+1:]
operations.append(Operation(instruction.pos, "loop",
condition="it.hasNext()"))
operations.append(Operation(instruction.pos, "interfacecall",
type="dynamic",
target=target, name=name,
method=name, field=target,
args="buf, it.next()"))
operations.append(Operation(instruction.pos, "endloop"))
else:
raise Exception("Unexpected descriptor " + desc)
else:
Expand Down Expand Up @@ -400,7 +420,7 @@ def operations(classloader, classname, classes, verbose, args=None,
break

elif mnemonic == "invokedynamic":
stack.append(stringify_invokedynamic(stack.pop(), instruction, cf))
stack.append(stringify_invokedynamic(stack, instruction, cf))

# Conditional statements and loops
elif mnemonic.startswith("if"):
Expand Down
17 changes: 13 additions & 4 deletions burger/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ def class_from_invokedynamic(ins, cf):
assert desc.returns.name != "void"
return desc.returns.name

def stringify_invokedynamic(obj, ins, cf):
def stringify_invokedynamic(stack, ins, cf):
"""
Converts an invokedynamic instruction into a string.
This is a rather limited implementation for now, only handling obj::method.
This is a rather limited implementation for now, only handling obj::method
and Class::method.
"""
const = cf.constants[ins.operands[0].value] # Hack due to packetinstructions not expanding constants
bootstrap = cf.bootstrap_methods[const.method_attr_index]
Expand All @@ -61,10 +62,18 @@ def stringify_invokedynamic(obj, ins, cf):
assert len(bootstrap.bootstrap_args) == 3 # Num arguments
# Actual implementation.
methodhandle = cf.constants.get(bootstrap.bootstrap_args[1])
if methodhandle.reference_kind == 7: # REF_invokeSpecial
return "%s::%s" % (obj, methodhandle.reference.name_and_type.name.value)
if methodhandle.reference_kind == 5: # REF_invokeVirtual
target = stack.pop()
name = methodhandle.reference.name_and_type.name.value
elif methodhandle.reference_kind == 6: # REF_invokeStatic
target = methodhandle.reference.class_.name.value
name = methodhandle.reference.name_and_type.name.value
elif methodhandle.reference_kind == 7: # REF_invokeSpecial
target = stack.pop()
name = methodhandle.reference.name_and_type.name.value
else:
raise Exception("Unhandled reference_kind %d" % methodhandle.reference_kind)
return "%s::%s" % (target, name)

def try_eval_lambda(ins, args, cf):
"""
Expand Down

0 comments on commit 9b9ace8

Please sign in to comment.