Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
67f60891
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
67f60891
编写于
9月 10, 2014
作者:
V
vlivanov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8050200: Make LambdaForm intrinsics detection more robust
Reviewed-by: vlivanov, psandoz Contributed-by: john.r.rose@oracle.com
上级
429c3764
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
140 addition
and
86 deletion
+140
-86
src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
...re/classes/java/lang/invoke/InvokerBytecodeGenerator.java
+55
-71
src/share/classes/java/lang/invoke/LambdaForm.java
src/share/classes/java/lang/invoke/LambdaForm.java
+6
-2
src/share/classes/java/lang/invoke/MethodHandle.java
src/share/classes/java/lang/invoke/MethodHandle.java
+6
-3
src/share/classes/java/lang/invoke/MethodHandleImpl.java
src/share/classes/java/lang/invoke/MethodHandleImpl.java
+73
-10
未找到文件。
src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
浏览文件 @
67f60891
...
...
@@ -35,7 +35,7 @@ import static java.lang.invoke.LambdaForm.*;
import
static
java
.
lang
.
invoke
.
LambdaForm
.
BasicType
.*;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
import
static
java
.
lang
.
invoke
.
MethodHandleNatives
.
Constants
.*;
import
java.lang.invoke.MethodHandleImpl.ArrayAccessor
;
import
sun.invoke.util.VerifyAccess
;
import
sun.invoke.util.VerifyType
;
import
sun.invoke.util.Wrapper
;
...
...
@@ -636,26 +636,44 @@ class InvokerBytecodeGenerator {
Name
onStack
=
null
;
for
(
int
i
=
lambdaForm
.
arity
;
i
<
lambdaForm
.
names
.
length
;
i
++)
{
Name
name
=
lambdaForm
.
names
[
i
];
MemberName
member
=
name
.
function
.
member
();
Class
<?>
rtype
=
name
.
function
.
methodType
().
returnType
();
emitStoreResult
(
onStack
);
onStack
=
name
;
// unless otherwise modified below
MethodHandleImpl
.
Intrinsic
intr
=
name
.
function
.
intrinsicName
();
switch
(
intr
)
{
case
SELECT_ALTERNATIVE:
assert
isSelectAlternative
(
i
);
onStack
=
emitSelectAlternative
(
name
,
lambdaForm
.
names
[
i
+
1
]);
i
++;
// skip MH.invokeBasic of the selectAlternative result
continue
;
case
GUARD_WITH_CATCH:
assert
isGuardWithCatch
(
i
);
onStack
=
emitGuardWithCatch
(
i
);
i
=
i
+
2
;
// Jump to the end of GWC idiom
continue
;
case
NEW_ARRAY:
Class
<?>
rtype
=
name
.
function
.
methodType
().
returnType
();
if
(
isStaticallyNameable
(
rtype
))
{
emitNewArray
(
name
);
continue
;
}
break
;
case
ARRAY_LOAD:
emitArrayLoad
(
name
);
continue
;
case
ARRAY_STORE:
emitArrayStore
(
name
);
continue
;
case
NONE:
// no intrinsic associated
break
;
default
:
throw
newInternalError
(
"Unknown intrinsic: "
+
intr
);
}
if
(
isSelectAlternative
(
i
))
{
onStack
=
emitSelectAlternative
(
name
,
lambdaForm
.
names
[
i
+
1
]);
i
++;
// skip MH.invokeBasic of the selectAlternative result
}
else
if
(
isGuardWithCatch
(
i
))
{
onStack
=
emitGuardWithCatch
(
i
);
i
=
i
+
2
;
// Jump to the end of GWC idiom
}
else
if
(
isNewArray
(
rtype
,
name
))
{
emitNewArray
(
rtype
,
name
);
}
else
if
(
isArrayLoad
(
member
))
{
emitArrayLoad
(
name
);
}
else
if
(
isArrayStore
(
member
))
{
emitArrayStore
(
name
);
}
else
if
(
isStaticallyInvocable
(
member
))
{
emitStaticInvoke
(
name
);
MemberName
member
=
name
.
function
.
member
();
if
(
isStaticallyInvocable
(
member
))
{
emitStaticInvoke
(
member
,
name
);
}
else
{
emitInvoke
(
name
);
}
...
...
@@ -672,20 +690,6 @@ class InvokerBytecodeGenerator {
return
classFile
;
}
boolean
isArrayLoad
(
MemberName
member
)
{
return
member
!=
null
&&
member
.
getDeclaringClass
()
==
ArrayAccessor
.
class
&&
member
.
getName
()
!=
null
&&
member
.
getName
().
startsWith
(
"getElement"
);
}
boolean
isArrayStore
(
MemberName
member
)
{
return
member
!=
null
&&
member
.
getDeclaringClass
()
==
ArrayAccessor
.
class
&&
member
.
getName
()
!=
null
&&
member
.
getName
().
startsWith
(
"setElement"
);
}
void
emitArrayLoad
(
Name
name
)
{
emitArrayOp
(
name
,
Opcodes
.
AALOAD
);
}
void
emitArrayStore
(
Name
name
)
{
emitArrayOp
(
name
,
Opcodes
.
AASTORE
);
}
...
...
@@ -837,33 +841,31 @@ class InvokerBytecodeGenerator {
}
}
boolean
isNewArray
(
Class
<?>
rtype
,
Name
name
)
{
return
rtype
.
isArray
()
&&
isStaticallyNameable
(
rtype
)
&&
isArrayBuilder
(
name
.
function
.
resolvedHandle
)
&&
name
.
arguments
.
length
>
0
;
}
void
emitNewArray
(
Class
<?>
rtype
,
Name
name
)
throws
InternalError
{
void
emitNewArray
(
Name
name
)
throws
InternalError
{
Class
<?>
rtype
=
name
.
function
.
methodType
().
returnType
();
if
(
name
.
arguments
.
length
==
0
)
{
// The array will be a constant.
Object
emptyArray
;
try
{
emptyArray
=
name
.
function
.
resolvedHandle
.
invoke
();
}
catch
(
Throwable
ex
)
{
throw
newInternalError
(
ex
);
}
assert
(
java
.
lang
.
reflect
.
Array
.
getLength
(
emptyArray
)
==
0
);
assert
(
emptyArray
.
getClass
()
==
rtype
);
// exact typing
mv
.
visitLdcInsn
(
constantPlaceholder
(
emptyArray
));
emitReferenceCast
(
rtype
,
emptyArray
);
return
;
}
Class
<?>
arrayElementType
=
rtype
.
getComponentType
();
assert
(
arrayElementType
!=
null
);
emitIconstInsn
(
name
.
arguments
.
length
);
int
xas
;
int
xas
=
Opcodes
.
AASTORE
;
if
(!
arrayElementType
.
isPrimitive
())
{
mv
.
visitTypeInsn
(
Opcodes
.
ANEWARRAY
,
getInternalName
(
arrayElementType
));
xas
=
Opcodes
.
AASTORE
;
}
else
{
int
tc
;
switch
(
Wrapper
.
forPrimitiveType
(
arrayElementType
))
{
case
BOOLEAN:
tc
=
Opcodes
.
T_BOOLEAN
;
xas
=
Opcodes
.
BASTORE
;
break
;
case
BYTE:
tc
=
Opcodes
.
T_BYTE
;
xas
=
Opcodes
.
BASTORE
;
break
;
case
CHAR:
tc
=
Opcodes
.
T_CHAR
;
xas
=
Opcodes
.
CASTORE
;
break
;
case
SHORT:
tc
=
Opcodes
.
T_SHORT
;
xas
=
Opcodes
.
SASTORE
;
break
;
case
INT:
tc
=
Opcodes
.
T_INT
;
xas
=
Opcodes
.
IASTORE
;
break
;
case
LONG:
tc
=
Opcodes
.
T_LONG
;
xas
=
Opcodes
.
LASTORE
;
break
;
case
FLOAT:
tc
=
Opcodes
.
T_FLOAT
;
xas
=
Opcodes
.
FASTORE
;
break
;
case
DOUBLE:
tc
=
Opcodes
.
T_DOUBLE
;
xas
=
Opcodes
.
DASTORE
;
break
;
default
:
throw
new
InternalError
(
rtype
.
getName
());
}
byte
tc
=
arrayTypeCode
(
Wrapper
.
forPrimitiveType
(
arrayElementType
));
xas
=
arrayInsnOpcode
(
tc
,
xas
);
mv
.
visitIntInsn
(
Opcodes
.
NEWARRAY
,
tc
);
}
// store arguments
...
...
@@ -890,24 +892,6 @@ class InvokerBytecodeGenerator {
throw
new
InternalError
(
"refKind="
+
refKind
);
}
static
boolean
isArrayBuilder
(
MethodHandle
fn
)
{
if
(
fn
==
null
)
return
false
;
MethodType
mtype
=
fn
.
type
();
Class
<?>
rtype
=
mtype
.
returnType
();
Class
<?>
arrayElementType
=
rtype
.
getComponentType
();
if
(
arrayElementType
==
null
)
return
false
;
List
<
Class
<?>>
ptypes
=
mtype
.
parameterList
();
int
size
=
ptypes
.
size
();
if
(!
ptypes
.
equals
(
Collections
.
nCopies
(
size
,
arrayElementType
)))
return
false
;
// Assume varargsArray caches pointers.
if
(
fn
!=
MethodHandleImpl
.
varargsArray
(
rtype
,
size
))
return
false
;
return
true
;
}
/**
* Check if MemberName is a call to a method named {@code name} in class {@code declaredClass}.
*/
...
...
src/share/classes/java/lang/invoke/LambdaForm.java
浏览文件 @
67f60891
...
...
@@ -27,11 +27,10 @@ package java.lang.invoke;
import
java.lang.annotation.*
;
import
java.lang.reflect.Method
;
import
java.util.Map
;
import
java.util.List
;
import
java.util.Arrays
;
import
java.util.HashMap
;
import
java.util.concurrent.ConcurrentHashMap
;
import
sun.invoke.util.Wrapper
;
import
java.lang.reflect.Field
;
...
...
@@ -1371,6 +1370,11 @@ class LambdaForm {
public
boolean
isConstantZero
()
{
return
this
.
equals
(
constantZero
(
returnType
()));
}
public
MethodHandleImpl
.
Intrinsic
intrinsicName
()
{
return
resolvedHandle
==
null
?
MethodHandleImpl
.
Intrinsic
.
NONE
:
resolvedHandle
.
intrinsicName
();
}
}
public
static
String
basicTypeSignature
(
MethodType
type
)
{
...
...
src/share/classes/java/lang/invoke/MethodHandle.java
浏览文件 @
67f60891
...
...
@@ -27,11 +27,8 @@ package java.lang.invoke;
import
java.util.*
;
import
java.lang.invoke.LambdaForm.BasicType
;
import
sun.misc.Unsafe
;
import
static
java
.
lang
.
invoke
.
MethodHandleStatics
.*;
import
static
java
.
lang
.
invoke
.
LambdaForm
.
BasicType
.*;
/**
* A method handle is a typed, directly executable reference to an underlying method,
...
...
@@ -1355,6 +1352,12 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
return
null
;
// caller-bound MH for @CallerSensitive method returns caller
}
/*non-public*/
MethodHandleImpl
.
Intrinsic
intrinsicName
()
{
// no special intrinsic meaning to most MHs
return
MethodHandleImpl
.
Intrinsic
.
NONE
;
}
/*non-public*/
MethodHandle
withInternalMemberName
(
MemberName
member
,
boolean
isInvokeSpecial
)
{
if
(
member
!=
null
)
{
...
...
src/share/classes/java/lang/invoke/MethodHandleImpl.java
浏览文件 @
67f60891
...
...
@@ -30,7 +30,6 @@ import java.security.PrivilegedAction;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.List
;
import
sun.invoke.empty.Empty
;
import
sun.invoke.util.ValueConversions
;
...
...
@@ -86,6 +85,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
// safe to view non-strictly, because element type follows from array type
mh
=
mh
.
viewAsType
(
correctType
,
false
);
}
mh
=
makeIntrinsic
(
mh
,
(
isSetter
?
Intrinsic
.
ARRAY_STORE
:
Intrinsic
.
ARRAY_LOAD
));
// Atomically update accessor cache.
synchronized
(
cache
)
{
if
(
cache
[
cacheIndex
]
==
null
)
{
...
...
@@ -111,8 +111,8 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static
final
MethodHandle
OBJECT_ARRAY_GETTER
,
OBJECT_ARRAY_SETTER
;
static
{
MethodHandle
[]
cache
=
TYPED_ACCESSORS
.
get
(
Object
[].
class
);
cache
[
GETTER_INDEX
]
=
OBJECT_ARRAY_GETTER
=
getAccessor
(
Object
[].
class
,
false
);
cache
[
SETTER_INDEX
]
=
OBJECT_ARRAY_SETTER
=
getAccessor
(
Object
[].
class
,
true
);
cache
[
GETTER_INDEX
]
=
OBJECT_ARRAY_GETTER
=
makeIntrinsic
(
getAccessor
(
Object
[].
class
,
false
),
Intrinsic
.
ARRAY_LOAD
);
cache
[
SETTER_INDEX
]
=
OBJECT_ARRAY_SETTER
=
makeIntrinsic
(
getAccessor
(
Object
[].
class
,
true
),
Intrinsic
.
ARRAY_STORE
);
assert
(
InvokerBytecodeGenerator
.
isStaticallyInvocable
(
ArrayAccessor
.
OBJECT_ARRAY_GETTER
.
internalMemberName
()));
assert
(
InvokerBytecodeGenerator
.
isStaticallyInvocable
(
ArrayAccessor
.
OBJECT_ARRAY_SETTER
.
internalMemberName
()));
...
...
@@ -502,10 +502,10 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
static
final
NamedFunction
NF_checkSpreadArgument
;
static
final
NamedFunction
NF_guardWithCatch
;
static
final
NamedFunction
NF_selectAlternative
;
static
final
NamedFunction
NF_throwException
;
static
final
MethodHandle
MH_castReference
;
static
final
MethodHandle
MH_selectAlternative
;
static
final
MethodHandle
MH_copyAsPrimitiveArray
;
static
final
MethodHandle
MH_fillNewTypedArray
;
static
final
MethodHandle
MH_fillNewArray
;
...
...
@@ -516,13 +516,10 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
NF_checkSpreadArgument
=
new
NamedFunction
(
MHI
.
getDeclaredMethod
(
"checkSpreadArgument"
,
Object
.
class
,
int
.
class
));
NF_guardWithCatch
=
new
NamedFunction
(
MHI
.
getDeclaredMethod
(
"guardWithCatch"
,
MethodHandle
.
class
,
Class
.
class
,
MethodHandle
.
class
,
Object
[].
class
));
NF_selectAlternative
=
new
NamedFunction
(
MHI
.
getDeclaredMethod
(
"selectAlternative"
,
boolean
.
class
,
MethodHandle
.
class
,
MethodHandle
.
class
));
NF_throwException
=
new
NamedFunction
(
MHI
.
getDeclaredMethod
(
"throwException"
,
Throwable
.
class
));
NF_checkSpreadArgument
.
resolve
();
NF_guardWithCatch
.
resolve
();
NF_selectAlternative
.
resolve
();
NF_throwException
.
resolve
();
MH_castReference
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"castReference"
,
...
...
@@ -535,6 +532,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodType
.
methodType
(
Object
[].
class
,
Integer
.
class
,
Object
[].
class
));
MH_fillNewTypedArray
=
IMPL_LOOKUP
.
findStatic
(
MHI
,
"fillNewTypedArray"
,
MethodType
.
methodType
(
Object
[].
class
,
Object
[].
class
,
Integer
.
class
,
Object
[].
class
));
MH_selectAlternative
=
makeIntrinsic
(
IMPL_LOOKUP
.
findStatic
(
MHI
,
"selectAlternative"
,
MethodType
.
methodType
(
MethodHandle
.
class
,
boolean
.
class
,
MethodHandle
.
class
,
MethodHandle
.
class
)),
Intrinsic
.
SELECT_ALTERNATIVE
);
}
catch
(
ReflectiveOperationException
ex
)
{
throw
newInternalError
(
ex
);
}
...
...
@@ -620,7 +622,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
// call selectAlternative
Object
[]
selectArgs
=
{
names
[
arity
+
1
],
target
,
fallback
};
names
[
arity
+
2
]
=
new
Name
(
Lazy
.
NF
_selectAlternative
,
selectArgs
);
names
[
arity
+
2
]
=
new
Name
(
Lazy
.
MH
_selectAlternative
,
selectArgs
);
targetArgs
[
0
]
=
names
[
arity
+
2
];
// call target or fallback
...
...
@@ -689,7 +691,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
Object
[]
args
=
new
Object
[
invokeBasic
.
type
().
parameterCount
()];
args
[
0
]
=
names
[
GET_COLLECT_ARGS
];
System
.
arraycopy
(
names
,
ARG_BASE
,
args
,
1
,
ARG_LIMIT
-
ARG_BASE
);
names
[
BOXED_ARGS
]
=
new
Name
(
new
NamedFunction
(
invokeBasic
),
args
);
names
[
BOXED_ARGS
]
=
new
Name
(
makeIntrinsic
(
invokeBasic
,
Intrinsic
.
GUARD_WITH_CATCH
),
args
);
// t_{i+1}:L=MethodHandleImpl.guardWithCatch(target:L,exType:L,catcher:L,t_{i}:L);
Object
[]
gwcArgs
=
new
Object
[]
{
names
[
GET_TARGET
],
names
[
GET_CLASS
],
names
[
GET_CATCHER
],
names
[
BOXED_ARGS
]};
...
...
@@ -698,7 +700,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
// t_{i+2}:I=MethodHandle.invokeBasic(unbox:L,t_{i+1}:L);
MethodHandle
invokeBasicUnbox
=
MethodHandles
.
basicInvoker
(
MethodType
.
methodType
(
basicType
.
rtype
(),
Object
.
class
));
Object
[]
unboxArgs
=
new
Object
[]
{
names
[
GET_UNBOX_RESULT
],
names
[
TRY_CATCH
]};
names
[
UNBOX_RESULT
]
=
new
Name
(
new
NamedFunction
(
invokeBasicUnbox
)
,
unboxArgs
);
names
[
UNBOX_RESULT
]
=
new
Name
(
invokeBasicUnbox
,
unboxArgs
);
lform
=
new
LambdaForm
(
"guardWithCatch"
,
lambdaType
.
parameterCount
(),
names
);
...
...
@@ -1004,6 +1006,63 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
return
new
WrappedMember
(
target
,
target
.
type
(),
member
,
isInvokeSpecial
,
null
);
}
/** Intrinsic IDs */
/*non-public*/
enum
Intrinsic
{
SELECT_ALTERNATIVE
,
GUARD_WITH_CATCH
,
NEW_ARRAY
,
ARRAY_LOAD
,
ARRAY_STORE
,
NONE
// no intrinsic associated
}
/** Mark arbitrary method handle as intrinsic.
* InvokerBytecodeGenerator uses this info to produce more efficient bytecode shape. */
private
static
final
class
IntrinsicMethodHandle
extends
DelegatingMethodHandle
{
private
final
MethodHandle
target
;
private
final
Intrinsic
intrinsicName
;
IntrinsicMethodHandle
(
MethodHandle
target
,
Intrinsic
intrinsicName
)
{
super
(
target
.
type
(),
target
);
this
.
target
=
target
;
this
.
intrinsicName
=
intrinsicName
;
}
@Override
protected
MethodHandle
getTarget
()
{
return
target
;
}
@Override
Intrinsic
intrinsicName
()
{
return
intrinsicName
;
}
@Override
public
MethodHandle
asTypeUncached
(
MethodType
newType
)
{
// This MH is an alias for target, except for the intrinsic name
// Drop the name if there is any conversion.
return
asTypeCache
=
target
.
asType
(
newType
);
}
@Override
String
internalProperties
()
{
return
super
.
internalProperties
()
+
"\n& Intrinsic="
+
intrinsicName
;
}
}
static
MethodHandle
makeIntrinsic
(
MethodHandle
target
,
Intrinsic
intrinsicName
)
{
if
(
intrinsicName
==
target
.
intrinsicName
())
return
target
;
return
new
IntrinsicMethodHandle
(
target
,
intrinsicName
);
}
static
MethodHandle
makeIntrinsic
(
MethodType
type
,
LambdaForm
form
,
Intrinsic
intrinsicName
)
{
return
new
IntrinsicMethodHandle
(
SimpleMethodHandle
.
make
(
type
,
form
),
intrinsicName
);
}
/// Collection of multiple arguments.
private
static
MethodHandle
findCollector
(
String
name
,
int
nargs
,
Class
<?>
rtype
,
Class
<?>...
ptypes
)
{
...
...
@@ -1053,6 +1112,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
for
(;;)
{
MethodHandle
mh
=
findCollector
(
"array"
,
mhs
.
size
(),
Object
[].
class
);
if
(
mh
==
null
)
break
;
mh
=
makeIntrinsic
(
mh
,
Intrinsic
.
NEW_ARRAY
);
mhs
.
add
(
mh
);
}
assert
(
mhs
.
size
()
==
11
);
// current number of methods
...
...
@@ -1131,9 +1191,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
MethodHandle
mh
=
ARRAYS
[
nargs
];
if
(
mh
!=
null
)
return
mh
;
mh
=
findCollector
(
"array"
,
nargs
,
Object
[].
class
);
if
(
mh
!=
null
)
mh
=
makeIntrinsic
(
mh
,
Intrinsic
.
NEW_ARRAY
);
if
(
mh
!=
null
)
return
ARRAYS
[
nargs
]
=
mh
;
mh
=
buildVarargsArray
(
Lazy
.
MH_fillNewArray
,
Lazy
.
MH_arrayIdentity
,
nargs
);
assert
(
assertCorrectArity
(
mh
,
nargs
));
mh
=
makeIntrinsic
(
mh
,
Intrinsic
.
NEW_ARRAY
);
return
ARRAYS
[
nargs
]
=
mh
;
}
...
...
@@ -1263,6 +1325,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
mh
=
buildVarargsArray
(
builder
,
producer
,
nargs
);
}
mh
=
mh
.
asType
(
MethodType
.
methodType
(
arrayType
,
Collections
.<
Class
<?>>
nCopies
(
nargs
,
elemType
)));
mh
=
makeIntrinsic
(
mh
,
Intrinsic
.
NEW_ARRAY
);
assert
(
assertCorrectArity
(
mh
,
nargs
));
if
(
nargs
<
cache
.
length
)
cache
[
nargs
]
=
mh
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录