From 6b0435348d0fe3a4276d3c630b3483048a307b4a Mon Sep 17 00:00:00 2001 From: Michael Wekesa Date: Sat, 11 Nov 2023 13:33:27 +0300 Subject: [PATCH] add array support for JDWP DSL (#74) * add array support for JDWP DSL * fix schema bugs * update arraytype in AllClasses command * update arraytype in AllClasses command remove error type * fix out and reply mismatch --- .../jdwp/defs/command_sets/virtual_machine.py | 64 +++++++++++++++++++ projects/jdwp/defs/schema.py | 33 +++++++--- 2 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 projects/jdwp/defs/command_sets/virtual_machine.py diff --git a/projects/jdwp/defs/command_sets/virtual_machine.py b/projects/jdwp/defs/command_sets/virtual_machine.py new file mode 100644 index 0000000..573b9ac --- /dev/null +++ b/projects/jdwp/defs/command_sets/virtual_machine.py @@ -0,0 +1,64 @@ +# Copyright (c) Meta Platforms, Inc. and affiliates. + +"""JDWP Commands for ThreadReference Command Set.""" + +from projects.jdwp.defs.schema import ( + Command, + Field, + Struct, + Type, + Array, + CommandSet, + ArrayLength, + IntegralType, +) +from projects.jdwp.defs.constants import ErrorType + + +__AllClasses_reply_classes = Field( + "classes", + ArrayLength(IntegralType.INT), + "Number of reference type that follow", +) + + +__AllClasses_reply_classesArray_element = Struct( + [ + Field("refTypeTag", IntegralType.BYTE, "Kind of following reference type"), + Field("typeID", Type.REFERENCE_TYPE_ID, "Loaded reference type"), + Field( + "signature", Type.STRING, "The JNI signature of the loaded reference type" + ), + Field("status", IntegralType.INT, "The current class status"), + ] +) + +__AllClasses_reply = Struct( + [ + __AllClasses_reply_classes, + Field( + "classesArray", + Array(__AllClasses_reply_classesArray_element, __AllClasses_reply_classes), + "Array of reference type.", + ), + ] +) + +AllClasses = Command( + name="AllClasses", + id=3, + out=None, + reply=__AllClasses_reply, + error={ + ErrorType.VM_DEAD, + }, +) + + +VirtualMachine = CommandSet( + name="VirtualMachine", + id=1, + commands=[ + AllClasses, + ], +) diff --git a/projects/jdwp/defs/schema.py b/projects/jdwp/defs/schema.py index 49b6c83..176cfb3 100644 --- a/projects/jdwp/defs/schema.py +++ b/projects/jdwp/defs/schema.py @@ -2,8 +2,9 @@ """Basic types for JDWP messages.""" +from __future__ import annotations from dataclasses import dataclass -from typing import Optional +from typing import Optional, Generic, TypeVar from enum import Enum from collections.abc import Set, Sequence @@ -14,8 +15,6 @@ class PrimitiveType(Enum): """Primitive type class.""" STRING = "string" - INT = "int" - BYTE = "byte" BOOLEAN = "boolean" DICT = "dict" REFERENCE_TYPE_ID = "referenceTypeID" @@ -32,10 +31,26 @@ class PrimitiveType(Enum): LOCATION = "location" -class Array(Enum): +class IntegralType(Enum): + """Integral type class.""" + + INT = "int" + BYTE = "byte" + + +@dataclass(frozen=True) +class ArrayLength: + """Array length class.""" + + type: IntegralType + + +@dataclass(frozen=True) +class Array: """Array class type.""" - pass + element_type: Struct + length: Field[ArrayLength] class TaggedUnion(Enum): @@ -44,15 +59,17 @@ class TaggedUnion(Enum): pass -Type = PrimitiveType | Array | TaggedUnion +Type = PrimitiveType | Array | TaggedUnion | IntegralType | ArrayLength + +T = TypeVar("T", bound=Type) @dataclass(frozen=True) -class Field: +class Field(Generic[T]): """Field class.""" name: str - type: Type + type: T description: str