From 5b3bfa8c0e37c3a6e99de8099515771b3cdfa832 Mon Sep 17 00:00:00 2001 From: zombieyang Date: Mon, 1 Apr 2024 11:44:15 +0800 Subject: [PATCH] symbol --- include/quickjs-msvc.h | 6 ++++-- include/v8.h | 18 +++++++++++++++++- quickjs/quickjs.c | 15 +++++++++++---- src/v8-impl.cc | 42 +++++++++++++++++++++++++++++++++++------- 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/include/quickjs-msvc.h b/include/quickjs-msvc.h index 7e12859..cfaf9a2 100644 --- a/include/quickjs-msvc.h +++ b/include/quickjs-msvc.h @@ -1016,11 +1016,13 @@ JSValue JS_SetDelete(JSContext *ctx, JSValueConst this_val, void JS_SetClear(JSContext *ctx, JSValueConst this_val); JSValue JS_DupModule(JSContext *ctx, JSModuleDef* v); - -/*-------end fuctions for v8 api---------*/ JSValue JS_GET_MODULE_NS(JSContext *ctx, JSModuleDef* v); int JS_ReleaseLoadedModule(JSContext *ctx, const char* path); +JSValue JS_NewSymbolByAtom(JSContext *ctx, JSAtom descr, int atom_type); +JSAtom JS_SymbolToAtom(JSContext *ctx, JSValue val); +/*-------end fuctions for v8 api---------*/ + #undef js_unlikely #undef js_force_inline diff --git a/include/v8.h b/include/v8.h index a66f1a0..2262653 100644 --- a/include/v8.h +++ b/include/v8.h @@ -1297,6 +1297,21 @@ class V8_EXPORT String : public Name { private: }; +/** + * A JavaScript symbol (ECMA-262 edition 6) + */ +class V8_EXPORT Symbol : public Name { + public: + static Local New( + Isolate* isolate, + Local description = Local() + ); + + V8_INLINE static Symbol* Cast(Value* data) { + return static_cast(data); + } +}; + class V8_EXPORT Function : public Object { public: V8_WARN_UNUSED_RESULT MaybeLocal Call(Local context, @@ -1338,7 +1353,8 @@ class V8_EXPORT Template : public Data { Local setter = Local(), PropertyAttribute attribute = None); - std::map> fields_; + // std::map> fields_; + std::map> fieldsByAtom_; class AccessorPropertyInfo { public: diff --git a/quickjs/quickjs.c b/quickjs/quickjs.c index dbcfaf9..d7162c3 100644 --- a/quickjs/quickjs.c +++ b/quickjs/quickjs.c @@ -54158,9 +54158,6 @@ JSValue JS_DupModule(JSContext *ctx, JSModuleDef* v) { return JS_DupValue(ctx, JS_MKPTR(JS_TAG_MODULE, v)); } - -/*-------end fuctions for v8 api---------*/ - JSValue JS_GET_MODULE_NS(JSContext *ctx, JSModuleDef* v) { return js_get_module_ns(ctx, v); @@ -54186,4 +54183,14 @@ int JS_ReleaseLoadedModule(JSContext *ctx, const char* path) } JS_FreeAtom(ctx, name); return 0; -} \ No newline at end of file +} +JSValue JS_NewSymbolByAtom(JSContext *ctx, JSAtom descr, int atom_type) +{ + return JS_NewSymbolFromAtom(ctx, descr, atom_type); +} + +JSAtom JS_SymbolToAtom(JSContext *ctx, JSValue val) +{ + return js_symbol_to_atom(ctx, val); +} +/*-------end fuctions for v8 api---------*/ diff --git a/src/v8-impl.cc b/src/v8-impl.cc index 1ee509e..58d6266 100644 --- a/src/v8-impl.cc +++ b/src/v8-impl.cc @@ -85,6 +85,19 @@ Isolate* Promise::GetIsolate() { return Isolate::current_; } +Local Symbol::New(Isolate* isolate, Local description) { + auto symbol = isolate->Alloc(); + auto context = isolate->current_context_->context_; + auto atom = JS_NewAtom(context, *String::Utf8Value(isolate, description)); + symbol->value_ = JS_NewSymbolByAtom( + isolate->current_context_->context_, + atom, + 2 + ); + JS_FreeAtom(context, atom); + return Local(symbol); +} + void V8FinalizerWrap(JSRuntime *rt, JSValue val) { Isolate* isolate = (Isolate*)JS_GetRuntimeOpaque(rt); Isolate::Scope Isolatescope(isolate); @@ -428,7 +441,6 @@ int String::Utf8Length(Isolate* isolate) const { int String::WriteUtf8(Isolate* isolate, char* buffer) const { size_t len; const char* p = JS_ToCStringLen(isolate->current_context_->context_, &len, value_); - memcpy(buffer, p, len); JS_FreeCString(isolate->current_context_->context_, p); @@ -804,13 +816,22 @@ MaybeLocal Function::NewInstance(Local context, int argc, Local } void Template::Set(Isolate* isolate, const char* name, Local value) { - fields_[name] = value; + // fields_[name] = value; + fieldsByAtom_[JS_NewAtom(isolate->current_context_->context_, name)] = value; } void Template::Set(Local name, Local value, PropertyAttribute attributes) { Isolate* isolate = Isolate::current_; - Set(isolate, *String::Utf8Value(Isolate::current_, name), value); + + if (name->IsSymbol()) + { + fieldsByAtom_[JS_SymbolToAtom(isolate->current_context_->context_, Symbol::Cast(*name)->value_)] = value; + } + else + { + Set(isolate, *String::Utf8Value(Isolate::current_, name), value); + } } void Template::SetAccessorProperty(Local name, @@ -822,13 +843,20 @@ void Template::SetAccessorProperty(Local name, } void Template::InitPropertys(Local context, JSValue obj) { - for(auto it : fields_) { - JSAtom atom = JS_NewAtom(context->context_, it.first.data()); + // for(auto it : fields_) { + // JSAtom atom = JS_NewAtom(context->context_, it.first.data()); + // Local funcTpl = Local::Cast(it.second); + // Local lfunc = funcTpl->GetFunction(context).ToLocalChecked(); + // context->GetIsolate()->Escape(*lfunc); + // JS_DefinePropertyValue(context->context_, obj, atom, lfunc->value_, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE | JS_PROP_WRITABLE); + // JS_FreeAtom(context->context_, atom); + // } + for(auto it : fieldsByAtom_) { + JSAtom atom = it.first; Local funcTpl = Local::Cast(it.second); Local lfunc = funcTpl->GetFunction(context).ToLocalChecked(); context->GetIsolate()->Escape(*lfunc); JS_DefinePropertyValue(context->context_, obj, atom, lfunc->value_, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE | JS_PROP_WRITABLE); - JS_FreeAtom(context->context_, atom); } for (auto it : accessor_property_infos_) { @@ -1034,7 +1062,7 @@ MaybeLocal FunctionTemplate::GetFunction(Local context) { JS_DupValueRT(isolate_->runtime_, ret->value_); return MaybeLocal(Local(ret)); } - cfunction_data_.is_construtor_ = !prototype_template_.IsEmpty() || !instance_template_.IsEmpty() || fields_.size() > 0 || accessor_property_infos_.size() > 0 || !parent_.IsEmpty(); + cfunction_data_.is_construtor_ = !prototype_template_.IsEmpty() || !instance_template_.IsEmpty() || fieldsByAtom_.size() > 0 || accessor_property_infos_.size() > 0 || !parent_.IsEmpty(); cfunction_data_.internal_field_count_ = instance_template_.IsEmpty() ? 0 : instance_template_->internal_field_count_; JSValue func_data[4];