Ignore:
Timestamp:
Jul 14, 2005, 11:13:50 AM (20 years ago)
Author:
ggaren
Message:

-fixed http://bugzilla.opendarwin.org/show_bug.cgi?id=3970
throw statements fail inside eval statements

Reviewed by mjs.

  • kjs/function.cpp: (KJS::GlobalFuncImp::call): Big change since I fixed the tabbing. The important part is: if (c.complType() == Throw) exec->setException(c.value());
  • kjs/nodes.cpp: (ThrowNode::execute): removed duplicate KJS_CHECKEXCEPTION (TryNode::execute): try now clears the exception state before the finally block executes, and checks the state after the block executes, so that exceptions in finally code get caught.
  • tests/mozilla/expected.html:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/function.cpp

    r9685 r9767  
    773773
    774774  switch (id) {
    775   case Eval: { // eval()
    776     Value x = args[0];
    777     if (x.type() != StringType)
    778       return x;
    779     else {
    780       UString s = x.toString(exec);
    781 
    782       int sid;
    783       int errLine;
    784       UString errMsg;
    785       ProgramNode *progNode = Parser::parse(UString(), 0, s.data(),s.size(),&sid,&errLine,&errMsg);
    786 
    787       // no program node means a syntax occurred
    788       if (!progNode) {
    789         Object err = Error::create(exec,SyntaxError,errMsg.ascii(),errLine);
    790         err.put(exec,"sid",Number(sid));
    791         exec->setException(err);
    792         return err;
     775    case Eval: { // eval()
     776      Value x = args[0];
     777      if (x.type() != StringType)
     778        return x;
     779      else {
     780        UString s = x.toString(exec);
     781       
     782        int sid;
     783        int errLine;
     784        UString errMsg;
     785        ProgramNode *progNode = Parser::parse(UString(), 0, s.data(),s.size(),&sid,&errLine,&errMsg);
     786       
     787        // no program node means a syntax occurred
     788        if (!progNode) {
     789          Object err = Error::create(exec,SyntaxError,errMsg.ascii(),errLine);
     790          err.put(exec,"sid",Number(sid));
     791          exec->setException(err);
     792          return err;
     793        }
     794       
     795        progNode->ref();
     796       
     797        // enter a new execution context
     798        Object thisVal(Object::dynamicCast(exec->context().thisValue()));
     799        ContextImp ctx(exec->dynamicInterpreter()->globalObject(),
     800                       exec->dynamicInterpreter()->imp(),
     801                       thisVal,
     802                       EvalCode,
     803                       exec->context().imp());
     804       
     805        ExecState newExec(exec->dynamicInterpreter(), &ctx);
     806        newExec.setException(exec->exception()); // could be null
     807       
     808        // execute the code
     809        progNode->processVarDecls(&newExec);
     810        Completion c = progNode->execute(&newExec);
     811
     812        // if an exception occured, propogate it back to the previous execution object
     813        if (newExec.hadException())
     814          exec->setException(newExec.exception());
     815
     816        res = Undefined();
     817        if (c.complType() == Throw)
     818          exec->setException(c.value());
     819        else if (c.isValueCompletion())
     820            res = c.value();
     821
     822        if ( progNode->deref() )
     823          delete progNode;
    793824      }
    794 
    795       progNode->ref();
    796 
    797       // enter a new execution context
    798       Object thisVal(Object::dynamicCast(exec->context().thisValue()));
    799       ContextImp ctx(exec->dynamicInterpreter()->globalObject(),
    800                      exec->dynamicInterpreter()->imp(),
    801                      thisVal,
    802                      EvalCode,
    803                      exec->context().imp());
    804 
    805       ExecState newExec(exec->dynamicInterpreter(), &ctx);
    806       newExec.setException(exec->exception()); // could be null
    807 
    808       // execute the code
    809       progNode->processVarDecls(&newExec);
    810       Completion c = progNode->execute(&newExec);
    811 
    812       // if an exception occured, propogate it back to the previous execution object
    813       if (newExec.hadException())
    814         exec->setException(newExec.exception());
    815 
    816       if ( progNode->deref() )
    817           delete progNode;
    818       if (c.complType() == ReturnValue)
    819           return c.value();
    820       // ### setException() on throw?
    821       else if (c.complType() == Normal) {
    822           if (c.isValueCompletion())
    823               return c.value();
    824           else
    825               return Undefined();
    826       } else {
    827           return Undefined();
    828       }
    829     }
    830     break;
    831   }
     825      break;
     826    }
    832827  case ParseInt:
    833828    res = Number(parseInt(args[0].toString(exec), args[1].toInt32(exec)));
Note: See TracChangeset for help on using the changeset viewer.