Пример #1
0
static Handle<Value> Nil(const Arguments& args)
{
    HandleScope handle_scope;

    if (object_template_.IsEmpty()) {
        Handle<ObjectTemplate> raw_template = PrepareTemplate();
        object_template_ = Persistent<ObjectTemplate>::New(raw_template);
    }

    if (nil_instance_.IsEmpty()) {
        nil_instance_ = Persistent<Value>::New(object_template_->NewInstance());
    }
    
    return handle_scope.Close(nil_instance_);
}
Пример #2
0
    static Handle<Value> WrapResults(cached_object cache)
    {
        HandleScope handle_scope;


        if (object_template_.IsEmpty()) {
            Handle<ObjectTemplate> raw_template = PrepareTemplate();
            object_template_ = Persistent<ObjectTemplate>::New(raw_template);
        }

        Handle<Object> new_object = object_template_->NewInstance();
        //new_object->SetInternalField(1, External::New(results));

        //printf("Here: %x\n", buffer);

        object* obj = new object(cache);
        obj->Wrap(new_object);
        // TODO: Lookup the args id and wrap it

        //printf("Wrapped and returning\n");

        return handle_scope.Close(new_object);
    }
Пример #3
0
    static Handle<Value> ObjectGet(Local<String> name, const AccessorInfo& info)
    {
        object* obj = ObjectWrap::Unwrap<object>(info.Holder());

        // Fetch the map wrapped by this object.
        /*
        Handle<External> field = Handle<External>::Cast(info.Holder()->GetInternalField(1));
        void* ptr = field->Value();
        js0n::result_vector* members = reinterpret_cast<js0n::result_vector*>(ptr);
        */
        //printf("Going to call find_key\n");
        js0n::js_value* value = js0n::find_key(*(String::Utf8Value(name)), &obj->cache_);
        //printf("Found type(%u) length(%u) start(%u) depth(%u)\n", value->type, value->length, value->start, value->depth);

        switch (value->type) {
        case JST_string:
            return String::New(obj->cache_.buffer + value->start, value->length);
        case JST_number:
            char tmpBuf[value->length];
            strncpy(tmpBuf, obj->cache_.buffer + value->start, value->length);
            // TODO: determine the if this is a float or an integer and return correctly
            return Integer::New(atoi(tmpBuf));
        case JST_null:
            return Null();
        case JST_boolean:
            // This was validated by the parser already so just check the first letter
            return Boolean::New((obj->cache_.buffer[value->start] == 't') ? true : false);
        case JST_array:
            // TODO: make it return a warpped array
            return Undefined();
        case JST_object:
            {
                // TODO: return a new wrapped object
                Local<Object> new_object = object_template_->NewInstance();
                //new_object->SetInternalField(1, External::New(results));

                //printf("Here: %x\n", buffer);
                cached_object subCache;
                // -1 +sizeof(js_value) to shift into the object actually
                subCache.count = obj->cache_.count - ((value - obj->cache_.values) / sizeof(js_value)) - 1;
                subCache.values = &value[1];
                subCache.buffer_length = obj->cache_.buffer_length;
                subCache.buffer = obj->cache_.buffer;

                object* obj = new object(subCache);
                obj->Wrap(new_object);
                return new_object;
            }
        default:
            return Undefined();
        }
        //js0n::js_value member = js0n::find_key(*members, *String::Utf8Value(name)); 
        //printf("Out of find_key\n");
        //printf("member type(%u) length(%u) start(%u) depth(%u)\n", member.type, member.length, member.start, member.depth);

      /* // Convert the JavaScript string to a std::string. */
      /* string key = ObjectToString(name); */

      /* // Look up the value if it exists using the standard STL ideom. */
      /* map<string, string>::iterator iter = obj->find(key); */

      /* // If the key is not present return an empty handle as signal */
      /* if (iter == obj->end()) return Handle<Value>(); */

      /* // Otherwise fetch the value and wrap it in a JavaScript string */
      /* const string& value = (*iter).second; */
    }
// Creates and launches a new isolate in a new background thread.
//创建并启动一个新的 isolate v8 运行时
static Handle<Value> Create (const Arguments &args) {
    HandleScope scope;
    
    typeThread* thread; 
    typeQueueItem* qitem= NULL;


    qitem= queue_pull(freeThreadsQueue); //从闲置队列中获取一个item
    if (qitem) {//如果获取到了这个item,则把这个item指向的线程赋值给thread指针
      thread= (typeThread*) qitem->asPtr;
      destroyItem(qitem); //摧毁这个item
    }
    else { //如果没有找到
      thread= (typeThread*) calloc(1, sizeof(typeThread)); //则创建一个空的 thread 指针指向 typeThread
      thread->threadMagicCookie= kThreadMagicCookie; //设置这个 thread 的标示
    }
    
    static long int threadsCtr= 0; //静态变量 threadsCtr ,用来做线程id的标示,每次创建都 +1
    thread->id= threadsCtr++;
    
    //为thread的jsobject实例设置属性,返回一个 threadTemplate 的实例 Local< Object >
    //然后调用  
    //Persistent<T> v8::Persistent<T>::New(Handle<T> that)   [inline, static]
    //将Handle<T> 改变为 Persistent<Object>
    thread->JSObject= Persistent<Object>::New(threadTemplate->NewInstance());
    //设置一个属性id在js对象中,让js对象可以访问
    //id_symbol 为 Persistent<String>::New(String::NewSymbol("id"));
    thread->JSObject->Set(id_symbol, Integer::New(thread->id));
    //SetPointerInInternalField (int index, void *value)
    //设置一个内部c++指针在js的对象中
    thread->JSObject->SetPointerInInternalField(0, thread);

/*
    这里比较复杂,需要一点点分析了
    1.static Local<Script> v8::Script::Compile  ( Handle< String >  source,
    ScriptOrigin *  origin = NULL,
    ScriptData *  pre_data = NULL,
    Handle< String >  script_data = Handle< String >()   
    )
    第一步compile将返回 Local<Script> 
    第二步run()将返回 kEvents_js 返回的内容,
    第三步将返回的内容,转为ToObject(), Local< Object >
    第四部调用CallAsFunction,环境对象使用 threadTemplate 实例,这样就继承了 events 对象
*/
    Local<Value> dispatchEvents= Script::Compile(String::New(kEvents_js))->Run()->ToObject()->CallAsFunction(thread->JSObject, 0, NULL);

    //将thread的 dispatchEvents 指针指向   Persistent<Object> 类型的 dispatchEvents
    thread->dispatchEvents= Persistent<Object>::New(dispatchEvents->ToObject());
    



    //注册libuv和callback
    //当执行 uv_async_send 时,就会调用注册进入的callback

    uv_async_init(uv_default_loop(), &thread->async_watcher, Callback);

    
    pthread_cond_init(&thread->IDLE_cv, NULL);
    pthread_mutex_init(&thread->IDLE_mutex, NULL);
    pthread_mutex_init(&thread->inQueue.queueLock, NULL);
    pthread_mutex_init(&thread->outQueue.queueLock, NULL);


    if (pthread_create(&thread->thread, NULL, aThread, thread)) { //如果创建线程不成功
      //Ha habido un error no se ha arrancado este hilo
      destroyaThread(thread);
      return ThrowException(Exception::TypeError(String::New("create(): error in pthread_create()")));
    }
    
    /*
    V8::AdjustAmountOfExternalAllocatedMemory(sizeof(typeThread));  //OJO V8 con V mayúscula.
    */
    
    return scope.Close(thread->JSObject);
}