예제 #1
0
파일: Interface.cpp 프로젝트: amolmk/anode
int Interface::UserInvoke(JNIEnv *jniEnv, Handle<Object> target, int opIdx, jobjectArray jArgs, jobject *jResult) {
  HandleScope scope;
  TryCatch tryCatch;
  Operation *op = operations->addr(opIdx);
  int result = OK;
  for(int i = 0; result == OK && i < op->argCount; i++) {
      result = conv->ToV8Value(jniEnv, jniEnv->GetObjectArrayElement(jArgs, i), op->argTypes[i], &op->vArgs[i]);
  }
  if(result == OK) {
    Handle<Value> vRes;
    if(target->IsFunction() && parent == 0 && operations->getLength() == 1) {
      /* invoke as function if target is a function, and interface delcares only one operation */
      vRes = (Handle<Function>::Cast(target))->Call(target, op->argCount, op->vArgs);
    } else {
      /* locate the method and invoke that */
      Handle<Value> vMethod = target->Get(op->name);
      if(!vMethod.IsEmpty() && vMethod->IsFunction()) {
        vRes = Handle<Function>::Cast(vMethod)->Call(target, op->argCount, op->vArgs);
      }
    }
    if(!vRes.IsEmpty() && op->type != TYPE_UNDEFINED) {
      jobject ob;
      result = conv->ToJavaObject(jniEnv, vRes, op->type, &ob);
      if(result == OK) {
        *jResult = ob;
      }
    }
  }
  if(tryCatch.HasCaught()) {
    result = ErrorJS;
    tryCatch.Reset();
  }
  return result;
}
예제 #2
0
파일: Interface.cpp 프로젝트: amolmk/anode
int Interface::UserSet(JNIEnv *jniEnv, Handle<Object> target, int attrIdx, jobject jVal) {
  HandleScope scope;
  TryCatch tryCatch;
  Attribute *attr = attributes->addr(attrIdx);
  Handle<Value> val;
  int result = conv->ToV8Value(jniEnv, jVal, attr->type, &val);
  if(result == OK) {
    target->Set(attr->name, val);
  }
  if(tryCatch.HasCaught()) {
    result = ErrorJS;
    tryCatch.Reset();
  }
  return result;
}
예제 #3
0
파일: Interface.cpp 프로젝트: amolmk/anode
int Interface::UserGet(JNIEnv *jniEnv, Handle<Object> target, int attrIdx, jobject *jVal) {
  HandleScope scope;
  TryCatch tryCatch;
  Attribute *attr = attributes->addr(attrIdx);
  Handle<Value> val = target->Get(attr->name);
  if(tryCatch.HasCaught()) {
    tryCatch.Reset();
    return ErrorJS;
  }
  jobject ob;
  int result = conv->ToJavaObject(jniEnv, val, attr->type, &ob);
  if(result == OK) {
    *jVal = ob;
  }
  return result;
}
예제 #4
0
void test1(cv::Shell & shell)
{
    using namespace v8;
    HandleScope scope;
    bind_MyType( shell.Global() );

    if(1)
    {
        Handle<Function> hf = FunctionTemplate::New(test1_callback)->GetFunction();
        Handle<Value> args[] = {
            Integer::New(3),
            Number::New(5.1),
            Undefined()
        };
        CERR << "Calling binding function...\n";
        TryCatch catcher;
        hf->Call( shell.Context()->Global(), 3, args );
        catcher.Reset();
        CERR << "Returned from binding function.\n";
    }
    else
    {
        BoundNative::SetupBindings( shell.Global() );
    }

    char const * extScr = "./test.js";
    CERR << "Calling external script ["<<extScr<<"]...\n";
    if(1)
    {
        Local<Object> global( shell.Context()->Global() );
        assert( ! global.IsEmpty() );
        Local<Function> jf( Function::Cast( *(global->Get(JSTR("load"))) ) );
        assert( ! jf.IsEmpty() );
        cv::CallForwarder<1>::Call( global, jf, extScr );
    }
    else if(1)
    {
        shell.ExecuteFile( extScr );
    }
    CERR << "Returned from external script\n";
}
//事件循环
//TAGG核心代码程序
static void eventLoop (typeThread* thread) {
  thread->isolate->Enter(); //进入 isolate
  thread->context= Context::New(); //创建一个sandbox沙箱用来执行js代码,他的上下文将有他自己控制
  thread->context->Enter(); //进入这个上下文
  
  {
    HandleScope scope1;
    
    //返回这个分离的沙箱内的全局对象
    //Local< Object >   Global ()
    Local<Object> global= thread->context->Global();

	global->Set(String::NewSymbol("_Global"), global);
    
	//将puts方法设置到全局中去,代替console.log
	Handle<Object> console_obj = Object::New();
	console_obj->Set(String::New("log"), FunctionTemplate::New(Puts)->GetFunction());
	

    global->Set(String::New("console"), console_obj);
	global->Set(String::New("require"), FunctionTemplate::New(require_file)->GetFunction(), ReadOnly);
  
	
	//定义一个thread对象到全局变量中
    Local<Object> threadObject= Object::New();
    global->Set(String::NewSymbol("thread"), threadObject);
    
    //设置这个全局对象thread的id和emit属性
    threadObject->Set(String::NewSymbol("id"), Number::New(thread->id));
    threadObject->Set(String::NewSymbol("emit"), FunctionTemplate::New(threadEmit)->GetFunction());
    threadObject->Set(String::NewSymbol("end"), FunctionTemplate::New(threadEnd)->GetFunction());
    threadObject->Set(String::New("_TAGG_RES"), Undefined()); //返回的全局变量字符串
    
	//将global对象放入全局global中,每次都会初始化
	Handle<Object> user_global = Object::New();
	global->Set(String::NewSymbol("global"), user_global);
	global->Set(String::NewSymbol("Global"), user_global);
	
	
	//让threadObject继承event接口
    Local<Object> dispatchEvents= Script::Compile(String::New(kEvents_js))->Run()->ToObject()->CallAsFunction(threadObject, 0, NULL)->ToObject();
	
	//获得下个事件循环的函数
    Local<Object> dispatchNextTicks= Script::Compile(String::New(kThread_nextTick_js))->Run()->ToObject();
	


    //获得thread_nextTick.js中定义的 next回调函数的数组
    Local<Array> _ntq= (v8::Array*) *threadObject->Get(String::NewSymbol("_ntq"));
   

    double nextTickQueueLength= 0; //事件循环次数
    long int ctr= 0;
    
    //SetFatalErrorHandler(FatalErrorCB);
    
    while (!thread->sigkill) { //当线程的信号不为kill时,则循环执行下面代码
      typeJob* job;
      typeQueueItem* qitem;
      
      {//while循环代码块


        HandleScope scope2;
        //v8的TryCatch类,
        //一个外部的异常控制类
        TryCatch onError;    
        String::Utf8Value* str;//临时保存js源代码的指针
        Local<String> source; //保存js源代码字符串
        Local<Script> script; //保存js源代码
        Local<Value> resultado; //保存js源代码执行的return 结果值
        
        
        while ((qitem= queue_pull(&thread->inQueue))) { //当队列中有项目时,循环执行如下代码
          
          job= (typeJob*) qitem->asPtr; //队列中的任务
          
          if ((++ctr) > 2e3) { //如果ctr 大于 2*10的3次方
            ctr= 0;
            V8::IdleNotification(); //强制V8进行GC while(!V8::IdleNotification()) {};
          }
          
          if (job->jobType == kJobTypeEval) { //如果执行的任务
            //Ejecutar un texto
            
            if (job->typeEval.useStringObject) { //如果是eval方法传入的参数进来的
              str= job->typeEval.scriptText_StringObject;
              source= String::New(**str, (*str).length()); 
              delete str; //删除str指针
            }
            else { //如果是load js 文件进来的
              source= String::New(job->typeEval.scriptText_CharPtr);//创建js源代码string,
              free(job->typeEval.scriptText_CharPtr); //释放
            }
            
            script= Script::New(source); //将源代码字符串,转存为js代码
            
            //这里进行判断,如果上下问里的js代码执行抛出了异常,则本次循环将不执行js代码了
            
			//将global对象放入全局global中,每次都会初始化
			Handle<Object> user_global = Object::New();
			global->Set(String::NewSymbol("global"), user_global);
			global->Set(String::NewSymbol("Global"), user_global);
            
			if (!onError.HasCaught()){  //如果没有错误


				//Local<Object> obj = job->buffer->Clone();
				//resultado = String::NewSymbol("id");
				//将char* 的job->buf_ptr又转换为Buffer指针
				//node::Buffer *buf = node::Buffer::New(job->buf_ptr, job->buf_len); 					
				//Local<Object> buf_obj = External::Wrap(buf)->ToObject();				
				threadObject->Set(String::New("_TAGG_RES"), Undefined()); //返回的全局变量字符串

				Local<Object> buf_obj = Object::New();
				

				if(job->buf_ptr){
					buf_obj->SetHiddenValue(String::New("buffer"), String::New(job->buf_ptr, job->buf_len));
					buf_obj->SetHiddenValue(String::New("isBuffer"),Number::New(1));
				}
				else{
					buf_obj->SetHiddenValue(String::New("isBuffer"),Number::New(0));
				}

				buf_obj->Set(String::NewSymbol("toString"), FunctionTemplate::New(Buffer_toString)->GetFunction());
				
				threadObject->Set(String::NewSymbol("buffer"),  buf_obj);				
				
				global->Set(String::NewSymbol("__dirname"), String::New(**job->__dirname));
				global->SetPointerInInternalField(0, job->__dirname);
				  

				script->Run(); //执行js代码,返回值为 resultado
			    resultado = threadObject->Get(String::New("_TAGG_RES"));
				

		   }//如果没有错误

            if (_ntq->Length() && !onError.HasCaught()) { //当有错误时,不执行异步
            
                  if ((++ctr) > 2e3) {
                      ctr= 0;
                      V8::IdleNotification();//强制GC
                  }

                  resultado = dispatchNextTicks->CallAsFunction(global, 0, NULL); //调用线程内的 nexttick
			
            }

            if (job->typeEval.tiene_callBack) { //如果执行任务具有回调函数
              //如果有错误,则 job->typeEval.error 是1,否则为0;
              job->typeEval.error= onError.HasCaught() ? 1 : 0; 
			  if(job->typeEval.error){
					 _ntq= Array::New();
			  }
              //如果有异常,则返回值 resultado 为异常内容,否则为函数返回内容
              job->typeEval.resultado= new String::Utf8Value(job->typeEval.error ? onError.Exception() : threadObject->Get(String::New("_TAGG_RES")));
              //执行完毕,将qtiem项丢入线程的出列队列
              queue_push(qitem, &thread->outQueue);
              // wake up callback
              //丢入异步队列

              uv_async_send(&thread->async_watcher);

            }
            else { //如果没有回调函数,则把改item丢入闲置任务队列
              queue_push(qitem, freeJobsQueue);
            }

            if (onError.HasCaught()){
				nextTickQueueLength= 1;
				onError.Reset(); //如果此次执行有错误,则清空
			}
			else{
				 nextTickQueueLength= resultado->NumberValue();
			}

     }//如果执行的任务


          else if (job->jobType == kJobTypeEvent) { //如果是事件的任务
            //Emitir evento.
            
            Local<Value> args[2]; //定义一个数组长度为2,保存 Local<Value> 类型的值
            str= job->typeEvent.eventName; //获得事件名字
            args[0]= String::New(**str, (*str).length()); //数组第一个保存event事件的名字,保存为local<string>类型
            delete str;
            
            Local<Array> array= Array::New(job->typeEvent.length);
            args[1]= array; //设置参数长度
            
            int i= 0;
            while (i < job->typeEvent.length) { //将参数保存入Local<Array>
              str= job->typeEvent.argumentos[i];
              array->Set(i, String::New(**str, (*str).length()));
              delete str;
              i++;
            }
            
            free(job->typeEvent.argumentos); //释放任务的 typeEvent 内存
            queue_push(qitem, freeJobsQueue); //将本项丢入闲置任务队列
            dispatchEvents->CallAsFunction(global, 2, args); //执行回调函数,并且加入参数
          



          }//如果是事件的任务


        }//while2 结束

	    
		/* 
		if (_ntq->Length()) { //执行异步
				  
				   if ((++ctr) > 2e3) {
                      ctr= 0;
                      V8::IdleNotification();//强制GC
                  }

                  resultado = dispatchNextTicks->CallAsFunction(global, 0, NULL); //调用线程内的 nexttick
                  if (onError.HasCaught()) { //如果有错误
                      nextTickQueueLength= 1; //nexttick队列长度为1
                      onError.Reset();
                  }
                  else {
                      nextTickQueueLength= resultado->NumberValue();
                  }
            }
		*/



      if (thread->inQueue.length) continue;
      if (thread->sigkill) break; //如果收到线程杀死信号,条春循环
      
      pthread_mutex_lock(&thread->IDLE_mutex); //锁住线程
      if (!thread->inQueue.length) { //如果线程的入队列长度为0
        thread->IDLE= 1; //则把线程设置为闲置
        pthread_cond_wait(&thread->IDLE_cv, &thread->IDLE_mutex); //休眠线程
        thread->IDLE= 0;
      }
      pthread_mutex_unlock(&thread->IDLE_mutex); //解锁线程




    }//while 结束



  }
  
  thread->context.Dispose(); //摧毁上下文
}

}