Explorar o código

Return JsErrorScriptException from JsDiagEvaluate if script
throws exception. Out parameter evalResult still contains the
error object (ResolvedObject)

Update JsDiagEvaluate documentation to show what is returned for
JsNoError and JsErrorScriptException

Update JsDiagGetStackTrace documentation to show the bit mask for
propertyAttributes

Sandeep Agarwal %!s(int64=9) %!d(string=hai) anos
pai
achega
b780dba6a3

+ 3 - 2
bin/ch/Debugger.cpp

@@ -171,14 +171,15 @@ JsValueRef Debugger::Evaluate(JsValueRef callee, bool isConstructCall, JsValueRe
     int stackFrameIndex;
     JsValueRef result = JS_INVALID_REFERENCE;
 
-    if (argumentCount > 2) {
+    if (argumentCount > 2)
+    {
         IfJsErrorFailLogAndRet(ChakraRTInterface::JsNumberToInt(arguments[1], &stackFrameIndex));
 
         LPCWSTR str = nullptr;
         size_t length;
         IfJsErrorFailLogAndRet(ChakraRTInterface::JsValueToWchar(arguments[2], &str, &length));
 
-        IfJsErrorFailLogAndRet(ChakraRTInterface::JsDiagEvaluate(str, stackFrameIndex, &result));
+        ChakraRTInterface::JsDiagEvaluate(str, stackFrameIndex, &result);
     }
 
     return result;

+ 23 - 2
lib/Jsrt/ChakraDebug.h

@@ -394,6 +394,14 @@
     /// <param name="properties">Object of properties array (properties, scopes and globals).</param>
     /// <remarks>
     ///     <para>
+    ///     propertyAttributes is a bit mask of
+    ///         NONE = 0x1,
+    ///         HAVE_CHILDRENS = 0x2,
+    ///         READ_ONLY_VALUE = 0x4,
+    ///     </para>
+    /// </remarks>
+    /// <remarks>
+    ///     <para>
     ///     {
     ///         "thisObject": {
     ///             "name": "this",
@@ -539,18 +547,31 @@
     /// <param name="evalResult">Result of evaluation.</param>
     /// <remarks>
     ///     <para>
+    ///     evalResult when evaluating 'this' and return is JsNoError
     ///     {
     ///         "name" : "this",
     ///         "type" : "object",
-    ///         "display" : "{...}",
     ///         "className" : "Object",
+    ///         "display" : "{...}",
+    ///         "propertyAttributes" : 1,
+    ///         "handle" : 18
+    ///     }
+    ///
+    ///     evalResult when evaluating a script which throws JavaScript error and return is JsErrorScriptException
+    ///     {
+    ///         "name" : "a.b.c",
+    ///         "type" : "object",
+    ///         "className" : "Error",
+    ///         "display" : "'a' is undefined",
     ///         "propertyAttributes" : 1,
     ///         "handle" : 18
     ///     }
     ///     </para>
     /// </remarks>
     /// <returns>
-    ///     The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
+    ///     The code <c>JsNoError</c> if the operation succeeded, evalResult will contain the result
+    ///     The code <c>JsErrorScriptException</c> if evaluate generated a JavaScript exception, evalResult will contain the error details
+    ///     Other error code for invalid parameters or API was not called at break
     /// </returns>
     /// <remarks>
     ///     The current runtime should be in debug state. This API can only be called when runtime is at a break.

+ 3 - 3
lib/Jsrt/JsrtDebugUtils.h

@@ -11,9 +11,9 @@ BEGIN_ENUM_UINT(JsrtDebugPropertyId)
 END_ENUM_UINT()
 
 BEGIN_ENUM_UINT(JsrtDebugPropertyAttribute)
-    NONE,
-    HAVE_CHILDRENS,
-    READ_ONLY_VALUE,
+    NONE = 0x1,
+    HAVE_CHILDRENS = 0x2,
+    READ_ONLY_VALUE = 0x4,
 END_ENUM_UINT()
 
 class JsrtDebugUtils

+ 20 - 7
lib/Jsrt/JsrtDebuggerObject.cpp

@@ -452,14 +452,16 @@ Js::DynamicObject * JsrtDebuggerStackFrame::GetLocalsObject(Js::ScriptContext* s
     return propertiesObject;
 }
 
-Js::DynamicObject* JsrtDebuggerStackFrame::Evaluate(Js::ScriptContext* scriptContext, const char16 *source, int sourceLength, bool isLibraryCode)
+bool JsrtDebuggerStackFrame::Evaluate(Js::ScriptContext* scriptContext, const char16 *source, int sourceLength, bool isLibraryCode, Js::DynamicObject** evalResult)
 {
-    Js::DynamicObject* evalResult = nullptr;
+    *evalResult = nullptr;
+    bool success = false;
     if (this->stackFrame != nullptr)
     {
         Js::ResolvedObject resolvedObject;
         HRESULT hr = S_OK;
         Js::ScriptContext* frameScriptContext = this->stackFrame->GetScriptContext();
+
         Js::JavascriptExceptionObject *exceptionObject = nullptr;
         {
             BEGIN_JS_RUNTIME_CALL_EX_AND_TRANSLATE_EXCEPTION_AND_ERROROBJECT_TO_HRESULT_NESTED(frameScriptContext, false)
@@ -469,6 +471,7 @@ Js::DynamicObject* JsrtDebuggerStackFrame::Evaluate(Js::ScriptContext* scriptCon
             }
             END_JS_RUNTIME_CALL_AND_TRANSLATE_AND_GET_EXCEPTION_AND_ERROROBJECT_TO_HRESULT(hr, frameScriptContext, exceptionObject);
         }
+
         if (resolvedObject.obj == nullptr)
         {
             resolvedObject.name = _u("{exception}");
@@ -484,26 +487,36 @@ Js::DynamicObject* JsrtDebuggerStackFrame::Evaluate(Js::ScriptContext* scriptCon
                 resolvedObject.obj = scriptContext->GetLibrary()->GetUndefined();
             }
         }
+        else
+        {
+          success = true;
+        }
+
         if (resolvedObject.obj != nullptr)
         {
             resolvedObject.scriptContext = scriptContext;
 
             charcount_t len = Js::JavascriptString::GetBufferLength(source);
             resolvedObject.name = AnewNoThrowArray(this->debuggerObjectsManager->GetDebugObjectArena(), WCHAR, len + 1);
-            if (resolvedObject.name == nullptr)
+
+            if (resolvedObject.name != nullptr)
+            {
+                wcscpy_s((WCHAR*)resolvedObject.name, len + 1, source);
+            }
+            else
             {
-                return nullptr;
+                // len can be big, if we failed just have empty string
+                resolvedObject.name = _u("");
             }
-            wcscpy_s((WCHAR*)resolvedObject.name, len + 1, source);
 
             resolvedObject.typeId = Js::JavascriptOperators::GetTypeId(resolvedObject.obj);
             JsrtDebuggerObjectBase::CreateDebuggerObject<JsrtDebuggerObjectProperty>(this->debuggerObjectsManager, resolvedObject, scriptContext, [&](Js::Var marshaledObj)
             {
-                evalResult = (Js::DynamicObject*)marshaledObj;
+                *evalResult = (Js::DynamicObject*)marshaledObj;
             });
         }
     }
-    return evalResult;
+    return success;
 }
 
 JsrtDebuggerObjectProperty::JsrtDebuggerObjectProperty(JsrtDebuggerObjectsManager* debuggerObjectsManager, WeakArenaReference<Js::IDiagObjectModelDisplay>* objectDisplay) :

+ 1 - 1
lib/Jsrt/JsrtDebuggerObject.h

@@ -120,7 +120,7 @@ public:
     ~JsrtDebuggerStackFrame();
     Js::DynamicObject* GetJSONObject(Js::ScriptContext* scriptContext);
     Js::DynamicObject* GetLocalsObject(Js::ScriptContext* scriptContext);
-    Js::DynamicObject* Evaluate(Js::ScriptContext* scriptContext, const char16 *source, int sourceLength, bool isLibraryCode);
+    bool Evaluate(Js::ScriptContext* scriptContext, const char16 *source, int sourceLength, bool isLibraryCode, Js::DynamicObject** evalResult);
     uint GetIndex() const { return this->frameIndex; }
 
 private:

+ 5 - 4
lib/Jsrt/JsrtDiag.cpp

@@ -658,14 +658,15 @@ CHAKRA_API JsDiagEvaluate(
             return JsErrorInvalidArgument;
         }
 
-        Js::DynamicObject* result = debuggerStackFrame->Evaluate(scriptContext, expression, static_cast<int>(len), false);
+        Js::DynamicObject* result = nullptr;
+        bool success = debuggerStackFrame->Evaluate(scriptContext, expression, static_cast<int>(len), false, &result);
 
         if (result != nullptr)
         {
             *evalResult = result;
-            return JsNoError;
         }
 
-        return JsErrorDiagUnableToPerformAction;
-    });
+        return success ? JsNoError : JsErrorScriptException;
+
+    }, false /*allowInObjectBeforeCollectCallback*/, true /*scriptExceptionAllowed*/);
 }

+ 2 - 2
lib/Jsrt/JsrtInternal.h

@@ -177,7 +177,7 @@ JsErrorCode ContextAPIWrapper(Fn fn)
 
 // allowInObjectBeforeCollectCallback only when current API is guaranteed not to do recycler allocation.
 template <class Fn>
-JsErrorCode ContextAPINoScriptWrapper(Fn fn, bool allowInObjectBeforeCollectCallback = false)
+JsErrorCode ContextAPINoScriptWrapper(Fn fn, bool allowInObjectBeforeCollectCallback = false, bool scriptExceptionAllowed = false)
 {
     JsrtContext *currentContext = JsrtContext::GetCurrent();
     JsErrorCode errCode = CheckContext(currentContext, /*verifyRuntimeState*/true, allowInObjectBeforeCollectCallback);
@@ -204,7 +204,7 @@ JsErrorCode ContextAPINoScriptWrapper(Fn fn, bool allowInObjectBeforeCollectCall
             errCode != JsErrorInExceptionState &&
             errCode != JsErrorInDisabledState &&
             errCode != JsErrorOutOfMemory &&
-            errCode != JsErrorScriptException &&
+            (scriptExceptionAllowed || errCode != JsErrorScriptException) &&
             errCode != JsErrorScriptTerminated);
     }
     CATCH_STATIC_JAVASCRIPT_EXCEPTION_OBJECT