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_); }
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); }
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); }