Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell11
提交
bb1f6a8e
D
dragonwell11
项目概览
openanolis
/
dragonwell11
通知
7
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell11
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
bb1f6a8e
编写于
10月 18, 2013
作者:
H
hannesw
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8026858: Array length does not handle defined properties correctly
Reviewed-by: jlaskey
上级
b8366bfd
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
135 addition
and
40 deletion
+135
-40
nashorn/src/jdk/nashorn/internal/codegen/Lower.java
nashorn/src/jdk/nashorn/internal/codegen/Lower.java
+2
-2
nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
+41
-13
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
+26
-25
nashorn/test/script/basic/JDK-8026858.js
nashorn/test/script/basic/JDK-8026858.js
+66
-0
未找到文件。
nashorn/src/jdk/nashorn/internal/codegen/Lower.java
浏览文件 @
bb1f6a8e
...
...
@@ -88,12 +88,12 @@ final class Lower extends NodeOperatorVisitor<BlockLexicalContext> {
private
static
final
DebugLogger
LOG
=
new
DebugLogger
(
"lower"
);
// needed only to get unique eval id
private
final
CodeInstaller
installer
;
private
final
CodeInstaller
<?>
installer
;
/**
* Constructor.
*/
Lower
(
final
CodeInstaller
installer
)
{
Lower
(
final
CodeInstaller
<?>
installer
)
{
super
(
new
BlockLexicalContext
()
{
@Override
...
...
nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java
浏览文件 @
bb1f6a8e
...
...
@@ -26,6 +26,8 @@
package
jdk.nashorn.internal.runtime
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
PropertyHashMap
.
EMPTY_HASHMAP
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
arrays
.
ArrayIndex
.
getArrayIndex
;
import
static
jdk
.
nashorn
.
internal
.
runtime
.
arrays
.
ArrayIndex
.
isValidArrayIndex
;
import
java.lang.invoke.SwitchPoint
;
import
java.lang.ref.WeakReference
;
...
...
@@ -50,6 +52,8 @@ import java.util.WeakHashMap;
public
final
class
PropertyMap
implements
Iterable
<
Object
>,
PropertyListener
{
/** Used for non extensible PropertyMaps, negative logic as the normal case is extensible. See {@link ScriptObject#preventExtensions()} */
public
static
final
int
NOT_EXTENSIBLE
=
0b0000_0001
;
/** Does this map contain valid array keys? */
public
static
final
int
CONTAINS_ARRAY_KEYS
=
0b0000_0010
;
/** This mask is used to preserve certain flags when cloning the PropertyMap. Others should not be copied */
private
static
final
int
CLONEABLE_FLAGS_MASK
=
0b0000_1111
;
/** Has a listener been added to this property map. This flag is not copied when cloning a map. See {@link PropertyListener} */
...
...
@@ -91,27 +95,22 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
* @param fieldCount Number of fields in use.
* @param fieldMaximum Number of fields available.
* @param spillLength Number of spill slots used.
* @param containsArrayKeys True if properties contain numeric keys
*/
private
PropertyMap
(
final
PropertyHashMap
properties
,
final
int
fieldCount
,
final
int
fieldMaximum
,
final
int
spillLength
)
{
private
PropertyMap
(
final
PropertyHashMap
properties
,
final
int
fieldCount
,
final
int
fieldMaximum
,
final
int
spillLength
,
final
boolean
containsArrayKeys
)
{
this
.
properties
=
properties
;
this
.
fieldCount
=
fieldCount
;
this
.
fieldMaximum
=
fieldMaximum
;
this
.
spillLength
=
spillLength
;
if
(
containsArrayKeys
)
{
setContainsArrayKeys
();
}
if
(
Context
.
DEBUG
)
{
count
++;
}
}
/**
* Constructor.
*
* @param properties A {@link PropertyHashMap} with initial contents.
*/
private
PropertyMap
(
final
PropertyHashMap
properties
)
{
this
(
properties
,
0
,
0
,
0
);
}
/**
* Cloning constructor.
*
...
...
@@ -152,12 +151,15 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
if
(
Context
.
DEBUG
)
{
duplicatedCount
++;
}
return
new
PropertyMap
(
this
.
properties
);
return
new
PropertyMap
(
this
.
properties
,
0
,
0
,
0
,
containsArrayKeys
()
);
}
/**
* Public property map allocator.
*
* <p>It is the caller's responsibility to make sure that {@code properties} does not contain
* properties with keys that are valid array indices.</p>
*
* @param properties Collection of initial properties.
* @param fieldCount Number of fields in use.
* @param fieldMaximum Number of fields available.
...
...
@@ -166,11 +168,15 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
*/
public
static
PropertyMap
newMap
(
final
Collection
<
Property
>
properties
,
final
int
fieldCount
,
final
int
fieldMaximum
,
final
int
spillLength
)
{
PropertyHashMap
newProperties
=
EMPTY_HASHMAP
.
immutableAdd
(
properties
);
return
new
PropertyMap
(
newProperties
,
fieldCount
,
fieldMaximum
,
spillLength
);
return
new
PropertyMap
(
newProperties
,
fieldCount
,
fieldMaximum
,
spillLength
,
false
);
}
/**
* Public property map allocator. Used by nasgen generated code.
*
* <p>It is the caller's responsibility to make sure that {@code properties} does not contain
* properties with keys that are valid array indices.</p>
*
* @param properties Collection of initial properties.
* @return New {@link PropertyMap}.
*/
...
...
@@ -184,7 +190,7 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
* @return New empty {@link PropertyMap}.
*/
public
static
PropertyMap
newMap
()
{
return
new
PropertyMap
(
EMPTY_HASHMAP
);
return
new
PropertyMap
(
EMPTY_HASHMAP
,
0
,
0
,
0
,
false
);
}
/**
...
...
@@ -294,6 +300,9 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
if
(!
property
.
isSpill
())
{
newMap
.
fieldCount
=
Math
.
max
(
newMap
.
fieldCount
,
property
.
getSlot
()
+
1
);
}
if
(
isValidArrayIndex
(
getArrayIndex
(
property
.
getKey
())))
{
newMap
.
setContainsArrayKeys
();
}
newMap
.
spillLength
+=
property
.
getSpillCount
();
}
...
...
@@ -408,6 +417,9 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
final
PropertyMap
newMap
=
new
PropertyMap
(
this
,
newProperties
);
for
(
final
Property
property
:
otherProperties
)
{
if
(
isValidArrayIndex
(
getArrayIndex
(
property
.
getKey
())))
{
newMap
.
setContainsArrayKeys
();
}
newMap
.
spillLength
+=
property
.
getSpillCount
();
}
...
...
@@ -699,6 +711,22 @@ public final class PropertyMap implements Iterable<Object>, PropertyListener {
return
new
PropertyMapIterator
(
this
);
}
/**
* Check if this map contains properties with valid array keys
*
* @return {@code true} if this map contains properties with valid array keys
*/
public
final
boolean
containsArrayKeys
()
{
return
(
flags
&
CONTAINS_ARRAY_KEYS
)
!=
0
;
}
/**
* Flag this object as having array keys in defined properties
*/
private
void
setContainsArrayKeys
()
{
flags
|=
CONTAINS_ARRAY_KEYS
;
}
/**
* Check whether a {@link PropertyListener} has been added to this map.
*
...
...
nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
浏览文件 @
bb1f6a8e
...
...
@@ -508,7 +508,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
if
(
property
==
null
)
{
// promoting an arrayData value to actual property
addOwnProperty
(
key
,
propFlags
,
value
);
removeArraySlot
(
key
);
checkIntegerKey
(
key
);
}
else
{
// Now set the new flags
modifyOwnProperty
(
property
,
propFlags
);
...
...
@@ -616,15 +616,6 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
}
private
void
removeArraySlot
(
final
String
key
)
{
final
int
index
=
getArrayIndex
(
key
);
final
ArrayData
array
=
getArray
();
if
(
array
.
has
(
index
))
{
setArray
(
array
.
delete
(
index
));
}
}
/**
* Add a new property to the object.
*
...
...
@@ -1203,21 +1194,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* Check if this ScriptObject has array entries. This means that someone has
* set values with numeric keys in the object.
*
* Note: this can be O(n) up to the array length
*
* @return true if array entries exists.
*/
public
boolean
hasArrayEntries
()
{
final
ArrayData
array
=
getArray
();
final
long
length
=
array
.
length
();
for
(
long
i
=
0
;
i
<
length
;
i
++)
{
if
(
array
.
has
((
int
)
i
))
{
return
true
;
}
}
return
false
;
return
getArray
().
length
()
>
0
||
getMap
().
containsArrayKeys
();
}
/**
...
...
@@ -2356,8 +2336,29 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
if
(
newLength
<
arrayLength
)
{
setArray
(
getArray
().
shrink
(
newLength
));
getArray
().
setLength
(
newLength
);
long
actualLength
=
newLength
;
// Check for numeric keys in property map and delete them or adjust length, depending on whether
// they're defined as configurable. See ES5 #15.4.5.2
if
(
getMap
().
containsArrayKeys
())
{
for
(
long
l
=
arrayLength
-
1
;
l
>=
newLength
;
l
--)
{
final
FindProperty
find
=
findProperty
(
JSType
.
toString
(
l
),
false
);
if
(
find
!=
null
)
{
if
(
find
.
getProperty
().
isConfigurable
())
{
deleteOwnProperty
(
find
.
getProperty
());
}
else
{
actualLength
=
l
+
1
;
break
;
}
}
}
}
setArray
(
getArray
().
shrink
(
actualLength
));
getArray
().
setLength
(
actualLength
);
}
}
...
...
@@ -2680,7 +2681,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
final
long
oldLength
=
getArray
().
length
();
final
long
longIndex
=
index
&
JSType
.
MAX_UINT
;
if
(
!
getArray
().
has
(
index
))
{
if
(
getMap
().
containsArrayKeys
(
))
{
final
String
key
=
JSType
.
toString
(
longIndex
);
final
FindProperty
find
=
findProperty
(
key
,
true
);
...
...
nashorn/test/script/basic/JDK-8026858.js
0 → 100644
浏览文件 @
bb1f6a8e
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code 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 General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* JDK-8026858: Array length does not handle defined properties correctly
*
* @test
* @run
*/
var
arr
=
[];
Object
.
defineProperty
(
arr
,
"
3
"
,
{
value
:
1
/* configurable: false */
});
if
(
arr
[
3
]
!=
1
)
{
throw
new
Error
(
"
arr[3] not defined
"
);
}
if
(
arr
.
length
!==
4
)
{
throw
new
Error
(
"
Array length not updated to 4
"
);
}
Object
.
defineProperty
(
arr
,
"
5
"
,
{
value
:
1
,
configurable
:
true
});
if
(
arr
[
5
]
!=
1
)
{
throw
new
Error
(
"
arr[5] not defined
"
);
}
if
(
arr
.
length
!==
6
)
{
throw
new
Error
(
"
Array length not updated to 4
"
);
}
arr
.
length
=
0
;
if
(
5
in
arr
)
{
throw
new
Error
(
"
configurable element was not deleted
"
);
}
if
(
arr
[
3
]
!=
1
)
{
throw
new
Error
(
"
non-configurable element was deleted
"
);
}
if
(
arr
.
length
!==
4
)
{
throw
new
Error
(
"
Array length not set
"
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录