template<typename Tok> JS::Result<ParseNode*> BinASTParser<Tok>::parseAux(const uint8_t* start, const size_t length) { tokenizer_.emplace(cx_, start, length); Directives directives(options().strictOption); GlobalSharedContext globalsc(cx_, ScopeKind::Global, directives, options().extraWarningsOption); BinParseContext globalpc(cx_, this, &globalsc, /* newDirectives = */ nullptr); if (!globalpc.init()) return cx_->alreadyReportedError(); ParseContext::VarScope varScope(cx_, &globalpc, usedNames_); if (!varScope.init(&globalpc)) return cx_->alreadyReportedError(); MOZ_TRY(tokenizer_->readHeader()); ParseNode* result(nullptr); MOZ_TRY_VAR(result, parseProgram()); Maybe<GlobalScope::Data*> bindings = NewGlobalScopeData(cx_, varScope, alloc_, parseContext_); if (!bindings) return cx_->alreadyReportedError(); globalsc.bindings = *bindings; return result; // Magic conversion to Ok. }
// Qualifiers are known to be appropriate for 'class' void Parser::classDefinition(int /*flags*/, Qualifier* qual) { // FIXME: pick up the methods plus all other flags somehow, these are available from the binding ribs // Maybe time to package them up conveniently (FunctionDefinition needs it too). eat(T_Class); Str* name = identifier(); Str* extends = NULL; SeqBuilder<Str*> implements(allocator); if (match(T_Extends)) { extends = identifier(); } if (match(T_Implements)) { do { implements.addAtEnd(identifier()); } while (match(T_Comma)); } eat(T_LeftBrace); pushBindingRib(RIB_Class); pushBindingRib(RIB_Instance); Seq<Stmt*>* instance_init = NULL; Seq<Stmt*>* class_init = directives(SFLAG_Class, &instance_init); popBindingRib(); popBindingRib(); eat(T_RightBrace); addClass(ALLOC(ClassDefn, (qual, name, extends, implements.get(), class_init, instance_init))); }
bool max_age_from_cache_control(const std::string& cache_control, S32 *max_age) { // Split the string on "," to get a list of directives typedef boost::tokenizer<boost::char_separator<char> > tokenizer; tokenizer directives(cache_control, COMMA_SEPARATOR); tokenizer::iterator token_it = directives.begin(); for ( ; token_it != directives.end(); ++token_it) { // Tokens may have leading or trailing whitespace std::string token = *token_it; LLStringUtil::trim(token); if (token.compare(0, MAX_AGE.size(), MAX_AGE) == 0) { // ...this token starts with max-age, so let's chop it up by "=" tokenizer subtokens(token, EQUALS_SEPARATOR); tokenizer::iterator subtoken_it = subtokens.begin(); // Must have a token if (subtoken_it == subtokens.end()) return false; std::string subtoken = *subtoken_it; // Must exactly equal "max-age" LLStringUtil::trim(subtoken); if (subtoken != MAX_AGE) return false; // Must have another token ++subtoken_it; if (subtoken_it == subtokens.end()) return false; subtoken = *subtoken_it; // Must be a valid integer // *NOTE: atoi() returns 0 for invalid values, so we have to // check the string first. // *TODO: Do servers ever send "0000" for zero? We don't handle it LLStringUtil::trim(subtoken); if (subtoken == "0") { *max_age = 0; return true; } S32 val = atoi( subtoken.c_str() ); if (val > 0 && val < S32_MAX) { *max_age = val; return true; } return false; } } return false; }
void Parser::interfaceDefinition(int /*flags*/, Qualifier* qual) { // FIXME: pick up the methods somehow, these are available from the binding ribs eat(T_Interface); Str* name = identifier(); SeqBuilder<Str*> extends(allocator); if (match(T_Extends)) { do { extends.addAtEnd(identifier()); } while (match(T_Comma)); } eat(T_LeftBrace); pushBindingRib(RIB_Instance); directives(SFLAG_Interface); popBindingRib(); eat(T_RightBrace); addInterface(ALLOC(InterfaceDefn, (qual, name, extends.get()))); }