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;
}
Example #2
0
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>());
}
Example #7
0
   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();
   }
Example #8
0
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);
}
Example #10
0
   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));
}