mirror of https://github.com/alibaba/arthas.git
Merge remote-tracking branch 'origin/master' into object-view-model
commit
226bdce059
@ -0,0 +1,55 @@
|
|||||||
|
name: build vmtool
|
||||||
|
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
runs-on: ubuntu-18.04
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up JDK 8
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '8'
|
||||||
|
distribution: 'adopt'
|
||||||
|
- name: Build with Maven
|
||||||
|
run: ./mvnw package
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: lib
|
||||||
|
path: arthas-vmtool/target/lib*
|
||||||
|
|
||||||
|
mac:
|
||||||
|
runs-on: macos-10.15
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up JDK 8
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '8'
|
||||||
|
distribution: 'adopt'
|
||||||
|
- name: Build with Maven
|
||||||
|
run: ./mvnw package
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: lib
|
||||||
|
path: arthas-vmtool/target/lib*
|
||||||
|
|
||||||
|
windows:
|
||||||
|
runs-on: windows-2016
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up JDK 8
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
java-version: '8'
|
||||||
|
distribution: 'adopt'
|
||||||
|
- name: Build with Maven
|
||||||
|
run: ./mvnw package
|
||||||
|
- uses: actions/upload-artifact@v2
|
||||||
|
with:
|
||||||
|
name: lib
|
||||||
|
path: arthas-vmtool/target/*.dll
|
@ -0,0 +1,34 @@
|
|||||||
|
name: release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- "arthas-all-*"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
java: [8]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup java
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: ${{ matrix.java }}
|
||||||
|
- name: Build with Maven
|
||||||
|
run: mvn clean package -P full
|
||||||
|
|
||||||
|
- name: Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
|
with:
|
||||||
|
files: |
|
||||||
|
packaging/target/*.zip
|
||||||
|
packaging/target/*.deb
|
||||||
|
packaging/target/*.rpm
|
||||||
|
tunnel-server/target/*fatjar.jar
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
@ -0,0 +1,43 @@
|
|||||||
|
name: JavaCI
|
||||||
|
|
||||||
|
on: [push, pull_request]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
java: [7, 8, 9, 10, 11 ]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup java
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: ${{ matrix.java }}
|
||||||
|
- name: Build with Maven
|
||||||
|
run: mvn clean package -P full
|
||||||
|
|
||||||
|
build_jdk_ge_12:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
java: [12, 13, 14 ]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Set up JDK 1.8
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: 8
|
||||||
|
- name: save java8 home
|
||||||
|
run: |
|
||||||
|
export JAVA8_HOME=$JAVA_HOME && echo $JAVA8_HOME
|
||||||
|
echo "export JAVA8_HOME=$JAVA_HOME" > ~/.testenv
|
||||||
|
|
||||||
|
- name: Setup java
|
||||||
|
uses: actions/setup-java@v1
|
||||||
|
with:
|
||||||
|
java-version: ${{ matrix.java }}
|
||||||
|
- name: Build with Maven
|
||||||
|
run: |
|
||||||
|
source ~/.testenv
|
||||||
|
mvn -Dmaven.compiler.fork=true -Dmaven.compiler.executable=$JAVA8_HOME/bin/javac -DJAVA8_HOME=$JAVA8_HOME clean package -P full
|
Binary file not shown.
@ -1 +1,2 @@
|
|||||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
|
||||||
|
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
||||||
|
@ -0,0 +1,157 @@
|
|||||||
|
### Known Users
|
||||||
|
|
||||||
|
Welcome to register the company name in this issue: https://github.com/alibaba/arthas/issues/111 (in order of registration)
|
||||||
|
|
||||||
|
![Alibaba](static/alibaba.png)
|
||||||
|
![Alipay](static/alipay.png)
|
||||||
|
![Aliyun](static/aliyun.png)
|
||||||
|
![Taobao](static/taobao.png)
|
||||||
|
![Tmall](static/tmall.png)
|
||||||
|
![微医](static/weiyi.png)
|
||||||
|
![卓越教育](static/zhuoyuejiaoyu.png)
|
||||||
|
![狐狸金服](static/hulijingfu.png)
|
||||||
|
![三体云](static/santiyun.png)
|
||||||
|
![证大文化](static/zhengdawenhua.png)
|
||||||
|
![连连支付](static/lianlianpay.png)
|
||||||
|
![Acmedcare+](static/acmedcare.png)
|
||||||
|
![好慷](static/homeking365_log.png)
|
||||||
|
![来电科技](static/laidian.png)
|
||||||
|
![四格互联](static/sigehulian.png)
|
||||||
|
![ICBC](static/icbc.png)
|
||||||
|
![陆鹰](static/luying.png)
|
||||||
|
![玩友时代](static/wangyoushidai.png)
|
||||||
|
![她社区](static/tashequ.png)
|
||||||
|
![龙腾出行](static/longtengchuxing.png)
|
||||||
|
![foscam](static/foscam.png)
|
||||||
|
![二维火](static/2dfire.png)
|
||||||
|
![lanxum](static/lanxum_com.png)
|
||||||
|
![纳里健康](static/ngarihealth.png)
|
||||||
|
![掌门1对1](static/zhangmen.png)
|
||||||
|
![offcn](static/offcn.png)
|
||||||
|
![sia](static/sia.png)
|
||||||
|
![振安资产](static/zhenganzichang.png)
|
||||||
|
![菠萝](static/bolo.png)
|
||||||
|
![中通快递](static/zto.png)
|
||||||
|
![光点科技](static/guangdian.png)
|
||||||
|
![广州工程技术职业学院](static/gzvtc.jpg)
|
||||||
|
![mstar](static/mstar.png)
|
||||||
|
![xwbank](static/xwbank.png)
|
||||||
|
![imexue](static/imexue.png)
|
||||||
|
![keking](static/keking.png)
|
||||||
|
![secoo](static/secoo.jpg)
|
||||||
|
![viax](static/viax.png)
|
||||||
|
![yanedu](static/yanedu.png)
|
||||||
|
![duia](static/duia.png)
|
||||||
|
![哈啰出行](static/hellobike.png)
|
||||||
|
![hollycrm](static/hollycrm.png)
|
||||||
|
![citycloud](static/citycloud.jpg)
|
||||||
|
![yidianzixun](static/yidianzixun.png)
|
||||||
|
![神州租车](static/zuche.png)
|
||||||
|
![天眼查](static/tianyancha.png)
|
||||||
|
![商脉云](static/anjianyun.png)
|
||||||
|
![三新文化](static/sanxinbook.png)
|
||||||
|
![雪球财经](static/xueqiu.png)
|
||||||
|
![百安居](static/bthome.png)
|
||||||
|
![安心保险](static/95303.png)
|
||||||
|
![杭州源诚科技](static/hzyc.png)
|
||||||
|
![91moxie](static/91moxie.png)
|
||||||
|
![智慧开源](static/wisdom.png)
|
||||||
|
![富佳科技](static/fujias.png)
|
||||||
|
![鼎尖软件](static/dingjiansoft.png)
|
||||||
|
![广通软件](static/broada.png)
|
||||||
|
![九鼎瑞信](static/evercreative.jpg)
|
||||||
|
![小米有品](static/xiaomiyoupin.png)
|
||||||
|
![欧冶云商](static/ouyeel.png)
|
||||||
|
![投投科技](static/toutou.png)
|
||||||
|
![饿了么](static/ele.png)
|
||||||
|
![58同城](static/58.png)
|
||||||
|
![上海浪沙](static/runsa.png)
|
||||||
|
![符律科技](static/fhldtech.png)
|
||||||
|
![顺丰科技](static/sf.png)
|
||||||
|
![新致软件](static/newtouch.png)
|
||||||
|
![北京华宇信息](static/thunisoft.png)
|
||||||
|
![太平洋保险](static/cpic.png)
|
||||||
|
![旅享网络](static/risingch.png)
|
||||||
|
![水滴互联](static/shuidihuzhu.png)
|
||||||
|
![贝壳找房](static/ke.png)
|
||||||
|
![嘟嘟牛](static/dodonew.png)
|
||||||
|
![云幂信息](static/yunmixinxi.png)
|
||||||
|
![随手科技](static/sui.png)
|
||||||
|
![妈妈去哪儿](static/mamaqunaer.jpg)
|
||||||
|
![云实信息](static/realscloud.png)
|
||||||
|
![BBD数联铭品](static/bbdservice.png)
|
||||||
|
![伙伴集团](static/zhaoshang800.png)
|
||||||
|
![数梦工场](static/dtdream.png)
|
||||||
|
![安恒信息](static/dbappsecurity.png)
|
||||||
|
![亚信科技](static/asiainfo.png)
|
||||||
|
![云舒写](static/yunshuxie.png)
|
||||||
|
![微住](static/iweizhu.png)
|
||||||
|
![月亮小屋](static/bluemoon.png)
|
||||||
|
![大搜车](static/souche.png)
|
||||||
|
![今日图书](static/jinritushu.png)
|
||||||
|
![竹间智能](static/emotibot.png)
|
||||||
|
![数字认证](static/bjca.png)
|
||||||
|
![360金融](static/360jinrong.png)
|
||||||
|
![安居客](static/anjuke.jpg)
|
||||||
|
![qunar](static/qunar.png)
|
||||||
|
![ctrip](static/ctrip.png)
|
||||||
|
![Tuniu](static/tuniu.png)
|
||||||
|
![多点](static/dmall.jpg)
|
||||||
|
![转转](static/zhuanzhuan.jpg)
|
||||||
|
![金蝶](static/kingdee.jpg)
|
||||||
|
![华清飞扬](static/sincetimes.jpg)
|
||||||
|
![神奇视角](static/fasterar.jpg)
|
||||||
|
![南京昂克软件](static/angke.jpg)
|
||||||
|
![网盛生意宝](static/netsun.jpg)
|
||||||
|
![北京登云美业网络](static/idengyun.jpg)
|
||||||
|
![Holder](static/holder.png)
|
||||||
|
![立林科技](static/leelen.png)
|
||||||
|
![爱成长](static/aichengzhang.png)
|
||||||
|
![嘉云数据](static/clubfactory.png)
|
||||||
|
![百草味](static/bcw.png)
|
||||||
|
![青岛优米](static/youmi.png)
|
||||||
|
![紫光软件](static/unis.png)
|
||||||
|
![拓保软件](static/tobosoft.png)
|
||||||
|
![海信集团](static/hisense.png)
|
||||||
|
![小红唇](static/xiaohongchun.png)
|
||||||
|
![上海恺英](static/kaiying.png)
|
||||||
|
![上海慧力](static/xiaohuasheng.png)
|
||||||
|
![上海喔噻](static/shouqingba.png)
|
||||||
|
![vipkid](static/vipkid.png)
|
||||||
|
![宇中科技](static/yuzhong.png)
|
||||||
|
![蘑菇财富](static/mogu.jpg)
|
||||||
|
![喔趣科技](static/woqu.png)
|
||||||
|
![百度凤巢](static/baidufengchao.png)
|
||||||
|
![喜百年供应链科技](static/xbn.png)
|
||||||
|
![折耳根科技](static/zheergen.png)
|
||||||
|
![qdama](static/qdm_logo.png)
|
||||||
|
![有赞](static/youzan.png)
|
||||||
|
![中原银行](static/zhongyuanbank.png)
|
||||||
|
![CVTE](static/cvte.png)
|
||||||
|
|
||||||
|
* 网易云
|
||||||
|
* 派迩信息技术
|
||||||
|
* 朴新教育
|
||||||
|
* OK智慧教育
|
||||||
|
* 云集
|
||||||
|
* 业余草科技
|
||||||
|
* 家家顺
|
||||||
|
* 兰亮
|
||||||
|
* 浪潮集团
|
||||||
|
* 福建博思软件
|
||||||
|
* OPPO
|
||||||
|
* 中科软科技
|
||||||
|
* 大搜车
|
||||||
|
* 泰豪软件
|
||||||
|
* 中房
|
||||||
|
* 安恒信息
|
||||||
|
* 武汉力龙
|
||||||
|
* 埃欧体科技
|
||||||
|
* 创维
|
||||||
|
* 启迪出行
|
||||||
|
* 大华股份
|
||||||
|
* 黄豆伟业
|
||||||
|
* 中国有赞
|
||||||
|
* 车巴达
|
||||||
|
* 华为
|
||||||
|
* 云管书
|
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
package arthas;
|
@ -0,0 +1,560 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CLASSFILE_CONSTANTS_H
|
||||||
|
#define CLASSFILE_CONSTANTS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Classfile version number for this information */
|
||||||
|
#define JVM_CLASSFILE_MAJOR_VERSION 52
|
||||||
|
#define JVM_CLASSFILE_MINOR_VERSION 0
|
||||||
|
|
||||||
|
/* Flags */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JVM_ACC_PUBLIC = 0x0001,
|
||||||
|
JVM_ACC_PRIVATE = 0x0002,
|
||||||
|
JVM_ACC_PROTECTED = 0x0004,
|
||||||
|
JVM_ACC_STATIC = 0x0008,
|
||||||
|
JVM_ACC_FINAL = 0x0010,
|
||||||
|
JVM_ACC_SYNCHRONIZED = 0x0020,
|
||||||
|
JVM_ACC_SUPER = 0x0020,
|
||||||
|
JVM_ACC_VOLATILE = 0x0040,
|
||||||
|
JVM_ACC_BRIDGE = 0x0040,
|
||||||
|
JVM_ACC_TRANSIENT = 0x0080,
|
||||||
|
JVM_ACC_VARARGS = 0x0080,
|
||||||
|
JVM_ACC_NATIVE = 0x0100,
|
||||||
|
JVM_ACC_INTERFACE = 0x0200,
|
||||||
|
JVM_ACC_ABSTRACT = 0x0400,
|
||||||
|
JVM_ACC_STRICT = 0x0800,
|
||||||
|
JVM_ACC_SYNTHETIC = 0x1000,
|
||||||
|
JVM_ACC_ANNOTATION = 0x2000,
|
||||||
|
JVM_ACC_ENUM = 0x4000
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Used in newarray instruction. */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JVM_T_BOOLEAN = 4,
|
||||||
|
JVM_T_CHAR = 5,
|
||||||
|
JVM_T_FLOAT = 6,
|
||||||
|
JVM_T_DOUBLE = 7,
|
||||||
|
JVM_T_BYTE = 8,
|
||||||
|
JVM_T_SHORT = 9,
|
||||||
|
JVM_T_INT = 10,
|
||||||
|
JVM_T_LONG = 11
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Constant Pool Entries */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JVM_CONSTANT_Utf8 = 1,
|
||||||
|
JVM_CONSTANT_Unicode = 2, /* unused */
|
||||||
|
JVM_CONSTANT_Integer = 3,
|
||||||
|
JVM_CONSTANT_Float = 4,
|
||||||
|
JVM_CONSTANT_Long = 5,
|
||||||
|
JVM_CONSTANT_Double = 6,
|
||||||
|
JVM_CONSTANT_Class = 7,
|
||||||
|
JVM_CONSTANT_String = 8,
|
||||||
|
JVM_CONSTANT_Fieldref = 9,
|
||||||
|
JVM_CONSTANT_Methodref = 10,
|
||||||
|
JVM_CONSTANT_InterfaceMethodref = 11,
|
||||||
|
JVM_CONSTANT_NameAndType = 12,
|
||||||
|
JVM_CONSTANT_MethodHandle = 15, // JSR 292
|
||||||
|
JVM_CONSTANT_MethodType = 16, // JSR 292
|
||||||
|
JVM_CONSTANT_InvokeDynamic = 18
|
||||||
|
};
|
||||||
|
|
||||||
|
/* JVM_CONSTANT_MethodHandle subtypes */
|
||||||
|
enum {
|
||||||
|
JVM_REF_getField = 1,
|
||||||
|
JVM_REF_getStatic = 2,
|
||||||
|
JVM_REF_putField = 3,
|
||||||
|
JVM_REF_putStatic = 4,
|
||||||
|
JVM_REF_invokeVirtual = 5,
|
||||||
|
JVM_REF_invokeStatic = 6,
|
||||||
|
JVM_REF_invokeSpecial = 7,
|
||||||
|
JVM_REF_newInvokeSpecial = 8,
|
||||||
|
JVM_REF_invokeInterface = 9
|
||||||
|
};
|
||||||
|
|
||||||
|
/* StackMapTable type item numbers */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JVM_ITEM_Top = 0,
|
||||||
|
JVM_ITEM_Integer = 1,
|
||||||
|
JVM_ITEM_Float = 2,
|
||||||
|
JVM_ITEM_Double = 3,
|
||||||
|
JVM_ITEM_Long = 4,
|
||||||
|
JVM_ITEM_Null = 5,
|
||||||
|
JVM_ITEM_UninitializedThis = 6,
|
||||||
|
JVM_ITEM_Object = 7,
|
||||||
|
JVM_ITEM_Uninitialized = 8
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Type signatures */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JVM_SIGNATURE_ARRAY = '[',
|
||||||
|
JVM_SIGNATURE_BYTE = 'B',
|
||||||
|
JVM_SIGNATURE_CHAR = 'C',
|
||||||
|
JVM_SIGNATURE_CLASS = 'L',
|
||||||
|
JVM_SIGNATURE_ENDCLASS = ';',
|
||||||
|
JVM_SIGNATURE_ENUM = 'E',
|
||||||
|
JVM_SIGNATURE_FLOAT = 'F',
|
||||||
|
JVM_SIGNATURE_DOUBLE = 'D',
|
||||||
|
JVM_SIGNATURE_FUNC = '(',
|
||||||
|
JVM_SIGNATURE_ENDFUNC = ')',
|
||||||
|
JVM_SIGNATURE_INT = 'I',
|
||||||
|
JVM_SIGNATURE_LONG = 'J',
|
||||||
|
JVM_SIGNATURE_SHORT = 'S',
|
||||||
|
JVM_SIGNATURE_VOID = 'V',
|
||||||
|
JVM_SIGNATURE_BOOLEAN = 'Z'
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Opcodes */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JVM_OPC_nop = 0,
|
||||||
|
JVM_OPC_aconst_null = 1,
|
||||||
|
JVM_OPC_iconst_m1 = 2,
|
||||||
|
JVM_OPC_iconst_0 = 3,
|
||||||
|
JVM_OPC_iconst_1 = 4,
|
||||||
|
JVM_OPC_iconst_2 = 5,
|
||||||
|
JVM_OPC_iconst_3 = 6,
|
||||||
|
JVM_OPC_iconst_4 = 7,
|
||||||
|
JVM_OPC_iconst_5 = 8,
|
||||||
|
JVM_OPC_lconst_0 = 9,
|
||||||
|
JVM_OPC_lconst_1 = 10,
|
||||||
|
JVM_OPC_fconst_0 = 11,
|
||||||
|
JVM_OPC_fconst_1 = 12,
|
||||||
|
JVM_OPC_fconst_2 = 13,
|
||||||
|
JVM_OPC_dconst_0 = 14,
|
||||||
|
JVM_OPC_dconst_1 = 15,
|
||||||
|
JVM_OPC_bipush = 16,
|
||||||
|
JVM_OPC_sipush = 17,
|
||||||
|
JVM_OPC_ldc = 18,
|
||||||
|
JVM_OPC_ldc_w = 19,
|
||||||
|
JVM_OPC_ldc2_w = 20,
|
||||||
|
JVM_OPC_iload = 21,
|
||||||
|
JVM_OPC_lload = 22,
|
||||||
|
JVM_OPC_fload = 23,
|
||||||
|
JVM_OPC_dload = 24,
|
||||||
|
JVM_OPC_aload = 25,
|
||||||
|
JVM_OPC_iload_0 = 26,
|
||||||
|
JVM_OPC_iload_1 = 27,
|
||||||
|
JVM_OPC_iload_2 = 28,
|
||||||
|
JVM_OPC_iload_3 = 29,
|
||||||
|
JVM_OPC_lload_0 = 30,
|
||||||
|
JVM_OPC_lload_1 = 31,
|
||||||
|
JVM_OPC_lload_2 = 32,
|
||||||
|
JVM_OPC_lload_3 = 33,
|
||||||
|
JVM_OPC_fload_0 = 34,
|
||||||
|
JVM_OPC_fload_1 = 35,
|
||||||
|
JVM_OPC_fload_2 = 36,
|
||||||
|
JVM_OPC_fload_3 = 37,
|
||||||
|
JVM_OPC_dload_0 = 38,
|
||||||
|
JVM_OPC_dload_1 = 39,
|
||||||
|
JVM_OPC_dload_2 = 40,
|
||||||
|
JVM_OPC_dload_3 = 41,
|
||||||
|
JVM_OPC_aload_0 = 42,
|
||||||
|
JVM_OPC_aload_1 = 43,
|
||||||
|
JVM_OPC_aload_2 = 44,
|
||||||
|
JVM_OPC_aload_3 = 45,
|
||||||
|
JVM_OPC_iaload = 46,
|
||||||
|
JVM_OPC_laload = 47,
|
||||||
|
JVM_OPC_faload = 48,
|
||||||
|
JVM_OPC_daload = 49,
|
||||||
|
JVM_OPC_aaload = 50,
|
||||||
|
JVM_OPC_baload = 51,
|
||||||
|
JVM_OPC_caload = 52,
|
||||||
|
JVM_OPC_saload = 53,
|
||||||
|
JVM_OPC_istore = 54,
|
||||||
|
JVM_OPC_lstore = 55,
|
||||||
|
JVM_OPC_fstore = 56,
|
||||||
|
JVM_OPC_dstore = 57,
|
||||||
|
JVM_OPC_astore = 58,
|
||||||
|
JVM_OPC_istore_0 = 59,
|
||||||
|
JVM_OPC_istore_1 = 60,
|
||||||
|
JVM_OPC_istore_2 = 61,
|
||||||
|
JVM_OPC_istore_3 = 62,
|
||||||
|
JVM_OPC_lstore_0 = 63,
|
||||||
|
JVM_OPC_lstore_1 = 64,
|
||||||
|
JVM_OPC_lstore_2 = 65,
|
||||||
|
JVM_OPC_lstore_3 = 66,
|
||||||
|
JVM_OPC_fstore_0 = 67,
|
||||||
|
JVM_OPC_fstore_1 = 68,
|
||||||
|
JVM_OPC_fstore_2 = 69,
|
||||||
|
JVM_OPC_fstore_3 = 70,
|
||||||
|
JVM_OPC_dstore_0 = 71,
|
||||||
|
JVM_OPC_dstore_1 = 72,
|
||||||
|
JVM_OPC_dstore_2 = 73,
|
||||||
|
JVM_OPC_dstore_3 = 74,
|
||||||
|
JVM_OPC_astore_0 = 75,
|
||||||
|
JVM_OPC_astore_1 = 76,
|
||||||
|
JVM_OPC_astore_2 = 77,
|
||||||
|
JVM_OPC_astore_3 = 78,
|
||||||
|
JVM_OPC_iastore = 79,
|
||||||
|
JVM_OPC_lastore = 80,
|
||||||
|
JVM_OPC_fastore = 81,
|
||||||
|
JVM_OPC_dastore = 82,
|
||||||
|
JVM_OPC_aastore = 83,
|
||||||
|
JVM_OPC_bastore = 84,
|
||||||
|
JVM_OPC_castore = 85,
|
||||||
|
JVM_OPC_sastore = 86,
|
||||||
|
JVM_OPC_pop = 87,
|
||||||
|
JVM_OPC_pop2 = 88,
|
||||||
|
JVM_OPC_dup = 89,
|
||||||
|
JVM_OPC_dup_x1 = 90,
|
||||||
|
JVM_OPC_dup_x2 = 91,
|
||||||
|
JVM_OPC_dup2 = 92,
|
||||||
|
JVM_OPC_dup2_x1 = 93,
|
||||||
|
JVM_OPC_dup2_x2 = 94,
|
||||||
|
JVM_OPC_swap = 95,
|
||||||
|
JVM_OPC_iadd = 96,
|
||||||
|
JVM_OPC_ladd = 97,
|
||||||
|
JVM_OPC_fadd = 98,
|
||||||
|
JVM_OPC_dadd = 99,
|
||||||
|
JVM_OPC_isub = 100,
|
||||||
|
JVM_OPC_lsub = 101,
|
||||||
|
JVM_OPC_fsub = 102,
|
||||||
|
JVM_OPC_dsub = 103,
|
||||||
|
JVM_OPC_imul = 104,
|
||||||
|
JVM_OPC_lmul = 105,
|
||||||
|
JVM_OPC_fmul = 106,
|
||||||
|
JVM_OPC_dmul = 107,
|
||||||
|
JVM_OPC_idiv = 108,
|
||||||
|
JVM_OPC_ldiv = 109,
|
||||||
|
JVM_OPC_fdiv = 110,
|
||||||
|
JVM_OPC_ddiv = 111,
|
||||||
|
JVM_OPC_irem = 112,
|
||||||
|
JVM_OPC_lrem = 113,
|
||||||
|
JVM_OPC_frem = 114,
|
||||||
|
JVM_OPC_drem = 115,
|
||||||
|
JVM_OPC_ineg = 116,
|
||||||
|
JVM_OPC_lneg = 117,
|
||||||
|
JVM_OPC_fneg = 118,
|
||||||
|
JVM_OPC_dneg = 119,
|
||||||
|
JVM_OPC_ishl = 120,
|
||||||
|
JVM_OPC_lshl = 121,
|
||||||
|
JVM_OPC_ishr = 122,
|
||||||
|
JVM_OPC_lshr = 123,
|
||||||
|
JVM_OPC_iushr = 124,
|
||||||
|
JVM_OPC_lushr = 125,
|
||||||
|
JVM_OPC_iand = 126,
|
||||||
|
JVM_OPC_land = 127,
|
||||||
|
JVM_OPC_ior = 128,
|
||||||
|
JVM_OPC_lor = 129,
|
||||||
|
JVM_OPC_ixor = 130,
|
||||||
|
JVM_OPC_lxor = 131,
|
||||||
|
JVM_OPC_iinc = 132,
|
||||||
|
JVM_OPC_i2l = 133,
|
||||||
|
JVM_OPC_i2f = 134,
|
||||||
|
JVM_OPC_i2d = 135,
|
||||||
|
JVM_OPC_l2i = 136,
|
||||||
|
JVM_OPC_l2f = 137,
|
||||||
|
JVM_OPC_l2d = 138,
|
||||||
|
JVM_OPC_f2i = 139,
|
||||||
|
JVM_OPC_f2l = 140,
|
||||||
|
JVM_OPC_f2d = 141,
|
||||||
|
JVM_OPC_d2i = 142,
|
||||||
|
JVM_OPC_d2l = 143,
|
||||||
|
JVM_OPC_d2f = 144,
|
||||||
|
JVM_OPC_i2b = 145,
|
||||||
|
JVM_OPC_i2c = 146,
|
||||||
|
JVM_OPC_i2s = 147,
|
||||||
|
JVM_OPC_lcmp = 148,
|
||||||
|
JVM_OPC_fcmpl = 149,
|
||||||
|
JVM_OPC_fcmpg = 150,
|
||||||
|
JVM_OPC_dcmpl = 151,
|
||||||
|
JVM_OPC_dcmpg = 152,
|
||||||
|
JVM_OPC_ifeq = 153,
|
||||||
|
JVM_OPC_ifne = 154,
|
||||||
|
JVM_OPC_iflt = 155,
|
||||||
|
JVM_OPC_ifge = 156,
|
||||||
|
JVM_OPC_ifgt = 157,
|
||||||
|
JVM_OPC_ifle = 158,
|
||||||
|
JVM_OPC_if_icmpeq = 159,
|
||||||
|
JVM_OPC_if_icmpne = 160,
|
||||||
|
JVM_OPC_if_icmplt = 161,
|
||||||
|
JVM_OPC_if_icmpge = 162,
|
||||||
|
JVM_OPC_if_icmpgt = 163,
|
||||||
|
JVM_OPC_if_icmple = 164,
|
||||||
|
JVM_OPC_if_acmpeq = 165,
|
||||||
|
JVM_OPC_if_acmpne = 166,
|
||||||
|
JVM_OPC_goto = 167,
|
||||||
|
JVM_OPC_jsr = 168,
|
||||||
|
JVM_OPC_ret = 169,
|
||||||
|
JVM_OPC_tableswitch = 170,
|
||||||
|
JVM_OPC_lookupswitch = 171,
|
||||||
|
JVM_OPC_ireturn = 172,
|
||||||
|
JVM_OPC_lreturn = 173,
|
||||||
|
JVM_OPC_freturn = 174,
|
||||||
|
JVM_OPC_dreturn = 175,
|
||||||
|
JVM_OPC_areturn = 176,
|
||||||
|
JVM_OPC_return = 177,
|
||||||
|
JVM_OPC_getstatic = 178,
|
||||||
|
JVM_OPC_putstatic = 179,
|
||||||
|
JVM_OPC_getfield = 180,
|
||||||
|
JVM_OPC_putfield = 181,
|
||||||
|
JVM_OPC_invokevirtual = 182,
|
||||||
|
JVM_OPC_invokespecial = 183,
|
||||||
|
JVM_OPC_invokestatic = 184,
|
||||||
|
JVM_OPC_invokeinterface = 185,
|
||||||
|
JVM_OPC_invokedynamic = 186,
|
||||||
|
JVM_OPC_new = 187,
|
||||||
|
JVM_OPC_newarray = 188,
|
||||||
|
JVM_OPC_anewarray = 189,
|
||||||
|
JVM_OPC_arraylength = 190,
|
||||||
|
JVM_OPC_athrow = 191,
|
||||||
|
JVM_OPC_checkcast = 192,
|
||||||
|
JVM_OPC_instanceof = 193,
|
||||||
|
JVM_OPC_monitorenter = 194,
|
||||||
|
JVM_OPC_monitorexit = 195,
|
||||||
|
JVM_OPC_wide = 196,
|
||||||
|
JVM_OPC_multianewarray = 197,
|
||||||
|
JVM_OPC_ifnull = 198,
|
||||||
|
JVM_OPC_ifnonnull = 199,
|
||||||
|
JVM_OPC_goto_w = 200,
|
||||||
|
JVM_OPC_jsr_w = 201,
|
||||||
|
JVM_OPC_MAX = 201
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Opcode length initializer, use with something like:
|
||||||
|
* unsigned char opcode_length[JVM_OPC_MAX+1] = JVM_OPCODE_LENGTH_INITIALIZER;
|
||||||
|
*/
|
||||||
|
#define JVM_OPCODE_LENGTH_INITIALIZER { \
|
||||||
|
1, /* nop */ \
|
||||||
|
1, /* aconst_null */ \
|
||||||
|
1, /* iconst_m1 */ \
|
||||||
|
1, /* iconst_0 */ \
|
||||||
|
1, /* iconst_1 */ \
|
||||||
|
1, /* iconst_2 */ \
|
||||||
|
1, /* iconst_3 */ \
|
||||||
|
1, /* iconst_4 */ \
|
||||||
|
1, /* iconst_5 */ \
|
||||||
|
1, /* lconst_0 */ \
|
||||||
|
1, /* lconst_1 */ \
|
||||||
|
1, /* fconst_0 */ \
|
||||||
|
1, /* fconst_1 */ \
|
||||||
|
1, /* fconst_2 */ \
|
||||||
|
1, /* dconst_0 */ \
|
||||||
|
1, /* dconst_1 */ \
|
||||||
|
2, /* bipush */ \
|
||||||
|
3, /* sipush */ \
|
||||||
|
2, /* ldc */ \
|
||||||
|
3, /* ldc_w */ \
|
||||||
|
3, /* ldc2_w */ \
|
||||||
|
2, /* iload */ \
|
||||||
|
2, /* lload */ \
|
||||||
|
2, /* fload */ \
|
||||||
|
2, /* dload */ \
|
||||||
|
2, /* aload */ \
|
||||||
|
1, /* iload_0 */ \
|
||||||
|
1, /* iload_1 */ \
|
||||||
|
1, /* iload_2 */ \
|
||||||
|
1, /* iload_3 */ \
|
||||||
|
1, /* lload_0 */ \
|
||||||
|
1, /* lload_1 */ \
|
||||||
|
1, /* lload_2 */ \
|
||||||
|
1, /* lload_3 */ \
|
||||||
|
1, /* fload_0 */ \
|
||||||
|
1, /* fload_1 */ \
|
||||||
|
1, /* fload_2 */ \
|
||||||
|
1, /* fload_3 */ \
|
||||||
|
1, /* dload_0 */ \
|
||||||
|
1, /* dload_1 */ \
|
||||||
|
1, /* dload_2 */ \
|
||||||
|
1, /* dload_3 */ \
|
||||||
|
1, /* aload_0 */ \
|
||||||
|
1, /* aload_1 */ \
|
||||||
|
1, /* aload_2 */ \
|
||||||
|
1, /* aload_3 */ \
|
||||||
|
1, /* iaload */ \
|
||||||
|
1, /* laload */ \
|
||||||
|
1, /* faload */ \
|
||||||
|
1, /* daload */ \
|
||||||
|
1, /* aaload */ \
|
||||||
|
1, /* baload */ \
|
||||||
|
1, /* caload */ \
|
||||||
|
1, /* saload */ \
|
||||||
|
2, /* istore */ \
|
||||||
|
2, /* lstore */ \
|
||||||
|
2, /* fstore */ \
|
||||||
|
2, /* dstore */ \
|
||||||
|
2, /* astore */ \
|
||||||
|
1, /* istore_0 */ \
|
||||||
|
1, /* istore_1 */ \
|
||||||
|
1, /* istore_2 */ \
|
||||||
|
1, /* istore_3 */ \
|
||||||
|
1, /* lstore_0 */ \
|
||||||
|
1, /* lstore_1 */ \
|
||||||
|
1, /* lstore_2 */ \
|
||||||
|
1, /* lstore_3 */ \
|
||||||
|
1, /* fstore_0 */ \
|
||||||
|
1, /* fstore_1 */ \
|
||||||
|
1, /* fstore_2 */ \
|
||||||
|
1, /* fstore_3 */ \
|
||||||
|
1, /* dstore_0 */ \
|
||||||
|
1, /* dstore_1 */ \
|
||||||
|
1, /* dstore_2 */ \
|
||||||
|
1, /* dstore_3 */ \
|
||||||
|
1, /* astore_0 */ \
|
||||||
|
1, /* astore_1 */ \
|
||||||
|
1, /* astore_2 */ \
|
||||||
|
1, /* astore_3 */ \
|
||||||
|
1, /* iastore */ \
|
||||||
|
1, /* lastore */ \
|
||||||
|
1, /* fastore */ \
|
||||||
|
1, /* dastore */ \
|
||||||
|
1, /* aastore */ \
|
||||||
|
1, /* bastore */ \
|
||||||
|
1, /* castore */ \
|
||||||
|
1, /* sastore */ \
|
||||||
|
1, /* pop */ \
|
||||||
|
1, /* pop2 */ \
|
||||||
|
1, /* dup */ \
|
||||||
|
1, /* dup_x1 */ \
|
||||||
|
1, /* dup_x2 */ \
|
||||||
|
1, /* dup2 */ \
|
||||||
|
1, /* dup2_x1 */ \
|
||||||
|
1, /* dup2_x2 */ \
|
||||||
|
1, /* swap */ \
|
||||||
|
1, /* iadd */ \
|
||||||
|
1, /* ladd */ \
|
||||||
|
1, /* fadd */ \
|
||||||
|
1, /* dadd */ \
|
||||||
|
1, /* isub */ \
|
||||||
|
1, /* lsub */ \
|
||||||
|
1, /* fsub */ \
|
||||||
|
1, /* dsub */ \
|
||||||
|
1, /* imul */ \
|
||||||
|
1, /* lmul */ \
|
||||||
|
1, /* fmul */ \
|
||||||
|
1, /* dmul */ \
|
||||||
|
1, /* idiv */ \
|
||||||
|
1, /* ldiv */ \
|
||||||
|
1, /* fdiv */ \
|
||||||
|
1, /* ddiv */ \
|
||||||
|
1, /* irem */ \
|
||||||
|
1, /* lrem */ \
|
||||||
|
1, /* frem */ \
|
||||||
|
1, /* drem */ \
|
||||||
|
1, /* ineg */ \
|
||||||
|
1, /* lneg */ \
|
||||||
|
1, /* fneg */ \
|
||||||
|
1, /* dneg */ \
|
||||||
|
1, /* ishl */ \
|
||||||
|
1, /* lshl */ \
|
||||||
|
1, /* ishr */ \
|
||||||
|
1, /* lshr */ \
|
||||||
|
1, /* iushr */ \
|
||||||
|
1, /* lushr */ \
|
||||||
|
1, /* iand */ \
|
||||||
|
1, /* land */ \
|
||||||
|
1, /* ior */ \
|
||||||
|
1, /* lor */ \
|
||||||
|
1, /* ixor */ \
|
||||||
|
1, /* lxor */ \
|
||||||
|
3, /* iinc */ \
|
||||||
|
1, /* i2l */ \
|
||||||
|
1, /* i2f */ \
|
||||||
|
1, /* i2d */ \
|
||||||
|
1, /* l2i */ \
|
||||||
|
1, /* l2f */ \
|
||||||
|
1, /* l2d */ \
|
||||||
|
1, /* f2i */ \
|
||||||
|
1, /* f2l */ \
|
||||||
|
1, /* f2d */ \
|
||||||
|
1, /* d2i */ \
|
||||||
|
1, /* d2l */ \
|
||||||
|
1, /* d2f */ \
|
||||||
|
1, /* i2b */ \
|
||||||
|
1, /* i2c */ \
|
||||||
|
1, /* i2s */ \
|
||||||
|
1, /* lcmp */ \
|
||||||
|
1, /* fcmpl */ \
|
||||||
|
1, /* fcmpg */ \
|
||||||
|
1, /* dcmpl */ \
|
||||||
|
1, /* dcmpg */ \
|
||||||
|
3, /* ifeq */ \
|
||||||
|
3, /* ifne */ \
|
||||||
|
3, /* iflt */ \
|
||||||
|
3, /* ifge */ \
|
||||||
|
3, /* ifgt */ \
|
||||||
|
3, /* ifle */ \
|
||||||
|
3, /* if_icmpeq */ \
|
||||||
|
3, /* if_icmpne */ \
|
||||||
|
3, /* if_icmplt */ \
|
||||||
|
3, /* if_icmpge */ \
|
||||||
|
3, /* if_icmpgt */ \
|
||||||
|
3, /* if_icmple */ \
|
||||||
|
3, /* if_acmpeq */ \
|
||||||
|
3, /* if_acmpne */ \
|
||||||
|
3, /* goto */ \
|
||||||
|
3, /* jsr */ \
|
||||||
|
2, /* ret */ \
|
||||||
|
99, /* tableswitch */ \
|
||||||
|
99, /* lookupswitch */ \
|
||||||
|
1, /* ireturn */ \
|
||||||
|
1, /* lreturn */ \
|
||||||
|
1, /* freturn */ \
|
||||||
|
1, /* dreturn */ \
|
||||||
|
1, /* areturn */ \
|
||||||
|
1, /* return */ \
|
||||||
|
3, /* getstatic */ \
|
||||||
|
3, /* putstatic */ \
|
||||||
|
3, /* getfield */ \
|
||||||
|
3, /* putfield */ \
|
||||||
|
3, /* invokevirtual */ \
|
||||||
|
3, /* invokespecial */ \
|
||||||
|
3, /* invokestatic */ \
|
||||||
|
5, /* invokeinterface */ \
|
||||||
|
5, /* invokedynamic */ \
|
||||||
|
3, /* new */ \
|
||||||
|
2, /* newarray */ \
|
||||||
|
3, /* anewarray */ \
|
||||||
|
1, /* arraylength */ \
|
||||||
|
1, /* athrow */ \
|
||||||
|
3, /* checkcast */ \
|
||||||
|
3, /* instanceof */ \
|
||||||
|
1, /* monitorenter */ \
|
||||||
|
1, /* monitorexit */ \
|
||||||
|
0, /* wide */ \
|
||||||
|
4, /* multianewarray */ \
|
||||||
|
3, /* ifnull */ \
|
||||||
|
3, /* ifnonnull */ \
|
||||||
|
5, /* goto_w */ \
|
||||||
|
5 /* jsr_w */ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* CLASSFILE_CONSTANTS */
|
@ -0,0 +1,299 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JAVASOFT_JAWT_H_
|
||||||
|
#define _JAVASOFT_JAWT_H_
|
||||||
|
|
||||||
|
#include "jni.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AWT native interface (new in JDK 1.3)
|
||||||
|
*
|
||||||
|
* The AWT native interface allows a native C or C++ application a means
|
||||||
|
* by which to access native structures in AWT. This is to facilitate moving
|
||||||
|
* legacy C and C++ applications to Java and to target the needs of the
|
||||||
|
* community who, at present, wish to do their own native rendering to canvases
|
||||||
|
* for performance reasons. Standard extensions such as Java3D also require a
|
||||||
|
* means to access the underlying native data structures of AWT.
|
||||||
|
*
|
||||||
|
* There may be future extensions to this API depending on demand.
|
||||||
|
*
|
||||||
|
* A VM does not have to implement this API in order to pass the JCK.
|
||||||
|
* It is recommended, however, that this API is implemented on VMs that support
|
||||||
|
* standard extensions, such as Java3D.
|
||||||
|
*
|
||||||
|
* Since this is a native API, any program which uses it cannot be considered
|
||||||
|
* 100% pure java.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AWT Native Drawing Surface (JAWT_DrawingSurface).
|
||||||
|
*
|
||||||
|
* For each platform, there is a native drawing surface structure. This
|
||||||
|
* platform-specific structure can be found in jawt_md.h. It is recommended
|
||||||
|
* that additional platforms follow the same model. It is also recommended
|
||||||
|
* that VMs on Win32 and Solaris support the existing structures in jawt_md.h.
|
||||||
|
*
|
||||||
|
*******************
|
||||||
|
* EXAMPLE OF USAGE:
|
||||||
|
*******************
|
||||||
|
*
|
||||||
|
* In Win32, a programmer wishes to access the HWND of a canvas to perform
|
||||||
|
* native rendering into it. The programmer has declared the paint() method
|
||||||
|
* for their canvas subclass to be native:
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* MyCanvas.java:
|
||||||
|
*
|
||||||
|
* import java.awt.*;
|
||||||
|
*
|
||||||
|
* public class MyCanvas extends Canvas {
|
||||||
|
*
|
||||||
|
* static {
|
||||||
|
* System.loadLibrary("mylib");
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* public native void paint(Graphics g);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* myfile.c:
|
||||||
|
*
|
||||||
|
* #include "jawt_md.h"
|
||||||
|
* #include <assert.h>
|
||||||
|
*
|
||||||
|
* JNIEXPORT void JNICALL
|
||||||
|
* Java_MyCanvas_paint(JNIEnv* env, jobject canvas, jobject graphics)
|
||||||
|
* {
|
||||||
|
* JAWT awt;
|
||||||
|
* JAWT_DrawingSurface* ds;
|
||||||
|
* JAWT_DrawingSurfaceInfo* dsi;
|
||||||
|
* JAWT_Win32DrawingSurfaceInfo* dsi_win;
|
||||||
|
* jboolean result;
|
||||||
|
* jint lock;
|
||||||
|
*
|
||||||
|
* // Get the AWT
|
||||||
|
* awt.version = JAWT_VERSION_1_3;
|
||||||
|
* result = JAWT_GetAWT(env, &awt);
|
||||||
|
* assert(result != JNI_FALSE);
|
||||||
|
*
|
||||||
|
* // Get the drawing surface
|
||||||
|
* ds = awt.GetDrawingSurface(env, canvas);
|
||||||
|
* assert(ds != NULL);
|
||||||
|
*
|
||||||
|
* // Lock the drawing surface
|
||||||
|
* lock = ds->Lock(ds);
|
||||||
|
* assert((lock & JAWT_LOCK_ERROR) == 0);
|
||||||
|
*
|
||||||
|
* // Get the drawing surface info
|
||||||
|
* dsi = ds->GetDrawingSurfaceInfo(ds);
|
||||||
|
*
|
||||||
|
* // Get the platform-specific drawing info
|
||||||
|
* dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;
|
||||||
|
*
|
||||||
|
* //////////////////////////////
|
||||||
|
* // !!! DO PAINTING HERE !!! //
|
||||||
|
* //////////////////////////////
|
||||||
|
*
|
||||||
|
* // Free the drawing surface info
|
||||||
|
* ds->FreeDrawingSurfaceInfo(dsi);
|
||||||
|
*
|
||||||
|
* // Unlock the drawing surface
|
||||||
|
* ds->Unlock(ds);
|
||||||
|
*
|
||||||
|
* // Free the drawing surface
|
||||||
|
* awt.FreeDrawingSurface(ds);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JAWT_Rectangle
|
||||||
|
* Structure for a native rectangle.
|
||||||
|
*/
|
||||||
|
typedef struct jawt_Rectangle {
|
||||||
|
jint x;
|
||||||
|
jint y;
|
||||||
|
jint width;
|
||||||
|
jint height;
|
||||||
|
} JAWT_Rectangle;
|
||||||
|
|
||||||
|
struct jawt_DrawingSurface;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JAWT_DrawingSurfaceInfo
|
||||||
|
* Structure for containing the underlying drawing information of a component.
|
||||||
|
*/
|
||||||
|
typedef struct jawt_DrawingSurfaceInfo {
|
||||||
|
/*
|
||||||
|
* Pointer to the platform-specific information. This can be safely
|
||||||
|
* cast to a JAWT_Win32DrawingSurfaceInfo on Windows or a
|
||||||
|
* JAWT_X11DrawingSurfaceInfo on Solaris. On Mac OS X this is a
|
||||||
|
* pointer to a NSObject that conforms to the JAWT_SurfaceLayers
|
||||||
|
* protocol. See jawt_md.h for details.
|
||||||
|
*/
|
||||||
|
void* platformInfo;
|
||||||
|
/* Cached pointer to the underlying drawing surface */
|
||||||
|
struct jawt_DrawingSurface* ds;
|
||||||
|
/* Bounding rectangle of the drawing surface */
|
||||||
|
JAWT_Rectangle bounds;
|
||||||
|
/* Number of rectangles in the clip */
|
||||||
|
jint clipSize;
|
||||||
|
/* Clip rectangle array */
|
||||||
|
JAWT_Rectangle* clip;
|
||||||
|
} JAWT_DrawingSurfaceInfo;
|
||||||
|
|
||||||
|
#define JAWT_LOCK_ERROR 0x00000001
|
||||||
|
#define JAWT_LOCK_CLIP_CHANGED 0x00000002
|
||||||
|
#define JAWT_LOCK_BOUNDS_CHANGED 0x00000004
|
||||||
|
#define JAWT_LOCK_SURFACE_CHANGED 0x00000008
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JAWT_DrawingSurface
|
||||||
|
* Structure for containing the underlying drawing information of a component.
|
||||||
|
* All operations on a JAWT_DrawingSurface MUST be performed from the same
|
||||||
|
* thread as the call to GetDrawingSurface.
|
||||||
|
*/
|
||||||
|
typedef struct jawt_DrawingSurface {
|
||||||
|
/*
|
||||||
|
* Cached reference to the Java environment of the calling thread.
|
||||||
|
* If Lock(), Unlock(), GetDrawingSurfaceInfo() or
|
||||||
|
* FreeDrawingSurfaceInfo() are called from a different thread,
|
||||||
|
* this data member should be set before calling those functions.
|
||||||
|
*/
|
||||||
|
JNIEnv* env;
|
||||||
|
/* Cached reference to the target object */
|
||||||
|
jobject target;
|
||||||
|
/*
|
||||||
|
* Lock the surface of the target component for native rendering.
|
||||||
|
* When finished drawing, the surface must be unlocked with
|
||||||
|
* Unlock(). This function returns a bitmask with one or more of the
|
||||||
|
* following values:
|
||||||
|
*
|
||||||
|
* JAWT_LOCK_ERROR - When an error has occurred and the surface could not
|
||||||
|
* be locked.
|
||||||
|
*
|
||||||
|
* JAWT_LOCK_CLIP_CHANGED - When the clip region has changed.
|
||||||
|
*
|
||||||
|
* JAWT_LOCK_BOUNDS_CHANGED - When the bounds of the surface have changed.
|
||||||
|
*
|
||||||
|
* JAWT_LOCK_SURFACE_CHANGED - When the surface itself has changed
|
||||||
|
*/
|
||||||
|
jint (JNICALL *Lock)
|
||||||
|
(struct jawt_DrawingSurface* ds);
|
||||||
|
/*
|
||||||
|
* Get the drawing surface info.
|
||||||
|
* The value returned may be cached, but the values may change if
|
||||||
|
* additional calls to Lock() or Unlock() are made.
|
||||||
|
* Lock() must be called before this can return a valid value.
|
||||||
|
* Returns NULL if an error has occurred.
|
||||||
|
* When finished with the returned value, FreeDrawingSurfaceInfo must be
|
||||||
|
* called.
|
||||||
|
*/
|
||||||
|
JAWT_DrawingSurfaceInfo* (JNICALL *GetDrawingSurfaceInfo)
|
||||||
|
(struct jawt_DrawingSurface* ds);
|
||||||
|
/*
|
||||||
|
* Free the drawing surface info.
|
||||||
|
*/
|
||||||
|
void (JNICALL *FreeDrawingSurfaceInfo)
|
||||||
|
(JAWT_DrawingSurfaceInfo* dsi);
|
||||||
|
/*
|
||||||
|
* Unlock the drawing surface of the target component for native rendering.
|
||||||
|
*/
|
||||||
|
void (JNICALL *Unlock)
|
||||||
|
(struct jawt_DrawingSurface* ds);
|
||||||
|
} JAWT_DrawingSurface;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JAWT
|
||||||
|
* Structure for containing native AWT functions.
|
||||||
|
*/
|
||||||
|
typedef struct jawt {
|
||||||
|
/*
|
||||||
|
* Version of this structure. This must always be set before
|
||||||
|
* calling JAWT_GetAWT()
|
||||||
|
*/
|
||||||
|
jint version;
|
||||||
|
/*
|
||||||
|
* Return a drawing surface from a target jobject. This value
|
||||||
|
* may be cached.
|
||||||
|
* Returns NULL if an error has occurred.
|
||||||
|
* Target must be a java.awt.Component (should be a Canvas
|
||||||
|
* or Window for native rendering).
|
||||||
|
* FreeDrawingSurface() must be called when finished with the
|
||||||
|
* returned JAWT_DrawingSurface.
|
||||||
|
*/
|
||||||
|
JAWT_DrawingSurface* (JNICALL *GetDrawingSurface)
|
||||||
|
(JNIEnv* env, jobject target);
|
||||||
|
/*
|
||||||
|
* Free the drawing surface allocated in GetDrawingSurface.
|
||||||
|
*/
|
||||||
|
void (JNICALL *FreeDrawingSurface)
|
||||||
|
(JAWT_DrawingSurface* ds);
|
||||||
|
/*
|
||||||
|
* Since 1.4
|
||||||
|
* Locks the entire AWT for synchronization purposes
|
||||||
|
*/
|
||||||
|
void (JNICALL *Lock)(JNIEnv* env);
|
||||||
|
/*
|
||||||
|
* Since 1.4
|
||||||
|
* Unlocks the entire AWT for synchronization purposes
|
||||||
|
*/
|
||||||
|
void (JNICALL *Unlock)(JNIEnv* env);
|
||||||
|
/*
|
||||||
|
* Since 1.4
|
||||||
|
* Returns a reference to a java.awt.Component from a native
|
||||||
|
* platform handle. On Windows, this corresponds to an HWND;
|
||||||
|
* on Solaris and Linux, this is a Drawable. For other platforms,
|
||||||
|
* see the appropriate machine-dependent header file for a description.
|
||||||
|
* The reference returned by this function is a local
|
||||||
|
* reference that is only valid in this environment.
|
||||||
|
* This function returns a NULL reference if no component could be
|
||||||
|
* found with matching platform information.
|
||||||
|
*/
|
||||||
|
jobject (JNICALL *GetComponent)(JNIEnv* env, void* platformInfo);
|
||||||
|
|
||||||
|
} JAWT;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the AWT native structure. This function returns JNI_FALSE if
|
||||||
|
* an error occurs.
|
||||||
|
*/
|
||||||
|
_JNI_IMPORT_OR_EXPORT_
|
||||||
|
jboolean JNICALL JAWT_GetAWT(JNIEnv* env, JAWT* awt);
|
||||||
|
|
||||||
|
#define JAWT_VERSION_1_3 0x00010003
|
||||||
|
#define JAWT_VERSION_1_4 0x00010004
|
||||||
|
#define JAWT_VERSION_1_7 0x00010007
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_JAVASOFT_JAWT_H_ */
|
@ -0,0 +1,259 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Java Debug Wire Protocol Transport Service Provider Interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef JDWPTRANSPORT_H
|
||||||
|
#define JDWPTRANSPORT_H
|
||||||
|
|
||||||
|
#include "jni.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JDWPTRANSPORT_VERSION_1_0 = 0x00010000
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct jdwpTransportNativeInterface_;
|
||||||
|
|
||||||
|
struct _jdwpTransportEnv;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
typedef _jdwpTransportEnv jdwpTransportEnv;
|
||||||
|
#else
|
||||||
|
typedef const struct jdwpTransportNativeInterface_ *jdwpTransportEnv;
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Errors. Universal errors with JVMTI/JVMDI equivalents keep the
|
||||||
|
* values the same.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
JDWPTRANSPORT_ERROR_NONE = 0,
|
||||||
|
JDWPTRANSPORT_ERROR_ILLEGAL_ARGUMENT = 103,
|
||||||
|
JDWPTRANSPORT_ERROR_OUT_OF_MEMORY = 110,
|
||||||
|
JDWPTRANSPORT_ERROR_INTERNAL = 113,
|
||||||
|
JDWPTRANSPORT_ERROR_ILLEGAL_STATE = 201,
|
||||||
|
JDWPTRANSPORT_ERROR_IO_ERROR = 202,
|
||||||
|
JDWPTRANSPORT_ERROR_TIMEOUT = 203,
|
||||||
|
JDWPTRANSPORT_ERROR_MSG_NOT_AVAILABLE = 204
|
||||||
|
} jdwpTransportError;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure to define capabilities
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
unsigned int can_timeout_attach :1;
|
||||||
|
unsigned int can_timeout_accept :1;
|
||||||
|
unsigned int can_timeout_handshake :1;
|
||||||
|
unsigned int reserved3 :1;
|
||||||
|
unsigned int reserved4 :1;
|
||||||
|
unsigned int reserved5 :1;
|
||||||
|
unsigned int reserved6 :1;
|
||||||
|
unsigned int reserved7 :1;
|
||||||
|
unsigned int reserved8 :1;
|
||||||
|
unsigned int reserved9 :1;
|
||||||
|
unsigned int reserved10 :1;
|
||||||
|
unsigned int reserved11 :1;
|
||||||
|
unsigned int reserved12 :1;
|
||||||
|
unsigned int reserved13 :1;
|
||||||
|
unsigned int reserved14 :1;
|
||||||
|
unsigned int reserved15 :1;
|
||||||
|
} JDWPTransportCapabilities;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structures to define packet layout.
|
||||||
|
*
|
||||||
|
* See: http://java.sun.com/j2se/1.5/docs/guide/jpda/jdwp-spec.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/*
|
||||||
|
* If additional flags are added that apply to jdwpCmdPacket,
|
||||||
|
* then debugLoop.c: reader() will need to be updated to
|
||||||
|
* accept more than JDWPTRANSPORT_FLAGS_NONE.
|
||||||
|
*/
|
||||||
|
JDWPTRANSPORT_FLAGS_NONE = 0x0,
|
||||||
|
JDWPTRANSPORT_FLAGS_REPLY = 0x80
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
jint len;
|
||||||
|
jint id;
|
||||||
|
jbyte flags;
|
||||||
|
jbyte cmdSet;
|
||||||
|
jbyte cmd;
|
||||||
|
jbyte *data;
|
||||||
|
} jdwpCmdPacket;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
jint len;
|
||||||
|
jint id;
|
||||||
|
jbyte flags;
|
||||||
|
jshort errorCode;
|
||||||
|
jbyte *data;
|
||||||
|
} jdwpReplyPacket;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
jdwpCmdPacket cmd;
|
||||||
|
jdwpReplyPacket reply;
|
||||||
|
} type;
|
||||||
|
} jdwpPacket;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* JDWP functions called by the transport.
|
||||||
|
*/
|
||||||
|
typedef struct jdwpTransportCallback {
|
||||||
|
void *(*alloc)(jint numBytes); /* Call this for all allocations */
|
||||||
|
void (*free)(void *buffer); /* Call this for all deallocations */
|
||||||
|
} jdwpTransportCallback;
|
||||||
|
|
||||||
|
typedef jint (JNICALL *jdwpTransport_OnLoad_t)(JavaVM *jvm,
|
||||||
|
jdwpTransportCallback *callback,
|
||||||
|
jint version,
|
||||||
|
jdwpTransportEnv** env);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Function Interface */
|
||||||
|
|
||||||
|
struct jdwpTransportNativeInterface_ {
|
||||||
|
/* 1 : RESERVED */
|
||||||
|
void *reserved1;
|
||||||
|
|
||||||
|
/* 2 : Get Capabilities */
|
||||||
|
jdwpTransportError (JNICALL *GetCapabilities)(jdwpTransportEnv* env,
|
||||||
|
JDWPTransportCapabilities *capabilities_ptr);
|
||||||
|
|
||||||
|
/* 3 : Attach */
|
||||||
|
jdwpTransportError (JNICALL *Attach)(jdwpTransportEnv* env,
|
||||||
|
const char* address,
|
||||||
|
jlong attach_timeout,
|
||||||
|
jlong handshake_timeout);
|
||||||
|
|
||||||
|
/* 4: StartListening */
|
||||||
|
jdwpTransportError (JNICALL *StartListening)(jdwpTransportEnv* env,
|
||||||
|
const char* address,
|
||||||
|
char** actual_address);
|
||||||
|
|
||||||
|
/* 5: StopListening */
|
||||||
|
jdwpTransportError (JNICALL *StopListening)(jdwpTransportEnv* env);
|
||||||
|
|
||||||
|
/* 6: Accept */
|
||||||
|
jdwpTransportError (JNICALL *Accept)(jdwpTransportEnv* env,
|
||||||
|
jlong accept_timeout,
|
||||||
|
jlong handshake_timeout);
|
||||||
|
|
||||||
|
/* 7: IsOpen */
|
||||||
|
jboolean (JNICALL *IsOpen)(jdwpTransportEnv* env);
|
||||||
|
|
||||||
|
/* 8: Close */
|
||||||
|
jdwpTransportError (JNICALL *Close)(jdwpTransportEnv* env);
|
||||||
|
|
||||||
|
/* 9: ReadPacket */
|
||||||
|
jdwpTransportError (JNICALL *ReadPacket)(jdwpTransportEnv* env,
|
||||||
|
jdwpPacket *pkt);
|
||||||
|
|
||||||
|
/* 10: Write Packet */
|
||||||
|
jdwpTransportError (JNICALL *WritePacket)(jdwpTransportEnv* env,
|
||||||
|
const jdwpPacket* pkt);
|
||||||
|
|
||||||
|
/* 11: GetLastError */
|
||||||
|
jdwpTransportError (JNICALL *GetLastError)(jdwpTransportEnv* env,
|
||||||
|
char** error);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use inlined functions so that C++ code can use syntax such as
|
||||||
|
* env->Attach("mymachine:5000", 10*1000, 0);
|
||||||
|
*
|
||||||
|
* rather than using C's :-
|
||||||
|
*
|
||||||
|
* (*env)->Attach(env, "mymachine:5000", 10*1000, 0);
|
||||||
|
*/
|
||||||
|
struct _jdwpTransportEnv {
|
||||||
|
const struct jdwpTransportNativeInterface_ *functions;
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
jdwpTransportError GetCapabilities(JDWPTransportCapabilities *capabilities_ptr) {
|
||||||
|
return functions->GetCapabilities(this, capabilities_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
jdwpTransportError Attach(const char* address, jlong attach_timeout,
|
||||||
|
jlong handshake_timeout) {
|
||||||
|
return functions->Attach(this, address, attach_timeout, handshake_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
jdwpTransportError StartListening(const char* address,
|
||||||
|
char** actual_address) {
|
||||||
|
return functions->StartListening(this, address, actual_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
jdwpTransportError StopListening(void) {
|
||||||
|
return functions->StopListening(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
jdwpTransportError Accept(jlong accept_timeout, jlong handshake_timeout) {
|
||||||
|
return functions->Accept(this, accept_timeout, handshake_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
jboolean IsOpen(void) {
|
||||||
|
return functions->IsOpen(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
jdwpTransportError Close(void) {
|
||||||
|
return functions->Close(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
jdwpTransportError ReadPacket(jdwpPacket *pkt) {
|
||||||
|
return functions->ReadPacket(this, pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
jdwpTransportError WritePacket(const jdwpPacket* pkt) {
|
||||||
|
return functions->WritePacket(this, pkt);
|
||||||
|
}
|
||||||
|
|
||||||
|
jdwpTransportError GetLastError(char** error) {
|
||||||
|
return functions->GetLastError(this, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* JDWPTRANSPORT_H */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This header file defines the data structures sent by the VM
|
||||||
|
* through the JVMTI CompiledMethodLoad callback function via the
|
||||||
|
* "void * compile_info" parameter. The memory pointed to by the
|
||||||
|
* compile_info parameter may not be referenced after returning from
|
||||||
|
* the CompiledMethodLoad callback. These are VM implementation
|
||||||
|
* specific data structures that may evolve in future releases. A
|
||||||
|
* JVMTI agent should interpret a non-NULL compile_info as a pointer
|
||||||
|
* to a region of memory containing a list of records. In a typical
|
||||||
|
* usage scenario, a JVMTI agent would cast each record to a
|
||||||
|
* jvmtiCompiledMethodLoadRecordHeader, a struct that represents
|
||||||
|
* arbitrary information. This struct contains a kind field to indicate
|
||||||
|
* the kind of information being passed, and a pointer to the next
|
||||||
|
* record. If the kind field indicates inlining information, then the
|
||||||
|
* agent would cast the record to a jvmtiCompiledMethodLoadInlineRecord.
|
||||||
|
* This record contains an array of PCStackInfo structs, which indicate
|
||||||
|
* for every pc address what are the methods on the invocation stack.
|
||||||
|
* The "methods" and "bcis" fields in each PCStackInfo struct specify a
|
||||||
|
* 1-1 mapping between these inlined methods and their bytecode indices.
|
||||||
|
* This can be used to derive the proper source lines of the inlined
|
||||||
|
* methods.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JVMTI_CMLR_H_
|
||||||
|
#define _JVMTI_CMLR_H_
|
||||||
|
|
||||||
|
enum {
|
||||||
|
JVMTI_CMLR_MAJOR_VERSION_1 = 0x00000001,
|
||||||
|
JVMTI_CMLR_MINOR_VERSION_0 = 0x00000000,
|
||||||
|
|
||||||
|
JVMTI_CMLR_MAJOR_VERSION = 0x00000001,
|
||||||
|
JVMTI_CMLR_MINOR_VERSION = 0x00000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This comment is for the "JDK import from HotSpot" sanity check:
|
||||||
|
* version: 1.0.0
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
JVMTI_CMLR_DUMMY = 1,
|
||||||
|
JVMTI_CMLR_INLINE_INFO = 2
|
||||||
|
} jvmtiCMLRKind;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record that represents arbitrary information passed through JVMTI
|
||||||
|
* CompiledMethodLoadEvent void pointer.
|
||||||
|
*/
|
||||||
|
typedef struct _jvmtiCompiledMethodLoadRecordHeader {
|
||||||
|
jvmtiCMLRKind kind; /* id for the kind of info passed in the record */
|
||||||
|
jint majorinfoversion; /* major and minor info version values. Init'ed */
|
||||||
|
jint minorinfoversion; /* to current version value in jvmtiExport.cpp. */
|
||||||
|
|
||||||
|
struct _jvmtiCompiledMethodLoadRecordHeader* next;
|
||||||
|
} jvmtiCompiledMethodLoadRecordHeader;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record that gives information about the methods on the compile-time
|
||||||
|
* stack at a specific pc address of a compiled method. Each element in
|
||||||
|
* the methods array maps to same element in the bcis array.
|
||||||
|
*/
|
||||||
|
typedef struct _PCStackInfo {
|
||||||
|
void* pc; /* the pc address for this compiled method */
|
||||||
|
jint numstackframes; /* number of methods on the stack */
|
||||||
|
jmethodID* methods; /* array of numstackframes method ids */
|
||||||
|
jint* bcis; /* array of numstackframes bytecode indices */
|
||||||
|
} PCStackInfo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record that contains inlining information for each pc address of
|
||||||
|
* an nmethod.
|
||||||
|
*/
|
||||||
|
typedef struct _jvmtiCompiledMethodLoadInlineRecord {
|
||||||
|
jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
|
||||||
|
jint numpcs; /* number of pc descriptors in this nmethod */
|
||||||
|
PCStackInfo* pcinfo; /* array of numpcs pc descriptors */
|
||||||
|
} jvmtiCompiledMethodLoadInlineRecord;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dummy record used to test that we can pass records with different
|
||||||
|
* information through the void pointer provided that they can be cast
|
||||||
|
* to a jvmtiCompiledMethodLoadRecordHeader.
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct _jvmtiCompiledMethodLoadDummyRecord {
|
||||||
|
jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
|
||||||
|
char message[50];
|
||||||
|
} jvmtiCompiledMethodLoadDummyRecord;
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999, 2001, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JAVASOFT_JAWT_MD_H_
|
||||||
|
#define _JAVASOFT_JAWT_MD_H_
|
||||||
|
|
||||||
|
#include <X11/Xlib.h>
|
||||||
|
#include <X11/Xutil.h>
|
||||||
|
#include <X11/Intrinsic.h>
|
||||||
|
#include "jawt.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* X11-specific declarations for AWT native interface.
|
||||||
|
* See notes in jawt.h for an example of use.
|
||||||
|
*/
|
||||||
|
typedef struct jawt_X11DrawingSurfaceInfo {
|
||||||
|
Drawable drawable;
|
||||||
|
Display* display;
|
||||||
|
VisualID visualID;
|
||||||
|
Colormap colormapID;
|
||||||
|
int depth;
|
||||||
|
/*
|
||||||
|
* Since 1.4
|
||||||
|
* Returns a pixel value from a set of RGB values.
|
||||||
|
* This is useful for paletted color (256 color) modes.
|
||||||
|
*/
|
||||||
|
int (JNICALL *GetAWTColor)(JAWT_DrawingSurface* ds,
|
||||||
|
int r, int g, int b);
|
||||||
|
} JAWT_X11DrawingSurfaceInfo;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_JAVASOFT_JAWT_MD_H_ */
|
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JAVASOFT_JNI_MD_H_
|
||||||
|
#define _JAVASOFT_JNI_MD_H_
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
#define __has_attribute(x) 0
|
||||||
|
#endif
|
||||||
|
#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility)
|
||||||
|
#define JNIEXPORT __attribute__((visibility("default")))
|
||||||
|
#define JNIIMPORT __attribute__((visibility("default")))
|
||||||
|
#else
|
||||||
|
#define JNIEXPORT
|
||||||
|
#define JNIIMPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define JNICALL
|
||||||
|
|
||||||
|
typedef int jint;
|
||||||
|
#ifdef _LP64 /* 64-bit Solaris */
|
||||||
|
typedef long jlong;
|
||||||
|
#else
|
||||||
|
typedef long long jlong;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef signed char jbyte;
|
||||||
|
|
||||||
|
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
@ -0,0 +1,77 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JAVASOFT_JAWT_MD_H_
|
||||||
|
#define _JAVASOFT_JAWT_MD_H_
|
||||||
|
|
||||||
|
#include "jawt.h"
|
||||||
|
|
||||||
|
#ifdef __OBJC__
|
||||||
|
#import <QuartzCore/CALayer.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mac OS X specific declarations for AWT native interface.
|
||||||
|
* See notes in jawt.h for an example of use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When calling JAWT_GetAWT with a JAWT version less than 1.7, you must pass this
|
||||||
|
* flag or you will not be able to get a valid drawing surface and JAWT_GetAWT will
|
||||||
|
* return false. This is to maintain compatibility with applications that used the
|
||||||
|
* interface with Java 6 which had multiple rendering models. This flag is not necessary
|
||||||
|
* when JAWT version 1.7 or greater is used as this is the only supported rendering mode.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* JAWT awt;
|
||||||
|
* awt.version = JAWT_VERSION_1_4 | JAWT_MACOSX_USE_CALAYER;
|
||||||
|
* jboolean success = JAWT_GetAWT(env, &awt);
|
||||||
|
*/
|
||||||
|
#define JAWT_MACOSX_USE_CALAYER 0x80000000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When the native Cocoa toolkit is in use, the pointer stored in
|
||||||
|
* JAWT_DrawingSurfaceInfo->platformInfo points to a NSObject that conforms to the
|
||||||
|
* JAWT_SurfaceLayers protocol. Setting the layer property of this object will cause the
|
||||||
|
* specified layer to be overlaid on the Components rectangle. If the window the
|
||||||
|
* Component belongs to has a CALayer attached to it, this layer will be accessible via
|
||||||
|
* the windowLayer property.
|
||||||
|
*/
|
||||||
|
#ifdef __OBJC__
|
||||||
|
@protocol JAWT_SurfaceLayers
|
||||||
|
@property (readwrite, retain) CALayer *layer;
|
||||||
|
@property (readonly) CALayer *windowLayer;
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_JAVASOFT_JAWT_MD_H_ */
|
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JAVASOFT_JNI_MD_H_
|
||||||
|
#define _JAVASOFT_JNI_MD_H_
|
||||||
|
|
||||||
|
#define JNIEXPORT __attribute__((visibility("default")))
|
||||||
|
#define JNIIMPORT __attribute__((visibility("default")))
|
||||||
|
#define JNICALL
|
||||||
|
|
||||||
|
typedef int jint;
|
||||||
|
#ifdef _LP64 /* 64-bit */
|
||||||
|
typedef long jlong;
|
||||||
|
#else
|
||||||
|
typedef long long jlong;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef signed char jbyte;
|
||||||
|
|
||||||
|
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AccessBridgeCallbacks.h 1.17 05/03/21
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Header file defining callback typedefs for Windows routines
|
||||||
|
* which are called from Java (responding to events, etc.).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __AccessBridgeCallbacks_H__
|
||||||
|
#define __AccessBridgeCallbacks_H__
|
||||||
|
|
||||||
|
#include <jni.h>
|
||||||
|
#include "AccessBridgePackages.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef void (*AccessBridge_PropertyChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source,
|
||||||
|
wchar_t *property, wchar_t *oldValue, wchar_t *newValue);
|
||||||
|
|
||||||
|
typedef void (*AccessBridge_JavaShutdownFP) (long vmID);
|
||||||
|
typedef void (*AccessBridge_JavaShutdownFP) (long vmID);
|
||||||
|
|
||||||
|
typedef void (*AccessBridge_FocusGainedFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_FocusLostFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
|
||||||
|
typedef void (*AccessBridge_CaretUpdateFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
|
||||||
|
typedef void (*AccessBridge_MouseClickedFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_MouseEnteredFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_MouseExitedFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_MousePressedFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_MouseReleasedFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
|
||||||
|
typedef void (*AccessBridge_MenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_MenuDeselectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_MenuSelectedFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_PopupMenuCanceledFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_PopupMenuWillBecomeInvisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_PopupMenuWillBecomeVisibleFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
|
||||||
|
typedef void (*AccessBridge_PropertyNameChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source,
|
||||||
|
wchar_t *oldName, wchar_t *newName);
|
||||||
|
typedef void (*AccessBridge_PropertyDescriptionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source,
|
||||||
|
wchar_t *oldDescription, wchar_t *newDescription);
|
||||||
|
typedef void (*AccessBridge_PropertyStateChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source,
|
||||||
|
wchar_t *oldState, wchar_t *newState);
|
||||||
|
typedef void (*AccessBridge_PropertyValueChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source,
|
||||||
|
wchar_t *oldValue, wchar_t *newValue);
|
||||||
|
typedef void (*AccessBridge_PropertySelectionChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_PropertyTextChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_PropertyCaretChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source,
|
||||||
|
int oldPosition, int newPosition);
|
||||||
|
typedef void (*AccessBridge_PropertyVisibleDataChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source);
|
||||||
|
typedef void (*AccessBridge_PropertyChildChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 source,
|
||||||
|
JOBJECT64 oldChild, JOBJECT64 newChild);
|
||||||
|
typedef void (*AccessBridge_PropertyActiveDescendentChangeFP) (long vmID, JOBJECT64 event,
|
||||||
|
JOBJECT64 source,
|
||||||
|
JOBJECT64 oldActiveDescendent,
|
||||||
|
JOBJECT64 newActiveDescendent);
|
||||||
|
|
||||||
|
typedef void (*AccessBridge_PropertyTableModelChangeFP) (long vmID, JOBJECT64 event, JOBJECT64 src,
|
||||||
|
wchar_t *oldValue, wchar_t *newValue);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,706 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper functions around calls to the AccessBridge DLL
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <jni.h>
|
||||||
|
#include "AccessBridgeCallbacks.h"
|
||||||
|
#include "AccessBridgePackages.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define null NULL
|
||||||
|
|
||||||
|
typedef JOBJECT64 AccessibleContext;
|
||||||
|
typedef JOBJECT64 AccessibleText;
|
||||||
|
typedef JOBJECT64 AccessibleValue;
|
||||||
|
typedef JOBJECT64 AccessibleSelection;
|
||||||
|
typedef JOBJECT64 Java_Object;
|
||||||
|
typedef JOBJECT64 PropertyChangeEvent;
|
||||||
|
typedef JOBJECT64 FocusEvent;
|
||||||
|
typedef JOBJECT64 CaretEvent;
|
||||||
|
typedef JOBJECT64 MouseEvent;
|
||||||
|
typedef JOBJECT64 MenuEvent;
|
||||||
|
typedef JOBJECT64 AccessibleTable;
|
||||||
|
typedef JOBJECT64 AccessibleHyperlink;
|
||||||
|
typedef JOBJECT64 AccessibleHypertext;
|
||||||
|
|
||||||
|
|
||||||
|
typedef void (*Windows_runFP) ();
|
||||||
|
|
||||||
|
typedef void (*SetPropertyChangeFP) (AccessBridge_PropertyChangeFP fp);
|
||||||
|
|
||||||
|
typedef void (*SetJavaShutdownFP) (AccessBridge_JavaShutdownFP fp);
|
||||||
|
typedef void (*SetFocusGainedFP) (AccessBridge_FocusGainedFP fp);
|
||||||
|
typedef void (*SetFocusLostFP) (AccessBridge_FocusLostFP fp);
|
||||||
|
|
||||||
|
typedef void (*SetCaretUpdateFP) (AccessBridge_CaretUpdateFP fp);
|
||||||
|
|
||||||
|
typedef void (*SetMouseClickedFP) (AccessBridge_MouseClickedFP fp);
|
||||||
|
typedef void (*SetMouseEnteredFP) (AccessBridge_MouseEnteredFP fp);
|
||||||
|
typedef void (*SetMouseExitedFP) (AccessBridge_MouseExitedFP fp);
|
||||||
|
typedef void (*SetMousePressedFP) (AccessBridge_MousePressedFP fp);
|
||||||
|
typedef void (*SetMouseReleasedFP) (AccessBridge_MouseReleasedFP fp);
|
||||||
|
|
||||||
|
typedef void (*SetMenuCanceledFP) (AccessBridge_MenuCanceledFP fp);
|
||||||
|
typedef void (*SetMenuDeselectedFP) (AccessBridge_MenuDeselectedFP fp);
|
||||||
|
typedef void (*SetMenuSelectedFP) (AccessBridge_MenuSelectedFP fp);
|
||||||
|
typedef void (*SetPopupMenuCanceledFP) (AccessBridge_PopupMenuCanceledFP fp);
|
||||||
|
typedef void (*SetPopupMenuWillBecomeInvisibleFP) (AccessBridge_PopupMenuWillBecomeInvisibleFP fp);
|
||||||
|
typedef void (*SetPopupMenuWillBecomeVisibleFP) (AccessBridge_PopupMenuWillBecomeVisibleFP fp);
|
||||||
|
|
||||||
|
typedef void (*SetPropertyNameChangeFP) (AccessBridge_PropertyNameChangeFP fp);
|
||||||
|
typedef void (*SetPropertyDescriptionChangeFP) (AccessBridge_PropertyDescriptionChangeFP fp);
|
||||||
|
typedef void (*SetPropertyStateChangeFP) (AccessBridge_PropertyStateChangeFP fp);
|
||||||
|
typedef void (*SetPropertyValueChangeFP) (AccessBridge_PropertyValueChangeFP fp);
|
||||||
|
typedef void (*SetPropertySelectionChangeFP) (AccessBridge_PropertySelectionChangeFP fp);
|
||||||
|
typedef void (*SetPropertyTextChangeFP) (AccessBridge_PropertyTextChangeFP fp);
|
||||||
|
typedef void (*SetPropertyCaretChangeFP) (AccessBridge_PropertyCaretChangeFP fp);
|
||||||
|
typedef void (*SetPropertyVisibleDataChangeFP) (AccessBridge_PropertyVisibleDataChangeFP fp);
|
||||||
|
typedef void (*SetPropertyChildChangeFP) (AccessBridge_PropertyChildChangeFP fp);
|
||||||
|
typedef void (*SetPropertyActiveDescendentChangeFP) (AccessBridge_PropertyActiveDescendentChangeFP fp);
|
||||||
|
|
||||||
|
typedef void (*SetPropertyTableModelChangeFP) (AccessBridge_PropertyTableModelChangeFP fp);
|
||||||
|
|
||||||
|
typedef void (*ReleaseJavaObjectFP) (long vmID, Java_Object object);
|
||||||
|
|
||||||
|
typedef BOOL (*GetVersionInfoFP) (long vmID, AccessBridgeVersionInfo *info);
|
||||||
|
|
||||||
|
typedef BOOL (*IsJavaWindowFP) (HWND window);
|
||||||
|
typedef BOOL (*IsSameObjectFP) (long vmID, JOBJECT64 obj1, JOBJECT64 obj2);
|
||||||
|
typedef BOOL (*GetAccessibleContextFromHWNDFP) (HWND window, long *vmID, AccessibleContext *ac);
|
||||||
|
typedef HWND (*getHWNDFromAccessibleContextFP) (long vmID, AccessibleContext ac);
|
||||||
|
|
||||||
|
typedef BOOL (*GetAccessibleContextAtFP) (long vmID, AccessibleContext acParent,
|
||||||
|
jint x, jint y, AccessibleContext *ac);
|
||||||
|
typedef BOOL (*GetAccessibleContextWithFocusFP) (HWND window, long *vmID, AccessibleContext *ac);
|
||||||
|
typedef BOOL (*GetAccessibleContextInfoFP) (long vmID, AccessibleContext ac, AccessibleContextInfo *info);
|
||||||
|
typedef AccessibleContext (*GetAccessibleChildFromContextFP) (long vmID, AccessibleContext ac, jint i);
|
||||||
|
typedef AccessibleContext (*GetAccessibleParentFromContextFP) (long vmID, AccessibleContext ac);
|
||||||
|
|
||||||
|
/* begin AccessibleTable */
|
||||||
|
typedef BOOL (*getAccessibleTableInfoFP) (long vmID, AccessibleContext ac, AccessibleTableInfo *tableInfo);
|
||||||
|
typedef BOOL (*getAccessibleTableCellInfoFP) (long vmID, AccessibleTable accessibleTable,
|
||||||
|
jint row, jint column, AccessibleTableCellInfo *tableCellInfo);
|
||||||
|
|
||||||
|
typedef BOOL (*getAccessibleTableRowHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo);
|
||||||
|
typedef BOOL (*getAccessibleTableColumnHeaderFP) (long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo);
|
||||||
|
|
||||||
|
typedef AccessibleContext (*getAccessibleTableRowDescriptionFP) (long vmID, AccessibleContext acParent, jint row);
|
||||||
|
typedef AccessibleContext (*getAccessibleTableColumnDescriptionFP) (long vmID, AccessibleContext acParent, jint column);
|
||||||
|
|
||||||
|
typedef jint (*getAccessibleTableRowSelectionCountFP) (long vmID, AccessibleTable table);
|
||||||
|
typedef BOOL (*isAccessibleTableRowSelectedFP) (long vmID, AccessibleTable table, jint row);
|
||||||
|
typedef BOOL (*getAccessibleTableRowSelectionsFP) (long vmID, AccessibleTable table, jint count,
|
||||||
|
jint *selections);
|
||||||
|
|
||||||
|
typedef jint (*getAccessibleTableColumnSelectionCountFP) (long vmID, AccessibleTable table);
|
||||||
|
typedef BOOL (*isAccessibleTableColumnSelectedFP) (long vmID, AccessibleTable table, jint column);
|
||||||
|
typedef BOOL (*getAccessibleTableColumnSelectionsFP) (long vmID, AccessibleTable table, jint count,
|
||||||
|
jint *selections);
|
||||||
|
|
||||||
|
typedef jint (*getAccessibleTableRowFP) (long vmID, AccessibleTable table, jint index);
|
||||||
|
typedef jint (*getAccessibleTableColumnFP) (long vmID, AccessibleTable table, jint index);
|
||||||
|
typedef jint (*getAccessibleTableIndexFP) (long vmID, AccessibleTable table, jint row, jint column);
|
||||||
|
/* end AccessibleTable */
|
||||||
|
|
||||||
|
/* AccessibleRelationSet */
|
||||||
|
typedef BOOL (*getAccessibleRelationSetFP) (long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleRelationSetInfo *relationSetInfo);
|
||||||
|
|
||||||
|
/* AccessibleHypertext */
|
||||||
|
typedef BOOL (*getAccessibleHypertextFP)(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleHypertextInfo *hypertextInfo);
|
||||||
|
|
||||||
|
typedef BOOL (*activateAccessibleHyperlinkFP)(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleHyperlink accessibleHyperlink);
|
||||||
|
|
||||||
|
typedef jint (*getAccessibleHyperlinkCountFP)(const long vmID,
|
||||||
|
const AccessibleContext accessibleContext);
|
||||||
|
|
||||||
|
typedef BOOL (*getAccessibleHypertextExtFP) (const long vmID,
|
||||||
|
const AccessibleContext accessibleContext,
|
||||||
|
const jint nStartIndex,
|
||||||
|
AccessibleHypertextInfo *hypertextInfo);
|
||||||
|
|
||||||
|
typedef jint (*getAccessibleHypertextLinkIndexFP)(const long vmID,
|
||||||
|
const AccessibleHypertext hypertext,
|
||||||
|
const jint nIndex);
|
||||||
|
|
||||||
|
typedef BOOL (*getAccessibleHyperlinkFP)(const long vmID,
|
||||||
|
const AccessibleHypertext hypertext,
|
||||||
|
const jint nIndex,
|
||||||
|
AccessibleHyperlinkInfo *hyperlinkInfo);
|
||||||
|
|
||||||
|
|
||||||
|
/* Accessible KeyBindings, Icons and Actions */
|
||||||
|
typedef BOOL (*getAccessibleKeyBindingsFP)(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleKeyBindings *keyBindings);
|
||||||
|
|
||||||
|
typedef BOOL (*getAccessibleIconsFP)(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleIcons *icons);
|
||||||
|
|
||||||
|
typedef BOOL (*getAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleActions *actions);
|
||||||
|
|
||||||
|
typedef BOOL (*doAccessibleActionsFP)(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleActionsToDo *actionsToDo, jint *failure);
|
||||||
|
|
||||||
|
|
||||||
|
/* AccessibleText */
|
||||||
|
|
||||||
|
typedef BOOL (*GetAccessibleTextInfoFP) (long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y);
|
||||||
|
typedef BOOL (*GetAccessibleTextItemsFP) (long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index);
|
||||||
|
typedef BOOL (*GetAccessibleTextSelectionInfoFP) (long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection);
|
||||||
|
typedef BOOL (*GetAccessibleTextAttributesFP) (long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes);
|
||||||
|
typedef BOOL (*GetAccessibleTextRectFP) (long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index);
|
||||||
|
typedef BOOL (*GetAccessibleTextLineBoundsFP) (long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex);
|
||||||
|
typedef BOOL (*GetAccessibleTextRangeFP) (long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len);
|
||||||
|
|
||||||
|
typedef BOOL (*GetCurrentAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len);
|
||||||
|
typedef BOOL (*GetMaximumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len);
|
||||||
|
typedef BOOL (*GetMinimumAccessibleValueFromContextFP) (long vmID, AccessibleValue av, wchar_t *value, short len);
|
||||||
|
|
||||||
|
typedef void (*AddAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i);
|
||||||
|
typedef void (*ClearAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as);
|
||||||
|
typedef JOBJECT64 (*GetAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i);
|
||||||
|
typedef int (*GetAccessibleSelectionCountFromContextFP) (long vmID, AccessibleSelection as);
|
||||||
|
typedef BOOL (*IsAccessibleChildSelectedFromContextFP) (long vmID, AccessibleSelection as, int i);
|
||||||
|
typedef void (*RemoveAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as, int i);
|
||||||
|
typedef void (*SelectAllAccessibleSelectionFromContextFP) (long vmID, AccessibleSelection as);
|
||||||
|
|
||||||
|
/* Utility methods */
|
||||||
|
|
||||||
|
typedef BOOL (*setTextContentsFP) (const long vmID, const AccessibleContext ac, const wchar_t *text);
|
||||||
|
typedef AccessibleContext (*getParentWithRoleFP) (const long vmID, const AccessibleContext ac, const wchar_t *role);
|
||||||
|
typedef AccessibleContext (*getParentWithRoleElseRootFP) (const long vmID, const AccessibleContext ac, const wchar_t *role);
|
||||||
|
typedef AccessibleContext (*getTopLevelObjectFP) (const long vmID, const AccessibleContext ac);
|
||||||
|
typedef int (*getObjectDepthFP) (const long vmID, const AccessibleContext ac);
|
||||||
|
typedef AccessibleContext (*getActiveDescendentFP) (const long vmID, const AccessibleContext ac);
|
||||||
|
|
||||||
|
|
||||||
|
typedef BOOL (*getVirtualAccessibleNameFP) (const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
wchar_t *name, int len);
|
||||||
|
|
||||||
|
typedef BOOL (*requestFocusFP) (const long vmID, const AccessibleContext accessibleContext);
|
||||||
|
|
||||||
|
typedef BOOL (*selectTextRangeFP) (const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
const int startIndex, const int endIndex);
|
||||||
|
|
||||||
|
typedef BOOL (*getTextAttributesInRangeFP) (const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
const int startIndex, const int endIndex,
|
||||||
|
AccessibleTextAttributesInfo *attributes, short *len);
|
||||||
|
|
||||||
|
typedef int (*getVisibleChildrenCountFP) (const long vmID, const AccessibleContext accessibleContext);
|
||||||
|
|
||||||
|
typedef BOOL (*getVisibleChildrenFP) (const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
const int startIndex, VisibleChildrenInfo *children);
|
||||||
|
|
||||||
|
typedef BOOL (*setCaretPositionFP) (const long vmID, const AccessibleContext accessibleContext, const int position);
|
||||||
|
|
||||||
|
typedef BOOL (*getCaretLocationFP) (long vmID, AccessibleContext ac, AccessibleTextRectInfo *rectInfo, jint index);
|
||||||
|
|
||||||
|
typedef int (*getEventsWaitingFP) ();
|
||||||
|
|
||||||
|
typedef struct AccessBridgeFPsTag {
|
||||||
|
Windows_runFP Windows_run;
|
||||||
|
|
||||||
|
SetPropertyChangeFP SetPropertyChange;
|
||||||
|
|
||||||
|
SetJavaShutdownFP SetJavaShutdown;
|
||||||
|
SetFocusGainedFP SetFocusGained;
|
||||||
|
SetFocusLostFP SetFocusLost;
|
||||||
|
|
||||||
|
SetCaretUpdateFP SetCaretUpdate;
|
||||||
|
|
||||||
|
SetMouseClickedFP SetMouseClicked;
|
||||||
|
SetMouseEnteredFP SetMouseEntered;
|
||||||
|
SetMouseExitedFP SetMouseExited;
|
||||||
|
SetMousePressedFP SetMousePressed;
|
||||||
|
SetMouseReleasedFP SetMouseReleased;
|
||||||
|
|
||||||
|
SetMenuCanceledFP SetMenuCanceled;
|
||||||
|
SetMenuDeselectedFP SetMenuDeselected;
|
||||||
|
SetMenuSelectedFP SetMenuSelected;
|
||||||
|
SetPopupMenuCanceledFP SetPopupMenuCanceled;
|
||||||
|
SetPopupMenuWillBecomeInvisibleFP SetPopupMenuWillBecomeInvisible;
|
||||||
|
SetPopupMenuWillBecomeVisibleFP SetPopupMenuWillBecomeVisible;
|
||||||
|
|
||||||
|
SetPropertyNameChangeFP SetPropertyNameChange;
|
||||||
|
SetPropertyDescriptionChangeFP SetPropertyDescriptionChange;
|
||||||
|
SetPropertyStateChangeFP SetPropertyStateChange;
|
||||||
|
SetPropertyValueChangeFP SetPropertyValueChange;
|
||||||
|
SetPropertySelectionChangeFP SetPropertySelectionChange;
|
||||||
|
SetPropertyTextChangeFP SetPropertyTextChange;
|
||||||
|
SetPropertyCaretChangeFP SetPropertyCaretChange;
|
||||||
|
SetPropertyVisibleDataChangeFP SetPropertyVisibleDataChange;
|
||||||
|
SetPropertyChildChangeFP SetPropertyChildChange;
|
||||||
|
SetPropertyActiveDescendentChangeFP SetPropertyActiveDescendentChange;
|
||||||
|
|
||||||
|
SetPropertyTableModelChangeFP SetPropertyTableModelChange;
|
||||||
|
|
||||||
|
ReleaseJavaObjectFP ReleaseJavaObject;
|
||||||
|
GetVersionInfoFP GetVersionInfo;
|
||||||
|
|
||||||
|
IsJavaWindowFP IsJavaWindow;
|
||||||
|
IsSameObjectFP IsSameObject;
|
||||||
|
GetAccessibleContextFromHWNDFP GetAccessibleContextFromHWND;
|
||||||
|
getHWNDFromAccessibleContextFP getHWNDFromAccessibleContext;
|
||||||
|
|
||||||
|
GetAccessibleContextAtFP GetAccessibleContextAt;
|
||||||
|
GetAccessibleContextWithFocusFP GetAccessibleContextWithFocus;
|
||||||
|
GetAccessibleContextInfoFP GetAccessibleContextInfo;
|
||||||
|
GetAccessibleChildFromContextFP GetAccessibleChildFromContext;
|
||||||
|
GetAccessibleParentFromContextFP GetAccessibleParentFromContext;
|
||||||
|
|
||||||
|
getAccessibleTableInfoFP getAccessibleTableInfo;
|
||||||
|
getAccessibleTableCellInfoFP getAccessibleTableCellInfo;
|
||||||
|
|
||||||
|
getAccessibleTableRowHeaderFP getAccessibleTableRowHeader;
|
||||||
|
getAccessibleTableColumnHeaderFP getAccessibleTableColumnHeader;
|
||||||
|
|
||||||
|
getAccessibleTableRowDescriptionFP getAccessibleTableRowDescription;
|
||||||
|
getAccessibleTableColumnDescriptionFP getAccessibleTableColumnDescription;
|
||||||
|
|
||||||
|
getAccessibleTableRowSelectionCountFP getAccessibleTableRowSelectionCount;
|
||||||
|
isAccessibleTableRowSelectedFP isAccessibleTableRowSelected;
|
||||||
|
getAccessibleTableRowSelectionsFP getAccessibleTableRowSelections;
|
||||||
|
|
||||||
|
getAccessibleTableColumnSelectionCountFP getAccessibleTableColumnSelectionCount;
|
||||||
|
isAccessibleTableColumnSelectedFP isAccessibleTableColumnSelected;
|
||||||
|
getAccessibleTableColumnSelectionsFP getAccessibleTableColumnSelections;
|
||||||
|
|
||||||
|
getAccessibleTableRowFP getAccessibleTableRow;
|
||||||
|
getAccessibleTableColumnFP getAccessibleTableColumn;
|
||||||
|
getAccessibleTableIndexFP getAccessibleTableIndex;
|
||||||
|
|
||||||
|
getAccessibleRelationSetFP getAccessibleRelationSet;
|
||||||
|
|
||||||
|
getAccessibleHypertextFP getAccessibleHypertext;
|
||||||
|
activateAccessibleHyperlinkFP activateAccessibleHyperlink;
|
||||||
|
getAccessibleHyperlinkCountFP getAccessibleHyperlinkCount;
|
||||||
|
getAccessibleHypertextExtFP getAccessibleHypertextExt;
|
||||||
|
getAccessibleHypertextLinkIndexFP getAccessibleHypertextLinkIndex;
|
||||||
|
getAccessibleHyperlinkFP getAccessibleHyperlink;
|
||||||
|
|
||||||
|
getAccessibleKeyBindingsFP getAccessibleKeyBindings;
|
||||||
|
getAccessibleIconsFP getAccessibleIcons;
|
||||||
|
getAccessibleActionsFP getAccessibleActions;
|
||||||
|
doAccessibleActionsFP doAccessibleActions;
|
||||||
|
|
||||||
|
GetAccessibleTextInfoFP GetAccessibleTextInfo;
|
||||||
|
GetAccessibleTextItemsFP GetAccessibleTextItems;
|
||||||
|
GetAccessibleTextSelectionInfoFP GetAccessibleTextSelectionInfo;
|
||||||
|
GetAccessibleTextAttributesFP GetAccessibleTextAttributes;
|
||||||
|
GetAccessibleTextRectFP GetAccessibleTextRect;
|
||||||
|
GetAccessibleTextLineBoundsFP GetAccessibleTextLineBounds;
|
||||||
|
GetAccessibleTextRangeFP GetAccessibleTextRange;
|
||||||
|
|
||||||
|
GetCurrentAccessibleValueFromContextFP GetCurrentAccessibleValueFromContext;
|
||||||
|
GetMaximumAccessibleValueFromContextFP GetMaximumAccessibleValueFromContext;
|
||||||
|
GetMinimumAccessibleValueFromContextFP GetMinimumAccessibleValueFromContext;
|
||||||
|
|
||||||
|
AddAccessibleSelectionFromContextFP AddAccessibleSelectionFromContext;
|
||||||
|
ClearAccessibleSelectionFromContextFP ClearAccessibleSelectionFromContext;
|
||||||
|
GetAccessibleSelectionFromContextFP GetAccessibleSelectionFromContext;
|
||||||
|
GetAccessibleSelectionCountFromContextFP GetAccessibleSelectionCountFromContext;
|
||||||
|
IsAccessibleChildSelectedFromContextFP IsAccessibleChildSelectedFromContext;
|
||||||
|
RemoveAccessibleSelectionFromContextFP RemoveAccessibleSelectionFromContext;
|
||||||
|
SelectAllAccessibleSelectionFromContextFP SelectAllAccessibleSelectionFromContext;
|
||||||
|
|
||||||
|
setTextContentsFP setTextContents;
|
||||||
|
getParentWithRoleFP getParentWithRole;
|
||||||
|
getTopLevelObjectFP getTopLevelObject;
|
||||||
|
getParentWithRoleElseRootFP getParentWithRoleElseRoot;
|
||||||
|
getObjectDepthFP getObjectDepth;
|
||||||
|
getActiveDescendentFP getActiveDescendent;
|
||||||
|
|
||||||
|
getVirtualAccessibleNameFP getVirtualAccessibleName;
|
||||||
|
requestFocusFP requestFocus;
|
||||||
|
selectTextRangeFP selectTextRange;
|
||||||
|
getTextAttributesInRangeFP getTextAttributesInRange;
|
||||||
|
getVisibleChildrenCountFP getVisibleChildrenCount;
|
||||||
|
getVisibleChildrenFP getVisibleChildren;
|
||||||
|
setCaretPositionFP setCaretPosition;
|
||||||
|
getCaretLocationFP getCaretLocation;
|
||||||
|
|
||||||
|
getEventsWaitingFP getEventsWaiting;
|
||||||
|
|
||||||
|
} AccessBridgeFPs;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the world
|
||||||
|
*/
|
||||||
|
BOOL initializeAccessBridge();
|
||||||
|
BOOL shutdownAccessBridge();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Window routines
|
||||||
|
*/
|
||||||
|
BOOL IsJavaWindow(HWND window);
|
||||||
|
|
||||||
|
// Returns the virtual machine ID and AccessibleContext for a top-level window
|
||||||
|
BOOL GetAccessibleContextFromHWND(HWND target, long *vmID, AccessibleContext *ac);
|
||||||
|
|
||||||
|
// Returns the HWND from the AccessibleContext of a top-level window
|
||||||
|
HWND getHWNDFromAccessibleContext(long vmID, AccessibleContext ac);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handling routines
|
||||||
|
*/
|
||||||
|
void SetJavaShutdown(AccessBridge_JavaShutdownFP fp);
|
||||||
|
void SetFocusGained(AccessBridge_FocusGainedFP fp);
|
||||||
|
void SetFocusLost(AccessBridge_FocusLostFP fp);
|
||||||
|
|
||||||
|
void SetCaretUpdate(AccessBridge_CaretUpdateFP fp);
|
||||||
|
|
||||||
|
void SetMouseClicked(AccessBridge_MouseClickedFP fp);
|
||||||
|
void SetMouseEntered(AccessBridge_MouseEnteredFP fp);
|
||||||
|
void SetMouseExited(AccessBridge_MouseExitedFP fp);
|
||||||
|
void SetMousePressed(AccessBridge_MousePressedFP fp);
|
||||||
|
void SetMouseReleased(AccessBridge_MouseReleasedFP fp);
|
||||||
|
|
||||||
|
void SetMenuCanceled(AccessBridge_MenuCanceledFP fp);
|
||||||
|
void SetMenuDeselected(AccessBridge_MenuDeselectedFP fp);
|
||||||
|
void SetMenuSelected(AccessBridge_MenuSelectedFP fp);
|
||||||
|
void SetPopupMenuCanceled(AccessBridge_PopupMenuCanceledFP fp);
|
||||||
|
void SetPopupMenuWillBecomeInvisible(AccessBridge_PopupMenuWillBecomeInvisibleFP fp);
|
||||||
|
void SetPopupMenuWillBecomeVisible(AccessBridge_PopupMenuWillBecomeVisibleFP fp);
|
||||||
|
|
||||||
|
void SetPropertyNameChange(AccessBridge_PropertyNameChangeFP fp);
|
||||||
|
void SetPropertyDescriptionChange(AccessBridge_PropertyDescriptionChangeFP fp);
|
||||||
|
void SetPropertyStateChange(AccessBridge_PropertyStateChangeFP fp);
|
||||||
|
void SetPropertyValueChange(AccessBridge_PropertyValueChangeFP fp);
|
||||||
|
void SetPropertySelectionChange(AccessBridge_PropertySelectionChangeFP fp);
|
||||||
|
void SetPropertyTextChange(AccessBridge_PropertyTextChangeFP fp);
|
||||||
|
void SetPropertyCaretChange(AccessBridge_PropertyCaretChangeFP fp);
|
||||||
|
void SetPropertyVisibleDataChange(AccessBridge_PropertyVisibleDataChangeFP fp);
|
||||||
|
void SetPropertyChildChange(AccessBridge_PropertyChildChangeFP fp);
|
||||||
|
void SetPropertyActiveDescendentChange(AccessBridge_PropertyActiveDescendentChangeFP fp);
|
||||||
|
|
||||||
|
void SetPropertyTableModelChange(AccessBridge_PropertyTableModelChangeFP fp);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General routines
|
||||||
|
*/
|
||||||
|
void ReleaseJavaObject(long vmID, Java_Object object);
|
||||||
|
BOOL GetVersionInfo(long vmID, AccessBridgeVersionInfo *info);
|
||||||
|
HWND GetHWNDFromAccessibleContext(long vmID, JOBJECT64 accesibleContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessible Context routines
|
||||||
|
*/
|
||||||
|
BOOL GetAccessibleContextAt(long vmID, AccessibleContext acParent,
|
||||||
|
jint x, jint y, AccessibleContext *ac);
|
||||||
|
BOOL GetAccessibleContextWithFocus(HWND window, long *vmID, AccessibleContext *ac);
|
||||||
|
BOOL GetAccessibleContextInfo(long vmID, AccessibleContext ac, AccessibleContextInfo *info);
|
||||||
|
AccessibleContext GetAccessibleChildFromContext(long vmID, AccessibleContext ac, jint index);
|
||||||
|
AccessibleContext GetAccessibleParentFromContext(long vmID, AccessibleContext ac);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessible Text routines
|
||||||
|
*/
|
||||||
|
BOOL GetAccessibleTextInfo(long vmID, AccessibleText at, AccessibleTextInfo *textInfo, jint x, jint y);
|
||||||
|
BOOL GetAccessibleTextItems(long vmID, AccessibleText at, AccessibleTextItemsInfo *textItems, jint index);
|
||||||
|
BOOL GetAccessibleTextSelectionInfo(long vmID, AccessibleText at, AccessibleTextSelectionInfo *textSelection);
|
||||||
|
BOOL GetAccessibleTextAttributes(long vmID, AccessibleText at, jint index, AccessibleTextAttributesInfo *attributes);
|
||||||
|
BOOL GetAccessibleTextRect(long vmID, AccessibleText at, AccessibleTextRectInfo *rectInfo, jint index);
|
||||||
|
BOOL GetAccessibleTextLineBounds(long vmID, AccessibleText at, jint index, jint *startIndex, jint *endIndex);
|
||||||
|
BOOL GetAccessibleTextRange(long vmID, AccessibleText at, jint start, jint end, wchar_t *text, short len);
|
||||||
|
|
||||||
|
/* begin AccessibleTable routines */
|
||||||
|
BOOL getAccessibleTableInfo(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo);
|
||||||
|
|
||||||
|
BOOL getAccessibleTableCellInfo(long vmID, AccessibleTable accessibleTable, jint row, jint column,
|
||||||
|
AccessibleTableCellInfo *tableCellInfo);
|
||||||
|
|
||||||
|
BOOL getAccessibleTableRowHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo);
|
||||||
|
BOOL getAccessibleTableColumnHeader(long vmID, AccessibleContext acParent, AccessibleTableInfo *tableInfo);
|
||||||
|
|
||||||
|
AccessibleContext getAccessibleTableRowDescription(long vmID, AccessibleContext acParent, jint row);
|
||||||
|
AccessibleContext getAccessibleTableColumnDescription(long vmID, AccessibleContext acParent, jint column);
|
||||||
|
|
||||||
|
jint getAccessibleTableRowSelectionCount(long vmID, AccessibleTable table);
|
||||||
|
BOOL isAccessibleTableRowSelected(long vmID, AccessibleTable table, jint row);
|
||||||
|
BOOL getAccessibleTableRowSelections(long vmID, AccessibleTable table, jint count, jint *selections);
|
||||||
|
|
||||||
|
jint getAccessibleTableColumnSelectionCount(long vmID, AccessibleTable table);
|
||||||
|
BOOL isAccessibleTableColumnSelected(long vmID, AccessibleTable table, jint column);
|
||||||
|
BOOL getAccessibleTableColumnSelections(long vmID, AccessibleTable table, jint count, jint *selections);
|
||||||
|
|
||||||
|
jint getAccessibleTableRow(long vmID, AccessibleTable table, jint index);
|
||||||
|
jint getAccessibleTableColumn(long vmID, AccessibleTable table, jint index);
|
||||||
|
jint getAccessibleTableIndex(long vmID, AccessibleTable table, jint row, jint column);
|
||||||
|
/* end AccessibleTable */
|
||||||
|
|
||||||
|
/* ----- AccessibleRelationSet routines */
|
||||||
|
BOOL getAccessibleRelationSet(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleRelationSetInfo *relationSetInfo);
|
||||||
|
|
||||||
|
/* ----- AccessibleHypertext routines */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns hypertext information associated with a component.
|
||||||
|
*/
|
||||||
|
BOOL getAccessibleHypertext(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleHypertextInfo *hypertextInfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Requests that a hyperlink be activated.
|
||||||
|
*/
|
||||||
|
BOOL activateAccessibleHyperlink(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleHyperlink accessibleHyperlink);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the number of hyperlinks in a component
|
||||||
|
* Maps to AccessibleHypertext.getLinkCount.
|
||||||
|
* Returns -1 on error.
|
||||||
|
*/
|
||||||
|
jint getAccessibleHyperlinkCount(const long vmID,
|
||||||
|
const AccessibleHypertext hypertext);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This method is used to iterate through the hyperlinks in a component. It
|
||||||
|
* returns hypertext information for a component starting at hyperlink index
|
||||||
|
* nStartIndex. No more than MAX_HYPERLINKS AccessibleHypertextInfo objects will
|
||||||
|
* be returned for each call to this method.
|
||||||
|
* Returns FALSE on error.
|
||||||
|
*/
|
||||||
|
BOOL getAccessibleHypertextExt(const long vmID,
|
||||||
|
const AccessibleContext accessibleContext,
|
||||||
|
const jint nStartIndex,
|
||||||
|
/* OUT */ AccessibleHypertextInfo *hypertextInfo);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the index into an array of hyperlinks that is associated with
|
||||||
|
* a character index in document; maps to AccessibleHypertext.getLinkIndex
|
||||||
|
* Returns -1 on error.
|
||||||
|
*/
|
||||||
|
jint getAccessibleHypertextLinkIndex(const long vmID,
|
||||||
|
const AccessibleHypertext hypertext,
|
||||||
|
const jint nIndex);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the nth hyperlink in a document
|
||||||
|
* Maps to AccessibleHypertext.getLink.
|
||||||
|
* Returns FALSE on error
|
||||||
|
*/
|
||||||
|
BOOL getAccessibleHyperlink(const long vmID,
|
||||||
|
const AccessibleHypertext hypertext,
|
||||||
|
const jint nIndex,
|
||||||
|
/* OUT */ AccessibleHyperlinkInfo *hyperlinkInfo);
|
||||||
|
|
||||||
|
/* Accessible KeyBindings, Icons and Actions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a list of key bindings associated with a component.
|
||||||
|
*/
|
||||||
|
BOOL getAccessibleKeyBindings(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleKeyBindings *keyBindings);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a list of icons associate with a component.
|
||||||
|
*/
|
||||||
|
BOOL getAccessibleIcons(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleIcons *icons);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a list of actions that a component can perform.
|
||||||
|
*/
|
||||||
|
BOOL getAccessibleActions(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleActions *actions);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Request that a list of AccessibleActions be performed by a component.
|
||||||
|
* Returns TRUE if all actions are performed. Returns FALSE
|
||||||
|
* when the first requested action fails in which case "failure"
|
||||||
|
* contains the index of the action that failed.
|
||||||
|
*/
|
||||||
|
BOOL doAccessibleActions(long vmID, AccessibleContext accessibleContext,
|
||||||
|
AccessibleActionsToDo *actionsToDo, jint *failure);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Additional utility methods */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns whether two object references refer to the same object.
|
||||||
|
*/
|
||||||
|
BOOL IsSameObject(long vmID, JOBJECT64 obj1, JOBJECT64 obj2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets editable text contents. The AccessibleContext must implement AccessibleEditableText and
|
||||||
|
* be editable. The maximum text length that can be set is MAX_STRING_SIZE - 1.
|
||||||
|
* Returns whether successful
|
||||||
|
*/
|
||||||
|
BOOL setTextContents (const long vmID, const AccessibleContext accessibleContext, const wchar_t *text);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Accessible Context with the specified role that is the
|
||||||
|
* ancestor of a given object. The role is one of the role strings
|
||||||
|
* defined in AccessBridgePackages.h
|
||||||
|
* If there is no ancestor object that has the specified role,
|
||||||
|
* returns (AccessibleContext)0.
|
||||||
|
*/
|
||||||
|
AccessibleContext getParentWithRole (const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
const wchar_t *role);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Accessible Context with the specified role that is the
|
||||||
|
* ancestor of a given object. The role is one of the role strings
|
||||||
|
* defined in AccessBridgePackages.h. If an object with the specified
|
||||||
|
* role does not exist, returns the top level object for the Java Window.
|
||||||
|
* Returns (AccessibleContext)0 on error.
|
||||||
|
*/
|
||||||
|
AccessibleContext getParentWithRoleElseRoot (const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
const wchar_t *role);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Accessible Context for the top level object in
|
||||||
|
* a Java Window. This is same Accessible Context that is obtained
|
||||||
|
* from GetAccessibleContextFromHWND for that window. Returns
|
||||||
|
* (AccessibleContext)0 on error.
|
||||||
|
*/
|
||||||
|
AccessibleContext getTopLevelObject (const long vmID, const AccessibleContext accessibleContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns how deep in the object hierarchy a given object is.
|
||||||
|
* The top most object in the object hierarchy has an object depth of 0.
|
||||||
|
* Returns -1 on error.
|
||||||
|
*/
|
||||||
|
int getObjectDepth (const long vmID, const AccessibleContext accessibleContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Accessible Context of the current ActiveDescendent of an object.
|
||||||
|
* This method assumes the ActiveDescendent is the component that is currently
|
||||||
|
* selected in a container object.
|
||||||
|
* Returns (AccessibleContext)0 on error or if there is no selection.
|
||||||
|
*/
|
||||||
|
AccessibleContext getActiveDescendent (const long vmID, const AccessibleContext accessibleContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
/**
|
||||||
|
* Accessible Value routines
|
||||||
|
*/
|
||||||
|
BOOL GetCurrentAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len);
|
||||||
|
BOOL GetMaximumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len);
|
||||||
|
BOOL GetMinimumAccessibleValueFromContext(long vmID, AccessibleValue av, wchar_t *value, short len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessible Selection routines
|
||||||
|
*/
|
||||||
|
void AddAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i);
|
||||||
|
void ClearAccessibleSelectionFromContext(long vmID, AccessibleSelection as);
|
||||||
|
JOBJECT64 GetAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i);
|
||||||
|
int GetAccessibleSelectionCountFromContext(long vmID, AccessibleSelection as);
|
||||||
|
BOOL IsAccessibleChildSelectedFromContext(long vmID, AccessibleSelection as, int i);
|
||||||
|
void RemoveAccessibleSelectionFromContext(long vmID, AccessibleSelection as, int i);
|
||||||
|
void SelectAllAccessibleSelectionFromContext(long vmID, AccessibleSelection as);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Additional methods for Teton
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the AccessibleName for a component based upon the JAWS algorithm. Returns
|
||||||
|
* whether successful.
|
||||||
|
*
|
||||||
|
* Bug ID 4916682 - Implement JAWS AccessibleName policy
|
||||||
|
*/
|
||||||
|
BOOL getVirtualAccessibleName(const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
wchar_t *name, int len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request focus for a component. Returns whether successful.
|
||||||
|
*
|
||||||
|
* Bug ID 4944757 - requestFocus method needed
|
||||||
|
*/
|
||||||
|
BOOL requestFocus(const long vmID, const AccessibleContext accessibleContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects text between two indices. Selection includes the text at the start index
|
||||||
|
* and the text at the end index. Returns whether successful.
|
||||||
|
*
|
||||||
|
* Bug ID 4944758 - selectTextRange method needed
|
||||||
|
*/
|
||||||
|
BOOL selectTextRange(const long vmID, const AccessibleContext accessibleContext, const int startIndex,
|
||||||
|
const int endIndex);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get text attributes between two indices. The attribute list includes the text at the
|
||||||
|
* start index and the text at the end index. Returns whether successful;
|
||||||
|
*
|
||||||
|
* Bug ID 4944761 - getTextAttributes between two indices method needed
|
||||||
|
*/
|
||||||
|
BOOL getTextAttributesInRange(const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
const int startIndex, const int endIndex,
|
||||||
|
AccessibleTextAttributesInfo *attributes, short *len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of visible children of a component. Returns -1 on error.
|
||||||
|
*
|
||||||
|
* Bug ID 4944762- getVisibleChildren for list-like components needed
|
||||||
|
*/
|
||||||
|
int getVisibleChildrenCount(const long vmID, const AccessibleContext accessibleContext);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the visible children of an AccessibleContext. Returns whether successful.
|
||||||
|
*
|
||||||
|
* Bug ID 4944762- getVisibleChildren for list-like components needed
|
||||||
|
*/
|
||||||
|
BOOL getVisibleChildren(const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
const int startIndex,
|
||||||
|
VisibleChildrenInfo *visibleChildrenInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the caret to a text position. Returns whether successful.
|
||||||
|
*
|
||||||
|
* Bug ID 4944770 - setCaretPosition method needed
|
||||||
|
*/
|
||||||
|
BOOL setCaretPosition(const long vmID, const AccessibleContext accessibleContext,
|
||||||
|
const int position);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the text caret location
|
||||||
|
*/
|
||||||
|
BOOL getCaretLocation(long vmID, AccessibleContext ac,
|
||||||
|
AccessibleTextRectInfo *rectInfo, jint index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of events waiting to fire
|
||||||
|
*/
|
||||||
|
int getEventsWaiting();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JAVASOFT_JAWT_MD_H_
|
||||||
|
#define _JAVASOFT_JAWT_MD_H_
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include "jawt.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Win32-specific declarations for AWT native interface.
|
||||||
|
* See notes in jawt.h for an example of use.
|
||||||
|
*/
|
||||||
|
typedef struct jawt_Win32DrawingSurfaceInfo {
|
||||||
|
/* Native window, DDB, or DIB handle */
|
||||||
|
union {
|
||||||
|
HWND hwnd;
|
||||||
|
HBITMAP hbitmap;
|
||||||
|
void* pbits;
|
||||||
|
};
|
||||||
|
/*
|
||||||
|
* This HDC should always be used instead of the HDC returned from
|
||||||
|
* BeginPaint() or any calls to GetDC().
|
||||||
|
*/
|
||||||
|
HDC hdc;
|
||||||
|
HPALETTE hpalette;
|
||||||
|
} JAWT_Win32DrawingSurfaceInfo;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !_JAVASOFT_JAWT_MD_H_ */
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 1996, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _JAVASOFT_JNI_MD_H_
|
||||||
|
#define _JAVASOFT_JNI_MD_H_
|
||||||
|
|
||||||
|
#define JNIEXPORT __declspec(dllexport)
|
||||||
|
#define JNIIMPORT __declspec(dllimport)
|
||||||
|
#define JNICALL __stdcall
|
||||||
|
|
||||||
|
typedef long jint;
|
||||||
|
typedef __int64 jlong;
|
||||||
|
typedef signed char jbyte;
|
||||||
|
|
||||||
|
#endif /* !_JAVASOFT_JNI_MD_H_ */
|
@ -0,0 +1,207 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <jni.h>
|
||||||
|
#include <jni_md.h>
|
||||||
|
#include <jvmti.h>
|
||||||
|
#include "arthas_VmTool.h" // under target/native/javah/
|
||||||
|
|
||||||
|
|
||||||
|
static jvmtiEnv *jvmti;
|
||||||
|
static jlong tagCounter = 0;
|
||||||
|
|
||||||
|
struct LimitCounter {
|
||||||
|
jint currentCounter;
|
||||||
|
jint limitValue;
|
||||||
|
|
||||||
|
void init(jint limit) {
|
||||||
|
currentCounter = 0;
|
||||||
|
limitValue = limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void countDown() {
|
||||||
|
currentCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool allow() {
|
||||||
|
if (limitValue < 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return limitValue > currentCounter;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 每次 IterateOverInstancesOfClass 调用前需要先 init
|
||||||
|
static LimitCounter limitCounter = {0, 0};
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
int init_agent(JavaVM *vm, void *reserved) {
|
||||||
|
jint rc;
|
||||||
|
/* Get JVMTI environment */
|
||||||
|
rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION_1_2);
|
||||||
|
if (rc != JNI_OK) {
|
||||||
|
fprintf(stderr, "ERROR: arthas vmtool Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
jvmtiCapabilities capabilities = {0};
|
||||||
|
capabilities.can_tag_objects = 1;
|
||||||
|
jvmtiError error = jvmti->AddCapabilities(&capabilities);
|
||||||
|
if (error) {
|
||||||
|
fprintf(stderr, "ERROR: arthas vmtool JVMTI AddCapabilities failed!%u\n", error);
|
||||||
|
return JNI_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return JNI_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
|
||||||
|
return init_agent(vm, reserved);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
Agent_OnAttach(JavaVM* vm, char* options, void* reserved) {
|
||||||
|
return init_agent(vm, reserved);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" JNIEXPORT jint JNICALL
|
||||||
|
JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
|
init_agent(vm, reserved);
|
||||||
|
return JNI_VERSION_1_6;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_arthas_VmTool_forceGc0(JNIEnv *env, jclass thisClass) {
|
||||||
|
jvmti->ForceGarbageCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
jlong getTag() {
|
||||||
|
return ++tagCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
jvmtiIterationControl JNICALL
|
||||||
|
HeapObjectCallback(jlong class_tag, jlong size, jlong *tag_ptr, void *user_data) {
|
||||||
|
jlong *data = static_cast<jlong *>(user_data);
|
||||||
|
*tag_ptr = *data;
|
||||||
|
|
||||||
|
limitCounter.countDown();
|
||||||
|
if (limitCounter.allow()) {
|
||||||
|
return JVMTI_ITERATION_CONTINUE;
|
||||||
|
}else {
|
||||||
|
return JVMTI_ITERATION_ABORT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobjectArray JNICALL
|
||||||
|
Java_arthas_VmTool_getInstances0(JNIEnv *env, jclass thisClass, jclass klass, jint limit) {
|
||||||
|
jlong tag = getTag();
|
||||||
|
limitCounter.init(limit);
|
||||||
|
jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER,
|
||||||
|
HeapObjectCallback, &tag);
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: JVMTI IterateOverInstancesOfClass failed!%u\n", error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jint count = 0;
|
||||||
|
jobject *instances;
|
||||||
|
error = jvmti->GetObjectsWithTags(1, &tag, &count, &instances, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: JVMTI GetObjectsWithTags failed!%u\n", error);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobjectArray array = env->NewObjectArray(count, klass, NULL);
|
||||||
|
//添加元素到数组
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
env->SetObjectArrayElement(array, i, instances[i]);
|
||||||
|
}
|
||||||
|
jvmti->Deallocate(reinterpret_cast<unsigned char *>(instances));
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
Java_arthas_VmTool_sumInstanceSize0(JNIEnv *env, jclass thisClass, jclass klass) {
|
||||||
|
jlong tag = getTag();
|
||||||
|
limitCounter.init(-1);
|
||||||
|
jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER,
|
||||||
|
HeapObjectCallback, &tag);
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: JVMTI IterateOverInstancesOfClass failed!%u\n", error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
jint count = 0;
|
||||||
|
jobject *instances;
|
||||||
|
error = jvmti->GetObjectsWithTags(1, &tag, &count, &instances, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: JVMTI GetObjectsWithTags failed!%u\n", error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
jlong sum = 0;
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
jlong size = 0;
|
||||||
|
jvmti->GetObjectSize(instances[i], &size);
|
||||||
|
sum = sum + size;
|
||||||
|
}
|
||||||
|
jvmti->Deallocate(reinterpret_cast<unsigned char *>(instances));
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jlong JNICALL Java_arthas_VmTool_getInstanceSize0
|
||||||
|
(JNIEnv *env, jclass thisClass, jobject instance) {
|
||||||
|
jlong size = -1;
|
||||||
|
jvmtiError error = jvmti->GetObjectSize(instance, &size);
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: JVMTI GetObjectSize failed!%u\n", error);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jlong JNICALL
|
||||||
|
Java_arthas_VmTool_countInstances0(JNIEnv *env, jclass thisClass, jclass klass) {
|
||||||
|
jlong tag = getTag();
|
||||||
|
limitCounter.init(-1);
|
||||||
|
jvmtiError error = jvmti->IterateOverInstancesOfClass(klass, JVMTI_HEAP_OBJECT_EITHER,
|
||||||
|
HeapObjectCallback, &tag);
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: JVMTI IterateOverInstancesOfClass failed!%u\n", error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
jint count = 0;
|
||||||
|
error = jvmti->GetObjectsWithTags(1, &tag, &count, NULL, NULL);
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: JVMTI GetObjectsWithTags failed!%u\n", error);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobjectArray JNICALL Java_arthas_VmTool_getAllLoadedClasses0
|
||||||
|
(JNIEnv *env, jclass thisClass, jclass kclass) {
|
||||||
|
jclass *classes;
|
||||||
|
jint count = 0;
|
||||||
|
|
||||||
|
jvmtiError error = jvmti->GetLoadedClasses(&count, &classes);
|
||||||
|
if (error) {
|
||||||
|
printf("ERROR: JVMTI GetLoadedClasses failed!\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jobjectArray array = env->NewObjectArray(count, kclass, NULL);
|
||||||
|
//添加元素到数组
|
||||||
|
for (int i = 0; i < count; i++) {
|
||||||
|
env->SetObjectArrayElement(array, i, classes[i]);
|
||||||
|
}
|
||||||
|
jvmti->Deallocate(reinterpret_cast<unsigned char *>(classes));
|
||||||
|
return array;
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,92 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>com.taobao.arthas</groupId>
|
|
||||||
<artifactId>arthas-all</artifactId>
|
|
||||||
<version>3.4.4-SNAPSHOT</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
<artifactId>arthas-bytekit</artifactId>
|
|
||||||
<name>arthas-bytekit</name>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.taobao.arthas</groupId>
|
|
||||||
<artifactId>arthas-common</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.alibaba.arthas</groupId>
|
|
||||||
<artifactId>arthas-repackage-asm</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.benf</groupId>
|
|
||||||
<artifactId>cfr</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.bytebuddy</groupId>
|
|
||||||
<artifactId>byte-buddy</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.bytebuddy</groupId>
|
|
||||||
<artifactId>byte-buddy-agent</artifactId>
|
|
||||||
<scope>provided</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Test Artifacts -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>junit</groupId>
|
|
||||||
<artifactId>junit</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.assertj</groupId>
|
|
||||||
<artifactId>assertj-core</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-test</artifactId>
|
|
||||||
<version>1.5.9.RELEASE</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.taobao.arthas</groupId>
|
|
||||||
<artifactId>arthas-demo</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
|
|
||||||
<build>
|
|
||||||
<finalName>arthas-bytekit</finalName>
|
|
||||||
<plugins>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
|
||||||
<configuration>
|
|
||||||
<source>1.6</source>
|
|
||||||
<target>1.6</target>
|
|
||||||
<encoding>UTF-8</encoding>
|
|
||||||
<showDeprecation>true</showDeprecation>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
|
||||||
</plugins>
|
|
||||||
</build>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,22 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.asm.interceptor.InterceptorProcessor;
|
|
||||||
import com.taobao.arthas.bytekit.asm.interceptor.parser.InterceptorClassParser;
|
|
||||||
import com.taobao.arthas.bytekit.asm.matcher.ClassMatcher;
|
|
||||||
import com.taobao.arthas.bytekit.asm.matcher.MethodMatcher;
|
|
||||||
|
|
||||||
public class ByteKit {
|
|
||||||
|
|
||||||
|
|
||||||
private ClassMatcher classMatcher;
|
|
||||||
private MethodMatcher methodMatcher;
|
|
||||||
|
|
||||||
private Class<?> interceptorClass;
|
|
||||||
|
|
||||||
private InterceptorClassParser interceptorClassParser;
|
|
||||||
|
|
||||||
private List<InterceptorProcessor> interceptorProcessors;
|
|
||||||
}
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Label;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Opcodes;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.commons.LocalVariablesSorter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adapter for to be inlined code.
|
|
||||||
*
|
|
||||||
* This adapter does all parameter renaming and replacing of the RETURN opcodes
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class InliningAdapter extends LocalVariablesSorter {
|
|
||||||
private final Label end;
|
|
||||||
private LocalVariablesSorter lvs;
|
|
||||||
|
|
||||||
public InliningAdapter(LocalVariablesSorter mv, int access, String desc, Label end) {
|
|
||||||
super(Opcodes.ASM9, access, desc, mv);
|
|
||||||
this.end = end;
|
|
||||||
this.lvs = mv;
|
|
||||||
|
|
||||||
// int off = (access & Opcodes.ACC_STATIC) != 0 ?
|
|
||||||
// 0 : 1;
|
|
||||||
// Type[] args = Type.getArgumentTypes(desc);
|
|
||||||
// for (int i = args.length - 1; i >= 0; i--) {
|
|
||||||
// super.visitVarInsn(args[i].getOpcode(
|
|
||||||
// Opcodes.ISTORE), i + off);
|
|
||||||
// }
|
|
||||||
// if (off > 0) {
|
|
||||||
// super.visitVarInsn(Opcodes.ASTORE, 0);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// save args to local vars
|
|
||||||
int off = (access & Opcodes.ACC_STATIC) != 0 ? 0 : 1;
|
|
||||||
Type[] args = Type.getArgumentTypes(desc);
|
|
||||||
int argsOff = off;
|
|
||||||
|
|
||||||
for(int i = 0; i < args.length; ++i) {
|
|
||||||
argsOff += args[i].getSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = args.length - 1; i >= 0; --i) {
|
|
||||||
argsOff -= args[i].getSize();
|
|
||||||
this.visitVarInsn(args[i].getOpcode(Opcodes.ISTORE), argsOff);
|
|
||||||
}
|
|
||||||
|
|
||||||
// this
|
|
||||||
if (off > 0) {
|
|
||||||
this.visitVarInsn(Opcodes.ASTORE, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitInsn(int opcode) {
|
|
||||||
if (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN) {
|
|
||||||
super.visitJumpInsn(Opcodes.GOTO, end);
|
|
||||||
} else {
|
|
||||||
super.visitInsn(opcode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitMaxs(int stack, int locals) {
|
|
||||||
// super.visitMaxs(stack, locals);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected int newLocalMapping(Type type) {
|
|
||||||
return lvs.newLocal(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitVarInsn(int opcode, int var) {
|
|
||||||
super.visitVarInsn(opcode, var + this.firstLocal);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void visitIincInsn(int var, int increment) {
|
|
||||||
super.visitIincInsn(var + this.firstLocal, increment);
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
|
|
||||||
super.visitLocalVariable(name, desc, signature, start, end, index + this.firstLocal);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Label;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.MethodVisitor;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Opcodes;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.commons.GeneratorAdapter;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author hengyunabc 2018-01-31
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class MethodCallInliner extends GeneratorAdapter {
|
|
||||||
public class CatchBlock {
|
|
||||||
|
|
||||||
private Label start;
|
|
||||||
private Label handler;
|
|
||||||
private String type;
|
|
||||||
private Label end;
|
|
||||||
|
|
||||||
public CatchBlock(Label start, Label end, Label handler, String type) {
|
|
||||||
this.start = start;
|
|
||||||
this.end = end;
|
|
||||||
this.handler = handler;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private final MethodNode toBeInlined;
|
|
||||||
private List<CatchBlock> blocks = new ArrayList<CatchBlock>();
|
|
||||||
private boolean inlining;
|
|
||||||
private boolean afterInlining;
|
|
||||||
|
|
||||||
public MethodCallInliner(int access, String name, String desc, MethodVisitor mv,
|
|
||||||
MethodNode toBeInlined) {
|
|
||||||
super(Opcodes.ASM9, mv, access, name, desc);
|
|
||||||
this.toBeInlined = toBeInlined;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
|
|
||||||
if (!shouldBeInlined(owner, name, desc)) {
|
|
||||||
mv.visitMethodInsn(opcode, owner, name, desc, itf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (this.analyzerAdapter != null) {
|
|
||||||
// mv = new MergeFrameAdapter(this.api, this.analyzerAdapter,
|
|
||||||
// (MethodVisitor)mv);
|
|
||||||
// }
|
|
||||||
|
|
||||||
Label end = new Label();
|
|
||||||
inlining = true;
|
|
||||||
toBeInlined.instructions.resetLabels();
|
|
||||||
|
|
||||||
// pass the to be inlined method through the inlining adapter to this
|
|
||||||
toBeInlined.accept(new InliningAdapter(this, toBeInlined.access, toBeInlined.desc, end));
|
|
||||||
inlining = false;
|
|
||||||
afterInlining = true;
|
|
||||||
|
|
||||||
// visit the end label
|
|
||||||
super.visitLabel(end);
|
|
||||||
|
|
||||||
// box the return value if necessary
|
|
||||||
// Type returnType =
|
|
||||||
// Type.getMethodType(toBeInlined.desc).getReturnType();
|
|
||||||
// valueOf(returnType);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract boolean shouldBeInlined(String owner, String name, String desc);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
|
|
||||||
if (!inlining) {
|
|
||||||
blocks.add(new CatchBlock(start, end, handler, type));
|
|
||||||
} else {
|
|
||||||
super.visitTryCatchBlock(start, end, handler, type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitMaxs(int stack, int locals) {
|
|
||||||
for (CatchBlock b : blocks)
|
|
||||||
super.visitTryCatchBlock(b.start, b.end, b.handler, b.type);
|
|
||||||
super.visitMaxs(stack, locals);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) {
|
|
||||||
// swallow
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author hengyunabc 2019-03-18
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MethodInfo {
|
|
||||||
|
|
||||||
private String owner;
|
|
||||||
|
|
||||||
private int access;
|
|
||||||
private String name;
|
|
||||||
private String desc;
|
|
||||||
|
|
||||||
public int getAccess() {
|
|
||||||
return access;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAccess(int access) {
|
|
||||||
this.access = access;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setName(String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDesc() {
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDesc(String desc) {
|
|
||||||
this.desc = desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOwner() {
|
|
||||||
return owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOwner(String owner) {
|
|
||||||
this.owner = owner;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.LabelNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.TryCatchBlockNode;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class MyTryCatchBlock {
|
|
||||||
private final MethodNode methodNode;
|
|
||||||
private final LabelNode startLabelNode = new LabelNode();
|
|
||||||
private final LabelNode endLabelNode = new LabelNode();
|
|
||||||
private final LabelNode handlerLabelNode = new LabelNode();
|
|
||||||
|
|
||||||
public MyTryCatchBlock(final MethodNode methodNode) {
|
|
||||||
this.methodNode = methodNode;
|
|
||||||
|
|
||||||
final TryCatchBlockNode tryCatchBlockNode = new TryCatchBlockNode(this.startLabelNode, this.endLabelNode, this.handlerLabelNode, "java/lang/Throwable");
|
|
||||||
if (this.methodNode.tryCatchBlocks == null) {
|
|
||||||
this.methodNode.tryCatchBlocks = new ArrayList<TryCatchBlockNode>();
|
|
||||||
}
|
|
||||||
this.methodNode.tryCatchBlocks.add(tryCatchBlockNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LabelNode getStartLabelNode() {
|
|
||||||
return this.startLabelNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LabelNode getEndLabelNode() {
|
|
||||||
return this.endLabelNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LabelNode getHandlerLabelNode() {
|
|
||||||
return this.handlerLabelNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sort() {
|
|
||||||
if (this.methodNode.tryCatchBlocks == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compares TryCatchBlockNodes by the length of their "try" block.
|
|
||||||
Collections.sort(this.methodNode.tryCatchBlocks, new Comparator<TryCatchBlockNode>() {
|
|
||||||
@Override
|
|
||||||
public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) {
|
|
||||||
int len1 = blockLength(t1);
|
|
||||||
int len2 = blockLength(t2);
|
|
||||||
return len1 - len2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int blockLength(TryCatchBlockNode block) {
|
|
||||||
final int startidx = methodNode.instructions.indexOf(block.start);
|
|
||||||
final int endidx = methodNode.instructions.indexOf(block.end);
|
|
||||||
return endidx - startidx;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Updates the 'target' of each try catch block annotation.
|
|
||||||
for (int i = 0; i < this.methodNode.tryCatchBlocks.size(); i++) {
|
|
||||||
this.methodNode.tryCatchBlocks.get(i).updateIndex(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.LabelNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.TryCatchBlockNode;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class TryCatchBlock {
|
|
||||||
private final MethodNode methodNode;
|
|
||||||
private final LabelNode startLabelNode = new LabelNode();
|
|
||||||
private final LabelNode endLabelNode = new LabelNode();
|
|
||||||
|
|
||||||
public TryCatchBlock(final MethodNode methodNode) {
|
|
||||||
this(methodNode, Type.getType(Throwable.class).getInternalName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public TryCatchBlock(final MethodNode methodNode, String exception) {
|
|
||||||
this.methodNode = methodNode;
|
|
||||||
|
|
||||||
final TryCatchBlockNode tryCatchBlockNode = new TryCatchBlockNode(this.startLabelNode, this.endLabelNode,
|
|
||||||
this.endLabelNode, exception);
|
|
||||||
if (this.methodNode.tryCatchBlocks == null) {
|
|
||||||
this.methodNode.tryCatchBlocks = new ArrayList<TryCatchBlockNode>();
|
|
||||||
}
|
|
||||||
this.methodNode.tryCatchBlocks.add(tryCatchBlockNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
public LabelNode getStartLabelNode() {
|
|
||||||
return this.startLabelNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LabelNode getEndLabelNode() {
|
|
||||||
return this.endLabelNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sort() {
|
|
||||||
if (this.methodNode.tryCatchBlocks == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compares TryCatchBlockNodes by the length of their "try" block.
|
|
||||||
Collections.sort(this.methodNode.tryCatchBlocks, new Comparator<TryCatchBlockNode>() {
|
|
||||||
@Override
|
|
||||||
public int compare(TryCatchBlockNode t1, TryCatchBlockNode t2) {
|
|
||||||
int len1 = blockLength(t1);
|
|
||||||
int len2 = blockLength(t2);
|
|
||||||
return len1 - len2;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int blockLength(TryCatchBlockNode block) {
|
|
||||||
final int startidx = methodNode.instructions.indexOf(block.start);
|
|
||||||
final int endidx = methodNode.instructions.indexOf(block.end);
|
|
||||||
return endidx - startidx;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Updates the 'target' of each try catch block annotation.
|
|
||||||
for (int i = 0; i < this.methodNode.tryCatchBlocks.size(); i++) {
|
|
||||||
this.methodNode.tryCatchBlocks.get(i).updateIndex(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,431 +0,0 @@
|
|||||||
/*
|
|
||||||
* JBoss, Home of Professional Open Source
|
|
||||||
* Copyright 2008-10 Red Hat and individual contributors
|
|
||||||
* by the @authors tag. See the copyright.txt in the distribution for a
|
|
||||||
* full listing of individual contributors.
|
|
||||||
*
|
|
||||||
* This is free software; you can redistribute it and/or modify it
|
|
||||||
* under the terms of the GNU Lesser General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2.1 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This software is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this software; if not, write to the Free
|
|
||||||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
||||||
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
|
|
||||||
*
|
|
||||||
* @authors Andrew Dinn
|
|
||||||
*/
|
|
||||||
package com.taobao.arthas.bytekit.asm;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helpoer class providing static methods for manipulating type and class names,
|
|
||||||
* field and method descriptor names etc
|
|
||||||
*/
|
|
||||||
public class TypeHelper {
|
|
||||||
|
|
||||||
public static boolean equalDescriptors(String desc1, String desc2)
|
|
||||||
{
|
|
||||||
int idx1 = 0, idx2 = 0;
|
|
||||||
int len1 = desc1.length(), len2 = desc2.length();
|
|
||||||
while (idx1 < len1) {
|
|
||||||
// check the other has not dropped off the end
|
|
||||||
if (idx2 == len2) {
|
|
||||||
if ((idx1 == (len1 - 1)) && (desc1.charAt(idx1) == '$')) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// check type is the same
|
|
||||||
char char1 = desc1.charAt(idx1);
|
|
||||||
char char2 = desc2.charAt(idx2);
|
|
||||||
// if we have a $ at the end of the descriptor then this means any return
|
|
||||||
// type so special case this
|
|
||||||
if ((char1 == '$' && idx1 == len1 - 1) || (char2 == '$' && idx2 == len2 - 1)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// otherwise the chars must match
|
|
||||||
if (char1 != char2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// however an L indicates a class name and we allow a classname without a package
|
|
||||||
// to match a class name with a package
|
|
||||||
if (char1 == 'L') {
|
|
||||||
// ok, ensure the names must match modulo a missing package
|
|
||||||
int end1 = idx1 + 1;
|
|
||||||
int end2 = idx2 + 1;
|
|
||||||
while (end1 < len1 && desc1.charAt(end1) != ';') {
|
|
||||||
end1++;
|
|
||||||
}
|
|
||||||
while (end2 < len2 && desc2.charAt(end2) != ';') {
|
|
||||||
end2++;
|
|
||||||
}
|
|
||||||
if (end1 == len1 || end2 == len2) {
|
|
||||||
// bad format for desc!!
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
String typeName1 = desc1.substring(idx1 + 1, end1);
|
|
||||||
String typeName2 = desc2.substring(idx2 + 1, end2);
|
|
||||||
if (!typeName1.equals(typeName2)) {
|
|
||||||
int tailIdx1 = typeName1.lastIndexOf('/');
|
|
||||||
int tailIdx2 = typeName2.lastIndexOf('/');
|
|
||||||
if (tailIdx1 > 0) {
|
|
||||||
if (tailIdx2 > 0) {
|
|
||||||
// both specify packages so they must be different types
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
// only type 1 specifies a package so type 2 should match the tail
|
|
||||||
if (!typeName2.equals(typeName1.substring(tailIdx1 + 1))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (tailIdx2 > 0) {
|
|
||||||
// only type 2 specifies a package so type 1 should match the tail
|
|
||||||
if (!typeName1.equals(typeName2.substring(tailIdx2 + 1))) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// neither specify packages so they must be different types
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// skp past ';'s
|
|
||||||
idx1 = end1;
|
|
||||||
idx2 = end2;
|
|
||||||
}
|
|
||||||
idx1++;
|
|
||||||
idx2++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check the other has not reached the end
|
|
||||||
if (idx2 != len2) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* convert a classname from canonical form to the form used to represent it externally i.e. replace
|
|
||||||
* all dots with slashes
|
|
||||||
*
|
|
||||||
* @param className the canonical name
|
|
||||||
* @return the external name
|
|
||||||
*/
|
|
||||||
public static String externalizeClass(String className)
|
|
||||||
{
|
|
||||||
return className.replace('.', '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert a classname from external form to canonical form i.e. replace
|
|
||||||
* all slashes with dots
|
|
||||||
*
|
|
||||||
* @param className the external name
|
|
||||||
* @return the canonical name
|
|
||||||
*/
|
|
||||||
public static String internalizeClass(String className)
|
|
||||||
{
|
|
||||||
String result = className;
|
|
||||||
int length = result.length();
|
|
||||||
if (result.charAt(length - 1) == ';') {
|
|
||||||
result = result.substring(1, length - 2);
|
|
||||||
}
|
|
||||||
result = result.replace('/', '.');
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert a type name from canonical form to the form used to represent it externally i.e.
|
|
||||||
* replace primitive type names by the appropriate single letter types, class names
|
|
||||||
* by the externalized class name bracketed by 'L' and ';' and array names by the
|
|
||||||
* base type name preceded by '['.
|
|
||||||
*
|
|
||||||
* @param typeName the type name
|
|
||||||
* @return the external name
|
|
||||||
*/
|
|
||||||
public static String externalizeType(String typeName)
|
|
||||||
{
|
|
||||||
String externalName = "";
|
|
||||||
String[] typeAndArrayIndices = typeName.split("\\[");
|
|
||||||
String baseType = typeAndArrayIndices[0].trim();
|
|
||||||
for (int i = 1; i< typeAndArrayIndices.length; i++) {
|
|
||||||
String arrayIdx = typeAndArrayIndices[i];
|
|
||||||
if (arrayIdx.indexOf("\\]") != 0) {
|
|
||||||
externalName += '[';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < internalNames.length; i++) {
|
|
||||||
if (internalNames[i].equals(baseType)) {
|
|
||||||
externalName += externalNames[i];
|
|
||||||
return externalName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
externalName += "L" + externalizeClass(baseType) + ";";
|
|
||||||
|
|
||||||
return externalName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* list of well known typenames as written in Java code
|
|
||||||
*/
|
|
||||||
final static private String[] internalNames = {
|
|
||||||
"", /* equivalent to void */
|
|
||||||
"void",
|
|
||||||
"byte",
|
|
||||||
"char",
|
|
||||||
"short",
|
|
||||||
"int",
|
|
||||||
"long",
|
|
||||||
"float",
|
|
||||||
"double",
|
|
||||||
"boolean",
|
|
||||||
"Byte",
|
|
||||||
"Character",
|
|
||||||
"Short",
|
|
||||||
"Integer",
|
|
||||||
"Long",
|
|
||||||
"Float",
|
|
||||||
"Double",
|
|
||||||
"String",
|
|
||||||
"java.lang.Byte",
|
|
||||||
"java.lang.Character",
|
|
||||||
"java.lang.Short",
|
|
||||||
"java.lang.Integer",
|
|
||||||
"java.lang.Long",
|
|
||||||
"java.lang.Float",
|
|
||||||
"java.lang.Double",
|
|
||||||
"java.lang.String"
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* list of typenames in external form corresponding to entries ni previous list
|
|
||||||
*/
|
|
||||||
final static private String[] externalNames = {
|
|
||||||
"$",
|
|
||||||
"V",
|
|
||||||
"B",
|
|
||||||
"C",
|
|
||||||
"S",
|
|
||||||
"I",
|
|
||||||
"J",
|
|
||||||
"F",
|
|
||||||
"D",
|
|
||||||
"Z",
|
|
||||||
"Ljava/lang/Byte;",
|
|
||||||
"Ljava/lang/Character;",
|
|
||||||
"Ljava/lang/Short;",
|
|
||||||
"Ljava/lang/Integer;",
|
|
||||||
"Ljava/lang/Long;",
|
|
||||||
"Ljava/lang/Float;",
|
|
||||||
"Ljava/lang/Double;",
|
|
||||||
"Ljava/lang/String;",
|
|
||||||
"Ljava/lang/Byte;",
|
|
||||||
"Ljava/lang/Character;",
|
|
||||||
"Ljava/lang/Short;",
|
|
||||||
"Ljava/lang/Integer;",
|
|
||||||
"Ljava/lang/Long;",
|
|
||||||
"Ljava/lang/Float;",
|
|
||||||
"Ljava/lang/Double;",
|
|
||||||
"Ljava/lang/String;"
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert a method descriptor from canonical form to the form used to represent it externally
|
|
||||||
*
|
|
||||||
* @param desc the method descriptor which must be trimmed of any surrounding white space
|
|
||||||
* @return an externalised form for the descriptor
|
|
||||||
*/
|
|
||||||
public static String externalizeDescriptor(String desc)
|
|
||||||
{
|
|
||||||
// the descriptor will start with '(' and the arguments list should end with ')' and,
|
|
||||||
// if it is not void be followed by a return type
|
|
||||||
int openIdx = desc.indexOf('(');
|
|
||||||
int closeIdx = desc.indexOf(')');
|
|
||||||
int length = desc.length();
|
|
||||||
if (openIdx != 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (closeIdx < 0) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
String retType = (closeIdx < length ? desc.substring(closeIdx + 1).trim() : "");
|
|
||||||
String externalRetType = externalizeType(retType);
|
|
||||||
String argString = desc.substring(1, closeIdx).trim();
|
|
||||||
String externalArgs = "";
|
|
||||||
if (argString.equals("")) {
|
|
||||||
externalArgs = argString;
|
|
||||||
} else {
|
|
||||||
String[] args = desc.substring(1, closeIdx).trim().split(",");
|
|
||||||
for (int i = 0; i < args.length ; i++) {
|
|
||||||
externalArgs += externalizeType(args[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "(" + externalArgs + ")" + externalRetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* convert a method descriptor from the form used to represent it externally to canonical form
|
|
||||||
*
|
|
||||||
* @param desc the method descriptor which must be trimmed of any surrounding white space and start with "(".
|
|
||||||
* it must end either with ")" or with ") " followed by an exernalized return type
|
|
||||||
* @return an internalised form for the descriptor, possibly followed by a space and externalized return type
|
|
||||||
*/
|
|
||||||
public static String internalizeDescriptor(String desc)
|
|
||||||
{
|
|
||||||
StringBuffer buffer = new StringBuffer();
|
|
||||||
String sepr = "";
|
|
||||||
int argStart = desc.indexOf('(');
|
|
||||||
int argEnd = desc.indexOf(')');
|
|
||||||
int max = desc.length();
|
|
||||||
if (argStart < 0 || argEnd < 0) {
|
|
||||||
return "(...)";
|
|
||||||
}
|
|
||||||
int arrayCount = 0;
|
|
||||||
boolean addSepr = false;
|
|
||||||
|
|
||||||
buffer.append("(");
|
|
||||||
|
|
||||||
for (int idx = argStart + 1; idx < max;) {
|
|
||||||
char next = desc.charAt(idx);
|
|
||||||
if (addSepr) {
|
|
||||||
while (arrayCount > 0) {
|
|
||||||
buffer.append("[]");
|
|
||||||
arrayCount--;
|
|
||||||
}
|
|
||||||
buffer.append(sepr);
|
|
||||||
}
|
|
||||||
addSepr = true;
|
|
||||||
switch(next) {
|
|
||||||
case 'B':
|
|
||||||
{
|
|
||||||
buffer.append("byte");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'C':
|
|
||||||
{
|
|
||||||
buffer.append("char");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'S':
|
|
||||||
{
|
|
||||||
buffer.append("short");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'I':
|
|
||||||
{
|
|
||||||
buffer.append("int");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'J':
|
|
||||||
{
|
|
||||||
buffer.append("long");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'Z':
|
|
||||||
{
|
|
||||||
buffer.append("boolean");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'F':
|
|
||||||
{
|
|
||||||
buffer.append("float");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'D':
|
|
||||||
{
|
|
||||||
buffer.append("double");
|
|
||||||
}
|
|
||||||
case 'V':
|
|
||||||
{
|
|
||||||
buffer.append("void");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'L':
|
|
||||||
{
|
|
||||||
int tailIdx = idx+1;
|
|
||||||
while (tailIdx < max) {
|
|
||||||
char tailChar = desc.charAt(tailIdx);
|
|
||||||
if (tailChar == ';') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (tailChar == '/')
|
|
||||||
{
|
|
||||||
tailChar = '.';
|
|
||||||
}
|
|
||||||
buffer.append(tailChar);
|
|
||||||
tailIdx++;
|
|
||||||
}
|
|
||||||
idx = tailIdx;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case '[':
|
|
||||||
{
|
|
||||||
arrayCount++;
|
|
||||||
addSepr = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ')':
|
|
||||||
{
|
|
||||||
if (idx == argEnd - 1) {
|
|
||||||
buffer.append(")");
|
|
||||||
} else {
|
|
||||||
// leave room for return type
|
|
||||||
buffer.append(") ");
|
|
||||||
}
|
|
||||||
addSepr = false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
addSepr = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
idx++;
|
|
||||||
if (idx < argEnd) {
|
|
||||||
sepr = ",";
|
|
||||||
} else {
|
|
||||||
sepr = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* split off the method name preceding the signature and return it
|
|
||||||
* @param targetMethod - the unqualified method name, possibly including signature
|
|
||||||
* @return the method name
|
|
||||||
*/
|
|
||||||
public static String parseMethodName(String targetMethod) {
|
|
||||||
int sigIdx = targetMethod.indexOf("(");
|
|
||||||
if (sigIdx > 0) {
|
|
||||||
return targetMethod.substring(0, sigIdx).trim();
|
|
||||||
} else {
|
|
||||||
return targetMethod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* split off the signature following the method name and return it
|
|
||||||
* @param targetMethod - the unqualified method name, possibly including signature
|
|
||||||
* @return the signature
|
|
||||||
*/
|
|
||||||
public static String parseMethodDescriptor(String targetMethod) {
|
|
||||||
int descIdx = targetMethod.indexOf("(");
|
|
||||||
if (descIdx >= 0) {
|
|
||||||
String desc = targetMethod.substring(descIdx, targetMethod.length()).trim();
|
|
||||||
return externalizeDescriptor(desc);
|
|
||||||
} else {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
public class ArgNamesBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
|
|
||||||
String[] parameterNames = bindingContext.getMethodProcessor().getParameterNames();
|
|
||||||
|
|
||||||
AsmOpUtils.push(instructions, parameterNames.length);
|
|
||||||
AsmOpUtils.newArray(instructions, AsmOpUtils.STRING_TYPE);
|
|
||||||
|
|
||||||
for(int i = 0; i < parameterNames.length; ++i) {
|
|
||||||
AsmOpUtils.dup(instructions);
|
|
||||||
|
|
||||||
AsmOpUtils.push(instructions, i);
|
|
||||||
AsmOpUtils.push(instructions, parameterNames[i]);
|
|
||||||
|
|
||||||
AsmOpUtils.arrayStore(instructions, AsmOpUtils.STRING_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return AsmOpUtils.STRING_ARRAY_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
public class ArgsBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
AsmOpUtils.loadArgArray(instructions, bindingContext.getMethodProcessor().getMethodNode());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return AsmOpUtils.OBJECT_ARRAY_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.asm.MethodProcessor;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
|
||||||
|
|
||||||
public class BindingContext {
|
|
||||||
private MethodProcessor methodProcessor;
|
|
||||||
private Location location;
|
|
||||||
private StackSaver stackSaver;
|
|
||||||
|
|
||||||
public BindingContext(Location location, MethodProcessor methodProcessor, StackSaver stackSaver) {
|
|
||||||
this.location = location;
|
|
||||||
this.methodProcessor = methodProcessor;
|
|
||||||
this.stackSaver = stackSaver;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MethodProcessor getMethodProcessor() {
|
|
||||||
return methodProcessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMethodProcessor(MethodProcessor methodProcessor) {
|
|
||||||
this.methodProcessor = methodProcessor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Location getLocation() {
|
|
||||||
return location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLocation(Location location) {
|
|
||||||
this.location = location;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StackSaver getStackSaver() {
|
|
||||||
return stackSaver;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStackSaver(StackSaver stackSaver) {
|
|
||||||
this.stackSaver = stackSaver;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
public class ClassBinding extends Binding{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
String owner = bindingContext.getMethodProcessor().getOwner();
|
|
||||||
AsmOpUtils.ldc(instructions, Type.getObjectType(owner));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(Class.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
public class IntBinding extends Binding {
|
|
||||||
|
|
||||||
private int value;
|
|
||||||
|
|
||||||
private boolean box = true;
|
|
||||||
|
|
||||||
public IntBinding(int value) {
|
|
||||||
this(value, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IntBinding(int value, boolean box) {
|
|
||||||
this.value = value;
|
|
||||||
this.box = box;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
AsmOpUtils.push(instructions, value);
|
|
||||||
if (box) {
|
|
||||||
AsmOpUtils.box(instructions, Type.INT_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.INT_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,64 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.AbstractInsnNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.LineNumberNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodInsnNode;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.MethodInsnNodeWare;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 包含 owner/method name/ method desc/ line number
|
|
||||||
*
|
|
||||||
* @author hengyunabc 2020-05-14
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class InvokeInfoBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
Location location = bindingContext.getLocation();
|
|
||||||
if (location instanceof MethodInsnNodeWare) {
|
|
||||||
MethodInsnNodeWare methodInsnNodeWare = (MethodInsnNodeWare) location;
|
|
||||||
MethodInsnNode methodInsnNode = methodInsnNodeWare.methodInsnNode();
|
|
||||||
|
|
||||||
int line = -1;
|
|
||||||
|
|
||||||
if (location.isWhenComplete() == false) {
|
|
||||||
AbstractInsnNode insnNode = methodInsnNode.getPrevious();
|
|
||||||
while (insnNode != null) {
|
|
||||||
if (insnNode instanceof LineNumberNode) {
|
|
||||||
line = ((LineNumberNode) insnNode).line;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
insnNode = insnNode.getPrevious();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
AbstractInsnNode insnNode = methodInsnNode.getNext();
|
|
||||||
while (insnNode != null) {
|
|
||||||
if (insnNode instanceof LineNumberNode) {
|
|
||||||
line = ((LineNumberNode) insnNode).line;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
insnNode = insnNode.getNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String result = methodInsnNode.owner + "|" + methodInsnNode.name + "|" + methodInsnNode.desc + "|" + line;
|
|
||||||
AsmOpUtils.push(instructions, result);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"InvokeMethodNameBinding location is not Invocation location, location: " + location);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodInsnNode;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.MethodInsnNodeWare;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author hengyunabc
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class InvokeMethodDeclarationBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
Location location = bindingContext.getLocation();
|
|
||||||
if (location instanceof MethodInsnNodeWare) {
|
|
||||||
MethodInsnNodeWare methodInsnNodeWare = (MethodInsnNodeWare) location;
|
|
||||||
MethodInsnNode methodInsnNode = methodInsnNodeWare.methodInsnNode();
|
|
||||||
AsmOpUtils.push(instructions, methodInsnNode.desc);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"InvokeMethodDeclarationBinding location is not Invocation location, location: " + location);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodInsnNode;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.MethodInsnNodeWare;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author hengyunabc
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class InvokeMethodNameBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
Location location = bindingContext.getLocation();
|
|
||||||
if (location instanceof MethodInsnNodeWare) {
|
|
||||||
MethodInsnNodeWare methodInsnNodeWare = (MethodInsnNodeWare) location;
|
|
||||||
MethodInsnNode methodInsnNode = methodInsnNodeWare.methodInsnNode();
|
|
||||||
AsmOpUtils.push(instructions, methodInsnNode.name);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"InvokeMethodNameBinding location is not Invocation location, location: " + location);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodInsnNode;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.MethodInsnNodeWare;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author hengyunabc 2020-05-02
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class InvokeMethodOwnerBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
Location location = bindingContext.getLocation();
|
|
||||||
if (location instanceof MethodInsnNodeWare) {
|
|
||||||
MethodInsnNodeWare methodInsnNodeWare = (MethodInsnNodeWare) location;
|
|
||||||
MethodInsnNode methodInsnNode = methodInsnNodeWare.methodInsnNode();
|
|
||||||
AsmOpUtils.push(instructions, methodInsnNode.owner);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"InvokeMethodOwnerBinding location is not Invocation location, location: " + location);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.AbstractInsnNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.LocalVariableNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodInsnNode;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.asm.MethodProcessor;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* invoke 的返回值
|
|
||||||
* @author hengyunabc
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class InvokeReturnBinding extends Binding {
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
AbstractInsnNode insnNode = bindingContext.getLocation().getInsnNode();
|
|
||||||
MethodProcessor methodProcessor = bindingContext.getMethodProcessor();
|
|
||||||
if (insnNode instanceof MethodInsnNode) {
|
|
||||||
MethodInsnNode methodInsnNode = (MethodInsnNode) insnNode;
|
|
||||||
String uniqueNameForMethod = AsmUtils.uniqueNameForMethod(methodInsnNode.owner, methodInsnNode.name,
|
|
||||||
methodInsnNode.desc);
|
|
||||||
Type invokeReturnType = Type.getMethodType(methodInsnNode.desc).getReturnType();
|
|
||||||
if(invokeReturnType.equals(Type.VOID_TYPE)) {
|
|
||||||
AsmOpUtils.push(instructions, null);
|
|
||||||
}else {
|
|
||||||
LocalVariableNode invokeReturnVariableNode = methodProcessor.initInvokeReturnVariableNode(
|
|
||||||
uniqueNameForMethod, Type.getMethodType(methodInsnNode.desc).getReturnType());
|
|
||||||
AsmOpUtils.loadVar(instructions, invokeReturnType, invokeReturnVariableNode.index);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"InvokeReturnBinding location is not MethodInsnNode, insnNode: " + insnNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fromStack() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
AbstractInsnNode insnNode = bindingContext.getLocation().getInsnNode();
|
|
||||||
if (insnNode instanceof MethodInsnNode) {
|
|
||||||
MethodInsnNode methodInsnNode = (MethodInsnNode) insnNode;
|
|
||||||
Type invokeReturnType = Type.getMethodType(methodInsnNode.desc).getReturnType();
|
|
||||||
return invokeReturnType;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"InvokeReturnBinding location is not MethodInsnNode, insnNode: " + insnNode);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,63 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.AbstractInsnNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.LineNumberNode;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author hengyunabc
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class LineBinding extends Binding {
|
|
||||||
|
|
||||||
private boolean exact;
|
|
||||||
|
|
||||||
public LineBinding(boolean exact) {
|
|
||||||
this.exact = exact;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
Location location = bindingContext.getLocation();
|
|
||||||
AbstractInsnNode insnNode = location.getInsnNode();
|
|
||||||
|
|
||||||
int line = -1;
|
|
||||||
if (exact) {
|
|
||||||
if (insnNode instanceof LineNumberNode) {
|
|
||||||
line = ((LineNumberNode) insnNode).line;
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException("LineBinding location is not LineNumberNode, insnNode: " + insnNode);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (location.isWhenComplete() == false) {
|
|
||||||
while (insnNode != null) {
|
|
||||||
if (insnNode instanceof LineNumberNode) {
|
|
||||||
line = ((LineNumberNode) insnNode).line;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
insnNode = insnNode.getPrevious();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (insnNode != null) {
|
|
||||||
if (insnNode instanceof LineNumberNode) {
|
|
||||||
line = ((LineNumberNode) insnNode).line;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
insnNode = insnNode.getNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AsmOpUtils.push(instructions, line);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(int.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.AbstractInsnNode;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.LocalVariableNode;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
public class LocalVarNamesBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
AbstractInsnNode currentInsnNode = bindingContext.getLocation().getInsnNode();
|
|
||||||
List<LocalVariableNode> results = AsmOpUtils
|
|
||||||
.validVariables(bindingContext.getMethodProcessor().getMethodNode().localVariables, currentInsnNode);
|
|
||||||
|
|
||||||
AsmOpUtils.push(instructions, results.size());
|
|
||||||
AsmOpUtils.newArray(instructions, AsmOpUtils.STRING_TYPE);
|
|
||||||
|
|
||||||
for (int i = 0; i < results.size(); ++i) {
|
|
||||||
AsmOpUtils.dup(instructions);
|
|
||||||
|
|
||||||
AsmOpUtils.push(instructions, i);
|
|
||||||
AsmOpUtils.push(instructions, results.get(i).name);
|
|
||||||
|
|
||||||
AsmOpUtils.arrayStore(instructions, AsmOpUtils.STRING_TYPE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return AsmOpUtils.STRING_ARRAY_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Opcodes;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodInsnNode;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.asm.MethodProcessor;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author hengyunabc
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MethodBinding extends Binding{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
// 先获取类本身的 class ,再调用 getDeclaredMethod ,它需要一个变长参数,实际上要传一个数组
|
|
||||||
/**
|
|
||||||
* @see java.lang.Class.getDeclaredMethod(String, Class<?>...)
|
|
||||||
*/
|
|
||||||
MethodProcessor methodProcessor = bindingContext.getMethodProcessor();
|
|
||||||
AsmOpUtils.ldc(instructions, Type.getObjectType(methodProcessor.getOwner()));
|
|
||||||
|
|
||||||
AsmOpUtils.push(instructions, methodProcessor.getMethodNode().name);
|
|
||||||
|
|
||||||
Type[] argumentTypes = Type.getMethodType(methodProcessor.getMethodNode().desc).getArgumentTypes();
|
|
||||||
|
|
||||||
AsmOpUtils.push(instructions, argumentTypes.length);
|
|
||||||
AsmOpUtils.newArray(instructions, Type.getType(Class.class));
|
|
||||||
|
|
||||||
for(int i = 0; i < argumentTypes.length; ++i) {
|
|
||||||
AsmOpUtils.dup(instructions);
|
|
||||||
|
|
||||||
AsmOpUtils.push(instructions, i);
|
|
||||||
|
|
||||||
AsmOpUtils.ldc(instructions, argumentTypes[i]);
|
|
||||||
AsmOpUtils.arrayStore(instructions, Type.getType(Class.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
MethodInsnNode declaredMethodInsnNode = new MethodInsnNode(Opcodes.INVOKEVIRTUAL, Type.getType(Class.class).getInternalName(),
|
|
||||||
"getDeclaredMethod", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;", false);
|
|
||||||
instructions.add(declaredMethodInsnNode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(java.lang.reflect.Method.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodNode;
|
|
||||||
import com.taobao.arthas.bytekit.asm.MethodProcessor;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* method name | method desc 的方式组织
|
|
||||||
*
|
|
||||||
* TODO 是否要有 line number ?
|
|
||||||
*
|
|
||||||
* @author hengyunabc 2020-05-16
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MethodInfoBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
MethodProcessor methodProcessor = bindingContext.getMethodProcessor();
|
|
||||||
MethodNode methodNode = methodProcessor.getMethodNode();
|
|
||||||
AsmOpUtils.ldc(instructions, methodNode.name + '|' + methodNode.desc);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(String.class);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.taobao.arthas.bytekit.asm.MethodProcessor;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author hengyunabc
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MethodNameBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
MethodProcessor methodProcessor = bindingContext.getMethodProcessor();
|
|
||||||
AsmOpUtils.ldc(instructions, methodProcessor.getMethodNode().name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(String.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.LocalVariableNode;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location.SyncEnterLocation;
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location.SyncExitLocation;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
public class MonitorBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
Location location = bindingContext.getLocation();
|
|
||||||
|
|
||||||
if (location.isWhenComplete()) {
|
|
||||||
throw new IllegalArgumentException("MonitorBinding only support location whenComplete is false.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (location instanceof SyncEnterLocation || location instanceof SyncExitLocation) {
|
|
||||||
LocalVariableNode monitorVariableNode = bindingContext.getMethodProcessor().initMonitorVariableNode();
|
|
||||||
AsmOpUtils.loadVar(instructions, AsmOpUtils.OBJECT_TYPE, monitorVariableNode.index);
|
|
||||||
} else {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"MonitorBinding only support SyncEnterLocation or SyncExitLocation. location: " + location);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fromStack() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return AsmOpUtils.OBJECT_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,43 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.LocalVariableNode;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.asm.location.Location;
|
|
||||||
import com.taobao.arthas.bytekit.utils.AsmOpUtils;
|
|
||||||
|
|
||||||
public class ReturnBinding extends Binding {
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
//check location
|
|
||||||
|
|
||||||
Location location = bindingContext.getLocation();
|
|
||||||
|
|
||||||
if (!AsmOpUtils.isReturnCode(location.getInsnNode().getOpcode())) {
|
|
||||||
throw new IllegalArgumentException("current location is not return location. location: " + location);
|
|
||||||
}
|
|
||||||
|
|
||||||
Type returnType = bindingContext.getMethodProcessor().getReturnType();
|
|
||||||
if(returnType.equals(Type.VOID_TYPE)) {
|
|
||||||
AsmOpUtils.push(instructions, null);
|
|
||||||
}else {
|
|
||||||
LocalVariableNode returnVariableNode = bindingContext.getMethodProcessor().initReturnVariableNode();
|
|
||||||
AsmOpUtils.loadVar(instructions, returnType, returnVariableNode.index);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fromStack() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return bindingContext.getMethodProcessor().getReturnType();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,18 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
|
|
||||||
public class ThisBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
bindingContext.getMethodProcessor().loadThis(instructions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(Object.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Type;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.InsnList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO 要检查 location 是否是合法的
|
|
||||||
* @author hengyunabc
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ThrowableBinding extends Binding {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean fromStack() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pushOntoStack(InsnList instructions, BindingContext bindingContext) {
|
|
||||||
// TODO 这里从 StackSaver 里取是否合理?
|
|
||||||
bindingContext.getStackSaver().load(instructions, bindingContext);
|
|
||||||
// 是否要 check cast ?
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Type getType(BindingContext bindingContext) {
|
|
||||||
return Type.getType(Throwable.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.Annotation;
|
|
||||||
|
|
||||||
import com.taobao.arthas.bytekit.asm.binding.Binding;
|
|
||||||
|
|
||||||
public interface BindingParser {
|
|
||||||
|
|
||||||
public Binding parse(Annotation annotation);
|
|
||||||
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.binding.annotation;
|
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
|
||||||
import java.lang.annotation.ElementType;
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
|
|
||||||
@Documented
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@java.lang.annotation.Target(ElementType.ANNOTATION_TYPE)
|
|
||||||
public @interface BindingParserHandler {
|
|
||||||
|
|
||||||
Class<? extends BindingParser> parser();
|
|
||||||
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.inst;
|
|
||||||
|
|
||||||
import java.lang.annotation.Retention;
|
|
||||||
import java.lang.annotation.RetentionPolicy;
|
|
||||||
import java.lang.annotation.Target;
|
|
||||||
|
|
||||||
@Target({ java.lang.annotation.ElementType.FIELD })
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
public @interface NewField {
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.inst.impl;
|
|
||||||
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.Label;
|
|
||||||
import com.alibaba.arthas.deps.org.objectweb.asm.tree.MethodNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author hengyunabc 2019-03-18
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class MethodReplaceResult {
|
|
||||||
|
|
||||||
private boolean success;
|
|
||||||
|
|
||||||
private Label start;
|
|
||||||
private Label end;
|
|
||||||
|
|
||||||
private MethodNode methodNode;
|
|
||||||
|
|
||||||
public Label getStart() {
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStart(Label start) {
|
|
||||||
this.start = start;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Label getEnd() {
|
|
||||||
return end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEnd(Label end) {
|
|
||||||
this.end = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MethodNode getMethodNode() {
|
|
||||||
return methodNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMethodNode(MethodNode methodNode) {
|
|
||||||
this.methodNode = methodNode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSuccess() {
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSuccess(boolean success) {
|
|
||||||
this.success = success;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +0,0 @@
|
|||||||
package com.taobao.arthas.bytekit.asm.interceptor;
|
|
||||||
|
|
||||||
public class EnterInteceptor {
|
|
||||||
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue