/[jscoverage]/trunk/js/jsexn.cpp
ViewVC logotype

Diff of /trunk/js/jsexn.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 459 by siliconforks, Tue Dec 9 03:37:47 2008 UTC revision 460 by siliconforks, Sat Sep 26 23:15:22 2009 UTC
# Line 68  Line 68 
68  Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);  Exception(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
69    
70  static void  static void
 exn_finalize(JSContext *cx, JSObject *obj);  
   
 static void  
71  exn_trace(JSTracer *trc, JSObject *obj);  exn_trace(JSTracer *trc, JSObject *obj);
72    
73  static void  static void
# Line 280  Line 277 
277      callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);      callerid = ATOM_KEY(cx->runtime->atomState.callerAtom);
278      stackDepth = 0;      stackDepth = 0;
279      valueCount = 0;      valueCount = 0;
280      for (fp = cx->fp; fp; fp = fp->down) {      for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) {
281          if (fp->fun && fp->argv) {          if (fp->fun && fp->argv) {
282              v = JSVAL_NULL;              v = JSVAL_NULL;
283              if (checkAccess &&              if (checkAccess &&
# Line 321  Line 318 
318    
319      values = GetStackTraceValueBuffer(priv);      values = GetStackTraceValueBuffer(priv);
320      elem = priv->stackElems;      elem = priv->stackElems;
321      for (fp = cx->fp; fp != fpstop; fp = fp->down) {      for (fp = js_GetTopStackFrame(cx); fp != fpstop; fp = fp->down) {
322          if (!fp->fun) {          if (!fp->fun) {
323              elem->funName = NULL;              elem->funName = NULL;
324              elem->argc = 0;              elem->argc = 0;
# Line 529  Line 526 
526      return priv->errorReport;      return priv->errorReport;
527  }  }
528    
 struct JSExnSpec {  
     int protoIndex;  
     const char *name;  
     JSProtoKey key;  
     JSNative native;  
 };  
   
 /*  
  * All *Error constructors share the same JSClass, js_ErrorClass.  But each  
  * constructor function for an *Error class must have a distinct native 'call'  
  * function pointer, in order for instanceof to work properly across multiple  
  * standard class sets.  See jsfun.c:fun_hasInstance.  
  */  
 #define MAKE_EXCEPTION_CTOR(name)                                             \  
 static JSBool                                                                 \  
 name(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)      \  
 {                                                                             \  
     return Exception(cx, obj, argc, argv, rval);                              \  
 }  
   
 MAKE_EXCEPTION_CTOR(Error)  
 MAKE_EXCEPTION_CTOR(InternalError)  
 MAKE_EXCEPTION_CTOR(EvalError)  
 MAKE_EXCEPTION_CTOR(RangeError)  
 MAKE_EXCEPTION_CTOR(ReferenceError)  
 MAKE_EXCEPTION_CTOR(SyntaxError)  
 MAKE_EXCEPTION_CTOR(TypeError)  
 MAKE_EXCEPTION_CTOR(URIError)  
   
 #undef MAKE_EXCEPTION_CTOR  
   
 static struct JSExnSpec exceptions[] = {  
     {JSEXN_NONE, js_Error_str,          JSProto_Error,          Error},  
     {JSEXN_ERR,  js_InternalError_str,  JSProto_InternalError,  InternalError},  
     {JSEXN_ERR,  js_EvalError_str,      JSProto_EvalError,      EvalError},  
     {JSEXN_ERR,  js_RangeError_str,     JSProto_RangeError,     RangeError},  
     {JSEXN_ERR,  js_ReferenceError_str, JSProto_ReferenceError, ReferenceError},  
     {JSEXN_ERR,  js_SyntaxError_str,    JSProto_SyntaxError,    SyntaxError},  
     {JSEXN_ERR,  js_TypeError_str,      JSProto_TypeError,      TypeError},  
     {JSEXN_ERR,  js_URIError_str,       JSProto_URIError,       URIError},  
     {0,          NULL,                  JSProto_Null,           NULL}  
 };  
   
529  static JSString *  static JSString *
530  ValueToShortSource(JSContext *cx, jsval v)  ValueToShortSource(JSContext *cx, jsval v)
531  {  {
# Line 742  Line 696 
696      JSString *message, *filename;      JSString *message, *filename;
697      JSStackFrame *fp;      JSStackFrame *fp;
698    
699      if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {      if (!JS_IsConstructing(cx)) {
700          /*          /*
701           * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when           * ECMA ed. 3, 15.11.1 requires Error, etc., to construct even when
702           * called as functions, without operator new.  But as we do not give           * called as functions, without operator new.  But as we do not give
# Line 786  Line 740 
740          argv[1] = STRING_TO_JSVAL(filename);          argv[1] = STRING_TO_JSVAL(filename);
741          fp = NULL;          fp = NULL;
742      } else {      } else {
743          fp = JS_GetScriptedCaller(cx, NULL);          fp = js_GetScriptedCaller(cx, NULL);
744          if (fp) {          if (fp) {
745              filename = FilenameToString(cx, fp->script->filename);              filename = FilenameToString(cx, fp->script->filename);
746              if (!filename)              if (!filename)
# Line 803  Line 757 
757              return JS_FALSE;              return JS_FALSE;
758      } else {      } else {
759          if (!fp)          if (!fp)
760              fp = JS_GetScriptedCaller(cx, NULL);              fp = js_GetScriptedCaller(cx, NULL);
761          lineno = (fp && fp->regs) ? js_FramePCToLineNumber(cx, fp) : 0;          lineno = (fp && fp->regs) ? js_FramePCToLineNumber(cx, fp) : 0;
762      }      }
763    
# Line 1022  Line 976 
976      JS_FS_END      JS_FS_END
977  };  };
978    
979    /* JSProto_ ordering for exceptions shall match JSEXN_ constants. */
980    JS_STATIC_ASSERT(JSEXN_ERR == 0);
981    JS_STATIC_ASSERT(JSProto_Error + JSEXN_INTERNALERR  == JSProto_InternalError);
982    JS_STATIC_ASSERT(JSProto_Error + JSEXN_EVALERR      == JSProto_EvalError);
983    JS_STATIC_ASSERT(JSProto_Error + JSEXN_RANGEERR     == JSProto_RangeError);
984    JS_STATIC_ASSERT(JSProto_Error + JSEXN_REFERENCEERR == JSProto_ReferenceError);
985    JS_STATIC_ASSERT(JSProto_Error + JSEXN_SYNTAXERR    == JSProto_SyntaxError);
986    JS_STATIC_ASSERT(JSProto_Error + JSEXN_TYPEERR      == JSProto_TypeError);
987    JS_STATIC_ASSERT(JSProto_Error + JSEXN_URIERR       == JSProto_URIError);
988    
989    static JS_INLINE JSProtoKey
990    GetExceptionProtoKey(intN exn)
991    {
992        JS_ASSERT(JSEXN_ERR <= exn);
993        JS_ASSERT(exn < JSEXN_LIMIT);
994        return (JSProtoKey) (JSProto_Error + exn);
995    }
996    
997  JSObject *  JSObject *
998  js_InitExceptionClasses(JSContext *cx, JSObject *obj)  js_InitExceptionClasses(JSContext *cx, JSObject *obj)
999  {  {
1000      JSObject *obj_proto, *protos[JSEXN_LIMIT];      jsval roots[3];
1001      int i;      JSObject *obj_proto, *error_proto;
1002        jsval empty;
1003    
1004      /*      /*
1005       * If lazy class initialization occurs for any Error subclass, then all       * If lazy class initialization occurs for any Error subclass, then all
# Line 1043  Line 1016 
1016          return NULL;          return NULL;
1017      }      }
1018    
1019      if (!js_EnterLocalRootScope(cx))      memset(roots, 0, sizeof(roots));
1020          return NULL;      JSAutoTempValueRooter tvr(cx, JS_ARRAY_LENGTH(roots), roots);
1021    
1022    #ifdef __GNUC__
1023        error_proto = NULL;   /* quell GCC overwarning */
1024    #endif
1025    
1026      /* Initialize the prototypes first. */      /* Initialize the prototypes first. */
1027      for (i = 0; exceptions[i].name != 0; i++) {      for (intN i = JSEXN_ERR; i != JSEXN_LIMIT; i++) {
1028            JSObject *proto;
1029            JSProtoKey protoKey;
1030          JSAtom *atom;          JSAtom *atom;
1031          JSFunction *fun;          JSFunction *fun;
         JSString *nameString;  
         int protoIndex = exceptions[i].protoIndex;  
1032    
1033          /* Make the prototype for the current constructor name. */          /* Make the prototype for the current constructor name. */
1034          protos[i] = js_NewObject(cx, &js_ErrorClass,          proto = js_NewObject(cx, &js_ErrorClass,
1035                                   (protoIndex != JSEXN_NONE)                               (i != JSEXN_ERR) ? error_proto : obj_proto,
1036                                   ? protos[protoIndex]                               obj, 0);
1037                                   : obj_proto,          if (!proto)
1038                                   obj, 0);              return NULL;
1039          if (!protos[i])          if (i == JSEXN_ERR) {
1040              break;              error_proto = proto;
1041                roots[0] = OBJECT_TO_JSVAL(proto);
1042            } else {
1043                // We cannot share the root for error_proto and other prototypes
1044                // as error_proto must be rooted until the function returns.
1045                roots[1] = OBJECT_TO_JSVAL(proto);
1046            }
1047    
1048          /* So exn_finalize knows whether to destroy private data. */          /* So exn_finalize knows whether to destroy private data. */
1049          STOBJ_SET_SLOT(protos[i], JSSLOT_PRIVATE, JSVAL_VOID);          STOBJ_SET_SLOT(proto, JSSLOT_PRIVATE, JSVAL_VOID);
1050    
1051          /* Make a constructor function for the current name. */          /* Make a constructor function for the current name. */
1052          atom = cx->runtime->atomState.classAtoms[exceptions[i].key];          protoKey = GetExceptionProtoKey(i);
1053          fun = js_DefineFunction(cx, obj, atom, exceptions[i].native, 3, 0);          atom = cx->runtime->atomState.classAtoms[protoKey];
1054            fun = js_DefineFunction(cx, obj, atom, Exception, 3, 0);
1055          if (!fun)          if (!fun)
1056              break;              return NULL;
1057            roots[2] = OBJECT_TO_JSVAL(FUN_OBJECT(fun));
1058    
1059          /* Make this constructor make objects of class Exception. */          /* Make this constructor make objects of class Exception. */
1060          FUN_CLASP(fun) = &js_ErrorClass;          FUN_CLASP(fun) = &js_ErrorClass;
1061    
1062          /* Make the prototype and constructor links. */          /* Make the prototype and constructor links. */
1063          if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), protos[i],          if (!js_SetClassPrototype(cx, FUN_OBJECT(fun), proto,
1064                                    JSPROP_READONLY | JSPROP_PERMANENT)) {                                    JSPROP_READONLY | JSPROP_PERMANENT)) {
1065              break;              return NULL;
1066          }          }
1067    
         /* proto bootstrap bit from JS_InitClass omitted. */  
         nameString = JS_NewStringCopyZ(cx, exceptions[i].name);  
         if (!nameString)  
             break;  
   
1068          /* Add the name property to the prototype. */          /* Add the name property to the prototype. */
1069          if (!JS_DefineProperty(cx, protos[i], js_name_str,          if (!JS_DefineProperty(cx, proto, js_name_str, ATOM_KEY(atom),
1070                                 STRING_TO_JSVAL(nameString),                                 NULL, NULL, JSPROP_ENUMERATE)) {
1071                                 NULL, NULL,              return NULL;
                                JSPROP_ENUMERATE)) {  
             break;  
1072          }          }
1073    
1074          /* Finally, stash the constructor for later uses. */          /* Finally, stash the constructor for later uses. */
1075          if (!js_SetClassObject(cx, obj, exceptions[i].key, FUN_OBJECT(fun)))          if (!js_SetClassObject(cx, obj, protoKey, FUN_OBJECT(fun)))
1076              break;              return NULL;
1077      }      }
1078    
     js_LeaveLocalRootScope(cx);  
     if (exceptions[i].name)  
         return NULL;  
   
1079      /*      /*
1080       * Add an empty message property.  (To Exception.prototype only,       * Set default values and add methods. We do it only for Error.prototype
1081       * because this property will be the same for all the exception       * as the rest of exceptions delegate to it.
      * protos.)  
1082       */       */
1083      if (!JS_DefineProperty(cx, protos[0], js_message_str,      empty = STRING_TO_JSVAL(cx->runtime->emptyString);
1084                             STRING_TO_JSVAL(cx->runtime->emptyString),      if (!JS_DefineProperty(cx, error_proto, js_message_str, empty,
1085                             NULL, NULL, JSPROP_ENUMERATE)) {                             NULL, NULL, JSPROP_ENUMERATE) ||
1086            !JS_DefineProperty(cx, error_proto, js_fileName_str, empty,
1087                               NULL, NULL, JSPROP_ENUMERATE) ||
1088            !JS_DefineProperty(cx, error_proto, js_lineNumber_str, JSVAL_ZERO,
1089                               NULL, NULL, JSPROP_ENUMERATE) ||
1090            !JS_DefineFunctions(cx, error_proto, exception_methods)) {
1091          return NULL;          return NULL;
1092      }      }
     if (!JS_DefineProperty(cx, protos[0], js_fileName_str,  
                            STRING_TO_JSVAL(cx->runtime->emptyString),  
                            NULL, NULL, JSPROP_ENUMERATE)) {  
         return NULL;  
     }  
     if (!JS_DefineProperty(cx, protos[0], js_lineNumber_str,  
                            INT_TO_JSVAL(0),  
                            NULL, NULL, JSPROP_ENUMERATE)) {  
         return NULL;  
     }  
   
     /*  
      * Add methods only to Exception.prototype, because ostensibly all  
      * exception types delegate to that.  
      */  
     if (!JS_DefineFunctions(cx, protos[0], exception_methods))  
         return NULL;  
1093    
1094      return protos[0];      return error_proto;
1095  }  }
1096    
1097  const JSErrorFormatString*  const JSErrorFormatString*
# Line 1218  Line 1179 
1179       * exception constructor name in the scope chain of the current context's       * exception constructor name in the scope chain of the current context's
1180       * top stack frame, or in the global object if no frame is active.       * top stack frame, or in the global object if no frame is active.
1181       */       */
1182      ok = js_GetClassPrototype(cx, NULL, INT_TO_JSID(exceptions[exn].key),      ok = js_GetClassPrototype(cx, NULL, INT_TO_JSID(GetExceptionProtoKey(exn)),
1183                                &errProto);                                &errProto);
1184      if (!ok)      if (!ok)
1185          goto out;          goto out;

Legend:
Removed from v.459  
changed lines
  Added in v.460

  ViewVC Help
Powered by ViewVC 1.1.24