MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

prototype

+138 -8
+1 -1
meson.build
··· 74 74 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 75 75 76 76 version_conf = configuration_data() 77 - version_conf.set('ANT_VERSION', '0.1.0.5') 77 + version_conf.set('ANT_VERSION', '0.1.0.6') 78 78 version_conf.set('ANT_GIT_HASH', git_hash) 79 79 version_conf.set('ANT_BUILD_DATE', build_date) 80 80
+121 -7
src/ant.c
··· 1131 1131 jsoff_t koff = loadoff(js, next + (jsoff_t) sizeof(next)); 1132 1132 jsoff_t klen = offtolen(loadoff(js, koff)); 1133 1133 const char *key = (char *) &js->mem[koff + sizeof(koff)]; 1134 - if (!streq(key, klen, "__proto__", 9) && !streq(key, klen, "@@toStringTag", 13) && !streq(key, klen, "__getter", 8)) { 1134 + 1135 + bool is_desc = (klen > 7 && key[0] == '_' && key[1] == '_' && key[2] == 'd' && key[3] == 'e' && key[4] == 's' && key[5] == 'c' && key[6] == '_'); 1136 + bool should_hide = streq(key, klen, "__proto__", 9) || streq(key, klen, "@@toStringTag", 13) || streq(key, klen, "__getter", 8) || is_desc; 1137 + 1138 + if (!should_hide) { 1139 + char desc_key[128]; 1140 + snprintf(desc_key, sizeof(desc_key), "__desc_%.*s", (int)klen, key); 1141 + jsoff_t desc_off = lkp(js, obj, desc_key, strlen(desc_key)); 1142 + if (desc_off != 0) { 1143 + jsval_t desc_obj = resolveprop(js, mkval(T_PROP, desc_off)); 1144 + if (vtype(desc_obj) == T_OBJ) { 1145 + jsoff_t enumerable_off = lkp(js, desc_obj, "enumerable", 10); 1146 + if (enumerable_off != 0) { 1147 + jsval_t enumerable_val = resolveprop(js, mkval(T_PROP, enumerable_off)); 1148 + if (!js_truthy(js, enumerable_val)) should_hide = true; 1149 + } 1150 + } 1151 + } 1152 + } 1153 + 1154 + if (!should_hide) { 1135 1155 jsval_t val = loadval(js, next + (jsoff_t) (sizeof(next) + sizeof(koff))); 1136 1156 if (!first) n += cpy(buf + n, len - n, ",\n", 2); 1137 1157 first = false; ··· 2024 2044 invalidate_obj_cache(head); 2025 2045 2026 2046 return mkentity(js, (b & ~(3U | CONSTMASK)) | T_PROP, buf, sizeof(buf)); 2047 + } 2048 + 2049 + static jsval_t setup_func_prototype(struct js *js, jsval_t func) { 2050 + jsval_t proto_obj = mkobj(js, 0); 2051 + if (is_err(proto_obj)) return proto_obj; 2052 + 2053 + jsval_t object_proto = get_ctor_proto(js, "Object", 6); 2054 + if (vtype(object_proto) == T_OBJ) { 2055 + set_proto(js, proto_obj, object_proto); 2056 + } 2057 + 2058 + jsval_t constructor_key = js_mkstr(js, "constructor", 11); 2059 + if (is_err(constructor_key)) return constructor_key; 2060 + 2061 + jsval_t res = mkprop(js, proto_obj, constructor_key, func, false); 2062 + if (is_err(res)) return res; 2063 + 2064 + jsval_t desc_key_str = js_mkstr(js, "__desc_constructor", 18); 2065 + if (is_err(desc_key_str)) return desc_key_str; 2066 + 2067 + jsval_t desc_obj = js_mkobj(js); 2068 + if (is_err(desc_obj)) return desc_obj; 2069 + 2070 + setprop(js, desc_obj, js_mkstr(js, "writable", 8), js_mktrue()); 2071 + setprop(js, desc_obj, js_mkstr(js, "enumerable", 10), js_mkfalse()); 2072 + setprop(js, desc_obj, js_mkstr(js, "configurable", 12), js_mktrue()); 2073 + setprop(js, proto_obj, desc_key_str, desc_obj); 2074 + 2075 + jsval_t prototype_key = js_mkstr(js, "prototype", 9); 2076 + if (is_err(prototype_key)) return prototype_key; 2077 + 2078 + res = setprop(js, func, prototype_key, proto_obj); 2079 + if (is_err(res)) return res; 2080 + 2081 + return js_mkundef(); 2027 2082 } 2028 2083 2029 2084 jsval_t js_setprop(struct js *js, jsval_t obj, jsval_t k, jsval_t v) { ··· 4603 4658 if (is_err(res4)) return res4; 4604 4659 } 4605 4660 4606 - return mkval(T_FUNC, (unsigned long) vdata(func_obj)); 4661 + jsval_t func = mkval(T_FUNC, (unsigned long) vdata(func_obj)); 4662 + 4663 + jsval_t proto_setup = setup_func_prototype(js, func); 4664 + if (is_err(proto_setup)) return proto_setup; 4665 + 4666 + return func; 4607 4667 } 4608 4668 4609 4669 #define RTL_BINOP(_f1, _f2, _cond) \ ··· 5622 5682 if (is_err(res4)) return res4; 5623 5683 } 5624 5684 jsval_t func = mkval(T_FUNC, (unsigned long) vdata(func_obj)); 5685 + 5686 + jsval_t proto_setup = setup_func_prototype(js, func); 5687 + if (is_err(proto_setup)) return proto_setup; 5688 + 5625 5689 if (exe) { 5626 5690 if (lkp(js, js->scope, name, nlen) > 0) 5627 5691 return js_mkerr(js, "'%.*s' already declared", (int) nlen, name); ··· 5680 5744 if (is_err(res4)) return res4; 5681 5745 } 5682 5746 jsval_t func = mkval(T_FUNC, (unsigned long) vdata(func_obj)); 5747 + 5748 + jsval_t proto_setup = setup_func_prototype(js, func); 5749 + if (is_err(proto_setup)) return proto_setup; 5750 + 5683 5751 if (exe) { 5684 5752 if (lkp(js, js->scope, name, nlen) > 0) 5685 5753 return js_mkerr(js, "'%.*s' already declared", (int) nlen, name); ··· 5845 5913 jsoff_t klen = offtolen(loadoff(js, koff)); 5846 5914 const char *key = (char *) &js->mem[koff + sizeof(koff)]; 5847 5915 5848 - if (!streq(key, klen, "__proto__", 9)) { 5916 + bool should_skip = streq(key, klen, "__proto__", 9); 5917 + 5918 + if (!should_skip && klen > 7 && key[0] == '_' && key[1] == '_' && 5919 + key[2] == 'd' && key[3] == 'e' && key[4] == 's' && key[5] == 'c' && key[6] == '_') { 5920 + should_skip = true; 5921 + } 5922 + 5923 + if (!should_skip) { 5924 + char desc_key[128]; 5925 + snprintf(desc_key, sizeof(desc_key), "__desc_%.*s", (int)klen, key); 5926 + jsoff_t desc_off = lkp(js, iter_obj, desc_key, strlen(desc_key)); 5927 + if (desc_off != 0) { 5928 + jsval_t desc_obj = resolveprop(js, mkval(T_PROP, desc_off)); 5929 + if (vtype(desc_obj) == T_OBJ) { 5930 + jsoff_t enumerable_off = lkp(js, desc_obj, "enumerable", 10); 5931 + if (enumerable_off != 0) { 5932 + jsval_t enumerable_val = resolveprop(js, mkval(T_PROP, enumerable_off)); 5933 + if (!js_truthy(js, enumerable_val)) { 5934 + should_skip = true; 5935 + } 5936 + } 5937 + } 5938 + } 5939 + } 5940 + 5941 + if (!should_skip) { 5849 5942 jsval_t key_str = js_mkstr(js, key, klen); 5850 5943 5851 5944 const char *var_name = &js->code[var_name_off]; ··· 7422 7515 res = setprop(js, func_obj, scope_key, js_glob(js)); 7423 7516 if (is_err(res)) return res; 7424 7517 7425 - return mkval(T_FUNC, (unsigned long) vdata(func_obj)); 7518 + jsval_t func = mkval(T_FUNC, (unsigned long) vdata(func_obj)); 7519 + 7520 + jsval_t proto_setup = setup_func_prototype(js, func); 7521 + if (is_err(proto_setup)) return proto_setup; 7522 + 7523 + return func; 7426 7524 } 7427 7525 7428 7526 size_t total_len = 1; ··· 7490 7588 res = setprop(js, func_obj, scope_key, js_glob(js)); 7491 7589 if (is_err(res)) return res; 7492 7590 7493 - return mkval(T_FUNC, (unsigned long) vdata(func_obj)); 7591 + jsval_t func = mkval(T_FUNC, (unsigned long) vdata(func_obj)); 7592 + 7593 + jsval_t proto_setup = setup_func_prototype(js, func); 7594 + if (is_err(proto_setup)) return proto_setup; 7595 + 7596 + return func; 7494 7597 } 7495 7598 7496 7599 static jsval_t builtin_function_call(struct js *js, jsval_t *args, int nargs) { ··· 7587 7690 setprop(js, bound_func, js_mkstr(js, "__native_func", 13), func); 7588 7691 setprop(js, bound_func, js_mkstr(js, "__this", 6), this_arg); 7589 7692 7590 - return mkval(T_FUNC, (unsigned long) vdata(bound_func)); 7693 + jsval_t bound = mkval(T_FUNC, (unsigned long) vdata(bound_func)); 7694 + 7695 + jsval_t proto_setup = setup_func_prototype(js, bound); 7696 + if (is_err(proto_setup)) return proto_setup; 7697 + 7698 + return bound; 7591 7699 } 7592 7700 7593 7701 jsval_t func_obj = mkval(T_OBJ, vdata(func)); ··· 7613 7721 } 7614 7722 7615 7723 setprop(js, bound_func, js_mkstr(js, "__this", 6), this_arg); 7616 - return mkval(T_FUNC, (unsigned long) vdata(bound_func)); 7724 + 7725 + jsval_t bound = mkval(T_FUNC, (unsigned long) vdata(bound_func)); 7726 + 7727 + jsval_t proto_setup = setup_func_prototype(js, bound); 7728 + if (is_err(proto_setup)) return proto_setup; 7729 + 7730 + return bound; 7617 7731 } 7618 7732 7619 7733 static jsval_t builtin_Array(struct js *js, jsval_t *args, int nargs) {
+16
tests/proto.js
··· 1 + function Person(first, last) { 2 + this.firstName = first; 3 + this.lastName = last; 4 + } 5 + 6 + Person.prototype.fullName = function () { 7 + return this.firstName + ' ' + this.lastName; 8 + }; 9 + 10 + const person1 = new Person('John', 'Doe'); 11 + const person2 = new Person('Jane', 'Smith'); 12 + 13 + console.log(person1.fullName()); 14 + console.log(person2.fullName()); 15 + 16 + console.log(Person.prototype);