| 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |