Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(92)

Side by Side Diff: src/compiler.cc

Issue 164470: Merge JSON fix to 1.2 branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/1.2/
Patch Set: Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/compiler.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 return Handle<Code>::null(); 78 return Handle<Code>::null();
79 } 79 }
80 80
81 // Generate code and return it. 81 // Generate code and return it.
82 Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval); 82 Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval);
83 return result; 83 return result;
84 } 84 }
85 85
86 86
87 static bool IsValidJSON(FunctionLiteral* lit) { 87 static bool IsValidJSON(FunctionLiteral* lit) {
88 if (!lit->body()->length() == 1) 88 if (lit->body()->length() != 1)
89 return false; 89 return false;
90 Statement* stmt = lit->body()->at(0); 90 Statement* stmt = lit->body()->at(0);
91 if (stmt->AsExpressionStatement() == NULL) 91 if (stmt->AsExpressionStatement() == NULL)
92 return false; 92 return false;
93 Expression* expr = stmt->AsExpressionStatement()->expression(); 93 Expression* expr = stmt->AsExpressionStatement()->expression();
94 return expr->IsValidJSON(); 94 return expr->IsValidJSON();
95 } 95 }
96 96
97 97
98 static Handle<JSFunction> MakeFunction(bool is_global, 98 static Handle<JSFunction> MakeFunction(bool is_global,
99 bool is_eval, 99 bool is_eval,
100 bool is_json, 100 Compiler::ValidationState validate,
101 Handle<Script> script, 101 Handle<Script> script,
102 Handle<Context> context, 102 Handle<Context> context,
103 v8::Extension* extension, 103 v8::Extension* extension,
104 ScriptDataImpl* pre_data) { 104 ScriptDataImpl* pre_data) {
105 CompilationZoneScope zone_scope(DELETE_ON_EXIT); 105 CompilationZoneScope zone_scope(DELETE_ON_EXIT);
106 106
107 // Make sure we have an initial stack limit. 107 // Make sure we have an initial stack limit.
108 StackGuard guard; 108 StackGuard guard;
109 PostponeInterruptsScope postpone; 109 PostponeInterruptsScope postpone;
110 110
111 ASSERT(!i::Top::global_context().is_null()); 111 ASSERT(!i::Top::global_context().is_null());
112 script->set_context_data((*i::Top::global_context())->data()); 112 script->set_context_data((*i::Top::global_context())->data());
113 113
114 #ifdef ENABLE_DEBUGGER_SUPPORT 114 #ifdef ENABLE_DEBUGGER_SUPPORT
115 bool is_json = (validate == Compiler::VALIDATE_JSON);
115 if (is_eval || is_json) { 116 if (is_eval || is_json) {
116 script->set_compilation_type( 117 script->set_compilation_type(
117 is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) : 118 is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) :
118 Smi::FromInt(Script::COMPILATION_TYPE_EVAL)); 119 Smi::FromInt(Script::COMPILATION_TYPE_EVAL));
119 // For eval scripts add information on the function from which eval was 120 // For eval scripts add information on the function from which eval was
120 // called. 121 // called.
121 if (is_eval) { 122 if (is_eval) {
122 JavaScriptFrameIterator it; 123 JavaScriptFrameIterator it;
123 script->set_eval_from_function(it.frame()->function()); 124 script->set_eval_from_function(it.frame()->function());
124 int offset = it.frame()->pc() - it.frame()->code()->instruction_start(); 125 int offset = it.frame()->pc() - it.frame()->code()->instruction_start();
(...skipping 13 matching lines...) Expand all
138 139
139 // Check for parse errors. 140 // Check for parse errors.
140 if (lit == NULL) { 141 if (lit == NULL) {
141 ASSERT(Top::has_pending_exception()); 142 ASSERT(Top::has_pending_exception());
142 return Handle<JSFunction>::null(); 143 return Handle<JSFunction>::null();
143 } 144 }
144 145
145 // When parsing JSON we do an ordinary parse and then afterwards 146 // When parsing JSON we do an ordinary parse and then afterwards
146 // check the AST to ensure it was well-formed. If not we give a 147 // check the AST to ensure it was well-formed. If not we give a
147 // syntax error. 148 // syntax error.
148 if (is_json && !IsValidJSON(lit)) { 149 if (validate == Compiler::VALIDATE_JSON && !IsValidJSON(lit)) {
149 HandleScope scope; 150 HandleScope scope;
150 Handle<JSArray> args = Factory::NewJSArray(1); 151 Handle<JSArray> args = Factory::NewJSArray(1);
151 Handle<Object> source(script->source()); 152 Handle<Object> source(script->source());
152 SetElement(args, 0, source); 153 SetElement(args, 0, source);
153 Handle<Object> result = Factory::NewSyntaxError("invalid_json", args); 154 Handle<Object> result = Factory::NewSyntaxError("invalid_json", args);
154 Top::Throw(*result, NULL); 155 Top::Throw(*result, NULL);
155 return Handle<JSFunction>::null(); 156 return Handle<JSFunction>::null();
156 } 157 }
157 158
158 // Measure how long it takes to do the compilation; only take the 159 // Measure how long it takes to do the compilation; only take the
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 Handle<Script> script = Factory::NewScript(source); 259 Handle<Script> script = Factory::NewScript(source);
259 if (!script_name.is_null()) { 260 if (!script_name.is_null()) {
260 script->set_name(*script_name); 261 script->set_name(*script_name);
261 script->set_line_offset(Smi::FromInt(line_offset)); 262 script->set_line_offset(Smi::FromInt(line_offset));
262 script->set_column_offset(Smi::FromInt(column_offset)); 263 script->set_column_offset(Smi::FromInt(column_offset));
263 } 264 }
264 265
265 // Compile the function and add it to the cache. 266 // Compile the function and add it to the cache.
266 result = MakeFunction(true, 267 result = MakeFunction(true,
267 false, 268 false,
268 false, 269 DONT_VALIDATE_JSON,
269 script, 270 script,
270 Handle<Context>::null(), 271 Handle<Context>::null(),
271 extension, 272 extension,
272 pre_data); 273 pre_data);
273 if (extension == NULL && !result.is_null()) { 274 if (extension == NULL && !result.is_null()) {
274 CompilationCache::PutScript(source, result); 275 CompilationCache::PutScript(source, result);
275 } 276 }
276 277
277 // Get rid of the pre-parsing data (if necessary). 278 // Get rid of the pre-parsing data (if necessary).
278 if (input_pre_data == NULL && pre_data != NULL) { 279 if (input_pre_data == NULL && pre_data != NULL) {
279 delete pre_data; 280 delete pre_data;
280 } 281 }
281 } 282 }
282 283
283 if (result.is_null()) Top::ReportPendingMessages(); 284 if (result.is_null()) Top::ReportPendingMessages();
284 return result; 285 return result;
285 } 286 }
286 287
287 288
288 Handle<JSFunction> Compiler::CompileEval(Handle<String> source, 289 Handle<JSFunction> Compiler::CompileEval(Handle<String> source,
289 Handle<Context> context, 290 Handle<Context> context,
290 bool is_global, 291 bool is_global,
291 bool is_json) { 292 ValidationState validate) {
293 // Note that if validation is required then no path through this
294 // function is allowed to return a value without validating that
295 // the input is legal json.
296
292 int source_length = source->length(); 297 int source_length = source->length();
293 Counters::total_eval_size.Increment(source_length); 298 Counters::total_eval_size.Increment(source_length);
294 Counters::total_compile_size.Increment(source_length); 299 Counters::total_compile_size.Increment(source_length);
295 300
296 // The VM is in the COMPILER state until exiting this function. 301 // The VM is in the COMPILER state until exiting this function.
297 VMState state(COMPILER); 302 VMState state(COMPILER);
298 303
299 // Do a lookup in the compilation cache; if the entry is not there, 304 // Do a lookup in the compilation cache; if the entry is not there,
300 // invoke the compiler and add the result to the cache. 305 // invoke the compiler and add the result to the cache. If we're
301 Handle<JSFunction> result = 306 // evaluating json we bypass the cache since we can't be sure a
302 CompilationCache::LookupEval(source, context, is_global); 307 // potential value in the cache has been validated.
308 Handle<JSFunction> result;
309 if (validate == DONT_VALIDATE_JSON)
310 result = CompilationCache::LookupEval(source, context, is_global);
311
303 if (result.is_null()) { 312 if (result.is_null()) {
304 // Create a script object describing the script to be compiled. 313 // Create a script object describing the script to be compiled.
305 Handle<Script> script = Factory::NewScript(source); 314 Handle<Script> script = Factory::NewScript(source);
306 result = MakeFunction(is_global, 315 result = MakeFunction(is_global,
307 true, 316 true,
308 is_json, 317 validate,
309 script, 318 script,
310 context, 319 context,
311 NULL, 320 NULL,
312 NULL); 321 NULL);
313 if (!result.is_null()) { 322 if (!result.is_null() && validate != VALIDATE_JSON) {
323 // For json it's unlikely that we'll ever see exactly the same
324 // string again so we don't use the compilation cache.
314 CompilationCache::PutEval(source, context, is_global, result); 325 CompilationCache::PutEval(source, context, is_global, result);
315 } 326 }
316 } 327 }
317 328
318 return result; 329 return result;
319 } 330 }
320 331
321 332
322 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared, 333 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared,
323 int loop_nesting) { 334 int loop_nesting) {
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 // Set the expected number of properties for instances. 411 // Set the expected number of properties for instances.
401 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); 412 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count());
402 413
403 // Check the function has compiled code. 414 // Check the function has compiled code.
404 ASSERT(shared->is_compiled()); 415 ASSERT(shared->is_compiled());
405 return true; 416 return true;
406 } 417 }
407 418
408 419
409 } } // namespace v8::internal 420 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/compiler.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698