Commit 69d218c0 authored by neis's avatar neis Committed by Commit bot

[proxies] Remove "fix" functionality, add (still unused) target property.

BUG=

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

Cr-Commit-Position: refs/heads/master@{#31972}
parent fa9c39ee
...@@ -1936,7 +1936,8 @@ Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer, ...@@ -1936,7 +1936,8 @@ Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
} }
Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler, Handle<JSProxy> Factory::NewJSProxy(Handle<JSReceiver> target,
Handle<JSReceiver> handler,
Handle<Object> prototype) { Handle<Object> prototype) {
// Allocate map. // Allocate map.
// TODO(rossberg): Once we optimize proxies, think about a scheme to share // TODO(rossberg): Once we optimize proxies, think about a scheme to share
...@@ -1946,14 +1947,15 @@ Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler, ...@@ -1946,14 +1947,15 @@ Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler,
// Allocate the proxy object. // Allocate the proxy object.
Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE); Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
result->InitializeBody(map->instance_size(), Smi::FromInt(0)); result->set_target(*target);
result->set_handler(*handler); result->set_handler(*handler);
result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER); result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
return result; return result;
} }
Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler, Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<JSReceiver> target,
Handle<JSReceiver> handler,
Handle<JSReceiver> call_trap, Handle<JSReceiver> call_trap,
Handle<Object> construct_trap, Handle<Object> construct_trap,
Handle<Object> prototype) { Handle<Object> prototype) {
...@@ -1967,7 +1969,7 @@ Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler, ...@@ -1967,7 +1969,7 @@ Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler,
// Allocate the proxy object. // Allocate the proxy object.
Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE); Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE);
result->InitializeBody(map->instance_size(), Smi::FromInt(0)); result->set_target(*target);
result->set_handler(*handler); result->set_handler(*handler);
result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER); result->set_hash(*undefined_value(), SKIP_WRITE_BARRIER);
result->set_call_trap(*call_trap); result->set_call_trap(*call_trap);
...@@ -1976,66 +1978,6 @@ Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler, ...@@ -1976,66 +1978,6 @@ Handle<JSProxy> Factory::NewJSFunctionProxy(Handle<Object> handler,
} }
void Factory::ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type,
int size) {
DCHECK(type == JS_OBJECT_TYPE || type == JS_FUNCTION_TYPE);
Handle<Map> proxy_map(proxy->map());
Handle<Map> map = Map::FixProxy(proxy_map, type, size);
// Check that the receiver has at least the size of the fresh object.
int size_difference = proxy_map->instance_size() - map->instance_size();
DCHECK(size_difference >= 0);
// Allocate the backing storage for the properties.
Handle<FixedArray> properties = empty_fixed_array();
Heap* heap = isolate()->heap();
MaybeHandle<SharedFunctionInfo> shared;
if (type == JS_FUNCTION_TYPE) {
OneByteStringKey key(STATIC_CHAR_VECTOR("<freezing call trap>"),
heap->HashSeed());
Handle<String> name = InternalizeStringWithKey(&key);
shared = NewSharedFunctionInfo(name, MaybeHandle<Code>());
}
// In order to keep heap in consistent state there must be no allocations
// before object re-initialization is finished and filler object is installed.
DisallowHeapAllocation no_allocation;
// Put in filler if the new object is smaller than the old.
if (size_difference > 0) {
Address address = proxy->address();
heap->CreateFillerObjectAt(address + map->instance_size(), size_difference);
heap->AdjustLiveBytes(*proxy, -size_difference,
Heap::CONCURRENT_TO_SWEEPER);
}
// Reset the map for the object.
proxy->synchronized_set_map(*map);
Handle<JSObject> jsobj = Handle<JSObject>::cast(proxy);
// Reinitialize the object from the constructor map.
heap->InitializeJSObjectFromMap(*jsobj, *properties, *map);
// The current native context is used to set up certain bits.
// TODO(adamk): Using the current context seems wrong, it should be whatever
// context the JSProxy originated in. But that context isn't stored anywhere.
Handle<Context> context(isolate()->native_context());
// Functions require some minimal initialization.
if (type == JS_FUNCTION_TYPE) {
map->set_is_constructor(true);
map->set_is_callable();
Handle<JSFunction> js_function = Handle<JSFunction>::cast(proxy);
InitializeFunction(js_function, shared.ToHandleChecked(), context);
} else {
// Provide JSObjects with a constructor.
map->SetConstructor(context->object_function());
}
}
Handle<JSGlobalProxy> Factory::NewUninitializedJSGlobalProxy() { Handle<JSGlobalProxy> Factory::NewUninitializedJSGlobalProxy() {
// Create an empty shell of a JSGlobalProxy that needs to be reinitialized // Create an empty shell of a JSGlobalProxy that needs to be reinitialized
// via ReinitializeJSGlobalProxy later. // via ReinitializeJSGlobalProxy later.
...@@ -2080,16 +2022,6 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object, ...@@ -2080,16 +2022,6 @@ void Factory::ReinitializeJSGlobalProxy(Handle<JSGlobalProxy> object,
} }
void Factory::BecomeJSObject(Handle<JSProxy> proxy) {
ReinitializeJSProxy(proxy, JS_OBJECT_TYPE, JSObject::kHeaderSize);
}
void Factory::BecomeJSFunction(Handle<JSProxy> proxy) {
ReinitializeJSProxy(proxy, JS_FUNCTION_TYPE, JSFunction::kSize);
}
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo( Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfo(
Handle<String> name, int number_of_literals, FunctionKind kind, Handle<String> name, int number_of_literals, FunctionKind kind,
Handle<Code> code, Handle<ScopeInfo> scope_info, Handle<Code> code, Handle<ScopeInfo> scope_info,
......
...@@ -476,10 +476,13 @@ class Factory final { ...@@ -476,10 +476,13 @@ class Factory final {
Handle<Object> done); Handle<Object> done);
// Allocates a Harmony proxy. // Allocates a Harmony proxy.
Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype); Handle<JSProxy> NewJSProxy(Handle<JSReceiver> target,
Handle<JSReceiver> handler,
Handle<Object> prototype);
// Allocates a Harmony function proxy. // Allocates a Harmony function proxy.
Handle<JSProxy> NewJSFunctionProxy(Handle<Object> handler, Handle<JSProxy> NewJSFunctionProxy(Handle<JSReceiver> target,
Handle<JSReceiver> handler,
Handle<JSReceiver> call_trap, Handle<JSReceiver> call_trap,
Handle<Object> construct_trap, Handle<Object> construct_trap,
Handle<Object> prototype); Handle<Object> prototype);
...@@ -493,10 +496,6 @@ class Factory final { ...@@ -493,10 +496,6 @@ class Factory final {
Handle<JSGlobalProxy> NewUninitializedJSGlobalProxy(); Handle<JSGlobalProxy> NewUninitializedJSGlobalProxy();
// Change the type of the argument into a JS object/function and reinitialize.
void BecomeJSObject(Handle<JSProxy> object);
void BecomeJSFunction(Handle<JSProxy> object);
Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code, Handle<JSFunction> NewFunction(Handle<String> name, Handle<Code> code,
Handle<Object> prototype, Handle<Object> prototype,
bool read_only_prototype = false, bool read_only_prototype = false,
...@@ -713,12 +712,6 @@ class Factory final { ...@@ -713,12 +712,6 @@ class Factory final {
Handle<JSFunction> NewFunction(Handle<Map> map, Handle<JSFunction> NewFunction(Handle<Map> map,
Handle<String> name, Handle<String> name,
MaybeHandle<Code> maybe_code); MaybeHandle<Code> maybe_code);
// Reinitialize a JSProxy into an (empty) JS object of respective type and
// size, but keeping the original prototype. The receiver must have at least
// the size of the new object. The object is reinitialized and behaves as an
// object that has been freshly allocated.
void ReinitializeJSProxy(Handle<JSProxy> proxy, InstanceType type, int size);
}; };
} // namespace internal } // namespace internal
......
// Copyright 2011 the V8 project authors. All rights reserved. // Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -30,7 +30,7 @@ function ProxyCreate(handler, proto) { ...@@ -30,7 +30,7 @@ function ProxyCreate(handler, proto) {
proto = null proto = null
else if (!(IS_SPEC_OBJECT(proto) || IS_NULL(proto))) else if (!(IS_SPEC_OBJECT(proto) || IS_NULL(proto)))
throw MakeTypeError(kProxyProtoNonObject) throw MakeTypeError(kProxyProtoNonObject)
return %CreateJSProxy(handler, proto) return %CreateJSProxy({}, handler, proto)
} }
function ProxyCreateFunction(handler, callTrap, constructTrap) { function ProxyCreateFunction(handler, callTrap, constructTrap) {
...@@ -50,7 +50,7 @@ function ProxyCreateFunction(handler, callTrap, constructTrap) { ...@@ -50,7 +50,7 @@ function ProxyCreateFunction(handler, callTrap, constructTrap) {
throw MakeTypeError(kProxyTrapFunctionExpected, "construct") throw MakeTypeError(kProxyTrapFunctionExpected, "construct")
} }
return %CreateJSFunctionProxy( return %CreateJSFunctionProxy(
handler, callTrap, constructTrap, GlobalFunction.prototype) {}, handler, callTrap, constructTrap, GlobalFunction.prototype)
} }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
......
...@@ -1116,43 +1116,12 @@ function ObjectDefineProperties(obj, properties) { ...@@ -1116,43 +1116,12 @@ function ObjectDefineProperties(obj, properties) {
} }
// Harmony proxies.
function ProxyFix(obj) {
var handler = %GetHandler(obj);
var props = CallTrap0(handler, "fix", UNDEFINED);
if (IS_UNDEFINED(props)) {
throw MakeTypeError(kProxyHandlerReturned, handler, "undefined", "fix");
}
if (%IsJSFunctionProxy(obj)) {
var callTrap = %GetCallTrap(obj);
var constructTrap = %GetConstructTrap(obj);
var code = ProxyDelegateCallAndConstruct(callTrap, constructTrap);
%Fix(obj); // becomes a regular function
%SetCode(obj, code);
// TODO(rossberg): What about length and other properties? Not specified.
// We just put in some half-reasonable defaults for now.
var prototype = new GlobalObject();
ObjectDefineProperty(prototype, "constructor",
{value: obj, writable: true, enumerable: false, configurable: true});
// TODO(v8:1530): defineProperty does not handle prototype and length.
%FunctionSetPrototype(obj, prototype);
obj.length = 0;
} else {
%Fix(obj);
}
ObjectDefineProperties(obj, props);
}
// ES5 section 15.2.3.8. // ES5 section 15.2.3.8.
function ObjectSealJS(obj) { function ObjectSealJS(obj) {
if (!IS_SPEC_OBJECT(obj)) return obj; if (!IS_SPEC_OBJECT(obj)) return obj;
var isProxy = %_IsJSProxy(obj); var isProxy = %_IsJSProxy(obj);
if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) { if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj)) {
if (isProxy) { // TODO(neis): For proxies, must call preventExtensions trap first.
ProxyFix(obj);
}
var names = OwnPropertyKeys(obj); var names = OwnPropertyKeys(obj);
for (var i = 0; i < names.length; i++) { for (var i = 0; i < names.length; i++) {
var name = names[i]; var name = names[i];
...@@ -1180,9 +1149,7 @@ function ObjectFreezeJS(obj) { ...@@ -1180,9 +1149,7 @@ function ObjectFreezeJS(obj) {
// objects. // objects.
if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj) || if (isProxy || %HasSloppyArgumentsElements(obj) || %IsObserved(obj) ||
IS_STRONG(obj)) { IS_STRONG(obj)) {
if (isProxy) { // TODO(neis): For proxies, must call preventExtensions trap first.
ProxyFix(obj);
}
var names = OwnPropertyKeys(obj); var names = OwnPropertyKeys(obj);
for (var i = 0; i < names.length; i++) { for (var i = 0; i < names.length; i++) {
var name = names[i]; var name = names[i];
...@@ -1206,11 +1173,7 @@ function ObjectFreezeJS(obj) { ...@@ -1206,11 +1173,7 @@ function ObjectFreezeJS(obj) {
// ES5 section 15.2.3.10 // ES5 section 15.2.3.10
function ObjectPreventExtension(obj) { function ObjectPreventExtension(obj) {
if (!IS_SPEC_OBJECT(obj)) return obj; if (!IS_SPEC_OBJECT(obj)) return obj;
if (%_IsJSProxy(obj)) { return %PreventExtensions(obj);
ProxyFix(obj);
}
%PreventExtensions(obj);
return obj;
} }
...@@ -1218,7 +1181,7 @@ function ObjectPreventExtension(obj) { ...@@ -1218,7 +1181,7 @@ function ObjectPreventExtension(obj) {
function ObjectIsSealed(obj) { function ObjectIsSealed(obj) {
if (!IS_SPEC_OBJECT(obj)) return true; if (!IS_SPEC_OBJECT(obj)) return true;
if (%_IsJSProxy(obj)) { if (%_IsJSProxy(obj)) {
return false; return false; // TODO(neis): Must call isExtensible trap and ownKeys trap.
} }
if (%IsExtensible(obj)) { if (%IsExtensible(obj)) {
return false; return false;
...@@ -1239,7 +1202,7 @@ function ObjectIsSealed(obj) { ...@@ -1239,7 +1202,7 @@ function ObjectIsSealed(obj) {
function ObjectIsFrozen(obj) { function ObjectIsFrozen(obj) {
if (!IS_SPEC_OBJECT(obj)) return true; if (!IS_SPEC_OBJECT(obj)) return true;
if (%_IsJSProxy(obj)) { if (%_IsJSProxy(obj)) {
return false; return false; // TODO(neis): Must call isExtensible trap and ownKeys trap.
} }
if (%IsExtensible(obj)) { if (%IsExtensible(obj)) {
return false; return false;
......
...@@ -6402,20 +6402,13 @@ int JSFunction::NumberOfLiterals() { ...@@ -6402,20 +6402,13 @@ int JSFunction::NumberOfLiterals() {
} }
ACCESSORS(JSProxy, target, Object, kTargetOffset)
ACCESSORS(JSProxy, handler, Object, kHandlerOffset) ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
ACCESSORS(JSProxy, hash, Object, kHashOffset) ACCESSORS(JSProxy, hash, Object, kHashOffset)
ACCESSORS(JSFunctionProxy, call_trap, JSReceiver, kCallTrapOffset) ACCESSORS(JSFunctionProxy, call_trap, JSReceiver, kCallTrapOffset)
ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset) ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
void JSProxy::InitializeBody(int object_size, Object* value) {
DCHECK(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
WRITE_FIELD(this, offset, value);
}
}
ACCESSORS(JSCollection, table, Object, kTableOffset) ACCESSORS(JSCollection, table, Object, kTableOffset)
......
...@@ -4654,28 +4654,6 @@ Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler( ...@@ -4654,28 +4654,6 @@ Maybe<PropertyAttributes> JSProxy::GetPropertyAttributesWithHandler(
} }
void JSProxy::Fix(Handle<JSProxy> proxy) {
Isolate* isolate = proxy->GetIsolate();
// Save identity hash.
Handle<Object> hash(proxy->GetIdentityHash(), isolate);
if (proxy->IsJSFunctionProxy()) {
isolate->factory()->BecomeJSFunction(proxy);
// Code will be set on the JavaScript side.
} else {
isolate->factory()->BecomeJSObject(proxy);
}
DCHECK(proxy->IsJSObject());
// Inherit identity, if it was present.
if (hash->IsSmi()) {
JSObject::SetIdentityHash(Handle<JSObject>::cast(proxy),
Handle<Smi>::cast(hash));
}
}
MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy, MaybeHandle<Object> JSProxy::CallTrap(Handle<JSProxy> proxy,
const char* name, const char* name,
Handle<Object> derived, Handle<Object> derived,
...@@ -8421,25 +8399,6 @@ Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map, ...@@ -8421,25 +8399,6 @@ Handle<Map> Map::CopyForPreventExtensions(Handle<Map> map,
} }
Handle<Map> Map::FixProxy(Handle<Map> map, InstanceType type, int size) {
DCHECK(type == JS_OBJECT_TYPE || type == JS_FUNCTION_TYPE);
DCHECK(map->IsJSProxyMap());
Isolate* isolate = map->GetIsolate();
// Allocate fresh map.
// TODO(rossberg): Once we optimize proxies, cache these maps.
Handle<Map> new_map = isolate->factory()->NewMap(type, size);
Handle<Object> prototype(map->prototype(), isolate);
Map::SetPrototype(new_map, prototype);
map->NotifyLeafMapLayoutChange();
return new_map;
}
bool DescriptorArray::CanHoldValue(int descriptor, Object* value) { bool DescriptorArray::CanHoldValue(int descriptor, Object* value) {
PropertyDetails details = GetDetails(descriptor); PropertyDetails details = GetDetails(descriptor);
switch (details.type()) { switch (details.type()) {
......
...@@ -9565,6 +9565,9 @@ class WeakCell : public HeapObject { ...@@ -9565,6 +9565,9 @@ class WeakCell : public HeapObject {
// The JSProxy describes EcmaScript Harmony proxies // The JSProxy describes EcmaScript Harmony proxies
class JSProxy: public JSReceiver { class JSProxy: public JSReceiver {
public: public:
// [target]: The target property.
DECL_ACCESSORS(target, Object)
// [handler]: The handler property. // [handler]: The handler property.
DECL_ACCESSORS(handler, Object) DECL_ACCESSORS(handler, Object)
...@@ -9596,21 +9599,6 @@ class JSProxy: public JSReceiver { ...@@ -9596,21 +9599,6 @@ class JSProxy: public JSReceiver {
Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name, Handle<JSProxy> proxy, Handle<Object> receiver, Handle<Name> name,
Handle<Object> value, ShouldThrow should_throw); Handle<Object> value, ShouldThrow should_throw);
// Turn the proxy into an (empty) JSObject.
static void Fix(Handle<JSProxy> proxy);
// Initializes the body after the handler slot.
inline void InitializeBody(int object_size, Object* value);
// Invoke a trap by name. If the trap does not exist on this's handler,
// but derived_trap is non-NULL, invoke that instead. May cause GC.
MUST_USE_RESULT static MaybeHandle<Object> CallTrap(
Handle<JSProxy> proxy,
const char* name,
Handle<Object> derived_trap,
int argc,
Handle<Object> args[]);
// Dispatched behavior. // Dispatched behavior.
DECLARE_PRINTER(JSProxy) DECLARE_PRINTER(JSProxy)
DECLARE_VERIFIER(JSProxy) DECLARE_VERIFIER(JSProxy)
...@@ -9618,22 +9606,22 @@ class JSProxy: public JSReceiver { ...@@ -9618,22 +9606,22 @@ class JSProxy: public JSReceiver {
// Layout description. We add padding so that a proxy has the same // Layout description. We add padding so that a proxy has the same
// size as a virgin JSObject. This is essential for becoming a JSObject // size as a virgin JSObject. This is essential for becoming a JSObject
// upon freeze. // upon freeze.
static const int kHandlerOffset = HeapObject::kHeaderSize; static const int kTargetOffset = HeapObject::kHeaderSize;
static const int kHandlerOffset = kTargetOffset + kPointerSize;
static const int kHashOffset = kHandlerOffset + kPointerSize; static const int kHashOffset = kHandlerOffset + kPointerSize;
static const int kPaddingOffset = kHashOffset + kPointerSize; static const int kSize = kHashOffset + kPointerSize;
static const int kSize = JSObject::kHeaderSize;
static const int kHeaderSize = kPaddingOffset;
static const int kPaddingSize = kSize - kPaddingOffset;
STATIC_ASSERT(kPaddingSize >= 0);
typedef FixedBodyDescriptor<kHandlerOffset, typedef FixedBodyDescriptor<kTargetOffset, kSize, kSize> BodyDescriptor;
kPaddingOffset,
kSize> BodyDescriptor;
private: private:
friend class JSReceiver; friend class JSReceiver;
// Invoke a trap by name. If the trap does not exist on this's handler,
// but derived_trap is non-NULL, invoke that instead. May cause GC.
MUST_USE_RESULT static MaybeHandle<Object> CallTrap(
Handle<JSProxy> proxy, const char* name, Handle<Object> derived_trap,
int argc, Handle<Object> args[]);
MUST_USE_RESULT static Maybe<bool> HasPropertyWithHandler( MUST_USE_RESULT static Maybe<bool> HasPropertyWithHandler(
Handle<JSProxy> proxy, Handle<Name> name); Handle<JSProxy> proxy, Handle<Name> name);
...@@ -9663,17 +9651,11 @@ class JSFunctionProxy: public JSProxy { ...@@ -9663,17 +9651,11 @@ class JSFunctionProxy: public JSProxy {
DECLARE_VERIFIER(JSFunctionProxy) DECLARE_VERIFIER(JSFunctionProxy)
// Layout description. // Layout description.
static const int kCallTrapOffset = JSProxy::kPaddingOffset; static const int kCallTrapOffset = JSProxy::kSize;
static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize; static const int kConstructTrapOffset = kCallTrapOffset + kPointerSize;
static const int kPaddingOffset = kConstructTrapOffset + kPointerSize; static const int kSize = kConstructTrapOffset + kPointerSize;
static const int kSize = JSFunction::kSize;
static const int kPaddingSize = kSize - kPaddingOffset;
STATIC_ASSERT(kPaddingSize >= 0); typedef FixedBodyDescriptor<kTargetOffset, kSize, kSize> BodyDescriptor;
typedef FixedBodyDescriptor<kHandlerOffset,
kConstructTrapOffset + kPointerSize,
kSize> BodyDescriptor;
private: private:
DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy); DISALLOW_IMPLICIT_CONSTRUCTORS(JSFunctionProxy);
......
...@@ -13,24 +13,26 @@ namespace internal { ...@@ -13,24 +13,26 @@ namespace internal {
RUNTIME_FUNCTION(Runtime_CreateJSProxy) { RUNTIME_FUNCTION(Runtime_CreateJSProxy) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK(args.length() == 2); DCHECK(args.length() == 3);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 2);
if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
return *isolate->factory()->NewJSProxy(handler, prototype); return *isolate->factory()->NewJSProxy(target, handler, prototype);
} }
RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) { RUNTIME_FUNCTION(Runtime_CreateJSFunctionProxy) {
HandleScope scope(isolate); HandleScope scope(isolate);
DCHECK(args.length() == 4); DCHECK(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 0); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, target, 0);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, call_trap, 1); CONVERT_ARG_HANDLE_CHECKED(JSReceiver, handler, 1);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, call_trap, 2);
RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy()); RUNTIME_ASSERT(call_trap->IsJSFunction() || call_trap->IsJSFunctionProxy());
CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 2); CONVERT_ARG_HANDLE_CHECKED(JSFunction, construct_trap, 3);
CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 3); CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 4);
if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value(); if (!prototype->IsJSReceiver()) prototype = isolate->factory()->null_value();
return *isolate->factory()->NewJSFunctionProxy(handler, call_trap, return *isolate->factory()->NewJSFunctionProxy(target, handler, call_trap,
construct_trap, prototype); construct_trap, prototype);
} }
...@@ -74,13 +76,5 @@ RUNTIME_FUNCTION(Runtime_GetConstructTrap) { ...@@ -74,13 +76,5 @@ RUNTIME_FUNCTION(Runtime_GetConstructTrap) {
return proxy->construct_trap(); return proxy->construct_trap();
} }
RUNTIME_FUNCTION(Runtime_Fix) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSProxy, proxy, 0);
JSProxy::Fix(proxy);
return isolate->heap()->undefined_value();
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -542,14 +542,13 @@ namespace internal { ...@@ -542,14 +542,13 @@ namespace internal {
F(BitwiseXor_Strong, 2, 1) F(BitwiseXor_Strong, 2, 1)
#define FOR_EACH_INTRINSIC_PROXY(F) \ #define FOR_EACH_INTRINSIC_PROXY(F) \
F(CreateJSProxy, 2, 1) \ F(CreateJSProxy, 3, 1) \
F(CreateJSFunctionProxy, 4, 1) \ F(CreateJSFunctionProxy, 5, 1) \
F(IsJSProxy, 1, 1) \ F(IsJSProxy, 1, 1) \
F(IsJSFunctionProxy, 1, 1) \ F(IsJSFunctionProxy, 1, 1) \
F(GetHandler, 1, 1) \ F(GetHandler, 1, 1) \
F(GetCallTrap, 1, 1) \ F(GetCallTrap, 1, 1) \
F(GetConstructTrap, 1, 1) \ F(GetConstructTrap, 1, 1)
F(Fix, 1, 1)
#define FOR_EACH_INTRINSIC_REGEXP(F) \ #define FOR_EACH_INTRINSIC_REGEXP(F) \
......
This diff is collapsed.
...@@ -70,9 +70,10 @@ function TestSet2(construct, fix, create) { ...@@ -70,9 +70,10 @@ function TestSet2(construct, fix, create) {
assertFalse(s.has(p3)); assertFalse(s.has(p3));
} }
TestSet(Set, Object.seal) // TODO(neis): Reenable once proxies properly support these operations.
TestSet(Set, Object.freeze) // TestSet(Set, Object.seal)
TestSet(Set, Object.preventExtensions) // TestSet(Set, Object.freeze)
// TestSet(Set, Object.preventExtensions)
// Maps and weak maps. // Maps and weak maps.
...@@ -113,10 +114,12 @@ function TestMap2(construct, fix, create) { ...@@ -113,10 +114,12 @@ function TestMap2(construct, fix, create) {
assertSame(undefined, m.get(p2)); assertSame(undefined, m.get(p2));
} }
TestMap(Map, Object.seal) // TODO(neis): Reenable once proxies properly support these operations.
TestMap(Map, Object.freeze) // TestMap(Map, Object.seal)
TestMap(Map, Object.preventExtensions) // TestMap(Map, Object.freeze)
// TestMap(Map, Object.preventExtensions)
TestMap(WeakMap, Object.seal) // TODO(neis): Reenable once proxies properly support these operations.
TestMap(WeakMap, Object.freeze) // TestMap(WeakMap, Object.seal)
TestMap(WeakMap, Object.preventExtensions) // TestMap(WeakMap, Object.freeze)
// TestMap(WeakMap, Object.preventExtensions)
...@@ -1824,59 +1824,61 @@ TestKeysThrow({ ...@@ -1824,59 +1824,61 @@ TestKeysThrow({
// Object.isFrozen, Object.isSealed, Object.isExtensible) // Object.isFrozen, Object.isSealed, Object.isExtensible)
function TestFix(names, handler) { function TestFix(names, handler) {
var proto = {p: 77} // TODO(neis): Reenable/adapt once proxies properly support these operations.
var assertFixing = function(o, s, f, e) { //
assertEquals(s, Object.isSealed(o)) // var proto = {p: 77}
assertEquals(f, Object.isFrozen(o)) // var assertFixing = function(o, s, f, e) {
assertEquals(e, Object.isExtensible(o)) // assertEquals(s, Object.isSealed(o))
} // assertEquals(f, Object.isFrozen(o))
// assertEquals(e, Object.isExtensible(o))
var p1 = Proxy.create(handler, proto) // }
assertFixing(p1, false, false, true) //
Object.seal(p1) // var p1 = Proxy.create(handler, proto)
assertFixing(p1, true, names.length === 0, false) // assertFixing(p1, false, false, true)
assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p1).sort()) // Object.seal(p1)
assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(), // assertFixing(p1, true, names.length === 0, false)
Object.keys(p1).sort()) // assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p1).sort())
assertEquals(proto, Object.getPrototypeOf(p1)) // assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
assertEquals(77, p1.p) // Object.keys(p1).sort())
for (var n in p1) { // assertEquals(proto, Object.getPrototypeOf(p1))
var desc = Object.getOwnPropertyDescriptor(p1, n) // assertEquals(77, p1.p)
if (desc !== undefined) assertFalse(desc.configurable) // for (var n in p1) {
} // var desc = Object.getOwnPropertyDescriptor(p1, n)
// if (desc !== undefined) assertFalse(desc.configurable)
var p2 = Proxy.create(handler, proto) // }
assertFixing(p2, false, false, true) //
Object.freeze(p2) // var p2 = Proxy.create(handler, proto)
assertFixing(p2, true, true, false) // assertFixing(p2, false, false, true)
assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p2).sort()) // Object.freeze(p2)
assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(), // assertFixing(p2, true, true, false)
Object.keys(p2).sort()) // assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p2).sort())
assertEquals(proto, Object.getPrototypeOf(p2)) // assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
assertEquals(77, p2.p) // Object.keys(p2).sort())
for (var n in p2) { // assertEquals(proto, Object.getPrototypeOf(p2))
var desc = Object.getOwnPropertyDescriptor(p2, n) // assertEquals(77, p2.p)
if (desc !== undefined) assertFalse(desc.writable) // for (var n in p2) {
if (desc !== undefined) assertFalse(desc.configurable) // var desc = Object.getOwnPropertyDescriptor(p2, n)
} // if (desc !== undefined) assertFalse(desc.writable)
// if (desc !== undefined) assertFalse(desc.configurable)
var p3 = Proxy.create(handler, proto) // }
assertFixing(p3, false, false, true) //
Object.preventExtensions(p3) // var p3 = Proxy.create(handler, proto)
assertFixing(p3, names.length === 0, names.length === 0, false) // assertFixing(p3, false, false, true)
assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p3).sort()) // Object.preventExtensions(p3)
assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(), // assertFixing(p3, names.length === 0, names.length === 0, false)
Object.keys(p3).sort()) // assertArrayEquals(names.sort(), Object.getOwnPropertyNames(p3).sort())
assertEquals(proto, Object.getPrototypeOf(p3)) // assertArrayEquals(names.filter(function(x) {return x < "z"}).sort(),
assertEquals(77, p3.p) // Object.keys(p3).sort())
// assertEquals(proto, Object.getPrototypeOf(p3))
var p = Proxy.create(handler, proto) // assertEquals(77, p3.p)
var o = Object.create(p) //
assertFixing(p, false, false, true) // var p = Proxy.create(handler, proto)
assertFixing(o, false, false, true) // var o = Object.create(p)
Object.freeze(o) // assertFixing(p, false, false, true)
assertFixing(p, false, false, true) // assertFixing(o, false, false, true)
assertFixing(o, true, true, false) // Object.freeze(o)
// assertFixing(p, false, false, true)
// assertFixing(o, true, true, false)
} }
TestFix([], { TestFix([], {
...@@ -1912,23 +1914,25 @@ TestFix(["b"], { ...@@ -1912,23 +1914,25 @@ TestFix(["b"], {
function TestFixFunction(fix) { function TestFixFunction(fix) {
var f1 = Proxy.createFunction({ // TODO(neis): Reenable/adapt once proxies properly support these operations.
fix: function() { return {} } //
}, function() {}) // var f1 = Proxy.createFunction({
fix(f1) // fix: function() { return {} }
assertEquals(0, f1.length) // }, function() {})
// fix(f1)
var f2 = Proxy.createFunction({ // assertEquals(0, f1.length)
fix: function() { return {length: {value: 3}} } //
}, function() {}) // var f2 = Proxy.createFunction({
fix(f2) // fix: function() { return {length: {value: 3}} }
assertEquals(3, f2.length) // }, function() {})
// fix(f2)
var f3 = Proxy.createFunction({ // assertEquals(3, f2.length)
fix: function() { return {length: {value: "huh"}} } //
}, function() {}) // var f3 = Proxy.createFunction({
fix(f3) // fix: function() { return {length: {value: "huh"}} }
assertEquals(0, f1.length) // }, function() {})
// fix(f3)
// assertEquals(0, f1.length)
} }
TestFixFunction(Object.seal) TestFixFunction(Object.seal)
...@@ -1941,10 +1945,12 @@ function TestFixThrow(handler) { ...@@ -1941,10 +1945,12 @@ function TestFixThrow(handler) {
} }
function TestFixThrow2(create, handler) { function TestFixThrow2(create, handler) {
var p = create(handler, {}) // TODO(neis): Reenable/adapt once proxies properly support these operations.
assertThrows(function(){ Object.seal(p) }, "myexn") //
assertThrows(function(){ Object.freeze(p) }, "myexn") // var p = create(handler, {})
assertThrows(function(){ Object.preventExtensions(p) }, "myexn") // assertThrows(function(){ Object.seal(p) }, "myexn")
// assertThrows(function(){ Object.freeze(p) }, "myexn")
// assertThrows(function(){ Object.preventExtensions(p) }, "myexn")
} }
TestFixThrow({ TestFixThrow({
...@@ -1971,9 +1977,11 @@ TestFixThrow({ ...@@ -1971,9 +1977,11 @@ TestFixThrow({
// TODO(rossberg): actual behaviour not specified consistently at the moment, // TODO(rossberg): actual behaviour not specified consistently at the moment,
// just make sure that we do not crash. // just make sure that we do not crash.
function TestReentrantFix(f) { function TestReentrantFix(f) {
TestWithProxies(f, Object.freeze) // TODO(neis): Reenable/adapt once proxies properly support these operations.
TestWithProxies(f, Object.seal) //
TestWithProxies(f, Object.preventExtensions) // TestWithProxies(f, Object.freeze)
// TestWithProxies(f, Object.seal)
// TestWithProxies(f, Object.preventExtensions)
} }
TestReentrantFix(function(create, freeze) { TestReentrantFix(function(create, freeze) {
......
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
// //
// Flags: --harmony-proxies --harmony-object-observe // Flags: --harmony-proxies --harmony-object-observe
var proxy = Proxy.create({ fix: function() { return {}; } }); // TODO(neis): These tests are temporarily commented out because of ongoing
Object.preventExtensions(proxy); // changes to the implementation of proxies.
Object.observe(proxy, function(){});
var functionProxy = Proxy.createFunction({ fix: function() { return {}; } }, function(){}); //var proxy = Proxy.create({ fix: function() { return {}; } });
Object.preventExtensions(functionProxy); //Object.preventExtensions(proxy);
Object.observe(functionProxy, function(){}); //Object.observe(proxy, function(){});
//
//var functionProxy = Proxy.createFunction({ fix: function() { return {}; } }, function(){});
//Object.preventExtensions(functionProxy);
//Object.observe(functionProxy, function(){});
...@@ -80,19 +80,21 @@ var childObjAccessor2 = { set foo(_){}, set "1"(_){}, __proto__: proxy2 }; ...@@ -80,19 +80,21 @@ var childObjAccessor2 = { set foo(_){}, set "1"(_){}, __proto__: proxy2 };
// semantics. // semantics.
Object.freeze(baseObj); Object.freeze(baseObj);
Object.freeze(proxy1); // TODO(neis): Reenable once proxies properly support freeze.
assertThrows(function(){proxy1.foo}, TypeError); //
assertThrows(function(){proxy1[1]}, TypeError); // Object.freeze(proxy1);
assertThrows(function(){childObj1.foo}, TypeError); // assertThrows(function(){proxy1.foo}, TypeError);
assertThrows(function(){childObj1[1]}, TypeError); // assertThrows(function(){proxy1[1]}, TypeError);
assertThrows(function(){childObjAccessor1.foo}, TypeError); // assertThrows(function(){childObj1.foo}, TypeError);
assertThrows(function(){childObjAccessor1[1]}, TypeError); // assertThrows(function(){childObj1[1]}, TypeError);
// assertThrows(function(){childObjAccessor1.foo}, TypeError);
Object.freeze(proxy2); // assertThrows(function(){childObjAccessor1[1]}, TypeError);
assertThrows(function(){proxy2.foo}, TypeError); //
assertThrows(function(){proxy2[1]}, TypeError); // Object.freeze(proxy2);
assertThrows(function(){childObj2.foo}, TypeError); // assertThrows(function(){proxy2.foo}, TypeError);
assertThrows(function(){childObj2[1]}, TypeError); // assertThrows(function(){proxy2[1]}, TypeError);
assertThrows(function(){childObjAccessor2.foo}, TypeError); // assertThrows(function(){childObj2.foo}, TypeError);
assertThrows(function(){childObjAccessor2[1]}, TypeError); // assertThrows(function(){childObj2[1]}, TypeError);
// assertThrows(function(){childObjAccessor2.foo}, TypeError);
// assertThrows(function(){childObjAccessor2[1]}, TypeError);
})(); })();
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