зеркало из https://github.com/mozilla/gecko-dev.git
Exception handling fixes.
This commit is contained in:
Родитель
d6fe2358de
Коммит
286e0c5fdc
|
@ -136,13 +136,24 @@ namespace MetaData {
|
|||
// the prior invocation deal with it.
|
||||
throw jsx;
|
||||
}
|
||||
// we need to clean up each activation as we pop it off
|
||||
// - basically this means just resetting it's frame
|
||||
curAct = --activationStackTop;
|
||||
} while (hndlr->mActivation != curAct);
|
||||
localFrame = activationStackTop->localFrame;
|
||||
parameterFrame = activationStackTop->parameterFrame;
|
||||
if (hndlr->mActivation != curAct) {
|
||||
while (activationStackTop->newEnv->getTopFrame() != activationStackTop->topFrame)
|
||||
activationStackTop->newEnv->removeTopFrame();
|
||||
meta->env = activationStackTop->env;
|
||||
}
|
||||
else
|
||||
break;
|
||||
} while (true);
|
||||
if (jsx.hasKind(Exception::userException)) // snatch the exception before the stack gets clobbered
|
||||
x = pop();
|
||||
activationStackTop = prev; // need the one before the target function to
|
||||
// be at the top, because of postincrement
|
||||
bCon = curAct->bCon;
|
||||
meta->env = activationStackTop->env;
|
||||
}
|
||||
else {
|
||||
if (jsx.hasKind(Exception::userException))
|
||||
|
@ -857,7 +868,7 @@ namespace MetaData {
|
|||
return 0;
|
||||
|
||||
case eVoid: // remove top item, push undefined
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
case eDup: // duplicate top item
|
||||
return 1;
|
||||
|
|
|
@ -124,24 +124,19 @@ js2val Error_toString(JS2Metadata *meta, const js2val thisValue, js2val *argv, u
|
|||
|
||||
static void initErrorClass(JS2Metadata *meta, JS2Class *c, Constructor *constructor)
|
||||
{
|
||||
// XXX Or make 'name' a static class member?
|
||||
c->construct = constructor;
|
||||
c->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(meta, JS2VAL_NULL, c));
|
||||
js2val nameVal = meta->engine->allocString(c->getName());
|
||||
QualifiedName qName(meta->publicNamespace, &meta->world.identifiers["name"]);
|
||||
meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), &qName, nameVal, ReadAccess, true, true);
|
||||
c->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(meta, meta->errorClass->prototype, meta->errorClass));
|
||||
|
||||
meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), &meta->world.identifiers["name"], meta->engine->allocString(c->getName()), ReadAccess, true, true);
|
||||
meta->createDynamicProperty(JS2VAL_TO_OBJECT(c->prototype), &meta->world.identifiers["message"], meta->engine->allocString("Message"), ReadAccess, true, true);
|
||||
|
||||
meta->initBuiltinClass(c, NULL, NULL, constructor, constructor);
|
||||
}
|
||||
|
||||
void initErrorObject(JS2Metadata *meta)
|
||||
{
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
uint16 length;
|
||||
NativeCode *code;
|
||||
} PrototypeFunction;
|
||||
|
||||
PrototypeFunction errorProtos[] =
|
||||
FunctionData errorProtos[] =
|
||||
{
|
||||
{ "toString", 0, Error_toString },
|
||||
{ NULL }
|
||||
|
@ -150,19 +145,11 @@ void initErrorObject(JS2Metadata *meta)
|
|||
NamespaceList publicNamespaceList;
|
||||
publicNamespaceList.push_back(meta->publicNamespace);
|
||||
|
||||
meta->errorClass->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(meta, meta->objectClass->prototype, meta->errorClass));
|
||||
meta->createDynamicProperty(JS2VAL_TO_OBJECT(meta->errorClass->prototype), &meta->world.identifiers["name"], meta->engine->allocString("Error"), ReadAccess, true, true);
|
||||
meta->createDynamicProperty(JS2VAL_TO_OBJECT(meta->errorClass->prototype), &meta->world.identifiers["message"], meta->engine->allocString("Message"), ReadAccess, true, true);
|
||||
meta->initBuiltinClass(meta->errorClass, errorProtos, NULL, Error_Constructor, Error_Constructor);
|
||||
|
||||
PrototypeFunction *pf = &errorProtos[0];
|
||||
while (pf->name) {
|
||||
FunctionInstance *fInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
fInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, meta->env);
|
||||
|
||||
Multiname *mn = new Multiname(&meta->world.identifiers[pf->name], &publicNamespaceList);
|
||||
InstanceMember *m = new InstanceMethod(mn, fInst, true, false);
|
||||
meta->defineInstanceMember(meta->errorClass, &meta->cxt, mn->name, *mn->nsList, Attribute::NoOverride, false, m, 0);
|
||||
pf++;
|
||||
}
|
||||
|
||||
initErrorClass(meta, meta->errorClass, Error_Constructor);
|
||||
|
||||
initErrorClass(meta, meta->evalErrorClass, EvalError_Constructor);
|
||||
initErrorClass(meta, meta->rangeErrorClass, RangeError_Constructor);
|
||||
|
|
|
@ -229,8 +229,11 @@ namespace MetaData {
|
|||
if (limit->readPublic(this, &thisValue, limit, fnName, RunPhase, &fnVal)) {
|
||||
if (JS2VAL_IS_OBJECT(fnVal)) {
|
||||
JS2Object *fnObj = JS2VAL_TO_OBJECT(fnVal);
|
||||
result = invokeFunction(fnObj, thisValue, NULL, 0);
|
||||
return true;
|
||||
if ((fnObj->kind == SimpleInstanceKind)
|
||||
&& ((checked_cast<SimpleInstance *>(fnObj))->type == functionClass)) {
|
||||
result = invokeFunction(fnObj, thisValue, NULL, 0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -286,7 +286,7 @@ static js2val Math_tan(JS2Metadata *meta, const js2val /*thisValue*/, js2val *ar
|
|||
}
|
||||
|
||||
|
||||
void initMathObject(JS2Metadata *meta)
|
||||
void initMathObject(JS2Metadata *meta, SimpleInstance *mathObject)
|
||||
{
|
||||
struct {
|
||||
char *name;
|
||||
|
@ -303,13 +303,13 @@ void initMathObject(JS2Metadata *meta)
|
|||
};
|
||||
|
||||
uint32 i;
|
||||
meta->env->addFrame(meta->mathClass);
|
||||
for (i = 0; i < M_CONSTANTS_COUNT; i++)
|
||||
{
|
||||
Variable *v = new Variable(meta->numberClass, meta->engine->allocNumber(MathObjectConstants[i].value), true);
|
||||
meta->defineLocalMember(meta->env, &meta->world.identifiers[MathObjectConstants[i].name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false);
|
||||
// Variable *v = new Variable(meta->numberClass, meta->engine->allocNumber(MathObjectConstants[i].value), true);
|
||||
// meta->defineLocalMember(meta->env, &meta->world.identifiers[MathObjectConstants[i].name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false);
|
||||
|
||||
meta->createDynamicProperty(mathObject, &meta->world.identifiers[MathObjectConstants[i].name], meta->engine->allocNumber(MathObjectConstants[i].value), ReadAccess, true, false);
|
||||
}
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
FunctionData prototypeFunctions[] =
|
||||
{
|
||||
|
@ -334,23 +334,23 @@ void initMathObject(JS2Metadata *meta)
|
|||
{ NULL },
|
||||
};
|
||||
|
||||
meta->env->addFrame(meta->mathClass);
|
||||
FunctionData *pf = &prototypeFunctions[0];
|
||||
while (pf->name) {
|
||||
FunctionInstance *callInst = new FunctionInstance(meta, meta->functionClass->prototype, meta->functionClass);
|
||||
callInst->fWrap = new FunctionWrapper(true, new ParameterFrame(JS2VAL_INACCESSIBLE, true), pf->code, meta->env);
|
||||
Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
|
||||
meta->defineLocalMember(meta->env, &meta->world.identifiers[pf->name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false);
|
||||
|
||||
meta->createDynamicProperty(mathObject, &meta->world.identifiers[pf->name], OBJECT_TO_JS2VAL(callInst), ReadAccess, true, false);
|
||||
|
||||
|
||||
|
||||
// Variable *v = new Variable(meta->functionClass, OBJECT_TO_JS2VAL(callInst), true);
|
||||
// meta->defineLocalMember(meta->env, &meta->world.identifiers[pf->name], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, false);
|
||||
|
||||
// XXX add 'length' as a dynamic property of the method
|
||||
meta->createDynamicProperty(callInst, meta->engine->length_StringAtom, INT_TO_JS2VAL(pf->length), ReadAccess, true, false);
|
||||
|
||||
pf++;
|
||||
}
|
||||
meta->env->removeTopFrame();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -3583,14 +3583,14 @@ static const uint8 urlCharType[256] =
|
|||
|
||||
static js2val Object_Constructor(JS2Metadata *meta, const js2val thisValue, js2val argv[], uint32 argc)
|
||||
{
|
||||
if (argc) {
|
||||
if ((argc == 0) || JS2VAL_IS_NULL(argv[0]) || JS2VAL_IS_UNDEFINED(argv[0]))
|
||||
return OBJECT_TO_JS2VAL(new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass));
|
||||
else {
|
||||
if (JS2VAL_IS_OBJECT(argv[0]))
|
||||
return argv[0]; // XXX special handling for host objects?
|
||||
else
|
||||
return meta->toObject(argv[0]);
|
||||
}
|
||||
else
|
||||
return OBJECT_TO_JS2VAL(new SimpleInstance(meta, meta->objectClass->prototype, meta->objectClass));
|
||||
}
|
||||
|
||||
static js2val Object_toString(JS2Metadata *meta, const js2val thisValue, js2val /* argv */ [], uint32 /* argc */)
|
||||
|
@ -3702,6 +3702,7 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
// Function properties of the Object prototype object
|
||||
objectClass->prototype = OBJECT_TO_JS2VAL(new SimpleInstance(this, NULL, objectClass));
|
||||
objectClass->construct = Object_Constructor;
|
||||
objectClass->call = Object_Constructor;
|
||||
// Adding "prototype" as a static member of the class - not a dynamic property
|
||||
env->addFrame(objectClass);
|
||||
v = new Variable(objectClass, OBJECT_TO_JS2VAL(objectClass->prototype), true);
|
||||
|
@ -3767,11 +3768,11 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
defineLocalMember(env, &world.identifiers["Boolean"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
initBooleanObject(this);
|
||||
|
||||
/*** ECMA 3 Math Class ***/
|
||||
MAKEBUILTINCLASS(mathClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Math"]), JS2VAL_NULL);
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(mathClass), true);
|
||||
/*** ECMA 3 Math Object ***/
|
||||
SimpleInstance *mathObject = new SimpleInstance(this, objectClass->prototype, objectClass);
|
||||
v = new Variable(objectClass, OBJECT_TO_JS2VAL(mathObject), true);
|
||||
defineLocalMember(env, &world.identifiers["Math"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
initMathObject(this);
|
||||
initMathObject(this, mathObject);
|
||||
|
||||
/*** ECMA 3 Array Class ***/
|
||||
MAKEBUILTINCLASS(arrayClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Array"]), JS2VAL_NULL);
|
||||
|
@ -3785,22 +3786,22 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
MAKEBUILTINCLASS(errorClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["Error"]), JS2VAL_NULL);
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(errorClass), true);
|
||||
defineLocalMember(env, &world.identifiers["Error"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
MAKEBUILTINCLASS(evalErrorClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["EvalError"]), JS2VAL_NULL);
|
||||
MAKEBUILTINCLASS(evalErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["EvalError"]), JS2VAL_NULL);
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(evalErrorClass), true);
|
||||
defineLocalMember(env, &world.identifiers["EvalError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
MAKEBUILTINCLASS(rangeErrorClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["RangeError"]), JS2VAL_NULL);
|
||||
MAKEBUILTINCLASS(rangeErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["RangeError"]), JS2VAL_NULL);
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(rangeErrorClass), true);
|
||||
defineLocalMember(env, &world.identifiers["RangeError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
MAKEBUILTINCLASS(referenceErrorClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["ReferenceError"]), JS2VAL_NULL);
|
||||
MAKEBUILTINCLASS(referenceErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["ReferenceError"]), JS2VAL_NULL);
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(referenceErrorClass), true);
|
||||
defineLocalMember(env, &world.identifiers["ReferenceError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
MAKEBUILTINCLASS(syntaxErrorClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["SyntaxError"]), JS2VAL_NULL);
|
||||
MAKEBUILTINCLASS(syntaxErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["SyntaxError"]), JS2VAL_NULL);
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(syntaxErrorClass), true);
|
||||
defineLocalMember(env, &world.identifiers["SyntaxError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
MAKEBUILTINCLASS(typeErrorClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["TypeError"]), JS2VAL_NULL);
|
||||
MAKEBUILTINCLASS(typeErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["TypeError"]), JS2VAL_NULL);
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(typeErrorClass), true);
|
||||
defineLocalMember(env, &world.identifiers["TypeError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
MAKEBUILTINCLASS(uriErrorClass, objectClass, true, true, engine->allocStringPtr(&world.identifiers["UriError"]), JS2VAL_NULL);
|
||||
MAKEBUILTINCLASS(uriErrorClass, errorClass, true, true, engine->allocStringPtr(&world.identifiers["UriError"]), JS2VAL_NULL);
|
||||
v = new Variable(classClass, OBJECT_TO_JS2VAL(uriErrorClass), true);
|
||||
defineLocalMember(env, &world.identifiers["UriError"], NULL, Attribute::NoOverride, false, ReadWriteAccess, v, 0, true);
|
||||
initErrorObject(this);
|
||||
|
@ -4237,7 +4238,6 @@ XXX see EvalAttributeExpression, where identifiers are being handled for now...
|
|||
GCMARKOBJECT(packageClass);
|
||||
GCMARKOBJECT(dateClass);
|
||||
GCMARKOBJECT(regexpClass);
|
||||
GCMARKOBJECT(mathClass);
|
||||
GCMARKOBJECT(arrayClass);
|
||||
GCMARKOBJECT(errorClass);
|
||||
GCMARKOBJECT(evalErrorClass);
|
||||
|
|
|
@ -90,7 +90,7 @@ js2val integerIs(JS2Metadata *meta, js2val newValue, JS2Class *isClass);
|
|||
|
||||
extern void initDateObject(JS2Metadata *meta);
|
||||
extern void initStringObject(JS2Metadata *meta);
|
||||
extern void initMathObject(JS2Metadata *meta);
|
||||
extern void initMathObject(JS2Metadata *meta, SimpleInstance *mathObject);
|
||||
extern void initArrayObject(JS2Metadata *meta);
|
||||
extern void initRegExpObject(JS2Metadata *meta);
|
||||
extern void initNumberObject(JS2Metadata *meta);
|
||||
|
@ -1456,7 +1456,6 @@ public:
|
|||
JS2Class *packageClass;
|
||||
JS2Class *dateClass;
|
||||
JS2Class *regexpClass;
|
||||
JS2Class *mathClass;
|
||||
JS2Class *arrayClass;
|
||||
JS2Class *errorClass;
|
||||
JS2Class *evalErrorClass;
|
||||
|
|
|
@ -38,7 +38,8 @@
|
|||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
b = pop();
|
||||
|
||||
if (JS2VAL_IS_NULL(b))
|
||||
meta->reportError(Exception::referenceError, "Null base", errorPos());
|
||||
if (JS2VAL_IS_OBJECT(b) && (JS2VAL_TO_OBJECT(b)->kind == LimitedInstanceKind)) {
|
||||
LimitedInstance *li = checked_cast<LimitedInstance *>(JS2VAL_TO_OBJECT(b));
|
||||
b = OBJECT_TO_JS2VAL(li->instance);
|
||||
|
@ -78,6 +79,8 @@
|
|||
Multiname *mn = bCon->mMultinameList[BytecodeContainer::getShort(pc)];
|
||||
pc += sizeof(short);
|
||||
b = pop();
|
||||
if (JS2VAL_IS_NULL(b))
|
||||
meta->reportError(Exception::referenceError, "Null base", errorPos());
|
||||
if (JS2VAL_IS_OBJECT(b) && (JS2VAL_TO_OBJECT(b)->kind == LimitedInstanceKind)) {
|
||||
LimitedInstance *li = checked_cast<LimitedInstance *>(JS2VAL_TO_OBJECT(b));
|
||||
b = OBJECT_TO_JS2VAL(li->instance);
|
||||
|
|
Загрузка…
Ссылка в новой задаче