зеркало из https://github.com/mozilla/gecko-dev.git
First cut at errors as exceptions - These changes should be benign since
the errors are being wrapped by runtime exceptions and still need to be explicitly caught (this is happening in the interpreter, but not in generated code).
This commit is contained in:
Родитель
b9528fb7bc
Коммит
079188169c
|
@ -563,12 +563,14 @@ public final class Context {
|
|||
if (scope.getPrototype() == null)
|
||||
scope.setPrototype(objectProto);
|
||||
|
||||
String[] classes = { "NativeGlobal", "NativeArray",
|
||||
String[] classes = { "NativeError", // must precede NativeGlobal
|
||||
// since it's needed therein
|
||||
"NativeGlobal", "NativeArray",
|
||||
"NativeString", "NativeBoolean",
|
||||
"NativeNumber", "NativeDate",
|
||||
"NativeMath", "NativeCall",
|
||||
"NativeClosure", "NativeWith",
|
||||
"regexp.NativeRegExp", "NativeScript"
|
||||
"regexp.NativeRegExp", "NativeScript"
|
||||
};
|
||||
for (int i=0; i < classes.length; i++) {
|
||||
try {
|
||||
|
@ -1108,8 +1110,7 @@ public final class Context {
|
|||
* @return new JavaScript object
|
||||
*/
|
||||
public static Scriptable toObject(Object value, Scriptable scope,
|
||||
Class staticType)
|
||||
{
|
||||
Class staticType) {
|
||||
if (value == null && staticType != null)
|
||||
return null;
|
||||
return ScriptRuntime.toObject(scope, value, staticType);
|
||||
|
|
|
@ -35,4 +35,12 @@ public class EvaluatorException extends RuntimeException {
|
|||
public EvaluatorException(String detail) {
|
||||
super(detail);
|
||||
}
|
||||
|
||||
public EvaluatorException(Object nativeError) {
|
||||
super("NativeError");
|
||||
errorObject = nativeError;
|
||||
}
|
||||
|
||||
Object errorObject;
|
||||
|
||||
}
|
||||
|
|
|
@ -1786,6 +1786,47 @@ public class Interpreter extends LabelTable {
|
|||
}
|
||||
pc++;
|
||||
}
|
||||
catch (EvaluatorException ee) {
|
||||
if (ee.errorObject != null) {
|
||||
// an EvaluatorException that is actually an offical
|
||||
// ECMA error object, handle as if it were a JavaScriptException
|
||||
stackTop = 0;
|
||||
cx.interpreterSecurityDomain = null;
|
||||
if (tryStackTop > 0) {
|
||||
pc = catchStack[--tryStackTop];
|
||||
scope = scopeStack[tryStackTop];
|
||||
if (pc == 0) {
|
||||
pc = finallyStack[tryStackTop];
|
||||
if (pc == 0)
|
||||
throw ee;
|
||||
stack[0] = ee.errorObject;
|
||||
}
|
||||
else
|
||||
stack[0] = ee.errorObject;
|
||||
}
|
||||
else
|
||||
throw ee;
|
||||
// We caught an exception; restore this function's
|
||||
// security domain.
|
||||
cx.interpreterSecurityDomain = theData.securityDomain;
|
||||
}
|
||||
else {
|
||||
// handle like any other RuntimeException, more code duplication
|
||||
cx.interpreterSecurityDomain = null;
|
||||
if (tryStackTop > 0) {
|
||||
stackTop = 0;
|
||||
stack[0] = ee;
|
||||
pc = finallyStack[--tryStackTop];
|
||||
scope = scopeStack[tryStackTop];
|
||||
if (pc == 0) throw ee;
|
||||
}
|
||||
else
|
||||
throw ee;
|
||||
// We caught an exception; restore this function's
|
||||
// security domain.
|
||||
cx.interpreterSecurityDomain = theData.securityDomain;
|
||||
}
|
||||
}
|
||||
catch (JavaScriptException jsx) {
|
||||
stackTop = 0;
|
||||
cx.interpreterSecurityDomain = null;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
*
|
||||
* The class of error objects
|
||||
*
|
||||
* ECMA 15.11
|
||||
*/
|
||||
public class NativeError extends ScriptableObject {
|
||||
|
||||
public NativeError()
|
||||
{
|
||||
}
|
||||
|
||||
public String getClassName() { return "Error"; }
|
||||
|
||||
public String jsFunction_toString()
|
||||
{
|
||||
return ScriptRuntime.toString(ScriptRuntime.getProp(this, "name", this))
|
||||
+ " "
|
||||
+ ScriptRuntime.toString(ScriptRuntime.getProp(this, "message", this));
|
||||
}
|
||||
|
||||
public static void finishInit(Scriptable scope, FunctionObject ctor,
|
||||
Scriptable proto)
|
||||
throws PropertyException
|
||||
{
|
||||
((ScriptableObject) proto).defineProperty("message", "",
|
||||
ScriptableObject.EMPTY);
|
||||
((ScriptableObject) proto).defineProperty("name", "Error",
|
||||
ScriptableObject.EMPTY);
|
||||
}
|
||||
|
||||
}
|
|
@ -33,7 +33,9 @@ import java.io.IOException;
|
|||
public class NativeGlobal {
|
||||
|
||||
public static void init(Scriptable scope)
|
||||
throws PropertyException
|
||||
throws PropertyException,
|
||||
NotAFunctionException,
|
||||
JavaScriptException
|
||||
{
|
||||
|
||||
String names[] = { "eval",
|
||||
|
@ -57,6 +59,30 @@ public class NativeGlobal {
|
|||
ScriptableObject.DONTENUM);
|
||||
global.defineProperty("undefined", Undefined.instance,
|
||||
ScriptableObject.DONTENUM);
|
||||
|
||||
String[] errorMethods = { "ConversionError",
|
||||
"EvalError",
|
||||
"RangeError",
|
||||
"ReferenceError",
|
||||
"SyntaxError",
|
||||
"TypeError",
|
||||
"URIError"
|
||||
};
|
||||
|
||||
global.defineFunctionProperties(errorMethods, NativeGlobal.class,
|
||||
ScriptableObject.DONTENUM);
|
||||
/*
|
||||
Each error constructor gets it's own Error object as a prototype,
|
||||
with the 'name' property set to the name of the error.
|
||||
*/
|
||||
for (int i = 0; i < errorMethods.length; i++) {
|
||||
FunctionObject errorConstructor
|
||||
= (FunctionObject)(global.get(errorMethods[i], global));
|
||||
Scriptable errorProto = Context.getContext().newObject(scope, "Error");
|
||||
errorProto.put("name", errorProto, errorMethods[i]);
|
||||
errorConstructor.put("prototype", errorConstructor, errorProto);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -400,4 +426,118 @@ public class NativeGlobal {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The NativeError functions
|
||||
*
|
||||
* See ECMA 15.11.6
|
||||
*/
|
||||
|
||||
public static EvaluatorException constructError(Context cx,
|
||||
String error,
|
||||
String message,
|
||||
Object scope)
|
||||
{
|
||||
Scriptable scopeObject;
|
||||
try {
|
||||
scopeObject = (Scriptable) scope;
|
||||
}
|
||||
catch (ClassCastException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
|
||||
Object args[] = { message };
|
||||
try {
|
||||
Object errorObject = cx.newObject(scopeObject, error, args);
|
||||
return new EvaluatorException(errorObject);
|
||||
}
|
||||
catch (PropertyException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
catch (JavaScriptException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
catch (NotAFunctionException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static Object ConversionError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object EvalError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object RangeError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object ReferenceError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object SyntaxError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object TypeError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object URIError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1136,8 +1136,10 @@ public class ScriptRuntime {
|
|||
obj = obj.getParentScope();
|
||||
}
|
||||
Object[] args = { id.toString() };
|
||||
throw Context.reportRuntimeError(getMessage
|
||||
("msg.is.not.defined", args));
|
||||
throw NativeGlobal.constructError(
|
||||
Context.getContext(), "ReferenceError",
|
||||
ScriptRuntime.getMessage("msg.is.not.defined", args),
|
||||
scopeChain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -87,14 +87,16 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
flags |= MULTILINE;
|
||||
} else {
|
||||
Object[] errArgs = { new Character(c) };
|
||||
throw Context.reportRuntimeError(ScriptRuntime.getMessage
|
||||
("msg.invalid.re.flag",
|
||||
errArgs));
|
||||
throw NativeGlobal.constructError(
|
||||
cx, "SyntaxError",
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.invalid.re.flag", errArgs),
|
||||
scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CompilerState state = new CompilerState(source, flags, cx);
|
||||
CompilerState state = new CompilerState(source, flags, cx, scope);
|
||||
this.ren = parseRegExp(state);
|
||||
if (ren == null) return;
|
||||
RENode end = new RENode(state, REOP_END, null);
|
||||
|
@ -204,8 +206,11 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
{
|
||||
if (!(thisObj instanceof NativeRegExp)) {
|
||||
Object[] errArgs = { ((NativeFunction) funObj).jsGet_name() };
|
||||
throw Context.reportRuntimeError(
|
||||
ScriptRuntime.getMessage("msg.incompat.call", errArgs));
|
||||
throw NativeGlobal.constructError(
|
||||
cx, "TypeError",
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.incompat.call", errArgs),
|
||||
scopeObj);
|
||||
}
|
||||
NativeRegExp re = (NativeRegExp) thisObj;
|
||||
String str;
|
||||
|
@ -1113,7 +1118,8 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
&& source[index + 1] >= '0'
|
||||
&& source[index + 1] <= '9') {
|
||||
if (c >= '0' && c <= '3') {
|
||||
if (c <= '7') { /* ZeroToThree OctalDigit */
|
||||
if (source[index + 1] <= '7') {
|
||||
/* ZeroToThree OctalDigit */
|
||||
if (index < (source.length - 2)
|
||||
&& source[index + 2] >= '0'
|
||||
&& source[index + 2] <= '9') {
|
||||
|
@ -1143,11 +1149,12 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
ren.flags = RENode.NONEMPTY;
|
||||
skipCommon = true;
|
||||
}
|
||||
if (c > '7' || source[index + 1] > '7') {
|
||||
Context.reportError(
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.invalid.backref", null));
|
||||
return null;
|
||||
if (c > '7' || source[index + 1] > '7') {
|
||||
throw NativeGlobal.constructError(
|
||||
state.cx, "SyntaxError",
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.invalid.backref", null),
|
||||
state.scope);
|
||||
}
|
||||
ren = new RENode(state, REOP_FLAT1, null);
|
||||
c = (char)(8 * unDigit(c) + unDigit(source[++index]));
|
||||
|
@ -1549,7 +1556,7 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
char[] source = (ren.s != null)
|
||||
? ren.s
|
||||
: this.source.toCharArray();
|
||||
ren.buildBitmap(source, ((state.flags & FOLD) != 0));
|
||||
ren.buildBitmap(state, source, ((state.flags & FOLD) != 0));
|
||||
}
|
||||
char c = input[index];
|
||||
int b = (c >>> 3);
|
||||
|
@ -1753,6 +1760,7 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
MatchState state = new MatchState();
|
||||
state.anchoring = false;
|
||||
state.flags = re.flags;
|
||||
state.scope = scopeObj;
|
||||
|
||||
char[] charArray = str.toCharArray();
|
||||
int start = indexp[0];
|
||||
|
@ -1900,12 +1908,14 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
}
|
||||
|
||||
class CompilerState {
|
||||
CompilerState(String source, int flags, Context cx) {
|
||||
CompilerState(String source, int flags, Context cx, Scriptable scope) {
|
||||
this.source = source.toCharArray();
|
||||
this.scope = scope;
|
||||
this.flags = flags;
|
||||
this.cx = cx;
|
||||
}
|
||||
Context cx;
|
||||
Scriptable scope;
|
||||
char[] source;
|
||||
int indexBegin;
|
||||
int index;
|
||||
|
@ -1993,7 +2003,7 @@ class RENode {
|
|||
matchBit('-', fill);
|
||||
}
|
||||
|
||||
void buildBitmap(char[] s, boolean fold)
|
||||
void buildBitmap(MatchState state, char[] s, boolean fold)
|
||||
{
|
||||
int index = ((Integer) kid).intValue();
|
||||
int end = kid2;
|
||||
|
@ -2160,9 +2170,11 @@ class RENode {
|
|||
|
||||
if (inrange) {
|
||||
if (lastc > c) {
|
||||
throw Context.reportRuntimeError
|
||||
(ScriptRuntime.getMessage("msg.bad.range",
|
||||
null));
|
||||
throw NativeGlobal.constructError(
|
||||
Context.getCurrentContext(), "RangeError",
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.bad.range", null),
|
||||
state.scope);
|
||||
}
|
||||
inrange = false;
|
||||
} else {
|
||||
|
@ -2222,5 +2234,6 @@ class MatchState {
|
|||
int parenCount; /* number of paren substring matches */
|
||||
SubString[] maybeParens; /* possible paren substring pointers */
|
||||
SubString[] parens; /* certain paren substring matches */
|
||||
Scriptable scope;
|
||||
}
|
||||
|
||||
|
|
|
@ -563,12 +563,14 @@ public final class Context {
|
|||
if (scope.getPrototype() == null)
|
||||
scope.setPrototype(objectProto);
|
||||
|
||||
String[] classes = { "NativeGlobal", "NativeArray",
|
||||
String[] classes = { "NativeError", // must precede NativeGlobal
|
||||
// since it's needed therein
|
||||
"NativeGlobal", "NativeArray",
|
||||
"NativeString", "NativeBoolean",
|
||||
"NativeNumber", "NativeDate",
|
||||
"NativeMath", "NativeCall",
|
||||
"NativeClosure", "NativeWith",
|
||||
"regexp.NativeRegExp", "NativeScript"
|
||||
"regexp.NativeRegExp", "NativeScript"
|
||||
};
|
||||
for (int i=0; i < classes.length; i++) {
|
||||
try {
|
||||
|
@ -1108,8 +1110,7 @@ public final class Context {
|
|||
* @return new JavaScript object
|
||||
*/
|
||||
public static Scriptable toObject(Object value, Scriptable scope,
|
||||
Class staticType)
|
||||
{
|
||||
Class staticType) {
|
||||
if (value == null && staticType != null)
|
||||
return null;
|
||||
return ScriptRuntime.toObject(scope, value, staticType);
|
||||
|
|
|
@ -35,4 +35,12 @@ public class EvaluatorException extends RuntimeException {
|
|||
public EvaluatorException(String detail) {
|
||||
super(detail);
|
||||
}
|
||||
|
||||
public EvaluatorException(Object nativeError) {
|
||||
super("NativeError");
|
||||
errorObject = nativeError;
|
||||
}
|
||||
|
||||
Object errorObject;
|
||||
|
||||
}
|
||||
|
|
|
@ -1786,6 +1786,47 @@ public class Interpreter extends LabelTable {
|
|||
}
|
||||
pc++;
|
||||
}
|
||||
catch (EvaluatorException ee) {
|
||||
if (ee.errorObject != null) {
|
||||
// an EvaluatorException that is actually an offical
|
||||
// ECMA error object, handle as if it were a JavaScriptException
|
||||
stackTop = 0;
|
||||
cx.interpreterSecurityDomain = null;
|
||||
if (tryStackTop > 0) {
|
||||
pc = catchStack[--tryStackTop];
|
||||
scope = scopeStack[tryStackTop];
|
||||
if (pc == 0) {
|
||||
pc = finallyStack[tryStackTop];
|
||||
if (pc == 0)
|
||||
throw ee;
|
||||
stack[0] = ee.errorObject;
|
||||
}
|
||||
else
|
||||
stack[0] = ee.errorObject;
|
||||
}
|
||||
else
|
||||
throw ee;
|
||||
// We caught an exception; restore this function's
|
||||
// security domain.
|
||||
cx.interpreterSecurityDomain = theData.securityDomain;
|
||||
}
|
||||
else {
|
||||
// handle like any other RuntimeException, more code duplication
|
||||
cx.interpreterSecurityDomain = null;
|
||||
if (tryStackTop > 0) {
|
||||
stackTop = 0;
|
||||
stack[0] = ee;
|
||||
pc = finallyStack[--tryStackTop];
|
||||
scope = scopeStack[tryStackTop];
|
||||
if (pc == 0) throw ee;
|
||||
}
|
||||
else
|
||||
throw ee;
|
||||
// We caught an exception; restore this function's
|
||||
// security domain.
|
||||
cx.interpreterSecurityDomain = theData.securityDomain;
|
||||
}
|
||||
}
|
||||
catch (JavaScriptException jsx) {
|
||||
stackTop = 0;
|
||||
cx.interpreterSecurityDomain = null;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1997-1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
|
||||
package org.mozilla.javascript;
|
||||
|
||||
/**
|
||||
*
|
||||
* The class of error objects
|
||||
*
|
||||
* ECMA 15.11
|
||||
*/
|
||||
public class NativeError extends ScriptableObject {
|
||||
|
||||
public NativeError()
|
||||
{
|
||||
}
|
||||
|
||||
public String getClassName() { return "Error"; }
|
||||
|
||||
public String jsFunction_toString()
|
||||
{
|
||||
return ScriptRuntime.toString(ScriptRuntime.getProp(this, "name", this))
|
||||
+ " "
|
||||
+ ScriptRuntime.toString(ScriptRuntime.getProp(this, "message", this));
|
||||
}
|
||||
|
||||
public static void finishInit(Scriptable scope, FunctionObject ctor,
|
||||
Scriptable proto)
|
||||
throws PropertyException
|
||||
{
|
||||
((ScriptableObject) proto).defineProperty("message", "",
|
||||
ScriptableObject.EMPTY);
|
||||
((ScriptableObject) proto).defineProperty("name", "Error",
|
||||
ScriptableObject.EMPTY);
|
||||
}
|
||||
|
||||
}
|
|
@ -33,7 +33,9 @@ import java.io.IOException;
|
|||
public class NativeGlobal {
|
||||
|
||||
public static void init(Scriptable scope)
|
||||
throws PropertyException
|
||||
throws PropertyException,
|
||||
NotAFunctionException,
|
||||
JavaScriptException
|
||||
{
|
||||
|
||||
String names[] = { "eval",
|
||||
|
@ -57,6 +59,30 @@ public class NativeGlobal {
|
|||
ScriptableObject.DONTENUM);
|
||||
global.defineProperty("undefined", Undefined.instance,
|
||||
ScriptableObject.DONTENUM);
|
||||
|
||||
String[] errorMethods = { "ConversionError",
|
||||
"EvalError",
|
||||
"RangeError",
|
||||
"ReferenceError",
|
||||
"SyntaxError",
|
||||
"TypeError",
|
||||
"URIError"
|
||||
};
|
||||
|
||||
global.defineFunctionProperties(errorMethods, NativeGlobal.class,
|
||||
ScriptableObject.DONTENUM);
|
||||
/*
|
||||
Each error constructor gets it's own Error object as a prototype,
|
||||
with the 'name' property set to the name of the error.
|
||||
*/
|
||||
for (int i = 0; i < errorMethods.length; i++) {
|
||||
FunctionObject errorConstructor
|
||||
= (FunctionObject)(global.get(errorMethods[i], global));
|
||||
Scriptable errorProto = Context.getContext().newObject(scope, "Error");
|
||||
errorProto.put("name", errorProto, errorMethods[i]);
|
||||
errorConstructor.put("prototype", errorConstructor, errorProto);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -400,4 +426,118 @@ public class NativeGlobal {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The NativeError functions
|
||||
*
|
||||
* See ECMA 15.11.6
|
||||
*/
|
||||
|
||||
public static EvaluatorException constructError(Context cx,
|
||||
String error,
|
||||
String message,
|
||||
Object scope)
|
||||
{
|
||||
Scriptable scopeObject;
|
||||
try {
|
||||
scopeObject = (Scriptable) scope;
|
||||
}
|
||||
catch (ClassCastException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
|
||||
Object args[] = { message };
|
||||
try {
|
||||
Object errorObject = cx.newObject(scopeObject, error, args);
|
||||
return new EvaluatorException(errorObject);
|
||||
}
|
||||
catch (PropertyException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
catch (JavaScriptException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
catch (NotAFunctionException x) {
|
||||
throw new RuntimeException(x.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static Object ConversionError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object EvalError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object RangeError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object ReferenceError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object SyntaxError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object TypeError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
public static Object URIError(Context cx, Object[] args,
|
||||
Function ctorObj, boolean inNewExpr)
|
||||
{
|
||||
Scriptable newInstance = new NativeError();
|
||||
newInstance.setPrototype((Scriptable)(ctorObj.get("prototype", ctorObj)));
|
||||
newInstance.setParentScope(cx.ctorScope);
|
||||
if (args.length > 0)
|
||||
newInstance.put("message", newInstance, args[0]);
|
||||
return newInstance;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1136,8 +1136,10 @@ public class ScriptRuntime {
|
|||
obj = obj.getParentScope();
|
||||
}
|
||||
Object[] args = { id.toString() };
|
||||
throw Context.reportRuntimeError(getMessage
|
||||
("msg.is.not.defined", args));
|
||||
throw NativeGlobal.constructError(
|
||||
Context.getContext(), "ReferenceError",
|
||||
ScriptRuntime.getMessage("msg.is.not.defined", args),
|
||||
scopeChain);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -87,14 +87,16 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
flags |= MULTILINE;
|
||||
} else {
|
||||
Object[] errArgs = { new Character(c) };
|
||||
throw Context.reportRuntimeError(ScriptRuntime.getMessage
|
||||
("msg.invalid.re.flag",
|
||||
errArgs));
|
||||
throw NativeGlobal.constructError(
|
||||
cx, "SyntaxError",
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.invalid.re.flag", errArgs),
|
||||
scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CompilerState state = new CompilerState(source, flags, cx);
|
||||
CompilerState state = new CompilerState(source, flags, cx, scope);
|
||||
this.ren = parseRegExp(state);
|
||||
if (ren == null) return;
|
||||
RENode end = new RENode(state, REOP_END, null);
|
||||
|
@ -204,8 +206,11 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
{
|
||||
if (!(thisObj instanceof NativeRegExp)) {
|
||||
Object[] errArgs = { ((NativeFunction) funObj).jsGet_name() };
|
||||
throw Context.reportRuntimeError(
|
||||
ScriptRuntime.getMessage("msg.incompat.call", errArgs));
|
||||
throw NativeGlobal.constructError(
|
||||
cx, "TypeError",
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.incompat.call", errArgs),
|
||||
scopeObj);
|
||||
}
|
||||
NativeRegExp re = (NativeRegExp) thisObj;
|
||||
String str;
|
||||
|
@ -1113,7 +1118,8 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
&& source[index + 1] >= '0'
|
||||
&& source[index + 1] <= '9') {
|
||||
if (c >= '0' && c <= '3') {
|
||||
if (c <= '7') { /* ZeroToThree OctalDigit */
|
||||
if (source[index + 1] <= '7') {
|
||||
/* ZeroToThree OctalDigit */
|
||||
if (index < (source.length - 2)
|
||||
&& source[index + 2] >= '0'
|
||||
&& source[index + 2] <= '9') {
|
||||
|
@ -1143,11 +1149,12 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
ren.flags = RENode.NONEMPTY;
|
||||
skipCommon = true;
|
||||
}
|
||||
if (c > '7' || source[index + 1] > '7') {
|
||||
Context.reportError(
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.invalid.backref", null));
|
||||
return null;
|
||||
if (c > '7' || source[index + 1] > '7') {
|
||||
throw NativeGlobal.constructError(
|
||||
state.cx, "SyntaxError",
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.invalid.backref", null),
|
||||
state.scope);
|
||||
}
|
||||
ren = new RENode(state, REOP_FLAT1, null);
|
||||
c = (char)(8 * unDigit(c) + unDigit(source[++index]));
|
||||
|
@ -1549,7 +1556,7 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
char[] source = (ren.s != null)
|
||||
? ren.s
|
||||
: this.source.toCharArray();
|
||||
ren.buildBitmap(source, ((state.flags & FOLD) != 0));
|
||||
ren.buildBitmap(state, source, ((state.flags & FOLD) != 0));
|
||||
}
|
||||
char c = input[index];
|
||||
int b = (c >>> 3);
|
||||
|
@ -1753,6 +1760,7 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
MatchState state = new MatchState();
|
||||
state.anchoring = false;
|
||||
state.flags = re.flags;
|
||||
state.scope = scopeObj;
|
||||
|
||||
char[] charArray = str.toCharArray();
|
||||
int start = indexp[0];
|
||||
|
@ -1900,12 +1908,14 @@ public class NativeRegExp extends ScriptableObject implements Function {
|
|||
}
|
||||
|
||||
class CompilerState {
|
||||
CompilerState(String source, int flags, Context cx) {
|
||||
CompilerState(String source, int flags, Context cx, Scriptable scope) {
|
||||
this.source = source.toCharArray();
|
||||
this.scope = scope;
|
||||
this.flags = flags;
|
||||
this.cx = cx;
|
||||
}
|
||||
Context cx;
|
||||
Scriptable scope;
|
||||
char[] source;
|
||||
int indexBegin;
|
||||
int index;
|
||||
|
@ -1993,7 +2003,7 @@ class RENode {
|
|||
matchBit('-', fill);
|
||||
}
|
||||
|
||||
void buildBitmap(char[] s, boolean fold)
|
||||
void buildBitmap(MatchState state, char[] s, boolean fold)
|
||||
{
|
||||
int index = ((Integer) kid).intValue();
|
||||
int end = kid2;
|
||||
|
@ -2160,9 +2170,11 @@ class RENode {
|
|||
|
||||
if (inrange) {
|
||||
if (lastc > c) {
|
||||
throw Context.reportRuntimeError
|
||||
(ScriptRuntime.getMessage("msg.bad.range",
|
||||
null));
|
||||
throw NativeGlobal.constructError(
|
||||
Context.getCurrentContext(), "RangeError",
|
||||
ScriptRuntime.getMessage(
|
||||
"msg.bad.range", null),
|
||||
state.scope);
|
||||
}
|
||||
inrange = false;
|
||||
} else {
|
||||
|
@ -2222,5 +2234,6 @@ class MatchState {
|
|||
int parenCount; /* number of paren substring matches */
|
||||
SubString[] maybeParens; /* possible paren substring pointers */
|
||||
SubString[] parens; /* certain paren substring matches */
|
||||
Scriptable scope;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче