Generator objects have [[Class]] === "Generator"
Generator object maps now link to their constructors, which are created with a "Generator" class name. This does not cause a per-generator constructor property to be set. BUG=v8:2355 TEST=mjsunit/harmony/generators-objects Review URL: https://codereview.chromium.org/14262004 Patch from Andy Wingo <wingo@igalia.com>. git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14309 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
705735ce79
commit
57a7714e06
@ -553,6 +553,7 @@ static Handle<SharedFunctionInfo> MakeFunctionInfo(CompilationInfo* info) {
|
|||||||
isolate->factory()->NewSharedFunctionInfo(
|
isolate->factory()->NewSharedFunctionInfo(
|
||||||
lit->name(),
|
lit->name(),
|
||||||
lit->materialized_literal_count(),
|
lit->materialized_literal_count(),
|
||||||
|
lit->is_generator(),
|
||||||
info->code(),
|
info->code(),
|
||||||
ScopeInfo::Create(info->scope(), info->zone()));
|
ScopeInfo::Create(info->scope(), info->zone()));
|
||||||
|
|
||||||
@ -1074,6 +1075,7 @@ Handle<SharedFunctionInfo> Compiler::BuildFunctionInfo(FunctionLiteral* literal,
|
|||||||
Handle<SharedFunctionInfo> result =
|
Handle<SharedFunctionInfo> result =
|
||||||
FACTORY->NewSharedFunctionInfo(literal->name(),
|
FACTORY->NewSharedFunctionInfo(literal->name(),
|
||||||
literal->materialized_literal_count(),
|
literal->materialized_literal_count(),
|
||||||
|
literal->is_generator(),
|
||||||
info.code(),
|
info.code(),
|
||||||
scope_info);
|
scope_info);
|
||||||
SetFunctionInfo(result, literal, false, script);
|
SetFunctionInfo(result, literal, false, script);
|
||||||
|
@ -1078,6 +1078,7 @@ void Factory::SetIdentityHash(Handle<JSObject> object, Smi* hash) {
|
|||||||
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
int number_of_literals,
|
int number_of_literals,
|
||||||
|
bool is_generator,
|
||||||
Handle<Code> code,
|
Handle<Code> code,
|
||||||
Handle<ScopeInfo> scope_info) {
|
Handle<ScopeInfo> scope_info) {
|
||||||
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
|
Handle<SharedFunctionInfo> shared = NewSharedFunctionInfo(name);
|
||||||
@ -1091,6 +1092,9 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
|
|||||||
literals_array_size += JSFunction::kLiteralsPrefixSize;
|
literals_array_size += JSFunction::kLiteralsPrefixSize;
|
||||||
}
|
}
|
||||||
shared->set_num_literals(literals_array_size);
|
shared->set_num_literals(literals_array_size);
|
||||||
|
if (is_generator) {
|
||||||
|
shared->set_instance_class_name(isolate()->heap()->Generator_string());
|
||||||
|
}
|
||||||
return shared;
|
return shared;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,6 +454,7 @@ class Factory {
|
|||||||
Handle<SharedFunctionInfo> NewSharedFunctionInfo(
|
Handle<SharedFunctionInfo> NewSharedFunctionInfo(
|
||||||
Handle<String> name,
|
Handle<String> name,
|
||||||
int number_of_literals,
|
int number_of_literals,
|
||||||
|
bool is_generator,
|
||||||
Handle<Code> code,
|
Handle<Code> code,
|
||||||
Handle<ScopeInfo> scope_info);
|
Handle<ScopeInfo> scope_info);
|
||||||
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
|
Handle<SharedFunctionInfo> NewSharedFunctionInfo(Handle<String> name);
|
||||||
|
@ -39,18 +39,38 @@
|
|||||||
// http://wiki.ecmascript.org/lib/exe/fetch.php?cache=cache&media=harmony:es6_generator_object_model_3-29-13.png
|
// http://wiki.ecmascript.org/lib/exe/fetch.php?cache=cache&media=harmony:es6_generator_object_model_3-29-13.png
|
||||||
|
|
||||||
function GeneratorObjectNext() {
|
function GeneratorObjectNext() {
|
||||||
|
if (!IS_GENERATOR(this)) {
|
||||||
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
|
['[Generator].prototype.next', this]);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(wingo): Implement.
|
// TODO(wingo): Implement.
|
||||||
}
|
}
|
||||||
|
|
||||||
function GeneratorObjectSend(value) {
|
function GeneratorObjectSend(value) {
|
||||||
|
if (!IS_GENERATOR(this)) {
|
||||||
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
|
['[Generator].prototype.send', this]);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(wingo): Implement.
|
// TODO(wingo): Implement.
|
||||||
}
|
}
|
||||||
|
|
||||||
function GeneratorObjectThrow(exn) {
|
function GeneratorObjectThrow(exn) {
|
||||||
|
if (!IS_GENERATOR(this)) {
|
||||||
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
|
['[Generator].prototype.throw', this]);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(wingo): Implement.
|
// TODO(wingo): Implement.
|
||||||
}
|
}
|
||||||
|
|
||||||
function GeneratorObjectClose() {
|
function GeneratorObjectClose() {
|
||||||
|
if (!IS_GENERATOR(this)) {
|
||||||
|
throw MakeTypeError('incompatible_method_receiver',
|
||||||
|
['[Generator].prototype.close', this]);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(wingo): Implement.
|
// TODO(wingo): Implement.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4358,6 +4358,7 @@ MaybeObject* Heap::AllocateJSGeneratorObject(JSFunction *function) {
|
|||||||
MaybeObject* maybe_map = AllocateInitialMap(function);
|
MaybeObject* maybe_map = AllocateInitialMap(function);
|
||||||
if (!maybe_map->To(&map)) return maybe_map;
|
if (!maybe_map->To(&map)) return maybe_map;
|
||||||
function->set_initial_map(map);
|
function->set_initial_map(map);
|
||||||
|
map->set_constructor(function);
|
||||||
}
|
}
|
||||||
ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE);
|
ASSERT(map->instance_type() == JS_GENERATOR_OBJECT_TYPE);
|
||||||
return AllocateJSObjectFromMap(map);
|
return AllocateJSObjectFromMap(map);
|
||||||
|
@ -268,7 +268,8 @@ namespace internal {
|
|||||||
V(infinity_string, "Infinity") \
|
V(infinity_string, "Infinity") \
|
||||||
V(minus_infinity_string, "-Infinity") \
|
V(minus_infinity_string, "-Infinity") \
|
||||||
V(hidden_stack_trace_string, "v8::hidden_stack_trace") \
|
V(hidden_stack_trace_string, "v8::hidden_stack_trace") \
|
||||||
V(query_colon_string, "(?:)")
|
V(query_colon_string, "(?:)") \
|
||||||
|
V(Generator_string, "Generator")
|
||||||
|
|
||||||
// Forward declarations.
|
// Forward declarations.
|
||||||
class GCTracer;
|
class GCTracer;
|
||||||
|
@ -117,6 +117,7 @@ macro IS_SCRIPT(arg) = (%_ClassOf(arg) === 'Script');
|
|||||||
macro IS_ARGUMENTS(arg) = (%_ClassOf(arg) === 'Arguments');
|
macro IS_ARGUMENTS(arg) = (%_ClassOf(arg) === 'Arguments');
|
||||||
macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global');
|
macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global');
|
||||||
macro IS_ARRAYBUFFER(arg) = (%_ClassOf(arg) === '__ArrayBuffer');
|
macro IS_ARRAYBUFFER(arg) = (%_ClassOf(arg) === '__ArrayBuffer');
|
||||||
|
macro IS_GENERATOR(arg) = (%_ClassOf(arg) === 'Generator');
|
||||||
macro IS_UNDETECTABLE(arg) = (%_IsUndetectableObject(arg));
|
macro IS_UNDETECTABLE(arg) = (%_IsUndetectableObject(arg));
|
||||||
macro FLOOR(arg) = $floor(arg);
|
macro FLOOR(arg) = $floor(arg);
|
||||||
|
|
||||||
|
@ -1872,9 +1872,10 @@ Statement* Parser::ParseNativeDeclaration(bool* ok) {
|
|||||||
const int literals = fun->NumberOfLiterals();
|
const int literals = fun->NumberOfLiterals();
|
||||||
Handle<Code> code = Handle<Code>(fun->shared()->code());
|
Handle<Code> code = Handle<Code>(fun->shared()->code());
|
||||||
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
|
Handle<Code> construct_stub = Handle<Code>(fun->shared()->construct_stub());
|
||||||
|
bool is_generator = false;
|
||||||
Handle<SharedFunctionInfo> shared =
|
Handle<SharedFunctionInfo> shared =
|
||||||
isolate()->factory()->NewSharedFunctionInfo(name, literals, code,
|
isolate()->factory()->NewSharedFunctionInfo(name, literals, is_generator,
|
||||||
Handle<ScopeInfo>(fun->shared()->scope_info()));
|
code, Handle<ScopeInfo>(fun->shared()->scope_info()));
|
||||||
shared->set_construct_stub(*construct_stub);
|
shared->set_construct_stub(*construct_stub);
|
||||||
|
|
||||||
// Copy the function data to the shared function info.
|
// Copy the function data to the shared function info.
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
// Flags: --harmony-generators --harmony-scoping
|
// Flags: --harmony-generators --harmony-scoping --allow-natives-syntax
|
||||||
|
|
||||||
// Test instantations of generators.
|
// Test instantations of generators.
|
||||||
|
|
||||||
@ -55,6 +55,8 @@ function TestGeneratorObject() {
|
|||||||
var iter = g();
|
var iter = g();
|
||||||
assertSame(g.prototype, Object.getPrototypeOf(iter));
|
assertSame(g.prototype, Object.getPrototypeOf(iter));
|
||||||
assertTrue(iter instanceof g);
|
assertTrue(iter instanceof g);
|
||||||
|
assertEquals("Generator", %ClassOf(iter));
|
||||||
|
assertEquals("[object Generator]", String(iter));
|
||||||
assertEquals([], Object.getOwnPropertyNames(iter));
|
assertEquals([], Object.getOwnPropertyNames(iter));
|
||||||
assertTrue(iter !== g());
|
assertTrue(iter !== g());
|
||||||
|
|
||||||
@ -62,7 +64,30 @@ function TestGeneratorObject() {
|
|||||||
iter = new g();
|
iter = new g();
|
||||||
assertSame(g.prototype, Object.getPrototypeOf(iter));
|
assertSame(g.prototype, Object.getPrototypeOf(iter));
|
||||||
assertTrue(iter instanceof g);
|
assertTrue(iter instanceof g);
|
||||||
|
assertEquals("Generator", %ClassOf(iter));
|
||||||
|
assertEquals("[object Generator]", String(iter));
|
||||||
assertEquals([], Object.getOwnPropertyNames(iter));
|
assertEquals([], Object.getOwnPropertyNames(iter));
|
||||||
assertTrue(iter !== new g());
|
assertTrue(iter !== new g());
|
||||||
}
|
}
|
||||||
TestGeneratorObject();
|
TestGeneratorObject();
|
||||||
|
|
||||||
|
|
||||||
|
// Test the methods of generator objects.
|
||||||
|
function TestGeneratorObjectMethods() {
|
||||||
|
function* g() { yield 1; }
|
||||||
|
var iter = g();
|
||||||
|
|
||||||
|
function TestNonGenerator(non_generator) {
|
||||||
|
assertThrows(function() { iter.next.call(non_generator); }, TypeError);
|
||||||
|
assertThrows(function() { iter.send.call(non_generator, 1); }, TypeError);
|
||||||
|
assertThrows(function() { iter.throw.call(non_generator, 1); }, TypeError);
|
||||||
|
assertThrows(function() { iter.close.call(non_generator); }, TypeError);
|
||||||
|
}
|
||||||
|
|
||||||
|
TestNonGenerator(1);
|
||||||
|
TestNonGenerator({});
|
||||||
|
TestNonGenerator(function(){});
|
||||||
|
TestNonGenerator(g);
|
||||||
|
TestNonGenerator(g.prototype);
|
||||||
|
}
|
||||||
|
TestGeneratorObjectMethods();
|
||||||
|
Loading…
Reference in New Issue
Block a user