Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
1 //
2 // Copyright (c) 2011 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
7 #include "Preprocessor.h"
9 #include <cassert>
10 #include <sstream>
12 #include "DiagnosticsBase.h"
13 #include "DirectiveParser.h"
14 #include "Macro.h"
15 #include "MacroExpander.h"
16 #include "Token.h"
17 #include "Tokenizer.h"
19 namespace pp
20 {
22 struct PreprocessorImpl
23 {
24 Diagnostics* diagnostics;
25 MacroSet macroSet;
26 Tokenizer tokenizer;
27 DirectiveParser directiveParser;
28 MacroExpander macroExpander;
30 PreprocessorImpl(Diagnostics* diag,
31 DirectiveHandler* directiveHandler) :
32 diagnostics(diag),
33 tokenizer(diag),
34 directiveParser(&tokenizer, ¯oSet, diag, directiveHandler),
35 macroExpander(&directiveParser, ¯oSet, diag)
36 {
37 }
38 };
40 Preprocessor::Preprocessor(Diagnostics* diagnostics,
41 DirectiveHandler* directiveHandler)
42 {
43 mImpl = new PreprocessorImpl(diagnostics, directiveHandler);
44 }
46 Preprocessor::~Preprocessor()
47 {
48 delete mImpl;
49 }
51 bool Preprocessor::init(size_t count,
52 const char* const string[],
53 const int length[])
54 {
55 static const int kGLSLVersion = 100;
57 // Add standard pre-defined macros.
58 predefineMacro("__LINE__", 0);
59 predefineMacro("__FILE__", 0);
60 predefineMacro("__VERSION__", kGLSLVersion);
61 predefineMacro("GL_ES", 1);
63 return mImpl->tokenizer.init(count, string, length);
64 }
66 void Preprocessor::predefineMacro(const char* name, int value)
67 {
68 std::ostringstream stream;
69 stream << value;
71 Token token;
72 token.type = Token::CONST_INT;
73 token.text = stream.str();
75 Macro macro;
76 macro.predefined = true;
77 macro.type = Macro::kTypeObj;
78 macro.name = name;
79 macro.replacements.push_back(token);
81 mImpl->macroSet[name] = macro;
82 }
84 void Preprocessor::lex(Token* token)
85 {
86 bool validToken = false;
87 while (!validToken)
88 {
89 mImpl->macroExpander.lex(token);
90 switch (token->type)
91 {
92 // We should not be returning internal preprocessing tokens.
93 // Convert preprocessing tokens to compiler tokens or report
94 // diagnostics.
95 case Token::PP_HASH:
96 assert(false);
97 break;
98 case Token::CONST_INT:
99 {
100 int val = 0;
101 if (!token->iValue(&val))
102 {
103 // Do not mark the token as invalid.
104 // Just emit the diagnostic and reset value to 0.
105 mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,
106 token->location, token->text);
107 token->text.assign("0");
108 }
109 validToken = true;
110 break;
111 }
112 case Token::CONST_FLOAT:
113 {
114 float val = 0;
115 if (!token->fValue(&val))
116 {
117 // Do not mark the token as invalid.
118 // Just emit the diagnostic and reset value to 0.0.
119 mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,
120 token->location, token->text);
121 token->text.assign("0.0");
122 }
123 validToken = true;
124 break;
125 }
126 case Token::PP_NUMBER:
127 mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
128 token->location, token->text);
129 break;
130 case Token::PP_OTHER:
131 mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
132 token->location, token->text);
133 break;
134 default:
135 validToken = true;
136 break;
137 }
138 }
139 }
141 } // namespace pp