Closed Bug 153497 Opened 23 years ago Closed 23 years ago

Problem comparing String to NativeString

Categories

(Rhino Graveyard :: Core, defect)

x86
Windows NT
defect
Not set
normal

Tracking

(Not tracked)

VERIFIED INVALID

People

(Reporter: lwerner, Assigned: norrisboyd)

Details

In Rhino 1.5r3, I ran across a problem evaluating a simple comparison expression "a != b" where a's implementation is a NativeString object and b's is a plain old java.lang.String. When ScriptRuntime.eq is called to do the comparison, it calls toPrimitive() on the NativeString, which calls getDefaultValue(null) on it. This resolves to the ScriptableObject version of getDefaultValue. This first tries getting the valueOf property and calling it as a function. If that doesn't work, it tries to get the toString properties and call it as a function. Unfortunately, NativeString doesn't expose either of these as true Function properties, so the code in ScriptableObject.getDefaultValue doesn't know what to do with the return value and ends up throwing an exception. My temporary fix was to change NativeString so that it exposes valueOf and toString as properties rather than as prototypes. I'm not entirely sure that this is the optimal fix because I don't fully understand how IdScriptable works, but this fix got me going again. The same thing may also need to be done to the other "Native" classes. Here are the diffs for what I did. I'd be interested in feedback on whether this is the right approach. diff -r1.1.1.1 NativeString.java 267a268,275 > } else { > switch (methodId) { > case Id_toString: > return realThis(thisObj, f).jsFunction_toString(); > > case Id_valueOf: > return realThis(thisObj, f).jsFunction_valueOf(); > } 830c838,840 < MAX_INSTANCE_ID = 1; --- > Id_toString = 2, > Id_valueOf = 3, > MAX_INSTANCE_ID = 3; 834c844,846 < if (s.equals("length")) { return Id_length; } --- > if (s.equals("length")) { return Id_length; } > else if (s.equals("valueOf")) { return Id_valueOf; } > else if (s.equals("toString")) { return Id_toString; } 908,909c920,921 < Id_toString = MAX_INSTANCE_ID + 2, < Id_valueOf = MAX_INSTANCE_ID + 3, --- > // Id_toString = MAX_INSTANCE_ID + 2, > // Id_valueOf = MAX_INSTANCE_ID + 3,
I don't understand: the following String and NativeString comparison appears to do the right thing: [rhino] java -jar build/rhino1_5R4pre/js.jar Rhino 1.5 release 4 0000 00 00 (in progress) js> (new String('hi')) != 'hi' false
Hmm. In the case where I ran across this, I have the Rhino interpreter embedded in another program. A Java object that's pretending to be a JavaScript one (via NativeJavaObject) returns a NativeString. Later this gets compared to a string literal, ala myJavaObject.functionThatReturnsNativeString() != 'foo' and I get an an exception stack trace like this: java.lang.RuntimeException: org.mozilla.javascript.PropertyException: Constructor for "TypeError" not found. at org.mozilla.javascript.NativeGlobal.constructError (NativeGlobal.java:585) at org.mozilla.javascript.NativeGlobal.constructError (NativeGlobal.java:541) at org.mozilla.javascript.NativeGlobal.typeError1(NativeGlobal.java:551) at org.mozilla.javascript.ScriptableObject.getDefaultValue (ScriptableObject.java:619) at org.mozilla.javascript.ScriptRuntime.toPrimitive (ScriptRuntime.java:1540) at org.mozilla.javascript.ScriptRuntime.eq(ScriptRuntime.java:1633) at org.mozilla.javascript.Interpreter.do_eq(Interpreter.java:2397) at org.mozilla.javascript.Interpreter.interpret(Interpreter.java:1577) at org.mozilla.javascript.InterpretedScript.call (InterpretedScript.java:68) at org.mozilla.javascript.InterpretedScript.exec (InterpretedScript.java:59) at org.mozilla.javascript.Context.evaluateReader(Context.java:785) at org.mozilla.javascript.Context.evaluateString(Context.java:749) at bevocal.vxml.ScopeActivation.evalExpr(ScopeActivation.java:793) at bevocal.vxml.ScopeActivation.evalExpr(ScopeActivation.java:784) at bevocal.vxml.ScopeActivation.evalBoolean(ScopeActivation.java:826) at bevocal.vxml.VXMLIf.execute(VXMLIf.java:29) The stuff at the bottom is mine, and at the top it's trying to construct a TypeError object for some reason I don't understand. But in between you can see that it's calling ScriptableObject.getDefaultValue() on the NativeString and failing. I'll try to put together a standalone test case for this in the next couple of days.
A possible reason for this behavior is that the application did not initialize NativeString prototype properly to point to String.prototype, where valueOf is defined. In any case, applications should not use NativeString as it is an internal class which was public for implementation reasons and it is already made package private in Rhino CVS. I suggest to resolve the bug as invalid.
OK, I'm going to mark this as invalid, then. Laura, please reopen the bug if you disagree -
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → INVALID
Marking Verified -
Status: RESOLVED → VERIFIED
Targeting as resolved against 1.5R4
Target Milestone: --- → 1.5R4
You need to log in before you can comment on or make changes to this bug.