History

rework ScriptValue to act like a stack variable rather than a pointer

Heather Anderson committed 5 years ago

Commit 85810221 parent f209c51170 files · +2837 −2594Browse files

Showing the changes to libraries/script-engine/src/ScriptManager.cpp (1 of 170 files). Show all

Unified · Split

libraries/script-engine/src/ScriptManager.cpp+168−168
@@ -87,7 +87,7 @@ int scriptManagerPointerMetaID = qRegisterMetaType<ScriptManagerPointer>(); · 86 unmodified lines
8787
8888 Q_DECLARE_METATYPE(ExternalResource::Bucket);
8989
90−Q_DECLARE_METATYPE(ScriptValuePointer);
90+Q_DECLARE_METATYPE(ScriptValue);
9191
9292 // --- Static script initialization registry
9393
@@ -109,21 +109,21 @@ static void runStaticInitializers(ScriptManager* manager) { · 15 unmodified lines
109109
110110 // ---
111111
112−static ScriptValuePointer debugPrint(ScriptContext* context, ScriptEngine* engine) {
112+static ScriptValue debugPrint(ScriptContext* context, ScriptEngine* engine) {
113113 // assemble the message by concatenating our arguments
114114 QString message = "";
115115 for (int i = 0; i < context->argumentCount(); i++) {
116116 if (i > 0) {
117117 message += " ";
118118 }
119− message += context->argument(i)->toString();
119+ message += context->argument(i).toString();
120120 }
121121
122122 // was this generated by a script engine? If we don't recognize it then send the message and exit
123123 ScriptManager* scriptManager = engine->manager();
124124 if (!scriptManager) {
125125 qCDebug(scriptengine_script, "%s", qUtf8Printable(message));
126− return ScriptValuePointer();
126+ return ScriptValue();
127127 }
128128
129129 // This message was sent by one of our script engines, let's try to see if we can find the source.
@@ -170,7 +170,7 @@ static ScriptValuePointer debugPrint(ScriptContext* context, ScriptEngine* engin · 40 unmodified lines
170170 qCDebug(scriptengine_script, "[%s] %s", qUtf8Printable(scriptManager->getFilename()), qUtf8Printable(message));
171171 }
172172
173− return ScriptValuePointer();
173+ return ScriptValue();
174174 }
175175
176176 // FIXME Come up with a way to properly encode entity IDs in filename
@@ -193,7 +193,7 @@ QString encodeEntityIdIntoEntityUrl(const QString& url, const QString& entityID) · 16 unmodified lines
193193 return url + " [EntityID:" + entityID + "]";
194194 }
195195
196−QString ScriptManager::logException(const ScriptValuePointer& exception) {
196+QString ScriptManager::logException(const ScriptValue& exception) {
197197 auto message = formatException(exception, _enableExtendedJSExceptions.get());
198198 scriptErrorMessage(message);
199199 return message;
@@ -249,10 +249,10 @@ ScriptManager::ScriptManager(Context context, const QString& scriptContents, con · 49 unmodified lines
249249 }
250250
251251 // this is where all unhandled exceptions end up getting logged
252− connect(this, &ScriptManager::unhandledException, this, [this](const ScriptValuePointer& err) {
253− auto output = err->engine() == _engine ? err : _engine->makeError(err);
254− if (!output->property("detail")->isValid()) {
255− output->setProperty("detail", "UnhandledException");
252+ connect(this, &ScriptManager::unhandledException, this, [this](const ScriptValue& err) {
253+ auto output = err.engine() == _engine ? err : _engine->makeError(err);
254+ if (!output.property("detail").isValid()) {
255+ output.setProperty("detail", "UnhandledException");
256256 }
257257 logException(output);
258258 });
@@ -516,10 +516,10 @@ void ScriptManager::clearDebugLogWindow() { · 257 unmodified lines
516516 // Templated qScriptRegisterMetaType fails to compile with raw pointers
517517 using ScriptableResourceRawPtr = ScriptableResource*;
518518
519−static ScriptValuePointer scriptableResourceToScriptValue(ScriptEngine* engine,
519+static ScriptValue scriptableResourceToScriptValue(ScriptEngine* engine,
520520 const ScriptableResourceRawPtr& resource) {
521521 if (!resource) {
522− return ScriptValuePointer(); // probably shutting down
522+ return ScriptValue(); // probably shutting down
523523 }
524524
525525 // The first script to encounter this resource will track its memory.
@@ -538,8 +538,8 @@ static ScriptValuePointer scriptableResourceToScriptValue(ScriptEngine* engine, · 12 unmodified lines
538538 return object;
539539 }
540540
541−static void scriptableResourceFromScriptValue(const ScriptValuePointer& value, ScriptableResourceRawPtr& resource) {
542− resource = static_cast<ScriptableResourceRawPtr>(value->toQObject());
541+static void scriptableResourceFromScriptValue(const ScriptValue& value, ScriptableResourceRawPtr& resource) {
542+ resource = static_cast<ScriptableResourceRawPtr>(value.toQObject());
543543 }
544544
545545 /*@jsdoc
@@ -555,7 +555,7 @@ static void scriptableResourceFromScriptValue(const ScriptValuePointer& value, S · 9 unmodified lines
555555 *
556556 * @property {Resource.State} State - The possible loading states of a resource. <em>Read-only.</em>
557557 */
558−static ScriptValuePointer createScriptableResourcePrototype(ScriptManagerPointer manager) {
558+static ScriptValue createScriptableResourcePrototype(ScriptManagerPointer manager) {
559559 auto engine = manager->engine();
560560 auto prototype = engine->newObject();
561561
@@ -569,17 +569,17 @@ static ScriptValuePointer createScriptableResourcePrototype(ScriptManagerPointer · 7 unmodified lines
569569
570570 auto prototypeState = engine->newQObject(state, ScriptEngine::QtOwnership,
571571 ScriptEngine::ExcludeSlots | ScriptEngine::ExcludeSuperClassMethods);
572− prototype->setProperty("State", prototypeState);
572+ prototype.setProperty("State", prototypeState);
573573
574574 return prototype;
575575 }
576576
577−ScriptValuePointer externalResourceBucketToScriptValue(ScriptEngine* engine, ExternalResource::Bucket const& in) {
577+ScriptValue externalResourceBucketToScriptValue(ScriptEngine* engine, ExternalResource::Bucket const& in) {
578578 return engine->newValue((int)in);
579579 }
580580
581−void externalResourceBucketFromScriptValue(const ScriptValuePointer& object, ExternalResource::Bucket& out) {
582− out = static_cast<ExternalResource::Bucket>(object->toInt32());
581+void externalResourceBucketFromScriptValue(const ScriptValue& object, ExternalResource::Bucket& out) {
582+ out = static_cast<ExternalResource::Bucket>(object.toInt32());
583583 }
584584
585585 void ScriptManager::resetModuleCache(bool deleteScriptCache) {
@@ -587,33 +587,33 @@ void ScriptManager::resetModuleCache(bool deleteScriptCache) { · 1 unmodified line
587587 executeOnScriptThread([=]() { resetModuleCache(deleteScriptCache); });
588588 return;
589589 }
590− auto jsRequire = _engine->globalObject()->property("Script")->property("require");
591− auto cache = jsRequire->property("cache");
592− auto cacheMeta = jsRequire->data();
590+ auto jsRequire = _engine->globalObject().property("Script").property("require");
591+ auto cache = jsRequire.property("cache");
592+ auto cacheMeta = jsRequire.data();
593593
594594 if (deleteScriptCache) {
595− auto it = cache->newIterator();
595+ auto it = cache.newIterator();
596596 while (it->hasNext()) {
597597 it->next();
598598 if (it->flags() & ScriptValue::SkipInEnumeration) {
599599 continue;
600600 }
601601 qCDebug(scriptengine) << "resetModuleCache(true) -- staging " << it->name() << " for cache reset at next require";
602− cacheMeta->setProperty(it->name(), true);
602+ cacheMeta.setProperty(it->name(), true);
603603 }
604604 }
605605 cache = _engine->newObject();
606− if (!cacheMeta->isObject()) {
606+ if (!cacheMeta.isObject()) {
607607 cacheMeta = _engine->newObject();
608− cacheMeta->setProperty("id", "Script.require.cacheMeta");
609− cacheMeta->setProperty("type", "cacheMeta");
610− jsRequire->setData(cacheMeta);
608+ cacheMeta.setProperty("id", "Script.require.cacheMeta");
609+ cacheMeta.setProperty("type", "cacheMeta");
610+ jsRequire.setData(cacheMeta);
611611 }
612− cache->setProperty("__created__", (double)QDateTime::currentMSecsSinceEpoch(), ScriptValue::SkipInEnumeration);
612+ cache.setProperty("__created__", (double)QDateTime::currentMSecsSinceEpoch(), ScriptValue::SkipInEnumeration);
613613 #if DEBUG_JS_MODULES
614614 cache.setProperty("__meta__", cacheMeta, READONLY_HIDDEN_PROP_FLAGS);
615615 #endif
616− jsRequire->setProperty("cache", cache, READONLY_PROP_FLAGS);
616+ jsRequire.setProperty("cache", cache, READONLY_PROP_FLAGS);
617617 }
618618
619619 void ScriptManager::init() {
@@ -638,11 +638,11 @@ void ScriptManager::init() { · 18 unmodified lines
638638 scriptRegisterSequenceMetaType<QVector<glm::quat>>(scriptEngine);
639639 scriptRegisterSequenceMetaType<QVector<QString>>(scriptEngine);
640640
641− ScriptValuePointer xmlHttpRequestConstructorValue = scriptEngine->newFunction(XMLHttpRequestClass::constructor);
642− scriptEngine->globalObject()->setProperty("XMLHttpRequest", xmlHttpRequestConstructorValue);
641+ ScriptValue xmlHttpRequestConstructorValue = scriptEngine->newFunction(XMLHttpRequestClass::constructor);
642+ scriptEngine->globalObject().setProperty("XMLHttpRequest", xmlHttpRequestConstructorValue);
643643
644− ScriptValuePointer webSocketConstructorValue = scriptEngine->newFunction(WebSocketClass::constructor);
645− scriptEngine->globalObject()->setProperty("WebSocket", webSocketConstructorValue);
644+ ScriptValue webSocketConstructorValue = scriptEngine->newFunction(WebSocketClass::constructor);
645+ scriptEngine->globalObject().setProperty("WebSocket", webSocketConstructorValue);
646646
647647 /*@jsdoc
648648 * Prints a message to the program log and emits {@link Script.printedMessage}.
@@ -651,7 +651,7 @@ void ScriptManager::init() { · 2 unmodified lines
651651 * @function print
652652 * @param {...*} [message] - The message values to print.
653653 */
654− scriptEngine->globalObject()->setProperty("print", scriptEngine->newFunction(debugPrint));
654+ scriptEngine->globalObject().setProperty("print", scriptEngine->newFunction(debugPrint));
655655
656656 scriptRegisterMetaType(scriptEngine, animationDetailsToScriptValue, animationDetailsFromScriptValue);
657657 scriptRegisterMetaType(scriptEngine, webSocketToScriptValue, webSocketFromScriptValue);
@@ -665,10 +665,10 @@ void ScriptManager::init() { · 7 unmodified lines
665665
666666 {
667667 // set up Script.require.resolve and Script.require.cache
668− auto Script = scriptEngine->globalObject()->property("Script");
669− auto require = Script->property("require");
670− auto resolve = Script->property("_requireResolve");
671− require->setProperty("resolve", resolve, READONLY_PROP_FLAGS);
668+ auto Script = scriptEngine->globalObject().property("Script");
669+ auto require = Script.property("require");
670+ auto resolve = Script.property("_requireResolve");
671+ require.setProperty("resolve", resolve, READONLY_PROP_FLAGS);
672672 resetModuleCache();
673673 }
674674
@@ -697,12 +697,12 @@ void ScriptManager::init() { · 22 unmodified lines
697697
698698 // Scriptable cache access
699699 auto resourcePrototype = createScriptableResourcePrototype(qSharedPointerCast<ScriptManager>(sharedFromThis()));
700− scriptEngine->globalObject()->setProperty("Resource", resourcePrototype);
700+ scriptEngine->globalObject().setProperty("Resource", resourcePrototype);
701701 scriptEngine->setDefaultPrototype(qMetaTypeId<ScriptableResource*>(), resourcePrototype);
702702 scriptRegisterMetaType(scriptEngine, scriptableResourceToScriptValue, scriptableResourceFromScriptValue);
703703
704704 // constants
705− scriptEngine->globalObject()->setProperty("TREE_SCALE", scriptEngine->newValue(TREE_SCALE));
705+ scriptEngine->globalObject().setProperty("TREE_SCALE", scriptEngine->newValue(TREE_SCALE));
706706
707707 scriptEngine->registerGlobalObject("Assets", _assetScriptingInterface);
708708 scriptEngine->registerGlobalObject("Resources", DependencyManager::get<ResourceScriptingInterface>().data());
@@ -718,14 +718,14 @@ void ScriptManager::init() { · 9 unmodified lines
718718 scriptEngine->registerGlobalObject("StackTest", new StackTestScriptingInterface(this));
719719 #endif
720720
721− scriptEngine->globalObject()->setProperty("KALILA", "isWaifu");
722− scriptEngine->globalObject()->setProperty("Kute", scriptEngine->newFunction([](ScriptContext* context, ScriptEngine* engine) -> ScriptValuePointer {
723− return context->engine()->newValue(context->argument(0)->toString().toLower() == "kalila" ? true : false);
721+ scriptEngine->globalObject().setProperty("KALILA", "isWaifu");
722+ scriptEngine->globalObject().setProperty("Kute", scriptEngine->newFunction([](ScriptContext* context, ScriptEngine* engine) -> ScriptValue {
723+ return context->engine()->newValue(context->argument(0).toString().toLower() == "kalila" ? true : false);
724724 }));
725725 }
726726
727727 // Unregister the handlers for this eventName and entityID.
728−void ScriptManager::removeEventHandler(const EntityItemID& entityID, const QString& eventName, ScriptValuePointer handler) {
728+void ScriptManager::removeEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler) {
729729 if (QThread::currentThread() != thread()) {
730730 #ifdef THREAD_DEBUGGING
731731 qCDebug(scriptengine) << "*** WARNING *** ScriptManager::removeEventHandler() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
@@ -734,7 +734,7 @@ void ScriptManager::removeEventHandler(const EntityItemID& entityID, const QStri · 2 unmodified lines
734734 QMetaObject::invokeMethod(this, "removeEventHandler",
735735 Q_ARG(const EntityItemID&, entityID),
736736 Q_ARG(const QString&, eventName),
737− Q_ARG(ScriptValuePointer, handler));
737+ Q_ARG(const ScriptValue&, handler));
738738 return;
739739 }
740740 #ifdef THREAD_DEBUGGING
@@ -746,9 +746,9 @@ void ScriptManager::removeEventHandler(const EntityItemID& entityID, const QStri · 5 unmodified lines
746746 }
747747 RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID];
748748 CallbackList& handlersForEvent = handlersOnEntity[eventName];
749− // ScriptValuePointer does not have operator==(), so we can't use QList::removeOne and friends. So iterate.
749+ // ScriptValue does not have operator==(), so we can't use QList::removeOne and friends. So iterate.
750750 for (int i = 0; i < handlersForEvent.count(); ++i) {
751− if (handlersForEvent[i].function->equals(handler)) {
751+ if (handlersForEvent[i].function.equals(handler)) {
752752 handlersForEvent.removeAt(i);
753753 return; // Design choice: since comparison is relatively expensive, just remove the first matching handler.
754754 }
@@ -771,7 +771,7 @@ void ScriptManager::removeAllEventHandlers(const EntityItemID& entityID) { · 16 unmodified lines
771771 }
772772
773773 // Register the handler.
774−void ScriptManager::addEventHandler(const EntityItemID& entityID, const QString& eventName, ScriptValuePointer handler) {
774+void ScriptManager::addEventHandler(const EntityItemID& entityID, const QString& eventName, const ScriptValue& handler) {
775775 if (QThread::currentThread() != thread()) {
776776 #ifdef THREAD_DEBUGGING
777777 qCDebug(scriptengine) << "*** WARNING *** ScriptManager::addEventHandler() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "] "
@@ -781,7 +781,7 @@ void ScriptManager::addEventHandler(const EntityItemID& entityID, const QString& · 3 unmodified lines
781781 QMetaObject::invokeMethod(this, "addEventHandler",
782782 Q_ARG(const EntityItemID&, entityID),
783783 Q_ARG(const QString&, eventName),
784− Q_ARG(ScriptValuePointer, handler));
784+ Q_ARG(const ScriptValue&, handler));
785785 return;
786786 }
787787 #ifdef THREAD_DEBUGGING
@@ -951,7 +951,7 @@ void ScriptManager::run() { · 163 unmodified lines
951951 // only clear exceptions if we are not in the middle of evaluating
952952 if (!_engine->isEvaluating() && _engine->hasUncaughtException()) {
953953 qCWarning(scriptengine) << __FUNCTION__ << "---------- UNCAUGHT EXCEPTION --------";
954− qCWarning(scriptengine) << "runInThread" << _engine->uncaughtException()->toString();
954+ qCWarning(scriptengine) << "runInThread" << _engine->uncaughtException().toString();
955955 emit unhandledException(_engine->cloneUncaughtException(__FUNCTION__));
956956 _engine->clearExceptions();
957957 }
@@ -1037,7 +1037,7 @@ void ScriptManager::timerFired() { · 79 unmodified lines
10371037 }
10381038
10391039 // call the associated JS function, if it exists
1040− if (timerData.function->isValid()) {
1040+ if (timerData.function.isValid()) {
10411041 PROFILE_RANGE(script, __FUNCTION__);
10421042 auto preTimer = p_high_resolution_clock::now();
10431043 callWithEnvironment(timerData.definingEntityIdentifier, timerData.definingSandboxURL, timerData.function, timerData.function, ScriptValueList());
@@ -1045,11 +1045,11 @@ void ScriptManager::timerFired() { · 1 unmodified line
10451045 auto elapsed = (postTimer - preTimer);
10461046 _totalTimerExecution += std::chrono::duration_cast<std::chrono::microseconds>(elapsed);
10471047 } else {
1048− qCWarning(scriptengine) << "timerFired -- invalid function" << timerData.function->toVariant().toString();
1048+ qCWarning(scriptengine) << "timerFired -- invalid function" << timerData.function.toVariant().toString();
10491049 }
10501050 }
10511051
1052−QObject* ScriptManager::setupTimerWithInterval(const ScriptValuePointer& function, int intervalMS, bool isSingleShot) {
1052+QObject* ScriptManager::setupTimerWithInterval(const ScriptValue& function, int intervalMS, bool isSingleShot) {
10531053 // create the timer, add it to the map, and start it
10541054 QTimer* newTimer = new QTimer(this);
10551055 newTimer->setSingleShot(isSingleShot);
@@ -1073,7 +1073,7 @@ QObject* ScriptManager::setupTimerWithInterval(const ScriptValuePointer& functio · 17 unmodified lines
10731073 return newTimer;
10741074 }
10751075
1076−QObject* ScriptManager::setInterval(const ScriptValuePointer& function, int intervalMS) {
1076+QObject* ScriptManager::setInterval(const ScriptValue& function, int intervalMS) {
10771077 if (isStopped()) {
10781078 scriptWarningMessage("Script.setInterval() while shutting down is ignored... parent script:" + getFilename());
10791079 return NULL; // bail early
@@ -1082,7 +1082,7 @@ QObject* ScriptManager::setInterval(const ScriptValuePointer& function, int inte · 2 unmodified lines
10821082 return setupTimerWithInterval(function, intervalMS, false);
10831083 }
10841084
1085−QObject* ScriptManager::setTimeout(const ScriptValuePointer& function, int timeoutMS) {
1085+QObject* ScriptManager::setTimeout(const ScriptValue& function, int timeoutMS) {
10861086 if (isStopped()) {
10871087 scriptWarningMessage("Script.setTimeout() while shutting down is ignored... parent script:" + getFilename());
10881088 return NULL; // bail early
@@ -1174,7 +1174,7 @@ QString ScriptManager::_requireResolve(const QString& moduleId, const QString& r · 85 unmodified lines
11741174 }
11751175 auto message = QString("Cannot find module '%1' (%2)").arg(displayId);
11761176
1177− auto throwResolveError = [&](const ScriptValuePointer& error) -> QString {
1177+ auto throwResolveError = [&](const ScriptValue& error) -> QString {
11781178 _engine->raiseException(error);
11791179 _engine->maybeEmitUncaughtException("require.resolve");
11801180 return QString();
@@ -1253,73 +1253,73 @@ QString ScriptManager::_requireResolve(const QString& moduleId, const QString& r · 72 unmodified lines
12531253 }
12541254
12551255 // retrieves the current parent module from the JS scope chain
1256−ScriptValuePointer ScriptManager::currentModule() {
1256+ScriptValue ScriptManager::currentModule() {
12571257 if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) {
12581258 return _engine->nullValue();
12591259 }
1260− auto jsRequire = _engine->globalObject()->property("Script")->property("require");
1261− auto cache = jsRequire->property("cache");
1262− ScriptValuePointer candidate;
1260+ auto jsRequire = _engine->globalObject().property("Script").property("require");
1261+ auto cache = jsRequire.property("cache");
1262+ ScriptValue candidate;
12631263 ScriptContextPointer parentContext; // using this variable to maintain parent variable lifespan
1264− for (auto context = _engine->currentContext(); context && (!candidate || !candidate->isObject()); parentContext = context->parentContext(), context = parentContext.data()) {
1264+ for (auto context = _engine->currentContext(); context && !candidate.isObject(); parentContext = context->parentContext(), context = parentContext.data()) {
12651265 auto contextInfo = context->functionContext();
1266− candidate = cache->property(contextInfo->fileName());
1266+ candidate = cache.property(contextInfo->fileName());
12671267 }
1268− if (!candidate || !candidate->isObject()) {
1269− return ScriptValuePointer();
1268+ if (!candidate.isObject()) {
1269+ return ScriptValue();
12701270 }
12711271 return candidate;
12721272 }
12731273
12741274 // replaces or adds "module" to "parent.children[]" array
12751275 // (for consistency with Node.js and userscript cache invalidation without "cache busters")
1276−bool ScriptManager::registerModuleWithParent(const ScriptValuePointer& module, const ScriptValuePointer& parent) {
1277− auto children = parent->property("children");
1278− if (children->isArray()) {
1279− auto key = module->property("id");
1280− auto length = children->property("length")->toInt32();
1276+bool ScriptManager::registerModuleWithParent(const ScriptValue& module, const ScriptValue& parent) {
1277+ auto children = parent.property("children");
1278+ if (children.isArray()) {
1279+ auto key = module.property("id");
1280+ auto length = children.property("length").toInt32();
12811281 for (int i = 0; i < length; i++) {
1282− if (children->property(i)->property("id")->strictlyEquals(key)) {
1283− qCDebug(scriptengine_module) << key->toString() << " updating parent.children[" << i << "] = module";
1284− children->setProperty(i, module);
1282+ if (children.property(i).property("id").strictlyEquals(key)) {
1283+ qCDebug(scriptengine_module) << key.toString() << " updating parent.children[" << i << "] = module";
1284+ children.setProperty(i, module);
12851285 return true;
12861286 }
12871287 }
1288− qCDebug(scriptengine_module) << key->toString() << " appending parent.children[" << length << "] = module";
1289− children->setProperty(length, module);
1288+ qCDebug(scriptengine_module) << key.toString() << " appending parent.children[" << length << "] = module";
1289+ children.setProperty(length, module);
12901290 return true;
1291− } else if (parent->isValid()) {
1292− qCDebug(scriptengine_module) << "registerModuleWithParent -- unrecognized parent" << parent->toVariant().toString();
1291+ } else if (parent.isValid()) {
1292+ qCDebug(scriptengine_module) << "registerModuleWithParent -- unrecognized parent" << parent.toVariant().toString();
12931293 }
12941294 return false;
12951295 }
12961296
12971297 // creates a new JS "module" Object with default metadata properties
1298−ScriptValuePointer ScriptManager::newModule(const QString& modulePath, const ScriptValuePointer& parent) {
1298+ScriptValue ScriptManager::newModule(const QString& modulePath, const ScriptValue& parent) {
12991299 auto closure = _engine->newObject();
13001300 auto exports = _engine->newObject();
13011301 auto module = _engine->newObject();
1302− qCDebug(scriptengine_module) << "newModule" << parent->property("filename")->toString();
1302+ qCDebug(scriptengine_module) << "newModule" << parent.property("filename").toString();
13031303
1304− closure->setProperty("module", module, READONLY_PROP_FLAGS);
1304+ closure.setProperty("module", module, READONLY_PROP_FLAGS);
13051305
13061306 // note: this becomes the "exports" free variable, so should not be set read only
1307− closure->setProperty("exports", exports);
1307+ closure.setProperty("exports", exports);
13081308
13091309 // make the closure available to module instantiation
1310− module->setProperty("__closure__", closure, READONLY_HIDDEN_PROP_FLAGS);
1310+ module.setProperty("__closure__", closure, READONLY_HIDDEN_PROP_FLAGS);
13111311
13121312 // for consistency with Node.js Module
1313− module->setProperty("id", modulePath, READONLY_PROP_FLAGS);
1314− module->setProperty("filename", modulePath, READONLY_PROP_FLAGS);
1315− module->setProperty("exports", exports); // not readonly
1316− module->setProperty("loaded", false, READONLY_PROP_FLAGS);
1317− module->setProperty("parent", parent, READONLY_PROP_FLAGS);
1318− module->setProperty("children", _engine->newArray(), READONLY_PROP_FLAGS);
1313+ module.setProperty("id", modulePath, READONLY_PROP_FLAGS);
1314+ module.setProperty("filename", modulePath, READONLY_PROP_FLAGS);
1315+ module.setProperty("exports", exports); // not readonly
1316+ module.setProperty("loaded", false, READONLY_PROP_FLAGS);
1317+ module.setProperty("parent", parent, READONLY_PROP_FLAGS);
1318+ module.setProperty("children", _engine->newArray(), READONLY_PROP_FLAGS);
13191319
13201320 // module.require is a bound version of require that always resolves relative to that module's path
13211321 auto boundRequire = _engine->evaluate("(function(id) { return Script.require(Script.require.resolve(id, this.filename)); })", "(boundRequire)");
1322− module->setProperty("require", boundRequire, READONLY_PROP_FLAGS);
1322+ module.setProperty("require", boundRequire, READONLY_PROP_FLAGS);
13231323
13241324 return module;
13251325 }
@@ -1383,23 +1383,23 @@ QVariantMap ScriptManager::fetchModuleSource(const QString& modulePath, const bo · 57 unmodified lines
13831383 }
13841384
13851385 // evaluate a pending module object using the fetched source code
1386−ScriptValuePointer ScriptManager::instantiateModule(const ScriptValuePointer& module, const QString& sourceCode) {
1387− ScriptValuePointer result;
1388− auto modulePath = module->property("filename")->toString();
1389− auto closure = module->property("__closure__");
1386+ScriptValue ScriptManager::instantiateModule(const ScriptValue& module, const QString& sourceCode) {
1387+ ScriptValue result;
1388+ auto modulePath = module.property("filename").toString();
1389+ auto closure = module.property("__closure__");
13901390
13911391 qCDebug(scriptengine_module) << QString("require.instantiateModule: %1 / %2 bytes")
13921392 .arg(QUrl(modulePath).fileName()).arg(sourceCode.length());
13931393
1394− if (module->property("content-type")->toString() == "application/json") {
1394+ if (module.property("content-type").toString() == "application/json") {
13951395 qCDebug(scriptengine_module) << "... parsing as JSON";
1396− closure->setProperty("__json", sourceCode);
1396+ closure.setProperty("__json", sourceCode);
13971397 result = _engine->evaluateInClosure(closure, _engine->newProgram( "module.exports = JSON.parse(__json)", modulePath ));
13981398 } else {
13991399 // scoped vars for consistency with Node.js
1400− closure->setProperty("require", module->property("require"));
1401− closure->setProperty("__filename", modulePath, READONLY_HIDDEN_PROP_FLAGS);
1402− closure->setProperty("__dirname", QString(modulePath).replace(QRegExp("/[^/]*$"), ""), READONLY_HIDDEN_PROP_FLAGS);
1400+ closure.setProperty("require", module.property("require"));
1401+ closure.setProperty("__filename", modulePath, READONLY_HIDDEN_PROP_FLAGS);
1402+ closure.setProperty("__dirname", QString(modulePath).replace(QRegExp("/[^/]*$"), ""), READONLY_HIDDEN_PROP_FLAGS);
14031403 result = _engine->evaluateInClosure(closure, _engine->newProgram( sourceCode, modulePath ));
14041404 }
14051405 _engine->maybeEmitUncaughtException(__FUNCTION__);
@@ -1407,19 +1407,19 @@ ScriptValuePointer ScriptManager::instantiateModule(const ScriptValuePointer& mo · 1 unmodified line
14071407 }
14081408
14091409 // CommonJS/Node.js like require/module support
1410−ScriptValuePointer ScriptManager::require(const QString& moduleId) {
1410+ScriptValue ScriptManager::require(const QString& moduleId) {
14111411 qCDebug(scriptengine_module) << "ScriptManager::require(" << moduleId.left(MAX_DEBUG_VALUE_LENGTH) << ")";
14121412 if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) {
14131413 return _engine->nullValue();
14141414 }
14151415
1416− auto jsRequire = _engine->globalObject()->property("Script")->property("require");
1416+ auto jsRequire = _engine->globalObject().property("Script").property("require");
14171417 auto cacheMeta = jsRequire.data();
1418− auto cache = jsRequire->property("cache");
1418+ auto cache = jsRequire.property("cache");
14191419 auto parent = currentModule();
14201420
1421− auto throwModuleError = [&](const QString& modulePath, const ScriptValuePointer& error) {
1422− cache->setProperty(modulePath, _engine->nullValue());
1421+ auto throwModuleError = [&](const QString& modulePath, const ScriptValue& error) {
1422+ cache.setProperty(modulePath, _engine->nullValue());
14231423 if (!error.isNull()) {
14241424 #ifdef DEBUG_JS_MODULES
14251425 qCWarning(scriptengine_module) << "throwing module error:" << error.toString() << modulePath << error.property("stack").toString();
@@ -1439,7 +1439,7 @@ ScriptValuePointer ScriptManager::require(const QString& moduleId) { · 13 unmodified lines
14391439 }
14401440
14411441 // check the resolved path against the cache
1442− auto module = cache->property(modulePath);
1442+ auto module = cache.property(modulePath);
14431443
14441444 // modules get cached in `Script.require.cache` and (similar to Node.js) users can access it
14451445 // to inspect particular entries and invalidate them by deleting the key:
@@ -1449,16 +1449,16 @@ ScriptValuePointer ScriptManager::require(const QString& moduleId) { · 3 unmodified lines
14491449 Setting::Handle<bool> getCachebustSetting {"cachebustScriptRequire", false };
14501450
14511451 // cacheMeta is just used right now to tell deleted keys apart from undefined ones
1452− bool invalidateCache = getCachebustSetting.get() || (module->isUndefined() && cacheMeta->property(moduleId)->isValid());
1452+ bool invalidateCache = getCachebustSetting.get() || (module.isUndefined() && cacheMeta.property(moduleId).isValid());
14531453
14541454 // reset the cacheMeta record so invalidation won't apply next time, even if the module fails to load
1455− cacheMeta->setProperty(modulePath, ScriptValuePointer());
1455+ cacheMeta.setProperty(modulePath, ScriptValue());
14561456
1457− auto exports = module->property("exports");
1458− if (!invalidateCache && exports->isObject()) {
1457+ auto exports = module.property("exports");
1458+ if (!invalidateCache && exports.isObject()) {
14591459 // we have found a cached module -- just need to possibly register it with current parent
14601460 qCDebug(scriptengine_module) << QString("require - using cached module for '%1' (loaded: %2)")
1461− .arg(moduleId).arg(module->property("loaded")->toString());
1461+ .arg(moduleId).arg(module.property("loaded").toString());
14621462 registerModuleWithParent(module, parent);
14631463 _engine->maybeEmitUncaughtException("cached module");
14641464 return exports;
@@ -1469,7 +1469,7 @@ ScriptValuePointer ScriptManager::require(const QString& moduleId) { · 4 unmodified lines
14691469 registerModuleWithParent(module, parent);
14701470
14711471 // add it to the cache (this is done early so any cyclic dependencies pick up)
1472− cache->setProperty(modulePath, module);
1472+ cache.setProperty(modulePath, module);
14731473
14741474 // download the module source
14751475 auto req = fetchModuleSource(modulePath, invalidateCache);
@@ -1487,36 +1487,36 @@ ScriptValuePointer ScriptManager::require(const QString& moduleId) { · 11 unmodified lines
14871487 auto sourceCode = req["contents"].toString();
14881488
14891489 if (QUrl(modulePath).fileName().endsWith(".json", Qt::CaseInsensitive)) {
1490− module->setProperty("content-type", "application/json");
1490+ module.setProperty("content-type", "application/json");
14911491 } else {
1492− module->setProperty("content-type", "application/javascript");
1492+ module.setProperty("content-type", "application/javascript");
14931493 }
14941494
14951495 // evaluate the module
14961496 auto result = instantiateModule(module, sourceCode);
14971497
1498− if (result->isError() && !result->strictlyEquals(module->property("exports"))) {
1499− qCWarning(scriptengine_module) << "-- result.isError --" << result->toString();
1498+ if (result.isError() && !result.strictlyEquals(module.property("exports"))) {
1499+ qCWarning(scriptengine_module) << "-- result.isError --" << result.toString();
15001500 return throwModuleError(modulePath, result);
15011501 }
15021502
15031503 // mark as fully-loaded
1504− module->setProperty("loaded", true, READONLY_PROP_FLAGS);
1504+ module.setProperty("loaded", true, READONLY_PROP_FLAGS);
15051505
15061506 // set up a new reference point for detecting cache key deletion
1507− cacheMeta->setProperty(modulePath, module);
1507+ cacheMeta.setProperty(modulePath, module);
15081508
15091509 qCDebug(scriptengine_module) << "//ScriptManager::require(" << moduleId << ")";
15101510
15111511 _engine->maybeEmitUncaughtException(__FUNCTION__);
1512− return module->property("exports");
1512+ return module.property("exports");
15131513 }
15141514
15151515 // If a callback is specified, the included files will be loaded asynchronously and the callback will be called
15161516 // when all of the files have finished loading.
15171517 // If no callback is specified, the included files will be loaded synchronously and will block execution until
15181518 // all of the files have finished loading.
1519−void ScriptManager::include(const QStringList& includeFiles, ScriptValuePointer callback) {
1519+void ScriptManager::include(const QStringList& includeFiles, const ScriptValue& callback) {
15201520 if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) {
15211521 return;
15221522 }
@@ -1592,8 +1592,8 @@ void ScriptManager::include(const QStringList& includeFiles, ScriptValuePointer · 69 unmodified lines
15921592 }
15931593 _parentURL = parentURL;
15941594
1595− if (callback && callback->isFunction()) {
1596− callWithEnvironment(capturedEntityIdentifier, capturedSandboxURL, callback, ScriptValuePointer(), ScriptValueList());
1595+ if (callback.isFunction()) {
1596+ callWithEnvironment(capturedEntityIdentifier, capturedSandboxURL, callback, ScriptValue(), ScriptValueList());
15971597 }
15981598
15991599 loader->deleteLater();
@@ -1606,14 +1606,14 @@ void ScriptManager::include(const QStringList& includeFiles, ScriptValuePointer · 6 unmodified lines
16061606
16071607 loader->start(processLevelMaxRetries);
16081608
1609− if ((!callback || !callback->isFunction()) && !loader->isFinished()) {
1609+ if (!callback.isFunction() && !loader->isFinished()) {
16101610 QEventLoop loop;
16111611 QObject::connect(loader, &BatchLoader::finished, &loop, &QEventLoop::quit);
16121612 loop.exec();
16131613 }
16141614 }
16151615
1616−void ScriptManager::include(const QString& includeFile, ScriptValuePointer callback) {
1616+void ScriptManager::include(const QString& includeFile, const ScriptValue& callback) {
16171617 if (isStopped()) {
16181618 scriptWarningMessage("Script.include() while shutting down is ignored... includeFile:"
16191619 + includeFile + "parent script:" + getFilename());
@@ -1654,7 +1654,7 @@ void ScriptManager::load(const QString& loadFile) { · 34 unmodified lines
16541654 }
16551655
16561656 // Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args
1657−void ScriptManager::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, ScriptValueList eventHandlerArgs) {
1657+void ScriptManager::forwardHandlerCall(const EntityItemID& entityID, const QString& eventName, const ScriptValueList& eventHandlerArgs) {
16581658 if (QThread::currentThread() != thread()) {
16591659 qCDebug(scriptengine) << "*** ERROR *** ScriptManager::forwardHandlerCall() called on wrong thread [" << QThread::currentThread() << "], invoking on correct thread [" << thread() << "]";
16601660 assert(false);
@@ -1674,7 +1674,7 @@ void ScriptManager::forwardHandlerCall(const EntityItemID& entityID, const QStri · 13 unmodified lines
16741674 // and the entity scripts may be for entities other than the one this is a handler for.
16751675 // Fortunately, the definingEntityIdentifier captured the entity script id (if any) when the handler was added.
16761676 CallbackData& handler = handlersForEvent[i];
1677− callWithEnvironment(handler.definingEntityIdentifier, handler.definingSandboxURL, handler.function, ScriptValuePointer(), eventHandlerArgs);
1677+ callWithEnvironment(handler.definingEntityIdentifier, handler.definingSandboxURL, handler.function, ScriptValue(), eventHandlerArgs);
16781678 }
16791679 }
16801680 }
@@ -1921,13 +1921,13 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 240 unmodified lines
19211921
19221922 // SYNTAX ERRORS
19231923 auto syntaxError = _engine->lintScript(contents, fileName);
1924− if (syntaxError->isError()) {
1925− auto message = syntaxError->property("formatted")->toString();
1924+ if (syntaxError.isError()) {
1925+ auto message = syntaxError.property("formatted").toString();
19261926 if (message.isEmpty()) {
1927− message = syntaxError->toString();
1927+ message = syntaxError.toString();
19281928 }
19291929 setError(QString("Bad syntax (%1)").arg(message), EntityScriptStatus::ERROR_RUNNING_SCRIPT);
1930− syntaxError->setProperty("detail", entityID.toString());
1930+ syntaxError.setProperty("detail", entityID.toString());
19311931 emit unhandledException(syntaxError);
19321932 return;
19331933 }
@@ -1946,7 +1946,7 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 12 unmodified lines
19461946 const int SANDBOX_TIMEOUT = 0.25 * MSECS_PER_SECOND;
19471947 ScriptEnginePointer sandbox = newScriptEngine();
19481948 sandbox->setProcessEventsInterval(SANDBOX_TIMEOUT);
1949− ScriptValuePointer testConstructor, exception;
1949+ ScriptValue testConstructor, exception;
19501950 if (atoi(getenv("UNSAFE_ENTITY_SCRIPTS") ? getenv("UNSAFE_ENTITY_SCRIPTS") : "0"))
19511951 {
19521952 QTimer timeout;
@@ -1966,7 +1966,7 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 13 unmodified lines
19661966 if (sandbox->hasUncaughtException()) {
19671967 exception = sandbox->cloneUncaughtException(QString("(preflight %1)").arg(entityID.toString()));
19681968 sandbox->clearExceptions();
1969− } else if (testConstructor && testConstructor->isError()) {
1969+ } else if (testConstructor.isError()) {
19701970 exception = testConstructor;
19711971 }
19721972 } else {
@@ -2041,7 +2041,7 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 68 unmodified lines
20412041 if (sandbox->hasUncaughtException()) {
20422042 exception = sandbox->cloneUncaughtException(QString("(preflight %1)").arg(entityID.toString()));
20432043 sandbox->clearExceptions();
2044− } else if (testConstructor && testConstructor->isError()) {
2044+ } else if (testConstructor.isError()) {
20452045 exception = testConstructor;
20462046 }
20472047 }
@@ -2051,7 +2051,7 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 3 unmodified lines
20512051 // exception = makeError("UNSAFE_ENTITY_SCRIPTS == 0");
20522052 }
20532053
2054− if (exception && exception->isError()) {
2054+ if (exception.isError()) {
20552055 // create a local copy using makeError to decouple from the sandbox engine
20562056 exception = _engine->makeError(exception);
20572057 setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT);
@@ -2060,12 +2060,12 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 2 unmodified lines
20602060 }
20612061
20622062 // CONSTRUCTOR VIABILITY
2063− if (!testConstructor || !testConstructor->isFunction()) {
2064− QString testConstructorType = QString(testConstructor->toVariant().typeName());
2063+ if (!testConstructor.isFunction()) {
2064+ QString testConstructorType = QString(testConstructor.toVariant().typeName());
20652065 if (testConstructorType == "") {
20662066 testConstructorType = "empty";
20672067 }
2068− QString testConstructorValue = testConstructor->toString();
2068+ QString testConstructorValue = testConstructor.toString();
20692069 if (testConstructorValue.size() > MAX_DEBUG_VALUE_LENGTH) {
20702070 testConstructorValue = testConstructorValue.mid(0, MAX_DEBUG_VALUE_LENGTH) + "...";
20712071 }
@@ -2073,8 +2073,8 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 1 unmodified line
20732073 .arg(testConstructorType).arg(testConstructorValue);
20742074
20752075 auto err = _engine->makeError(_engine->newValue(message));
2076− err->setProperty("fileName", scriptOrURL);
2077− err->setProperty("detail", "(constructor " + entityID.toString() + ")");
2076+ err.setProperty("fileName", scriptOrURL);
2077+ err.setProperty("detail", "(constructor " + entityID.toString() + ")");
20782078
20792079 setError("Could not find constructor (" + testConstructorType + ")", EntityScriptStatus::ERROR_RUNNING_SCRIPT);
20802080 emit unhandledException(err);
@@ -2089,11 +2089,11 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 8 unmodified lines
20892089 }
20902090
20912091 // THE ACTUAL EVALUATION AND CONSTRUCTION
2092− ScriptValuePointer entityScriptConstructor, entityScriptObject;
2092+ ScriptValue entityScriptConstructor, entityScriptObject;
20932093 QUrl sandboxURL = currentSandboxURL.isEmpty() ? scriptOrURL : currentSandboxURL;
20942094 auto initialization = [&]{
20952095 entityScriptConstructor = _engine->evaluate(contents, fileName);
2096− entityScriptObject = entityScriptConstructor->construct();
2096+ entityScriptObject = entityScriptConstructor.construct();
20972097
20982098 if (_engine->hasUncaughtException()) {
20992099 entityScriptObject = _engine->cloneUncaughtException("(construct " + entityID.toString() + ")");
@@ -2103,7 +2103,7 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c · 3 unmodified lines
21032103
21042104 doWithEnvironment(entityID, sandboxURL, initialization);
21052105
2106− if (entityScriptObject && entityScriptObject->isError()) {
2106+ if (entityScriptObject.isError()) {
21072107 auto exception = entityScriptObject;
21082108 setError(formatException(exception, _enableExtendedJSExceptions.get()), EntityScriptStatus::ERROR_RUNNING_SCRIPT);
21092109 emit unhandledException(exception);
@@ -2266,7 +2266,7 @@ void ScriptManager::doWithEnvironment(const EntityItemID& entityID, const QUrl& · 156 unmodified lines
22662266 currentSandboxURL = sandboxURL;
22672267
22682268 #if DEBUG_CURRENT_ENTITY
2269− ScriptValuePointer oldData = this->globalObject().property("debugEntityID");
2269+ ScriptValue oldData = this->globalObject().property("debugEntityID");
22702270 this->globalObject().setProperty("debugEntityID", entityID.toScriptValue(this)); // Make the entityID available to javascript as a global.
22712271 operation();
22722272 this->globalObject().setProperty("debugEntityID", oldData);
@@ -2278,9 +2278,9 @@ void ScriptManager::doWithEnvironment(const EntityItemID& entityID, const QUrl& · 5 unmodified lines
22782278 currentSandboxURL = oldSandboxURL;
22792279 }
22802280
2281−void ScriptManager::callWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, ScriptValuePointer function, ScriptValuePointer thisObject, ScriptValueList args) {
2281+void ScriptManager::callWithEnvironment(const EntityItemID& entityID, const QUrl& sandboxURL, const ScriptValue& function, const ScriptValue& thisObject, const ScriptValueList& args) {
22822282 auto operation = [&]() {
2283− function->call(thisObject, args);
2283+ function.call(thisObject, args);
22842284 };
22852285 doWithEnvironment(entityID, sandboxURL, operation);
22862286 }
@@ -2313,7 +2313,7 @@ void ScriptManager::callEntityScriptMethod(const EntityItemID& entityID, const Q · 26 unmodified lines
23132313 QWriteLocker locker { &_entityScriptsLock };
23142314 details = _entityScripts[entityID];
23152315 }
2316− ScriptValuePointer entityScript = details.scriptObject; // previously loaded
2316+ ScriptValue entityScript = details.scriptObject; // previously loaded
23172317
23182318 // If this is a remote call, we need to check to see if the function is remotely callable
23192319 // we do this by checking for the existance of the 'remotelyCallable' property on the
@@ -2323,11 +2323,11 @@ void ScriptManager::callEntityScriptMethod(const EntityItemID& entityID, const Q · 3 unmodified lines
23232323 if (remoteCallerID == QUuid()) {
23242324 callAllowed = true;
23252325 } else {
2326− if (entityScript->property("remotelyCallable")->isArray()) {
2327− auto callables = entityScript->property("remotelyCallable");
2328− auto callableCount = callables->property("length")->toInteger();
2326+ if (entityScript.property("remotelyCallable").isArray()) {
2327+ auto callables = entityScript.property("remotelyCallable");
2328+ auto callableCount = callables.property("length").toInteger();
23292329 for (int i = 0; i < callableCount; i++) {
2330− auto callable = callables->property(i)->toString();
2330+ auto callable = callables.property(i).toString();
23312331 if (callable == methodName) {
23322332 callAllowed = true;
23332333 break;
@@ -2339,17 +2339,17 @@ void ScriptManager::callEntityScriptMethod(const EntityItemID& entityID, const Q · 5 unmodified lines
23392339 }
23402340 }
23412341
2342− if (callAllowed && entityScript->property(methodName)->isFunction()) {
2342+ if (callAllowed && entityScript.property(methodName).isFunction()) {
23432343 auto scriptEngine = engine().data();
23442344
23452345 ScriptValueList args;
23462346 args << EntityItemIDtoScriptValue(scriptEngine, entityID);
23472347 args << scriptValueFromSequence(scriptEngine, params);
23482348
2349− ScriptValuePointer oldData = scriptEngine->globalObject()->property("Script")->property("remoteCallerID");
2350− scriptEngine->globalObject()->property("Script")->setProperty("remoteCallerID", remoteCallerID.toString()); // Make the remoteCallerID available to javascript as a global.
2351− callWithEnvironment(entityID, details.definingSandboxURL, entityScript->property(methodName), entityScript, args);
2352− scriptEngine->globalObject()->property("Script")->setProperty("remoteCallerID", oldData);
2349+ ScriptValue oldData = scriptEngine->globalObject().property("Script").property("remoteCallerID");
2350+ scriptEngine->globalObject().property("Script").setProperty("remoteCallerID", remoteCallerID.toString()); // Make the remoteCallerID available to javascript as a global.
2351+ callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
2352+ scriptEngine->globalObject().property("Script").setProperty("remoteCallerID", oldData);
23532353 }
23542354 }
23552355 }
@@ -2381,14 +2381,14 @@ void ScriptManager::callEntityScriptMethod(const EntityItemID& entityID, const Q · 25 unmodified lines
23812381 QWriteLocker locker { &_entityScriptsLock };
23822382 details = _entityScripts[entityID];
23832383 }
2384− ScriptValuePointer entityScript = details.scriptObject; // previously loaded
2385− if (entityScript->property(methodName)->isFunction()) {
2384+ ScriptValue entityScript = details.scriptObject; // previously loaded
2385+ if (entityScript.property(methodName).isFunction()) {
23862386 auto scriptEngine = engine().data();
23872387
23882388 ScriptValueList args;
23892389 args << EntityItemIDtoScriptValue(scriptEngine, entityID);
23902390 args << event.toScriptValue(scriptEngine);
2391− callWithEnvironment(entityID, details.definingSandboxURL, entityScript->property(methodName), entityScript, args);
2391+ callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
23922392 }
23932393 }
23942394 }
@@ -2421,15 +2421,15 @@ void ScriptManager::callEntityScriptMethod(const EntityItemID& entityID, const Q · 26 unmodified lines
24212421 QWriteLocker locker { &_entityScriptsLock };
24222422 details = _entityScripts[entityID];
24232423 }
2424− ScriptValuePointer entityScript = details.scriptObject; // previously loaded
2425− if (entityScript->property(methodName)->isFunction()) {
2424+ ScriptValue entityScript = details.scriptObject; // previously loaded
2425+ if (entityScript.property(methodName).isFunction()) {
24262426 auto scriptEngine = engine().data();
24272427
24282428 ScriptValueList args;
24292429 args << EntityItemIDtoScriptValue(scriptEngine, entityID);
24302430 args << EntityItemIDtoScriptValue(scriptEngine, otherID);
24312431 args << collisionToScriptValue(scriptEngine, collision);
2432− callWithEnvironment(entityID, details.definingSandboxURL, entityScript->property(methodName), entityScript, args);
2432+ callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args);
24332433 }
24342434 }
24352435 }
@@ -2438,28 +2438,28 @@ QString ScriptManager::getExternalPath(ExternalResource::Bucket bucket, const QS · 2 unmodified lines
24382438 return ExternalResource::getInstance()->getUrl(bucket, path);
24392439 }
24402440
2441−QString ScriptManager::formatException(const ScriptValuePointer& exception, bool includeExtendedDetails) {
2441+QString ScriptManager::formatException(const ScriptValue& exception, bool includeExtendedDetails) {
24422442 if (!_engine->IS_THREADSAFE_INVOCATION(__FUNCTION__)) {
24432443 return QString();
24442444 }
24452445 QString note{ "UncaughtException" };
24462446 QString result;
24472447
2448− if (!exception->isObject()) {
2448+ if (!exception.isObject()) {
24492449 return result;
24502450 }
2451− const auto message = exception->toString();
2452− const auto fileName = exception->property("fileName")->toString();
2453− const auto lineNumber = exception->property("lineNumber")->toString();
2454− const auto stacktrace = exception->property("stack")->toString();
2451+ const auto message = exception.toString();
2452+ const auto fileName = exception.property("fileName").toString();
2453+ const auto lineNumber = exception.property("lineNumber").toString();
2454+ const auto stacktrace = exception.property("stack").toString();
24552455
24562456 if (includeExtendedDetails) {
24572457 // Display additional exception / troubleshooting hints that can be added via the custom Error .detail property
24582458 // Example difference:
24592459 // [UncaughtExceptions] Error: Can't find variable: foobar in atp:/myentity.js\n...
24602460 // [UncaughtException (construct {1eb5d3fa-23b1-411c-af83-163af7220e3f})] Error: Can't find variable: foobar in atp:/myentity.js\n...
2461− if (exception->property("detail")->isValid()) {
2462− note += " " + exception->property("detail")->toString();
2461+ if (exception.property("detail").isValid()) {
2462+ note += " " + exception.property("detail").toString();
24632463 }
24642464 }
24652465
@@ -2470,6 +2470,6 @@ QString ScriptManager::formatException(const ScriptValuePointer& exception, bool · 4 unmodified lines
24702470 return result;
24712471 }
24722472
2473−ScriptValuePointer ScriptManager::evaluate(const QString& program, const QString& fileName) {
2473+ScriptValue ScriptManager::evaluate(const QString& program, const QString& fileName) {
24742474 return _engine->evaluate(program, fileName);
24752475 }