void ConnectionPool::EIO_AfterGetConnection(uv_work_t* req) {
  Nan::HandleScope scope;
  ConnectionPoolBaton* baton = CONTAINER_OF(req, ConnectionPoolBaton, work_req);

  Local<Value> argv[2];
  if (baton->error) {
    argv[0] = Nan::Error(baton->error->c_str());
    argv[1] = Nan::Undefined();
  } else {
    argv[0] = Nan::Undefined();
    Local<FunctionTemplate> ft = Nan::New(Connection::s_ct);
    Local<Object> connection = ft->GetFunction()->NewInstance();
    (Nan::ObjectWrap::Unwrap<Connection>(connection))->setConnection(
        baton->connectionPool->getEnvironment(),
        baton->connectionPool,
        baton->connection);
    argv[1] = connection;
  }

  Nan::TryCatch tryCatch;
  baton->callback->Call(2, argv);
  delete baton;

  if (tryCatch.HasCaught()) {
    Nan::FatalException(tryCatch);
  }

}
void ILob::Async_AfterWrite(uv_work_t *req)
{ 
  Nan::HandleScope scope;

  LobBaton     *lobBaton = (LobBaton *)req->data;
  ILob         *iLob = lobBaton->iLob;
  Nan::TryCatch  tc;
  Local<Value> argv[1];

  iLob->state_ = INACTIVE;     // mark Lob as inactive as back in main thread

  if(!(lobBaton->error).empty())
    argv[0] = v8::Exception::Error(Nan::New<v8::String>((lobBaton->error).c_str()).ToLocalChecked());
  else
    argv[0] = Nan::Undefined();

  Local<Function> callback = Nan::New<Function>(lobBaton->cb);
  delete lobBaton;

  Nan::MakeCallback(Nan::GetCurrentContext()->Global(), callback, 1, argv);

  if(tc.HasCaught())
  {
    Nan::FatalException(tc);
  }
}
Exemple #3
0
/*
   DESCRIPTION
     Callback function of close method

   PARAMETERS:
     UV queue work block
*/
void ILob::Async_AfterClose(uv_work_t *req)
{
  Nan::HandleScope scope;

  LobBaton         *lobBaton = ( LobBaton * ) req->data;
  ILob             *iLob = lobBaton->iLob;
  Nan::TryCatch    tc;

  if ( !lobBaton->errOnActiveOrInvalid )
  {
    iLob->state_ = NJS_INACTIVE;
  }

  Local<Value> argv[1];

  if( !lobBaton->error.empty () )
    argv[0] = v8::Exception::Error(
                Nan::New<v8::String> ( lobBaton->error ).ToLocalChecked () );
  else
  {
    argv[0] = Nan::Undefined ();

    iLob->cleanupNJS ();
  }

  Local<Function> callback = Nan::New<Function> ( lobBaton->cb );
  delete lobBaton;
  Nan::MakeCallback( Nan::GetCurrentContext()->Global(),
                      callback, 1, argv );

  if( tc.HasCaught () )
  {
    Nan::FatalException ( tc );
  }
}
/*
   DESCRIPTION
     Callback function of terminate

   PARAMETERS:
     UV queue work block
*/
void Pool::Async_AfterTerminate(uv_work_t *req)
{
  Nan::HandleScope scope;
  poolBaton *terminateBaton = (poolBaton*)req->data;

  Nan::TryCatch tc;

  Local<Value> argv[1];

  if(!(terminateBaton->error).empty())
  {
    argv[0] = v8::Exception::Error(Nan::New<v8::String>((terminateBaton->error).c_str()).ToLocalChecked());
  }
  else
  {
    argv[0] = Nan::Undefined();
    // pool is not valid after terminate succeeds.
    terminateBaton-> njspool-> isValid_ = false;
  }

  Local<Function> callback = Nan::New<Function>(terminateBaton->cb);
  delete terminateBaton;
  Nan::MakeCallback( Nan::GetCurrentContext()->Global(),
                      callback, 1, argv );
  if(tc.HasCaught())
  {
    Nan::FatalException(tc);
  }
}
/*
   DESCRIPTION
     Callback function of Get Connection method

   PARAMETERS:
     UV queue work block
     status - expected to be non-zero.

   NOTES:
     Connection handle is formed and handed over to JS.
*/
void Pool::Async_AfterGetConnection(uv_work_t *req)
{
  Nan::HandleScope scope;
  poolBaton *connBaton = (poolBaton*)req->data;

  Nan::TryCatch tc;
  Local<Value> argv[2];

  if(!(connBaton->error).empty())
  {
    argv[0] = v8::Exception::Error(Nan::New<v8::String>((connBaton->error).c_str()).ToLocalChecked());
    argv[1] = Nan::Undefined();
  } 
  else
  {
    argv[0] = Nan::Undefined();
    Local<FunctionTemplate> lft = Nan::New(Connection::connectionTemplate_s);
    Local<Object> connection = lft->GetFunction()-> NewInstance();
    (Nan::ObjectWrap::Unwrap<Connection> (connection))->
                                 setConnection( connBaton->dpiconn,
                                                connBaton->njspool->oracledb_ );
    argv[1] = connection;
  }

  Local<Function> callback = Nan::New<Function>(connBaton->cb);
  delete connBaton;
  Nan::MakeCallback( Nan::GetCurrentContext()->Global(),
                      callback, 2, argv );

  if(tc.HasCaught())
  {
    Nan::FatalException(tc);
  }
}
inline v8::Local<v8::Object> node::Function::construct(v8::Isolate* isolate, const v8::Local<v8::Function> &function, size_t argc, const v8::Local<v8::Value> arguments[]) {
    Nan::TryCatch trycatch;
    auto result = Nan::NewInstance(function, (int)argc, const_cast<v8::Local<v8::Value>*>(arguments));

    if (trycatch.HasCaught()) {
        throw node::Exception(isolate, trycatch.Exception());
    }
    return result.ToLocalChecked();
}
Exemple #7
0
void ILob::Async_AfterRead(uv_work_t *req)
{
  Nan::HandleScope scope;

  LobBaton     *lobBaton = (LobBaton *)req->data;
  ILob         *iLob = lobBaton->iLob;
  Nan::TryCatch  tc;
  Local<Value> argv[2];

  if ( !lobBaton->errOnActiveOrInvalid )
  {
    iLob->state_ = NJS_INACTIVE; // mark Lob as inactive as back in main thread
  }

  if(!(lobBaton->error).empty())
  {
    argv[0] = v8::Exception::Error(
                    Nan::New<v8::String>(lobBaton->error).ToLocalChecked());
    argv[1] = Nan::Undefined();
  }
  else
  {
    argv[0] = Nan::Undefined();

    if (iLob->amountRead_)
    {
      if (iLob->dpiLobType_ == DpiClob)
      {
        Local<Value> str = Nan::New<v8::String>((char *)iLob->buf_,
                                         iLob->amountRead_).ToLocalChecked();
        argv[1] = str;
      }
      else
      {
        // Blobs use buffers rather than strings
        // TODO: We could use NewBuffer to save memory and CPU, but it gets the ownership of buffer to itself (behaviour changed in Nan 2.0)
        Local<Value> buffer = Nan::CopyBuffer((char *)iLob->buf_,
                                             iLob->amountRead_).ToLocalChecked();
        argv[1] = buffer;
      }


    }
    else
      argv[1] = Nan::Null();
  }

  Local<Function> callback = Nan::New<Function>(lobBaton->cb);
  delete lobBaton;

  Nan::MakeCallback(Nan::GetCurrentContext()->Global(), callback, 2, argv);

  if(tc.HasCaught())
  {
    Nan::FatalException(tc);
  }
}
inline v8::Local<v8::Value> node::Function::callback(v8::Isolate* isolate, const v8::Local<v8::Function> &function, const v8::Local<v8::Object> &this_object, size_t argc, const v8::Local<v8::Value> arguments[]) {
    Nan::TryCatch trycatch;
    
    auto recv = this_object.IsEmpty() ? isolate->GetCurrentContext()->Global() : this_object;
    auto result = Nan::MakeCallback(recv, function, (int)argc, const_cast<v8::Local<v8::Value>*>(arguments));

    if (trycatch.HasCaught()) {
        throw node::Exception(isolate, trycatch.Exception());
    }
    return result;
}
/*
   DESCRIPTION
     Callback function of GetRows method

   PARAMETERS:
     req - UV queue work block
*/
void ResultSet::Async_AfterGetRows(uv_work_t *req)
{
  Nan::HandleScope scope;

  rsBaton *getRowsBaton = (rsBaton*)req->data;
  Nan::TryCatch tc;
  Local<Value> argv[2];

  if(!(getRowsBaton->error).empty())
  {
    argv[0] = v8::Exception::Error(
                   Nan::New<v8::String>(getRowsBaton->error).ToLocalChecked());
    argv[1] = Nan::Undefined();
  }
  else
  {
    argv[0]           = Nan::Undefined();

    eBaton* ebaton               = getRowsBaton->ebaton;
    ebaton->outFormat            = getRowsBaton->njsRS->outFormat_;
    Local<Value> rowsArray       = Nan::New<v8::Array>(0),
                 rowsArrayValue  = Nan::Null();

    if(ebaton->rowsFetched)
    {
      rowsArray = Connection::GetRows(ebaton);
      if(!(ebaton->error).empty())
      {
        argv[0] = v8::Exception::Error(
                        Nan::New<v8::String>(ebaton->error).ToLocalChecked());
        argv[1] = Nan::Undefined();
        goto exitAsyncAfterGetRows;
      }
      rowsArrayValue =  Local<Array>::Cast(rowsArray)->Get(0);
    }
    argv[1] = (getRowsBaton->fetchMultiple) ? rowsArray : rowsArrayValue;
  }

  exitAsyncAfterGetRows:
  if(!getRowsBaton->errOnActiveOrInvalid)
  {
    getRowsBaton->njsRS->state_ = NJS_INACTIVE;
  }

  Local<Function> callback = Nan::New(getRowsBaton->ebaton->cb);
  delete getRowsBaton;
  Nan::MakeCallback(Nan::GetCurrentContext()->Global(),
                  callback, 2, argv);
  if(tc.HasCaught())
  {
    Nan::FatalException(tc);
  }
}
/*
   DESCRIPTION
     Callback function of close

   PARAMETERS:
     req - UV queue work block
*/
void ResultSet::Async_AfterClose(uv_work_t *req)
{
  Nan::HandleScope scope;
  rsBaton *closeBaton = (rsBaton*)req->data;

  Nan::TryCatch tc;

  Local<Value> argv[1];

  if(!(closeBaton->error).empty())
  {
    argv[0] = v8::Exception::Error(
                   Nan::New<v8::String>(closeBaton->error).ToLocalChecked());
    if(!closeBaton->errOnActiveOrInvalid)
    {
      closeBaton->njsRS->state_ = NJS_INACTIVE;
    }
  }
  else
  {
    argv[0] = Nan::Undefined();
    // resultset is not valid after close succeeds.
    closeBaton-> njsRS-> state_ = NJS_INVALID;
  }

  /*
   * When we close the resultSet, we have to clear the reference of
   * its parent.
   */
  closeBaton->njsRS->jsParent_.Reset ();

  Local<Function> callback = Nan::New(closeBaton->ebaton->cb);
  delete closeBaton;

  Nan::MakeCallback( Nan::GetCurrentContext()->Global(), callback, 1, argv );
  if(tc.HasCaught())
  {
    Nan::FatalException(tc);
  }
}
Exemple #11
0
void Connection::EIO_AfterClose(uv_work_t* req) {
  Nan::HandleScope scope;
  ConnectionBaton* baton = CONTAINER_OF(req, ConnectionBaton, work_req);
  baton->connection->Unref();
  Nan::TryCatch tryCatch;
  if (baton->callback != NULL) {
    Local<Value> argv[2];
    if (baton->error) {
      argv[0] = Nan::Error(baton->error->c_str());
      argv[1] = Nan::Undefined();
    } else {
      argv[0] = Nan::Undefined();
      argv[1] = Nan::Undefined();
    }
    baton->callback->Call(2, argv);
  }
  delete baton;

  if (tryCatch.HasCaught()) {
    Nan::FatalException(tryCatch);
  }
}
Exemple #12
0
void EIO_AfterCallJs(uv_work_t* req, int status) {
#else
void EIO_AfterCallJs(uv_work_t* req) {
#endif
  DynamicProxyData* dynamicProxyData = static_cast<DynamicProxyData*>(req->data);
  if(!dynamicProxyDataVerify(dynamicProxyData)) {
    return;
  }
  dynamicProxyData->result = NULL;

  JNIEnv* env;
  int ret = dynamicProxyData->java->getJvm()->GetEnv((void**)&env, JNI_BEST_VERSION);
  if (ret != JNI_OK) {
    dynamicProxyData->throwableClass = "java/lang/IllegalStateException";
    dynamicProxyData->throwableMessage = "Could not retrieve JNIEnv: jvm->GetEnv returned " + to_string<int>(ret);
    dynamicProxyData->done = DYNAMIC_PROXY_JS_ERROR;
    return;
  }

  Nan::HandleScope scope;
  v8::Array* v8Args;
  v8::Function* fn;
  v8::Handle<v8::Value>* argv;
  int argc;
  int i;
  v8::Local<v8::Value> v8Result;
  jobject javaResult;

  v8::Local<v8::Object> dynamicProxyDataFunctions = Nan::New(dynamicProxyData->functions);
  v8::Local<v8::Value> fnObj = dynamicProxyDataFunctions->Get(Nan::New<v8::String>(dynamicProxyData->methodName.c_str()).ToLocalChecked());
  if(fnObj->IsUndefined() || fnObj->IsNull()) {
    dynamicProxyData->throwableClass = "java/lang/NoSuchMethodError";
    dynamicProxyData->throwableMessage = "Could not find js function " + dynamicProxyData->methodName;
    dynamicProxyData->done = DYNAMIC_PROXY_JS_ERROR;
    return;
  }
  if(!fnObj->IsFunction()) {
    dynamicProxyData->throwableClass = "java/lang/IllegalStateException";
    dynamicProxyData->throwableMessage = dynamicProxyData->methodName + " is not a function";
    dynamicProxyData->done = DYNAMIC_PROXY_JS_ERROR;
    return;
  }

  fn = v8::Function::Cast(*fnObj);

  if(dynamicProxyData->args) {
    v8Args = v8::Array::Cast(*javaArrayToV8(dynamicProxyData->java, env, dynamicProxyData->args));
    argc = v8Args->Length();
  } else {
    argc = 0;
  }
  argv = new v8::Handle<v8::Value>[argc];
  for(i=0; i<argc; i++) {
    argv[i] = v8Args->Get(i);
  }

  Nan::TryCatch tryCatch;
  tryCatch.SetCaptureMessage(true);
  v8Result = fn->Call(dynamicProxyDataFunctions, argc, argv);
  delete[] argv;
  if (tryCatch.HasCaught()) {
    dynamicProxyData->throwableClass = "node/NodeJsException";
    v8::String::Utf8Value message(tryCatch.Message()->Get());
    dynamicProxyData->throwableMessage = std::string(*message);
    tryCatch.Reset();
    dynamicProxyData->done = DYNAMIC_PROXY_JS_ERROR;
    return;
  }

  if(!dynamicProxyDataVerify(dynamicProxyData)) {
    return;
  }

  javaResult = v8ToJava(env, v8Result);
  if(javaResult == NULL) {
    dynamicProxyData->result = NULL;
  } else {
    dynamicProxyData->result = env->NewGlobalRef(javaResult);
  }

  dynamicProxyData->done = true;
}
Exemple #13
0
/*
 * Tcl proc to embed Javascript
 */
int jsEval(
	ClientData clientData,
	Tcl_Interp *interp,
	int objc,
	Tcl_Obj *const objv[]
){
	v8log("TclBinding::jsEval (interp=%p)\n", interp);

	// Get handle to the V8 Isolate for this Tcl interpreter
	Isolate* isolate  = v8::Isolate::GetCurrent();
	assert(isolate != nullptr);

	// lock the Isolate for multi-threaded access (not reentrant on its own)
	Locker locker(isolate);

	// create a bindings map and store it in the current V8 Isolate
	TclVariableBindingsMap* varbindings = new TclVariableBindingsMap;
	isolate->SetData(0, varbindings);
	v8log("jsEval: created new bindings map at %lp\n", (void*)varbindings );

	// validate input params
	if ( (objc != 3) ) {
		std::string msg("usage: jsEval [list of tcl vars to add to v8 context] { javascript }");
		Tcl_SetObjResult(interp, Tcl_NewStringObj(msg.c_str(), msg.length()));
		return TCL_ERROR;
	}

	// get the argument list
	Tcl_Obj* arglist = objv[1];
	if ( (arglist->typePtr == NULL) || strcmp(arglist->typePtr->name, "list") ) {
		std::string msg("jsEval: 1st arg not a list");
		Tcl_SetObjResult(interp, Tcl_NewStringObj(msg.c_str(), msg.length()));
		return TCL_ERROR;
	}

	// get the JS snippet
	char* javascript = Tcl_GetString(objv[2]);
	if ( strlen(javascript) == 0 ) {
		std::string msg("jsEval: 2nd arg not a string");
		Tcl_SetObjResult(interp, Tcl_NewStringObj(msg.c_str(), msg.length()));
		return TCL_ERROR;
	}

	// Create stack-allocated isolate and handle scopes.
	Isolate::Scope isolate_scope(isolate);
	HandleScope    handle_scope(isolate);

	// new v8 global template
	Handle<ObjectTemplate> global_templ = ObjectTemplate::New(isolate);

	// scrum our F18 Interceptors
	global_templ->SetNamedPropertyHandler(
			&TclVariableBinding::GenericNamedPropertyReader,
			&TclVariableBinding::GenericNamedPropertyWriter
	);

	// Create and Enter a new context for compiling and running the script.
	Handle<Context> context = Context::New(isolate, NULL, global_templ);
	context->Enter();

	int arglistLength;
	Tcl_ListObjLength(interp, arglist, &arglistLength);
	v8log("arg list length == %d\n", arglistLength);

	for ( int i = 0; i < arglistLength; i++ ) {
		// get the variable NAME
		Tcl_Obj* varName;
		Tcl_ListObjIndex(interp, arglist, i, &varName);
		char* vn = Tcl_GetString(varName);
		v8log("binding %s (idx: %d) to V8\n", vn, i);
		// then create a binding  and store it
		(*varbindings)[vn] = new TclVariableBinding(interp, varName);
	}

	// Compile
	v8log("compiling jsEval'ed script\n");
	v8::MaybeLocal<v8::Script> jsSource = v8::Script::Compile(context, Nan::New<String>(javascript).ToLocalChecked());
	if (jsSource.IsEmpty()) {
		v8log("*** jsSource.IsEmpty()\n");
	} else {
		// Run
		v8log("running jsEval'ed script\n");
		Nan::TryCatch tc;
		Nan::MaybeLocal<v8::Value> retv = jsSource.ToLocalChecked()->Run();
		v8log("done running jsEval'ed script\n");
		if ( tc.HasCaught() ) {
			// oops, exception raised from V8 while in JS land
			Local<Message> msg = tc.Message();
			std::string msgtext(*String::Utf8Value(msg->Get()));
			v8log("*** caught JS exception: %s\n", msgtext.c_str());
		}

		TclVariableBindingsMap::const_iterator it;
		for (it = varbindings->begin(); it != varbindings->end(); it++) {
			TclVariableBinding* vb = it->second;
			v8log("reverse mapping of %s (v8: %p) to Tcl...\n", it->first.c_str(), vb->m_v8val);
			Tcl_SetVar2Ex(vb->m_interp, it->first.c_str(), NULL, vb->m_tclvar, 0);
			delete vb;
		}
		varbindings->clear();
		// handle return value, if there is one
		if (!retv.IsEmpty()) {
			Local<Value> rv = retv.ToLocalChecked();
			std::string res(*String::Utf8Value(rv));
			std::string restype(V8ValueType(rv));
			v8log("Tcl_SetObjResult(interp == %lp, result == %s (%s)\n", (void*) interp, res.c_str(), restype.c_str());
			Tcl_Obj* tclres = V8ToTcl(interp, rv);
			Tcl_SetObjResult(interp, tclres);
		}
		delete varbindings;
	}
	context->Exit();

// TODO: error handling!
	return TCL_OK;
}