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,
|
||||
empty_function, Builtins::kIllegal);
|
||||
function_function->initial_map()->set_is_callable();
|
||||
function_function->initial_map()->set_is_constructor(true);
|
||||
|
||||
{ // --- A r r a y ---
|
||||
Handle<JSFunction> array_function =
|
||||
@ -1952,7 +1951,6 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
|
||||
JSFunction::kSize, generator_function_prototype,
|
||||
Builtins::kIllegal, kUseStrictFunctionMap);
|
||||
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
|
||||
|
@ -1318,19 +1318,8 @@ Handle<JSFunction> Factory::NewFunctionFromSharedFunctionInfo(
|
||||
PretenureFlag pretenure) {
|
||||
int map_index =
|
||||
Context::FunctionMapIndex(info->language_mode(), info->kind());
|
||||
Handle<Map> initial_map(Map::cast(context->native_context()->get(map_index)));
|
||||
|
||||
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);
|
||||
Handle<Map> map(Map::cast(context->native_context()->get(map_index)));
|
||||
Handle<JSFunction> result = NewFunction(map, info, context, pretenure);
|
||||
|
||||
if (info->ic_age() != isolate()->heap()->global_ic_age()) {
|
||||
info->ResetForNewContext(isolate()->heap()->global_ic_age());
|
||||
|
@ -507,11 +507,8 @@ class Factory final {
|
||||
bool is_strict = false);
|
||||
|
||||
Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
|
||||
Handle<Map> initial_map, Handle<SharedFunctionInfo> function_info,
|
||||
Handle<Context> context, PretenureFlag pretenure = TENURED);
|
||||
|
||||
Handle<JSFunction> NewFunctionFromSharedFunctionInfo(
|
||||
Handle<SharedFunctionInfo> function_info, Handle<Context> context,
|
||||
Handle<SharedFunctionInfo> function_info,
|
||||
Handle<Context> context,
|
||||
PretenureFlag pretenure = TENURED);
|
||||
|
||||
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
|
||||
|
@ -84,11 +84,9 @@ function GeneratorFunctionConstructor(arg1) { // length == 1
|
||||
var global_proxy = %GlobalProxy(GeneratorFunctionConstructor);
|
||||
// Compile the string in the constructor and not a helper so that errors
|
||||
// appear to come from here.
|
||||
var func = %_CallFunction(global_proxy, %CompileString(source, true));
|
||||
// Set name-should-print-as-anonymous flag on the ShareFunctionInfo and
|
||||
// ensure that |func| uses correct initial map from |new.target| if
|
||||
// it's available.
|
||||
return %CompleteFunctionConstruction(func, GeneratorFunction, new.target);
|
||||
var f = %_CallFunction(global_proxy, %CompileString(source, true));
|
||||
%FunctionMarkNameShouldPrintAsAnonymous(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -1786,11 +1786,9 @@ function FunctionConstructor(arg1) { // length == 1
|
||||
var global_proxy = %GlobalProxy(FunctionConstructor);
|
||||
// Compile the string in the constructor and not a helper so that errors
|
||||
// appear to come from here.
|
||||
var func = %_CallFunction(global_proxy, %CompileString(source, true));
|
||||
// Set name-should-print-as-anonymous flag on the ShareFunctionInfo and
|
||||
// ensure that |func| uses correct initial map from |new.target| if
|
||||
// it's available.
|
||||
return %CompleteFunctionConstruction(func, GlobalFunction, new.target);
|
||||
var f = %_CallFunction(global_proxy, %CompileString(source, true));
|
||||
%FunctionMarkNameShouldPrintAsAnonymous(f);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -870,9 +870,6 @@ void JSFunction::JSFunctionPrint(std::ostream& os) { // NOLINT
|
||||
if (has_initial_map()) os << Brief(initial_map());
|
||||
os << "\n - shared_info = " << Brief(shared());
|
||||
os << "\n - name = " << Brief(shared()->name());
|
||||
if (shared()->is_generator()) {
|
||||
os << "\n - generator";
|
||||
}
|
||||
os << "\n - context = " << Brief(context());
|
||||
if (shared()->bound()) {
|
||||
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);
|
||||
DCHECK(args.length() == 3);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, func, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(Object, new_target, 2);
|
||||
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;
|
||||
DCHECK(args.length() == 1);
|
||||
CONVERT_ARG_CHECKED(JSFunction, f, 0);
|
||||
f->shared()->set_name_should_print_as_anonymous(true);
|
||||
return isolate->heap()->undefined_value();
|
||||
}
|
||||
|
||||
|
||||
|
@ -996,16 +996,24 @@ static Object* Runtime_NewObjectHelper(Isolate* isolate,
|
||||
Compiler::Compile(function, CLEAR_EXCEPTION);
|
||||
|
||||
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 =
|
||||
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 =
|
||||
isolate->factory()->NewJSObjectFromMap(initial_map, NOT_TENURED, site);
|
||||
|
||||
|
@ -236,7 +236,7 @@ namespace internal {
|
||||
F(FunctionGetName, 1, 1) \
|
||||
F(FunctionSetName, 2, 1) \
|
||||
F(FunctionNameShouldPrintAsAnonymous, 1, 1) \
|
||||
F(CompleteFunctionConstruction, 3, 1) \
|
||||
F(FunctionMarkNameShouldPrintAsAnonymous, 1, 1) \
|
||||
F(FunctionIsArrow, 1, 1) \
|
||||
F(FunctionIsConciseMethod, 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() {
|
||||
class A extends Boolean {
|
||||
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() {
|
||||
class A extends Boolean {
|
||||
constructor() {
|
||||
|
@ -10,8 +10,8 @@ try {
|
||||
new Function({toString:0,valueOf:0});
|
||||
} catch (e) {
|
||||
threw = true;
|
||||
// Ensure that the receiver during "new Function" is the undefined value.
|
||||
assertEquals(undefined, e.stack[0].getThis());
|
||||
// Ensure that the receiver during "new Function" is the global proxy.
|
||||
assertEquals(this, e.stack[0].getThis());
|
||||
}
|
||||
|
||||
assertTrue(threw);
|
||||
|
Loading…
Reference in New Issue
Block a user