From d5fc8b25afe9adca74cc99b609bb268fc98943a4 Mon Sep 17 00:00:00 2001 From: Daniel Ehrenberg <littledan@chromium.org> Date: Mon, 5 Feb 2018 20:40:19 +0100 Subject: [PATCH] Test for change to cache templates by site, not contents (#972) * Test for change to cache templates by site, not contents These tests are against a specification change based on discussion in https://github.com/tc39/ecma262/issues/840 The tests here passed on SpiderMonkey but failed on other implementations, which implement the current specification. * Add a test that caching is by source location, not function identity * Update existing tests to reference the spec properly --- .../cache-different-functions-same-site.js | 38 +++++++++++++++++++ .../cache-differing-expressions-eval.js | 13 +++---- ...ache-differing-expressions-new-function.js | 15 ++++---- .../cache-differing-expressions.js | 12 +++--- .../cache-differing-raw-strings.js | 11 +++--- .../cache-differing-string-count.js | 11 +++--- .../cache-identical-source-eval.js | 14 +++---- .../cache-identical-source-new-function.js | 14 +++---- .../tagged-template/cache-identical-source.js | 15 ++++---- .../tagged-template/cache-realm.js | 3 +- .../cache-same-site-top-level.js | 31 +++++++++++++++ .../tagged-template/cache-same-site.js | 36 ++++++++++++++++++ 12 files changed, 159 insertions(+), 54 deletions(-) create mode 100644 test/language/expressions/tagged-template/cache-different-functions-same-site.js create mode 100644 test/language/expressions/tagged-template/cache-same-site-top-level.js create mode 100644 test/language/expressions/tagged-template/cache-same-site.js diff --git a/test/language/expressions/tagged-template/cache-different-functions-same-site.js b/test/language/expressions/tagged-template/cache-different-functions-same-site.js new file mode 100644 index 0000000000..91a554b8b1 --- /dev/null +++ b/test/language/expressions/tagged-template/cache-different-functions-same-site.js @@ -0,0 +1,38 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-gettemplateobject +description: Templates are cached by source location inside a function +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. +---*/ +function tag(templateObject) { + previousObject = templateObject; +} + +var a = 1; +var firstObject = null; +var previousObject = null; + +function factory() { + return function() { + tag`head${a}tail`; + } +} + +factory()(); +firstObject = previousObject; + +assert(firstObject !== null); +previousObject = null; + +factory()(); + +assert.sameValue( + previousObject, + firstObject, + 'The realm\'s template cache is for source code locations in a function' +); + diff --git a/test/language/expressions/tagged-template/cache-differing-expressions-eval.js b/test/language/expressions/tagged-template/cache-differing-expressions-eval.js index 1ae1f2d992..3c89f7fcda 100644 --- a/test/language/expressions/tagged-template/cache-differing-expressions-eval.js +++ b/test/language/expressions/tagged-template/cache-differing-expressions-eval.js @@ -1,13 +1,12 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 12.2.8 +esid: sec-gettemplateobject description: Template caching using distinct expressions within `eval` -info: | - Previously-created template objects should be retrieved from the internal - template registry when their source is identical but their expressions - evaluate to different values and the tagged template is being evaluated in - an `eval` context. +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. ---*/ function tag(templateObject) { previousObject = templateObject; @@ -23,4 +22,4 @@ assert(firstObject !== null); previousObject = null; eval('tag`head${b}tail`'); -assert.sameValue(previousObject, firstObject); +assert.notSameValue(previousObject, firstObject); diff --git a/test/language/expressions/tagged-template/cache-differing-expressions-new-function.js b/test/language/expressions/tagged-template/cache-differing-expressions-new-function.js index f909e9b944..35dcf4485f 100644 --- a/test/language/expressions/tagged-template/cache-differing-expressions-new-function.js +++ b/test/language/expressions/tagged-template/cache-differing-expressions-new-function.js @@ -1,13 +1,12 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 12.2.8 +esid: sec-gettemplateobject description: Template caching using distinct expressions within `new Function` -info: | - Previously-created template objects should be retrieved from the internal - template registry when their source is identical but their expressions - evaluate to different values and the tagged template is being evaluated in - an `eval` context. +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. ---*/ function tag(templateObject) { previousObject = templateObject; @@ -23,8 +22,8 @@ assert(firstObject !== null); previousObject = null; (new Function('tag', 'a', 'b', 'return tag`head${b}tail`;'))(tag, 1, 2); -assert.sameValue( +assert.notSameValue( previousObject, firstObject, - 'The realm\'s template cache is referenced when tagged templates are declared within "new Function" contexts and templated values differ' + 'The realm\'s template cache is by site, not string contents' ); diff --git a/test/language/expressions/tagged-template/cache-differing-expressions.js b/test/language/expressions/tagged-template/cache-differing-expressions.js index 17689d87df..dd0b70cc40 100644 --- a/test/language/expressions/tagged-template/cache-differing-expressions.js +++ b/test/language/expressions/tagged-template/cache-differing-expressions.js @@ -1,12 +1,12 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 12.2.8 +esid: sec-gettemplateobject description: Template caching using distinct expressions -info: | - Previously-created template objects should be retrieved from the internal - template registry when their source is identical but their expressions - evaluate to different values. +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. ---*/ function tag(templateObject) { previousObject = templateObject; @@ -22,4 +22,4 @@ assert(firstObject !== null); previousObject = null; tag`head${b}tail`; -assert.sameValue(previousObject, firstObject); +assert.notSameValue(previousObject, firstObject); diff --git a/test/language/expressions/tagged-template/cache-differing-raw-strings.js b/test/language/expressions/tagged-template/cache-differing-raw-strings.js index 7e3cbeceff..54ee21ba48 100644 --- a/test/language/expressions/tagged-template/cache-differing-raw-strings.js +++ b/test/language/expressions/tagged-template/cache-differing-raw-strings.js @@ -1,11 +1,12 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 12.2.8 -description: Templates are cached according to their "raw" representation -info: | - The internal template registry should be queried according to the "raw" - strings of the tagged template. +esid: sec-gettemplateobject +description: Templates are cached according to their site +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. ---*/ var previousObject = null; var firstObject = null; diff --git a/test/language/expressions/tagged-template/cache-differing-string-count.js b/test/language/expressions/tagged-template/cache-differing-string-count.js index 6e02a124be..bebf79b1a0 100644 --- a/test/language/expressions/tagged-template/cache-differing-string-count.js +++ b/test/language/expressions/tagged-template/cache-differing-string-count.js @@ -1,11 +1,12 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 12.2.8 -description: Templates are cached according to the number of "raw" strings -info: | - The internal template registry should be queried according to the number of - "raw" strings in the tagged template. +esid: sec-gettemplateobject +description: Templates are cached according to the site +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. ---*/ var previousObject = null; var firstObject = null; diff --git a/test/language/expressions/tagged-template/cache-identical-source-eval.js b/test/language/expressions/tagged-template/cache-identical-source-eval.js index e7e3078e64..3a2a24f2c7 100644 --- a/test/language/expressions/tagged-template/cache-identical-source-eval.js +++ b/test/language/expressions/tagged-template/cache-identical-source-eval.js @@ -1,12 +1,12 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 12.2.8 -description: Template caching using identical expressions within `eval` -info: | - Previously-created template objects should be retrieved from the internal - template registry when their source is identical and the tagged template is - being evaluated in an `eval` context. +esid: sec-gettemplateobject +description: Templates are cached by site, even using identical expressions within `eval` +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. ---*/ function tag(templateObject) { previousObject = templateObject; @@ -21,4 +21,4 @@ assert(firstObject !== null); previousObject = null; eval('tag`head${a}tail`'); -assert.sameValue(previousObject, firstObject); +assert.notSameValue(previousObject, firstObject); diff --git a/test/language/expressions/tagged-template/cache-identical-source-new-function.js b/test/language/expressions/tagged-template/cache-identical-source-new-function.js index da0393f723..01a5dd57ff 100644 --- a/test/language/expressions/tagged-template/cache-identical-source-new-function.js +++ b/test/language/expressions/tagged-template/cache-identical-source-new-function.js @@ -1,12 +1,12 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 12.2.8 -description: Template caching using identical expressions within `new Function` -info: | - Previously-created template objects should be retrieved from the internal - template registry when their source is identical and the tagged template is - being evaluated in a `new Function` context. +esid: sec-gettemplateobject +description: Template caching is by site, using identical expressions within `new Function` +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. ---*/ function tag(templateObject) { previousObject = templateObject; @@ -21,4 +21,4 @@ assert(firstObject !== null); previousObject = null; (new Function('tag', 'a', 'b', 'return tag`head${b}tail`;'))(tag, 1, 2); -assert.sameValue(previousObject, firstObject); +assert.notSameValue(previousObject, firstObject); diff --git a/test/language/expressions/tagged-template/cache-identical-source.js b/test/language/expressions/tagged-template/cache-identical-source.js index c6a5644a06..436aea6bde 100644 --- a/test/language/expressions/tagged-template/cache-identical-source.js +++ b/test/language/expressions/tagged-template/cache-identical-source.js @@ -1,11 +1,12 @@ // Copyright (C) 2014 the V8 project authors. All rights reserved. // This code is governed by the BSD license found in the LICENSE file. /*--- -es6id: 12.2.8 -description: Template caching using identical expressions -info: | - Previously-created template objects should be retrieved from the internal - template registry when their source is identical. +esid: sec-gettemplateobject +description: Templates are cached by site, even when using identical expressions +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. ---*/ function tag(templateObject) { previousObject = templateObject; @@ -20,8 +21,8 @@ assert(firstObject !== null); previousObject = null; tag`head${a}tail`; -assert.sameValue( +assert.notSameValue( previousObject, firstObject, - 'The realm\'s template cache is used when tagged templates are executed in the source code directly' + 'The realm\'s template cache is by site, not string contents' ); diff --git a/test/language/expressions/tagged-template/cache-realm.js b/test/language/expressions/tagged-template/cache-realm.js index 039d9ba171..2d185391c1 100644 --- a/test/language/expressions/tagged-template/cache-realm.js +++ b/test/language/expressions/tagged-template/cache-realm.js @@ -25,8 +25,7 @@ info: | 2. Let realm be the current Realm Record. 3. Let templateRegistry be realm.[[TemplateMap]]. 4. For each element e of templateRegistry, do - a, If e.[[Strings]] and rawStrings contain the same values in the same - order, then + a. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then i. Return e.[[Array]]. features: [cross-realm] ---*/ diff --git a/test/language/expressions/tagged-template/cache-same-site-top-level.js b/test/language/expressions/tagged-template/cache-same-site-top-level.js new file mode 100644 index 0000000000..6968f3f3c3 --- /dev/null +++ b/test/language/expressions/tagged-template/cache-same-site-top-level.js @@ -0,0 +1,31 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-gettemplateobject +description: Templates are cached by source location inside a function +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. +---*/ + +let templates = []; + +function tag(templateObject) { + templates.push(templateObject); +} + +let a = 1; +for (let i = 0; i < 2; i++) { + tag`head${a}tail`; +} + +assert.sameValue(templates.length, 2); + +assert.sameValue( + templates[0], + templates[1], + 'The realm\'s template cache is for source code locations in a top-level script' +); + + diff --git a/test/language/expressions/tagged-template/cache-same-site.js b/test/language/expressions/tagged-template/cache-same-site.js new file mode 100644 index 0000000000..ab37d62502 --- /dev/null +++ b/test/language/expressions/tagged-template/cache-same-site.js @@ -0,0 +1,36 @@ +// Copyright (C) 2017 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +esid: sec-gettemplateobject +description: Templates are cached by source location inside a function +info: > + 1. For each element _e_ of _templateRegistry_, do + 1. If _e_.[[Site]] is the same Parse Node as _templateLiteral_, then + 1. Return _e_.[[Array]]. +---*/ +function tag(templateObject) { + previousObject = templateObject; +} + +var a = 1; +var firstObject = null; +var previousObject = null; + +function runTemplate() { + tag`head${a}tail`; +} + +runTemplate(); +firstObject = previousObject; + +assert(firstObject !== null); +previousObject = null; + +runTemplate(); + +assert.sameValue( + previousObject, + firstObject, + 'The realm\'s template cache is for source code locations in a function' +); + -- GitLab