Made getOwnPropertDescriptor use the actual attributes for builtins, rather

than the isMethod heuristic.

Patch from Raphael Speyer.


git-svn-id: svn://10.0.0.236/trunk@258016 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
nboyd%atg.com
2009-08-08 20:56:57 +00:00
parent 46753e3326
commit eea8cc1e97
3 changed files with 44 additions and 21 deletions

View File

@@ -720,23 +720,38 @@ public abstract class IdScriptableObject extends ScriptableObject
protected ScriptableObject getOwnPropertyDescriptor(Context cx, Object id) {
ScriptableObject desc = super.getOwnPropertyDescriptor(cx, id);
if (desc == null && id instanceof String) {
Object value = get((String) id, this);
if (value != NOT_FOUND) {
boolean isMethod = (value instanceof Callable);
desc = new NativeObject();
Scriptable scope = getParentScope();
ScriptRuntime.setObjectProtoAndParent(desc, (scope == null ? this : scope));
desc.defineProperty("value", value, EMPTY);
desc.defineProperty("enumerable", false, EMPTY);
desc.defineProperty("writable", isMethod, EMPTY);
desc.defineProperty("configurable", isMethod, EMPTY);
}
desc = getBuiltInDescriptor((String) id);
}
return desc;
}
private ScriptableObject getBuiltInDescriptor(String name) {
Object value = null;
int attr = EMPTY;
Scriptable scope = getParentScope();
if (scope == null) {
scope = this;
}
int info = findInstanceIdInfo(name);
if (info != 0) {
int id = (info & 0xFFFF);
value = getInstanceIdValue(id);
attr = (info >>> 16);
return buildDataDescriptor(scope, value, attr);
}
if (prototypeValues != null) {
int id = prototypeValues.findId(name);
if (id != 0) {
value = prototypeValues.get(id);
attr = prototypeValues.getAttributes(id);
return buildDataDescriptor(scope, value, attr);
}
}
return null;
}
private void readObject(ObjectInputStream stream)
throws IOException, ClassNotFoundException
{

View File

@@ -206,17 +206,25 @@ public abstract class ScriptableObject implements Scriptable, Serializable,
}
ScriptableObject getPropertyDescriptor(Context cx, Scriptable scope) {
ScriptableObject desc = new NativeObject();
ScriptRuntime.setObjectProtoAndParent(desc, scope);
if (value != null) desc.defineProperty("value", value, EMPTY);
desc.defineProperty("writable", (attributes & READONLY) == 0, EMPTY);
desc.defineProperty("enumerable", (attributes & DONTENUM) == 0, EMPTY);
desc.defineProperty("configurable", (attributes & PERMANENT) == 0, EMPTY);
return desc;
return buildDataDescriptor(
scope,
(value == null ? Undefined.instance : value),
attributes);
}
}
protected static ScriptableObject buildDataDescriptor(Scriptable scope, Object value, int attributes) {
ScriptableObject desc = new NativeObject();
ScriptRuntime.setObjectProtoAndParent(desc, scope);
desc.defineProperty("value", value, EMPTY);
desc.defineProperty("writable", (attributes & READONLY) == 0, EMPTY);
desc.defineProperty("enumerable", (attributes & DONTENUM) == 0, EMPTY);
desc.defineProperty("configurable", (attributes & PERMANENT) == 0, EMPTY);
return desc;
}
private static final class GetterSlot extends Slot
{
static final long serialVersionUID = -4900574849788797588L;

View File

@@ -32,7 +32,7 @@ js> var describe = Object.getOwnPropertyDescriptor;
js> // when define new property with empty descriptor then default values are used for the descriptor
js> var obj = define({}, 'a', {});
js> describe(obj, 'a').toSource()
({writable:false, enumerable:false, configurable:false})
({value:undefined, writable:false, enumerable:false, configurable:false})
js> // when define new property with data descriptor then those values are used for the descriptor
js> var obj = define({}, 'a', { value: 2, writable: true });