Revert of [es6] Fix Function and GeneratorFunction built-ins subclassing. (patchset #4 id:80001 of https://codereview.chromium.org/1428823002/ )
Reason for revert: Buildbot failures Original issue's description: > [es6] Fix Function and GeneratorFunction built-ins subclassing. > > BUG=v8:3101, v8:3330 > LOG=Y > > Committed: https://crrev.com/99e7f872d3d0a5fb799dcbafb05537cda491314a > Cr-Commit-Position: refs/heads/master@{#31708} TBR=verwaest@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=v8:3101, v8:3330 Review URL: https://codereview.chromium.org/1413723008 Cr-Commit-Position: refs/heads/master@{#31709}
This commit is contained in:
parent
99e7f872d3
commit
2210cc84de
@ -1116,7 +1116,6 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> global_object,
|
|||||||
InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
|
InstallFunction(global, "Function", JS_FUNCTION_TYPE, JSFunction::kSize,
|
||||||
empty_function, Builtins::kIllegal);
|
empty_function, Builtins::kIllegal);
|
||||||
function_function->initial_map()->set_is_callable();
|
function_function->initial_map()->set_is_callable();
|
||||||
function_function->initial_map()->set_is_constructor(true);
|
|
||||||
|
|
||||||
{ // --- A r r a y ---
|
{ // --- A r r a y ---
|
||||||
Handle<JSFunction> array_function =
|
Handle<JSFunction> array_function =
|
||||||
@ -1952,7 +1951,6 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
|
|||||||
JSFunction::kSize, generator_function_prototype,
|
JSFunction::kSize, generator_function_prototype,
|
||||||
Builtins::kIllegal, kUseStrictFunctionMap);
|
Builtins::kIllegal, kUseStrictFunctionMap);
|
||||||
generator_function_function->initial_map()->set_is_callable();
|
generator_function_function->initial_map()->set_is_callable();
|
||||||
generator_function_function->initial_map()->set_is_constructor(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
{ // -- S e t I t e r a t o r
|
{ // -- S e t I t e r a t o r
|
||||||
|
@ -1318,19 +1318,8 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
|
|||||||
PretenureFlag pretenure) {
|
PretenureFlag pretenure) {
|
||||||
int map_index =
|
int map_index =
|
||||||
Context::FunctionMapIndex(info->language_mode(), info->kind());
|
Context::FunctionMapIndex(info->language_mode(), info->kind());
|
||||||
Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index)));
|
Handle<Map> map(Map::cast(context->native_context()->get(map_index)));
|
||||||
|
Handle<JSFunction> result = NewFunction(map, info, context, pretenure);
|
||||||
return NewFunctionFromSharedFunctionInfo(initial_map, info, context,
|
|
||||||
pretenure);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
|
|
||||||
Handle<Map> initial_map, Handle<SharedFunctionInfo> info,
|
|
||||||
Handle<Context> context, PretenureFlag pretenure) {
|
|
||||||
DCHECK_EQ(JS_FUNCTION_TYPE, initial_map->instance_type());
|
|
||||||
Handle<JSFunction> result =
|
|
||||||
NewFunction(initial_map, info, context, pretenure);
|
|
||||||
|
|
||||||
if (info->ic_age() != isolate()->heap()->global_ic_age()) {
|
if (info->ic_age() != isolate()->heap()->global_ic_age()) {
|
||||||
info->ResetForNewContext(isolate()->heap()->global_ic_age());
|
info->ResetForNewContext(isolate()->heap()->global_ic_age());
|
||||||
|
@ -507,11 +507,8 @@ class Factory final {
|
|||||||
bool is_strict = false);
|
bool is_strict = false);
|
||||||
|
|
||||||
Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
|
Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
|
||||||
Handle<Map> initial_map, Handle<SharedFunctionInfo> function_info,
|
Handle<SharedFunctionInfo> function_info,
|
||||||
Handle<Context> context, PretenureFlag pretenure = TENURED);
|
Handle<Context> context,
|
||||||
|
|
||||||
Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
|
|
||||||
Handle<SharedFunctionInfo> function_info, Handle<Context> context,
|
|
||||||
PretenureFlag pretenure = TENURED);
|
PretenureFlag pretenure = TENURED);
|
||||||
|
|
||||||
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
|
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
|
||||||
|
@ -84,11 +84,9 @@ function GeneratorFunctionConstructor(arg1) { // length == 1
|
|||||||
var global_proxy = %GlobalProxy(GeneratorFunctionConstructor);
|
var global_proxy = %GlobalProxy(GeneratorFunctionConstructor);
|
||||||
// Compile the string in the constructor and not a helper so that errors
|
// Compile the string in the constructor and not a helper so that errors
|
||||||
// appear to come from here.
|
// appear to come from here.
|
||||||
var func = %_CallFunction(global_proxy, %CompileString(source, true));
|
var f = %_CallFunction(global_proxy, %CompileString(source, true));
|
||||||
// Set name-should-print-as-anonymous flag on the ShareFunctionInfo and
|
%FunctionMarkNameShouldPrintAsAnonymous(f);
|
||||||
// ensure that |func| uses correct initial map from |new.target| if
|
return f;
|
||||||
// it's available.
|
|
||||||
return %CompleteFunctionConstruction(func, GeneratorFunction, new.target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -1786,11 +1786,9 @@ function FunctionConstructor(arg1) { // length == 1
|
|||||||
var global_proxy = %GlobalProxy(FunctionConstructor);
|
var global_proxy = %GlobalProxy(FunctionConstructor);
|
||||||
// Compile the string in the constructor and not a helper so that errors
|
// Compile the string in the constructor and not a helper so that errors
|
||||||
// appear to come from here.
|
// appear to come from here.
|
||||||
var func = %_CallFunction(global_proxy, %CompileString(source, true));
|
var f = %_CallFunction(global_proxy, %CompileString(source, true));
|
||||||
// Set name-should-print-as-anonymous flag on the ShareFunctionInfo and
|
%FunctionMarkNameShouldPrintAsAnonymous(f);
|
||||||
// ensure that |func| uses correct initial map from |new.target| if
|
return f;
|
||||||
// it's available.
|
|
||||||
return %CompleteFunctionConstruction(func, GlobalFunction, new.target);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -870,9 +870,6 @@ void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT
|
|||||||
if (has_initial_map()) os << Brief(initial_map());
|
if (has_initial_map()) os << Brief(initial_map());
|
||||||
os << "\n - shared_info = " << Brief(shared());
|
os << "\n - shared_info = " << Brief(shared());
|
||||||
os << "\n - name = " << Brief(shared()->name());
|
os << "\n - name = " << Brief(shared()->name());
|
||||||
if (shared()->is_generator()) {
|
|
||||||
os << "\n - generator";
|
|
||||||
}
|
|
||||||
os << "\n - context = " << Brief(context());
|
os << "\n - context = " << Brief(context());
|
||||||
if (shared()->bound()) {
|
if (shared()->bound()) {
|
||||||
os << "\n - bindings = " << Brief(function_bindings());
|
os << "\n - bindings = " << Brief(function_bindings());
|
||||||
|
@ -47,40 +47,12 @@ RUNTIME_FUNCTION(Runtime_FunctionNameShouldPrintAsAnonymous) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
RUNTIME_FUNCTION(Runtime_CompleteFunctionConstruction) {
|
RUNTIME_FUNCTION(Runtime_FunctionMarkNameShouldPrintAsAnonymous) {
|
||||||
SealHandleScope shs(isolate);
|
SealHandleScope shs(isolate);
|
||||||
DCHECK(args.length() == 3);
|
DCHECK(args.length() == 1);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
|
CONVERT_ARG_CHECKED(JSFunction, f, 0);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1);
|
f->shared()->set_name_should_print_as_anonymous(true);
|
||||||
CONVERT_ARG_HANDLE_CHECKED(Object, new_target, 2);
|
return isolate->heap()->undefined_value();
|
||||||
func->shared()->set_name_should_print_as_anonymous(true);
|
|
||||||
|
|
||||||
// If new.target is equal to |constructor| then the function |func| created
|
|
||||||
// is already correctly setup and nothing else should be done here.
|
|
||||||
// But if new.target is not equal to |constructor| then we are have a
|
|
||||||
// Function builtin subclassing case and therefore the function |func|
|
|
||||||
// has wrong initial map. To fix that we create a new function object with
|
|
||||||
// correct initial map.
|
|
||||||
if (new_target->IsUndefined() || *constructor == *new_target) {
|
|
||||||
return *func;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new JSFunction object with correct initial map.
|
|
||||||
HandleScope handle_scope(isolate);
|
|
||||||
Handle<JSFunction> original_constructor =
|
|
||||||
Handle<JSFunction>::cast(new_target);
|
|
||||||
|
|
||||||
DCHECK(constructor->has_initial_map());
|
|
||||||
Handle<Map> initial_map =
|
|
||||||
JSFunction::EnsureDerivedHasInitialMap(original_constructor, constructor);
|
|
||||||
|
|
||||||
Handle<SharedFunctionInfo> shared_info(func->shared(), isolate);
|
|
||||||
Handle<Context> context(func->context(), isolate);
|
|
||||||
Handle<JSFunction> result =
|
|
||||||
isolate->factory()->NewFunctionFromSharedFunctionInfo(
|
|
||||||
initial_map, shared_info, context, NOT_TENURED);
|
|
||||||
DCHECK_EQ(func->IsConstructor(), result->IsConstructor());
|
|
||||||
return *result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -996,16 +996,24 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate,
|
|||||||
Compiler::Compile(function, CLEAR_EXCEPTION);
|
Compiler::Compile(function, CLEAR_EXCEPTION);
|
||||||
|
|
||||||
JSFunction::EnsureHasInitialMap(function);
|
JSFunction::EnsureHasInitialMap(function);
|
||||||
if (function->initial_map()->instance_type() == JS_FUNCTION_TYPE) {
|
|
||||||
// The 'Function' function ignores the receiver object when
|
|
||||||
// called using 'new' and creates a new JSFunction object that
|
|
||||||
// is returned.
|
|
||||||
return isolate->heap()->undefined_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<Map> initial_map =
|
Handle<Map> initial_map =
|
||||||
JSFunction::EnsureDerivedHasInitialMap(original_function, function);
|
JSFunction::EnsureDerivedHasInitialMap(original_function, function);
|
||||||
|
|
||||||
|
if (initial_map->instance_type() == JS_FUNCTION_TYPE) {
|
||||||
|
// The 'Function' function ignores the receiver object when
|
||||||
|
// called using 'new' and creates a new JSFunction object that
|
||||||
|
// is returned. The receiver object is only used for error
|
||||||
|
// reporting if an error occurs when constructing the new
|
||||||
|
// JSFunction. Factory::NewJSObject() should not be used to
|
||||||
|
// allocate JSFunctions since it does not properly initialize
|
||||||
|
// the shared part of the function. Since the receiver is
|
||||||
|
// ignored anyway, we use the global object as the receiver
|
||||||
|
// instead of a new JSFunction object. This way, errors are
|
||||||
|
// reported the same way whether or not 'Function' is called
|
||||||
|
// using 'new'.
|
||||||
|
return isolate->global_proxy();
|
||||||
|
}
|
||||||
|
|
||||||
Handle<JSObject> result =
|
Handle<JSObject> result =
|
||||||
isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
|
isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
|
||||||
|
|
||||||
|
@ -236,7 +236,7 @@ namespace internal {
|
|||||||
F(FunctionGetName, 1, 1) \
|
F(FunctionGetName, 1, 1) \
|
||||||
F(FunctionSetName, 2, 1) \
|
F(FunctionSetName, 2, 1) \
|
||||||
F(FunctionNameShouldPrintAsAnonymous, 1, 1) \
|
F(FunctionNameShouldPrintAsAnonymous, 1, 1) \
|
||||||
F(CompleteFunctionConstruction, 3, 1) \
|
F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1) \
|
||||||
F(FunctionIsArrow, 1, 1) \
|
F(FunctionIsArrow, 1, 1) \
|
||||||
F(FunctionIsConciseMethod, 1, 1) \
|
F(FunctionIsConciseMethod, 1, 1) \
|
||||||
F(FunctionRemovePrototype, 1, 1) \
|
F(FunctionRemovePrototype, 1, 1) \
|
||||||
|
@ -17,30 +17,6 @@ function checkPrototypeChain(object, constructors) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
class A extends Function {
|
|
||||||
constructor(...args) {
|
|
||||||
assertTrue(%IsConstructCall());
|
|
||||||
super(...args);
|
|
||||||
this.a = 42;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var o = new A("this.foo = 153;");
|
|
||||||
assertTrue(o instanceof Object);
|
|
||||||
assertTrue(o instanceof Function);
|
|
||||||
assertTrue(o instanceof A);
|
|
||||||
assertEquals("function", typeof o);
|
|
||||||
checkPrototypeChain(o, [A, Function, Object]);
|
|
||||||
assertEquals(42, o.a);
|
|
||||||
var oo = new o();
|
|
||||||
assertEquals(153, oo.foo);
|
|
||||||
|
|
||||||
var o1 = new A("return 312;");
|
|
||||||
assertTrue(%HaveSameMap(o, o1));
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
class A extends Boolean {
|
class A extends Boolean {
|
||||||
constructor(...args) {
|
constructor(...args) {
|
||||||
@ -324,42 +300,6 @@ function TestArraySubclassing(array) {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
|
||||||
// TODO(ishell): remove once GeneratorFunction is available.
|
|
||||||
var GeneratorFunction = (function*() {}).__proto__.constructor;
|
|
||||||
class A extends GeneratorFunction {
|
|
||||||
constructor(...args) {
|
|
||||||
assertTrue(%IsConstructCall());
|
|
||||||
super(...args);
|
|
||||||
this.a = 42;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var generator_func = new A("var index = 0; while (index < 5) { yield ++index; }");
|
|
||||||
assertTrue(generator_func instanceof Object);
|
|
||||||
assertTrue(generator_func instanceof Function);
|
|
||||||
assertTrue(generator_func instanceof GeneratorFunction);
|
|
||||||
assertTrue(generator_func instanceof A);
|
|
||||||
assertEquals("function", typeof generator_func);
|
|
||||||
checkPrototypeChain(generator_func, [A, GeneratorFunction, Function, Object]);
|
|
||||||
assertEquals(42, generator_func.a);
|
|
||||||
|
|
||||||
var o = new generator_func();
|
|
||||||
assertTrue(o instanceof Object);
|
|
||||||
assertTrue(o instanceof generator_func);
|
|
||||||
assertEquals("object", typeof o);
|
|
||||||
|
|
||||||
assertPropertiesEqual({done: false, value: 1}, o.next());
|
|
||||||
assertPropertiesEqual({done: false, value: 2}, o.next());
|
|
||||||
assertPropertiesEqual({done: false, value: 3}, o.next());
|
|
||||||
assertPropertiesEqual({done: false, value: 4}, o.next());
|
|
||||||
assertPropertiesEqual({done: false, value: 5}, o.next());
|
|
||||||
assertPropertiesEqual({done: true, value: undefined}, o.next());
|
|
||||||
|
|
||||||
var generator_func1 = new A("return 0;");
|
|
||||||
assertTrue(%HaveSameMap(generator_func, generator_func1));
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
(function() {
|
(function() {
|
||||||
class A extends Boolean {
|
class A extends Boolean {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -10,8 +10,8 @@ try {
|
|||||||
new Function({toString:0,valueOf:0});
|
new Function({toString:0,valueOf:0});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
threw = true;
|
threw = true;
|
||||||
// Ensure that the receiver during "new Function" is the undefined value.
|
// Ensure that the receiver during "new Function" is the global proxy.
|
||||||
assertEquals(undefined, e.stack[0].getThis());
|
assertEquals(this, e.stack[0].getThis());
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(threw);
|
assertTrue(threw);
|
||||||
|
Loading…
Reference in New Issue
Block a user