1160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org// Copyright 2011 the V8 project authors. All rights reserved. 23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be 33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file. 4160a7b0747492f3f735353d9582521f3314bf4dfdanno@chromium.org 5f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org"use strict"; 6f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org 7e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// This file relies on the fact that the following declaration has been made 8e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// in runtime.js: 9e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// var $Object = global.Object; 107304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 11e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgvar $Proxy = new $Object(); 12e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 13e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// ------------------------------------------------------------------- 147304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org 1572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgfunction ProxyCreate(handler, proto) { 16d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com if (!IS_SPEC_OBJECT(handler)) 17d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com throw MakeTypeError("handler_non_object", ["create"]) 18394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (IS_UNDEFINED(proto)) 19394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com proto = null 20690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org else if (!(IS_SPEC_OBJECT(proto) || IS_NULL(proto))) 21394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com throw MakeTypeError("proto_non_object", ["create"]) 227304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org return %CreateJSProxy(handler, proto) 237304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org} 24ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 2572204d59e7fb1b8a0e9012e1fac5ef160351e8e4danno@chromium.orgfunction ProxyCreateFunction(handler, callTrap, constructTrap) { 2634e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (!IS_SPEC_OBJECT(handler)) 2734e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org throw MakeTypeError("handler_non_object", ["create"]) 2834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (!IS_SPEC_FUNCTION(callTrap)) 2934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org throw MakeTypeError("trap_function_expected", ["createFunction", "call"]) 3034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org if (IS_UNDEFINED(constructTrap)) { 31394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com constructTrap = DerivedConstructTrap(callTrap) 32c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else if (IS_SPEC_FUNCTION(constructTrap)) { 33394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com // Make sure the trap receives 'undefined' as this. 34394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com var construct = constructTrap 35394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com constructTrap = function() { 36690083842e7c67a362017dae50909d4bb0b2a9c2mstarzinger@chromium.org return %Apply(construct, UNDEFINED, arguments, 0, %_ArgumentsLength()); 37c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 38c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } else { 3934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org throw MakeTypeError("trap_function_expected", 4034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org ["createFunction", "construct"]) 4134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 4234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return %CreateJSFunctionProxy( 43394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com handler, callTrap, constructTrap, $Function.prototype) 4434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 45ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 46e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 47e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// ------------------------------------------------------------------- 48e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 49e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgfunction SetUpProxy() { 50e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org %CheckIsBootstrapping() 51e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 5258a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org var global_proxy = %GlobalProxy(global); 5358a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org global_proxy.Proxy = $Proxy; 54e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 55e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org // Set up non-enumerable properties of the Proxy object. 56e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org InstallFunctions($Proxy, DONT_ENUM, [ 57e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "create", ProxyCreate, 58e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org "createFunction", ProxyCreateFunction 59e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org ]) 60e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org} 61e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org 62e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgSetUpProxy(); 63ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 64ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 65e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// ------------------------------------------------------------------- 66e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org// Proxy Builtins 67ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org 68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comfunction DerivedConstructTrap(callTrap) { 69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return function() { 70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com var proto = this.prototype 71c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype 72750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org var obj = { __proto__: proto }; 73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com var result = %Apply(callTrap, obj, arguments, 0, %_ArgumentsLength()); 74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com return IS_SPEC_OBJECT(result) ? result : obj 75c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com } 76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com} 77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com 7834e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.orgfunction DelegateCallAndConstruct(callTrap, constructTrap) { 7934e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return function() { 8034e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org return %Apply(%_IsConstructCall() ? constructTrap : callTrap, 8134e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org this, arguments, 0, %_ArgumentsLength()) 8234e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org } 8334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org} 8434e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org 85ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.orgfunction DerivedGetTrap(receiver, name) { 86ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org var desc = this.getPropertyDescriptor(name) 87d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (IS_UNDEFINED(desc)) { return desc } 88ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org if ('value' in desc) { 89ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org return desc.value 90ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } else { 91d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (IS_UNDEFINED(desc.get)) { return desc.get } 92d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // The proposal says: desc.get.call(receiver) 93d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return %_CallFunction(receiver, desc.get) 94ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org } 95ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org} 96d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org 97d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.orgfunction DerivedSetTrap(receiver, name, val) { 98d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org var desc = this.getOwnPropertyDescriptor(name) 99d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (desc) { 100d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if ('writable' in desc) { 101d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (desc.writable) { 102d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org desc.value = val 103d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org this.defineProperty(name, desc) 104d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return true 105d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } else { 106d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return false 107d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 108d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } else { // accessor 109d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (desc.set) { 110d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // The proposal says: desc.set.call(receiver, val) 111d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org %_CallFunction(receiver, val, desc.set) 112d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return true 113d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } else { 114d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return false 115d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 116d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 117d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 118d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org desc = this.getPropertyDescriptor(name) 119d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (desc) { 120d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if ('writable' in desc) { 121d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (desc.writable) { 122d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // fall through 123d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } else { 124d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return false 125d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 126d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } else { // accessor 127d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org if (desc.set) { 128d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org // The proposal says: desc.set.call(receiver, val) 129d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org %_CallFunction(receiver, val, desc.set) 130d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return true 131d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } else { 132d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return false 133d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 134d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 135d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org } 136d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org this.defineProperty(name, { 137d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org value: val, 138d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org writable: true, 139d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org enumerable: true, 140d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org configurable: true}); 141d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org return true; 142d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org} 143d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com 144d6076d96a1411932548838e5960b594564264010erik.corry@gmail.comfunction DerivedHasTrap(name) { 145d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com return !!this.getPropertyDescriptor(name) 146d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com} 147030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org 1489fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.orgfunction DerivedHasOwnTrap(name) { 1499fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org return !!this.getOwnPropertyDescriptor(name) 1509fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org} 1519fa09679c31dd1fc79a07ed24431b6951227240aricow@chromium.org 152030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.orgfunction DerivedKeysTrap() { 153030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org var names = this.getOwnPropertyNames() 154030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org var enumerableNames = [] 155030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org for (var i = 0, count = 0; i < names.length; ++i) { 156030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org var name = names[i] 157750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IS_SYMBOL(name)) continue 158394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com var desc = this.getOwnPropertyDescriptor(TO_STRING_INLINE(name)) 159394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (!IS_UNDEFINED(desc) && desc.enumerable) { 160030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org enumerableNames[count++] = names[i] 161030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org } 162030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org } 163030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org return enumerableNames 164030d38ee536bc25856546e75fdac60d1a0c42bddwhesse@chromium.org} 165394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 166394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comfunction DerivedEnumerateTrap() { 167394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com var names = this.getPropertyNames() 168394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com var enumerableNames = [] 169394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com for (var i = 0, count = 0; i < names.length; ++i) { 170394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com var name = names[i] 171750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org if (IS_SYMBOL(name)) continue 172394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com var desc = this.getPropertyDescriptor(TO_STRING_INLINE(name)) 173ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (!IS_UNDEFINED(desc)) { 174ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (!desc.configurable) { 175ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org throw MakeTypeError("proxy_prop_not_configurable", 176ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org [this, "getPropertyDescriptor", name]) 177ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org } 178ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org if (desc.enumerable) enumerableNames[count++] = names[i] 179394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 180394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 181394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return enumerableNames 182394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 183394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com 184394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.comfunction ProxyEnumerate(proxy) { 185394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com var handler = %GetHandler(proxy) 186394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com if (IS_UNDEFINED(handler.enumerate)) { 187394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com return %Apply(DerivedEnumerateTrap, handler, [], 0, 0) 188394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } else { 189750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org return ToNameArray(handler.enumerate(), "enumerate", false) 190394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com } 191394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com} 192