Skip to content

Commit

Permalink
- support special GetValue and PutValue on primitives in call express…
Browse files Browse the repository at this point in the history
…ions

- handle primitive thisObject in NativeString, NativeBoolean and NativeNumber functions
  • Loading branch information
anba committed Mar 21, 2012
1 parent 7026596 commit f5329f6
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 98 deletions.
2 changes: 1 addition & 1 deletion src/org/mozilla/javascript/Context.java
Expand Up @@ -2665,7 +2665,7 @@ public void removeActivationName(String name)
long scratchUint32;

// It can be used to return the second Scriptable result from function
Scriptable scratchScriptable;
Object scratchThis;

// Generate an observer count on compiled code
public boolean generateObserverCount = false;
Expand Down
17 changes: 11 additions & 6 deletions src/org/mozilla/javascript/Interpreter.java
Expand Up @@ -1540,7 +1540,7 @@ private static Object interpretLoop(Context cx, CallFrame frame,
stack[stackTop] = ScriptRuntime.getNameObjectAndThis(stringReg,
cx, frame.scope);
++stackTop;
Scriptable thisObj = ScriptRuntime.lastStoredScriptable(cx);
Object thisObj = ScriptRuntime.lastStoredThis(cx);
stack[stackTop] = (thisObj != null ? thisObj : Undefined.instance);
continue Loop;
}
Expand All @@ -1551,25 +1551,30 @@ private static Object interpretLoop(Context cx, CallFrame frame,
stack[stackTop] = ScriptRuntime.getPropObjectAndThis(obj, stringReg,
cx, frame.scope);
++stackTop;
stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
// ignore stored this
ScriptRuntime.lastStoredThis(cx);
stack[stackTop] = obj;
continue Loop;
}
case Icode_ELEM_AND_THIS: {
Object obj = stack[stackTop - 1];
if (obj == DBL_MRK) obj = ScriptRuntime.wrapNumber(sDbl[stackTop - 1]);
Object id = stack[stackTop];
if (id == DBL_MRK) id = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop - 1] = ScriptRuntime.getElemObjectAndThis(obj, id, cx);
stack[stackTop] = ScriptRuntime.lastStoredScriptable(cx);
stack[stackTop - 1] = ScriptRuntime.getElemObjectAndThis(obj, id, cx,
frame.scope);
// ignore stored this
ScriptRuntime.lastStoredThis(cx);
stack[stackTop] = obj;
continue Loop;
}
case Icode_VALUE_AND_THIS : {
Object value = stack[stackTop];
if (value == DBL_MRK) value = ScriptRuntime.wrapNumber(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.getValueObjectAndThis(value, cx);
++stackTop;
// ignore stored scriptable
ScriptRuntime.lastStoredScriptable(cx);
// ignore stored this
ScriptRuntime.lastStoredThis(cx);
stack[stackTop] = Undefined.instance;
continue Loop;
}
Expand Down
9 changes: 7 additions & 2 deletions src/org/mozilla/javascript/NativeBoolean.java
Expand Up @@ -121,9 +121,14 @@ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,

// The rest of Boolean.prototype methods require thisObj to be Boolean

if (!(thisObj instanceof NativeBoolean))
boolean value;
if (thisObj instanceof Boolean) {
value = ((Boolean)thisObj).booleanValue();
} else if (thisObj instanceof NativeBoolean) {
value = ((NativeBoolean)thisObj).booleanValue;
} else {
throw incompatibleCallError(f);
boolean value = ((NativeBoolean)thisObj).booleanValue;
}

switch (id) {

Expand Down
9 changes: 7 additions & 2 deletions src/org/mozilla/javascript/NativeNumber.java
Expand Up @@ -136,9 +136,14 @@ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,

// The rest of Number.prototype methods require thisObj to be Number

if (!(thisObj instanceof NativeNumber))
double value;
if (thisObj instanceof Number) {
value = ((Number)thisObj).doubleValue();
} else if (thisObj instanceof NativeNumber) {
value = ((NativeNumber)thisObj).doubleValue;
} else {
throw incompatibleCallError(f);
double value = ((NativeNumber)thisObj).doubleValue;
}

switch (id) {

Expand Down
15 changes: 9 additions & 6 deletions src/org/mozilla/javascript/NativeString.java
Expand Up @@ -272,11 +272,11 @@ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
case Id_toString:
case Id_valueOf:
// ECMA 15.5.4.2: 'the toString function is not generic.
CharSequence cs = realThis(thisObj, f).string;
CharSequence cs = realThis(thisObj, f);
return cs instanceof String ? cs : cs.toString();

case Id_toSource: {
CharSequence s = realThis(thisObj, f).string;
CharSequence s = realThis(thisObj, f);
return "(new String(\""+ScriptRuntime.escapeString(s.toString())+"\"))";
}

Expand Down Expand Up @@ -452,11 +452,14 @@ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
}
}

private static NativeString realThis(Object thisObj, IdFunctionObject f)
private static CharSequence realThis(Object thisObj, IdFunctionObject f)
{
if (!(thisObj instanceof NativeString))
throw incompatibleCallError(f);
return (NativeString)thisObj;
if (thisObj instanceof CharSequence) {
return (CharSequence)thisObj;
} else if (thisObj instanceof NativeString) {
return ((NativeString)thisObj).string;
}
throw incompatibleCallError(f);
}

/*
Expand Down

0 comments on commit f5329f6

Please sign in to comment.