JavaScript:SpiderMonkey:C Coding Style: Difference between revisions
Jump to navigation
Jump to search
Line 132: | Line 132: | ||
* As with all Mozilla code, SpiderMonkey needs to compile and execute correctly on many platforms, including 64-bits systems. | * As with all Mozilla code, SpiderMonkey needs to compile and execute correctly on many platforms, including 64-bits systems. | ||
* JS and NSPR have common roots in the dawn of time (Netscape 2), and the <code>JS_THREADSAFE</code> mode of building SpiderMonkey depends on NSPR, so reading the [http://www.mozilla.org/projects/nspr/reference/html/ NSPR documentation] is well worth your while. | * JS and NSPR have common roots in the dawn of time (Netscape 2), and the <code>JS_THREADSAFE</code> mode of building SpiderMonkey depends on NSPR, so reading the [http://www.mozilla.org/projects/nspr/reference/html/ NSPR documentation] is well worth your while. | ||
* Not all 64-bit systems use the same integer type model: some are "LP64" (long and pointer | * Not all 64-bit systems use the same integer type model: some are "LP64" (long and pointer are 64 bits, int is 32 bits), while others are "LLP64" (only long long and pointer are 64 bits; long and int are 32 bits). | ||
* Use size_t for unsigned number of bytes variables, ptrdiff_t for signed pointer subtraction results. In particular, do not use uintN, which is just shorthand for unsigned int, and so may not be big enough. | * Use size_t for unsigned number of bytes variables, ptrdiff_t for signed pointer subtraction results. In particular, do not use uintN, which is just shorthand for unsigned int, and so may not be big enough. |
Revision as of 22:09, 15 January 2006
Functions
- Public function names begin with JS_ followed by capitalized "intercaps", e.g. JS_NewObject.
- Extern but library-private function names use a js_ prefix and mixed case, e.g. js_SearchScope.
- Most static function names have unprefixed, mixed-case names: GetChar.
- But static native methods of JS objects have lowercase, underscore-separated or intercaps names, e.g., str_indexOf.
- Function return types are on a separate line preceding the function name.
void DoThis() { // bad ... } void DoThis() { // OK ... }
Other Symbols
- Library-private and static data use underscores, not intercaps (but library-private data do use a js_ prefix).
- Scalar type names are lowercase and js-prefixed: jsdouble.
- Aggregate type names are JS-prefixed and mixed-case: JSObject.
- Macros are generally ALL_CAPS and underscored, to call out potential side effects, multiple uses of a formal argument, etc.
Tabs and Spaces
- Do not add tabs to source files (expand them at 8-space stops if they creep back in).
- Observe the 80-column limit per line, and break down lines that are too long.
- Four spaces of indentation per statement nesting level.
- "case L:" labels in "switch" statements count as half of a nesting level, so indent two spaces, with the labeled statements indenting two more for a standard four spaces indentation from "switch" to a case-controlled statement.
switch (discriminant) { case L1: DoSomething(); . . . }
- Exception: for switches with every case labeling a trivially-short statement it's ok to put the case, the statement, and the break; all on one line.
- Comment /* FALL THROUGH */ in place of missing break when intentionally falling through from one case-controlled statement sequence into another, or into the default statements.
- Do not use spaces between a function name and its arguments list, or between an array name and the square bracket. Also, do no use spaces after a bracket. Use a space after a comma to separate arguments.
JS_SetContext ( rt, cx ); // bad JS_SetContext(rt, cx); // OK
- Use a space between a C keyword and parentheses.
if(condition) // bad if (condition) // OK
Indentation and Bracing
- Function arguments that overflow the first line of the call expression should be aligned to underhang the first argument (to start in overflow lines in the column after the opening parenthesis).
JS_SetContext(rt, // bad cx); JS_SetContext(rt, // OK cx);
- An opening brace is placed on the same line as the preceding statement.
if (condition) // bad { } if (condition) { // OK }
- Do not put compound statements in one line. Indent the controlled statement on the next line, for clarity and break-pointing.
if (condition) break; // bad if (condition) // OK break;
- If a statement or condition covers multiple lines, use braces for all the controlled statements (even if the else part fits on one line, brace it too).
if (condition) // bad CallThisMethod(argument1, argument2); if (condition) { // OK CallThisMethod(argument1, argument2); }
Control Flow
- Minimize indentation using return, break, and continue where appropriate. Prefer return (break, continue) statements to cast out abnormal cases, instead of nesting "if/else" statements and indenting the common cases.
void MyFunction(int n) { if (n) { // bad ... } } void MyFunction(int n) { if(!n) return; // OK ... }
- If an "if" statement controls a "then" clause ending in a return statement, do not use "else" after return.
if (condition) { // bad DoThis(); return; } else DoThat(); if (condition) { // OK DoThis(); return; } DoThat();
- Avoid similar arbitrary patterns and non-sequiturs:
if (condition) { // bad DoThis(); DoThat(); } else { CleanUp(); return; } DoTheOther(); if (!condition) { // OK CleanUp(); return; } DoThis(); DoThat(); DoTheOther();
Comments
- Always use C style comments. Never use C++ style comments.
- Terminate a comment with a period (so try to make comments be complete sentences).
/* This is a good comment. */
- Align multiline comments with any indentation, and start every line with an asterisk. Asterisks stack in the same column. Precede the multiline comment with one empty line unless the prior line ends in a left brace. The first line of the comment contains only leading space followed by
/*
. Multiline comments should also be bracketed.
if (condition) { /* * This is a lengthy * multiline comment. */ DoYourStuff(); }
Entry Points and Callbacks
- DLL entry points have their return type expanded within a JS_PUBLIC_API() macro call, to get the right Windows secret type qualifiers in the right places for all build variants.
- Callback functions that might be called from a DLL are similarly macroized with JS_STATIC_DLL_CALLBACK (if the function otherwise would be static to hide its name) or JS_DLL_CALLBACK (this macro takes no type argument; it should be used after the return type and before the function name).
Data Types and Alignments
- As with all Mozilla code, SpiderMonkey needs to compile and execute correctly on many platforms, including 64-bits systems.
- JS and NSPR have common roots in the dawn of time (Netscape 2), and the
JS_THREADSAFE
mode of building SpiderMonkey depends on NSPR, so reading the NSPR documentation is well worth your while. - Not all 64-bit systems use the same integer type model: some are "LP64" (long and pointer are 64 bits, int is 32 bits), while others are "LLP64" (only long long and pointer are 64 bits; long and int are 32 bits).
- Use size_t for unsigned number of bytes variables, ptrdiff_t for signed pointer subtraction results. In particular, do not use uintN, which is just shorthand for unsigned int, and so may not be big enough.