Fixing bug 256317: report about invalid references during parsing, not runtime.

This commit is contained in:
igor%mir2.org 2004-08-20 17:43:24 +00:00
Родитель e908f13c42
Коммит a60c5d3cb3
6 изменённых файлов: 121 добавлений и 117 удалений

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

@ -1016,6 +1016,18 @@ final class IRFactory
Node createIncDec(int nodeType, boolean post, Node child) Node createIncDec(int nodeType, boolean post, Node child)
{ {
child = makeReference(child);
if (child == null) {
String msg;
if (nodeType == Token.DEC) {
msg = "msg.bad.decr";
} else {
msg = "msg.bad.incr";
}
parser.reportError(msg);
return null;
}
int childType = child.getType(); int childType = child.getType();
switch (childType) { switch (childType) {
@ -1035,19 +1047,7 @@ final class IRFactory
return n; return n;
} }
} }
return createIncDec(nodeType, post, makeReferenceGet(child)); throw Kit.codeBug();
}
private Node makeReferenceGet(Node node)
{
Node ref;
if (node.getType() == Token.CALL) {
node.setType(Token.REF_CALL);
ref = node;
} else {
ref = new Node(Token.GENERIC_REF, node);
}
return new Node(Token.GET_REF, ref);
} }
/** /**
@ -1227,6 +1227,12 @@ final class IRFactory
Node createAssignment(Node left, Node right) Node createAssignment(Node left, Node right)
{ {
left = makeReference(left);
if (left == null) {
parser.reportError("msg.bad.assign.left");
return null;
}
int nodeType = left.getType(); int nodeType = left.getType();
switch (nodeType) { switch (nodeType) {
case Token.NAME: case Token.NAME:
@ -1250,11 +1256,18 @@ final class IRFactory
return new Node(Token.SET_REF, ref, right); return new Node(Token.SET_REF, ref, right);
} }
} }
return createAssignment(makeReferenceGet(left), right);
throw Kit.codeBug();
} }
Node createAssignmentOp(int assignOp, Node left, Node right) Node createAssignmentOp(int assignOp, Node left, Node right)
{ {
left = makeReference(left);
if (left == null) {
parser.reportError("msg.bad.assign.left");
return null;
}
int nodeType = left.getType(); int nodeType = left.getType();
switch (nodeType) { switch (nodeType) {
case Token.NAME: { case Token.NAME: {
@ -1285,7 +1298,8 @@ final class IRFactory
return new Node(Token.SET_REF_OP, ref, op); return new Node(Token.SET_REF_OP, ref, op);
} }
} }
return createAssignmentOp(assignOp, makeReferenceGet(left), right);
throw Kit.codeBug();
} }
Node createUseLocal(Node localBlock) Node createUseLocal(Node localBlock)
@ -1296,6 +1310,23 @@ final class IRFactory
return result; return result;
} }
private Node makeReference(Node node)
{
int type = node.getType();
switch (type) {
case Token.NAME:
case Token.GETPROP:
case Token.GETELEM:
case Token.GET_REF:
return node;
case Token.CALL:
node.setType(Token.REF_CALL);
return new Node(Token.GET_REF, node);
}
// Signal caller to report error
return null;
}
// Check if Node always mean true or false in boolean context // Check if Node always mean true or false in boolean context
private static int isAlwaysDefinedBoolean(Node node) private static int isAlwaysDefinedBoolean(Node node)
{ {

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

@ -972,7 +972,6 @@ public class Interpreter
} }
case Token.XML_REF: case Token.XML_REF:
case Token.GENERIC_REF:
visitExpression(child); visitExpression(child);
addToken(type); addToken(type);
break; break;
@ -2839,12 +2838,6 @@ switch (op) {
stack[stackTop] = ScriptRuntime.xmlReference(lhs, cx, scope); stack[stackTop] = ScriptRuntime.xmlReference(lhs, cx, scope);
continue Loop; continue Loop;
} }
case Token.GENERIC_REF : {
Object lhs = stack[stackTop];
if (lhs == DBL_MRK) lhs = doubleWrap(sDbl[stackTop]);
stack[stackTop] = ScriptRuntime.genericReference(lhs, cx, scope);
continue Loop;
}
case Icode_SCOPE : case Icode_SCOPE :
stack[++stackTop] = scope; stack[++stackTop] = scope;
continue Loop; continue Loop;

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

@ -1616,13 +1616,6 @@ public class ScriptRuntime {
}; };
} }
public static Object genericReference(Object obj,
Context cx, Scriptable scope)
{
String msg = getMessage1("msg.not.ref", toString(obj));
throw constructError("ReferenceError", msg);
}
/** /**
* The delete operator * The delete operator
* *

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

@ -142,87 +142,86 @@ public class Token
DEL_REF = 67, // delete reference DEL_REF = 67, // delete reference
REF_CALL = 68, // f(args) = something or f(args)++ REF_CALL = 68, // f(args) = something or f(args)++
SPECIAL_REF = 69, // reference for special properties like __proto SPECIAL_REF = 69, // reference for special properties like __proto
GENERIC_REF = 70, // generic reference to generate runtime ref errors
// For XML support: // For XML support:
DEFAULTNAMESPACE = 71, // default xml namespace = DEFAULTNAMESPACE = 70, // default xml namespace =
COLONCOLON = 72, // :: COLONCOLON = 71, // ::
ESCXMLATTR = 73, ESCXMLATTR = 72,
ESCXMLTEXT = 74, ESCXMLTEXT = 73,
TOATTRNAME = 75, TOATTRNAME = 74,
DESCENDANTS = 76, DESCENDANTS = 75,
XML_REF = 77, XML_REF = 76,
LAST_BYTECODE_TOKEN = 77, LAST_BYTECODE_TOKEN = 76,
// End of interpreter bytecodes // End of interpreter bytecodes
TRY = 78, TRY = 77,
SEMI = 79, // semicolon SEMI = 78, // semicolon
LB = 80, // left and right brackets LB = 79, // left and right brackets
RB = 81, RB = 80,
LC = 82, // left and right curlies (braces) LC = 81, // left and right curlies (braces)
RC = 83, RC = 82,
LP = 84, // left and right parentheses LP = 83, // left and right parentheses
RP = 85, RP = 84,
COMMA = 86, // comma operator COMMA = 85, // comma operator
ASSIGN = 87, // simple assignment (=) ASSIGN = 86, // simple assignment (=)
ASSIGNOP = 88, // assignment with operation (+= -= etc.) ASSIGNOP = 87, // assignment with operation (+= -= etc.)
HOOK = 89, // conditional (?:) HOOK = 88, // conditional (?:)
COLON = 90, COLON = 89,
OR = 91, // logical or (||) OR = 90, // logical or (||)
AND = 92, // logical and (&&) AND = 91, // logical and (&&)
INC = 93, // increment/decrement (++ --) INC = 92, // increment/decrement (++ --)
DEC = 94, DEC = 93,
DOT = 95, // member operator (.) DOT = 94, // member operator (.)
FUNCTION = 96, // function keyword FUNCTION = 95, // function keyword
EXPORT = 97, // export keyword EXPORT = 96, // export keyword
IMPORT = 98, // import keyword IMPORT = 97, // import keyword
IF = 99, // if keyword IF = 98, // if keyword
ELSE = 100, // else keyword ELSE = 99, // else keyword
SWITCH = 101, // switch keyword SWITCH = 100, // switch keyword
CASE = 102, // case keyword CASE = 101, // case keyword
DEFAULT = 103, // default keyword DEFAULT = 102, // default keyword
WHILE = 104, // while keyword WHILE = 103, // while keyword
DO = 105, // do keyword DO = 104, // do keyword
FOR = 106, // for keyword FOR = 105, // for keyword
BREAK = 107, // break keyword BREAK = 106, // break keyword
CONTINUE = 108, // continue keyword CONTINUE = 107, // continue keyword
VAR = 109, // var keyword VAR = 108, // var keyword
WITH = 110, // with keyword WITH = 109, // with keyword
CATCH = 111, // catch keyword CATCH = 110, // catch keyword
FINALLY = 112, // finally keyword FINALLY = 111, // finally keyword
VOID = 113, // void keyword VOID = 112, // void keyword
RESERVED = 114, // reserved keywords RESERVED = 113, // reserved keywords
EMPTY = 115, EMPTY = 114,
/* types used for the parse tree - these never get returned /* types used for the parse tree - these never get returned
* by the scanner. * by the scanner.
*/ */
BLOCK = 116, // statement block BLOCK = 115, // statement block
LABEL = 117, // label LABEL = 116, // label
TARGET = 118, TARGET = 117,
LOOP = 119, LOOP = 118,
EXPR_VOID = 120, // expression statement in functions EXPR_VOID = 119, // expression statement in functions
EXPR_RESULT = 121, // expression statement in scripts EXPR_RESULT = 120, // expression statement in scripts
JSR = 122, JSR = 121,
SCRIPT = 123, // top-level node for entire script SCRIPT = 122, // top-level node for entire script
TYPEOFNAME = 124, // for typeof(simple-name) TYPEOFNAME = 123, // for typeof(simple-name)
USE_STACK = 125, USE_STACK = 124,
SETPROP_OP = 126, // x.y op= something SETPROP_OP = 125, // x.y op= something
SETELEM_OP = 127, // x[y] op= something SETELEM_OP = 126, // x[y] op= something
LOCAL_BLOCK = 128, LOCAL_BLOCK = 127,
SET_REF_OP = 129, // *reference op= something SET_REF_OP = 128, // *reference op= something
// For XML support: // For XML support:
DOTDOT = 130, // member operator (..) DOTDOT = 129, // member operator (..)
XML = 131, // XML type XML = 130, // XML type
DOTQUERY = 132, // .() -- e.g., x.emps.emp.(name == "terry") DOTQUERY = 131, // .() -- e.g., x.emps.emp.(name == "terry")
XMLATTR = 133, // @ XMLATTR = 132, // @
XMLEND = 134, XMLEND = 133,
LAST_TOKEN = 134; LAST_TOKEN = 133;
public static String name(int token) public static String name(int token)
{ {
@ -306,7 +305,6 @@ public class Token
case DEL_REF: return "DEL_REF"; case DEL_REF: return "DEL_REF";
case REF_CALL: return "REF_CALL"; case REF_CALL: return "REF_CALL";
case SPECIAL_REF: return "SPECIAL_REF"; case SPECIAL_REF: return "SPECIAL_REF";
case GENERIC_REF: return "GENERIC_REF";
case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE"; case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
case COLONCOLON: return "COLONCOLON"; case COLONCOLON: return "COLONCOLON";
case ESCXMLTEXT: return "ESCXMLTEXT"; case ESCXMLTEXT: return "ESCXMLTEXT";

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

@ -1952,10 +1952,6 @@ class BodyCodegen
visitXMLRef(node, child); visitXMLRef(node, child);
break; break;
case Token.GENERIC_REF:
visitGenericRef(node, child);
break;
case Token.DOTQUERY: case Token.DOTQUERY:
visitDotQuery(node, child); visitDotQuery(node, child);
break; break;
@ -3815,18 +3811,6 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
+")Ljava/lang/Object;"); +")Ljava/lang/Object;");
} }
private void visitGenericRef(Node node, Node child)
{
generateExpression(child, node);
cfw.addALoad(contextLocal);
cfw.addALoad(variableObjectLocal);
addScriptRuntimeInvoke("genericReference",
"(Ljava/lang/Object;"
+"Lorg/mozilla/javascript/Context;"
+"Lorg/mozilla/javascript/Scriptable;"
+")Ljava/lang/Object;");
}
private void visitDotQuery(Node node, Node child) private void visitDotQuery(Node node, Node child)
{ {
updateLineNumber(node); updateLineNumber(node);

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

@ -112,6 +112,15 @@ msg.mult.index =\
msg.cant.convert =\ msg.cant.convert =\
Can''t convert to type "{0}". Can''t convert to type "{0}".
msg.bad.assign.left =\
Invalid assignment left-hand side.
msg.bad.decr =\
Invalid decerement operand.
msg.bad.incr =\
Invalid increment operand.
# NativeGlobal # NativeGlobal
msg.cant.call.indirect =\ msg.cant.call.indirect =\
Function "{0}" must be called directly, and not by way of a \ Function "{0}" must be called directly, and not by way of a \
@ -442,10 +451,6 @@ msg.no.ref.from.function =\
Function {0} can not be used as the left-hand side of assignment \ Function {0} can not be used as the left-hand side of assignment \
or as an operand of ++ or -- operator. or as an operand of ++ or -- operator.
msg.not.ref =\
{0} can not be used as the left-hand side of assignment \
or as an operand of ++ or -- operator.
msg.bad.default.value =\ msg.bad.default.value =\
Object''s getDefaultValue() method returned an object. Object''s getDefaultValue() method returned an object.