igor%mir2.org 2003-05-06 18:53:16 +00:00
Родитель c496d0ae06
Коммит f8bd7bf48c
7 изменённых файлов: 132 добавлений и 78 удалений

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

@ -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);
}
}