github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/v8/lib/instruction_counter.cc (about) 1 // Copyright (C) 2017 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // the go-nebulas library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with the go-nebulas library. If not, see 17 // <http://www.gnu.org/licenses/>. 18 // 19 20 #include "instruction_counter.h" 21 #include "logger.h" 22 23 static char sInstructionCounter[] = "_instruction_counter"; 24 25 static InstructionCounterIncrListener sListener = NULL; 26 27 void NewInstructionCounterInstance(Isolate *isolate, Local<Context> context, 28 size_t *counter, void *listenerContext) { 29 Local<ObjectTemplate> counterTpl = ObjectTemplate::New(isolate); 30 counterTpl->SetInternalFieldCount(2); 31 32 counterTpl->Set(String::NewFromUtf8(isolate, "incr"), 33 FunctionTemplate::New(isolate, IncrCounterCallback), 34 static_cast<PropertyAttribute>(PropertyAttribute::DontDelete | 35 PropertyAttribute::ReadOnly)); 36 37 counterTpl->SetAccessor( 38 String::NewFromUtf8(isolate, "count"), CountGetterCallback, 0, 39 Local<Value>(), DEFAULT, 40 static_cast<PropertyAttribute>(PropertyAttribute::DontDelete | 41 PropertyAttribute::ReadOnly)); 42 43 Local<Object> instance = counterTpl->NewInstance(context).ToLocalChecked(); 44 instance->SetInternalField(0, External::New(isolate, counter)); 45 instance->SetInternalField(1, External::New(isolate, listenerContext)); 46 47 context->Global()->DefineOwnProperty( 48 context, String::NewFromUtf8(isolate, sInstructionCounter), instance, 49 static_cast<PropertyAttribute>(PropertyAttribute::DontDelete | 50 PropertyAttribute::ReadOnly)); 51 } 52 53 void IncrCounterCallback(const FunctionCallbackInfo<Value> &info) { 54 Isolate *isolate = info.GetIsolate(); 55 Local<Object> thisArg = info.Holder(); 56 Local<External> count = Local<External>::Cast(thisArg->GetInternalField(0)); 57 Local<External> listenerContext = 58 Local<External>::Cast(thisArg->GetInternalField(1)); 59 60 if (info.Length() < 1) { 61 isolate->ThrowException( 62 Exception::Error(String::NewFromUtf8(isolate, "incr: mssing params"))); 63 return; 64 } 65 66 Local<Value> arg = info[0]; 67 if (!arg->IsNumber()) { 68 isolate->ThrowException(Exception::Error( 69 String::NewFromUtf8(isolate, "incr: value must be number"))); 70 return; 71 } 72 73 // always return true. 74 info.GetReturnValue().Set(true); 75 76 int32_t val = arg->Int32Value(); 77 if (val < 0) { 78 return; 79 } 80 81 size_t *cnt = static_cast<size_t *>(count->Value()); 82 *cnt += val; 83 84 if (sListener != NULL) { 85 sListener(isolate, *cnt, listenerContext->Value()); 86 } 87 } 88 89 void CountGetterCallback(Local<String> property, 90 const PropertyCallbackInfo<Value> &info) { 91 Isolate *isolate = info.GetIsolate(); 92 Local<Object> thisArg = info.Holder(); 93 Local<External> count = Local<External>::Cast(thisArg->GetInternalField(0)); 94 95 size_t *cnt = static_cast<size_t *>(count->Value()); 96 info.GetReturnValue().Set(Number::New(isolate, (double)*cnt)); 97 } 98 99 void IncrCounter(Isolate *isolate, Local<Context> context, size_t val) { 100 if (val == 0) { 101 return; 102 } 103 104 Local<Object> global = context->Global(); 105 HandleScope handle_scope(isolate); 106 107 Local<Object> counter = Local<Object>::Cast( 108 global->Get(String::NewFromUtf8(isolate, sInstructionCounter))); 109 110 Local<External> count = Local<External>::Cast(counter->GetInternalField(0)); 111 Local<External> listenerContext = 112 Local<External>::Cast(counter->GetInternalField(1)); 113 114 size_t *cnt = static_cast<size_t *>(count->Value()); 115 *cnt += val; 116 117 if (sListener != NULL) { 118 sListener(isolate, *cnt, listenerContext->Value()); 119 } 120 } 121 122 void SetInstructionCounterIncrListener( 123 InstructionCounterIncrListener listener) { 124 sListener = listener; 125 }