1// Copyright 2016 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "src/v8.h" 6 7#include "test/cctest/cctest.h" 8 9namespace { 10 11int* global_use_counts = NULL; 12 13void MockUseCounterCallback(v8::Isolate* isolate, 14 v8::Isolate::UseCounterFeature feature) { 15 ++global_use_counts[feature]; 16} 17} 18 19TEST(DefineGetterSetterThrowUseCount) { 20 v8::Isolate* isolate = CcTest::isolate(); 21 v8::HandleScope scope(isolate); 22 LocalContext env; 23 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; 24 global_use_counts = use_counts; 25 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); 26 27 // __defineGetter__ and __defineSetter__ do not increment 28 // kDefineGetterOrSetterWouldThrow on success 29 CompileRun( 30 "var a = {};" 31 "Object.defineProperty(a, 'b', { value: 0, configurable: true });" 32 "a.__defineGetter__('b', ()=>{});"); 33 CHECK_EQ(0, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]); 34 CompileRun( 35 "var a = {};" 36 "Object.defineProperty(a, 'b', { value: 0, configurable: true });" 37 "a.__defineSetter__('b', ()=>{});"); 38 CHECK_EQ(0, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]); 39 40 // __defineGetter__ and __defineSetter__ do not increment 41 // kDefineGetterOrSetterWouldThrow on other errors 42 v8::Local<v8::Value> resultProxyThrow = CompileRun( 43 "var exception;" 44 "try {" 45 "var a = new Proxy({}, { defineProperty: ()=>{throw new Error;} });" 46 "a.__defineGetter__('b', ()=>{});" 47 "} catch (e) { exception = e; }" 48 "exception"); 49 CHECK_EQ(0, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]); 50 CHECK(resultProxyThrow->IsObject()); 51 resultProxyThrow = CompileRun( 52 "var exception;" 53 "try {" 54 "var a = new Proxy({}, { defineProperty: ()=>{throw new Error;} });" 55 "a.__defineSetter__('b', ()=>{});" 56 "} catch (e) { exception = e; }" 57 "exception"); 58 CHECK_EQ(0, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]); 59 CHECK(resultProxyThrow->IsObject()); 60 61 // __defineGetter__ and __defineSetter__ increment 62 // kDefineGetterOrSetterWouldThrow when they would throw per spec (B.2.2.2) 63 CompileRun( 64 "var a = {};" 65 "Object.defineProperty(a, 'b', { value: 0, configurable: false });" 66 "a.__defineGetter__('b', ()=>{});"); 67 CHECK_EQ(1, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]); 68 CompileRun( 69 "var a = {};" 70 "Object.defineProperty(a, 'b', { value: 0, configurable: false });" 71 "a.__defineSetter__('b', ()=>{});"); 72 CHECK_EQ(2, use_counts[v8::Isolate::kDefineGetterOrSetterWouldThrow]); 73} 74