Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
为 GitLab 提交贡献
登录/注册
切换导航
H
h2database
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分枝图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
分枝图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
Administrator
h2database
Commits
c93bf7a6
提交
c93bf7a6
authored
15 年前
作者:
Thomas Mueller
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
JaQu: the plan is to support natural (pure Java) conditions.
上级
2afa260c
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
1472 行增加
和
5 行删除
+1472
-5
jaqu.html
h2/src/docsrc/html/jaqu.html
+20
-1
SamplesTest.java
h2/src/test/org/h2/test/jaqu/SamplesTest.java
+4
-4
Query.java
h2/src/tools/org/h2/jaqu/Query.java
+4
-0
ClassReader.java
h2/src/tools/org/h2/jaqu/util/ClassReader.java
+1444
-0
没有找到文件。
h2/src/docsrc/html/jaqu.html
浏览文件 @
c93bf7a6
...
@@ -256,7 +256,26 @@ This is not possible using annotations.
...
@@ -256,7 +256,26 @@ This is not possible using annotations.
Unlike XML mapping configuration, the configuration is integrated in the class itself.
Unlike XML mapping configuration, the configuration is integrated in the class itself.
</p>
</p>
<h2>
Ideas
</h2>
<h2>
Natural Syntax
</h2>
<p>
The plan is to support more natural (pure Java) syntax in conditions.
To do that, the condition class is de-compiled to a SQL condition.
A proof of concept decompiler is included (but it doesn't work yet).
The planned syntax is:
</p>
<pre>
long count = db.from(co).
where(new Filter() { public boolean where() {
return co.id == x
&&
co.name.equals(name)
&&
co.value == new BigDecimal("1")
&&
co.amount == 1L
&&
co.birthday.before(new java.util.Date())
&&
co.created.before(java.sql.Timestamp.valueOf("2005-05-05 05:05:05"))
&&
co.time.before(java.sql.Time.valueOf("23:23:23"));
} }).selectCount();
</pre>
<h2>
Other Ideas
</h2>
<p>
<p>
This project has just been started, and nothing is fixed yet.
This project has just been started, and nothing is fixed yet.
Some ideas for what to implement are:
Some ideas for what to implement are:
...
...
This diff is collapsed.
Click to expand it.
h2/src/test/org/h2/test/jaqu/SamplesTest.java
浏览文件 @
c93bf7a6
...
@@ -347,12 +347,12 @@ private void testComplexObject2(final int x, final String name) {
...
@@ -347,12 +347,12 @@ private void testComplexObject2(final int x, final String name) {
long
count
=
db
.
from
(
co
).
long
count
=
db
.
from
(
co
).
where
(
new
Filter
()
{
public
boolean
where
()
{
where
(
new
Filter
()
{
public
boolean
where
()
{
return
co
.
id
==
x
return
co
.
id
==
x
&&
co
.
name
.
equals
(
name
)
&&
co
.
value
==
new
BigDecimal
(
"1"
)
&&
co
.
amount
==
1L
&&
co
.
amount
==
1L
&&
co
.
birthday
.
before
(
new
java
.
util
.
Date
())
&&
co
.
birthday
.
before
(
new
java
.
util
.
Date
())
&&
co
.
created
.
before
(
java
.
sql
.
Timestamp
.
valueOf
(
"2005-05-05 05:05:05"
))
&&
co
.
created
.
before
(
java
.
sql
.
Timestamp
.
valueOf
(
"2005-05-05 05:05:05"
))
&&
co
.
name
.
equals
(
name
)
&&
co
.
time
.
before
(
java
.
sql
.
Time
.
valueOf
(
"23:23:23"
));
&&
co
.
time
.
before
(
java
.
sql
.
Time
.
valueOf
(
"23:23:23"
))
&&
co
.
value
==
new
BigDecimal
(
"1"
);
}
}).
selectCount
();
}
}).
selectCount
();
// TODO should return only one object
// TODO should return only one object
assertEquals
(
2
,
count
);
assertEquals
(
2
,
count
);
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/jaqu/Query.java
浏览文件 @
c93bf7a6
...
@@ -14,6 +14,7 @@ import java.util.ArrayList;
...
@@ -14,6 +14,7 @@ import java.util.ArrayList;
import
java.util.HashMap
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.List
;
import
org.h2.jaqu.util.ClassReader
;
import
org.h2.jaqu.util.Utils
;
import
org.h2.jaqu.util.Utils
;
//## Java 1.5 end ##
//## Java 1.5 end ##
...
@@ -178,6 +179,9 @@ public class Query<T> {
...
@@ -178,6 +179,9 @@ public class Query<T> {
// // convert
// // convert
// }
// }
}
}
// String filterQuery =
new
ClassReader
().
decompile
(
filter
,
"where"
);
// System.out.println(filterQuery);
return
new
QueryWhere
<
T
>(
this
);
return
new
QueryWhere
<
T
>(
this
);
}
}
...
...
This diff is collapsed.
Click to expand it.
h2/src/tools/org/h2/jaqu/util/ClassReader.java
0 → 100644
浏览文件 @
c93bf7a6
/*
* Copyright 2004-2009 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package
org
.
h2
.
jaqu
.
util
;
import
java.io.ByteArrayOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
import
java.util.Stack
;
/**
* This class converts a method to a SQL expression by interpreting
* (decompiling) the bytecode of the class.
*/
public
class
ClassReader
{
private
static
final
boolean
DEBUG
=
false
;
private
byte
[]
data
;
private
int
pos
;
private
int
[]
cpType
;
private
String
[]
cpString
;
private
int
[]
cpInt
;
private
int
startByteCode
;
private
String
methodName
;
private
String
convertMethodName
;
private
String
result
;
private
Stack
<
String
>
stack
=
new
Stack
<
String
>();
private
ArrayList
<
String
>
variables
=
new
ArrayList
<
String
>();
private
boolean
end
;
private
boolean
condition
;
private
int
nextPc
;
private
void
debug
(
String
s
)
{
if
(
DEBUG
)
{
System
.
out
.
println
(
s
);
}
}
public
String
decompile
(
Object
instance
,
String
methodName
)
{
this
.
convertMethodName
=
methodName
;
Class
<
?
>
clazz
=
instance
.
getClass
();
String
className
=
clazz
.
getName
();
debug
(
"class name "
+
className
);
ByteArrayOutputStream
buff
=
new
ByteArrayOutputStream
();
try
{
InputStream
in
=
clazz
.
getClassLoader
().
getResource
(
className
.
replace
(
'.'
,
'/'
)
+
".class"
).
openStream
();
while
(
true
)
{
int
x
=
in
.
read
();
if
(
x
<
0
)
{
break
;
}
buff
.
write
(
x
);
}
}
catch
(
IOException
e
)
{
throw
new
RuntimeException
(
"Could not read class bytecode"
,
e
);
}
data
=
buff
.
toByteArray
();
int
header
=
readInt
();
debug
(
"header: "
+
Integer
.
toHexString
(
header
));
int
minorVersion
=
readShort
();
int
majorVersion
=
readShort
();
debug
(
"version: "
+
majorVersion
+
"."
+
minorVersion
);
int
constantPoolCount
=
readShort
();
cpString
=
new
String
[
constantPoolCount
];
cpInt
=
new
int
[
constantPoolCount
];
cpType
=
new
int
[
constantPoolCount
];
for
(
int
i
=
1
;
i
<
constantPoolCount
;
i
++)
{
int
tag
=
readByte
();
cpType
[
i
]
=
tag
;
switch
(
tag
)
{
case
1
:
cpString
[
i
]
=
readString
();
break
;
case
3
:
{
int
x
=
readInt
();
cpString
[
i
]
=
String
.
valueOf
(
x
);
break
;
}
case
4
:
{
int
x
=
readInt
();
cpString
[
i
]
=
Float
.
toString
(
Float
.
intBitsToFloat
(
x
));
cpInt
[
i
]
=
x
;
break
;
}
case
5
:
{
long
x
=
readLong
();
cpString
[
i
]
=
String
.
valueOf
(
x
);
i
++;
break
;
}
case
6
:
{
long
x
=
readLong
();
cpString
[
i
]
=
String
.
valueOf
(
Double
.
longBitsToDouble
(
x
));
i
++;
break
;
}
case
7
:
{
int
x
=
readShort
();
cpString
[
i
]
=
"class"
;
cpInt
[
i
]
=
x
;
break
;
}
case
8
:
{
int
x
=
readShort
();
cpString
[
i
]
=
"string"
;
cpInt
[
i
]
=
x
;
break
;
}
case
9
:
{
int
x
=
readInt
();
cpString
[
i
]
=
"field"
;
cpInt
[
i
]
=
x
;
break
;
}
case
10
:
{
int
x
=
readInt
();
cpString
[
i
]
=
"method"
;
cpInt
[
i
]
=
x
;
break
;
}
case
11
:
{
int
x
=
readInt
();
cpString
[
i
]
=
"interface method"
;
cpInt
[
i
]
=
x
;
break
;
}
case
12
:
{
int
x
=
readInt
();
cpString
[
i
]
=
"name and type"
;
cpInt
[
i
]
=
x
;
break
;
}
default
:
throw
new
Error
(
"Unsupported constant pool tag: "
+
tag
);
}
}
int
accessFlags
=
readShort
();
debug
(
"access flags: "
+
accessFlags
);
int
classRef
=
readShort
();
debug
(
"class: "
+
cpString
[
cpInt
[
classRef
]]);
int
superClassRef
=
readShort
();
debug
(
" extends "
+
cpString
[
cpInt
[
superClassRef
]]);
int
interfaceCount
=
readShort
();
for
(
int
i
=
0
;
i
<
interfaceCount
;
i
++)
{
int
interfaceRef
=
readShort
();
debug
(
" implements "
+
cpString
[
cpInt
[
interfaceRef
]]);
}
int
fieldCount
=
readShort
();
for
(
int
i
=
0
;
i
<
fieldCount
;
i
++)
{
readField
();
}
int
methodCount
=
readShort
();
for
(
int
i
=
0
;
i
<
methodCount
;
i
++)
{
readMethod
();
}
readAttributes
();
return
result
;
}
private
void
readField
()
{
int
accessFlags
=
readShort
();
int
nameIndex
=
readShort
();
int
descIndex
=
readShort
();
debug
(
" "
+
cpString
[
descIndex
]
+
" "
+
cpString
[
nameIndex
]
+
" "
+
accessFlags
);
readAttributes
();
}
private
void
readMethod
()
{
int
accessFlags
=
readShort
();
int
nameIndex
=
readShort
();
int
descIndex
=
readShort
();
String
desc
=
cpString
[
descIndex
];
methodName
=
cpString
[
nameIndex
];
debug
(
" "
+
desc
+
" "
+
methodName
+
" "
+
accessFlags
);
readAttributes
();
}
private
void
readAttributes
()
{
int
attributeCount
=
readShort
();
for
(
int
i
=
0
;
i
<
attributeCount
;
i
++)
{
int
attributeNameIndex
=
readShort
();
String
attributeName
=
cpString
[
attributeNameIndex
];
debug
(
" attribute "
+
attributeName
);
int
attributeLength
=
readInt
();
int
end
=
pos
+
attributeLength
;
if
(
"Code"
.
equals
(
attributeName
))
{
readCode
();
}
pos
=
end
;
}
}
void
decompile
()
{
int
maxStack
=
readShort
();
int
maxLocals
=
readShort
();
debug
(
"stack: "
+
maxStack
+
" locals: "
+
maxLocals
);
int
codeLength
=
readInt
();
startByteCode
=
pos
;
int
end
=
pos
+
codeLength
;
while
(
pos
<
end
)
{
readByteCode
();
}
debug
(
""
);
pos
=
startByteCode
+
codeLength
;
int
exceptionTableLength
=
readShort
();
pos
+=
2
*
exceptionTableLength
;
readAttributes
();
}
private
void
readCode
()
{
variables
.
clear
();
stack
.
clear
();
int
maxStack
=
readShort
();
int
maxLocals
=
readShort
();
debug
(
"stack: "
+
maxStack
+
" locals: "
+
maxLocals
);
int
codeLength
=
readInt
();
startByteCode
=
pos
;
if
(
methodName
.
startsWith
(
convertMethodName
))
{
result
=
getResult
();
}
pos
=
startByteCode
+
codeLength
;
int
exceptionTableLength
=
readShort
();
pos
+=
2
*
exceptionTableLength
;
readAttributes
();
}
private
String
getResult
()
{
while
(
true
)
{
readByteCode
();
if
(
end
)
{
return
stack
.
pop
();
}
if
(
condition
)
{
String
c
=
stack
.
pop
();
Stack
<
String
>
currentStack
=
new
Stack
<
String
>();
currentStack
.
addAll
(
stack
);
ArrayList
<
String
>
currentVariables
=
new
ArrayList
<
String
>();
currentVariables
.
addAll
(
variables
);
int
branch
=
nextPc
;
String
a
=
getResult
();
stack
=
currentStack
;
variables
=
currentVariables
;
pos
=
branch
+
startByteCode
;
String
b
=
getResult
();
if
(
a
.
equals
(
"0"
)
&&
b
.
equals
(
"1"
))
{
return
c
;
}
else
if
(
a
.
equals
(
"1"
)
&&
b
.
equals
(
"0"
))
{
return
"NOT("
+
c
+
")"
;
}
else
if
(
b
.
equals
(
"0"
))
{
return
"NOT("
+
c
+
") AND ("
+
a
+
")"
;
}
else
if
(
a
.
equals
(
"0"
))
{
return
"("
+
c
+
") AND ("
+
b
+
")"
;
}
else
if
(
b
.
equals
(
"1"
))
{
return
"("
+
c
+
") OR ("
+
a
+
")"
;
}
else
if
(
a
.
equals
(
"1"
))
{
return
"NOT("
+
c
+
") AND ("
+
b
+
")"
;
}
return
"("
+
c
+
") ? ("
+
b
+
") : ("
+
a
+
")"
;
}
if
(
nextPc
!=
0
)
{
pos
=
nextPc
+
startByteCode
;
}
}
}
private
void
readByteCode
()
{
int
startPos
=
pos
-
startByteCode
;
int
opCode
=
readByte
();
String
op
;
end
=
false
;
condition
=
false
;
nextPc
=
0
;
switch
(
opCode
)
{
case
0
:
op
=
"nop"
;
break
;
case
1
:
op
=
"aconst_null"
;
stack
.
push
(
"null"
);
break
;
case
2
:
op
=
"iconst_m1"
;
stack
.
push
(
"-1"
);
break
;
case
3
:
op
=
"iconst_0"
;
stack
.
push
(
"0"
);
break
;
case
4
:
op
=
"iconst_1"
;
stack
.
push
(
"1"
);
break
;
case
5
:
op
=
"iconst_2"
;
stack
.
push
(
"2"
);
break
;
case
6
:
op
=
"iconst_3"
;
stack
.
push
(
"3"
);
break
;
case
7
:
op
=
"iconst_4"
;
stack
.
push
(
"4"
);
break
;
case
8
:
op
=
"iconst_5"
;
stack
.
push
(
"5"
);
break
;
case
9
:
op
=
"lconst_0"
;
stack
.
push
(
"0"
);
break
;
case
10
:
op
=
"lconst_1"
;
stack
.
push
(
"1"
);
break
;
case
11
:
op
=
"fconst_0"
;
stack
.
push
(
"0.0"
);
break
;
case
12
:
op
=
"fconst_1"
;
stack
.
push
(
"1.0"
);
break
;
case
13
:
op
=
"fconst_2"
;
stack
.
push
(
"2.0"
);
break
;
case
14
:
op
=
"dconst_0"
;
stack
.
push
(
"0.0"
);
break
;
case
15
:
op
=
"dconst_1"
;
stack
.
push
(
"1.0"
);
break
;
case
16
:
{
int
x
=
(
byte
)
readByte
();
op
=
"bipush "
+
x
;
stack
.
push
(
""
+
x
);
break
;
}
case
17
:
{
int
x
=
(
short
)
readShort
();
op
=
"sipush "
+
x
;
stack
.
push
(
""
+
x
);
break
;
}
case
18
:
{
String
s
=
getConstant
(
readByte
());
op
=
"ldc "
+
s
;
stack
.
push
(
s
);
break
;
}
case
19
:
{
String
s
=
getConstant
(
readShort
());
op
=
"ldc_w "
+
s
;
stack
.
push
(
s
);
break
;
}
case
20
:
{
String
s
=
getConstant
(
readShort
());
op
=
"ldc2_w "
+
s
;
stack
.
push
(
s
);
break
;
}
case
21
:
{
int
x
=
readByte
();
op
=
"iload "
+
x
;
stack
.
push
(
getVariable
(
x
));
break
;
}
case
22
:
{
int
x
=
readByte
();
op
=
"lload "
+
x
;
stack
.
push
(
getVariable
(
x
));
break
;
}
case
23
:
{
int
x
=
readByte
();
op
=
"fload "
+
x
;
stack
.
push
(
getVariable
(
x
));
break
;
}
case
24
:
{
int
x
=
readByte
();
op
=
"dload "
+
x
;
stack
.
push
(
getVariable
(
x
));
break
;
}
case
25
:
{
int
x
=
readByte
();
op
=
"aload "
+
x
;
stack
.
push
(
getVariable
(
x
));
break
;
}
case
26
:
op
=
"iload_0"
;
stack
.
push
(
getVariable
(
0
));
break
;
case
27
:
op
=
"iload_1"
;
stack
.
push
(
getVariable
(
1
));
break
;
case
28
:
op
=
"iload_2"
;
stack
.
push
(
getVariable
(
2
));
break
;
case
29
:
op
=
"iload_3"
;
stack
.
push
(
getVariable
(
3
));
break
;
case
30
:
op
=
"lload_0"
;
stack
.
push
(
getVariable
(
0
));
break
;
case
31
:
op
=
"lload_1"
;
stack
.
push
(
getVariable
(
1
));
break
;
case
32
:
op
=
"lload_2"
;
stack
.
push
(
getVariable
(
2
));
break
;
case
33
:
op
=
"lload_3"
;
stack
.
push
(
getVariable
(
3
));
break
;
case
34
:
op
=
"fload_0"
;
stack
.
push
(
getVariable
(
0
));
break
;
case
35
:
op
=
"fload_1"
;
stack
.
push
(
getVariable
(
1
));
break
;
case
36
:
op
=
"fload_2"
;
stack
.
push
(
getVariable
(
2
));
break
;
case
37
:
op
=
"fload_3"
;
stack
.
push
(
getVariable
(
3
));
break
;
case
38
:
op
=
"dload_0"
;
stack
.
push
(
getVariable
(
0
));
break
;
case
39
:
op
=
"dload_1"
;
stack
.
push
(
getVariable
(
1
));
break
;
case
40
:
op
=
"dload_2"
;
stack
.
push
(
getVariable
(
2
));
break
;
case
41
:
op
=
"dload_3"
;
stack
.
push
(
getVariable
(
3
));
break
;
case
42
:
op
=
"aload_0"
;
stack
.
push
(
getVariable
(
0
));
break
;
case
43
:
op
=
"aload_1"
;
stack
.
push
(
getVariable
(
1
));
break
;
case
44
:
op
=
"aload_2"
;
stack
.
push
(
getVariable
(
2
));
break
;
case
45
:
op
=
"aload_3"
;
stack
.
push
(
getVariable
(
3
));
break
;
case
46
:
{
String
index
=
stack
.
pop
();
String
ref
=
stack
.
pop
();
op
=
"iaload"
;
stack
.
push
(
ref
+
"["
+
index
+
"]"
);
break
;
}
case
47
:
{
String
index
=
stack
.
pop
();
String
ref
=
stack
.
pop
();
op
=
"laload"
;
stack
.
push
(
ref
+
"["
+
index
+
"]"
);
break
;
}
case
48
:
{
String
index
=
stack
.
pop
();
String
ref
=
stack
.
pop
();
op
=
"faload"
;
stack
.
push
(
ref
+
"["
+
index
+
"]"
);
break
;
}
case
49
:
{
String
index
=
stack
.
pop
();
String
ref
=
stack
.
pop
();
op
=
"daload"
;
stack
.
push
(
ref
+
"["
+
index
+
"]"
);
break
;
}
case
50
:
{
String
index
=
stack
.
pop
();
String
ref
=
stack
.
pop
();
op
=
"aaload"
;
stack
.
push
(
ref
+
"["
+
index
+
"]"
);
break
;
}
case
51
:
{
String
index
=
stack
.
pop
();
String
ref
=
stack
.
pop
();
op
=
"baload"
;
stack
.
push
(
ref
+
"["
+
index
+
"]"
);
break
;
}
case
52
:
{
String
index
=
stack
.
pop
();
String
ref
=
stack
.
pop
();
op
=
"caload"
;
stack
.
push
(
ref
+
"["
+
index
+
"]"
);
break
;
}
case
53
:
{
String
index
=
stack
.
pop
();
String
ref
=
stack
.
pop
();
op
=
"saload"
;
stack
.
push
(
ref
+
"["
+
index
+
"]"
);
break
;
}
case
54
:
{
int
var
=
readByte
();
op
=
"istore "
+
var
;
setVariable
(
var
,
stack
.
pop
());
break
;
}
case
55
:
{
int
var
=
readByte
();
op
=
"lstore "
+
var
;
setVariable
(
var
,
stack
.
pop
());
break
;
}
case
56
:
{
int
var
=
readByte
();
op
=
"fstore "
+
var
;
setVariable
(
var
,
stack
.
pop
());
break
;
}
case
57
:
{
int
var
=
readByte
();
op
=
"dstore "
+
var
;
setVariable
(
var
,
stack
.
pop
());
break
;
}
case
58
:
{
int
var
=
readByte
();
op
=
"astore "
+
var
;
setVariable
(
var
,
stack
.
pop
());
break
;
}
case
59
:
op
=
"istore_0"
;
setVariable
(
0
,
stack
.
pop
());
break
;
case
60
:
op
=
"istore_1"
;
setVariable
(
1
,
stack
.
pop
());
break
;
case
61
:
op
=
"istore_2"
;
setVariable
(
2
,
stack
.
pop
());
break
;
case
62
:
op
=
"istore_3"
;
setVariable
(
3
,
stack
.
pop
());
break
;
case
63
:
op
=
"lstore_0"
;
setVariable
(
0
,
stack
.
pop
());
break
;
case
64
:
op
=
"lstore_1"
;
setVariable
(
1
,
stack
.
pop
());
break
;
case
65
:
op
=
"lstore_2"
;
setVariable
(
2
,
stack
.
pop
());
break
;
case
66
:
op
=
"lstore_3"
;
setVariable
(
3
,
stack
.
pop
());
break
;
case
67
:
op
=
"fstore_0"
;
setVariable
(
0
,
stack
.
pop
());
break
;
case
68
:
op
=
"fstore_1"
;
setVariable
(
1
,
stack
.
pop
());
break
;
case
69
:
op
=
"fstore_2"
;
setVariable
(
2
,
stack
.
pop
());
break
;
case
70
:
op
=
"fstore_3"
;
setVariable
(
3
,
stack
.
pop
());
break
;
case
71
:
op
=
"dstore_0"
;
setVariable
(
0
,
stack
.
pop
());
break
;
case
72
:
op
=
"dstore_1"
;
setVariable
(
1
,
stack
.
pop
());
break
;
case
73
:
op
=
"dstore_2"
;
setVariable
(
2
,
stack
.
pop
());
break
;
case
74
:
op
=
"dstore_3"
;
setVariable
(
3
,
stack
.
pop
());
break
;
case
75
:
op
=
"astore_0"
;
setVariable
(
0
,
stack
.
pop
());
break
;
case
76
:
op
=
"astore_1"
;
setVariable
(
1
,
stack
.
pop
());
break
;
case
77
:
op
=
"astore_2"
;
setVariable
(
2
,
stack
.
pop
());
break
;
case
78
:
op
=
"astore_3"
;
setVariable
(
3
,
stack
.
pop
());
break
;
case
79
:
{
// String value = stack.pop();
// String index = stack.pop();
// String ref = stack.pop();
op
=
"iastore"
;
// TODO side effect - not supported
break
;
}
case
80
:
op
=
"lastore"
;
// TODO side effect - not supported
break
;
case
81
:
op
=
"fastore"
;
// TODO side effect - not supported
break
;
case
82
:
op
=
"dastore"
;
// TODO side effect - not supported
break
;
case
83
:
op
=
"aastore"
;
// TODO side effect - not supported
break
;
case
84
:
op
=
"bastore"
;
// TODO side effect - not supported
break
;
case
85
:
op
=
"castore"
;
// TODO side effect - not supported
break
;
case
86
:
op
=
"sastore"
;
// TODO side effect - not supported
break
;
case
87
:
op
=
"pop"
;
stack
.
pop
();
break
;
case
88
:
op
=
"pop2"
;
// TODO currently we don't know the stack types
stack
.
pop
();
stack
.
pop
();
break
;
case
89
:
{
op
=
"dup"
;
String
x
=
stack
.
pop
();
stack
.
push
(
x
);
stack
.
push
(
x
);
break
;
}
case
90
:
{
op
=
"dup_x1"
;
String
a
=
stack
.
pop
();
String
b
=
stack
.
pop
();
stack
.
push
(
a
);
stack
.
push
(
b
);
stack
.
push
(
a
);
break
;
}
case
91
:
{
// TODO currently we don't know the stack types
op
=
"dup_x2"
;
String
a
=
stack
.
pop
();
String
b
=
stack
.
pop
();
String
c
=
stack
.
pop
();
stack
.
push
(
a
);
stack
.
push
(
c
);
stack
.
push
(
b
);
stack
.
push
(
a
);
break
;
}
case
92
:
{
// TODO currently we don't know the stack types
op
=
"dup2"
;
String
a
=
stack
.
pop
();
String
b
=
stack
.
pop
();
stack
.
push
(
b
);
stack
.
push
(
a
);
stack
.
push
(
b
);
stack
.
push
(
a
);
break
;
}
case
93
:
{
// TODO currently we don't know the stack types
op
=
"dup2_x1"
;
String
a
=
stack
.
pop
();
String
b
=
stack
.
pop
();
String
c
=
stack
.
pop
();
stack
.
push
(
b
);
stack
.
push
(
a
);
stack
.
push
(
c
);
stack
.
push
(
b
);
stack
.
push
(
a
);
break
;
}
case
94
:
{
// TODO currently we don't know the stack types
op
=
"dup2_x2"
;
String
a
=
stack
.
pop
();
String
b
=
stack
.
pop
();
String
c
=
stack
.
pop
();
String
d
=
stack
.
pop
();
stack
.
push
(
b
);
stack
.
push
(
a
);
stack
.
push
(
d
);
stack
.
push
(
c
);
stack
.
push
(
b
);
stack
.
push
(
a
);
break
;
}
case
95
:
{
op
=
"swap"
;
String
a
=
stack
.
pop
();
String
b
=
stack
.
pop
();
stack
.
push
(
a
);
stack
.
push
(
b
);
break
;
}
case
96
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"iadd"
;
stack
.
push
(
"("
+
a
+
" + "
+
b
+
")"
);
break
;
}
case
97
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"ladd"
;
stack
.
push
(
"("
+
a
+
" + "
+
b
+
")"
);
break
;
}
case
98
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"fadd"
;
stack
.
push
(
"("
+
a
+
" + "
+
b
+
")"
);
break
;
}
case
99
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"dadd"
;
stack
.
push
(
"("
+
a
+
" + "
+
b
+
")"
);
break
;
}
case
100
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"isub"
;
stack
.
push
(
"("
+
a
+
" - "
+
b
+
")"
);
break
;
}
case
101
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"lsub"
;
stack
.
push
(
"("
+
a
+
" - "
+
b
+
")"
);
break
;
}
case
102
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"fsub"
;
stack
.
push
(
"("
+
a
+
" - "
+
b
+
")"
);
break
;
}
case
103
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"dsub"
;
stack
.
push
(
"("
+
a
+
" - "
+
b
+
")"
);
break
;
}
case
104
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"imul"
;
stack
.
push
(
"("
+
a
+
" * "
+
b
+
")"
);
break
;
}
case
105
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"lmul"
;
stack
.
push
(
"("
+
a
+
" * "
+
b
+
")"
);
break
;
}
case
106
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"fmul"
;
stack
.
push
(
"("
+
a
+
" * "
+
b
+
")"
);
break
;
}
case
107
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"dmul"
;
stack
.
push
(
"("
+
a
+
" * "
+
b
+
")"
);
break
;
}
case
108
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"idiv"
;
stack
.
push
(
"("
+
a
+
" / "
+
b
+
")"
);
break
;
}
case
109
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"ldiv"
;
stack
.
push
(
"("
+
a
+
" / "
+
b
+
")"
);
break
;
}
case
110
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"fdiv"
;
stack
.
push
(
"("
+
a
+
" / "
+
b
+
")"
);
break
;
}
case
111
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"ddiv"
;
stack
.
push
(
"("
+
a
+
" / "
+
b
+
")"
);
break
;
}
case
112
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"irem"
;
stack
.
push
(
"("
+
a
+
" % "
+
b
+
")"
);
break
;
}
case
113
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"lrem"
;
stack
.
push
(
"("
+
a
+
" % "
+
b
+
")"
);
break
;
}
case
114
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"frem"
;
stack
.
push
(
"("
+
a
+
" % "
+
b
+
")"
);
break
;
}
case
115
:
{
String
b
=
stack
.
pop
();
String
a
=
stack
.
pop
();
op
=
"drem"
;
stack
.
push
(
"("
+
a
+
" % "
+
b
+
")"
);
break
;
}
case
116
:
op
=
"ineg"
;
break
;
case
117
:
op
=
"lneg"
;
break
;
case
118
:
op
=
"fneg"
;
break
;
case
119
:
op
=
"dneg"
;
break
;
case
120
:
op
=
"ishl"
;
break
;
case
121
:
op
=
"lshl"
;
break
;
case
122
:
op
=
"ishr"
;
break
;
case
123
:
op
=
"lshr"
;
break
;
case
124
:
op
=
"iushr"
;
break
;
case
125
:
op
=
"lushr"
;
break
;
case
126
:
op
=
"iand"
;
break
;
case
127
:
op
=
"land"
;
break
;
case
128
:
op
=
"ior"
;
break
;
case
129
:
op
=
"lor"
;
break
;
case
130
:
op
=
"ixor"
;
break
;
case
131
:
op
=
"lxor"
;
break
;
case
132
:
{
int
var
=
readByte
();
int
off
=
(
byte
)
readByte
();
op
=
"iinc "
+
var
+
" "
+
off
;
break
;
}
case
133
:
op
=
"i2l"
;
break
;
case
134
:
op
=
"i2f"
;
break
;
case
135
:
op
=
"i2d"
;
break
;
case
136
:
op
=
"l2i"
;
break
;
case
137
:
op
=
"l2f"
;
break
;
case
138
:
op
=
"l2d"
;
break
;
case
139
:
op
=
"f2i"
;
break
;
case
140
:
op
=
"f2l"
;
break
;
case
141
:
op
=
"f2d"
;
break
;
case
142
:
op
=
"d2i"
;
break
;
case
143
:
op
=
"d2l"
;
break
;
case
144
:
op
=
"d2f"
;
break
;
case
145
:
op
=
"i2b"
;
break
;
case
146
:
op
=
"i2c"
;
break
;
case
147
:
op
=
"i2s"
;
break
;
case
148
:
{
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"SIGN("
+
a
+
" - "
+
b
+
")"
);
op
=
"lcmp"
;
break
;
}
case
149
:
op
=
"fcmpl"
;
break
;
case
150
:
op
=
"fcmpg"
;
break
;
case
151
:
op
=
"dcmpl"
;
break
;
case
152
:
op
=
"dcmpg"
;
break
;
case
153
:
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
stack
.
push
(
"("
+
stack
.
pop
()
+
" = 0)"
);
op
=
"ifeq "
+
nextPc
;
break
;
case
154
:
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
stack
.
push
(
"("
+
stack
.
pop
()
+
" <> 0)"
);
op
=
"ifne "
+
nextPc
;
break
;
case
155
:
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
stack
.
push
(
"("
+
stack
.
pop
()
+
" < 0)"
);
op
=
"iflt "
+
nextPc
;
break
;
case
156
:
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
stack
.
push
(
"("
+
stack
.
pop
()
+
" >= 0)"
);
op
=
"ifge "
+
nextPc
;
break
;
case
157
:
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
stack
.
push
(
"("
+
stack
.
pop
()
+
" > 0)"
);
op
=
"ifgt "
+
nextPc
;
break
;
case
158
:
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
stack
.
push
(
"("
+
stack
.
pop
()
+
"<= 0)"
);
op
=
"ifle "
+
nextPc
;
break
;
case
159
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" = "
+
b
+
")"
);
op
=
"if_icmpeq "
+
nextPc
;
break
;
}
case
160
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" <> "
+
b
+
")"
);
op
=
"if_icmpne "
+
nextPc
;
break
;
}
case
161
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" < "
+
b
+
")"
);
op
=
"if_icmplt "
+
nextPc
;
break
;
}
case
162
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" >= "
+
b
+
")"
);
op
=
"if_icmpge "
+
nextPc
;
break
;
}
case
163
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" > "
+
b
+
")"
);
op
=
"if_icmpgt "
+
nextPc
;
break
;
}
case
164
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" <= "
+
b
+
")"
);
op
=
"if_icmple "
+
nextPc
;
break
;
}
case
165
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" = "
+
b
+
")"
);
op
=
"if_acmpeq "
+
nextPc
;
break
;
}
case
166
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
b
=
stack
.
pop
(),
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" <> "
+
b
+
")"
);
op
=
"if_acmpne "
+
nextPc
;
break
;
}
case
167
:
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
op
=
"goto "
+
nextPc
;
break
;
case
168
:
// TODO not supported yet
op
=
"jsr "
+
getAbsolutePos
(
pos
,
readShort
());
break
;
case
169
:
// TODO not supported yet
op
=
"ret "
+
readByte
();
break
;
case
170
:
{
int
start
=
pos
;
pos
+=
4
-
((
pos
-
startByteCode
)
&
3
);
int
def
=
readInt
();
int
low
=
readInt
(),
high
=
readInt
();
int
n
=
high
-
low
+
1
;
op
=
"tableswitch default:"
+
getAbsolutePos
(
start
,
def
);
StringBuilder
buff
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
buff
.
append
(
' '
).
append
(
low
++).
append
(
":"
).
append
(
getAbsolutePos
(
start
,
readInt
()));
}
op
+=
buff
.
toString
();
// pos += n * 4;
break
;
}
case
171
:
{
int
start
=
pos
;
pos
+=
4
-
((
pos
-
startByteCode
)
&
3
);
int
def
=
readInt
();
int
n
=
readInt
();
op
=
"lookupswitch default:"
+
getAbsolutePos
(
start
,
def
);
StringBuilder
buff
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
<
n
;
i
++)
{
buff
.
append
(
' '
).
append
(
readInt
()).
append
(
":"
).
append
(
getAbsolutePos
(
start
,
readInt
()));
}
op
+=
buff
.
toString
();
// pos += n * 8;
break
;
}
case
172
:
op
=
"ireturn"
;
end
=
true
;
break
;
case
173
:
op
=
"lreturn"
;
end
=
true
;
break
;
case
174
:
op
=
"freturn"
;
end
=
true
;
break
;
case
175
:
op
=
"dreturn"
;
end
=
true
;
break
;
case
176
:
op
=
"areturn"
;
end
=
true
;
break
;
case
177
:
op
=
"return"
;
// no value returned
stack
.
push
(
null
);
end
=
true
;
break
;
case
178
:
op
=
"getstatic "
+
getField
(
readShort
());
break
;
case
179
:
op
=
"putstatic "
+
getField
(
readShort
());
break
;
case
180
:
{
String
field
=
getField
(
readShort
());
String
p
=
stack
.
pop
();
p
=
p
+
"."
+
field
.
substring
(
Math
.
max
(
field
.
lastIndexOf
(
'$'
),
field
.
lastIndexOf
(
'.'
))
+
1
,
field
.
indexOf
(
' '
));
if
(
p
.
startsWith
(
"this."
))
{
p
=
p
.
substring
(
5
);
}
stack
.
push
(
p
);
op
=
"getfield "
+
field
;
break
;
}
case
181
:
op
=
"putfield "
+
getField
(
readShort
());
break
;
case
182
:
{
String
method
=
getMethod
(
readShort
());
op
=
"invokevirtual "
+
method
;
if
(
method
.
equals
(
"java/lang/String.equals (Ljava/lang/Object;)Z"
))
{
String
a
=
stack
.
pop
();
String
b
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" = "
+
b
+
")"
);
}
else
if
(
method
.
equals
(
"java/lang/Integer.intValue ()I"
))
{
// ignore
}
else
if
(
method
.
equals
(
"java/lang/Long.longValue ()J"
))
{
// ignore
}
break
;
}
case
183
:
op
=
"invokespecial "
+
getMethod
(
readShort
());
break
;
case
184
:
op
=
"invokestatic "
+
getMethod
(
readShort
());
break
;
case
185
:
{
int
methodRef
=
readShort
();
readByte
();
readByte
();
op
=
"invokeinterface "
+
getMethod
(
methodRef
);
break
;
}
case
187
:
op
=
"new "
+
cpString
[
cpInt
[
readShort
()]];
break
;
case
188
:
op
=
"newarray "
+
readByte
();
break
;
case
189
:
op
=
"anewarray "
+
cpString
[
readShort
()];
break
;
case
190
:
op
=
"arraylength"
;
break
;
case
191
:
op
=
"athrow"
;
break
;
case
192
:
op
=
"checkcast "
+
cpString
[
readShort
()];
break
;
case
193
:
op
=
"instanceof "
+
cpString
[
readShort
()];
break
;
case
194
:
op
=
"monitorenter"
;
break
;
case
195
:
op
=
"monitorexit"
;
break
;
case
196
:
{
opCode
=
readByte
();
switch
(
opCode
)
{
case
21
:
op
=
"wide iload "
+
readShort
();
break
;
case
22
:
op
=
"wide lload "
+
readShort
();
break
;
case
23
:
op
=
"wide fload "
+
readShort
();
break
;
case
24
:
op
=
"wide dload "
+
readShort
();
break
;
case
25
:
op
=
"wide aload "
+
readShort
();
break
;
case
54
:
op
=
"wide istore "
+
readShort
();
break
;
case
55
:
op
=
"wide lstore "
+
readShort
();
break
;
case
56
:
op
=
"wide fstore "
+
readShort
();
break
;
case
57
:
op
=
"wide dstore "
+
readShort
();
break
;
case
58
:
op
=
"wide astore "
+
readShort
();
break
;
case
132
:
{
int
var
=
readShort
();
int
off
=
(
short
)
readShort
();
op
=
"wide iinc "
+
var
+
" "
+
off
;
break
;
}
case
169
:
op
=
"wide ret "
+
readShort
();
break
;
default
:
throw
new
Error
(
"unsupported wide opCode "
+
opCode
);
}
break
;
}
case
197
:
op
=
"multianewarray "
+
cpString
[
readShort
()]
+
" "
+
readByte
();
break
;
case
198
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" IS NULL)"
);
op
=
"ifnull "
+
nextPc
;
break
;
}
case
199
:
{
condition
=
true
;
nextPc
=
getAbsolutePos
(
pos
,
readShort
());
String
a
=
stack
.
pop
();
stack
.
push
(
"("
+
a
+
" IS NOT NULL)"
);
op
=
"ifnonnull "
+
nextPc
;
break
;
}
case
200
:
op
=
"goto_w "
+
getAbsolutePos
(
pos
,
readInt
());
break
;
case
201
:
op
=
"jsr_w "
+
getAbsolutePos
(
pos
,
readInt
());
break
;
default
:
throw
new
Error
(
"unsupported opCode "
+
opCode
);
}
debug
(
" "
+
startPos
+
": "
+
op
);
}
private
void
setVariable
(
int
x
,
String
value
)
{
while
(
x
>=
variables
.
size
())
{
variables
.
add
(
"p"
+
variables
.
size
());
}
variables
.
set
(
x
,
value
);
}
private
String
getVariable
(
int
x
)
{
if
(
x
==
0
)
{
return
"this"
;
}
while
(
x
>=
variables
.
size
())
{
variables
.
add
(
"p"
+
variables
.
size
());
}
return
variables
.
get
(
x
);
}
private
String
getField
(
int
fieldRef
)
{
int
field
=
cpInt
[
fieldRef
];
int
classIndex
=
field
>>>
16
;
int
nameAndType
=
cpInt
[
field
&
0xffff
];
String
className
=
cpString
[
cpInt
[
classIndex
]]
+
"."
+
cpString
[
nameAndType
>>>
16
]
+
" "
+
cpString
[
nameAndType
&
0xffff
];
return
className
;
}
private
String
getMethod
(
int
methodRef
)
{
int
method
=
cpInt
[
methodRef
];
int
classIndex
=
method
>>>
16
;
int
nameAndType
=
cpInt
[
method
&
0xffff
];
String
className
=
cpString
[
cpInt
[
classIndex
]]
+
"."
+
cpString
[
nameAndType
>>>
16
]
+
" "
+
cpString
[
nameAndType
&
0xffff
];
return
className
;
}
private
String
getConstant
(
int
constantRef
)
{
switch
(
cpType
[
constantRef
])
{
case
3
:
// int
return
cpString
[
constantRef
];
case
4
:
// float
return
cpString
[
constantRef
];
case
5
:
// long
return
cpString
[
constantRef
];
case
6
:
// double
return
cpString
[
constantRef
];
case
8
:
// string
// TODO escape
return
"\""
+
cpString
[
cpInt
[
constantRef
]]
+
"\""
;
default
:
throw
new
Error
(
"not a constant: "
+
constantRef
);
}
}
private
String
readString
()
{
int
size
=
readShort
();
byte
[]
buff
=
data
;
int
p
=
pos
,
end
=
p
+
size
;
char
[]
chars
=
new
char
[
size
];
int
j
=
0
;
for
(;
p
<
end
;
j
++)
{
int
x
=
buff
[
p
++]
&
0xff
;
if
(
x
<
0x80
)
{
chars
[
j
]
=
(
char
)
x
;
}
else
if
(
x
>=
0xe0
)
{
chars
[
j
]
=
(
char
)
(((
x
&
0xf
)
<<
12
)
+
((
buff
[
p
++]
&
0x3f
)
<<
6
)
+
(
buff
[
p
++]
&
0x3f
));
}
else
{
chars
[
j
]
=
(
char
)
(((
x
&
0x1f
)
<<
6
)
+
(
buff
[
p
++]
&
0x3f
));
}
}
pos
=
p
;
return
new
String
(
chars
,
0
,
j
);
}
private
int
getAbsolutePos
(
int
pos
,
int
offset
)
{
return
pos
-
startByteCode
-
1
+
(
short
)
offset
;
}
private
int
readByte
()
{
return
data
[
pos
++]
&
0xff
;
}
private
int
readShort
()
{
byte
[]
buff
=
data
;
return
((
buff
[
pos
++]
&
0xff
)
<<
8
)
+
(
buff
[
pos
++]
&
0xff
);
}
private
int
readInt
()
{
byte
[]
buff
=
data
;
return
(
buff
[
pos
++]
<<
24
)
+
((
buff
[
pos
++]
&
0xff
)
<<
16
)
+
((
buff
[
pos
++]
&
0xff
)
<<
8
)
+
(
buff
[
pos
++]
&
0xff
);
}
private
long
readLong
()
{
return
((
long
)
(
readInt
())
<<
32
)
+
(
readInt
()
&
0xffffffff
L
);
}
}
This diff is collapsed.
Click to expand it.
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论