La fase di preprocessamento del motore V8 di Chrome viene gestita dalla classe PreParser
. Uno dei file principali di questo componente si trova nella directory /v8/src/
del codice sorgente di Chromium ed è chiamato preparser.cc
. Questa classe ha il compito di riconoscere e separare i token di input che saranno gestiti successivamente dal processore JavaScript. Per esempio un compito del preprocessore JavaScript è quello di riconoscere le asserzioni JavaScript. V8 lo fa nel modo seguente:
PreParser::SourceElements PreParser::ParseSourceElements(int end_token,
bool* ok) {
// SourceElements ::
// (Statement)* <end_token>
while (peek() != end_token) {
ParseStatement(CHECK_OK);
}
return kUnknownSourceElements;
}
Il metodo PreParser::ParseStatement()
, che esegue il preprocessamento delle asserzioni JavaScript, viene definito come segue:
PreParser::Statement PreParser::ParseStatement(bool* ok) {
// Statement ::
// Block
// VariableStatement
// EmptyStatement
// ExpressionStatement
// IfStatement
// IterationStatement
// ContinueStatement
// BreakStatement
// ReturnStatement
// WithStatement
// LabelledStatement
// SwitchStatement
// ThrowStatement
// TryStatement
// DebuggerStatement
// Note: Since labels can only be used by 'break' and 'continue'
// statements, which themselves are only valid within blocks,
// iterations or 'switch' statements (i.e., BreakableStatements),
// labels can be simply ignored in all other cases; except for
// trivial labeled break statements 'label: break label' which is
// parsed into an empty statement.
// Keep the source position of the statement
switch (peek()) {
case i::Token::LBRACE:
return ParseBlock(ok);
case i::Token::CONST:
case i::Token::VAR:
return ParseVariableStatement(ok);
case i::Token::SEMICOLON:
Next();
return kUnknownStatement;
case i::Token::IF:
return ParseIfStatement(ok);
case i::Token::DO:
return ParseDoWhileStatement(ok);
case i::Token::WHILE:
return ParseWhileStatement(ok);
case i::Token::FOR:
return ParseForStatement(ok);
case i::Token::CONTINUE:
return ParseContinueStatement(ok);
case i::Token::BREAK:
return ParseBreakStatement(ok);
case i::Token::RETURN:
return ParseReturnStatement(ok);
case i::Token::WITH:
return ParseWithStatement(ok);
case i::Token::SWITCH:
return ParseSwitchStatement(ok);
case i::Token::THROW:
return ParseThrowStatement(ok);
case i::Token::TRY:
return ParseTryStatement(ok);
case i::Token::FUNCTION:
return ParseFunctionDeclaration(ok);
case i::Token::NATIVE:
return ParseNativeDeclaration(ok);
case i::Token::DEBUGGER:
return ParseDebuggerStatement(ok);
default:
return ParseExpressionOrLabelledStatement(ok);
}
}
Come si può notare, questo metodo esegue una verifica sequenziale usando un costrutto switch
. Per ciascun valore, che corrisponde ad un differente token di input, viene chiamato un metodo corrispondente per ogni token a seconda del tipo di asserzione JavaScript incontrato. Si noti come il costrutto switch
utilizzi un'istruzione return
per ciascun blocco case
cosicchè l'istruzione break
non è necessaria.