// Copyright 2019 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: --allow-natives-syntax var get_count = 0; var has_count = 0; var property_descriptor_count = 0; globalThis.__proto__ = new Proxy({}, {get() {get_count++}, has() {has_count++;}, getOwnPropertyDescriptor() {property_desciptor_count++}}); function checkCounts(count) { assertEquals(has_count, count); assertEquals(get_count, 0); assertEquals(property_descriptor_count, 0); } function load_lookup_global_error() { eval("var b = 10"); x; } assertThrows(load_lookup_global_error, ReferenceError); checkCounts(1); %EnsureFeedbackVectorForFunction(load_lookup_global_error); assertThrows(load_lookup_global_error, ReferenceError); checkCounts(2); assertThrows(load_lookup_global_error, ReferenceError); checkCounts(3); function load_global_error() { x; } assertThrows(load_global_error, ReferenceError); checkCounts(4); %EnsureFeedbackVectorForFunction(load_global_error); assertThrows(load_global_error, ReferenceError); checkCounts(5); assertThrows(load_global_error, ReferenceError); checkCounts(6); // Check when the object is present on the proxy. get_count = 0; has_count = 0; property_descriptor_count = 0; globalThis.__proto__ = new Proxy({}, {get() {get_count++; return 10;}, has() {has_count++; return true;}, getOwnPropertyDescriptor() {property_desciptor_count++}}); function checkCountsWithGet(count) { assertEquals(has_count, count); assertEquals(get_count, count); assertEquals(property_descriptor_count, 0); } function load_lookup_global() { eval("var b = 10"); return x; } assertEquals(load_lookup_global(), 10); checkCountsWithGet(1); %EnsureFeedbackVectorForFunction(load_lookup_global); assertEquals(load_lookup_global(), 10); checkCountsWithGet(2); assertEquals(load_lookup_global(), 10); checkCountsWithGet(3); function load_global() { return x; } assertEquals(load_global(), 10); checkCountsWithGet(4); %EnsureFeedbackVectorForFunction(load_global); assertEquals(load_global(), 10); checkCountsWithGet(5); assertEquals(load_global(), 10); checkCountsWithGet(6); // Check unbound variable access inside typeof get_count = 0; has_count = 0; property_descriptor_count = 0; globalThis.__proto__ = new Proxy({}, {get() {get_count++}, has() {has_count++;}, getOwnPropertyDescriptor() {property_desciptor_count++}}); function checkCountsInsideTypeof(count) { assertEquals(has_count, count); assertEquals(get_count, 0); assertEquals(property_descriptor_count, 0); } function load_lookup_inside_typeof() { eval("var b = 10"); return typeof(x); } assertEquals(load_lookup_inside_typeof(), "undefined"); checkCountsInsideTypeof(1); %EnsureFeedbackVectorForFunction(load_lookup_inside_typeof); assertEquals(load_lookup_inside_typeof(), "undefined"); checkCountsInsideTypeof(2); assertEquals(load_lookup_inside_typeof(), "undefined"); checkCountsInsideTypeof(3); function load_inside_typeof() { return typeof(x); } assertEquals(load_inside_typeof(), "undefined"); checkCountsInsideTypeof(4); %EnsureFeedbackVectorForFunction(load_inside_typeof); assertEquals(load_inside_typeof(), "undefined"); checkCountsInsideTypeof(5); assertEquals(load_inside_typeof(), "undefined"); checkCountsInsideTypeof(6); // Check bound variable access inside typeof get_count = 0; has_count = 0; property_descriptor_count = 0; globalThis.__proto__ = new Proxy({}, {get() {get_count++; return 10;}, has() {has_count++; return true;}, getOwnPropertyDescriptor() {property_desciptor_count++}}); function checkCountsBoundVarInsideTypeof(count) { assertEquals(has_count, count); assertEquals(get_count, count); assertEquals(property_descriptor_count, 0); } function load_lookup_number_inside_typeof() { eval("var b = 10"); return typeof(x); } assertEquals(load_lookup_number_inside_typeof(), "number"); checkCountsBoundVarInsideTypeof(1); %EnsureFeedbackVectorForFunction(load_lookup_number_inside_typeof); assertEquals(load_lookup_number_inside_typeof(), "number"); checkCountsBoundVarInsideTypeof(2); assertEquals(load_lookup_number_inside_typeof(), "number"); checkCountsBoundVarInsideTypeof(3); function load_number_inside_typeof() { return typeof(x); } assertEquals(load_number_inside_typeof(), "number"); checkCountsBoundVarInsideTypeof(4); %EnsureFeedbackVectorForFunction(load_inside_typeof); assertEquals(load_number_inside_typeof(), "number"); checkCountsBoundVarInsideTypeof(5); assertEquals(load_number_inside_typeof(), "number"); checkCountsBoundVarInsideTypeof(6); // Check that if has property returns true we don't throw even when get property // says otherwise. globalThis.__proto__ = new Proxy({}, {has() {has_count++; return true;}, getOwnPropertyDescriptor() {property_desciptor_count++}}); function load_lookup_global_has_property() { eval("var b = 10"); return x; } assertEquals(load_lookup_global_has_property(), undefined); function load_global_has_property() { return x; } assertEquals(load_global_has_property(), undefined);