Handle<Value> Ti::TiProxy::_Setter (Local<String> property, Local<Value> value, const AccessorInfo& info) { HandleScope handleScope; // Ti::TiHelper::LogInternal(QString("Property Setter: ").append(Ti::TiHelper::QStringFromValue(property))); // Todo: Come back to this later // if(value == info.Holder()->Get(property)) { // Ti::TiHelper::LogInternal(QString("Already set: ").append(Ti::TiHelper::QStringFromValue(property))); // return value; // } Handle<Object> obj = Handle<Object>::Cast(info.Holder()); // Todo: come back to this - might not be allowing GC to collect proxies obj->ForceSet(property, value); // for example. scrollView.views = [a,b,c] // scrollView.remove(a) <--- removed from view, but still in array Handle<External> proxyObject = Handle<External>::Cast(obj->GetHiddenValue(String::New("module"))); if(proxyObject.IsEmpty()) proxyObject = Handle<External>::Cast(obj->GetHiddenValue(String::New("proxy"))); if(proxyObject.IsEmpty()) return value; Ti::TiProxy* tiProxy = static_cast<Ti::TiProxy*>(proxyObject->Value()); if(tiProxy->properties.contains(Ti::TiHelper::QStringFromValue(property))) { Ti::TiProperty *prop = tiProxy->properties[Ti::TiHelper::QStringFromValue(property)]; return handleScope.Close(prop->setValue(value)); } return value; }
int Conv::UnwrapObject(JNIEnv *jniEnv, Handle<Object> val, Handle<String> key, jobject *jVal) { int result = ErrorNotfound; //LOGV("UnwrapObject; getting hidden value; key = %p\n", key); Local<Value> hiddenVal = val->GetHiddenValue(key); if(!hiddenVal.IsEmpty() && !hiddenVal->IsUndefined()) { jobject extRef = (jobject)External::Unwrap(hiddenVal); if(jniEnv->GetObjectRefType(extRef) == JNIWeakGlobalRefType) { jobject localRef = jniEnv->NewLocalRef(extRef); if(localRef == 0) { /* the Java object died */ jniEnv->DeleteWeakGlobalRef(extRef); val->DeleteHiddenValue(key); } else { /* the java object is alive */ *jVal = localRef; result = OK; } } else { /* the object is strongly referenced */ *jVal = extRef; result = OK; } } return result; }
void TiProxy::onRemoveEventListener(const char* eventName, Handle<Function> eventFunction) { NativeObject* no = getNativeObject(); if (no == NULL) { return; } // Get the event subscriber's id so we know which to remove from the event container. Handle<Int32> v8id = eventFunction->GetHiddenValue(String::New("ID"))->ToInt32(); if ((v8id.IsEmpty()) || (v8id->Value() == 0)) { return; } // Make sure that the function being removed has been added to this event container. Handle<Value> v8extValue = eventFunction->GetHiddenValue(String::New("OWNER")); if ((v8extValue.IsEmpty()) || (!v8extValue->IsExternal())) { return; } Handle<External> v8ext = Handle<External>::Cast(v8extValue); TiProxy* referencedControl = (TiProxy*)v8ext->Value(); if (referencedControl != this) { // User was attempting to remove an event handler from a control that it // doesn't belong to. return; } no->removeEventHandler(eventName, v8id->Value()); no->release(); no = NULL; // Free up the memory used by the TiV8Event Handle<Value> v8evtValue = eventFunction->GetHiddenValue(String::New("POINTER")); if ((v8evtValue.IsEmpty()) || (!v8evtValue->IsExternal())) { return; } Handle<External> v8evt = Handle<External>::Cast(v8evtValue); delete(TiV8Event*)v8evt->Value(); }
bool NativeScriptRuntime::RegisterInstance(const Handle<Object>& jsObject, const std::string& fullClassName, const ArgsWrapper& argWrapper, const Handle<Object>& implementationObject, bool isInterface) { bool success; DEBUG_WRITE("RegisterInstance called for '%s'", fullClassName.c_str()); if(fullClassName == "java/lang/Object_") { int a = 5; } JEnv env; // get class from implementation object if you can jclass generatedJavaClass = nullptr; bool classIsResolved = false; if (!implementationObject.IsEmpty()) { Local < Value > val = implementationObject->GetHiddenValue(ConvertToV8String(fullClassName)); if (!val.IsEmpty()) { void* voidPointerToVal = val.As<External>()->Value(); generatedJavaClass = reinterpret_cast<jclass>(voidPointerToVal); classIsResolved = true; } } if(!classIsResolved) { generatedJavaClass = ResolveClass(fullClassName, implementationObject); } int javaObjectID = objectManager->GenerateNewObjectID(); DEBUG_WRITE("RegisterInstance: Linking new instance"); objectManager->Link(jsObject, javaObjectID, nullptr); jobject instance = CreateJavaInstance(javaObjectID, fullClassName, argWrapper, generatedJavaClass, isInterface); JniLocalRef localInstance(instance); success = !localInstance.IsNull(); if (success) { DEBUG_WRITE("RegisterInstance: Updating linked instance with its real class"); jclass instanceClass = env.FindClass(fullClassName); objectManager->SetJavaClass(jsObject, instanceClass); } else { DEBUG_WRITE("RegisterInstance failed with null new instance"); } return success; }
TiObject* TiObject::getTiObjectFromJsObject(Handle<Value> value) { if (!value->IsObject()) { return NULL; } Handle<Object> obj = Handle<Object>::Cast(value); Handle<External> ext = Handle<External>::Cast(obj->GetHiddenValue(String::New(HIDDEN_TI_OBJECT_PROPERTY))); if (ext.IsEmpty()) { return NULL; } TiObject* tiObj = (TiObject*) ext->Value(); return tiObj; }
Handle<Value> Ti::TiProxy::_Getter (Local<String> property, const AccessorInfo& info) { HandleScope handleScope; Handle<Object> obj = Handle<Object>::Cast(info.Holder()); Handle<External> proxyObject = Handle<External>::Cast(obj->GetHiddenValue(String::New("module"))); if(proxyObject.IsEmpty()) proxyObject = Handle<External>::Cast(obj->GetHiddenValue(String::New("proxy"))); if(proxyObject.IsEmpty()) return handleScope.Close(Handle<Value>()); Ti::TiProxy* tiProxy = static_cast<Ti::TiProxy*>(proxyObject->Value()); if(tiProxy->properties.contains(Ti::TiHelper::QStringFromValue(property))) { Ti::TiProperty *prop = tiProxy->properties[Ti::TiHelper::QStringFromValue(property)]; Handle<Value> r = prop->getValue(); if(r.IsEmpty() || r->IsUndefined()) return handleScope.Close(Handle<Value>()); return handleScope.Close(r); } return handleScope.Close(Handle<Value>()); }
void ComponentWrapperDestructor(v8::Persistent<Value> v, void* scriptsysnull) { dtEntity::Component* component = UnwrapComponent(v); if(component != NULL) { ScriptSystem* scriptsys = static_cast<ScriptSystem*>(Isolate::GetCurrent()->GetData()); HandleScope scope; Handle<Object> o = Handle<Object>::Cast(v); assert(!o.IsEmpty()); Handle<Value> val = o->GetHiddenValue(scriptsys->GetEntityIdString()); assert(!val.IsEmpty()); dtEntity::EntityId id = val->Uint32Value(); scriptsys->RemoveFromComponentMap(component->GetType(), id); } // is already called in RemoveFromComponentMap: //v.Dispose(); }
VALUE rr_reflect_v8_object_as(Handle<Value> value, VALUE ruby_class) { Handle<Object> object = Handle<Object>::Cast(value); VALUE handle; v8_weakref* backref; Local<Value> holder = object->GetHiddenValue(String::NewSymbol("TheRubyRacer::Backref")); if (holder.IsEmpty()) { handle = rr_v8_handle_new(ruby_class, object); backref = new v8_weakref(handle); object->SetHiddenValue(String::NewSymbol("TheRubyRacer::Backref"), backref->external); } else { backref = (v8_weakref*)External::Unwrap(holder); handle = backref->get(); if (!RTEST(handle)) { handle = rr_v8_handle_new(ruby_class, object); backref->set(handle); } } return handle; }
Local<Value> tns::V8GetHiddenValue(const Handle<Object>& obj, const string& propName) { auto s = tns::ConvertToV8String(propName); return obj->GetHiddenValue(s); }
Handle<Object> WrapComponent(Handle<Object> wrappedes, ScriptSystem* scriptsys, dtEntity::EntityId eid, dtEntity::Component* v) { HandleScope handle_scope; Handle<Object> wrapped = scriptsys->GetFromComponentMap(v->GetType(), eid); if(!wrapped.IsEmpty()) { return wrapped; } Handle<FunctionTemplate> templt = GetScriptSystem()->GetTemplateBySID(s_componentWrapper); if(templt.IsEmpty()) { templt = FunctionTemplate::New(); templt->SetClassName(String::New("Component")); templt->InstanceTemplate()->SetInternalFieldCount(1); Handle<ObjectTemplate> proto = templt->PrototypeTemplate(); proto->Set("equals", FunctionTemplate::New(COEquals)); proto->Set("getType", FunctionTemplate::New(COGetType)); proto->Set("properties", FunctionTemplate::New(COProperties)); proto->Set("toString", FunctionTemplate::New(COToString)); proto->Set("finished", FunctionTemplate::New(COFinished)); proto->Set("copyPropertyValues", FunctionTemplate::New(COCopyPropertyValues)); GetScriptSystem()->SetTemplateBySID(s_componentWrapper, templt); } Local<Object> instance = templt->GetFunction()->NewInstance(); instance->SetInternalField(0, External::New(v)); instance->SetHiddenValue(scriptsys->GetEntityIdString(), Uint32::New(eid)); // GetStringFromSID and conversion to v8::String is costly, create a // hidden value in entity system wrapper that stores // strings and their string ids as name=>value pairs Handle<Value> propnamesval = wrappedes->GetHiddenValue(scriptsys->GetPropertyNamesString()); if(propnamesval.IsEmpty()) { Handle<Object> names = Object::New(); dtEntity::PropertyGroup::const_iterator i; const dtEntity::PropertyGroup& props = v->Get(); for(i = props.begin(); i != props.end(); ++i) { dtEntity::StringId sid = i->first; std::string propname = dtEntity::GetStringFromSID(sid); names->Set(String::New(propname.c_str()), WrapSID(sid)); } wrappedes->SetHiddenValue(scriptsys->GetPropertyNamesString(), names); propnamesval = names; } Handle<Object> propnames = Handle<Object>::Cast(propnamesval); Handle<Array> keys = propnames->GetPropertyNames(); for(unsigned int i = 0; i < keys->Length(); ++i) { Handle<String> str = keys->Get(i)->ToString(); dtEntity::StringId sid = UnwrapSID(propnames->Get(str)); dtEntity::Property* prop = v->Get(sid); if(prop == NULL) { LOG_ERROR("Could not find property in component: " << ToStdString(str)); continue; } Handle<External> ext = v8::External::New(static_cast<void*>(prop)); instance->SetAccessor(str, COPropertyGetter, COPropertySetter, ext); } // store wrapped component to script system scriptsys->AddToComponentMap(v->GetType(), eid, instance); return handle_scope.Close(instance); }
Handle<Object> MetadataNode::GetImplementationObject(const Handle<Object>& object) { DEBUG_WRITE("GetImplementationObject called on object:%d", object->GetIdentityHash()); auto target = object; Handle<Value> currentPrototype = target; Handle<Object> implementationObject; implementationObject = object->GetHiddenValue(ConvertToV8String("t::implObj")).As<Object>(); if (!implementationObject.IsEmpty()) { return implementationObject; } if (object->HasOwnProperty(V8StringConstants::GetIsPrototypeImplementationObject())) { auto v8Prototype = V8StringConstants::GetPrototype(); if (!object->HasOwnProperty(v8Prototype)) { return Handle<Object>(); } DEBUG_WRITE("GetImplementationObject returning the prototype of the object :%d", object->GetIdentityHash()); return object->Get(v8Prototype).As<Object>(); } auto obj = V8GetHiddenValue(object, "t::ActivityImplementationObject").As<Object>(); if (!obj.IsEmpty()) { DEBUG_WRITE("GetImplementationObject returning ActivityImplementationObject property on object: %d", object->GetIdentityHash()); return obj; } Handle<Value> lastPrototype; bool prototypeCycleDetected = false; while (implementationObject.IsEmpty()) { // currentPrototype = currentPrototype.As<Object>()->GetPrototype(); if (currentPrototype->IsNull()) break; //DEBUG_WRITE("GetImplementationObject currentPrototypeObject:%d", (currentPrototype.IsEmpty() || currentPrototype.As<Object>().IsEmpty()) ? -1 : currentPrototype.As<Object>()->GetIdentityHash()); //DEBUG_WRITE("GetImplementationObject lastPrototypeObject:%d", (lastPrototype.IsEmpty() || lastPrototype.As<Object>().IsEmpty()) ? -1 : lastPrototype.As<Object>()->GetIdentityHash()); if (currentPrototype == lastPrototype) { auto abovePrototype = currentPrototype.As<Object>()->GetPrototype(); prototypeCycleDetected = abovePrototype == currentPrototype; } if (currentPrototype.IsEmpty() || prototypeCycleDetected) { //Handle<Value> abovePrototype = currentPrototype.As<Object>()->GetPrototype(); //DEBUG_WRITE("GetImplementationObject not found since cycle parents reached abovePrototype:%d", (abovePrototype.IsEmpty() || abovePrototype.As<Object>().IsEmpty()) ? -1 : abovePrototype.As<Object>()->GetIdentityHash()); return Handle<Object>(); } else { auto value = currentPrototype.As<Object>()->GetHiddenValue(V8StringConstants::GetClassImplementationObject()); if (!value.IsEmpty()) { implementationObject = currentPrototype.As<Object>(); } } lastPrototype = currentPrototype; } return implementationObject; }
void MetadataNode::ExtendCallMethodHandler(const v8::FunctionCallbackInfo<v8::Value>& info) { if (info.IsConstructCall()) { string exMsg("Cannot call 'extend' as constructor"); ExceptionUtil::GetInstance()->ThrowExceptionToJs(exMsg); return; } SET_PROFILER_FRAME(); Handle<Object> implementationObject; Handle<String> extendName; string extendLocation; auto validArgs = ValidateExtendArguments(info, extendLocation, extendName, implementationObject); if (!validArgs) return; auto node = reinterpret_cast<MetadataNode*>(info.Data().As<External>()->Value()); DEBUG_WRITE("ExtendsCallMethodHandler: called with %s", ConvertToString(extendName).c_str()); string extendNameAndLocation = extendLocation + ConvertToString(extendName); auto fullClassName = TNS_PREFIX + CreateFullClassName(node->m_name, extendNameAndLocation); // JEnv env; //resolve class (pre-generated or generated runtime from dex generator) jclass generatedClass = s_resolveClass(fullClassName, implementationObject); //resolve class returns GlobalRef std::string generatedFullClassName = s_objectManager->GetClassName(generatedClass); // auto fullExtendedName = generatedFullClassName; DEBUG_WRITE("ExtendsCallMethodHandler: extend full name %s", fullClassName.c_str()); auto isolate = info.GetIsolate(); auto cachedData = GetCachedExtendedClassData(isolate, fullExtendedName); if (cachedData.extendedCtorFunction != nullptr) { auto cachedExtendedCtorFunc = Local<Function>::New(isolate, *cachedData.extendedCtorFunction); info.GetReturnValue().Set(cachedExtendedCtorFunc); return; } auto implementationObjectPropertyName = V8StringConstants::GetClassImplementationObject(); //reuse validation - checks that implementationObject is not reused for different classes auto implementationObjectProperty = implementationObject->GetHiddenValue(implementationObjectPropertyName).As<String>(); if (implementationObjectProperty.IsEmpty()) { //mark the implementationObject as such and set a pointer to it's class node inside it for reuse validation later implementationObject->SetHiddenValue(implementationObjectPropertyName, String::NewFromUtf8(isolate, fullExtendedName.c_str())); //append resolved class to implementation object implementationObject->SetHiddenValue(ConvertToV8String(fullExtendedName), External::New(Isolate::GetCurrent(), generatedClass)); } else { string usedClassName = ConvertToString(implementationObjectProperty); stringstream s; s << "This object is used to extend another class '" << usedClassName << "'"; ExceptionUtil::GetInstance()->ThrowExceptionToJs(s.str()); return; } auto baseClassCtorFunc = node->GetConstructorFunction(isolate); auto extendData = External::New(isolate, new ExtendedClassData(node, extendNameAndLocation, implementationObject, fullExtendedName)); auto extendFuncTemplate = FunctionTemplate::New(isolate, ExtendedClassConstructorCallback, extendData); auto extendFunc = extendFuncTemplate->GetFunction(); auto prototypeName = ConvertToV8String("prototype"); implementationObject->SetPrototype(baseClassCtorFunc->Get(prototypeName)); implementationObject->SetAccessor(ConvertToV8String("super"), SuperAccessorGetterCallback, nullptr, implementationObject); extendFunc->Set(prototypeName, implementationObject); extendFunc->SetPrototype(baseClassCtorFunc); SetClassAccessor(extendFunc); SetTypeMetadata(isolate, extendFunc, new TypeMetadata(fullExtendedName)); info.GetReturnValue().Set(extendFunc); s_name2NodeCache.insert(make_pair(fullExtendedName, node)); ExtendedClassCacheData cacheData(extendFunc, fullExtendedName, node); s_extendedCtorFuncCache.insert(make_pair(fullExtendedName, cacheData)); }