template<> void ScriptInterface::ToJSVal<CFixedVector3D>(JSContext* cx, JS::MutableHandleValue ret, const CFixedVector3D& val) { JSAutoRequest rq(cx); // apply the Vector3D prototype to the return value; ScriptInterface::CxPrivate* pCxPrivate = ScriptInterface::GetScriptInterfaceAndCBData(cx); JS::RootedObject proto(cx, &pCxPrivate->pScriptInterface->GetCachedValue(ScriptInterface::CACHE_VECTOR3DPROTO).toObject()); JS::RootedObject obj(cx, JS_NewObject(cx, nullptr, proto, JS::NullPtr())); if (!obj) { ret.setUndefined(); return; } JS::RootedValue x(cx); JS::RootedValue y(cx); JS::RootedValue z(cx); ToJSVal(cx, &x, val.X); ToJSVal(cx, &y, val.Y); ToJSVal(cx, &z, val.Z); JS_SetProperty(cx, obj, "x", x); JS_SetProperty(cx, obj, "y", y); JS_SetProperty(cx, obj, "z", z); ret.setObject(*obj); }
template<> void ScriptInterface::ToJSVal<IComponent*>(JSContext* cx, JS::MutableHandleValue ret, IComponent* const& val) { JSAutoRequest rq(cx); if (val == NULL) { ret.setNull(); return; } // If this is a scripted component, just return the JS object directly JS::RootedValue instance(cx, val->GetJSInstance()); if (!instance.isNull()) { ret.set(instance); return; } // Otherwise we need to construct a wrapper object // (TODO: cache wrapper objects?) JS::RootedObject obj(cx); if (!val->NewJSObject(*ScriptInterface::GetScriptInterfaceAndCBData(cx)->pScriptInterface, &obj)) { // Report as an error, since scripts really shouldn't try to use unscriptable interfaces LOGERROR("IComponent does not have a scriptable interface"); ret.setUndefined(); return; } JS_SetPrivate(obj, static_cast<void*>(val)); ret.setObject(*obj); }
bool rs::jsapi::Object::Get(JSContext* cx, JS::HandleObject obj, JS::HandleId id, JS::MutableHandleValue vp) { JSAutoRequest ar(cx); auto state = Object::GetState(cx, obj); if (state != nullptr && state->getter != nullptr) { Value value(cx); auto name = JSID_TO_STRING(id); char nameBuffer[256]; auto nameLength = JS_EncodeStringToBuffer(cx, name, nameBuffer, sizeof(nameBuffer) - 1); try { value.setUndefined(); if (nameLength < sizeof(nameBuffer)) { nameBuffer[nameLength] = '\0'; state->getter(nameBuffer, value); } else { std::vector<char> nameVector(nameLength + 1); nameLength = JS_EncodeStringToBuffer(cx, name, &nameVector[0], nameVector.size() - 1); nameVector[nameLength] = '\0'; state->getter(&nameVector[0], value); } vp.set(value); return true; } catch (const std::exception& ex) { JS_ReportError(cx, ex.what()); return false; } } else { vp.setUndefined(); return true; } }
void WebGL2Context::GetActiveUniformBlockParameter(JSContext* cx, const WebGLProgram& program, GLuint uniformBlockIndex, GLenum pname, JS::MutableHandleValue out_retval, ErrorResult& out_error) { out_retval.setNull(); if (IsContextLost()) return; if (!ValidateObject("getActiveUniformBlockParameter: program", program)) return; MakeContextCurrent(); switch(pname) { case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER: case LOCAL_GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: case LOCAL_GL_UNIFORM_BLOCK_BINDING: case LOCAL_GL_UNIFORM_BLOCK_DATA_SIZE: case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: out_retval.set(program.GetActiveUniformBlockParam(uniformBlockIndex, pname)); return; case LOCAL_GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: out_retval.set(program.GetActiveUniformBlockActiveUniforms(cx, uniformBlockIndex, &out_error)); return; } ErrorInvalidEnumInfo("getActiveUniformBlockParameter: parameter", pname); }
void WebGL2Context::GetSamplerParameter(JSContext*, WebGLSampler* sampler, GLenum pname, JS::MutableHandleValue retval) { if (IsContextLost()) return; if (!sampler || sampler->IsDeleted()) return ErrorInvalidOperation("getSamplerParameter: invalid sampler"); if (!ValidateSamplerParameterName(pname, "getSamplerParameter")) return; retval.set(JS::NullValue()); switch (pname) { case LOCAL_GL_TEXTURE_MIN_FILTER: case LOCAL_GL_TEXTURE_MAG_FILTER: case LOCAL_GL_TEXTURE_WRAP_S: case LOCAL_GL_TEXTURE_WRAP_T: case LOCAL_GL_TEXTURE_WRAP_R: case LOCAL_GL_TEXTURE_COMPARE_MODE: case LOCAL_GL_TEXTURE_COMPARE_FUNC: retval.set(JS::Int32Value( WebGLContextUnchecked::GetSamplerParameteriv(sampler, pname))); return; case LOCAL_GL_TEXTURE_MIN_LOD: case LOCAL_GL_TEXTURE_MAX_LOD: retval.set(JS::Float32Value( WebGLContextUnchecked::GetSamplerParameterfv(sampler, pname))); return; } }
template<> void ScriptInterface::ToJSVal<CColor>(JSContext* cx, JS::MutableHandleValue ret, CColor const& val) { JSAutoRequest rq(cx); JS::RootedObject obj(cx, JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr())); if (!obj) { ret.setUndefined(); return; } JS::RootedValue r(cx); JS::RootedValue g(cx); JS::RootedValue b(cx); JS::RootedValue a(cx); ToJSVal(cx, &r, val.r); ToJSVal(cx, &g, val.g); ToJSVal(cx, &b, val.b); ToJSVal(cx, &a, val.a); JS_SetProperty(cx, obj, "r", r); JS_SetProperty(cx, obj, "g", g); JS_SetProperty(cx, obj, "b", b); JS_SetProperty(cx, obj, "a", a); ret.setObject(*obj); }
bool JSAudioContext::JSSetter_volume(JSContext *cx, JS::MutableHandleValue vp) { if (vp.isNumber()) { m_Audio->setVolume((float)vp.toNumber()); } return true; }
void WebGL2Context::GetIndexedParameter(JSContext* cx, GLenum target, GLuint index, JS::MutableHandleValue retval, ErrorResult& out_error) { const char funcName[] = "getIndexedParameter"; retval.set(JS::NullValue()); if (IsContextLost()) return; const std::vector<IndexedBufferBinding>* bindings; switch (target) { case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START: case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: bindings = &(mBoundTransformFeedback->mIndexedBindings); break; case LOCAL_GL_UNIFORM_BUFFER_BINDING: case LOCAL_GL_UNIFORM_BUFFER_START: case LOCAL_GL_UNIFORM_BUFFER_SIZE: bindings = &mIndexedUniformBufferBindings; break; default: ErrorInvalidEnumInfo("getIndexedParameter: target", target); return; } if (index >= bindings->size()) { ErrorInvalidValue("%s: `index` must be < %s.", funcName, "MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS"); return; } const auto& binding = (*bindings)[index]; JS::Value ret = JS::NullValue(); switch (target) { case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: case LOCAL_GL_UNIFORM_BUFFER_BINDING: if (binding.mBufferBinding) { ret = WebGLObjectAsJSValue(cx, binding.mBufferBinding.get(), out_error); } break; case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_START: case LOCAL_GL_UNIFORM_BUFFER_START: ret = JS::NumberValue(binding.mRangeStart); break; case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: case LOCAL_GL_UNIFORM_BUFFER_SIZE: ret = JS::NumberValue(binding.mRangeSize); break; } retval.set(ret); }
template<> void ScriptInterface::ToJSVal<const char*>(JSContext* cx, JS::MutableHandleValue ret, const char* const& val) { JSAutoRequest rq(cx); JS::RootedString str(cx, JS_NewStringCopyZ(cx, val)); if (str) ret.setString(str); else ret.setUndefined(); }
bool JSAudioNodeCustomSource::JSSetter_position(JSContext *cx, JS::MutableHandleValue vp) { if (vp.isNumber()) { this->getNode<AudioSourceCustom>()->seek(vp.toNumber()); } return true; }
template<> void ScriptInterface::ToJSVal<std::string>(JSContext* cx, JS::MutableHandleValue ret, const std::string& val) { JSAutoRequest rq(cx); JS::RootedString str(cx, JS_NewStringCopyN(cx, val.c_str(), val.length())); if (str) ret.setString(str); else ret.setUndefined(); }
void WebGLContext::GetQuery(JSContext* cx, GLenum target, GLenum pname, JS::MutableHandleValue retval) { const FuncScope funcScope(*this, "getQuery"); retval.setNull(); if (IsContextLost()) return; switch (pname) { case LOCAL_GL_CURRENT_QUERY_EXT: { if (IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query) && target == LOCAL_GL_TIMESTAMP) { // Doesn't seem illegal to ask about, but is always null. // TIMESTAMP has no slot, so ValidateQuerySlotByTarget would generate // INVALID_ENUM. return; } const auto& slot = ValidateQuerySlotByTarget(target); if (!slot || !*slot) return; const auto& query = *slot; if (target != query->Target()) return; JS::Rooted<JS::Value> v(cx); dom::GetOrCreateDOMReflector(cx, slot->get(), &v); retval.set(v); } return; case LOCAL_GL_QUERY_COUNTER_BITS_EXT: if (!IsExtensionEnabled(WebGLExtensionID::EXT_disjoint_timer_query)) break; if (target != LOCAL_GL_TIME_ELAPSED_EXT && target != LOCAL_GL_TIMESTAMP_EXT) { ErrorInvalidEnumInfo("target", target); return; } { GLint bits = 0; gl->fGetQueryiv(target, pname, &bits); if (!Has64BitTimestamps() && bits > 32) { bits = 32; } retval.set(JS::Int32Value(bits)); } return; default: break; } ErrorInvalidEnumInfo("pname", pname); }
template<> void ScriptInterface::ToJSVal<std::wstring>(JSContext* cx, JS::MutableHandleValue ret, const std::wstring& val) { JSAutoRequest rq(cx); utf16string utf16(val.begin(), val.end()); JS::RootedString str(cx, JS_NewUCStringCopyN(cx, reinterpret_cast<const char16_t*> (utf16.c_str()), utf16.length())); if (str) ret.setString(str); else ret.setUndefined(); }
void CNetClient::GuiPoll(JS::MutableHandleValue ret) { if (m_GuiMessageQueue.empty()) { ret.setUndefined(); return; } ret.set(m_GuiMessageQueue.front()); m_GuiMessageQueue.pop_front(); }
static JSBool gjs_value_from_gsize(JSContext *context, gsize v, JS::MutableHandleValue value_p) { if (v > (gsize) JSVAL_INT_MAX) { value_p.set(INT_TO_JSVAL(v)); return JS_TRUE; } else { return JS_NewNumberValue(context, v, value_p.address()); } }
template<> void ScriptInterface::ToJSVal<CParamNode>(JSContext* cx, JS::MutableHandleValue ret, CParamNode const& val) { JSAutoRequest rq(cx); val.ToJSVal(cx, true, ret); // Prevent modifications to the object, so that it's safe to share between // components and to reconstruct on deserialization if (ret.isObject()) { JS::RootedObject obj(cx, &ret.toObject()); JS_DeepFreezeObject(cx, obj); } }
void ScriptInterface::CallConstructor(JS::HandleValue ctor, JS::HandleValueArray argv, JS::MutableHandleValue out) { JSAutoRequest rq(m->m_cx); if (!ctor.isObject()) { LOGERROR("CallConstructor: ctor is not an object"); out.setNull(); return; } JS::RootedObject ctorObj(m->m_cx, &ctor.toObject()); out.setObjectOrNull(JS_New(m->m_cx, ctorObj, argv)); }
void MozJSImplScope::_MozJSCreateFunction(const char* raw, ScriptingFunction functionNumber, JS::MutableHandleValue fun) { std::string code = str::stream() << "_funcs" << functionNumber << " = " << parseJSFunctionOrExpression(_context, StringData(raw)); JS::CompileOptions co(_context); setCompileOptions(&co); _checkErrorState(JS::Evaluate(_context, _global, co, code.c_str(), code.length(), fun)); uassert(10232, "not a function", fun.isObject() && JS_ObjectIsFunction(_context, fun.toObjectOrNull())); }
void IdWrapper::toValue(JS::MutableHandleValue value) const { if (isInt()) { value.setInt32(toInt32()); return; } if (isString()) { auto str = JSID_TO_STRING(_value); value.setString(str); return; } uasserted(ErrorCodes::BadValue, "Failed to toValue() non-string and non-integer jsid"); }
bool JSAudioContext::JSGetter_channels(JSContext *cx, JS::MutableHandleValue vp) { AudioParameters *params = m_Audio->m_OutputParameters; vp.setInt32(params->m_Channels); return true; }
bool gjs_lookup_interface_constructor(JSContext *context, GType gtype, JS::MutableHandleValue value_p) { JSObject *constructor; GIBaseInfo *interface_info; interface_info = g_irepository_find_by_gtype(NULL, gtype); if (interface_info == NULL) { gjs_throw(context, "Cannot expose non introspectable interface %s", g_type_name(gtype)); return false; } g_assert(g_base_info_get_type(interface_info) == GI_INFO_TYPE_INTERFACE); constructor = gjs_lookup_generic_constructor(context, interface_info); if (G_UNLIKELY (constructor == NULL)) return false; g_base_info_unref(interface_info); value_p.setObject(*constructor); return true; }
static JSBool byte_array_set_index(JSContext *context, JS::HandleObject obj, ByteArrayInstance *priv, gsize idx, JS::MutableHandleValue value_p) { guint8 v; if (!gjs_value_to_byte(context, value_p, &v)) { return JS_FALSE; } byte_array_ensure_array(priv); /* grow the array if necessary */ if (idx >= priv->array->len) { g_byte_array_set_size(priv->array, idx + 1); } g_array_index(priv->array, guint8, idx) = v; /* Stop JS from storing a copy of the value */ value_p.set(JSVAL_VOID); return JS_TRUE; }
void MongoStatusInfo::fromStatus(JSContext* cx, Status status, JS::MutableHandleValue value) { auto scope = getScope(cx); JS::RootedValue undef(cx); undef.setUndefined(); JS::AutoValueArray<1> args(cx); ValueReader(cx, args[0]).fromStringData(status.reason()); JS::RootedObject error(cx); scope->getProto<ErrorInfo>().newInstance(args, &error); JS::RootedObject thisv(cx); scope->getProto<MongoStatusInfo>().newObjectWithProto(&thisv, error); ObjectWrapper thisvObj(cx, thisv); thisvObj.defineProperty( InternedString::code, undef, JSPROP_ENUMERATE | JSPROP_SHARED, smUtils::wrapConstrainedMethod<Functions::code, false, MongoStatusInfo>); thisvObj.defineProperty( InternedString::reason, undef, JSPROP_ENUMERATE | JSPROP_SHARED, smUtils::wrapConstrainedMethod<Functions::reason, false, MongoStatusInfo>); JS_SetPrivate(thisv, scope->trackedNew<Status>(std::move(status))); value.setObjectOrNull(thisv); }
/** * gjs_string_from_ucs4: * @cx: a #JSContext * @ucs4_string: string of #gunichar * @n_chars: number of characters in @ucs4_string or -1 for zero-terminated * @value_p: JS::Value that will be filled with a string * * Returns: true on success, false otherwise in which case a JS error is thrown */ bool gjs_string_from_ucs4(JSContext *cx, const gunichar *ucs4_string, ssize_t n_chars, JS::MutableHandleValue value_p) { long u16_string_length; GError *error = NULL; char16_t *u16_string = reinterpret_cast<char16_t *>(g_ucs4_to_utf16(ucs4_string, n_chars, NULL, &u16_string_length, &error)); if (!u16_string) { gjs_throw(cx, "Failed to convert UCS-4 string to UTF-16: %s", error->message); g_error_free(error); return false; } JSAutoRequest ar(cx); /* Avoid a copy - assumes that g_malloc == js_malloc == malloc */ JS::RootedString str(cx, JS_NewUCString(cx, u16_string, u16_string_length)); if (!str) { gjs_throw(cx, "Failed to convert UCS-4 string to UTF-16"); return false; } value_p.setString(str); return true; }
void std_map_string_string_to_jsval(JSContext* cx, const std::map<std::string, std::string>& v, JS::MutableHandleValue retVal) { JS::RootedObject proto(cx); JS::RootedObject parent(cx); #if defined(MOZJS_MAJOR_VERSION) and MOZJS_MAJOR_VERSION >= 52 JS::RootedObject jsRet(cx, JS_NewObject(cx, NULL)); #elif defined(MOZJS_MAJOR_VERSION) and MOZJS_MAJOR_VERSION >= 26 JS::RootedObject jsRet(cx, JS_NewObject(cx, NULL, proto, parent)); #else JSObject *jsRet = JS_NewObject(cx, NULL, NULL, NULL); #endif for (auto iter = v.begin(); iter != v.end(); ++iter) { #if defined(MOZJS_MAJOR_VERSION) and MOZJS_MAJOR_VERSION >= 26 JS::RootedValue element(cx); #else jsval element; #endif std::string key = iter->first; std::string val = iter->second; JSString* jsstr = JS_NewStringCopyZ(cx, val.c_str()); element = JS::StringValue(jsstr); if (!key.empty()) { #if defined(MOZJS_MAJOR_VERSION) and MOZJS_MAJOR_VERSION >= 26 JS_SetProperty(cx, jsRet, key.c_str(), element); #else JS_SetProperty(cx, jsRet, key.c_str(), &element); #endif } } retVal.set(JS::ObjectOrNullValue(jsRet.get())); }
/*! @brief Convert a YARP list into a %JavaScript object. @param[in] jct The %JavaScript engine context. @param[in,out] theData The output object. @param[in] inputValue The value to be processed. */ static void convertList(JSContext * jct, JS::MutableHandleValue theData, const yarp::os::Bottle & inputValue) { ODL_ENTER(); //#### ODL_P2("jct = ", jct, "inputValue = ", &inputValue); //#### JSObject * valueArray = JS_NewArrayObject(jct, 0); if (valueArray) { JS::RootedObject arrayRooted(jct); JS::RootedValue anElement(jct); JS::RootedId aRootedId(jct); arrayRooted = valueArray; for (int ii = 0, mm = inputValue.size(); mm > ii; ++ii) { yarp::os::Value aValue(inputValue.get(ii)); convertValue(jct, &anElement, aValue); if (JS_IndexToId(jct, ii, &aRootedId)) { JS_SetPropertyById(jct, arrayRooted, aRootedId, anElement); } } theData.setObject(*valueArray); } ODL_EXIT(); //#### } // convertList
template<> void ScriptInterface::ToJSVal<const CParamNode*>(JSContext* cx, JS::MutableHandleValue ret, const CParamNode* const& val) { if (val) ToJSVal(cx, ret, *val); else ret.setUndefined(); }
bool JSGlobal::JSGetter___dirname(JSContext *cx, JS::MutableHandleValue vp) { Path path(JSUtils::CurrentJSCaller(cx), false, true); vp.setString(JS_NewStringCopyZ(cx, path.dir())); return true; }
// TODO: This is copy-pasted from scriptinterface/ScriptConversions.cpp (#define VECTOR stuff), would be nice to remove the duplication template<> void ScriptInterface::ToJSVal<std::vector<CFixedVector2D> >(JSContext* cx, JS::MutableHandleValue ret, const std::vector<CFixedVector2D>& val) { JSAutoRequest rq(cx); JS::RootedObject obj(cx, JS_NewArrayObject(cx, 0)); if (!obj) { ret.setUndefined(); return; } for (size_t i = 0; i < val.size(); ++i) { JS::RootedValue el(cx); ScriptInterface::ToJSVal<CFixedVector2D>(cx, &el, val[i]); JS_SetElement(cx, obj, i, el); } ret.setObject(*obj); }
template<typename T> static void ToJSVal_vector(JSContext* cx, JS::MutableHandleValue ret, const std::vector<T>& val) { JSAutoRequest rq(cx); JS::RootedObject obj(cx, JS_NewArrayObject(cx, 0)); if (!obj) { ret.setUndefined(); return; } for (u32 i = 0; i < val.size(); ++i) { JS::RootedValue el(cx); ScriptInterface::ToJSVal<T>(cx, &el, val[i]); JS_SetElement(cx, obj, i, el); } ret.setObject(*obj); }