| OLD | NEW |
| 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 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 } | 95 } |
| 96 } | 96 } |
| 97 | 97 |
| 98 // Generate code and return it. | 98 // Generate code and return it. |
| 99 Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval); | 99 Handle<Code> result = CodeGenerator::MakeCode(literal, script, is_eval); |
| 100 return result; | 100 return result; |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 static bool IsValidJSON(FunctionLiteral* lit) { | 104 static bool IsValidJSON(FunctionLiteral* lit) { |
| 105 if (!lit->body()->length() == 1) | 105 if (lit->body()->length() != 1) |
| 106 return false; | 106 return false; |
| 107 Statement* stmt = lit->body()->at(0); | 107 Statement* stmt = lit->body()->at(0); |
| 108 if (stmt->AsExpressionStatement() == NULL) | 108 if (stmt->AsExpressionStatement() == NULL) |
| 109 return false; | 109 return false; |
| 110 Expression* expr = stmt->AsExpressionStatement()->expression(); | 110 Expression* expr = stmt->AsExpressionStatement()->expression(); |
| 111 return expr->IsValidJSON(); | 111 return expr->IsValidJSON(); |
| 112 } | 112 } |
| 113 | 113 |
| 114 | 114 |
| 115 static Handle<JSFunction> MakeFunction(bool is_global, | 115 static Handle<JSFunction> MakeFunction(bool is_global, |
| 116 bool is_eval, | 116 bool is_eval, |
| 117 bool is_json, | 117 Compiler::ValidationState validate, |
| 118 Handle<Script> script, | 118 Handle<Script> script, |
| 119 Handle<Context> context, | 119 Handle<Context> context, |
| 120 v8::Extension* extension, | 120 v8::Extension* extension, |
| 121 ScriptDataImpl* pre_data) { | 121 ScriptDataImpl* pre_data) { |
| 122 CompilationZoneScope zone_scope(DELETE_ON_EXIT); | 122 CompilationZoneScope zone_scope(DELETE_ON_EXIT); |
| 123 | 123 |
| 124 // Make sure we have an initial stack limit. | 124 // Make sure we have an initial stack limit. |
| 125 StackGuard guard; | 125 StackGuard guard; |
| 126 PostponeInterruptsScope postpone; | 126 PostponeInterruptsScope postpone; |
| 127 | 127 |
| 128 ASSERT(!i::Top::global_context().is_null()); | 128 ASSERT(!i::Top::global_context().is_null()); |
| 129 script->set_context_data((*i::Top::global_context())->data()); | 129 script->set_context_data((*i::Top::global_context())->data()); |
| 130 | 130 |
| 131 #ifdef ENABLE_DEBUGGER_SUPPORT | 131 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 132 bool is_json = (validate == Compiler::VALIDATE_JSON); |
| 132 if (is_eval || is_json) { | 133 if (is_eval || is_json) { |
| 133 script->set_compilation_type( | 134 script->set_compilation_type( |
| 134 is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) : | 135 is_json ? Smi::FromInt(Script::COMPILATION_TYPE_JSON) : |
| 135 Smi::FromInt(Script::COMPILATION_TYPE_EVAL)); | 136 Smi::FromInt(Script::COMPILATION_TYPE_EVAL)); |
| 136 // For eval scripts add information on the function from which eval was | 137 // For eval scripts add information on the function from which eval was |
| 137 // called. | 138 // called. |
| 138 if (is_eval) { | 139 if (is_eval) { |
| 139 JavaScriptFrameIterator it; | 140 JavaScriptFrameIterator it; |
| 140 script->set_eval_from_function(it.frame()->function()); | 141 script->set_eval_from_function(it.frame()->function()); |
| 141 int offset = it.frame()->pc() - it.frame()->code()->instruction_start(); | 142 int offset = it.frame()->pc() - it.frame()->code()->instruction_start(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 155 | 156 |
| 156 // Check for parse errors. | 157 // Check for parse errors. |
| 157 if (lit == NULL) { | 158 if (lit == NULL) { |
| 158 ASSERT(Top::has_pending_exception()); | 159 ASSERT(Top::has_pending_exception()); |
| 159 return Handle<JSFunction>::null(); | 160 return Handle<JSFunction>::null(); |
| 160 } | 161 } |
| 161 | 162 |
| 162 // When parsing JSON we do an ordinary parse and then afterwards | 163 // When parsing JSON we do an ordinary parse and then afterwards |
| 163 // check the AST to ensure it was well-formed. If not we give a | 164 // check the AST to ensure it was well-formed. If not we give a |
| 164 // syntax error. | 165 // syntax error. |
| 165 if (is_json && !IsValidJSON(lit)) { | 166 if (validate == Compiler::VALIDATE_JSON && !IsValidJSON(lit)) { |
| 166 HandleScope scope; | 167 HandleScope scope; |
| 167 Handle<JSArray> args = Factory::NewJSArray(1); | 168 Handle<JSArray> args = Factory::NewJSArray(1); |
| 168 Handle<Object> source(script->source()); | 169 Handle<Object> source(script->source()); |
| 169 SetElement(args, 0, source); | 170 SetElement(args, 0, source); |
| 170 Handle<Object> result = Factory::NewSyntaxError("invalid_json", args); | 171 Handle<Object> result = Factory::NewSyntaxError("invalid_json", args); |
| 171 Top::Throw(*result, NULL); | 172 Top::Throw(*result, NULL); |
| 172 return Handle<JSFunction>::null(); | 173 return Handle<JSFunction>::null(); |
| 173 } | 174 } |
| 174 | 175 |
| 175 // Measure how long it takes to do the compilation; only take the | 176 // Measure how long it takes to do the compilation; only take the |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 275 Handle<Script> script = Factory::NewScript(source); | 276 Handle<Script> script = Factory::NewScript(source); |
| 276 if (!script_name.is_null()) { | 277 if (!script_name.is_null()) { |
| 277 script->set_name(*script_name); | 278 script->set_name(*script_name); |
| 278 script->set_line_offset(Smi::FromInt(line_offset)); | 279 script->set_line_offset(Smi::FromInt(line_offset)); |
| 279 script->set_column_offset(Smi::FromInt(column_offset)); | 280 script->set_column_offset(Smi::FromInt(column_offset)); |
| 280 } | 281 } |
| 281 | 282 |
| 282 // Compile the function and add it to the cache. | 283 // Compile the function and add it to the cache. |
| 283 result = MakeFunction(true, | 284 result = MakeFunction(true, |
| 284 false, | 285 false, |
| 285 false, | 286 DONT_VALIDATE_JSON, |
| 286 script, | 287 script, |
| 287 Handle<Context>::null(), | 288 Handle<Context>::null(), |
| 288 extension, | 289 extension, |
| 289 pre_data); | 290 pre_data); |
| 290 if (extension == NULL && !result.is_null()) { | 291 if (extension == NULL && !result.is_null()) { |
| 291 CompilationCache::PutScript(source, result); | 292 CompilationCache::PutScript(source, result); |
| 292 } | 293 } |
| 293 | 294 |
| 294 // Get rid of the pre-parsing data (if necessary). | 295 // Get rid of the pre-parsing data (if necessary). |
| 295 if (input_pre_data == NULL && pre_data != NULL) { | 296 if (input_pre_data == NULL && pre_data != NULL) { |
| 296 delete pre_data; | 297 delete pre_data; |
| 297 } | 298 } |
| 298 } | 299 } |
| 299 | 300 |
| 300 if (result.is_null()) Top::ReportPendingMessages(); | 301 if (result.is_null()) Top::ReportPendingMessages(); |
| 301 return result; | 302 return result; |
| 302 } | 303 } |
| 303 | 304 |
| 304 | 305 |
| 305 Handle<JSFunction> Compiler::CompileEval(Handle<String> source, | 306 Handle<JSFunction> Compiler::CompileEval(Handle<String> source, |
| 306 Handle<Context> context, | 307 Handle<Context> context, |
| 307 bool is_global, | 308 bool is_global, |
| 308 bool is_json) { | 309 ValidationState validate) { |
| 310 // Note that if validation is required then no path through this |
| 311 // function is allowed to return a value without validating that |
| 312 // the input is legal json. |
| 313 |
| 309 int source_length = source->length(); | 314 int source_length = source->length(); |
| 310 Counters::total_eval_size.Increment(source_length); | 315 Counters::total_eval_size.Increment(source_length); |
| 311 Counters::total_compile_size.Increment(source_length); | 316 Counters::total_compile_size.Increment(source_length); |
| 312 | 317 |
| 313 // The VM is in the COMPILER state until exiting this function. | 318 // The VM is in the COMPILER state until exiting this function. |
| 314 VMState state(COMPILER); | 319 VMState state(COMPILER); |
| 315 | 320 |
| 316 // Do a lookup in the compilation cache; if the entry is not there, | 321 // Do a lookup in the compilation cache; if the entry is not there, |
| 317 // invoke the compiler and add the result to the cache. | 322 // invoke the compiler and add the result to the cache. If we're |
| 318 Handle<JSFunction> result = | 323 // evaluating json we bypass the cache since we can't be sure a |
| 319 CompilationCache::LookupEval(source, context, is_global); | 324 // potential value in the cache has been validated. |
| 325 Handle<JSFunction> result; |
| 326 if (validate == DONT_VALIDATE_JSON) |
| 327 result = CompilationCache::LookupEval(source, context, is_global); |
| 328 |
| 320 if (result.is_null()) { | 329 if (result.is_null()) { |
| 321 // Create a script object describing the script to be compiled. | 330 // Create a script object describing the script to be compiled. |
| 322 Handle<Script> script = Factory::NewScript(source); | 331 Handle<Script> script = Factory::NewScript(source); |
| 323 result = MakeFunction(is_global, | 332 result = MakeFunction(is_global, |
| 324 true, | 333 true, |
| 325 is_json, | 334 validate, |
| 326 script, | 335 script, |
| 327 context, | 336 context, |
| 328 NULL, | 337 NULL, |
| 329 NULL); | 338 NULL); |
| 330 if (!result.is_null()) { | 339 if (!result.is_null() && validate != VALIDATE_JSON) { |
| 340 // For json it's unlikely that we'll ever see exactly the same |
| 341 // string again so we don't use the compilation cache. |
| 331 CompilationCache::PutEval(source, context, is_global, result); | 342 CompilationCache::PutEval(source, context, is_global, result); |
| 332 } | 343 } |
| 333 } | 344 } |
| 334 | 345 |
| 335 return result; | 346 return result; |
| 336 } | 347 } |
| 337 | 348 |
| 338 | 349 |
| 339 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared, | 350 bool Compiler::CompileLazy(Handle<SharedFunctionInfo> shared, |
| 340 int loop_nesting) { | 351 int loop_nesting) { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 417 // Set the expected number of properties for instances. | 428 // Set the expected number of properties for instances. |
| 418 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); | 429 SetExpectedNofPropertiesFromEstimate(shared, lit->expected_property_count()); |
| 419 | 430 |
| 420 // Check the function has compiled code. | 431 // Check the function has compiled code. |
| 421 ASSERT(shared->is_compiled()); | 432 ASSERT(shared->is_compiled()); |
| 422 return true; | 433 return true; |
| 423 } | 434 } |
| 424 | 435 |
| 425 | 436 |
| 426 } } // namespace v8::internal | 437 } } // namespace v8::internal |
| OLD | NEW |