void VJSRequireClass::_getCurrentPath (VJSParms_callStaticFunction &ioParms, void *)
{
	VJSGlobalObject	*globalObject	= ioParms.GetContext().GetGlobalObjectPrivateInstance();
	
	xbox_assert(globalObject != NULL);

	XBOX::VFilePath	*path	= (XBOX::VFilePath *) globalObject->GetSpecific(VJSContext::kURLSpecificKey);
	
	xbox_assert(path != NULL);

	XBOX::VFilePath	parent;

	if (!path->GetParent(parent)) {

		ioParms.ReturnString("/");

	} else {

		XBOX::VString	posixPath;

		parent.GetPosixPath(posixPath);

		ioParms.ReturnString(posixPath);

	}
}
Beispiel #2
0
void VJSSession::_unPromote(VJSParms_callStaticFunction& ioParms, CUAGSession* inSession)
{
	sLONG promotionToken = 0;
	ioParms.GetLongParam(1, &promotionToken);
	CUAGThreadPrivilege* privileges = static_cast<CUAGThreadPrivilege*>(ioParms.GetContext().GetGlobalObjectPrivateInstance()->GetSpecific('uagX'));
	inSession->UnPromoteFromToken(promotionToken, privileges);
}
void VJSTimer::ClearInterval (VJSParms_callStaticFunction &ioParms, VJSGlobalObject *inGlobalObject)
{
	VJSWorker	*worker;

	worker = VJSWorker::RetainWorker(ioParms.GetContext());
	VJSTimer::_ClearTimer(ioParms, worker, true);
	XBOX::ReleaseRefCountable<VJSWorker>(&worker);
}
void VJSTimer::SetTimeout (VJSParms_callStaticFunction &ioParms, VJSGlobalObject *inGlobalObject)
{
	VJSWorker	*worker;

	worker = VJSWorker::RetainWorker(ioParms.GetContext());
	VJSTimer::_SetTimer(ioParms, worker, false);
	XBOX::ReleaseRefCountable<VJSWorker>(&worker);
}
void VJSDataServiceCore::_setEnabled( VJSParms_callStaticFunction& ioParms, VDataService *inService)
{
	VRIAContext *riaContext = VRIAJSRuntimeContext::GetApplicationContextFromJSContext( ioParms.GetContext(), inService->GetApplication());

	bool enabled = false;
	if (ioParms.GetBoolParam( 1, &enabled))
	{
		inService->SetEnabled( enabled);
	}
}
Beispiel #6
0
VJSArray buildArrFromGroups(VJSParms_callStaticFunction& ioParms, CUAGGroupVector groups, const VString* filter)
{
	VJSArray groupArr(ioParms.GetContext());
	for (CUAGGroupVector::iterator cur = groups.begin(), end = groups.end(); cur != end; ++cur)
	{
		if (filter == nil)
		{
			groupArr.PushValue((*cur)->CreateJSGroupObject(ioParms.GetContext()));
		}
		else
		{
			VString s;
			(*cur)->GetName(s);
			if (s.CompareToSameKind_Like(filter) == CR_EQUAL)
				groupArr.PushValue((*cur)->CreateJSGroupObject(ioParms.GetContext()));
		}
	}

	return groupArr;
}
Beispiel #7
0
VJSArray buildArrFromUsers(VJSParms_callStaticFunction& ioParms, CUAGUserVector& users, const VString* filter)
{
	VJSArray userArr(ioParms.GetContext());
	for (CUAGUserVector::iterator cur = users.begin(), end = users.end(); cur != end; ++cur)
	{
		if (filter == nil)
		{
			userArr.PushValue((*cur)->CreateJSUserObject(ioParms.GetContext()));
		}
		else
		{
			VString s;
			(*cur)->GetName(s);
			if (s.CompareToSameKind_Like(filter) == CR_EQUAL)
				userArr.PushValue((*cur)->CreateJSUserObject(ioParms.GetContext()));
		}
	}

	return userArr;
}
void VJSGlobalClass::do_include( VJSParms_callStaticFunction& inParms, VJSGlobalObject *inGlobalObject)
{
	// EvaluateScript() uses NULL (this is default) as inThisObject argument. 
	// This works fine currently, but would it be better (if any problem) to pass global (application) object instead? 
	// See WAK0074064.

	VFile* file = inParms.RetainFileParam(1, false);
	if (file != NULL)
	{
		bool newlyRegistered = inGlobalObject->RegisterIncludedFile( file);		// sc 15/06/2010 the file must be registered
		if (inParms.GetBoolParam(2,"refresh","auto") || newlyRegistered)
		{
			inParms.GetContext().EvaluateScript( file, NULL, inParms.GetExceptionRefPointer());
		}
		file->Release();
	}
	else
	{
		VString pathname;
		if (inParms.IsStringParam(1) && inParms.GetStringParam( 1, pathname))
		{
			VFolder* folder = inGlobalObject->GetRuntimeDelegate()->RetainScriptsFolder();
			if (folder != NULL)
			{
				file = new VFile( *folder, pathname, FPS_POSIX);
				
				bool newlyRegistered = inGlobalObject->RegisterIncludedFile( file);		// sc 15/06/2010 the file must be registered
				if (inParms.GetBoolParam(2,"refresh","auto") || newlyRegistered)
				{
					inParms.GetContext().EvaluateScript( file, NULL, inParms.GetExceptionRefPointer());
				}
				ReleaseRefCountable( &file);
			}
			ReleaseRefCountable( &folder);
		}
		else
			vThrowError(VE_JVSC_WRONG_PARAMETER_TYPE_FILE, "1");
	}
}
Beispiel #9
0
void VJSSession::_promoteWith(VJSParms_callStaticFunction& ioParms, CUAGSession* inSession)
{
	sLONG promotionToken = 0;

	CUAGGroup* group = RetainParamGroup(inSession->GetDirectory(), ioParms, 1);
	if (group != nil)
	{
		CUAGThreadPrivilege* privileges = static_cast<CUAGThreadPrivilege*>(ioParms.GetContext().GetGlobalObjectPrivateInstance()->GetSpecific('uagX'));
		promotionToken = inSession->PromoteIntoGroup(group, privileges);
	}

	QuickReleaseRefCountable(group);
	ioParms.ReturnNumber(promotionToken);
}
Beispiel #10
0
void VJSSession::_belongsTo(VJSParms_callStaticFunction& ioParms, CUAGSession* inSession)
{
	bool ok = false;

	CUAGGroup* group = RetainParamGroup(inSession->GetDirectory(), ioParms, 1);
	if (group != nil)
	{
		CUAGThreadPrivilege* privileges = static_cast<CUAGThreadPrivilege*>(ioParms.GetContext().GetGlobalObjectPrivateInstance()->GetSpecific('uagX'));
		ok = inSession->BelongsTo(group, privileges);
	}

	QuickReleaseRefCountable(group);
	ioParms.ReturnBool(ok);
}
void VJSGlobalClass::do_Require(VJSParms_callStaticFunction& ioParms, VJSGlobalObject *inGlobalObject)
{
	xbox_assert(inGlobalObject != NULL);

	XBOX::VString	className;

	if (ioParms.CountParams() != 1 || !ioParms.IsStringParam(1) || !ioParms.GetStringParam(1, className))

		vThrowError(VE_JVSC_WRONG_PARAMETER_TYPE_STRING, "1");

	else

		ioParms.ReturnValue(inGlobalObject->Require(ioParms.GetContext(), className));
}
Beispiel #12
0
void VJSDirectory::_addGroup(VJSParms_callStaticFunction& ioParms, CUAGDirectory* inDirectory)
{
	VError err;
	VString groupname, fullname;
	ioParms.GetStringParam(1, groupname);
	ioParms.GetStringParam(2, fullname);
	CUAGGroup* group = inDirectory->AddOneGroup(groupname, fullname, err);
	if (group == nil)
		ioParms.ReturnNullValue();
	else
	{
		ioParms.ReturnValue(VJSGroup::CreateInstance(ioParms.GetContext(), group));
		group->Release();
	}
}
void VJSGlobalClass::do_testMe( VJSParms_callStaticFunction& inParms, VJSGlobalObject*)
{
	VJSObject globalObject( inParms.GetContext().GetGlobalObject());
	
	VString functionName;
	inParms.GetStringParam( 1, functionName);
	
	std::vector<VJSValue> values;
	size_t count = inParms.CountParams();
	for( size_t i = 2 ; i <= count ; ++i)
		values.push_back( inParms.GetParamValue( i));

	VJSValue result( inParms.GetContextRef());
	bool ok = globalObject.CallMemberFunction( functionName, &values, &result, inParms.GetExceptionRefPointer());
	inParms.ReturnValue( result);
}
Beispiel #14
0
void VJSDirectory::_addUser(VJSParms_callStaticFunction& ioParms, CUAGDirectory* inDirectory)
{
	VError err;
	VString username, password, fullname;
	ioParms.GetStringParam(1, username);
	ioParms.GetStringParam(2, password);
	ioParms.GetStringParam(3, fullname);
	CUAGUser* user = inDirectory->AddOneUser(username, password, fullname, err);
	if (user == nil)
		ioParms.ReturnNullValue();
	else
	{
		ioParms.ReturnValue(VJSUser::CreateInstance(ioParms.GetContext(), user));
		user->Release();
	}
	
}
void VJSStorageClass::_key (VJSParms_callStaticFunction &ioParms, IJSStorageObject *inStorageObject)
{
	xbox_assert(inStorageObject != NULL);

	sLONG	index;

	if (ioParms.CountParams() && ioParms.IsNumberParam(1) && ioParms.GetLongParam(1, &index)) {

		XBOX::VJSValue	value(ioParms.GetContext());

		inStorageObject->GetKeyValue(index, &value);

		ioParms.ReturnValue(value);

	} else

		ioParms.ReturnNullValue();
}
void VJSStorageClass::_getItem (VJSParms_callStaticFunction &ioParms, VJSStorageObject *inStorageObject)
{
	xbox_assert(inStorageObject != NULL);

	XBOX::VString	name;

	if (ioParms.CountParams() && ioParms.IsStringParam(1) && ioParms.GetStringParam(1, name)) {

		XBOX::VJSValue	value(ioParms.GetContext());

		inStorageObject->GetKeyValue(name, &value);

		ioParms.ReturnValue(value);

	} else

		ioParms.ReturnNullValue();
}
Beispiel #17
0
void VJSDirectory::_getGroup(VJSParms_callStaticFunction& ioParms, CUAGDirectory* inDirectory)
{
	StErrorContextInstaller errs(false, true);
	VString s;
	ioParms.GetStringParam(1, s);
	CUAGGroup* group = inDirectory->RetainGroup(s);
	if (group == nil)
	{
		VUUID id;
		id.FromString(s);
		group = inDirectory->RetainGroup(id);
	}
	if (group == nil)
		ioParms.ReturnNullValue();
	else
	{
		ioParms.ReturnValue(VJSGroup::CreateInstance(ioParms.GetContext(), group));
		group->Release();
	}
}
Beispiel #18
0
void VJSDirectory::_getUser(VJSParms_callStaticFunction& ioParms, CUAGDirectory* inDirectory)
{
	StErrorContextInstaller errs(false, true);
	VString s;
	ioParms.GetStringParam(1, s);
	CUAGUser* user = inDirectory->RetainUser(s);
	if (user == nil)
	{
		VUUID id;
		id.FromString(s);
		user = inDirectory->RetainUser(id);
	}
	if (user == nil)
		ioParms.ReturnNullValue();
	else
	{
		ioParms.ReturnValue(VJSUser::CreateInstance(ioParms.GetContext(), user));
		user->Release();
	}
}
Beispiel #19
0
void VJSGroup::_removeFrom(VJSParms_callStaticFunction& ioParms, CUAGGroup* inGroup)
{
	VError err = VE_OK;
	sLONG nbparam = ioParms.CountParams();
	for (sLONG i = 1; i <= nbparam /*&& err == VE_OK*/; i++)
	{
		if (ioParms.IsArrayParam(i))
		{
			VJSArray arr(ioParms.GetContext(), nil, false);
			ioParms.GetParamArray(i, arr);
			sLONG nbelem = arr.GetLength();
			for (sLONG j = 0; j < nbelem; ++j)
			{
				VJSValue val(arr.GetValueAt(j));
				if (val.IsString())
				{
					VString s;
					val.GetString(s);
					err = removeGroupFromGroup(ioParms, inGroup, s);
				}
				else /*if (val.IsInstanceOf("Group"))*/
				{
					CUAGGroup* group = val.GetObjectPrivateData<VJSGroup>();
					if (group != nil)
						err = inGroup->RemoveFromGroup(group);
				}
			}
		}
		else if (ioParms.IsStringParam(i))
		{
			VString s;
			ioParms.GetStringParam(i, s);
			err = removeGroupFromGroup(ioParms, inGroup, s);
		}
		else
		{
			CUAGGroup* group = ioParms.GetParamObjectPrivateData<VJSGroup>(i);
			err = inGroup->RemoveFromGroup(group);
		}
	}
}
void VJSStorageClass::_setItem (VJSParms_callStaticFunction &ioParms, VJSStorageObject *inStorageObject)
{
	xbox_assert(inStorageObject != NULL);

	XBOX::VString	name;

	if (ioParms.CountParams() && ioParms.IsStringParam(1) && ioParms.GetStringParam(1, name)) {

		XBOX::VJSValue	value(ioParms.GetContext());
		
		if (ioParms.CountParams() < 2)
		
			value.SetUndefined();

		else

			value = ioParms.GetParamValue(2);

		inStorageObject->SetKeyValue(name, value);

	}	
}
Beispiel #21
0
void VJSSession::_checkPermission(VJSParms_callStaticFunction& ioParms, CUAGSession* inSession)
{
	bool ok = false;

	CUAGGroup* group = RetainParamGroup(inSession->GetDirectory(), ioParms, 1);
	if (group != nil)
	{
		CUAGThreadPrivilege* privileges = static_cast<CUAGThreadPrivilege*>(ioParms.GetContext().GetGlobalObjectPrivateInstance()->GetSpecific('uagX'));
		ok = inSession->BelongsTo(group, privileges);
	}

	if (!ok)
	{
		VString groupName;
		if (group != nil)
			group->GetName(groupName);
		ThrowError(VE_UAG_SESSION_FAILED_PERMISSION, groupName);
	}

	QuickReleaseRefCountable(group);
	ioParms.ReturnBool(ok);
}
void VJSRequireClass::_evaluate (VJSParms_callStaticFunction &ioParms, void *)
{
	XBOX::VJSContext	context(ioParms.GetContext());
	XBOX::VString		fullPath;
	XBOX::VJSObject		exportsObject(context), moduleObject(context);

	if (!ioParms.GetStringParam(1, fullPath)) {
		
		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_STRING, "1");
		return;

	}

	if (!ioParms.GetParamObject(2, exportsObject)) {

		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_OBJECT, "2");
		return;

	}

	if (!ioParms.GetParamObject(3, moduleObject)) {

		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_OBJECT, "3");
		return;

	}

	XBOX::VError	error;
	XBOX::VURL		url;
	XBOX::VString	script;
		
	if ((error = VJSModuleState::LoadScript(fullPath, &url, &script)) != XBOX::VE_OK) {

		if (error == XBOX::VE_JVSC_SCRIPT_NOT_FOUND) {

			// Should not happen as require() does already check for existence.

			XBOX::vThrowError(XBOX::VE_JVSC_SCRIPT_NOT_FOUND, fullPath);

		} else

			XBOX::vThrowError(error);
			
	} else {

		XBOX::VFilePath	path(fullPath, FPS_POSIX);
		XBOX::VFile		*file;
			
		if ((file = new XBOX::VFile(path)) == NULL) {

			XBOX::vThrowError(XBOX::VE_MEMORY_FULL);
			
		} else {

			context.GetGlobalObjectPrivateInstance()->RegisterIncludedFile(file);

			XBOX::VString				functionScript;
			XBOX::VJSValue				functionResult(context);
			XBOX::JS4D::ExceptionRef	exception;			

			// Make a function of the module script, then call it.
			
			functionScript.AppendString("(function (exports, module) {");
			functionScript.AppendString(script);
			functionScript.AppendString("})");

			if (!context.EvaluateScript(functionScript, &url, &functionResult, &exception)) {
						
				ioParms.SetException(exception);	// Syntax error.

			} else {

				xbox_assert(functionResult.IsFunction());

				XBOX::VJSObject				functionObject(context);
				std::vector<XBOX::VJSValue>	arguments;
				XBOX::VJSValue				result(context);

				functionObject.SetObjectRef((XBOX::JS4D::ObjectRef) functionResult.GetValueRef());
	
				arguments.push_back(exportsObject);
				arguments.push_back(moduleObject);

				if (!context.GetGlobalObject().CallFunction(functionObject, &arguments, &result, &exception, &path)) 

					ioParms.SetException(exception);

				else 

					ioParms.ReturnValue(result);

			}

			XBOX::ReleaseRefCountable<XBOX::VFile>(&file);

		}

	}	
}
void VJSGlobalClass::do_garbageCollect(VJSParms_callStaticFunction& ioParms, VJSGlobalObject*)
{
	ioParms.GetContext().GarbageCollect();
}
void VJSStream::_PutBinary (VJSParms_callStaticFunction &ioParms, XBOX::VStream *inStream)
{
	xbox_assert(inStream != NULL);

	XBOX::VJSObject	binaryObject(ioParms.GetContext());
		
	if (!ioParms.GetParamObject(1, binaryObject)) {
	
		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER, "1");
		return;

	} 

	bool			isBuffer;
	VJSBufferObject	*buffer;
	VJSDataSlice	*dataSlice;
	const void		*data;
	VSize			size;

	if (binaryObject.IsOfClass(VJSBufferClass::Class())) {
		
		isBuffer = true;

		buffer = binaryObject.GetPrivateData<VJSBufferClass>();
		xbox_assert(buffer != NULL);

		buffer->Retain();

		data = buffer->GetDataPtr();
		size = buffer->GetDataSize();

	} else if (binaryObject.IsOfClass(VJSBlob::Class())) {

		VJSBlobValue	*blob;

		isBuffer = false;

		blob = binaryObject.GetPrivateData<VJSBlob>();
		xbox_assert(blob != NULL);

		dataSlice = blob->RetainDataSlice();
		xbox_assert(dataSlice != NULL);
		
		data = dataSlice->GetDataPtr();
		size = dataSlice->GetDataSize();

	} else {

		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER, "1");
		return;

	}

	bool	isOk;
	sLONG	index, length;

	isOk = true;	
		
	if (ioParms.CountParams() >= 2) {
		
		if (!ioParms.GetLongParam(2, &index)) {

			XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "2");
			isOk = false;

		} 

	} else

		index = 0;

	if (isOk && ioParms.CountParams() >= 3) {
		
		if (!ioParms.GetLongParam(3, &length)) {

			XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "3");
			isOk = false;

		} 

	} else {

		length = (sLONG) size;
		if (index > 0)

			length -= index;

	}

	// Silently ignore if out of bound.

	if (isOk && index >= 0 && length > 0 && index + length <= size) {

		XBOX::VError	error;

		if ((error = inStream->PutData((uBYTE *) data + index, length)) != XBOX::VE_OK)

			XBOX::vThrowError(error);

	}

	if (isBuffer)

		buffer->Release();

	else

		dataSlice->Release();

}
void VJSStream::_GetBinary (VJSParms_callStaticFunction &ioParms, XBOX::VStream* inStream, bool inIsBuffer)
{
	xbox_assert(inStream != NULL);

	sLONG	size;
	void	*buffer;

	if (!ioParms.GetLongParam(1, &size) || size < 0) {

		XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1");
		ioParms.ReturnNullValue();

	} else if (!size) {

		if (inIsBuffer)

			ioParms.ReturnValue(VJSBufferClass::NewInstance(ioParms.GetContext(), 0, NULL));

		else 

			ioParms.ReturnValue(VJSBlob::NewInstance(ioParms.GetContext(), 0, NULL, ""));
			
	} else if ((buffer = ::malloc(size)) == NULL) {
	
		vThrowError(XBOX::VE_MEMORY_FULL);
		ioParms.ReturnNullValue();
	
	} else {

		XBOX::VError	error;
		VSize			bytesRead;

		// Prevent error throwing for XBOX::VE_STREAM_EOF, this will allow to read less than requested.

		{
			StErrorContextInstaller	context(false, true);

			error = inStream->GetData(buffer, size, &bytesRead);
		}

/*
		// Do ::realloc()?

		if (bytesRead < size)

			buffer = ::realloc(buffer, bytesRead);
*/
				
		if (error != XBOX::VE_OK && error != XBOX::VE_STREAM_EOF) {

			XBOX::vThrowError(error);
			ioParms.ReturnNullValue();
			::free(buffer);

		} else {
			
			if (inIsBuffer) 

				ioParms.ReturnValue(VJSBufferClass::NewInstance(ioParms.GetContext(), bytesRead, buffer));

			else

				ioParms.ReturnValue(VJSBlob::NewInstance(ioParms.GetContext(), bytesRead, buffer, ""));

			// Check if instance creation has succeed, if not free memory.

			if (ioParms.GetReturnValue().IsNull())

				::free(buffer);
			
		}	

	}
}
Beispiel #26
0
void VJSTimer::_SetTimer (VJSParms_callStaticFunction &ioParms, VJSWorker *inWorker, bool inIsInterval) 
{
	xbox_assert(inWorker != NULL);

	if (!ioParms.CountParams())
		
		return;

	XBOX::VJSContext	context(ioParms.GetContext());
	XBOX::VJSObject		functionObject(context);

	ioParms.GetParamObject(1, functionObject);
	if (!functionObject.IsFunction())

		return;

	functionObject.Protect();

	Real	duration;

	duration = 0.0;
	if (ioParms.CountParams() >= 2) {

		if (ioParms.IsNumberParam(2)) {
			
			if (!ioParms.GetRealParam(2, &duration))
			
				duration = 0.0;

		} else {

			// According to specification, if timeout is an object, call its toString() method if any. 
			// Then apply ToNumber() on the string to obtain duration.
			
			XBOX::VJSObject	timeOutObject(context);

			if (ioParms.GetParamObject(2, timeOutObject)) {

				timeOutObject.SetContext(context);
				if (timeOutObject.HasProperty("toString")) {

					XBOX::VJSObject	toStringObject = timeOutObject.GetPropertyAsObject("toString");

					if (toStringObject.IsFunction()) {

						std::vector<XBOX::VJSValue>	values;
						XBOX::VJSValue				string(context);

						toStringObject.SetContext(context);
						timeOutObject.CallFunction(toStringObject, &values, &string, NULL);

						if (string.IsString()) {

							// If Number() is called as a function (and not as a constructor), it acts as ToNumber().
							// See section 15.7.1 of ECMA-262 specification.

							XBOX::VJSObject	toNumberObject = context.GetGlobalObject().GetPropertyAsObject("Number");

							if (toNumberObject.IsFunction()) {

								XBOX::VJSValue	number(context);

								values.clear();
								values.push_back(string);
								toNumberObject.SetContext(context);
								context.GetGlobalObject().CallFunction(toNumberObject, &values, &number, NULL);

								if (number.IsNumber() && !number.GetReal(&duration))

									duration = 0.0;

							}

						}

					}

				}

			}
		
		}

		// (value != value) is true if value is a NaN.

		if (duration < 0.0 || duration > XBOX::kMAX_Real || duration != duration)
		
			duration = 0.0;

	}	
	
	std::vector<XBOX::VJSValue> *arguments;

	arguments = new std::vector<XBOX::VJSValue>;
	for (sLONG i = 3; i <= ioParms.CountParams(); i++) 

		arguments->push_back(ioParms.GetParamValue(i));

	sLONG		period, id;
	VJSTimer	*timer;

	period = (sLONG) duration;
	if (inIsInterval) {

		if (period < VJSTimer::kMinimumInterval)

			period = VJSTimer::kMinimumInterval;

	} else {

		if (period < VJSTimer::kMinimumTimeout)

			period = VJSTimer::kMinimumTimeout;

	}		 
	timer = new VJSTimer(functionObject, inIsInterval ? period : VJSTimer::kTimeOut);
	if ((id = inWorker->GetTimerContext()->InsertTimer(timer)) < 0) {

		// Too many timers (should never happen). Silently ignore. 
		// Returned ID (-1) isn't valid and a clear on it, will do nothing.

		timer->Release();
		delete arguments;
	
	} else {

		XBOX::VTime	triggerTime;
	
		triggerTime.FromSystemTime();
		triggerTime.AddMilliseconds(period);

		inWorker->QueueEvent(VJSTimerEvent::Create(timer, triggerTime, arguments));

	}

	ioParms.ReturnNumber(id);
}