зеркало из https://github.com/mozilla/pjs.git
Fixing bug 256317: report about invalid references during parsing, not runtime.
This commit is contained in:
Родитель
e908f13c42
Коммит
a60c5d3cb3
|
@ -1016,6 +1016,18 @@ final class IRFactory
|
|||
|
||||
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();
|
||||
|
||||
switch (childType) {
|
||||
|
@ -1035,19 +1047,7 @@ final class IRFactory
|
|||
return n;
|
||||
}
|
||||
}
|
||||
return createIncDec(nodeType, post, makeReferenceGet(child));
|
||||
}
|
||||
|
||||
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);
|
||||
throw Kit.codeBug();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1227,6 +1227,12 @@ final class IRFactory
|
|||
|
||||
Node createAssignment(Node left, Node right)
|
||||
{
|
||||
left = makeReference(left);
|
||||
if (left == null) {
|
||||
parser.reportError("msg.bad.assign.left");
|
||||
return null;
|
||||
}
|
||||
|
||||
int nodeType = left.getType();
|
||||
switch (nodeType) {
|
||||
case Token.NAME:
|
||||
|
@ -1250,11 +1256,18 @@ final class IRFactory
|
|||
return new Node(Token.SET_REF, ref, right);
|
||||
}
|
||||
}
|
||||
return createAssignment(makeReferenceGet(left), right);
|
||||
|
||||
throw Kit.codeBug();
|
||||
}
|
||||
|
||||
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();
|
||||
switch (nodeType) {
|
||||
case Token.NAME: {
|
||||
|
@ -1285,7 +1298,8 @@ final class IRFactory
|
|||
return new Node(Token.SET_REF_OP, ref, op);
|
||||
}
|
||||
}
|
||||
return createAssignmentOp(assignOp, makeReferenceGet(left), right);
|
||||
|
||||
throw Kit.codeBug();
|
||||
}
|
||||
|
||||
Node createUseLocal(Node localBlock)
|
||||
|
@ -1296,6 +1310,23 @@ final class IRFactory
|
|||
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
|
||||
private static int isAlwaysDefinedBoolean(Node node)
|
||||
{
|
||||
|
|
|
@ -972,7 +972,6 @@ public class Interpreter
|
|||
}
|
||||
|
||||
case Token.XML_REF:
|
||||
case Token.GENERIC_REF:
|
||||
visitExpression(child);
|
||||
addToken(type);
|
||||
break;
|
||||
|
@ -2839,12 +2838,6 @@ switch (op) {
|
|||
stack[stackTop] = ScriptRuntime.xmlReference(lhs, cx, scope);
|
||||
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 :
|
||||
stack[++stackTop] = scope;
|
||||
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
|
||||
*
|
||||
|
|
|
@ -142,87 +142,86 @@ public class Token
|
|||
DEL_REF = 67, // delete reference
|
||||
REF_CALL = 68, // f(args) = something or f(args)++
|
||||
SPECIAL_REF = 69, // reference for special properties like __proto
|
||||
GENERIC_REF = 70, // generic reference to generate runtime ref errors
|
||||
|
||||
// For XML support:
|
||||
DEFAULTNAMESPACE = 71, // default xml namespace =
|
||||
COLONCOLON = 72, // ::
|
||||
ESCXMLATTR = 73,
|
||||
ESCXMLTEXT = 74,
|
||||
TOATTRNAME = 75,
|
||||
DESCENDANTS = 76,
|
||||
XML_REF = 77,
|
||||
DEFAULTNAMESPACE = 70, // default xml namespace =
|
||||
COLONCOLON = 71, // ::
|
||||
ESCXMLATTR = 72,
|
||||
ESCXMLTEXT = 73,
|
||||
TOATTRNAME = 74,
|
||||
DESCENDANTS = 75,
|
||||
XML_REF = 76,
|
||||
|
||||
LAST_BYTECODE_TOKEN = 77,
|
||||
LAST_BYTECODE_TOKEN = 76,
|
||||
// End of interpreter bytecodes
|
||||
|
||||
TRY = 78,
|
||||
SEMI = 79, // semicolon
|
||||
LB = 80, // left and right brackets
|
||||
RB = 81,
|
||||
LC = 82, // left and right curlies (braces)
|
||||
RC = 83,
|
||||
LP = 84, // left and right parentheses
|
||||
RP = 85,
|
||||
COMMA = 86, // comma operator
|
||||
ASSIGN = 87, // simple assignment (=)
|
||||
ASSIGNOP = 88, // assignment with operation (+= -= etc.)
|
||||
HOOK = 89, // conditional (?:)
|
||||
COLON = 90,
|
||||
OR = 91, // logical or (||)
|
||||
AND = 92, // logical and (&&)
|
||||
INC = 93, // increment/decrement (++ --)
|
||||
DEC = 94,
|
||||
DOT = 95, // member operator (.)
|
||||
FUNCTION = 96, // function keyword
|
||||
EXPORT = 97, // export keyword
|
||||
IMPORT = 98, // import keyword
|
||||
IF = 99, // if keyword
|
||||
ELSE = 100, // else keyword
|
||||
SWITCH = 101, // switch keyword
|
||||
CASE = 102, // case keyword
|
||||
DEFAULT = 103, // default keyword
|
||||
WHILE = 104, // while keyword
|
||||
DO = 105, // do keyword
|
||||
FOR = 106, // for keyword
|
||||
BREAK = 107, // break keyword
|
||||
CONTINUE = 108, // continue keyword
|
||||
VAR = 109, // var keyword
|
||||
WITH = 110, // with keyword
|
||||
CATCH = 111, // catch keyword
|
||||
FINALLY = 112, // finally keyword
|
||||
VOID = 113, // void keyword
|
||||
RESERVED = 114, // reserved keywords
|
||||
TRY = 77,
|
||||
SEMI = 78, // semicolon
|
||||
LB = 79, // left and right brackets
|
||||
RB = 80,
|
||||
LC = 81, // left and right curlies (braces)
|
||||
RC = 82,
|
||||
LP = 83, // left and right parentheses
|
||||
RP = 84,
|
||||
COMMA = 85, // comma operator
|
||||
ASSIGN = 86, // simple assignment (=)
|
||||
ASSIGNOP = 87, // assignment with operation (+= -= etc.)
|
||||
HOOK = 88, // conditional (?:)
|
||||
COLON = 89,
|
||||
OR = 90, // logical or (||)
|
||||
AND = 91, // logical and (&&)
|
||||
INC = 92, // increment/decrement (++ --)
|
||||
DEC = 93,
|
||||
DOT = 94, // member operator (.)
|
||||
FUNCTION = 95, // function keyword
|
||||
EXPORT = 96, // export keyword
|
||||
IMPORT = 97, // import keyword
|
||||
IF = 98, // if keyword
|
||||
ELSE = 99, // else keyword
|
||||
SWITCH = 100, // switch keyword
|
||||
CASE = 101, // case keyword
|
||||
DEFAULT = 102, // default keyword
|
||||
WHILE = 103, // while keyword
|
||||
DO = 104, // do keyword
|
||||
FOR = 105, // for keyword
|
||||
BREAK = 106, // break keyword
|
||||
CONTINUE = 107, // continue keyword
|
||||
VAR = 108, // var keyword
|
||||
WITH = 109, // with keyword
|
||||
CATCH = 110, // catch keyword
|
||||
FINALLY = 111, // finally keyword
|
||||
VOID = 112, // void keyword
|
||||
RESERVED = 113, // reserved keywords
|
||||
|
||||
EMPTY = 115,
|
||||
EMPTY = 114,
|
||||
|
||||
/* types used for the parse tree - these never get returned
|
||||
* by the scanner.
|
||||
*/
|
||||
|
||||
BLOCK = 116, // statement block
|
||||
LABEL = 117, // label
|
||||
TARGET = 118,
|
||||
LOOP = 119,
|
||||
EXPR_VOID = 120, // expression statement in functions
|
||||
EXPR_RESULT = 121, // expression statement in scripts
|
||||
JSR = 122,
|
||||
SCRIPT = 123, // top-level node for entire script
|
||||
TYPEOFNAME = 124, // for typeof(simple-name)
|
||||
USE_STACK = 125,
|
||||
SETPROP_OP = 126, // x.y op= something
|
||||
SETELEM_OP = 127, // x[y] op= something
|
||||
LOCAL_BLOCK = 128,
|
||||
SET_REF_OP = 129, // *reference op= something
|
||||
BLOCK = 115, // statement block
|
||||
LABEL = 116, // label
|
||||
TARGET = 117,
|
||||
LOOP = 118,
|
||||
EXPR_VOID = 119, // expression statement in functions
|
||||
EXPR_RESULT = 120, // expression statement in scripts
|
||||
JSR = 121,
|
||||
SCRIPT = 122, // top-level node for entire script
|
||||
TYPEOFNAME = 123, // for typeof(simple-name)
|
||||
USE_STACK = 124,
|
||||
SETPROP_OP = 125, // x.y op= something
|
||||
SETELEM_OP = 126, // x[y] op= something
|
||||
LOCAL_BLOCK = 127,
|
||||
SET_REF_OP = 128, // *reference op= something
|
||||
|
||||
// For XML support:
|
||||
DOTDOT = 130, // member operator (..)
|
||||
XML = 131, // XML type
|
||||
DOTQUERY = 132, // .() -- e.g., x.emps.emp.(name == "terry")
|
||||
XMLATTR = 133, // @
|
||||
XMLEND = 134,
|
||||
DOTDOT = 129, // member operator (..)
|
||||
XML = 130, // XML type
|
||||
DOTQUERY = 131, // .() -- e.g., x.emps.emp.(name == "terry")
|
||||
XMLATTR = 132, // @
|
||||
XMLEND = 133,
|
||||
|
||||
LAST_TOKEN = 134;
|
||||
LAST_TOKEN = 133;
|
||||
|
||||
public static String name(int token)
|
||||
{
|
||||
|
@ -306,7 +305,6 @@ public class Token
|
|||
case DEL_REF: return "DEL_REF";
|
||||
case REF_CALL: return "REF_CALL";
|
||||
case SPECIAL_REF: return "SPECIAL_REF";
|
||||
case GENERIC_REF: return "GENERIC_REF";
|
||||
case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
|
||||
case COLONCOLON: return "COLONCOLON";
|
||||
case ESCXMLTEXT: return "ESCXMLTEXT";
|
||||
|
|
|
@ -1952,10 +1952,6 @@ class BodyCodegen
|
|||
visitXMLRef(node, child);
|
||||
break;
|
||||
|
||||
case Token.GENERIC_REF:
|
||||
visitGenericRef(node, child);
|
||||
break;
|
||||
|
||||
case Token.DOTQUERY:
|
||||
visitDotQuery(node, child);
|
||||
break;
|
||||
|
@ -3815,18 +3811,6 @@ Else pass the JS object in the aReg and 0.0 in the dReg.
|
|||
+")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)
|
||||
{
|
||||
updateLineNumber(node);
|
||||
|
|
|
@ -112,6 +112,15 @@ msg.mult.index =\
|
|||
msg.cant.convert =\
|
||||
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
|
||||
msg.cant.call.indirect =\
|
||||
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 \
|
||||
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 =\
|
||||
Object''s getDefaultValue() method returned an object.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче