From fe6598cffb82ec4180dcc2e2310e77d07a803f96 Mon Sep 17 00:00:00 2001 From: rossberg Date: Mon, 18 May 2015 06:23:30 -0700 Subject: [PATCH] [strong] Object literals create strong objects R=dslomov@chromium.org BUG=v8:3956 LOG=N Review URL: https://codereview.chromium.org/1134333005 Cr-Commit-Position: refs/heads/master@{#28444} --- include/v8.h | 2 +- src/ast.h | 45 ++++++++++++++----- src/bootstrapper.cc | 5 +++ src/contexts.h | 2 + src/factory.cc | 8 +++- src/factory.h | 1 + src/hydrogen.cc | 3 +- src/objects.cc | 16 +++++-- src/parser.cc | 6 ++- src/preparser.h | 10 ++++- src/runtime/runtime-literals.cc | 43 +++++++++++------- src/runtime/runtime.h | 2 +- test/mjsunit/strong/literals.js | 79 +++++++++++++++++++++++++++++++++ test/mjsunit/strong/objects.js | 10 ----- 14 files changed, 182 insertions(+), 50 deletions(-) create mode 100644 test/mjsunit/strong/literals.js delete mode 100644 test/mjsunit/strong/objects.js diff --git a/include/v8.h b/include/v8.h index d4b664a54..4bef47222 100644 --- a/include/v8.h +++ b/include/v8.h @@ -6673,7 +6673,7 @@ class Internals { static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFixedArrayHeaderSize = 2 * kApiPointerSize; static const int kContextHeaderSize = 2 * kApiPointerSize; - static const int kContextEmbedderDataIndex = 77; + static const int kContextEmbedderDataIndex = 78; static const int kFullStringRepresentationMask = 0x07; static const int kStringEncodingMask = 0x4; static const int kExternalTwoByteRepresentationTag = 0x02; diff --git a/src/ast.h b/src/ast.h index 26950b4c9..60f0068d3 100644 --- a/src/ast.h +++ b/src/ast.h @@ -1295,11 +1295,14 @@ class MaterializedLiteral : public Expression { return depth_; } + bool is_strong() const { return is_strong_; } + protected: - MaterializedLiteral(Zone* zone, int literal_index, int pos) + MaterializedLiteral(Zone* zone, int literal_index, bool is_strong, int pos) : Expression(zone, pos), literal_index_(literal_index), is_simple_(false), + is_strong_(is_strong), depth_(0) {} // A materialized literal is simple if the values consist of only @@ -1328,6 +1331,7 @@ class MaterializedLiteral : public Expression { private: int literal_index_; bool is_simple_; + bool is_strong_; int depth_; }; @@ -1422,6 +1426,9 @@ class ObjectLiteral final : public MaterializedLiteral { if (disable_mementos) { flags |= kDisableMementos; } + if (is_strong()) { + flags |= kIsStrong; + } return flags; } @@ -1430,7 +1437,8 @@ class ObjectLiteral final : public MaterializedLiteral { kFastElements = 1, kHasFunction = 1 << 1, kShallowProperties = 1 << 2, - kDisableMementos = 1 << 3 + kDisableMementos = 1 << 3, + kIsStrong = 1 << 4 }; struct Accessors: public ZoneObject { @@ -1450,8 +1458,9 @@ class ObjectLiteral final : public MaterializedLiteral { protected: ObjectLiteral(Zone* zone, ZoneList* properties, int literal_index, - int boilerplate_properties, bool has_function, int pos) - : MaterializedLiteral(zone, literal_index, pos), + int boilerplate_properties, bool has_function, + bool is_strong, int pos) + : MaterializedLiteral(zone, literal_index, is_strong, pos), properties_(properties), boilerplate_properties_(boilerplate_properties), fast_elements_(false), @@ -1482,8 +1491,9 @@ class RegExpLiteral final : public MaterializedLiteral { protected: RegExpLiteral(Zone* zone, const AstRawString* pattern, - const AstRawString* flags, int literal_index, int pos) - : MaterializedLiteral(zone, literal_index, pos), + const AstRawString* flags, int literal_index, bool is_strong, + int pos) + : MaterializedLiteral(zone, literal_index, is_strong, pos), pattern_(pattern), flags_(flags) { set_depth(1); @@ -1528,19 +1538,24 @@ class ArrayLiteral final : public MaterializedLiteral { if (disable_mementos) { flags |= kDisableMementos; } + if (is_strong()) { + flags |= kIsStrong; + } return flags; } enum Flags { kNoFlags = 0, kShallowElements = 1, - kDisableMementos = 1 << 1 + kDisableMementos = 1 << 1, + kIsStrong = 1 << 2 }; protected: ArrayLiteral(Zone* zone, ZoneList* values, int literal_index, - int pos) - : MaterializedLiteral(zone, literal_index, pos), values_(values) {} + bool is_strong, int pos) + : MaterializedLiteral(zone, literal_index, is_strong, pos), + values_(values) {} static int parent_num_ids() { return MaterializedLiteral::num_ids(); } private: @@ -3305,9 +3320,11 @@ class AstNodeFactory final BASE_EMBEDDED { int literal_index, int boilerplate_properties, bool has_function, + bool is_strong, int pos) { return new (zone_) ObjectLiteral(zone_, properties, literal_index, - boilerplate_properties, has_function, pos); + boilerplate_properties, has_function, + is_strong, pos); } ObjectLiteral::Property* NewObjectLiteralProperty( @@ -3328,14 +3345,18 @@ class AstNodeFactory final BASE_EMBEDDED { RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, const AstRawString* flags, int literal_index, + bool is_strong, int pos) { - return new (zone_) RegExpLiteral(zone_, pattern, flags, literal_index, pos); + return new (zone_) RegExpLiteral(zone_, pattern, flags, literal_index, + is_strong, pos); } ArrayLiteral* NewArrayLiteral(ZoneList* values, int literal_index, + bool is_strong, int pos) { - return new (zone_) ArrayLiteral(zone_, values, literal_index, pos); + return new (zone_) ArrayLiteral(zone_, values, literal_index, is_strong, + pos); } VariableProxy* NewVariableProxy(Variable* var, diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index 55b5b3141..21f3ec0e2 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1016,6 +1016,11 @@ void Genesis::InitializeGlobal(Handle global_object, ArrayConstructorStub array_constructor_stub(isolate); Handle code = array_constructor_stub.GetCode(); array_function->shared()->set_construct_stub(*code); + + Handle initial_strong_map = + Map::Copy(initial_map, "SetInstancePrototype"); + initial_strong_map->set_is_strong(true); + CacheInitialJSArrayMaps(native_context(), initial_strong_map); } { // --- N u m b e r --- diff --git a/src/contexts.h b/src/contexts.h index f12078860..d06e4e818 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -85,6 +85,7 @@ enum BindingFlags { V(INTERNAL_ARRAY_FUNCTION_INDEX, JSFunction, internal_array_function) \ V(ARRAY_FUNCTION_INDEX, JSFunction, array_function) \ V(JS_ARRAY_MAPS_INDEX, Object, js_array_maps) \ + V(JS_ARRAY_STRONG_MAPS_INDEX, Object, js_array_strong_maps) \ V(DATE_FUNCTION_INDEX, JSFunction, date_function) \ V(JSON_OBJECT_INDEX, JSObject, json_object) \ V(REGEXP_FUNCTION_INDEX, JSFunction, regexp_function) \ @@ -341,6 +342,7 @@ class Context: public FixedArray { INTERNAL_ARRAY_FUNCTION_INDEX, ARRAY_FUNCTION_INDEX, JS_ARRAY_MAPS_INDEX, + JS_ARRAY_STRONG_MAPS_INDEX, DATE_FUNCTION_INDEX, JSON_OBJECT_INDEX, REGEXP_FUNCTION_INDEX, diff --git a/src/factory.cc b/src/factory.cc index e966e5ca9..06373d2d8 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -2339,14 +2339,18 @@ Handle Factory::NewJSWeakMap() { Handle Factory::ObjectLiteralMapFromCache(Handle context, int number_of_properties, + bool is_strong, bool* is_result_from_cache) { const int kMapCacheSize = 128; // We do not cache maps for too many properties or when running builtin code. - if (number_of_properties > kMapCacheSize || + // TODO(rossberg): cache strong maps properly + if (number_of_properties > kMapCacheSize || is_strong || isolate()->bootstrapper()->IsActive()) { *is_result_from_cache = false; - return Map::Create(isolate(), number_of_properties); + Handle map = Map::Create(isolate(), number_of_properties); + if (is_strong) map->set_is_strong(true); + return map; } *is_result_from_cache = true; if (number_of_properties == 0) { diff --git a/src/factory.h b/src/factory.h index 4aba6eeb7..8eaa216ee 100644 --- a/src/factory.h +++ b/src/factory.h @@ -670,6 +670,7 @@ class Factory final { // native context. Handle ObjectLiteralMapFromCache(Handle context, int number_of_properties, + bool is_strong, bool* is_result_from_cache); // Creates a new FixedArray that holds the data associated with the diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 4f0458037..86bf76342 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -5790,7 +5790,8 @@ void HOptimizedGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) { ASSIGN_RETURN_ON_EXCEPTION_VALUE( isolate(), raw_boilerplate, Runtime::CreateArrayLiteralBoilerplate( - isolate(), literals, expr->constant_elements()), + isolate(), literals, expr->constant_elements(), + is_strong(function_language_mode())), Bailout(kArrayBoilerplateCreationFailed)); boilerplate_object = Handle::cast(raw_boilerplate); diff --git a/src/objects.cc b/src/objects.cc index 645ea57e3..b07cc9953 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -3804,7 +3804,9 @@ Handle Map::TransitionElementsTo(Handle map, Isolate* isolate = map->GetIsolate(); Context* native_context = isolate->context()->native_context(); - Object* maybe_array_maps = native_context->js_array_maps(); + Object* maybe_array_maps = map->is_strong() + ? native_context->js_array_strong_maps() + : native_context->js_array_maps(); if (maybe_array_maps->IsFixedArray()) { DisallowHeapAllocation no_gc; FixedArray* array_maps = FixedArray::cast(maybe_array_maps); @@ -10318,7 +10320,10 @@ Handle CacheInitialJSArrayMaps( maps->set(next_kind, *new_map); current_map = new_map; } - native_context->set_js_array_maps(*maps); + if (initial_map->is_strong()) + native_context->set_js_array_strong_maps(*maps); + else + native_context->set_js_array_maps(*maps); return initial_map; } @@ -10353,13 +10358,18 @@ void JSFunction::SetInstancePrototype(Handle function, JSFunction::SetInitialMap(function, new_map, value); // If the function is used as the global Array function, cache the - // initial map (and transitioned versions) in the native context. + // updated initial maps (and transitioned versions) in the native context. Context* native_context = function->context()->native_context(); Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX); if (array_function->IsJSFunction() && *function == JSFunction::cast(array_function)) { CacheInitialJSArrayMaps(handle(native_context, isolate), new_map); + Handle new_strong_map = + Map::Copy(initial_map, "SetInstancePrototype"); + new_strong_map->set_is_strong(true); + CacheInitialJSArrayMaps(handle(native_context, isolate), + new_strong_map); } } diff --git a/src/parser.cc b/src/parser.cc index 7c0332781..7d7f6a626 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -5588,11 +5588,12 @@ Expression* Parser::CloseTemplateLiteral(TemplateLiteralState* state, int start, ZoneList* args = new (zone()) ZoneList(4, zone()); args->Add(factory()->NewArrayLiteral( const_cast*>(cooked_strings), - cooked_idx, pos), + cooked_idx, is_strong(language_mode()), pos), zone()); args->Add( factory()->NewArrayLiteral( - const_cast*>(raw_strings), raw_idx, pos), + const_cast*>(raw_strings), raw_idx, + is_strong(language_mode()), pos), zone()); // Ensure hash is suitable as a Smi value @@ -5683,6 +5684,7 @@ ZoneList* Parser::PrepareSpreadArguments( } int literal_index = function_state_->NextMaterializedLiteralIndex(); args->Add(factory()->NewArrayLiteral(unspread, literal_index, + is_strong(language_mode()), RelocInfo::kNoPosition), zone()); diff --git a/src/preparser.h b/src/preparser.h index 67ff6d876..0163a33a8 100644 --- a/src/preparser.h +++ b/src/preparser.h @@ -1352,11 +1352,13 @@ class PreParserFactory { PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, PreParserIdentifier js_flags, int literal_index, + bool is_strong, int pos) { return PreParserExpression::Default(); } PreParserExpression NewArrayLiteral(PreParserExpressionList values, int literal_index, + bool is_strong, int pos) { return PreParserExpression::Default(); } @@ -1377,6 +1379,7 @@ class PreParserFactory { int literal_index, int boilerplate_properties, bool has_function, + bool is_strong, int pos) { return PreParserExpression::Default(); } @@ -2230,7 +2233,8 @@ typename ParserBase::ExpressionT ParserBase::ParseRegExpLiteral( } IdentifierT js_flags = this->GetNextSymbol(scanner()); Next(); - return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); + return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, + is_strong(language_mode()), pos); } @@ -2496,7 +2500,8 @@ typename ParserBase::ExpressionT ParserBase::ParseArrayLiteral( // Update the scope information before the pre-parsing bailout. int literal_index = function_state_->NextMaterializedLiteralIndex(); - return factory()->NewArrayLiteral(values, literal_index, pos); + return factory()->NewArrayLiteral(values, literal_index, + is_strong(language_mode()), pos); } @@ -2752,6 +2757,7 @@ typename ParserBase::ExpressionT ParserBase::ParseObjectLiteral( literal_index, number_of_boilerplate_properties, has_function, + is_strong(language_mode()), pos); } diff --git a/src/runtime/runtime-literals.cc b/src/runtime/runtime-literals.cc index 76226d68f..8fe6e3f2f 100644 --- a/src/runtime/runtime-literals.cc +++ b/src/runtime/runtime-literals.cc @@ -16,7 +16,7 @@ namespace internal { static Handle ComputeObjectLiteralMap( Handle context, Handle constant_properties, - bool* is_result_from_cache) { + bool is_strong, bool* is_result_from_cache) { int properties_length = constant_properties->length(); int number_of_properties = properties_length / 2; @@ -30,28 +30,30 @@ static Handle ComputeObjectLiteralMap( } Isolate* isolate = context->GetIsolate(); return isolate->factory()->ObjectLiteralMapFromCache( - context, number_of_properties, is_result_from_cache); + context, number_of_properties, is_strong, is_result_from_cache); } MUST_USE_RESULT static MaybeHandle CreateLiteralBoilerplate( Isolate* isolate, Handle literals, - Handle constant_properties); + Handle constant_properties, bool is_strong); MUST_USE_RESULT static MaybeHandle CreateObjectLiteralBoilerplate( Isolate* isolate, Handle literals, Handle constant_properties, bool should_have_fast_elements, - bool has_function_literal) { + bool has_function_literal, bool is_strong) { Handle context = isolate->native_context(); // In case we have function literals, we want the object to be in // slow properties mode for now. We don't go in the map cache because // maps with constant functions can't be shared if the functions are // not the same (which is the common case). + // TODO(rossberg): handle strong objects with function literals bool is_result_from_cache = false; Handle map = has_function_literal ? Handle(context->object_function()->initial_map()) : ComputeObjectLiteralMap(context, constant_properties, + is_strong, &is_result_from_cache); PretenureFlag pretenure_flag = @@ -82,7 +84,8 @@ MUST_USE_RESULT static MaybeHandle CreateObjectLiteralBoilerplate( // simple object or array literal. Handle array = Handle::cast(value); ASSIGN_RETURN_ON_EXCEPTION( - isolate, value, CreateLiteralBoilerplate(isolate, literals, array), + isolate, value, + CreateLiteralBoilerplate(isolate, literals, array, is_strong), Object); } MaybeHandle maybe_result; @@ -137,7 +140,7 @@ MUST_USE_RESULT static MaybeHandle CreateObjectLiteralBoilerplate( MaybeHandle Runtime::CreateArrayLiteralBoilerplate( Isolate* isolate, Handle literals, - Handle elements) { + Handle elements, bool is_strong) { // Create the JSArray. Handle constructor = isolate->array_function(); @@ -156,7 +159,9 @@ MaybeHandle Runtime::CreateArrayLiteralBoilerplate( DisallowHeapAllocation no_gc; DCHECK(IsFastElementsKind(constant_elements_kind)); Context* native_context = isolate->context()->native_context(); - Object* maps_array = native_context->js_array_maps(); + Object* maps_array = is_strong + ? native_context->js_array_strong_maps() + : native_context->js_array_maps(); DCHECK(!maps_array->IsUndefined()); Object* map = FixedArray::cast(maps_array)->get(constant_elements_kind); object->set_map(Map::cast(map)); @@ -192,7 +197,8 @@ MaybeHandle Runtime::CreateArrayLiteralBoilerplate( Handle fa(FixedArray::cast(fixed_array_values->get(i))); Handle result; ASSIGN_RETURN_ON_EXCEPTION( - isolate, result, CreateLiteralBoilerplate(isolate, literals, fa), + isolate, result, + CreateLiteralBoilerplate(isolate, literals, fa, is_strong), Object); fixed_array_values_copy->set(i, *result); } @@ -208,19 +214,20 @@ MaybeHandle Runtime::CreateArrayLiteralBoilerplate( MUST_USE_RESULT static MaybeHandle CreateLiteralBoilerplate( - Isolate* isolate, Handle literals, Handle array) { + Isolate* isolate, Handle literals, Handle array, + bool is_strong) { Handle elements = CompileTimeValue::GetElements(array); const bool kHasNoFunctionLiteral = false; switch (CompileTimeValue::GetLiteralType(array)) { case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: return CreateObjectLiteralBoilerplate(isolate, literals, elements, true, - kHasNoFunctionLiteral); + kHasNoFunctionLiteral, is_strong); case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: return CreateObjectLiteralBoilerplate(isolate, literals, elements, false, - kHasNoFunctionLiteral); + kHasNoFunctionLiteral, is_strong); case CompileTimeValue::ARRAY_LITERAL: return Runtime::CreateArrayLiteralBoilerplate(isolate, literals, - elements); + elements, is_strong); default: UNREACHABLE(); return MaybeHandle(); @@ -238,6 +245,7 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { bool should_have_fast_elements = (flags & ObjectLiteral::kFastElements) != 0; bool has_function_literal = (flags & ObjectLiteral::kHasFunction) != 0; bool enable_mementos = (flags & ObjectLiteral::kDisableMementos) == 0; + bool is_strong = (flags & ObjectLiteral::kIsStrong) != 0; RUNTIME_ASSERT(literals_index >= 0 && literals_index < literals->length()); @@ -251,7 +259,7 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { isolate, raw_boilerplate, CreateObjectLiteralBoilerplate(isolate, literals, constant_properties, should_have_fast_elements, - has_function_literal)); + has_function_literal, is_strong)); boilerplate = Handle::cast(raw_boilerplate); AllocationSiteCreationContext creation_context(isolate); @@ -281,7 +289,7 @@ RUNTIME_FUNCTION(Runtime_CreateObjectLiteral) { MUST_USE_RESULT static MaybeHandle GetLiteralAllocationSite( Isolate* isolate, Handle literals, int literals_index, - Handle elements) { + Handle elements, bool is_strong) { // Check if boilerplate exists. If not, create it first. Handle literal_site(literals->get(literals_index), isolate); Handle site; @@ -290,7 +298,8 @@ MUST_USE_RESULT static MaybeHandle GetLiteralAllocationSite( Handle boilerplate; ASSIGN_RETURN_ON_EXCEPTION( isolate, boilerplate, - Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements), + Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements, + is_strong), AllocationSite); AllocationSiteCreationContext creation_context(isolate); @@ -318,9 +327,11 @@ static MaybeHandle CreateArrayLiteralImpl(Isolate* isolate, RUNTIME_ASSERT_HANDLIFIED( literals_index >= 0 && literals_index < literals->length(), JSObject); Handle site; + bool is_strong = (flags & ArrayLiteral::kIsStrong) != 0; ASSIGN_RETURN_ON_EXCEPTION( isolate, site, - GetLiteralAllocationSite(isolate, literals, literals_index, elements), + GetLiteralAllocationSite(isolate, literals, literals_index, elements, + is_strong), JSObject); bool enable_mementos = (flags & ArrayLiteral::kDisableMementos) == 0; diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index bd37a68a7..b4de53539 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -848,7 +848,7 @@ class Runtime : public AllStatic { // Used in runtime.cc and hydrogen's VisitArrayLiteral. MUST_USE_RESULT static MaybeHandle CreateArrayLiteralBoilerplate( Isolate* isolate, Handle literals, - Handle elements); + Handle elements, bool is_strong); static void WeakCollectionInitialize( Isolate* isolate, Handle weak_collection); diff --git a/test/mjsunit/strong/literals.js b/test/mjsunit/strong/literals.js new file mode 100644 index 000000000..b9368e1f9 --- /dev/null +++ b/test/mjsunit/strong/literals.js @@ -0,0 +1,79 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --strong-mode --allow-natives-syntax +// Flags: --harmony-arrow-functions --harmony-rest-parameters + + +(function WeakObjectLiterals() { + assertTrue(!%IsStrong({})); + assertTrue(!%IsStrong({a: 0, b: 0})); + assertTrue(!%IsStrong({f: function(){}})); + assertTrue(!%IsStrong(Realm.eval(Realm.current(), + "({f: function(){}})"))); +})(); + +(function StrongObjectLiterals() { + 'use strong'; + assertTrue(%IsStrong({})); + assertTrue(%IsStrong({a: 0, b: 0})); + assertTrue(%IsStrong({__proto__: {}, get a() {}, set b(x) {}})); + assertTrue(%IsStrong({[Date() + ""]: 0, [Symbol()]: 0})); + // TODO(rossberg): super does not work yet + // assertTrue(%IsStrong({m() { super.m() }})); + // Object literals with constant functions are treated specially, + // but currently only on the toplevel. + assertTrue(%IsStrong({f: function(){}})); + // TODO(rossberg): implement strong object literals with functions + // assertTrue(%IsStrong(Realm.eval(Realm.current(), + // "'use strong'; ({f: function(){}})"))); +})(); + +(function WeakArrayLiterals(...args) { + assertTrue(!%IsStrong(args)); + assertTrue(!%IsStrong([])); + assertTrue(!%IsStrong([1, 2, 3])); + Array.prototype = {} + assertTrue(!%IsStrong([])); + assertTrue(!%IsStrong([1, 2, 3])); +})(); + +(function StrongArrayLiterals(...args) { + 'use strong'; + // TODO(rossberg): implement strong array literals + // assertTrue(%IsStrong(args)); + // assertTrue(%IsStrong([])); + // assertTrue(%IsStrong([1, 2, 3])); + // Array.prototype = {} + // assertTrue(%IsStrong([])); + // assertTrue(%IsStrong([1, 2, 3])); +})(0); // TODO(arv): drop dummy + +(function WeakFunctionLiterals() { + function f() {} + assertTrue(!%IsStrong(f)); + assertTrue(!%IsStrong(function(){})); + assertTrue(!%IsStrong(() => {})); + assertTrue(!%IsStrong(x => x)); +})(); + +(function StrongFunctionLiterals(g) { + 'use strong'; + function f() {} + assertTrue(%IsStrong(f)); + assertTrue(%IsStrong(g)); + assertTrue(%IsStrong(function(){})); + assertTrue(%IsStrong(() => {})); + assertTrue(%IsStrong(x => x)); +})(function() { 'use strong' }); + +(function WeakRegExpLiterals() { + assertTrue(!%IsStrong(/abc/)); +})(); + +(function StrongRegExpLiterals() { + 'use strong'; + // TODO(rossberg): implement strong regexp literals + // assertTrue(%IsStrong(/abc/)); +})(); diff --git a/test/mjsunit/strong/objects.js b/test/mjsunit/strong/objects.js deleted file mode 100644 index 4654606ab..000000000 --- a/test/mjsunit/strong/objects.js +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2015 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --strong-mode --allow-natives-syntax - -'use strong'; - -function f() {} -assertTrue(%IsStrong(f)); -- 2.34.1