@@ -44,21 +44,19 @@ namespace Js
4444 }
4545 type->SetPrototype (proto);
4646 }
47+
48+ int len = 0 ;
4749 // If targetFunction is proxy, need to make sure that traps are called in right order as per 19.2.3.2 in RC#4 dated April 3rd 2015.
48- // Here although we won't use value of length, this is just to make sure that we call traps involved with HasOwnProperty(Target, " length") and Get(Target, "length")
49- if (JavascriptProxy::Is (targetFunction) )
50+ // additionally need to get the correct length value for the boundFunctions' length property
51+ if (JavascriptOperators::HasOwnProperty (targetFunction, PropertyIds::length, scriptContext, nullptr ) == TRUE )
5052 {
51- if (JavascriptOperators::HasOwnProperty (targetFunction, PropertyIds::length, scriptContext, nullptr ) == TRUE )
53+ Var varLength;
54+ if (targetFunction->GetProperty (targetFunction, PropertyIds::length, &varLength, nullptr , scriptContext))
5255 {
53- int len = 0 ;
54- Var varLength;
55- if (targetFunction->GetProperty (targetFunction, PropertyIds::length, &varLength, nullptr , scriptContext))
56- {
57- len = JavascriptConversion::ToInt32 (varLength, scriptContext);
58- }
56+ len = JavascriptConversion::ToInt32 (varLength, scriptContext);
5957 }
60- GetTypeHandler ()->EnsureObjectReady (this );
6158 }
59+ GetTypeHandler ()->EnsureObjectReady (this );
6260
6361 if (args.Info .Count > 1 )
6462 {
@@ -84,6 +82,12 @@ namespace Js
8482 // If no "this" is passed, "undefined" is used
8583 boundThis = scriptContext->GetLibrary ()->GetUndefined ();
8684 }
85+
86+ // Reduce length number of bound args
87+ len = len - this ->count ;
88+ len = max (len, 0 );
89+
90+ SetPropertyWithAttributes (PropertyIds::length, TaggedInt::ToVarUnchecked (len), PropertyConfigurable, nullptr , PropertyOperation_None, SideEffects_None);
8791 }
8892
8993 BoundFunction::BoundFunction (RecyclableObject* targetFunction, Var boundThis, Var* args, uint argsCount, DynamicType * type)
@@ -307,108 +311,11 @@ namespace Js
307311 return false ;
308312 }
309313
310- PropertyQueryFlags BoundFunction::HasPropertyQuery (PropertyId propertyId, _Inout_opt_ PropertyValueInfo* info)
311- {
312- if (propertyId == PropertyIds::length)
313- {
314- return PropertyQueryFlags::Property_Found;
315- }
316-
317- return JavascriptFunction::HasPropertyQuery (propertyId, info);
318- }
319-
320- PropertyQueryFlags BoundFunction::GetPropertyQuery (Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
321- {
322- BOOL result;
323- if (GetPropertyBuiltIns (originalInstance, propertyId, value, info, requestContext, &result))
324- {
325- return JavascriptConversion::BooleanToPropertyQueryFlags (result);
326- }
327-
328- return JavascriptFunction::GetPropertyQuery (originalInstance, propertyId, value, info, requestContext);
329- }
330-
331- PropertyQueryFlags BoundFunction::GetPropertyQuery (Var originalInstance, JavascriptString* propertyNameString, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
332- {
333- BOOL result;
334- PropertyRecord const * propertyRecord;
335- this ->GetScriptContext ()->FindPropertyRecord (propertyNameString, &propertyRecord);
336-
337- if (propertyRecord != nullptr && GetPropertyBuiltIns (originalInstance, propertyRecord->GetPropertyId (), value, info, requestContext, &result))
338- {
339- return JavascriptConversion::BooleanToPropertyQueryFlags (result);
340- }
341-
342- return JavascriptFunction::GetPropertyQuery (originalInstance, propertyNameString, value, info, requestContext);
343- }
344-
345- bool BoundFunction::GetPropertyBuiltIns (Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext, BOOL* result)
346- {
347- if (propertyId == PropertyIds::length)
348- {
349- // Get the "length" property of the underlying target function
350- int len = 0 ;
351- Var varLength;
352- if (targetFunction->GetProperty (targetFunction, PropertyIds::length, &varLength, nullptr , requestContext))
353- {
354- len = JavascriptConversion::ToInt32 (varLength, requestContext);
355- }
356-
357- // Reduce by number of bound args
358- len = len - this ->count ;
359- len = max (len, 0 );
360-
361- *value = JavascriptNumber::ToVar (len, requestContext);
362- *result = true ;
363- return true ;
364- }
365-
366- return false ;
367- }
368-
369314 PropertyQueryFlags BoundFunction::GetPropertyReferenceQuery (Var originalInstance, PropertyId propertyId, Var* value, PropertyValueInfo* info, ScriptContext* requestContext)
370315 {
371316 return BoundFunction::GetPropertyQuery (originalInstance, propertyId, value, info, requestContext);
372317 }
373318
374- BOOL BoundFunction::SetProperty (PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
375- {
376- BOOL result;
377- if (SetPropertyBuiltIns (propertyId, value, flags, info, &result))
378- {
379- return result;
380- }
381-
382- return JavascriptFunction::SetProperty (propertyId, value, flags, info);
383- }
384-
385- BOOL BoundFunction::SetProperty (JavascriptString* propertyNameString, Var value, PropertyOperationFlags flags, PropertyValueInfo* info)
386- {
387- BOOL result;
388- PropertyRecord const * propertyRecord;
389- this ->GetScriptContext ()->FindPropertyRecord (propertyNameString, &propertyRecord);
390-
391- if (propertyRecord != nullptr && SetPropertyBuiltIns (propertyRecord->GetPropertyId (), value, flags, info, &result))
392- {
393- return result;
394- }
395-
396- return JavascriptFunction::SetProperty (propertyNameString, value, flags, info);
397- }
398-
399- bool BoundFunction::SetPropertyBuiltIns (PropertyId propertyId, Var value, PropertyOperationFlags flags, PropertyValueInfo* info, BOOL* result)
400- {
401- if (propertyId == PropertyIds::length)
402- {
403- JavascriptError::ThrowCantAssignIfStrictMode (flags, this ->GetScriptContext ());
404-
405- *result = false ;
406- return true ;
407- }
408-
409- return false ;
410- }
411-
412319 _Check_return_ _Success_ (return ) BOOL BoundFunction::GetAccessors(PropertyId propertyId, _Outptr_result_maybenull_ Var* getter, _Outptr_result_maybenull_ Var* setter, ScriptContext* requestContext)
413320 {
414321 return DynamicObject::GetAccessors (propertyId, getter, setter, requestContext);
@@ -429,56 +336,6 @@ namespace Js
429336 return SetProperty (propertyId, value, PropertyOperation_None, info);
430337 }
431338
432- BOOL BoundFunction::DeleteProperty (PropertyId propertyId, PropertyOperationFlags flags)
433- {
434- if (propertyId == PropertyIds::length)
435- {
436- return false ;
437- }
438-
439- return JavascriptFunction::DeleteProperty (propertyId, flags);
440- }
441-
442- BOOL BoundFunction::DeleteProperty (JavascriptString *propertyNameString, PropertyOperationFlags flags)
443- {
444- if (BuiltInPropertyRecords::length.Equals (propertyNameString))
445- {
446- return false ;
447- }
448-
449- return JavascriptFunction::DeleteProperty (propertyNameString, flags);
450- }
451-
452- BOOL BoundFunction::IsWritable (PropertyId propertyId)
453- {
454- if (propertyId == PropertyIds::length)
455- {
456- return false ;
457- }
458-
459- return JavascriptFunction::IsWritable (propertyId);
460- }
461-
462- BOOL BoundFunction::IsConfigurable (PropertyId propertyId)
463- {
464- if (propertyId == PropertyIds::length)
465- {
466- return false ;
467- }
468-
469- return JavascriptFunction::IsConfigurable (propertyId);
470- }
471-
472- BOOL BoundFunction::IsEnumerable (PropertyId propertyId)
473- {
474- if (propertyId == PropertyIds::length)
475- {
476- return false ;
477- }
478-
479- return JavascriptFunction::IsEnumerable (propertyId);
480- }
481-
482339 BOOL BoundFunction::HasInstance (Var instance, ScriptContext* scriptContext, IsInstInlineCache* inlineCache)
483340 {
484341 return this ->targetFunction ->HasInstance (instance, scriptContext, inlineCache);
0 commit comments