bool VJSTextStream::_HasInstance (const VJSParms_hasInstance &inParms) { xbox_assert(inParms.GetObject().GetObjectRef() == inParms.GetObjectToTest()); xbox_assert(inParms.GetContext().GetGlobalObject().GetPropertyAsObject("TextStream") == inParms.GetPossibleContructor()); XBOX::VJSObject objectToTest = inParms.GetObject(); return objectToTest.IsOfClass(VJSTextStream::Class()); }
VJSTimer::VJSTimer (XBOX::VJSObject &inFunctionObject, sLONG inInterval) { xbox_assert(inFunctionObject.GetObjectRef() != NULL); xbox_assert(inInterval >= 0 || inInterval == VJSTimer::kTimeOut); fTimerContext = NULL; fID = -1; fInterval = inInterval; fFunctionObject = inFunctionObject.GetObjectRef(); }
XBOX::VJSObject VJSSharedWorkerClass::MakeConstructor (XBOX::VJSContext inContext) { XBOX::VJSObject constructor = JS4DMakeConstructor(inContext, Class(), _Construct, false, VJSSharedWorkerClass::sConstrFunctions ); XBOX::VJSArray listArray(inContext); constructor.SetProperty("list", listArray, JS4D::PropertyAttributeDontDelete); return constructor; }
void VJSSharedWorkerClass::_Construct (VJSParms_construct &ioParms) { if (!ioParms.CountParams() || !ioParms.IsStringParam(1) || (ioParms.CountParams() >= 2 && !ioParms.IsStringParam(2))) { XBOX::vThrowError(XBOX::VE_INVALID_PARAMETER); return; } XBOX::VJSContext context(ioParms.GetContext()); XBOX::VString url, name; bool reUseContext; VJSWorker *outsideWorker; VJSWebWorkerObject *workerProxy; #if USE_V8_ENGINE XBOX::VJSObject constructedObject = ioParms.fConstructedObject; #else XBOX::VJSObject constructedObject(context); #endif ioParms.GetStringParam(1, url); if (ioParms.CountParams() == 2) ioParms.GetStringParam(2, name); outsideWorker = VJSWorker::RetainWorker(context); if (ioParms.CountParams() < 3 || !ioParms.IsBooleanParam(3) || !ioParms.GetBoolParam(3, &reUseContext)) reUseContext = false; if ((workerProxy = VJSWebWorkerObject::_CreateWorker(context, outsideWorker, reUseContext, NULL, url, false, name)) != NULL) { constructedObject = VJSSharedWorkerClass::ConstructInstance(ioParms, workerProxy); workerProxy->fOnErrorPort->SetObject(outsideWorker, constructedObject); XBOX::VJSObject messagePortObject(context); messagePortObject = VJSMessagePortClass::CreateInstance(context, workerProxy->fOnMessagePort); workerProxy->fOnMessagePort->SetObject(outsideWorker, messagePortObject); constructedObject.SetProperty("port", messagePortObject); _AddToList(context, "SharedWorker", constructedObject); } ioParms.ReturnConstructedObject(constructedObject); XBOX::ReleaseRefCountable<VJSWorker>(&outsideWorker); }
void VJSMessagePort::SetObject (VJSWorker *inWorker, XBOX::VJSObject &inObject) { xbox_assert(inWorker != NULL && (inWorker == fOutsideWorker || inWorker == fInsideWorker)); xbox_assert((inWorker == fOutsideWorker && !fOutsideClosingFlag) || (inWorker == fInsideWorker && !fInsideClosingFlag)); xbox_assert(inObject.GetObjectRef() != NULL); if (inWorker == fOutsideWorker) fOutsideObject = inObject.GetObjectRef(); else fInsideObject = inObject.GetObjectRef(); }
bool VJSStructuredClone::_IsSerializable (XBOX::VJSValue inValue) { xbox_assert(inValue.IsObject()); XBOX::VJSObject object = inValue.GetObject(); if (object.HasProperty("constructorName") && object.GetProperty("constructorName").IsString() && object.HasProperty("serialize") && object.GetProperty("serialize").IsFunction()) return true; else return false; }
static void _AddToList (XBOX::VJSContext &inContext, const XBOX::VString &inConstructorName, XBOX::VJSObject &inConstructedObject) { if (inContext.GetGlobalObject().HasProperty(inConstructorName)) { XBOX::VJSObject workerObject = inContext.GetGlobalObject().GetPropertyAsObject(inConstructorName); if (workerObject.IsObject() && workerObject.HasProperty("list")) { XBOX::VJSValue value = workerObject.GetProperty("list"); if (value.IsArray()) { XBOX::VJSArray listArray(value); sLONG i; for (i = 0; i < listArray.GetLength(); i++) { value = listArray.GetValueAt(i); if (value.IsNull()) { listArray.SetValueAt(i, inConstructedObject); break; } } if (i == listArray.GetLength()) listArray.PushValue(inConstructedObject); } else { xbox_assert(false); } } else { xbox_assert(false); } } else { xbox_assert(false); } }
XBOX::VJSValue VJSStructuredClone::_ConstructObject (XBOX::VJSContext inContext, const XBOX::VString &inConstructorName, XBOX::VJSValue inArgument) { XBOX::VJSObject object = inContext.GetGlobalObject().GetPropertyAsObject(inConstructorName); std::vector<XBOX::VJSValue> arguments; XBOX::VJSValue value(inContext); arguments.push_back(inArgument); if (object.CallAsConstructor(&arguments, &object, NULL)) value.SetValueRef((JS4D::ObjectRef) object.GetObjectRef()); else value.SetUndefined(); return value; }
void VJSNetServerSyncClass::_accept (XBOX::VJSParms_callStaticFunction &ioParms, VJSNetServerObject *inServer) { xbox_assert(inServer != NULL); sLONG timeOut; if (ioParms.CountParams() >= 1) { if (!ioParms.IsNumberParam(1) || !ioParms.GetLongParam(1, &timeOut)) { XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1"); return; } if (timeOut < 0) { XBOX::vThrowError(XBOX::VE_JVSC_WRONG_PARAMETER_TYPE_NUMBER, "1"); return; } } else timeOut = 0; XBOX::XTCPSock *socket; // If socket returned is NULL, accept() has timed out or an error has occured. // An exception is thrown by GetNewConnectedSocket() if erroneous. if ((socket = inServer->fSockListener->GetNewConnectedSocket(timeOut)) == NULL) ioParms.ReturnNullValue(); else { XBOX::VTCPEndPoint *endPoint = NULL; VJSNetSocketObject *socketObject = NULL; if ((endPoint = new XBOX::VTCPEndPoint(socket)) == NULL || (socketObject = new VJSNetSocketObject(true, VJSNetSocketObject::eTYPE_TCP4, false)) == NULL) { if (endPoint != NULL) endPoint->Release(); if (socketObject != NULL) socketObject->Release(); socket->Close(); delete socket; XBOX::vThrowError(XBOX::VE_MEMORY_FULL); } else { socketObject->fEndPoint = endPoint; socketObject->fEndPoint->SetNoDelay(false); XBOX::VJSObject newSocketSync = VJSNetSocketSyncClass::CreateInstance(ioParms.GetContext(), socketObject); XBOX::VString address; socketObject->fObjectRef = newSocketSync.GetObjectRef(); socketObject->fWorker = VJSWorker::RetainWorker(ioParms.GetContext()); socketObject->fEndPoint->GetIP(address); newSocketSync.SetProperty("remoteAddress", address); newSocketSync.SetProperty("remotePort", (sLONG) socketObject->fEndPoint->GetPort() & 0xffff); ioParms.ReturnValue(newSocketSync); } } }
USING_TOOLBOX_NAMESPACE VJSStructuredClone *VJSStructuredClone::RetainClone (XBOX::VJSValue inValue) { std::map<JS4D::ValueRef, SNode *> alreadyCreated; std::list<SEntry> toDoList; SNode *root; if ((root = _ValueToNode(inValue, &alreadyCreated, &toDoList)) == NULL) return NULL; while (!toDoList.empty()) { // Property iterator will also iterate Array object indexes (they are converted into string). XBOX::VJSValue value(inValue.GetContext(), toDoList.front().fValueRef); XBOX::VJSPropertyIterator i(value.GetObject()); SNode *p, *q, *r; p = toDoList.front().fNode; xbox_assert(p->fType == eNODE_OBJECT || p->fType == eNODE_ARRAY); toDoList.pop_front(); // Object or Array with no attributes? if (!i.IsValid()) continue; // Get prototype and dump its attribute names. XBOX::VJSObject prototypeObject = value.GetObject().GetPrototype(inValue.GetContext()); bool hasPrototype = prototypeObject.IsObject(); // Iterate child(s). for ( ; i.IsValid(); ++i) { XBOX::VString name; i.GetPropertyName(name); // Check attribute name: If it is part of prototype, do not clone it. if (hasPrototype && prototypeObject.HasProperty(name)) continue; value = i.GetProperty(); if ((r = _ValueToNode(value, &alreadyCreated, &toDoList)) == NULL) break; else if (p->fValue.fFirstChild != NULL) q->fNextSibling = r; else p->fValue.fFirstChild = r; r->fName = name; q = r; } if (p->fValue.fFirstChild != NULL) q->fNextSibling = NULL; if (i.IsValid()) { _FreeNode(root); root = NULL; break; } } if (root != NULL) { VJSStructuredClone *structuredClone; if ((structuredClone = new VJSStructuredClone()) != NULL) structuredClone->fRoot = root; else _FreeNode(root); return structuredClone; } else return NULL; }
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); }