зеркало из https://github.com/mozilla/pjs.git
This commit is contained in:
Родитель
c496d0ae06
Коммит
f8bd7bf48c
|
@ -69,6 +69,11 @@ public class IdFunction extends BaseFunction
|
|||
ScriptableObject.defineProperty(scope, name, f, attributes);
|
||||
}
|
||||
|
||||
public final int getMethodId()
|
||||
{
|
||||
return methodId;
|
||||
}
|
||||
|
||||
public Scriptable getPrototype()
|
||||
{
|
||||
// Lazy initialization of prototype: for native functions this
|
||||
|
|
|
@ -420,6 +420,9 @@ public class Interpreter {
|
|||
if (callType != Node.NON_SPECIALCALL) {
|
||||
// embed line number and source filename
|
||||
iCodeTop = addByte(TokenStream.CALLSPECIAL, iCodeTop);
|
||||
iCodeTop = addByte(callType, iCodeTop);
|
||||
iCodeTop = addByte(type == TokenStream.NEW ? 1 : 0,
|
||||
iCodeTop);
|
||||
iCodeTop = addShort(itsLineNumber, iCodeTop);
|
||||
iCodeTop = addString(itsSourceFile, iCodeTop);
|
||||
} else {
|
||||
|
@ -1262,12 +1265,15 @@ public class Interpreter {
|
|||
break;
|
||||
}
|
||||
case TokenStream.CALLSPECIAL : {
|
||||
int line = getShort(iCode, pc);
|
||||
String name = strings[getIndex(iCode, pc + 2)];
|
||||
int count = getIndex(iCode, pc + 4);
|
||||
out.println(tname + " " + count
|
||||
+ " " + line + " " + name);
|
||||
pc += 6;
|
||||
int callType = iCode[pc] & 0xFF;
|
||||
boolean isNew = (iCode[pc + 1] != 0);
|
||||
int line = getShort(iCode, pc+2);
|
||||
String source = strings[getIndex(iCode, pc + 4)];
|
||||
int count = getIndex(iCode, pc + 6);
|
||||
out.println(tname + " " + callType + " " + isNew
|
||||
+ " " + count
|
||||
+ " " + line + " " + source);
|
||||
pc += 8;
|
||||
break;
|
||||
}
|
||||
case TokenStream.REGEXP : {
|
||||
|
@ -1431,10 +1437,12 @@ public class Interpreter {
|
|||
return 1 + 1;
|
||||
|
||||
case TokenStream.CALLSPECIAL :
|
||||
// call type
|
||||
// is new
|
||||
// line number
|
||||
// name string index
|
||||
// arg count
|
||||
return 1 + 2 + 2 + 2;
|
||||
return 1 + 1 + 1 + 2 + 2 + 2;
|
||||
|
||||
case TokenStream.REGEXP :
|
||||
// regexp index
|
||||
|
@ -2106,20 +2114,30 @@ public class Interpreter {
|
|||
cx.instructionCount = instructionCount;
|
||||
instructionCount = -1;
|
||||
}
|
||||
int lineNum = getShort(iCode, pc + 1);
|
||||
String name = strings[getIndex(iCode, pc + 3)];
|
||||
int count = getIndex(iCode, pc + 5);
|
||||
int callType = iCode[pc + 1] & 0xFF;
|
||||
boolean isNew = (iCode[pc + 2] != 0);
|
||||
int sourceLine = getShort(iCode, pc + 3);
|
||||
String sourceName = strings[getIndex(iCode, pc + 5)];
|
||||
int count = getIndex(iCode, pc + 7);
|
||||
stackTop -= count;
|
||||
Object[] outArgs = getArgsArray(stack, sDbl, stackTop + 1, count);
|
||||
Object rhs = stack[stackTop];
|
||||
if (rhs == DBL_MRK) rhs = doubleWrap(sDbl[stackTop]);
|
||||
--stackTop;
|
||||
Object lhs = stack[stackTop];
|
||||
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
|
||||
Object functionThis;
|
||||
if (isNew) {
|
||||
functionThis = null;
|
||||
} else {
|
||||
functionThis = stack[stackTop];
|
||||
if (functionThis == DBL_MRK) {
|
||||
functionThis = doubleWrap(sDbl[stackTop]);
|
||||
}
|
||||
--stackTop;
|
||||
}
|
||||
Object function = stack[stackTop];
|
||||
if (function == DBL_MRK) function = doubleWrap(sDbl[stackTop]);
|
||||
stack[stackTop] = ScriptRuntime.callSpecial(
|
||||
cx, lhs, rhs, outArgs,
|
||||
thisObj, scope, name, lineNum);
|
||||
pc += 6;
|
||||
cx, function, isNew, functionThis, outArgs,
|
||||
scope, thisObj, callType,
|
||||
sourceName, sourceLine);
|
||||
pc += 8;
|
||||
instructionCount = cx.instructionCount;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -468,6 +468,19 @@ public class NativeGlobal implements Serializable, IdFunctionMaster
|
|||
throw NativeGlobal.constructError(cx, "EvalError", m, scope);
|
||||
}
|
||||
|
||||
static boolean isEvalFunction(Object functionObj)
|
||||
{
|
||||
if (functionObj instanceof IdFunction) {
|
||||
IdFunction function = (IdFunction)functionObj;
|
||||
if (function.master instanceof NativeGlobal
|
||||
&& function.getMethodId() == Id_eval)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The eval function property of the global object.
|
||||
*
|
||||
|
|
|
@ -165,16 +165,23 @@ public final class NativeWith implements Scriptable, IdFunctionMaster {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public static Object newWithSpecial(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
static boolean isWithFunction(Object functionObj)
|
||||
{
|
||||
if (!inNewExpr) {
|
||||
throw Context.reportRuntimeError1("msg.only.from.new", "With");
|
||||
if (functionObj instanceof IdFunction) {
|
||||
IdFunction function = (IdFunction)functionObj;
|
||||
if (function.master instanceof NativeWith
|
||||
&& function.getMethodId() == Id_constructor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Object newWithSpecial(Context cx, Scriptable scope, Object[] args)
|
||||
{
|
||||
ScriptRuntime.checkDeprecated(cx, "With");
|
||||
|
||||
Scriptable scope = ScriptableObject.getTopLevelScope(ctorObj);
|
||||
scope = ScriptableObject.getTopLevelScope(scope);
|
||||
NativeWith thisObj = new NativeWith();
|
||||
thisObj.setPrototype(args.length == 0
|
||||
? ScriptableObject.getClassPrototype(scope,
|
||||
|
|
|
@ -87,8 +87,6 @@ public class ScriptRuntime {
|
|||
public final static Class
|
||||
ContextClass = classOrNull("org.mozilla.javascript.Context"),
|
||||
FunctionClass = classOrNull("org.mozilla.javascript.Function"),
|
||||
NativeGlobalClass = classOrNull("org.mozilla.javascript.NativeGlobal"),
|
||||
NativeWithClass = classOrNull("org.mozilla.javascript.NativeWith"),
|
||||
ScriptableClass = classOrNull("org.mozilla.javascript.Scriptable"),
|
||||
ScriptableObjectClass = classOrNull(
|
||||
"org.mozilla.javascript.ScriptableObject"),
|
||||
|
@ -1188,49 +1186,6 @@ public class ScriptRuntime {
|
|||
return function.call(cx, scope, thisObj, args);
|
||||
}
|
||||
|
||||
private static Object callOrNewSpecial(Context cx, Scriptable scope,
|
||||
Object fun, Object jsThis,
|
||||
Object thisArg,
|
||||
Object[] args, boolean isCall,
|
||||
String filename, int lineNumber)
|
||||
throws JavaScriptException
|
||||
{
|
||||
if (fun instanceof IdFunction) {
|
||||
IdFunction f = (IdFunction)fun;
|
||||
String name = f.getFunctionName();
|
||||
if (name.length() == 4) {
|
||||
if (name.equals("eval")) {
|
||||
if (f.master.getClass() == NativeGlobalClass) {
|
||||
return NativeGlobal.evalSpecial(cx, scope,
|
||||
thisArg, args,
|
||||
filename, lineNumber);
|
||||
}
|
||||
}
|
||||
else if (name.equals("With")) {
|
||||
if (f.master.getClass() == NativeWithClass) {
|
||||
return NativeWith.newWithSpecial(cx, args, f, !isCall);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isCall)
|
||||
return call(cx, fun, jsThis, args, scope);
|
||||
return newObject(cx, fun, args, scope);
|
||||
}
|
||||
|
||||
public static Object callSpecial(Context cx, Object fun,
|
||||
Object thisArg, Object[] args,
|
||||
Scriptable enclosingThisArg,
|
||||
Scriptable scope, String filename,
|
||||
int lineNumber)
|
||||
throws JavaScriptException
|
||||
{
|
||||
return callOrNewSpecial(cx, scope, fun, thisArg,
|
||||
enclosingThisArg, args, true,
|
||||
filename, lineNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Operator new.
|
||||
*
|
||||
|
@ -1248,12 +1203,40 @@ public class ScriptRuntime {
|
|||
return function.construct(cx, scope, args);
|
||||
}
|
||||
|
||||
public static Scriptable newObjectSpecial(Context cx, Object fun,
|
||||
Object[] args, Scriptable scope)
|
||||
public static Object callSpecial(Context cx, Object fun,
|
||||
boolean isNew, Object thisObj,
|
||||
Object[] args, Scriptable scope,
|
||||
Scriptable callerThis, int callType,
|
||||
String filename, int lineNumber)
|
||||
throws JavaScriptException
|
||||
{
|
||||
return (Scriptable) callOrNewSpecial(cx, scope, fun, null, null, args,
|
||||
false, null, -1);
|
||||
if (callType == Node.SPECIALCALL_EVAL) {
|
||||
if (NativeGlobal.isEvalFunction(fun)) {
|
||||
if (isNew) {
|
||||
throw NativeGlobal.typeError1("msg.not.ctor",
|
||||
"eval", scope);
|
||||
}
|
||||
return NativeGlobal.evalSpecial(cx, scope,
|
||||
callerThis, args,
|
||||
filename, lineNumber);
|
||||
}
|
||||
} else if (callType == Node.SPECIALCALL_WITH) {
|
||||
if (NativeWith.isWithFunction(fun)) {
|
||||
if (!isNew) {
|
||||
throw Context.reportRuntimeError1("msg.only.from.new",
|
||||
"With");
|
||||
}
|
||||
return NativeWith.newWithSpecial(cx, scope, args);
|
||||
}
|
||||
} else {
|
||||
Context.codeBug();
|
||||
}
|
||||
|
||||
if (isNew) {
|
||||
return newObject(cx, fun, args, scope);
|
||||
} else {
|
||||
return call(cx, fun, thisObj, args, scope);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1891,9 +1891,8 @@ public class Codegen extends Interpreter {
|
|||
int callType = node.getIntProp(Node.SPECIALCALL_PROP,
|
||||
Node.NON_SPECIALCALL);
|
||||
boolean isSimpleCall = false;
|
||||
String simpleCallName = null;
|
||||
if (!firstArgDone && type != TokenStream.NEW) {
|
||||
simpleCallName = getSimpleCallName(node);
|
||||
String simpleCallName = getSimpleCallName(node);
|
||||
if (simpleCallName != null && callType == Node.NON_SPECIALCALL) {
|
||||
isSimpleCall = true;
|
||||
push(simpleCallName);
|
||||
|
@ -1957,15 +1956,19 @@ public class Codegen extends Interpreter {
|
|||
String callSignature;
|
||||
|
||||
if (callType != Node.NON_SPECIALCALL) {
|
||||
className = "org/mozilla/javascript/ScriptRuntime";
|
||||
className = "org/mozilla/javascript/optimizer/OptRuntime";
|
||||
if (type == TokenStream.NEW) {
|
||||
methodName = "newObjectSpecial";
|
||||
callSignature = "(Lorg/mozilla/javascript/Context;"
|
||||
+"Ljava/lang/Object;"
|
||||
+"[Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+")Lorg/mozilla/javascript/Scriptable;";
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"I" // call type
|
||||
+")Ljava/lang/Object;";
|
||||
aload(variableObjectLocal);
|
||||
aload(thisObjLocal);
|
||||
push(callType);
|
||||
} else {
|
||||
methodName = "callSpecial";
|
||||
callSignature = "(Lorg/mozilla/javascript/Context;"
|
||||
|
@ -1974,10 +1977,12 @@ public class Codegen extends Interpreter {
|
|||
+"[Ljava/lang/Object;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"Lorg/mozilla/javascript/Scriptable;"
|
||||
+"I" // call type
|
||||
+"Ljava/lang/String;I" // filename, linenumber
|
||||
+")Ljava/lang/Object;";
|
||||
aload(thisObjLocal);
|
||||
aload(variableObjectLocal);
|
||||
aload(thisObjLocal);
|
||||
push(callType);
|
||||
push(itsSourceFile == null ? "" : itsSourceFile);
|
||||
push(itsLineNumber);
|
||||
}
|
||||
|
|
|
@ -306,4 +306,27 @@ public final class OptRuntime extends ScriptRuntime {
|
|||
{
|
||||
ScriptRuntime.initFunction(cx, scope, fn, functionType, false);
|
||||
}
|
||||
|
||||
public static Object callSpecial(Context cx, Object fun,
|
||||
Object thisObj, Object[] args,
|
||||
Scriptable scope,
|
||||
Scriptable callerThis, int callType,
|
||||
String fileName, int lineNumber)
|
||||
throws JavaScriptException
|
||||
{
|
||||
return ScriptRuntime.callSpecial(cx, fun, false, thisObj, args, scope,
|
||||
callerThis, callType,
|
||||
fileName, lineNumber);
|
||||
}
|
||||
|
||||
public static Object newObjectSpecial(Context cx, Object fun,
|
||||
Object[] args, Scriptable scope,
|
||||
Scriptable callerThis, int callType)
|
||||
throws JavaScriptException
|
||||
{
|
||||
return ScriptRuntime.callSpecial(cx, fun, true, null, args, scope,
|
||||
callerThis, callType,
|
||||
"", -1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче