From 2aa74658763e8be676ce7aa6264994ffa0f2e643 Mon Sep 17 00:00:00 2001 From: eching Date: Thu, 20 Jan 2022 18:05:46 -0800 Subject: [PATCH 1/4] Add classes and builtin objects for GeneratorFunction support. --- .../ast2cpp/runtime/include/builtins.h | 41 ++++++++++++++++++- src/MapleFE/ast2cpp/runtime/include/ts2cpp.h | 14 +++++-- src/MapleFE/ast2cpp/runtime/src/builtins.cpp | 11 +++-- 3 files changed, 58 insertions(+), 8 deletions(-) diff --git a/src/MapleFE/ast2cpp/runtime/include/builtins.h b/src/MapleFE/ast2cpp/runtime/include/builtins.h index 24f6176af1..4018d7d5e9 100644 --- a/src/MapleFE/ast2cpp/runtime/include/builtins.h +++ b/src/MapleFE/ast2cpp/runtime/include/builtins.h @@ -76,16 +76,53 @@ class RegExp : public Object { class Number : public Object { public: // TODO - class Ctor : public t2crt::Function { + class Ctor : public Function { public: - Ctor(t2crt::Function* ctor, t2crt::Object* proto, t2crt::Object* prototype_proto) : t2crt::Function(ctor, proto, prototype_proto) { } + Ctor(Function* ctor, Object* proto, Object* prototype_proto) : Function(ctor, proto, prototype_proto) { } virtual const char* __GetClassName() const {return "Number ";} }; static Ctor ctor; }; +class IteratorProto : public Object { +public: + // TODO + IteratorProto(Function* ctor, Object* proto) : Object(ctor, proto) { } +}; + +class GeneratorFunctionPrototype : public Function { +public: + GeneratorFunctionPrototype(Function* ctor, Object* proto, Object* prototype_proto) : Function(ctor, proto, prototype_proto) { } +}; + + +class GeneratorProto : public IteratorProto { +public: + // TODO + GeneratorProto(Function* ctor, Object* proto) : IteratorProto(ctor, proto) { } +}; + +class GeneratorFunc : public Function::Ctor { +public: + // TODO + GeneratorFunc(Function* ctor, Object* proto, Object* prototype_proto, Function* prototype_obj) : Function::Ctor(ctor, proto, prototype_proto, prototype_obj) { } +}; + +// GeneratorFunction objects. (Ref: ECMA spec 27.3) +// IteratorPrototype: It is not a prototype object of any constructor func, but holds shared properties for iterators +// GeneratorFunction: A builtin function used as the constructor for generators (i.e. generator functions).// +// Generator: (a.k.a. GeneratorFuncion.prototype in 2022 spec) is the prototype object of GeneratorFunction, +// It is a special object used as both prototype object and constructor - as prototype for sharing +// properties between generator functions, and as constructor whose prototype object (GeneratorPrototype +// in pre-2022 spec) holds shared properties for instances returned by generator functions. +extern IteratorProto IteratorPrototype; +extern GeneratorFunc GeneratorFunction; +extern GeneratorFunctionPrototype Generator; +extern Object* GeneratorPrototype; + } // namespace t2crt + using t2crt::Record; using t2crt::JSON; using t2crt::RegExp; diff --git a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h index 863f83f57a..6a133e3986 100644 --- a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h +++ b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h @@ -316,6 +316,13 @@ class Function : public Object { prototype = new Object(this, prototype_proto); prototype->AddProp("constructor", val); } + // Special constructor for creating builtin constructor function "GeneratorFunction" see builtins.h + Function(Function* ctor, Object* proto, Object* prototype_proto, Object* prototype_obj) : Object(ctor, proto) { + JS_Val val(this); + prototype = prototype_obj; + prototype->AddProp("constructor", val); + } + class Ctor; static Ctor ctor; @@ -323,11 +330,11 @@ class Function : public Object { return true; } - Object* bind(Object* obj, ArgsT* argv); - virtual JS_Val func(Object* obj, ArgsT& args) {JS_Val res; return res;} - // Put code for JS Function.prototype props as static fields and methods in this class // and add to propList of Function_ctor.prototype object on system init. + virtual Object* bind (Object* obj, ArgsT* argv) { return nullptr; } + virtual JS_Val call (Object* obj, ArgsT* argv) { JS_Val res; return res; } + virtual JS_Val apply(Object* obj, ArgsT* argv) { JS_Val res; return res; } std::string TypeId() override { return "function"s; @@ -354,6 +361,7 @@ class Object::Ctor : public Function { class Function::Ctor : public Function { public: Ctor(Function* ctor, Object* proto, Object* prototype_proto) : Function(ctor, proto, prototype_proto) {} + Ctor(Function* ctor, Object* proto, Object* prototype_proto, Object* prototype_obj) : Function(ctor, proto, prototype_proto, prototype_obj) {} }; template diff --git a/src/MapleFE/ast2cpp/runtime/src/builtins.cpp b/src/MapleFE/ast2cpp/runtime/src/builtins.cpp index d2bd4d4bb0..55c1546d93 100644 --- a/src/MapleFE/ast2cpp/runtime/src/builtins.cpp +++ b/src/MapleFE/ast2cpp/runtime/src/builtins.cpp @@ -2,9 +2,14 @@ namespace t2crt { -Object::Ctor Object::ctor = Object::Ctor (&Function::ctor, Function::ctor.prototype); -Function::Ctor Function::ctor = Function::Ctor(&Function::ctor, Function::ctor.prototype, Object::ctor.prototype); -Number::Ctor Number::ctor = Number::Ctor (&Function::ctor, Function::ctor.prototype, Object::ctor.prototype); +Object::Ctor Object::ctor (&Function::ctor, Function::ctor.prototype); +Function::Ctor Function::ctor(&Function::ctor, Function::ctor.prototype, Object::ctor.prototype); +Number::Ctor Number::ctor (&Function::ctor, Function::ctor.prototype, Object::ctor.prototype); + +IteratorProto IteratorPrototype(&Object::ctor, Object::ctor.prototype); +GeneratorFunctionPrototype Generator(&GeneratorFunction, Function::ctor.prototype, &IteratorPrototype); +GeneratorFunc GeneratorFunction(&Function::ctor, &Function::ctor, Function::ctor.prototype, &Generator); +Object* GeneratorPrototype = Generator.prototype; ARR_CTOR_DEF(int) ARR_CTOR_DEF(long) -- Gitee From b3362305d155a91e48f35be4cfa8e8cd2d0e04ce Mon Sep 17 00:00:00 2001 From: Wen HU Date: Fri, 21 Jan 2022 18:03:30 -0500 Subject: [PATCH 2/4] update field's scope from type of upper --- src/MapleFE/astopt/src/ast_ti.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/MapleFE/astopt/src/ast_ti.cpp b/src/MapleFE/astopt/src/ast_ti.cpp index ba09cc287a..dacabfb01f 100644 --- a/src/MapleFE/astopt/src/ast_ti.cpp +++ b/src/MapleFE/astopt/src/ast_ti.cpp @@ -1473,10 +1473,8 @@ IdentifierNode *TypeInferVisitor::VisitIdentifierNode(IdentifierNode *node) { TreeNode *uptype = gTypeTable.GetTypeFromTypeIdx(upper->GetTypeIdx()); if (uptype) { scope = uptype->GetScope(); - decl = scope->FindDeclOf(node->GetStrIdx()); - if (!decl) { - decl = scope->FindExportedDeclOf(node->GetStrIdx()); - } + node->SetScope(scope); + decl = mHandler->FindDecl(node, true); } } else { NOTYETIMPL("node not in field"); -- Gitee From 2c96815618d564610ee2d0fda123f7c92578afee Mon Sep 17 00:00:00 2001 From: eching Date: Sun, 23 Jan 2022 17:22:41 -0800 Subject: [PATCH 3/4] Handle output of TypeScript arrays that are wrapped in JS_Val. Handles multi dimensional arrays. Note: output of testcase three-dim-array.ts with this fix is correct although different than output from NodeJS and SpiderMonkey. --- .../ast2cpp/runtime/include/builtins.h | 20 +++++++++++++++++++ src/MapleFE/ast2cpp/runtime/include/ts2cpp.h | 1 + src/MapleFE/ast2cpp/runtime/src/ts2cpp.cpp | 4 +++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/MapleFE/ast2cpp/runtime/include/builtins.h b/src/MapleFE/ast2cpp/runtime/include/builtins.h index 4018d7d5e9..944a5866b9 100644 --- a/src/MapleFE/ast2cpp/runtime/include/builtins.h +++ b/src/MapleFE/ast2cpp/runtime/include/builtins.h @@ -16,6 +16,8 @@ #ifndef __BUILTINS_H__ #define __BUILTINS_H__ +#include + namespace t2crt { template @@ -39,6 +41,24 @@ class Array : public Object { void operator = (const std::vector &v) { elements = v; } long size() { return elements.size(); } + // Dump output to string (recurses if multi-dim array via ostream output operator overload in t2cpp.cpp) + virtual std::string Dump(void) { + std::stringstream ss; + std::streambuf* old = std::cout.rdbuf(ss.rdbuf()); + if (elements.empty()) + std::cout << "[]"; + else { + std::cout << "[ "; + auto i = elements.begin(), e = elements.end(); + std::cout << *i++; + for (; i != e; ++i) + std::cout << ", " << *i; + std::cout << " ]"; + } + std::cout.rdbuf(old); + return ss.str(); + } + // Put JS Array.prototype props as static fields and methods in this class // and add to proplist of Array_ctor.prototype object on system init. diff --git a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h index 6a133e3986..873afe6ff4 100644 --- a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h +++ b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h @@ -216,6 +216,7 @@ class Object { virtual ~Object() {} class Ctor; static Ctor ctor; + virtual std::string Dump(void) { return("Object"); } JS_Val& operator[] (std::string key) { diff --git a/src/MapleFE/ast2cpp/runtime/src/ts2cpp.cpp b/src/MapleFE/ast2cpp/runtime/src/ts2cpp.cpp index 1fa036b3af..9a7ef93cf7 100644 --- a/src/MapleFE/ast2cpp/runtime/src/ts2cpp.cpp +++ b/src/MapleFE/ast2cpp/runtime/src/ts2cpp.cpp @@ -16,6 +16,7 @@ std::ostream& operator<< (std::ostream& out, const t2crt::JS_Val& v) { case t2crt::TY_Symbol: out << "symbol"; break; case t2crt::TY_Function: out << "function"; break; case t2crt::TY_Object: out << v.x.val_obj; break; + case t2crt::TY_Array: out << v.x.val_obj->Dump(); break; case t2crt::TY_CXX_Undef: out << "undefined"; break; case t2crt::TY_CXX_Null: out << "null"; break; @@ -27,7 +28,8 @@ std::ostream& operator<< (std::ostream& out, const t2crt::JS_Val& v) { case t2crt::TY_CXX_Symbol: out << "symbol"; break; case t2crt::TY_CXX_Function: out << "function"; break; case t2crt::TY_CXX_Object: out << *(Object**)v.x.field; break; - } + case t2crt::TY_CXX_Array: out << (*(Object**)v.x.field)->Dump(); break; + } return out; } -- Gitee From 7fa4386fd8290b9baa291e3b6631d877c5b68d03 Mon Sep 17 00:00:00 2001 From: eching Date: Mon, 24 Jan 2022 02:55:26 -0800 Subject: [PATCH 4/4] Add interface in runtime to create JS_Val for array objects. --- src/MapleFE/ast2cpp/runtime/include/builtins.h | 7 ++++++- src/MapleFE/ast2cpp/runtime/include/ts2cpp.h | 4 ++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/MapleFE/ast2cpp/runtime/include/builtins.h b/src/MapleFE/ast2cpp/runtime/include/builtins.h index 944a5866b9..70f4f09ce5 100644 --- a/src/MapleFE/ast2cpp/runtime/include/builtins.h +++ b/src/MapleFE/ast2cpp/runtime/include/builtins.h @@ -41,7 +41,7 @@ class Array : public Object { void operator = (const std::vector &v) { elements = v; } long size() { return elements.size(); } - // Dump output to string (recurses if multi-dim array via ostream output operator overload in t2cpp.cpp) + // Output array to string (recurses if multi-dim array via ostream output operator overload in t2cpp.cpp) virtual std::string Dump(void) { std::stringstream ss; std::streambuf* old = std::cout.rdbuf(ss.rdbuf()); @@ -75,6 +75,11 @@ class Array : public Object { static Ctor ctor; }; +// Return pointer to Array object as JS_Val +inline JS_Val Arr2JsVal(Object* o, bool isCxx = false) { + return JS_Val(o, isCxx? TY_CXX_Array: TY_Array); +} + // Create ctor func for 1,2,3 dimension array of given type // note: must be in sync with format generated by ArrayCtorName in helper.h #define ARR_CTOR_DEF(type) \ diff --git a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h index 873afe6ff4..9129111795 100644 --- a/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h +++ b/src/MapleFE/ast2cpp/runtime/include/ts2cpp.h @@ -88,14 +88,14 @@ struct JS_Val { JS_Val(bool b) { x.val_bool = b; type = TY_Bool; } JS_Val(int64_t l) { x.val_long = l; type = TY_Long; } JS_Val(double d) { x.val_double = d; type = TY_Double; } - JS_Val(Object* o){ x.val_obj = o; type = TY_Object; } + JS_Val(Object* o) { x.val_obj = o; type = TY_Object; } + JS_Val(Object* o, JS_Type t) { x.val_obj = o; type = t; } JS_Val(Function* o){ x.val_func = o; type = TY_Function; } JS_Val(std::string* s) { x.val_string = s; type = TY_String; } JS_Val(std::string s) { x.val_string = new std::string(s); type = TY_String; } JS_Val(const char* s) { x.val_string = new std::string(s); type = TY_String; } JS_Val(int i) { x.val_long = i; type = TY_Long; } JS_Val(JS_Type jstype, bool v) { x.val_long = (int64_t)v; type = jstype; } - // Prop directly generated as class fields when TS is compiled into CPP JS_Val(JS_Type jstype, void* field) { x.field = field; type = static_cast(jstype|TY_CXX); } -- Gitee