DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (5b81998bb7ab)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
    
#include "nsISupports.idl"

%{ C++
#include "jsdebug.h"
#include "nsAString.h"
%}
    
[ptr] native JSDContext(JSDContext);
[ptr] native JSDObject(JSDObject);
[ptr] native JSDProperty(JSDProperty);
[ptr] native JSDScript(JSDScript);
[ptr] native JSDStackFrameInfo(JSDStackFrameInfo);
[ptr] native JSDThreadState(JSDThreadState);
[ptr] native JSDValue(JSDValue);
[ptr] native JSRuntime(JSRuntime);
[ptr] native JSContext(JSContext);
[ptr] native JSCompartment(JSCompartment);

/* interfaces we declare in this file */
interface jsdIDebuggerService;
interface jsdIFilter;
interface jsdINestCallback;
interface jsdIFilterEnumerator;
interface jsdIContextEnumerator;
interface jsdIScriptEnumerator;
interface jsdIScriptHook;
interface jsdIErrorHook;
interface jsdIExecutionHook;
interface jsdICallHook;
interface jsdIEphemeral;
interface jsdIContext;
interface jsdIStackFrame;
interface jsdIScript;
interface jsdIValue;
interface jsdIObject;
interface jsdIProperty;
interface jsdIActivationCallback;

/**
 * Debugger service. It is not a good idea to have more than one active client
 * of the debugger service.
 */
[scriptable, uuid(029b8f0a-aa84-47eb-a60f-1a4752b7ad06)]
interface jsdIDebuggerService : nsISupports
{
    /** Internal use only. */
    [noscript] readonly attribute JSDContext        JSDContext;

    /**
     * Called when an error or warning occurs.
     */
    attribute jsdIErrorHook     errorHook;
    /**
     * Called when a jsdIScript is created or destroyed.
     */
    attribute jsdIScriptHook    scriptHook;
    /**
     * Called when the engine encounters a breakpoint.
     */
    attribute jsdIExecutionHook breakpointHook;
    /**
     * Called when the engine encounters the debugger keyword.
     */
    attribute jsdIExecutionHook debuggerHook;
    /**
     * Called when the errorHook returns false.
     */
    attribute jsdIExecutionHook debugHook;
    /**
     * Called before the next PC is executed.
     */
    attribute jsdIExecutionHook interruptHook;
    /**
     * Called when an exception is thrown (even if it will be caught.)
     */
    attribute jsdIExecutionHook throwHook;
    /**
     * Called before and after a toplevel script is evaluated.
     */
    attribute jsdICallHook      topLevelHook;
    /**
     * Called before and after a function is called.
     */
    attribute jsdICallHook      functionHook;

    /**
     * Link native frames in call stacks.
     */
    const unsigned long ENABLE_NATIVE_FRAMES     = 0x01;
    /**
     * Normally, if a script has a 0 in JSD_SCRIPT_PROFILE_BIT it is included in
     * profile data, otherwise it is not profiled. Setting the
     * PROFILE_WHEN_SET flag reverses this convention.
     */
    const unsigned long PROFILE_WHEN_SET         = 0x02;
    /**
     * Normally, when the script in the top frame of a thread state has a 1 in
     * JSD_SCRIPT_DEBUG_BIT, the execution hook is ignored. Setting the
     * DEBUG_WHEN_SET flag reverses this convention.
     */
    const unsigned long DEBUG_WHEN_SET           = 0x04;
    /**
     * When this flag is set the internal call hook will collect profile data.
     */
    const unsigned long COLLECT_PROFILE_DATA     = 0x08;
    /**
     * When this flag is set, stack frames that are disabled for debugging
     * will not appear in the call stack chain.
     */
    const unsigned long HIDE_DISABLED_FRAMES     = 0x10;
    /**
     * When this flag is set, the debugger will only check the
     * JSD_SCRIPT_DEBUG_BIT on the top (most recent) stack frame. This
     * makes it possible to stop in an enabled frame which was called from
     * a stack that contains a disabled frame.
     *
     * When this flag is *not* set, any stack that contains a disabled frame
     * will not be debugged (the execution hook will not be invoked.)
     *
     * This only applies when the reason for calling the hook would have
     * been TYPE_INTERRUPTED or TYPE_THROW. TYPE_BREAKPOINT,
     * TYPE_DEBUG_REQUESTED, and TYPE_DEBUGGER_KEYWORD always stop, regardless
     * of this setting, as long as the top frame is not disabled.
     *
     * If HIDE_DISABLED_FRAMES is set, this is effectively set as well.
     */
    const unsigned long MASK_TOP_FRAME_ONLY     = 0x20;
    /**
     * This flag has been retired, do not re-use. It previously provided a hook
     * for object allocation.
     */
    const unsigned long DISABLE_OBJECT_TRACE_RETIRED = 0x40;

    /**
     * Debugger service flags.
     */
    attribute unsigned long flags;
    
    /**
     * Major version number of implementation.
     */
    readonly attribute unsigned long implementationMajor;
    /**
     * Minor version number of implementation.
     */
    readonly attribute unsigned long implementationMinor;
    /**
     * Free form AUTF8String identifier for implementation.
     */
    readonly attribute AUTF8String implementationString;
    
    /**
     * |true| if the debugger service has been turned on. This does not
     * necessarily mean another app is actively using the service, as the 
     * autostart pref may have turned the service on.
     */
    readonly attribute boolean isOn;


    /**
     * Synchronous activation of the debugger is no longer supported,
     * and will throw an exception.
     */
    void on();

    /**
     * Turn on the debugger. This function should only be called from
     * JavaScript code. The debugger will be enabled on the runtime the call is
     * made on, as determined by nsIXPCNativeCallContext.
     *
     * The debugger will be activated asynchronously, because there can be no
     * JS on the stack when code is to be re-compiled for debug mode.
     */
    void asyncOn(in jsdIActivationCallback callback);
    
    /**
     * Called by nsIXPConnect after it's had a chance to recompile for
     * debug mode.
     */
    [noscript] void activateDebugger(in JSRuntime rt);

    /**
     * Called by nsIXPConnect to deactivate debugger on setup failure.
     */
    [noscript] void deactivateDebugger();

    /**
     * Recompile all active scripts in the runtime for debugMode.
     */
    [noscript] void recompileForDebugMode(in JSContext cx, in JSCompartment comp, in boolean mode);

    /**
     * Turn the debugger off. This will invalidate all of your jsdIEphemeral
     * derived objects, and clear all of your breakpoints.
     */
    void off ();

    /**
     * Peek at the current pause depth of the debugger.
     *
     * @return depth Number of pause() calls still waiting to be unPause()d.
     */
    readonly attribute unsigned long pauseDepth;
    /**
     * Temporarily disable the debugger. Hooks will not be called while the
     * debugger is paused. Multiple calls to pause will increase the "pause
     * depth", and equal number of unPause calles must be made to resume
     * normal debugging.
     *
     * @return depth Number of times pause has been called since the debugger
     *               has been unpaused.
     */
    unsigned long pause();
    /**
     * Undo a pause.  Once this is called, the debugger won't start
     * getting execution callbacks until the stack is fully unwound so
     * that no JS scripts are live.  There is no way to query whether
     * there are such scripts left to unwind at a given point in time.
     *
     * @return depth The number of remaining pending pause calls.
     */
    unsigned long unPause();
    
    /**
     * Force the engine to perform garbage collection.
     */
    void GC();
    
    /**
     * Clear profile data for all scripts.
     */
    void clearProfileData();
    
    /**
     * Adds an execution hook filter. These filters are consulted each time one
     * of the jsdIExecutionHooks is about to be called. Filters are matched in
     * a first in, first compared fashion. The first filter to match determines
     * whether or not the hook is called. Use swapFilter to reorder existing
     * filters, and removeFilter to remove them.
     *
     * If |filter| is already present this method throws NS_ERROR_INVALID_ARG.
     *
     * @param filter Object representing the filter to add.
     * @param after  Insert |filter| after this one. Pass null to insert at
     *               the beginning.
     */
    void insertFilter(in jsdIFilter filter, in jsdIFilter after);
    /**
     * Same as insertFilter, except always add to the end of the list.
     */
    void appendFilter(in jsdIFilter filter);
    /**
     * Remove a filter.
     *
     * If |filter| is not present this method throws NS_ERROR_INVALID_ARG.
     *
     * @param filter Object representing the filter to remove. Must be the exact
     * object passed to addFilter, not just a new object with the same
     * properties.
     */
    void removeFilter(in jsdIFilter filter);
    /**
     * Swap position of two filters.
     * 
     * If |filter_a| is not present, this method throws NS_ERROR_INVALID_ARG.
     * If |filter_b| is not present, filter_a is replaced by filter_b.
     * If |filter_a| == |filter_b|, then filter is refreshed.
     */
    void swapFilters(in jsdIFilter filter_a, in jsdIFilter filter_b);
    /**
     * Enumerate registered filters. This routine refreshes each filter before
     * passing them on to the enumeration function. Calling this with a null
     * |enumerator| is equivalent to jsdIService::refreshFilters.
     *
     * @param enumerator jsdIFilterEnumerator instance to be called back for the
     *                   enumeration.
     */
    void enumerateFilters(in jsdIFilterEnumerator enumerator);
    /**
     * Force the debugger to resync its internal filter cache with the
     * actual values in the jsdIFilter objects. To refresh a single filter
     * use jsdIService::swapFilters. This method is equivalent to
     * jsdIService::enumerateFilters with a null enumerator.
     */
    void refreshFilters();
    /**
     * Clear the list of filters.
     */
    void clearFilters();

    /**
     * Enumerate all known contexts.
     */
    void enumerateContexts(in jsdIContextEnumerator enumerator);
    
    /**
     * Enumerate all scripts the debugger knows about. Any scripts created
     * before you turned the debugger on, or after turning the debugger off
     * will not be available unless the autostart perf is set.
     *
     * @param enumerator jsdIScriptEnumerator instance to be called back for
     *                   the enumeration.
     */
    void enumerateScripts(in jsdIScriptEnumerator enumerator);
    /**
     * Clear all breakpoints in all scripts.
     */
    void clearAllBreakpoints();

    /**
     * When called from JavaScript, this method returns the jsdIValue wrapper
     * for the given value. If a wrapper does not exist one will be created.
     * When called from another language this method returns an xpconnect
     * defined error code.
     */
    jsdIValue wrapValue(in jsval value);

    /* XXX these two routines are candidates for refactoring. The only problem
     * is that it is not clear where and how they should land.
     */

    /**
     * Push a new network queue, and enter a new UI event loop.
     * @param callback jsdINestCallback instance to be called back after the
     *                 network queue has been pushed, but before the
     *                 UI loop starts.
     * @return depth returns the current number of times the event loop has been
     *               nested. your code can use it for sanity checks.
     */
    unsigned long enterNestedEventLoop(in jsdINestCallback callback);
    /**
     * Exit the current nested event loop after the current iteration completes,
     * and pop the network event queue.
     *
     * @return depth returns the current number of times the event loop has been
     *               nested. your code can use it for sanity checks.
     */
    unsigned long exitNestedEventLoop();

    /**
     * Output dump of JS heap.
     *
     * @param fileName Filename to dump the heap into.
     */
    void dumpHeap(in AUTF8String fileName);
};

/* callback interfaces */

/**
 * Object representing a pattern of global object and/or url the debugger should
 * ignore. The debugger service itself will not modify properties of these
 * objects.
 */
[scriptable, uuid(9ae587cd-b78c-47f0-a612-4b3a211a6a71)]
interface jsdIFilter : nsISupports
{
    /**
     * These two bytes of the flags attribute are reserved for interpretation
     * by the jsdService implementation. You can do what you like with the
     * remaining flags.
     */
    const unsigned long FLAG_RESERVED_MASK = 0xFF;
    /**
     * Filters without this flag set are ignored.
     */
    const unsigned long FLAG_ENABLED       = 0x01;
    /**
     * Filters with this flag set are "pass" filters, they allow matching hooks
     * to continue. Filters without this flag block matching hooks.
     */
    const unsigned long FLAG_PASS          = 0x02;

    /**
     * FLAG_* values from above, OR'd together.
     */
    attribute unsigned long flags;

    /**
     * String representing the url pattern to be filtered. Supports limited
     * glob matching, at the beginning and end of the pattern only. For example,
     * "chrome://venkman*" filters all urls that start with chrome/venkman,
     * "*.cgi" filters all cgi's, and "http://myserver/utils.js" filters only
     * the utils.js file on "myserver". A null urlPattern matches all urls.
     *
     * The jsdIService caches this value internally, to if it changes you must
     * swap the filter with itself using jsdIService::swapFilters.
     */
    attribute AUTF8String urlPattern;

    /**
     * Line number for the start of this filter. Line numbers are one based.
     * Assigning a 0 to this attribute will tell the debugger to ignore the
     * entire file.
     */
    attribute unsigned long startLine;

    /**
     * Line number for the end of this filter. Line numbers are one based.
     * Assigning a 0 to this attribute will tell the debugger to ignore from
     * |startLine| to the end of the file.
     */
    attribute unsigned long endLine;
};

/**
 * Notify client code that debugMode has been activated.
 */
[scriptable, function, uuid(6da7f5fb-3a84-4abe-9e23-8b2045960732)]
interface jsdIActivationCallback : nsISupports
{
    void onDebuggerActivated();
};

/**
 * Pass an instance of one of these to jsdIDebuggerService::enterNestedEventLoop.
 */
[scriptable, function, uuid(88bea60f-9b5d-4b39-b08b-1c3a278782c6)]
interface jsdINestCallback : nsISupports
{
    /**
     * This method will be called after pre-nesting work has completed, such
     * as pushing the js context and network event queue, but before the new
     * event loop starts.
     */
    void onNest();
};

/**
 * Pass an instance of one of these to jsdIDebuggerService::enumerateFilters.
 */
[scriptable, function, uuid(e391ba85-9379-4762-b387-558e38db730f)]
interface jsdIFilterEnumerator : nsISupports
{
    /**
     * The enumerateFilter method will be called once for every filter the
     * debugger knows about.
     */
    void enumerateFilter(in jsdIFilter filter);
};

/**
 * Pass an instance of one of these to jsdIDebuggerService::enumerateScripts.
 */
[scriptable, function, uuid(4eef60c2-9bbc-48fa-b196-646a832c6c81)]
interface jsdIScriptEnumerator : nsISupports
{
    /**
     * The enumerateScript method will be called once for every script the
     * debugger knows about.
     */
    void enumerateScript(in jsdIScript script);
};

/**
 * Pass an instance of one of these to jsdIDebuggerService::enumerateContexts.
 */
[scriptable, function, uuid(57d18286-550c-4ca9-ac33-56f12ebba91e)]
interface jsdIContextEnumerator : nsISupports
{
    /**
     * The enumerateContext method will be called once for every context
     * currently in use.
     */
    void enumerateContext(in jsdIContext executionContext);
};

/**
 * Set jsdIDebuggerService::scriptHook to an instance of one of these.
 */
[scriptable, uuid(d030d1a2-a58a-4f19-b9e3-96da4e2cdd09)]
interface jsdIScriptHook : nsISupports
{
    /**
     * Called when scripts are created.
     */
    void onScriptCreated(in jsdIScript script);
    /**
     * Called when the JavaScript engine destroys a script. The jsdIScript
     * object passed in will already be invalidated.
     */
    void onScriptDestroyed(in jsdIScript script);
};

/**
 * Hook instances of this interface up to the
 * jsdIDebuggerService::functionHook and toplevelHook properties.
 */
[scriptable, function, uuid(3eff1314-7ae3-4cf8-833b-c33c24a55633)]
interface jsdICallHook : nsISupports
{
    /**
     * TYPE_* values must be kept in sync with the JSD_HOOK_* #defines
     * in jsdebug.h.
     */

    /**
     * Toplevel script is starting.
     */
    const unsigned long TYPE_TOPLEVEL_START  = 0;
    /**
     * Toplevel script has completed.
     */
    const unsigned long TYPE_TOPLEVEL_END    = 1;
    /**
     * Function is being called.
     */
    const unsigned long TYPE_FUNCTION_CALL   = 2;
    /**
     * Function is returning.
     */
    const unsigned long TYPE_FUNCTION_RETURN = 3;
    
    /**
     * Called before the JavaScript engine executes a top level script or calls
     * a function.
     */
    void onCall(in jsdIStackFrame frame, in unsigned long type);
};

[scriptable, function, uuid(e6b45eee-d974-4d85-9d9e-f5a67218deb4)]
interface jsdIErrorHook : nsISupports
{
    /**
     * REPORT_* values must be kept in sync with JSREPORT_* #defines in
     * jsapi.h
     */
    
    /**
     * Report is an error.
     */
    const unsigned long REPORT_ERROR     = 0x00;
    /**
     * Report is only a warning.
     */
    const unsigned long REPORT_WARNING   = 0x01;
    /**
     * Report represents an uncaught exception.
     */
    const unsigned long REPORT_EXCEPTION = 0x02;
    /**
     * Report is due to strict mode.
     */
    const unsigned long REPORT_STRICT    = 0x04;

    /**
     * Called when the JavaScript engine encounters an error. Return |true|
     * to pass the error along, |false| to invoke the debugHook.
     */
    boolean onError(in AUTF8String message, in AUTF8String fileName,
                    in unsigned long line, in unsigned long pos,
                    in unsigned long flags, in unsigned long errnum,
                    in jsdIValue exc);
};

/**
 * Hook instances of this interface up to the
 * jsdIDebuggerService::breakpointHook, debuggerHook, errorHook, interruptHook,
 * and throwHook properties.
 */
[scriptable, function, uuid(3a722496-9d78-4f0a-a797-293d9e8cb8d2)]
interface jsdIExecutionHook : nsISupports
{
    /**
     * TYPE_* values must be kept in sync with JSD_HOOK_* #defines in jsdebug.h.
     */

    /**
     * Execution stopped because we're in single step mode.
     */
    const unsigned long TYPE_INTERRUPTED      = 0;
    /**
     * Execution stopped by a trap instruction (i.e. breakoint.)
     */
    const unsigned long TYPE_BREAKPOINT       = 1;
    /**
     * Error handler returned an "invoke debugger" value.
     */
    const unsigned long TYPE_DEBUG_REQUESTED  = 2;
    /**
     * Debugger keyword encountered.
     */
    const unsigned long TYPE_DEBUGGER_KEYWORD = 3;
    /**
     * Exception was thrown.
     */
    const unsigned long TYPE_THROW            = 4;

    /**
     * RETURN_* values must be kept in sync with JSD_HOOK_RETURN_* #defines in
     * jsdebug.h.
     */

    /**
     * Indicates unrecoverable error processing the hook. This will cause
     * the script being executed to be aborted without raising a JavaScript
     * exception.
     */
    const unsigned long RETURN_HOOK_ERROR     = 0;
    /**
     * Continue processing normally. This is the "do nothing special" return
     * value for all hook types *except* TYPE_THROW. Returning RETURN_CONTINUE
     * from TYPE_THROW cause the exception to be ignored. Return
     * RETURN_CONTINUE_THROW to continue exception processing from TYPE_THROW
     * hooks.
     */
    const unsigned long RETURN_CONTINUE       = 1;
    /**
     * Same effect as RETURN_HOOK_ERROR.
     */
    const unsigned long RETURN_ABORT          = 2;
    /**
     * Return the value of the |val| parameter.
     */
    const unsigned long RETURN_RET_WITH_VAL   = 3;
    /**
     * Throw the value of the |val| parameter.
     */
    const unsigned long RETURN_THROW_WITH_VAL = 4;
    /**
     * Continue the current throw.
     */
    const unsigned long RETURN_CONTINUE_THROW = 5;

    /**
     * @param frame A jsdIStackFrame object representing the bottom stack frame.
     * @param type  One of the jsdIExecutionHook::TYPE_ constants.
     * @param val   in  - Current exception (if any) when this method is called.
     *              out - If you return RETURN_THROW_WITH_VAL, value to be
     *                    thrown.
     *                    If you return RETURN_RET_WITH_VAL, value to return.
     *                    All other return values, not significant.
     * @retval      One of the jsdIExecutionHook::RETURN_* constants.
     */
    unsigned long onExecute(in jsdIStackFrame frame, 
                            in unsigned long type, inout jsdIValue val);
};

/**
 * Objects which inherit this interface may go away, with (jsdIScript) or
 * without (all others) notification. These objects are generally wrappers
 * around JSD structures that go away when you call jsdService::Off().
 */
[scriptable, uuid(46f1e23e-1dd2-11b2-9ceb-8285f2e95e69)]
interface jsdIEphemeral : nsISupports
{
    /**
     * |true| if this object is still valid. If not, many or all of the methods
     * and/or properties of the inheritor may no longer be callable.
     */
    readonly attribute boolean isValid;
    /**
     * Mark this instance as invalid.
     */
    [noscript] void invalidate(); 
};    

/* handle objects */

/**
 * Context object. Only context's which are also nsISupports objects can be
 * reflected by this interface.
 */
[scriptable, uuid(3e5c934d-6863-4d81-96f5-76a3b962fc2b)]
interface jsdIContext : jsdIEphemeral
{
    /* Internal use only. */
    [noscript] readonly attribute JSContext   JSContext;

    /**
     * OPT_* values must be kept in sync with JSOPTION_* #defines in jsapi.h.
     */

    /**
     * Strict mode is on.
     */
    const long OPT_STRICT      = 0x01;
    /**
     * Warnings reported as errors.
     */
    const long OPT_WERR        = 0x02;
    /**
     * Makes eval() use the last object on its 'obj' param's scope chain as the
     * ECMA 'variables object'.
     */
    const long OPT_VAROBJFIX   = 0x04;
    /**
     * Private data for this object is an nsISupports object. Attempting to
     * alter this bit will result in an NS_ERROR_ILLEGAL_VALUE.
     */
    const long OPT_ISUPPORTS   = 0x08;
    /**
     * OPT_* values above, OR'd together.
     */
    attribute unsigned long          options;

    /**
     * Unique tag among all valid jsdIContext objects, useful as a hash key.
     */
    readonly attribute unsigned long tag;

    /**
     * Private data for this context, if it is an nsISupports, |null| otherwise.
     */
    readonly attribute nsISupports   privateData;
    
    /**
     * Retrieve the underlying context wrapped by this jsdIContext.
     */
    readonly attribute nsISupports   wrappedContext;

    /**
     * Top of the scope chain for this context.
     */
    readonly attribute jsdIValue     globalObject;

    /**
     * |true| if this context should be allowed to run scripts, |false|
     * otherwise. This attribute is only valid for contexts which implement
     * nsIScriptContext. Setting or getting this attribute on any other
     * context will throw a NS_ERROR_NO_INTERFACE exception.
     */
    attribute boolean                scriptsEnabled;
};

/**
 * Stack frame objects. These are only valid inside the jsdIExecutionHook which
 * gave it to you. After you return from that handler the bottom frame, and any
 * frame you found attached through it, are invalidated via the jsdIEphemeral
 * interface. Once a jsdIStackFrame has been invalidated all method and
 * property accesses will throw a NS_ERROR_NOT_AVAILABLE exception.
 */
[scriptable, uuid(7c95422c-7579-4a6f-8ef7-e5b391552ee5)]
interface jsdIStackFrame : jsdIEphemeral
{
    /** Internal use only. */
    [noscript] readonly attribute JSDContext        JSDContext;
    /** Internal use only. */
    [noscript] readonly attribute JSDThreadState    JSDThreadState;
    /** Internal use only. */
    [noscript] readonly attribute JSDStackFrameInfo JSDStackFrameInfo;
   
    /**
     * True if stack frame represents a frame created as a result of a debugger
     * evaluation.
     */
    readonly attribute boolean isDebugger;
    /**
     * True if stack frame is constructing a new object.
     */
    readonly attribute boolean isConstructing;

    /**
     * Link to the caller's stack frame.
     */
    readonly attribute jsdIStackFrame callingFrame;
    /**
     * Executon context.
     */
    readonly attribute jsdIContext    executionContext;
    /**
     * Function name executing in this stack frame.
     */
    readonly attribute AUTF8String    functionName;
    /**
     * Script running in this stack frame, null for native frames.
     */
    readonly attribute jsdIScript     script;
    /**
     * Current program counter in this stack frame.
     */
    readonly attribute unsigned long  pc;
    /**
     * Current line number (using the script's pc to line map.)
     */
    readonly attribute unsigned long  line;
    /**
     * Function object running in this stack frame.
     */
    readonly attribute jsdIValue      callee;
    /**
     * Top object in the scope chain.
     */
    readonly attribute jsdIValue      scope;
    /**
     * |this| object for this stack frame.
     */
    readonly attribute jsdIValue      thisValue;
    /**
     * Evaluate arbitrary JavaScript in this stack frame.
     * @param bytes    Script to be evaluated.
     * @param fileName Filename to compile this script under. This is the
     *                 filename you'll see in error messages, etc.
     * @param line     Starting line number for this script. One based.
     * @retval         Result of evaluating the script.
     */
    boolean eval(in AString bytes, in AUTF8String fileName,
                 in unsigned long line, out jsdIValue result);
    
};

/**
 * Script object. In JavaScript engine terms, there's a single script for each
 * function, and one for the top level script.
 */
[scriptable, uuid(8ce9b2a2-cc33-48a8-9f47-8696186ed9a5)]
interface jsdIScript : jsdIEphemeral
{
    /** Internal use only. */
    [noscript] readonly attribute JSDContext JSDContext;
    /** Internal use only. */
    [noscript] readonly attribute JSDScript  JSDScript;
    
    /**
     * Last version set on this context.
     * Scripts typically select this with the "language" attribute.
     * See the VERSION_* consts on jsdIDebuggerService.
     */
    readonly attribute long          version;

    /**
     * Tag value guaranteed unique among jsdIScript objects. Useful as a
     * hash key in script.
     */
    readonly attribute unsigned long tag;

    /**
     * FLAG_* values need to be kept in sync with JSD_SCRIPT_* #defines in
     * jsdebug.h.
     */

    /**
     * Determines whether or not to collect profile information for this
     * script. The context flag FLAG_PROFILE_WHEN_SET decides the logic.
     */
    const unsigned long FLAG_PROFILE = 0x01;
    /**
     * Determines whether or not to ignore breakpoints, etc. in this script.
     * The context flag JSD_DEBUG_WHEN_SET decides the logic.
     */
    const unsigned long FLAG_DEBUG   = 0x02;
    /**
     * Determines whether to invoke the onScriptDestroy callback for this
     * script. The default is for this to be true if the onScriptCreated
     * callback was invoked for this script.
     */
    const unsigned long FLAG_CALL_DESTROY_HOOK = 0x04;
    
    /**
     * FLAG_* attributes from above, OR'd together.
     */
    attribute unsigned long flags;

    /**
     * Filename given for this script when it was compiled.
     * This data is copied from the underlying structure when the jsdIScript
     * instance is created and is therefore available even after the script is
     * invalidated.
     */
    readonly attribute AUTF8String   fileName;
    /**
     * Function name for this script. "anonymous" for unnamed functions (or
     * a function actually named anonymous), empty for top level scripts.
     * This data is copied from the underlying structure when the jsdIScript
     * instance is created and is therefore available even after the script is
     * invalidated.
     */
    readonly attribute AUTF8String   functionName;
    /**
     * The names of the arguments for this function; empty if this is
     * not a function.
     */
    void getParameterNames([optional] out unsigned long count,
                           [array, size_is(count), retval] out wstring paramNames);
    /**
     * Fetch the function object as a jsdIValue.
     */
    readonly attribute jsdIValue     functionObject;
    /**
     * Source code for this script, without function declaration.
     */
    readonly attribute AString functionSource;
    /**
     * Line number in source file containing the first line of this script.
     * This data is copied from the underlying structure when the jsdIScript
     * instance is created and is therefore available even after the script is
     * invalidated.
     */
    readonly attribute unsigned long baseLineNumber;
    /**
     * Total number of lines in this script.
     * This data is copied from the underlying structure when the jsdIScript
     * instance is created and is therefore available even after the script is
     * invalidated.
     */
    readonly attribute unsigned long lineExtent;

    /**
     * Number of times this script has been called.
     */
    readonly attribute unsigned long callCount;
    /**
     * Number of times this script called itself, directly or indirectly.
     */
    readonly attribute unsigned long maxRecurseDepth;
    /**
     * Shortest execution time recorded, in milliseconds.
     */
    readonly attribute double minExecutionTime;
    /**
     * Longest execution time recorded, in milliseconds.
     */
    readonly attribute double maxExecutionTime;
    /**
     * Total time spent in this function, in milliseconds.
     */
    readonly attribute double totalExecutionTime;
    /**
     * Shortest execution time recorded, in milliseconds, excluding time spent
     * in other called code.
     */
    readonly attribute double minOwnExecutionTime;
    /**
     * Longest execution time recorded, in milliseconds, excluding time spent
     * in other called code.
     */
    readonly attribute double maxOwnExecutionTime;
    /**
     * Total time spent in this function, in milliseconds, excluding time spent
     * in other called code.
     */
    readonly attribute double totalOwnExecutionTime;
    
    /**
     * Clear profile data for this script.
     */
    void clearProfileData();
    
    const unsigned long PCMAP_SOURCETEXT  = 1; /* map to actual source text    */
    const unsigned long PCMAP_PRETTYPRINT = 2; /* map to pretty printed source */

    /**
     * Get the closest line number to a given PC.
     * The |pcmap| argument specifies which pc to source line map to use.
     */
    unsigned long pcToLine(in unsigned long pc, in unsigned long pcmap);
    /**
     * Get the first PC associated with a line.
     * The |pcmap| argument specifies which pc to source line map to use.
     */
    unsigned long lineToPc(in unsigned long line, in unsigned long pcmap);
    /**
     * Determine is a particular line is executable, like checking that
     * lineToPc == pcToLine, except in one call.
     * The |pcmap| argument specifies which pc to source line map to use.
     */
    boolean isLineExecutable(in unsigned long line, in unsigned long pcmap);

    /**
     * Return a list of all executable lines in a script.
     * |pcmap| specifies which pc to source line map to use.
     * |startLine| and |maxLines| may be used to retrieve a chunk at a time.
     */
    void getExecutableLines(in unsigned long pcmap,
                            in unsigned long startLine, in unsigned long maxLines,
                            [optional] out unsigned long count,
                            [array, size_is(count), retval] out unsigned long executableLines);
 
    /**
     * Set a breakpoint at a PC in this script.
     */
    void setBreakpoint(in unsigned long pc);
    /**
     * Clear a breakpoint at a PC in this script.
     */
    void clearBreakpoint(in unsigned long pc);
    /**
     * Clear all breakpoints set in this script.
     */
    void clearAllBreakpoints();
    /**
     * Call interrupt hook at least once per source line
     */
    void enableSingleStepInterrupts(in boolean mode);
};

/**
 * Value objects. Represents typeless JavaScript values (jsval in SpiderMonkey
 * terminology.)  These are valid until the debugger is turned off. Holding a
 * jsdIValue adds a root for the underlying JavaScript value, so don't keep it
 * if you don't need to.
 */
[scriptable, uuid(1cd3535b-4ddb-4202-9053-e0ec88f5c82b)]
interface jsdIValue : jsdIEphemeral
{
    /** Internal use only. */
    [noscript] readonly attribute JSDContext JSDContext;
    /** Internal use only. */
    [noscript] readonly attribute JSDValue   JSDValue;

    /**
     * |false| unless the value is a function declared in script.
     */
    readonly attribute boolean isNative;
    /**
     * |true| if the value represents a number, either double or integer.
     * |false| for all other values, including numbers assigned as strings
     * (eg. x = "1";)
     */
    readonly attribute boolean isNumber;
    /**
     * |true| if the value represents a JavaScript primitive number or AUTF8String
     */
    readonly attribute boolean isPrimitive;
    
    /** Value is either |true| or |false|. */
    const unsigned long TYPE_BOOLEAN  = 0;
    /** Value is a primitive number that is too large to fit in an integer. */
    const unsigned long TYPE_DOUBLE   = 1;
    /** Value is a primitive number that fits into an integer. */
    const unsigned long TYPE_INT      = 2;
    /** Value is a function. */
    const unsigned long TYPE_FUNCTION = 3;
    /** Value is |null|. */
    const unsigned long TYPE_NULL     = 4;
    /** Value is an object. */
    const unsigned long TYPE_OBJECT   = 5;
    /** Value is a primitive AUTF8String. */
    const unsigned long TYPE_STRING   = 6;
    /** Value is void. */
    const unsigned long TYPE_VOID     = 7;
    
    /**
     * One of the TYPE_* values above.
     */
    readonly attribute unsigned long jsType;
    /**
     * Prototype value if this value represents an object, null if the value is
     * not an object or the object has no prototype.
     */
    readonly attribute jsdIValue     jsPrototype;
    /**
     * Parent value if this value represents an object, null if the value is not
     * an object or the object has no parent.
     */    
    readonly attribute jsdIValue     jsParent;
    /**
     * Class name if this value represents an object. Empty AUTF8String if the value
     * is not an object.
     */
    readonly attribute AUTF8String   jsClassName;
    /**
     * Constructor name if this value represents an object. Empty AUTF8String if the
     * value is not an object.
     */
    readonly attribute jsdIValue     jsConstructor;
    /**
     * Function name if this value represents a function. Empty AUTF8String if the
     * value is not a function.
     */
    readonly attribute AUTF8String   jsFunctionName;
    
    /**
     * Value if interpreted as a boolean. Converts if necessary.
     */
    readonly attribute boolean       booleanValue;
    /**
     * Value if interpreted as a double. Converts if necessary.
     */
    readonly attribute double        doubleValue;
    /**
     * Value if interpreted as an integer. Converts if necessary.
     */
    readonly attribute long          intValue;
    /**
     * Value if interpreted as an object.
     */
    readonly attribute jsdIObject    objectValue;
    /**
     * Value if interpreted as a AUTF8String. Converts if necessary.
     */
    readonly attribute AUTF8String   stringValue;

    /**
     * Number of properties. 0 if the value is not an object, or the value is
     * an object but has no properties.
     */
    readonly attribute long propertyCount;
    
    /**
     * Retrieves all properties if this value represents an object. If this
     * value is not an object a 0 element array is returned.
     * @param propArray Array of jsdIProperty values for this value.
     * @param length    Size of array.
     */
    void getProperties([array, size_is(length)] out jsdIProperty propArray,
                       out unsigned long length);
    /**
     * Retrieves a single property from the value. Only valid if the value
     * represents an object.
     * @param name Name of the property to retrieve.
     * @retval     jsdIProperty for the requested property name or null if no
     *             property exists for the requested name.
     */
    jsdIProperty getProperty(in AUTF8String name);

    /**
     * jsdIValues are wrappers around JavaScript engine structures. Much of the
     * data is copied instead of shared. The refresh method is used to resync
     * the jsdIValue with the underlying structure.
     */
    void refresh();

    /**
     * When called from JavaScript, this method returns the JavaScript value
     * wrapped by this jsdIValue. The calling script is free to use the result
     * as it would any other JavaScript value.
     * When called from another language this method returns an xpconnect
     * defined error code.
     */
    [implicit_jscontext] jsval getWrappedValue();

    /**
     * If this is a function value, return its associated jsdIScript.
     * Otherwise, return null.
     */
    readonly attribute jsdIScript script;
};

/**
 * Properties specific to values which are also objects.
 * XXX We don't add roots for these yet, so make sure you hold on to the
 * jsdIValue from whence your jsdIObject instance came for at least as long as
 * you hold the jsdIObject.
 * XXX Maybe the jsClassName, jsConstructorName, and property related attribute/
 * functions from jsdIValue should move to this interface. We could inherit from
 * jsdIValue or use interface flattening or something.
 */
[scriptable, uuid(87d86308-7a27-4255-b23c-ce2394f02473)]
interface jsdIObject : nsISupports
{
    /** Internal use only. */
    [noscript] readonly attribute JSDContext JSDContext;
    /** Internal use only. */
    [noscript] readonly attribute JSDObject  JSDObject;

    /**
     * The URL (filename) that contains the script which caused this object
     * to be created.
     */
    readonly attribute AUTF8String   creatorURL;
    /**
     * Line number in the creatorURL where this object was created.
     */
    readonly attribute unsigned long creatorLine;
    /**
     * The URL (filename) that contains the script which defined the constructor
     * used to create this object.
     */
    readonly attribute AUTF8String   constructorURL;
    /**
     * Line number in the creatorURL where this object was created.
     */
    readonly attribute unsigned long constructorLine;
    /**
     * jsdIValue for this object.
     */
    readonly attribute jsdIValue     value;
};

/**
 * Representation of a property of an object. When an instance is invalid, all
 * method and property access will result in a NS_UNAVAILABLE error.
 */
[scriptable, uuid(acf1329e-aaf6-4d6a-a1eb-f75858566f09)]
interface jsdIProperty : jsdIEphemeral
{
    /** Internal use only. */
    [noscript] readonly attribute JSDContext  JSDContext;
    /** Internal use only. */
    [noscript] readonly attribute JSDProperty JSDProperty;

    /**
     * FLAG_* values must be kept in sync with JSDPD_* #defines in jsdebug.h.
     */

    /** visible to for/in loop */
    const unsigned long FLAG_ENUMERATE = 0x01;
    /** assignment is error */    
    const unsigned long FLAG_READONLY  = 0x02;
    /** property cannot be deleted */
    const unsigned long FLAG_PERMANENT = 0x04;
    /** property has an alias id */
    const unsigned long FLAG_ALIAS     = 0x08;
    /** argument to function */
    const unsigned long FLAG_ARGUMENT  = 0x10;
    /** local variable in function */
    const unsigned long FLAG_VARIABLE  = 0x20;
    /** exception occurred looking up property, value is exception */
    const unsigned long FLAG_EXCEPTION = 0x40;
    /** native getter returned JS_FALSE without throwing an exception */
    const unsigned long FLAG_ERROR     = 0x80;
    /** found via explicit lookup (property defined elsewhere.) */
    const unsigned long FLAG_HINTED    = 0x800;

    /** FLAG_* values OR'd together, representing the flags for this property. */
    readonly attribute unsigned long flags;
    /** jsdIValue representing the alias for this property. */
    readonly attribute jsdIValue     alias;
    /** name for this property. */
    readonly attribute jsdIValue     name;
    /** value of this property. */
    readonly attribute jsdIValue     value;
};