Commit 938d88e1 authored by lrn@chromium.org's avatar lrn@chromium.org

Separate JSON parsing from the JavaScript parser.

Switch JSON parsing to creating the value directly instead of createing
code to create the value.

Review URL: http://codereview.chromium.org/4135004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5715 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a8f27144
...@@ -152,10 +152,8 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) { ...@@ -152,10 +152,8 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
script->set_context_data((*i::Top::global_context())->data()); script->set_context_data((*i::Top::global_context())->data());
#ifdef ENABLE_DEBUGGER_SUPPORT #ifdef ENABLE_DEBUGGER_SUPPORT
if (info->is_eval() || info->is_json()) { if (info->is_eval()) {
Script::CompilationType compilation_type = info->is_json() Script::CompilationType compilation_type = Script::COMPILATION_TYPE_EVAL;
? Script::COMPILATION_TYPE_JSON
: Script::COMPILATION_TYPE_EVAL;
script->set_compilation_type(Smi::FromInt(compilation_type)); script->set_compilation_type(Smi::FromInt(compilation_type));
// For eval scripts add information on the function from which eval was // For eval scripts add information on the function from which eval was
// called. // called.
...@@ -323,13 +321,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source, ...@@ -323,13 +321,7 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
Handle<Context> context, Handle<Context> context,
bool is_global, bool is_global) {
ValidationState validate) {
// Note that if validation is required then no path through this function
// is allowed to return a value without validating that the input is legal
// json.
bool is_json = (validate == VALIDATE_JSON);
int source_length = source->length(); int source_length = source->length();
Counters::total_eval_size.Increment(source_length); Counters::total_eval_size.Increment(source_length);
Counters::total_compile_size.Increment(source_length); Counters::total_compile_size.Increment(source_length);
...@@ -338,13 +330,9 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, ...@@ -338,13 +330,9 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
VMState state(COMPILER); VMState state(COMPILER);
// Do a lookup in the compilation cache; if the entry is not there, invoke // Do a lookup in the compilation cache; if the entry is not there, invoke
// the compiler and add the result to the cache. If we're evaluating json // the compiler and add the result to the cache.
// we bypass the cache since we can't be sure a potential value in the
// cache has been validated.
Handle<SharedFunctionInfo> result; Handle<SharedFunctionInfo> result;
if (!is_json) { result = CompilationCache::LookupEval(source, context, is_global);
result = CompilationCache::LookupEval(source, context, is_global);
}
if (result.is_null()) { if (result.is_null()) {
// Create a script object describing the script to be compiled. // Create a script object describing the script to be compiled.
...@@ -352,12 +340,9 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, ...@@ -352,12 +340,9 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
CompilationInfo info(script); CompilationInfo info(script);
info.MarkAsEval(); info.MarkAsEval();
if (is_global) info.MarkAsGlobal(); if (is_global) info.MarkAsGlobal();
if (is_json) info.MarkAsJson();
info.SetCallingContext(context); info.SetCallingContext(context);
result = MakeFunctionInfo(&info); result = MakeFunctionInfo(&info);
if (!result.is_null() && !is_json) { if (!result.is_null()) {
// For json it's unlikely that we'll ever see exactly the same string
// again so we don't use the compilation cache.
CompilationCache::PutEval(source, context, is_global, result); CompilationCache::PutEval(source, context, is_global, result);
} }
} }
......
...@@ -49,7 +49,6 @@ class CompilationInfo BASE_EMBEDDED { ...@@ -49,7 +49,6 @@ class CompilationInfo BASE_EMBEDDED {
bool is_lazy() const { return (flags_ & IsLazy::mask()) != 0; } bool is_lazy() const { return (flags_ & IsLazy::mask()) != 0; }
bool is_eval() const { return (flags_ & IsEval::mask()) != 0; } bool is_eval() const { return (flags_ & IsEval::mask()) != 0; }
bool is_global() const { return (flags_ & IsGlobal::mask()) != 0; } bool is_global() const { return (flags_ & IsGlobal::mask()) != 0; }
bool is_json() const { return (flags_ & IsJson::mask()) != 0; }
bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; } bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; }
FunctionLiteral* function() const { return function_; } FunctionLiteral* function() const { return function_; }
Scope* scope() const { return scope_; } Scope* scope() const { return scope_; }
...@@ -69,10 +68,6 @@ class CompilationInfo BASE_EMBEDDED { ...@@ -69,10 +68,6 @@ class CompilationInfo BASE_EMBEDDED {
ASSERT(!is_lazy()); ASSERT(!is_lazy());
flags_ |= IsGlobal::encode(true); flags_ |= IsGlobal::encode(true);
} }
void MarkAsJson() {
ASSERT(!is_lazy());
flags_ |= IsJson::encode(true);
}
void MarkAsInLoop() { void MarkAsInLoop() {
ASSERT(is_lazy()); ASSERT(is_lazy());
flags_ |= IsInLoop::encode(true); flags_ |= IsInLoop::encode(true);
...@@ -108,16 +103,15 @@ class CompilationInfo BASE_EMBEDDED { ...@@ -108,16 +103,15 @@ class CompilationInfo BASE_EMBEDDED {
// Flags that can be set for eager compilation. // Flags that can be set for eager compilation.
class IsEval: public BitField<bool, 1, 1> {}; class IsEval: public BitField<bool, 1, 1> {};
class IsGlobal: public BitField<bool, 2, 1> {}; class IsGlobal: public BitField<bool, 2, 1> {};
class IsJson: public BitField<bool, 3, 1> {};
// Flags that can be set for lazy compilation. // Flags that can be set for lazy compilation.
class IsInLoop: public BitField<bool, 4, 1> {}; class IsInLoop: public BitField<bool, 3, 1> {};
unsigned flags_; unsigned flags_;
// Fields filled in by the compilation pipeline. // Fields filled in by the compilation pipeline.
// AST filled in by the parser. // AST filled in by the parser.
FunctionLiteral* function_; FunctionLiteral* function_;
// The scope of the function literal as a convenience. Set to indidicate // The scope of the function literal as a convenience. Set to indicate
// that scopes have been analyzed. // that scopes have been analyzed.
Scope* scope_; Scope* scope_;
// The compiled code. // The compiled code.
...@@ -153,8 +147,6 @@ class CompilationInfo BASE_EMBEDDED { ...@@ -153,8 +147,6 @@ class CompilationInfo BASE_EMBEDDED {
class Compiler : public AllStatic { class Compiler : public AllStatic {
public: public:
enum ValidationState { DONT_VALIDATE_JSON, VALIDATE_JSON };
// All routines return a JSFunction. // All routines return a JSFunction.
// If an error occurs an exception is raised and // If an error occurs an exception is raised and
// the return handle contains NULL. // the return handle contains NULL.
...@@ -172,8 +164,7 @@ class Compiler : public AllStatic { ...@@ -172,8 +164,7 @@ class Compiler : public AllStatic {
// Compile a String source within a context for Eval. // Compile a String source within a context for Eval.
static Handle<SharedFunctionInfo> CompileEval(Handle<String> source, static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
Handle<Context> context, Handle<Context> context,
bool is_global, bool is_global);
ValidationState validation);
// Compile from function info (used for lazy compilation). Returns true on // Compile from function info (used for lazy compilation). Returns true on
// success and false if the compilation resulted in a stack overflow. // success and false if the compilation resulted in a stack overflow.
......
...@@ -1301,7 +1301,7 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(json_request) ...@@ -1301,7 +1301,7 @@ DebugCommandProcessor.prototype.processDebugJSONRequest = function(json_request)
try { try {
try { try {
// Convert the JSON string to an object. // Convert the JSON string to an object.
request = %CompileString('(' + json_request + ')', false)(); request = %CompileString('(' + json_request + ')')();
// Create an initial response. // Create an initial response.
response = this.createResponse(request); response = this.createResponse(request);
......
...@@ -29,8 +29,7 @@ var $JSON = global.JSON; ...@@ -29,8 +29,7 @@ var $JSON = global.JSON;
function ParseJSONUnfiltered(text) { function ParseJSONUnfiltered(text) {
var s = $String(text); var s = $String(text);
var f = %CompileString(s, true); return %ParseJson(s);
return f();
} }
function Revive(holder, name, reviver) { function Revive(holder, name, reviver) {
......
...@@ -3409,8 +3409,7 @@ class Script: public Struct { ...@@ -3409,8 +3409,7 @@ class Script: public Struct {
// Script compilation types. // Script compilation types.
enum CompilationType { enum CompilationType {
COMPILATION_TYPE_HOST = 0, COMPILATION_TYPE_HOST = 0,
COMPILATION_TYPE_EVAL = 1, COMPILATION_TYPE_EVAL = 1
COMPILATION_TYPE_JSON = 2
}; };
// [source]: the script source. // [source]: the script source.
......
This diff is collapsed.
...@@ -218,7 +218,6 @@ class Parser { ...@@ -218,7 +218,6 @@ class Parser {
FunctionLiteral* ParseProgram(Handle<String> source, FunctionLiteral* ParseProgram(Handle<String> source,
bool in_global_context); bool in_global_context);
FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info); FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info);
FunctionLiteral* ParseJson(Handle<String> source);
// The minimum number of contiguous assignment that will // The minimum number of contiguous assignment that will
// be treated as an initialization block. Benchmarks show that // be treated as an initialization block. Benchmarks show that
...@@ -411,29 +410,6 @@ class Parser { ...@@ -411,29 +410,6 @@ class Parser {
Handle<String> type, Handle<String> type,
Vector< Handle<Object> > arguments); Vector< Handle<Object> > arguments);
// JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
// specification section 15.12.1 (and appendix A.8).
// The grammar is given section 15.12.1.2 (and appendix A.8.2).
// Parse JSON input as a single JSON value.
Expression* ParseJson(bool* ok);
// Parse a single JSON value from input (grammar production JSONValue).
// A JSON value is either a (double-quoted) string literal, a number literal,
// one of "true", "false", or "null", or an object or array literal.
Expression* ParseJsonValue(bool* ok);
// Parse a JSON object literal (grammar production JSONObject).
// An object literal is a squiggly-braced and comma separated sequence
// (possibly empty) of key/value pairs, where the key is a JSON string
// literal, the value is a JSON value, and the two are spearated by a colon.
// A JavaScript object also allows numbers and identifiers as keys.
Expression* ParseJsonObject(bool* ok);
// Parses a JSON array literal (grammar production JSONArray). An array
// literal is a square-bracketed and comma separated sequence (possibly empty)
// of JSON values.
// A JavaScript array allows leaving out values from the sequence.
Expression* ParseJsonArray(bool* ok);
friend class Target; friend class Target;
friend class TargetScope; friend class TargetScope;
friend class LexicalScope; friend class LexicalScope;
...@@ -472,6 +448,49 @@ class CompileTimeValue: public AllStatic { ...@@ -472,6 +448,49 @@ class CompileTimeValue: public AllStatic {
}; };
// JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
// specification section 15.12.1 (and appendix A.8).
// The grammar is given section 15.12.1.2 (and appendix A.8.2).
class JsonParser BASE_EMBEDDED {
public:
// Parse JSON input as a single JSON value.
// Returns null handle and sets exception if parsing failed.
static Handle<Object> Parse(Handle<String> source) {
return JsonParser().ParseJson(source);
}
private:
JsonParser() { }
~JsonParser() { }
// Parse a string containing a single JSON value.
Handle<Object> ParseJson(Handle<String>);
// Parse a single JSON value from input (grammar production JSONValue).
// A JSON value is either a (double-quoted) string literal, a number literal,
// one of "true", "false", or "null", or an object or array literal.
Handle<Object> ParseJsonValue();
// Parse a JSON object literal (grammar production JSONObject).
// An object literal is a squiggly-braced and comma separated sequence
// (possibly empty) of key/value pairs, where the key is a JSON string
// literal, the value is a JSON value, and the two are separated by a colon.
// A JSON array dosn't allow numbers and identifiers as keys, like a
// JavaScript array.
Handle<Object> ParseJsonObject();
// Parses a JSON array literal (grammar production JSONArray). An array
// literal is a square-bracketed and comma separated sequence (possibly empty)
// of JSON values.
// A JSON array doesn't allow leaving out values from the sequence, nor does
// it allow a terminal comma, like a JavaScript array does.
Handle<Object> ParseJsonArray();
// Mark that a parsing error has happened at the current token, and
// return a null handle. Primarily for readability.
Handle<Object> ReportUnexpectedToken() { return Handle<Object>::null(); }
// Converts the currently parsed literal to a JavaScript String.
Handle<String> GetString();
Scanner scanner_;
};
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_PARSER_H_ #endif // V8_PARSER_H_
...@@ -7129,20 +7129,31 @@ static MaybeObject* Runtime_GlobalReceiver(Arguments args) { ...@@ -7129,20 +7129,31 @@ static MaybeObject* Runtime_GlobalReceiver(Arguments args) {
} }
static MaybeObject* Runtime_ParseJson(Arguments args) {
HandleScope scope;
ASSERT_EQ(1, args.length());
CONVERT_ARG_CHECKED(String, source, 0);
Handle<Object> result = JsonParser::Parse(source);
if (result.is_null()) {
// Syntax error or stack overflow in scanner.
ASSERT(Top::has_pending_exception());
return Failure::Exception();
}
return *result;
}
static MaybeObject* Runtime_CompileString(Arguments args) { static MaybeObject* Runtime_CompileString(Arguments args) {
HandleScope scope; HandleScope scope;
ASSERT_EQ(2, args.length()); ASSERT_EQ(1, args.length());
CONVERT_ARG_CHECKED(String, source, 0); CONVERT_ARG_CHECKED(String, source, 0);
CONVERT_ARG_CHECKED(Oddball, is_json, 1)
// Compile source string in the global context. // Compile source string in the global context.
Handle<Context> context(Top::context()->global_context()); Handle<Context> context(Top::context()->global_context());
Compiler::ValidationState validate = (is_json->IsTrue())
? Compiler::VALIDATE_JSON : Compiler::DONT_VALIDATE_JSON;
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source,
context, context,
true, true);
validate);
if (shared.is_null()) return Failure::Exception(); if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> fun = Handle<JSFunction> fun =
Factory::NewFunctionFromSharedFunctionInfo(shared, context, NOT_TENURED); Factory::NewFunctionFromSharedFunctionInfo(shared, context, NOT_TENURED);
...@@ -7157,8 +7168,7 @@ static ObjectPair CompileGlobalEval(Handle<String> source, ...@@ -7157,8 +7168,7 @@ static ObjectPair CompileGlobalEval(Handle<String> source,
Handle<SharedFunctionInfo> shared = Compiler::CompileEval( Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
source, source,
Handle<Context>(Top::context()), Handle<Context>(Top::context()),
Top::context()->IsGlobalContext(), Top::context()->IsGlobalContext());
Compiler::DONT_VALIDATE_JSON);
if (shared.is_null()) return MakePair(Failure::Exception(), NULL); if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
Handle<JSFunction> compiled = Factory::NewFunctionFromSharedFunctionInfo( Handle<JSFunction> compiled = Factory::NewFunctionFromSharedFunctionInfo(
shared, shared,
...@@ -9370,8 +9380,7 @@ static MaybeObject* Runtime_DebugEvaluate(Arguments args) { ...@@ -9370,8 +9380,7 @@ static MaybeObject* Runtime_DebugEvaluate(Arguments args) {
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
Compiler::CompileEval(function_source, Compiler::CompileEval(function_source,
context, context,
context->IsGlobalContext(), context->IsGlobalContext());
Compiler::DONT_VALIDATE_JSON);
if (shared.is_null()) return Failure::Exception(); if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> compiled_function = Handle<JSFunction> compiled_function =
Factory::NewFunctionFromSharedFunctionInfo(shared, context); Factory::NewFunctionFromSharedFunctionInfo(shared, context);
...@@ -9442,8 +9451,7 @@ static MaybeObject* Runtime_DebugEvaluateGlobal(Arguments args) { ...@@ -9442,8 +9451,7 @@ static MaybeObject* Runtime_DebugEvaluateGlobal(Arguments args) {
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
Compiler::CompileEval(source, Compiler::CompileEval(source,
context, context,
true, true);
Compiler::DONT_VALIDATE_JSON);
if (shared.is_null()) return Failure::Exception(); if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> compiled_function = Handle<JSFunction> compiled_function =
Handle<JSFunction>(Factory::NewFunctionFromSharedFunctionInfo(shared, Handle<JSFunction>(Factory::NewFunctionFromSharedFunctionInfo(shared,
......
...@@ -164,6 +164,9 @@ namespace internal { ...@@ -164,6 +164,9 @@ namespace internal {
F(RegExpConstructResult, 3, 1) \ F(RegExpConstructResult, 3, 1) \
F(RegExpCloneResult, 1, 1) \ F(RegExpCloneResult, 1, 1) \
\ \
/* JSON */ \
F(ParseJson, 1, 1) \
\
/* Strings */ \ /* Strings */ \
F(StringCharCodeAt, 2, 1) \ F(StringCharCodeAt, 2, 1) \
F(StringIndexOf, 3, 1) \ F(StringIndexOf, 3, 1) \
...@@ -222,7 +225,7 @@ namespace internal { ...@@ -222,7 +225,7 @@ namespace internal {
/* Numbers */ \ /* Numbers */ \
\ \
/* Globals */ \ /* Globals */ \
F(CompileString, 2, 1) \ F(CompileString, 1, 1) \
F(GlobalPrint, 1, 1) \ F(GlobalPrint, 1, 1) \
\ \
/* Eval */ \ /* Eval */ \
......
...@@ -296,6 +296,9 @@ class Scanner { ...@@ -296,6 +296,9 @@ class Scanner {
// Returns the next token. // Returns the next token.
Token::Value Next(); Token::Value Next();
// Returns the current token again.
Token::Value current_token() { return current_.token; }
// One token look-ahead (past the token returned by Next()). // One token look-ahead (past the token returned by Next()).
Token::Value peek() const { return next_.token; } Token::Value peek() const { return next_.token; }
......
...@@ -140,7 +140,7 @@ function GlobalEval(x) { ...@@ -140,7 +140,7 @@ function GlobalEval(x) {
'be the global object from which eval originated'); 'be the global object from which eval originated');
} }
var f = %CompileString(x, false); var f = %CompileString(x);
if (!IS_FUNCTION(f)) return f; if (!IS_FUNCTION(f)) return f;
return f.call(this); return f.call(this);
...@@ -151,7 +151,7 @@ function GlobalEval(x) { ...@@ -151,7 +151,7 @@ function GlobalEval(x) {
function GlobalExecScript(expr, lang) { function GlobalExecScript(expr, lang) {
// NOTE: We don't care about the character casing. // NOTE: We don't care about the character casing.
if (!lang || /javascript/i.test(lang)) { if (!lang || /javascript/i.test(lang)) {
var f = %CompileString(ToString(expr), false); var f = %CompileString(ToString(expr));
f.call(%GlobalReceiver(global)); f.call(%GlobalReceiver(global));
} }
return null; return null;
...@@ -1177,7 +1177,7 @@ function NewFunction(arg1) { // length == 1 ...@@ -1177,7 +1177,7 @@ function NewFunction(arg1) { // length == 1
// The call to SetNewFunctionAttributes will ensure the prototype // The call to SetNewFunctionAttributes will ensure the prototype
// property of the resulting function is enumerable (ECMA262, 15.3.5.2). // property of the resulting function is enumerable (ECMA262, 15.3.5.2).
var f = %CompileString(source, false)(); var f = %CompileString(source)();
%FunctionSetName(f, "anonymous"); %FunctionSetName(f, "anonymous");
return %SetNewFunctionAttributes(f); return %SetNewFunctionAttributes(f);
} }
......
...@@ -36,7 +36,6 @@ var current_source = ''; // Current source being compiled. ...@@ -36,7 +36,6 @@ var current_source = ''; // Current source being compiled.
var source_count = 0; // Total number of scources compiled. var source_count = 0; // Total number of scources compiled.
var host_compilations = 0; // Number of scources compiled through the API. var host_compilations = 0; // Number of scources compiled through the API.
var eval_compilations = 0; // Number of scources compiled through eval. var eval_compilations = 0; // Number of scources compiled through eval.
var json_compilations = 0; // Number of scources compiled through JSON.parse.
function compileSource(source) { function compileSource(source) {
...@@ -62,9 +61,6 @@ function listener(event, exec_state, event_data, data) { ...@@ -62,9 +61,6 @@ function listener(event, exec_state, event_data, data) {
case Debug.ScriptCompilationType.Eval: case Debug.ScriptCompilationType.Eval:
eval_compilations++; eval_compilations++;
break; break;
case Debug.ScriptCompilationType.JSON:
json_compilations++;
break;
} }
} }
...@@ -74,13 +70,6 @@ function listener(event, exec_state, event_data, data) { ...@@ -74,13 +70,6 @@ function listener(event, exec_state, event_data, data) {
// For source with 'eval' there will be compile events with substrings // For source with 'eval' there will be compile events with substrings
// as well as with with the exact source. // as well as with with the exact source.
assertTrue(current_source.indexOf(event_data.script().source()) >= 0); assertTrue(current_source.indexOf(event_data.script().source()) >= 0);
} else if (current_source.indexOf('JSON.parse') == 0) {
// For JSON the JSON source will be in parentheses.
var s = event_data.script().source();
if (s[0] == '(') {
s = s.substring(1, s.length - 2);
}
assertTrue(current_source.indexOf(s) >= 0);
} else { } else {
// For source without 'eval' there will be a compile events with the // For source without 'eval' there will be a compile events with the
// exact source. // exact source.
...@@ -113,7 +102,7 @@ source_count++; // Using eval causes additional compilation event. ...@@ -113,7 +102,7 @@ source_count++; // Using eval causes additional compilation event.
compileSource('eval("eval(\'(function(){return a;})\')")'); compileSource('eval("eval(\'(function(){return a;})\')")');
source_count += 2; // Using eval causes additional compilation event. source_count += 2; // Using eval causes additional compilation event.
compileSource('JSON.parse(\'{"a":1,"b":2}\')'); compileSource('JSON.parse(\'{"a":1,"b":2}\')');
source_count++; // Using JSON.parse causes additional compilation event. // Using JSON.parse does not causes additional compilation events.
compileSource('x=1; //@ sourceURL=myscript.js'); compileSource('x=1; //@ sourceURL=myscript.js');
// Make sure that the debug event listener was invoked. // Make sure that the debug event listener was invoked.
...@@ -123,10 +112,9 @@ assertFalse(exception, "exception in listener") ...@@ -123,10 +112,9 @@ assertFalse(exception, "exception in listener")
assertEquals(before_compile_count, after_compile_count); assertEquals(before_compile_count, after_compile_count);
// Check the actual number of events (no compilation through the API as all // Check the actual number of events (no compilation through the API as all
// source compiled through eval except for one JSON.parse call). // source compiled through eval).
assertEquals(source_count, after_compile_count); assertEquals(source_count, after_compile_count);
assertEquals(0, host_compilations); assertEquals(0, host_compilations);
assertEquals(source_count - 1, eval_compilations); assertEquals(source_count, eval_compilations);
assertEquals(1, json_compilations);
Debug.setListener(null); Debug.setListener(null);
...@@ -83,12 +83,10 @@ function testScriptMirror(f, file_name, file_lines, type, compilation_type, ...@@ -83,12 +83,10 @@ function testScriptMirror(f, file_name, file_lines, type, compilation_type,
// Test the script mirror for different functions. // Test the script mirror for different functions.
testScriptMirror(function(){}, 'mirror-script.js', 100, 2, 0); testScriptMirror(function(){}, 'mirror-script.js', 98, 2, 0);
testScriptMirror(Math.sin, 'native math.js', -1, 0, 0); testScriptMirror(Math.sin, 'native math.js', -1, 0, 0);
testScriptMirror(eval('(function(){})'), null, 1, 2, 1, '(function(){})', 87); testScriptMirror(eval('(function(){})'), null, 1, 2, 1, '(function(){})', 87);
testScriptMirror(eval('(function(){\n })'), null, 2, 2, 1, '(function(){\n })', 88); testScriptMirror(eval('(function(){\n })'), null, 2, 2, 1, '(function(){\n })', 88);
testScriptMirror(%CompileString('{"a":1,"b":2}', true), null, 1, 2, 2, '{"a":1,"b":2}');
testScriptMirror(%CompileString('{"a":1,\n "b":2}', true), null, 2, 2, 2, '{"a":1,\n "b":2}');
// Test taking slices of source. // Test taking slices of source.
var mirror = debug.MakeMirror(eval('(function(){\n 1;\n})')).script(); var mirror = debug.MakeMirror(eval('(function(){\n 1;\n})')).script();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment