Jelajahi Sumber

Updating ARM CallFunction scenarios according to the CallInfo.Count update

Following up on the PR https://github.com/Microsoft/ChakraCore/pull/4140 this change fixes the CallFunciton scenarios for ARM architecture.
Aneesh Divakarakurup 8 tahun lalu
induk
melakukan
6e828b83a5

+ 4 - 5
lib/Runtime/Library/JavascriptFunction.cpp

@@ -1313,7 +1313,7 @@ dbl_align:
 #elif defined(_M_ARM)
     extern "C"
     {
-        extern Var arm_CallFunction(JavascriptFunction* function, CallInfo info, Var* values, JavascriptMethod entryPoint);
+        extern Var arm_CallFunction(JavascriptFunction* function, CallInfo info, uint argCount, Var* values, JavascriptMethod entryPoint);
     }
 
     template <bool doStackProbe>
@@ -1334,13 +1334,12 @@ dbl_align:
 
         //The ARM can pass 4 arguments via registers so handle the cases for 0 or 1 values without resorting to asm code
         //(so that the asm code can assume 0 or more values will go on the stack: putting -1 values on the stack is unhealthy).
-        unsigned count = args.Info.Count;
-        if (count == 0)
+        if (argCount == 0)
         {
             varResult = CALL_ENTRYPOINT(function->GetScriptContext()->GetThreadContext(),
                 entryPoint, (JavascriptFunction*)function, args.Info);
         }
-        else if (count == 1)
+        else if (argCount == 1)
         {
             varResult = CALL_ENTRYPOINT(function->GetScriptContext()->GetThreadContext(),
                 entryPoint, (JavascriptFunction*)function, args.Info, args.Values[0]);
@@ -1348,7 +1347,7 @@ dbl_align:
         else
         {
             varResult = JS_REENTRANCY_CHECK(function->GetScriptContext()->GetThreadContext(),
-                arm_CallFunction((JavascriptFunction*)function, args.Info, args.Values, entryPoint));
+                arm_CallFunction((JavascriptFunction*)function, args.Info, argCount, args.Values, entryPoint));
         }
 
         return varResult;

+ 23 - 22
lib/Runtime/Library/arm/arm_CallFunction.asm

@@ -3,10 +3,10 @@
 ; Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 ;-------------------------------------------------------------------------------------------------------
 
-;Var arm_CallFunction(JavascriptFunction* function, CallInfo info, Var* values, JavascriptMethod entryPoint)
+;Var arm_CallFunction(JavascriptFunction* function, CallInfo info, uint count, Var* values, JavascriptMethod entryPoint)
 ;
 ;   This method should be called as follows
-;       varResult = arm_CallFunction((JavascriptFunction*)function, args.Info, args.Values, entryPoint);
+;       varResult = arm_CallFunction((JavascriptFunction*)function, args.Info, argCount, args.Values, entryPoint);
 ;
 ;   and makes the following call
 ;           return entryPoint(function, info, values[0], values[1], ..., values[n-2], values[n-1]);
@@ -53,9 +53,7 @@
 
 
     ;All but two values go onto the stack ... calculate the number of values on the stack.
-    mov     r4,r1               ;r4 = callInfo.
-    bfc     r4,#24,#8           ;clear high order 8 bits of r6 -- clean callInfo.Flags which shares same word as callInfo.Count.
-    sub     r4,r4,#2            ;subtract 2 == number of values that we can pass via registers.
+    sub     r4,r2,#2            ;subtract 2 == number of values that we can pass via registers.
     mov     r5,r4,lsl #2        ;r5 = space needed on the stack for values.
 
     ; Adjust sp to meet ABI requirement: stack must be 8-bytes aligned at any function boundary.
@@ -70,20 +68,23 @@
     ;  - output: r4 = total number of BYTES probed/allocated.
     blx     __chkstk            ;now r4 = the space to allocate, r5 = actual space needed for values on stack, r4 >= r5.
 
+#if defined(_CONTROL_FLOW_GUARD)
+    ldr     r6,[sp, #32]        ; r6 = entryPoint
+#else
+    ldr     r6,[sp, #24]
+#endif
     ;offset stack by the amount of space we'll need.
     sub     sp,sp,r4
 
-    mov     r4,r3                               ;copy entryPoint to r4 so we can use r3 as a scratch variable
-
-    add     r2,r2,#8                            ;add 8 to r2 (so it is the address of the first value to be placed on the stack).
+    add     r3,r3,#8                            ;add 8 to r3 (so it is the address of the first value to be placed on the stack).
     mov     r12,#0                              ;offset for getting values/storing on stack.
 
 |argN|
     cmp     r5,r12
     beq     arg2                                ;if r5 == r12, no more values need to go onto the stack.
 
-        ldr     r3,[r2,r12]                     ;r3 = *(r2 + r12)
-        str     r3,[sp,r12]                     ;*(sp + r12) = r3
+        ldr     r4,[r3,r12]                     ;r3 = *(r2 + r12)
+        str     r4,[sp,r12]                     ;*(sp + r12) = r3
 
         add     r12,r12,#4                      ;offset increases by 4.
     b   argN                                    ;goto argN
@@ -91,27 +92,27 @@
 |arg2|
     ; Verify that the call target is valid, and process last two arguments
 #if defined(_CONTROL_FLOW_GUARD)
-    mov     r5, r0    ; save argument registers
-    mov     r6, r1
-    mov     r8, r2
+    mov     r4, r0    ; save argument registers
+    mov     r5, r1
+    mov     r8, r3
 
-    mov     r0, r4    ; the target address to check
+    mov     r0, r6    ; the target address to check
     mov32   r12, __guard_check_icall_fptr
     ldr     r12, [r12]
     blx     r12
 
-    mov     r0, r5    ; restore argument registers
-    mov     r1, r6
-    mov     r2, r8
+    mov     r0, r4    ; restore argument registers
+    mov     r1, r5
+    mov     r3, r8
 #endif
 
-    ;Push values[1] into r3
-    ldr     r3,[r2,#-4]                         ;r3 = *(r2-4) = values[1]
-
     ;Push values[0] into r2
-    ldr     r2,[r2,#-8]                         ;r2 = *(r2-8) = values[0]
+    ldr     r2,[r3,#-8]                         ;r2 = *(r2-8) = values[0]
+
+    ;Push values[1] into r3
+    ldr     r3,[r3,#-4]                         ;r3 = *(r2-4) = values[1]
 
-    blx     r4                                  ;call r4 (== entry point)
+    blx     r6                                  ;call r4 (== entry point)
 
     EPILOG_STACK_RESTORE r7
 #if defined(_CONTROL_FLOW_GUARD)