Commit 08a1d1a2 authored by bmeurer's avatar bmeurer Committed by Commit bot

Revert of Add web compat workarounds for ES2015 RegExp semantics (patchset #3...

Revert of Add web compat workarounds for ES2015 RegExp semantics (patchset #3 id:40001 of https://codereview.chromium.org/1543723002/ )

Reason for revert:
Breaks nosnap: http://build.chromium.org/p/client.v8/builders/V8%20Linux%20-%20nosnap/builds/5883

Original issue's description:
> Add web compat workarounds for ES2015 RegExp semantics
>
> Unexpectedly, websites depend on doing feature testing with
> RegExp.prototype.sticky and browser testing with RegExp.prototype.toString().
> ES2015 newly throws exceptions for both of these. In order to enable shipping
> new ES2015 semantics, this patch puts in narrow workarounds for those two
> cases, keeping their old behavior. UseCounters are added for how often
> those particular cases come up, so we can see if it can be deprecated.
>
> R=yangguo
> BUG=v8:4637,v8:4617
> LOG=Y
> CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_chromium_rel_ng;tryserver.blink:linux_blink_rel
>
> Committed: https://crrev.com/98f819c3e0c92d54a306cdacadda73cf96d21b52
> Cr-Commit-Position: refs/heads/master@{#32997}

TBR=yangguo@google.com,yangguo@chromium.org,littledan@chromium.org
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=v8:4637,v8:4617

Review URL: https://codereview.chromium.org/1546493003

Cr-Commit-Position: refs/heads/master@{#32999}
parent d33b8f20
......@@ -5411,8 +5411,6 @@ class V8_EXPORT Isolate {
kSloppyMode = 8,
kStrictMode = 9,
kStrongMode = 10,
kRegExpPrototypeStickyGetter = 11,
kRegExpPrototypeToString = 12,
kUseCounterFeatureCount // This enum value must be last.
};
......
......@@ -12,7 +12,6 @@
// Imports
var GlobalRegExp = global.RegExp;
var GlobalRegExpPrototype = GlobalRegExp.prototype;
var MakeTypeError;
var regExpFlagsSymbol = utils.ImportNow("regexp_flags_symbol");
......@@ -38,17 +37,10 @@ function RegExpGetFlags() {
return result;
}
const kRegExpPrototypeStickyGetter = 11;
// ES6 21.2.5.12.
function RegExpGetSticky() {
if (!IS_REGEXP(this)) {
// Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it
// TODO(littledan): Remove this workaround or standardize it
if (this === GlobalRegExpPrototype) {
%IncrementUseCounter(kRegExpPrototypeStickyGetter);
return UNDEFINED;
}
throw MakeTypeError(kRegExpNonRegExp, "RegExp.prototype.sticky");
}
return !!REGEXP_STICKY(this);
......
......@@ -270,17 +270,8 @@ function TrimRegExp(regexp) {
}
const kRegExpPrototypeToString = 12;
function RegExpToString() {
if (!IS_REGEXP(this)) {
// RegExp.prototype.toString() returns '/(?:)/' as a compatibility fix;
// a UseCounter is incremented to track it.
// TODO(littledan): Remove this workaround or standardize it
if (this === GlobalRegExpPrototype) {
%IncrementUseCounter(kRegExpPrototypeToString);
return '/(?:)/';
}
throw MakeTypeError(kIncompatibleMethodReceiver,
'RegExp.prototype.toString', this);
}
......@@ -500,8 +491,7 @@ function RegExpGetSource() {
// -------------------------------------------------------------------
%FunctionSetInstanceClassName(GlobalRegExp, 'RegExp');
const GlobalRegExpPrototype = new GlobalObject();
%FunctionSetPrototype(GlobalRegExp, GlobalRegExpPrototype);
%FunctionSetPrototype(GlobalRegExp, new GlobalObject());
%AddNamedProperty(
GlobalRegExp.prototype, 'constructor', GlobalRegExp, DONT_ENUM);
%SetCode(GlobalRegExp, RegExpConstructor);
......
......@@ -460,14 +460,5 @@ RUNTIME_FUNCTION(Runtime_CreateListFromArrayLike) {
return *result;
}
RUNTIME_FUNCTION(Runtime_IncrementUseCounter) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_SMI_ARG_CHECKED(counter, 0);
isolate->CountUsage(static_cast<v8::Isolate::UseCounterFeature>(counter));
return isolate->heap()->undefined_value();
}
} // namespace internal
} // namespace v8
......@@ -346,8 +346,7 @@ namespace internal {
F(IncrementStatsCounter, 1, 1) \
F(ThrowConstructedNonConstructable, 1, 1) \
F(ThrowCalledNonCallable, 1, 1) \
F(CreateListFromArrayLike, 1, 1) \
F(IncrementUseCounter, 1, 1)
F(CreateListFromArrayLike, 1, 1)
#define FOR_EACH_INTRINSIC_JSON(F) \
......
......@@ -28,7 +28,6 @@
#include <cstdlib>
#include <sstream>
#include "include/v8.h"
#include "src/v8.h"
#include "src/ast/ast.h"
......@@ -1848,82 +1847,3 @@ TEST(CharacterRangeMerge) {
TEST(Graph) {
Execute("\\b\\w+\\b", false, true, true);
}
namespace {
int* global_use_counts = NULL;
void MockUseCounterCallback(v8::Isolate* isolate,
v8::Isolate::UseCounterFeature feature) {
++global_use_counts[feature];
}
}
// Test that ES2015 RegExp compatibility fixes are in place, that they
// are not overly broad, and the appropriate UseCounters are incremented
TEST(UseCountRegExp) {
i::FLAG_harmony_regexps = true;
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
LocalContext env;
int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
global_use_counts = use_counts;
CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
// Compat fix: RegExp.prototype.sticky == undefined; UseCounter tracks it
v8::Local<v8::Value> resultSticky = CompileRun("RegExp.prototype.sticky");
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
CHECK(resultSticky->IsUndefined());
// re.sticky has approriate value and doesn't touch UseCounter
v8::Local<v8::Value> resultReSticky = CompileRun("/a/.sticky");
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
CHECK(resultReSticky->IsFalse());
// When the getter is caleld on another object, throw an exception
// and don't increment the UseCounter
v8::Local<v8::Value> resultStickyError = CompileRun(
"var exception;"
"try { "
" Object.getOwnPropertyDescriptor(RegExp.prototype, 'sticky')"
" .get.call(null);"
"} catch (e) {"
" exception = e;"
"}"
"exception");
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
CHECK_EQ(0, use_counts[v8::Isolate::kRegExpPrototypeToString]);
CHECK(resultStickyError->IsObject());
// RegExp.prototype.toString() returns '/(?:)/' as a compatibility fix;
// a UseCounter is incremented to track it.
v8::Local<v8::Value> resultToString =
CompileRun("RegExp.prototype.toString().length");
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
CHECK(resultToString->IsInt32());
CHECK_EQ(6,
resultToString->Int32Value(isolate->GetCurrentContext()).FromJust());
// .toString() works on normal RegExps
v8::Local<v8::Value> resultReToString = CompileRun("/a/.toString().length");
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
CHECK(resultReToString->IsInt32());
CHECK_EQ(
3, resultReToString->Int32Value(isolate->GetCurrentContext()).FromJust());
// .toString() throws on non-RegExps that aren't RegExp.prototype
v8::Local<v8::Value> resultToStringError = CompileRun(
"var exception;"
"try { RegExp.prototype.toString.call(null) }"
"catch (e) { exception = e; }"
"exception");
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeStickyGetter]);
CHECK_EQ(1, use_counts[v8::Isolate::kRegExpPrototypeToString]);
CHECK(resultToStringError->IsObject());
}
......@@ -50,11 +50,7 @@ assertEquals(4, get_count);
function testName(name) {
if (name === "sticky") {
assertEquals(undefined, RegExp.prototype[name]);
} else {
assertThrows(() => RegExp.prototype[name], TypeError);
}
assertThrows(() => RegExp.prototype[name], TypeError);
assertEquals(
"get " + name,
Object.getOwnPropertyDescriptor(RegExp.prototype, name).get.name);
......
......@@ -114,7 +114,7 @@ PASS str.match(/d/gi).toString() is 'D,d'
PASS /\u0061/.source is '\\u0061'
PASS 'abc'.match(/\u0062/).toString() is 'b'
FAIL Object.prototype.toString.apply(RegExp.prototype) should be [object RegExp]. Was [object Object].
PASS typeof RegExp.prototype.toString() is 'string'
FAIL typeof RegExp.prototype.toString() should be string. Threw exception TypeError: Method RegExp.prototype.toString called on incompatible receiver [object Object]
PASS new RegExp().toString() is '/(?:)/'
PASS (new RegExp('(?:)')).source is '(?:)'
PASS /(?:)/.toString() is '/(?:)/'
......
......@@ -31,7 +31,7 @@ PASS RegExp('').source is "(?:)"
FAIL RegExp.prototype.source should be (?:). Threw exception TypeError: RegExp.prototype.source getter called on non-RegExp object
PASS RegExp('/').toString() is "/\\//"
PASS RegExp('').toString() is "/(?:)/"
PASS RegExp.prototype.toString() is "/(?:)/"
FAIL RegExp.prototype.toString() should be /(?:)/. Threw exception TypeError: Method RegExp.prototype.toString called on incompatible receiver [object Object]
PASS testForwardSlash("^/$", "/"); is true
PASS testForwardSlash("^/$", "/"); is true
PASS testForwardSlash("^\/$", "/"); is true
......
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