Home | History | Annotate | Download | only in cctest
      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 
      9 namespace {
     10 
     11 int* global_use_counts = NULL;
     12 
     13 void MockUseCounterCallback(v8::Isolate* isolate,
     14                             v8::Isolate::UseCounterFeature feature) {
     15   ++global_use_counts[feature];
     16 }
     17 }
     18 
     19 TEST(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