-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
boa 源码相关 #758
Comments
参与
arraytoString
Array.prototype.toString ( )
toString 函数被有意设计成通用的;它的this 值并非必须是数组对象。因此,它可以作为方法转移到其他类型的对象中。一个宿主对象是否可以正确应用这个toString 函数是依赖于实现的。 英文标准描述 15.4.4.2 Array.prototype.toString ( )
/**
* The Array.prototype object's 'toString' routine
* 数组的toString函数
*
* See also:
* ECMA-262 v5, 15.4.4.2
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_array_prototype_object_to_string (ecma_value_t this_arg, /**< this argument */
ecma_object_t *obj_p) /**< array object */
{
/* 2. */
// 获取join函数
ecma_value_t join_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_JOIN);
// 如果不存在join函数
if (ECMA_IS_VALUE_ERROR (join_value))
{
return join_value;
}
// 如果不运行调用join函数
if (!ecma_op_is_callable (join_value))
{
/* 3. */
ecma_free_value (join_value);
return ecma_builtin_helper_object_to_string (this_arg);
}
/* 4. */
ecma_object_t *join_func_obj_p = ecma_get_object_from_value (join_value);
ecma_value_t ret_value = ecma_op_function_call (join_func_obj_p, this_arg, NULL, 0);
ecma_deref_object (join_func_obj_p);
return ret_value;
} /* ecma_builtin_array_prototype_object_to_string */ rust
ObjecttoString
15.2.4.2 Object.prototype.toString ( )
jerryscript的实现/**
* Common implementation of the Object.prototype.toString routine
*
* See also:
* ECMA-262 v5, 15.2.4.2
*
* Used by:
* - The Object.prototype.toString routine.
* - The Array.prototype.toString routine as fallback.
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_builtin_helper_object_to_string (const ecma_value_t this_arg) /**< this argument */
{
lit_magic_string_id_t type_string;
if (ecma_is_value_undefined (this_arg))
{
type_string = LIT_MAGIC_STRING_UNDEFINED_UL;
}
else if (ecma_is_value_null (this_arg))
{
type_string = LIT_MAGIC_STRING_NULL_UL;
}
else
{
ecma_value_t obj_this = ecma_op_to_object (this_arg);
if (ECMA_IS_VALUE_ERROR (obj_this))
{
return obj_this;
}
JERRY_ASSERT (ecma_is_value_object (obj_this));
ecma_object_t *obj_p = ecma_get_object_from_value (obj_this);
type_string = ecma_object_get_class_name (obj_p);
#if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL)
ecma_value_t tag_value = ecma_op_object_get_by_symbol_id (obj_p, LIT_MAGIC_STRING_TO_STRING_TAG);
if (ECMA_IS_VALUE_ERROR (tag_value))
{
ecma_deref_object (obj_p);
return tag_value;
}
if (ecma_is_value_string (tag_value))
{
ecma_deref_object (obj_p);
return ecma_builtin_helper_object_to_string_tag_helper (tag_value);
}
ecma_free_value (tag_value);
#endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */
ecma_deref_object (obj_p);
}
ecma_string_t *ret_string_p;
/* Building string "[object #type#]" where type is 'Undefined',
'Null' or one of possible object's classes.
The string with null character is maximum 27 characters long. */
const lit_utf8_size_t buffer_size = 27;
JERRY_VLA (lit_utf8_byte_t, str_buffer, buffer_size);
lit_utf8_byte_t *buffer_ptr = str_buffer;
const lit_magic_string_id_t magic_string_ids[] =
{
LIT_MAGIC_STRING_LEFT_SQUARE_CHAR,
LIT_MAGIC_STRING_OBJECT,
LIT_MAGIC_STRING_SPACE_CHAR,
type_string,
LIT_MAGIC_STRING_RIGHT_SQUARE_CHAR
};
for (uint32_t i = 0; i < sizeof (magic_string_ids) / sizeof (lit_magic_string_id_t); ++i)
{
buffer_ptr = lit_copy_magic_string_to_buffer (magic_string_ids[i], buffer_ptr,
(lit_utf8_size_t) ((str_buffer + buffer_size) - buffer_ptr));
JERRY_ASSERT (buffer_ptr <= str_buffer + buffer_size);
}
ret_string_p = ecma_new_ecma_string_from_utf8 (str_buffer, (lit_utf8_size_t) (buffer_ptr - str_buffer));
return ecma_make_string_value (ret_string_p);
} /* ecma_builtin_helper_object_to_string */ 其他模块的toString实现原理String
number
Boolean
Regexp
jerryscript的实现
|
bugfixnew Array
|
prpr的检查命令
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
总结
feature
支持
不支持
总体流程
环境
问答
boa原型链的遍历在哪里?
如何/在哪里 实现作用域链上变量的遍历的?
LexicalEnvironment
里上搜索的global_env
作为根对象,另外一个作为词法环境的第一个环境存储到realm.environment
链中realm如何增删改查的?
let realm = Realm::create();
创建,也是parse之前。然后存到Executor里面,供全局使用realm里面的global_env和environment有啥用途区别?
console/JSON之类的全局对象是如何获取的?
原生函数根JS函数有什么区别?
NativeFunction
, JS函数叫RegularFunction
JS定义的普通函数是如何存储的?数据结构是什么?
GC在rust里面时如何实现的?
ifelse/switch/case如何实现的?
expect_punc
函数就会去截取计算后面的第一个token,并比较是否是期待的。不符合的就会报ParseError
错误,switch的token生成是在Keyword::Switch => {
Parser.tokens
里面ExprDef::Switch(ref val_e, ref vals, ref default) => {
let/const在{}块作用域如何保证不提升和局部性(比如在if里面)?
而let/const的是:
然后塞入环境的变量数组里面是根据block还是function的,最后寻找的时候也是从块作用域开始的
凡是{}都会创建一个环境?
.号和[]是如何取到值的?这两个有什么区别?
get_field_slice
函数调用的是get_field
来取值,对get_field
函数会取值的.和[]设置值是把值添加到可枚举的对象中?
ExprDef::Assign
,再在set_field_slice
函数打断点嵌套
self.run
递归如何传递参数。比如aa.bb = 1;
bb如何传递给assign?Object.to_string
函数做了什么object.create_constructor
函数里面。调用GC封装携带的to_string函数to_value
这块比较复杂,根据数据的类型ToValue,string,number啊等之类的实现不同的to_value函数。这里是字符串类型,所以调用impl ToValue for String
里面的函数FromValue
Array.prototype.join
的原理rust已经有所有权了,还需要JS的GC吗?
The text was updated successfully, but these errors were encountered: