Fixing bug 254915: proper name lookup etc.

This commit is contained in:
igor%mir2.org 2004-08-09 16:57:06 +00:00
Родитель 2628259213
Коммит ca75e5c0c8
3 изменённых файлов: 59 добавлений и 55 удалений

Просмотреть файл

@ -2459,7 +2459,7 @@ switch (op) {
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
--stackTop;
Scriptable lhs = (Scriptable)stack[stackTop];
stack[stackTop] = ScriptRuntime.setName(lhs, rhs, cx, stringReg);
stack[stackTop] = ScriptRuntime.setName(lhs, rhs, cx, scope, stringReg);
continue Loop;
}
case Token.DELPROP : {

Просмотреть файл

@ -1640,43 +1640,69 @@ public class ScriptRuntime {
* Looks up a name in the scope chain and returns its value.
*/
public static Object name(Context cx, Scriptable scopeChain, String id)
{
return name(cx, scopeChain, id, false);
}
private static Object name(Context cx, Scriptable scopeChain, String id,
boolean asFunctionCall)
{
Scriptable scope = scopeChain;
XMLObject firstXMLObject = null;
do {
Object result;
for (;;) {
if (scope instanceof NativeWith) {
Scriptable withObj = scope.getPrototype();
if (withObj instanceof XMLObject) {
XMLObject xmlObj = (XMLObject)withObj;
if (xmlObj.ecmaHas(cx, id)) {
return xmlObj.ecmaGet(cx, id);
result = xmlObj.ecmaGet(cx, id);
break;
}
if (firstXMLObject == null) {
firstXMLObject = xmlObj;
}
} else {
Object result = ScriptableObject.getProperty(withObj, id);
result = ScriptableObject.getProperty(withObj, id);
if (result != Scriptable.NOT_FOUND) {
return result;
break;
}
}
} else {
Object result = ScriptableObject.getProperty(scope, id);
result = ScriptableObject.getProperty(scope, id);
if (result != Scriptable.NOT_FOUND) {
return result;
break;
}
}
scope = scope.getParentScope();
} while (scope != null);
if (scope == null) {
if (firstXMLObject != null) {
// The name was not found, but we did find an XML object in the
// scope chain. The result should be an empty XMLList
return firstXMLObject.ecmaGet(cx, id);
// The name was not found, but we did find an XML object in
//the scope chain. The result should be an empty XMLList
result = firstXMLObject.ecmaGet(cx, id);
break;
}
throw notFoundError(scopeChain, id);
}
}
if (asFunctionCall) {
if (!(result instanceof Function)) {
throw notFunctionError(result, id);
}
Scriptable thisObj = scope;
if (thisObj.getParentScope() != null) {
// Check for with and activation:
while (thisObj instanceof NativeWith) {
thisObj = thisObj.getPrototype();
}
if (thisObj instanceof NativeCall) {
thisObj = ScriptableObject.getTopLevelScope(thisObj);
}
}
storeScriptable(cx, thisObj);
}
return result;
}
/**
* Returns the object in the scope chain that has a given property.
@ -1693,11 +1719,10 @@ public class ScriptRuntime {
*/
public static Scriptable bind(Context cx, Scriptable scope, String id)
{
Scriptable obj = scope;
Scriptable firstXMLObject = null;
for (;;) {
if (obj instanceof NativeWith) {
Scriptable withObj = obj.getPrototype();
do {
if (scope instanceof NativeWith) {
Scriptable withObj = scope.getPrototype();
if (withObj instanceof XMLObject) {
XMLObject xmlObject = (XMLObject)withObj;
if (xmlObject.ecmaHas(cx, id)) {
@ -1712,25 +1737,19 @@ public class ScriptRuntime {
}
}
} else {
if (ScriptableObject.hasProperty(obj, id)) {
return obj;
if (ScriptableObject.hasProperty(scope, id)) {
return scope;
}
}
obj = obj.getParentScope();
if (obj == null) {
scope = scope.getParentScope();
} while (scope != null);
// Nothing was found
if (firstXMLObject != null) {
// XML objects always bind so return it if it was found
return firstXMLObject;
}
}
}
public static Scriptable getBase(Context cx, Scriptable scope, String id)
{
Scriptable base = bind(cx, scope, id);
if (base != null) {
return base;
}
throw notFoundError(scope, id);
return null;
}
public static Scriptable getThis(Scriptable base) {
@ -1742,7 +1761,7 @@ public class ScriptRuntime {
}
public static Object setName(Scriptable bound, Object value,
Context cx, String id)
Context cx, Scriptable scope, String id)
{
if (bound != null) {
if (bound instanceof XMLObject) {
@ -1756,7 +1775,7 @@ public class ScriptRuntime {
// been defined, creates a new property in the
// global object. Find the global object by
// walking up the scope chain.
bound = cx.topCallScope;
bound = ScriptableObject.getTopLevelScope(scope);
bound.put(id, bound, value);
/*
This code is causing immense performance problems in
@ -1769,7 +1788,6 @@ public class ScriptRuntime {
return value;
}
/**
* This is the enumeration needed by the for..in statement.
*
@ -1904,24 +1922,8 @@ public class ScriptRuntime {
Context cx,
Scriptable scope)
{
Object value = name(cx, scope, name);
if (!(value instanceof Function)) {
throw notFunctionError(value, name);
}
Scriptable thisObj = scope;
if (scope.getParentScope() != null) {
// Check for with and activation:
while (thisObj instanceof NativeWith) {
thisObj = thisObj.getPrototype();
}
if (thisObj instanceof NativeCall) {
thisObj = ScriptableObject.getTopLevelScope(thisObj);
}
}
storeScriptable(cx, thisObj);
return (Function)value;
// name will call storeScriptable(cx, thisObj);
return (Function)name(cx, scope, name, true);
}
/**

Просмотреть файл

@ -3473,12 +3473,14 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
child = child.getNext();
}
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
cfw.addPush(name);
addScriptRuntimeInvoke(
"setName",
"(Lorg/mozilla/javascript/Scriptable;"
+"Ljava/lang/Object;"
+"Lorg/mozilla/javascript/Context;"
+"Lorg/mozilla/javascript/Scriptable;"
+"Ljava/lang/String;"
+")Ljava/lang/Object;");
}