Add proxy support for HasBinding operation for Object Environment records (#3731)

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik
2020-05-13 14:27:31 +02:00
committed by GitHub
parent 4dc2cb3328
commit 9ad9d574fe
4 changed files with 116 additions and 69 deletions
@@ -86,42 +86,14 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
{ {
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND); JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); ecma_value_t result = ecma_op_object_bound_environment_resolve_reference_value (lex_env_p, name_p);
ecma_value_t result = ecma_op_object_find (binding_obj_p, name_p);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
if (ecma_is_value_found (result)) if (ecma_is_value_found (result))
{ {
/* Note: the result may contains ECMA_VALUE_ERROR */
*ref_base_lex_env_p = lex_env_p; *ref_base_lex_env_p = lex_env_p;
#if ENABLED (JERRY_ES2015)
ecma_value_t blocked = ecma_op_is_prop_unscopable (lex_env_p, name_p);
if (ECMA_IS_VALUE_ERROR (blocked))
{
ecma_free_value (result);
return blocked;
}
if (ecma_is_value_true (blocked))
{
*ref_base_lex_env_p = NULL;
ecma_free_value (result);
}
else
{
return result; return result;
} }
#else /* !ENABLED (JERRY_ES2015) */
return result;
#endif /* ENABLED (JERRY_ES2015) */
}
break; break;
} }
+92 -38
View File
@@ -140,17 +140,10 @@ ecma_op_resolve_super_base (ecma_object_t *lex_env_p) /**< starting lexical envi
* ECMA_VALUE_FALSE - if a the property is not unscopable * ECMA_VALUE_FALSE - if a the property is not unscopable
* ECMA_VALUE_ERROR - otherwise * ECMA_VALUE_ERROR - otherwise
*/ */
ecma_value_t static ecma_value_t
ecma_op_is_prop_unscopable (ecma_object_t *lex_env_p, /**< lexical environment */ ecma_op_is_prop_unscopable (ecma_object_t *binding_obj_p, /**< binding object */
ecma_string_t *prop_name_p) /**< property's name */ ecma_string_t *prop_name_p) /**< property's name */
{ {
if (lex_env_p == ecma_get_global_scope ())
{
return ECMA_VALUE_FALSE;
}
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
ecma_value_t unscopables = ecma_op_object_get_by_symbol_id (binding_obj_p, LIT_GLOBAL_SYMBOL_UNSCOPABLES); ecma_value_t unscopables = ecma_op_object_get_by_symbol_id (binding_obj_p, LIT_GLOBAL_SYMBOL_UNSCOPABLES);
if (ECMA_IS_VALUE_ERROR (unscopables)) if (ECMA_IS_VALUE_ERROR (unscopables))
@@ -182,6 +175,91 @@ ecma_op_is_prop_unscopable (ecma_object_t *lex_env_p, /**< lexical environment *
} /* ecma_op_is_prop_unscopable */ } /* ecma_op_is_prop_unscopable */
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
/**
* Helper method for HasBindig operation
*
* See also:
* ECMA-262 v6, 8.1.1.2.1 steps 7-9;
*
* @return ECMA_VALUE_TRUE - if the property is unscopable
* ECMA_VALUE_FALSE - if a the property is not unscopable
* ECMA_VALUE_ERROR - otherwise
*/
/**
* Resolve value corresponding to the given object environment reference.
*
* Note: the steps are already include the HasBindig operation steps
*
* See also:
* ECMA-262 v6, 8.1.1.2.1
*
* @return ECMA_VALUE_ERROR - if the operation fails
* ECMA_VALUE_NOT_FOUND - if the binding not exists or blocked via @@unscopables
* result of the binding - otherwise
*/
ecma_value_t
ecma_op_object_bound_environment_resolve_reference_value (ecma_object_t *lex_env_p, /**< lexical environment */
ecma_string_t *name_p) /**< variable name */
{
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
ecma_value_t found_binding;
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (ECMA_OBJECT_IS_PROXY (binding_obj_p))
{
found_binding = ecma_proxy_object_has (binding_obj_p, name_p);
if (!ecma_is_value_true (found_binding))
{
return ECMA_IS_VALUE_ERROR (found_binding) ? found_binding : ECMA_VALUE_NOT_FOUND;
}
}
else
{
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
found_binding = ecma_op_object_find (binding_obj_p, name_p);
if (ECMA_IS_VALUE_ERROR (found_binding) || !ecma_is_value_found (found_binding))
{
return found_binding;
}
#if ENABLED (JERRY_ES2015)
if (JERRY_LIKELY (lex_env_p == ecma_get_global_scope ()))
#endif /* ENABLED (JERRY_ES2015) */
{
return found_binding;
}
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
#if ENABLED (JERRY_ES2015)
ecma_value_t blocked = ecma_op_is_prop_unscopable (binding_obj_p, name_p);
if (ecma_is_value_false (blocked))
{
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (ECMA_OBJECT_IS_PROXY (binding_obj_p))
{
return ecma_proxy_object_get (binding_obj_p, name_p, ecma_make_object_value (binding_obj_p));
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
return found_binding;
}
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
if (!ECMA_OBJECT_IS_PROXY (binding_obj_p))
{
ecma_free_value (found_binding);
}
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
return ECMA_IS_VALUE_ERROR (blocked) ? blocked : ECMA_VALUE_NOT_FOUND;
#endif /* ENABLED (JERRY_ES2015) */
} /* ecma_op_object_bound_environment_resolve_reference_value */
/** /**
* Resolve value corresponding to reference. * Resolve value corresponding to reference.
* *
@@ -218,8 +296,6 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
} }
else if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND) else if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
{ {
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
bool lcache_lookup_allowed = (lex_env_p == ecma_get_global_environment ()); bool lcache_lookup_allowed = (lex_env_p == ecma_get_global_environment ());
#else /* !ENABLED (JERRY_ES2015)*/ #else /* !ENABLED (JERRY_ES2015)*/
@@ -229,6 +305,7 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
if (lcache_lookup_allowed) if (lcache_lookup_allowed)
{ {
#if ENABLED (JERRY_LCACHE) #if ENABLED (JERRY_LCACHE)
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
ecma_property_t *property_p = ecma_lcache_lookup (binding_obj_p, name_p); ecma_property_t *property_p = ecma_lcache_lookup (binding_obj_p, name_p);
if (property_p != NULL) if (property_p != NULL)
@@ -257,35 +334,12 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
#endif /* ENABLED (JERRY_LCACHE) */ #endif /* ENABLED (JERRY_LCACHE) */
} }
ecma_value_t prop_value = ecma_op_object_find (binding_obj_p, name_p); ecma_value_t result = ecma_op_object_bound_environment_resolve_reference_value (lex_env_p, name_p);
if (ECMA_IS_VALUE_ERROR (prop_value)) if (ecma_is_value_found (result))
{ {
return prop_value; /* Note: the result may contains ECMA_VALUE_ERROR */
} return result;
if (ecma_is_value_found (prop_value))
{
#if ENABLED (JERRY_ES2015)
ecma_value_t blocked = ecma_op_is_prop_unscopable (lex_env_p, name_p);
if (ECMA_IS_VALUE_ERROR (blocked))
{
ecma_free_value (prop_value);
return blocked;
}
if (ecma_is_value_true (blocked))
{
ecma_free_value (prop_value);
}
else
{
return prop_value;
}
#else /* !ENABLED (JERRY_ES2015) */
return prop_value;
#endif /* ENABLED (JERRY_ES2015) */
} }
} }
else else
+1 -1
View File
@@ -28,9 +28,9 @@
ecma_object_t *ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, ecma_string_t *name_p); ecma_object_t *ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, ecma_string_t *name_p);
ecma_value_t ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, ecma_string_t *name_p); ecma_value_t ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, ecma_string_t *name_p);
ecma_value_t ecma_op_object_bound_environment_resolve_reference_value (ecma_object_t *lex_env_p, ecma_string_t *name_p);
#if ENABLED (JERRY_ES2015) #if ENABLED (JERRY_ES2015)
ecma_value_t ecma_op_resolve_super_base (ecma_object_t *lex_env_p); ecma_value_t ecma_op_resolve_super_base (ecma_object_t *lex_env_p);
ecma_value_t ecma_op_is_prop_unscopable (ecma_object_t *lex_env_p, ecma_string_t *prop_name_p);
#endif /* ENABLED (JERRY_ES2015) */ #endif /* ENABLED (JERRY_ES2015) */
/** /**
+21
View File
@@ -104,3 +104,24 @@ with (a) {
assert(foo === 1); assert(foo === 1);
assert(typeof bar === "undefined"); assert(typeof bar === "undefined");
} }
let track = [];
let proxy = new Proxy({ a : 4, [Symbol.unscopables] : [] }, {
has (t, p) {
track.push(p);
return Reflect.has(...arguments);
},
get (t, p, r) {
track.push(p);
return Reflect.get(...arguments);
}
});
with (proxy){
a;
}
assert(track.length == 3);
assert(track[0] === 'a');
assert(track[1] === Symbol.unscopables);
assert(track[2] === 'a');