// 25.4.2.2 PromiseResolveThenableTask ( promiseToResolve, thenable, then) static void PromiseResolveThenableTask (ejsval promiseToResolve, ejsval thenable, ejsval then) { // 1. Let resolvingFunctions be CreateResolvingFunctions(promiseToResolve). ejsval resolvingFunctions_resolve; ejsval resolvingFunctions_reject; CreateResolvingFunctions(promiseToResolve, &resolvingFunctions_resolve, &resolvingFunctions_reject); // 2. Let thenCallResult be the result of calling the [[Call]] internal method of then passing thenable as the thisArgument and (resolvingFunctions.[[Resolve]], resolvingFunctions.[[Reject]]) as argumentsList. ejsval thenCallResult; ejsval args[] = { resolvingFunctions_resolve, resolvingFunctions_reject }; EJSBool success = _ejs_invoke_closure_catch(&thenCallResult, then, thenable, 2, args); // 3. If thenCallResult is an abrupt completion, if (!success) { // a. Let status be the result of calling the [[Call]] internal method of resolvingFunctions.[[Reject]] passing undefined as the thisArgument and (thenCallResult.[[value]]) as argumentsList. ejsval status; success = _ejs_invoke_closure_catch(&status, resolvingFunctions_reject, _ejs_undefined, 1, &thenCallResult); // b. NextTask status. EJS_NOT_IMPLEMENTED(); } // 4. NextTask thenCallResult. EJS_NOT_IMPLEMENTED(); }
/* 15.12.2 */ static ejsval _ejs_JSON_parse (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { ejsval text = _ejs_undefined; ejsval reviver = _ejs_undefined; if (argc > 0) text = args[0]; if (argc > 1) reviver = args[1]; /* 1. Let JText be ToString(text). */ ejsval jtext = ToString(text); /* 2. Parse JText using the grammars in 15.12.1. Throw a SyntaxError exception if JText did not conform to the JSON grammar for the goal symbol JSONText. */ char *flattened_jtext = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(jtext)); /* 3. Let unfiltered be the result of parsing and evaluating JText as if it was the source text of an ECMAScript Program but using JSONString in place of StringLiteral. Note that since JText conforms to the JSON grammar this result will be either a primitive value or an object that is defined by either an ArrayLiteral or an ObjectLiteral. */ JSON_Value* root_val = json_parse_string(flattened_jtext); free(flattened_jtext); if (root_val == NULL) { printf ("SyntaxError\n"); EJS_NOT_IMPLEMENTED(); } ejsval unfiltered; if (!json_value_to_ejsval(root_val, &unfiltered)) { json_value_free (root_val); /* unfiltered here is an exception */ EJS_NOT_IMPLEMENTED(); } json_value_free (root_val); /* 4. If IsCallable(reviver) is true, then */ if (EJSVAL_IS_CALLABLE(reviver)) { printf ("no reviver support in JSON.parse yet\n"); EJS_NOT_IMPLEMENTED(); /* a. Let root be a new object created as if by the expression new Object(), where Object is the standard built-in constructor with that name. */ /* b. Call the [[DefineOwnProperty]] internal method of root with the empty String, the PropertyDescriptor {[[Value]]: unfiltered, [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true}, and false as arguments. */ /* c. Return the result of calling the abstract operation Walk, passing root and the empty String. The abstract operation Walk is described below. */ } /* 5. Else */ else { /* a. Return unfiltered. */ return unfiltered; } }
static EJSObject* _ejs_function_specop_allocate () { // we shouldn't ever get here.. EJS_NOT_IMPLEMENTED(); return NULL; }
// ECMA262: 15.3.5.3 static EJSBool _ejs_function_specop_has_instance (ejsval F, ejsval V) { /* 1. If V is not an object, return false. */ if (!EJSVAL_IS_OBJECT(V)) return EJS_FALSE; /* 2. Let O be the result of calling the [[Get]] internal method of F with property name "prototype". */ ejsval O = OP(EJSVAL_TO_OBJECT(F),Get)(F, _ejs_atom_prototype, F); /* 3. If Type(O) is not Object, throw a TypeError exception. */ if (!EJSVAL_IS_OBJECT(O)) { printf ("throw TypeError, O is not an object\n"); EJS_NOT_IMPLEMENTED(); } /* 4. Repeat */ while (1) { /* a. Let V be the value of the [[Prototype]] internal property of V. */ V = EJSVAL_TO_OBJECT(V)->proto; /* b. If V is null, return false. */ if (EJSVAL_IS_NULL(V)) return EJS_FALSE; /* c. If O and V refer to the same object, return true. */ if (EJSVAL_EQ(O, V)) return EJS_TRUE; } }
// returns an EJSPrimString*. // maybe we could change it to return a char* to match ToDouble? that way string concat wouldn't create // temporary strings for non-PrimString objects only to throw them away after concatenation? ejsval ToString(ejsval exp) { if (EJSVAL_IS_MAGIC_IMPL(exp)) { // holes in dense arrays end up here return _ejs_atom_empty; } else if (EJSVAL_IS_NULL(exp)) return _ejs_atom_null; else if (EJSVAL_IS_UNDEFINED(exp)) return _ejs_atom_undefined; else if (EJSVAL_IS_BOOLEAN(exp)) return EJSVAL_TO_BOOLEAN(exp) ? _ejs_atom_true : _ejs_atom_false; else if (EJSVAL_IS_NUMBER(exp)) return NumberToString(EJSVAL_TO_NUMBER(exp)); else if (EJSVAL_IS_STRING(exp)) return exp; else if (EJSVAL_IS_OBJECT(exp)) { ejsval toString = _ejs_object_getprop (exp, _ejs_atom_toString); if (!EJSVAL_IS_FUNCTION(toString)) { return _ejs_Object_prototype_toString(_ejs_null, exp, 0, NULL); } // should we be checking if this returns a string? i'd assume so... return _ejs_invoke_closure (toString, exp, 0, NULL); } else EJS_NOT_IMPLEMENTED(); }
ejsval _ejs_typedarray_new_from_array (EJSTypedArrayType element_type, ejsval arrayObj) { EJSObject *arr = EJSVAL_TO_OBJECT(arrayObj); int arrlen = EJSARRAY_LEN(arr); ejsval typedarr = _ejs_typedarray_new (element_type, arrlen); int i; void* data = _ejs_typedarray_get_data (EJSVAL_TO_OBJECT(typedarr)); // this is woefully underoptimized... for (i = 0; i < arrlen; i ++) { ejsval item = _ejs_object_getprop (arrayObj, NUMBER_TO_EJSVAL(i)); switch (element_type) { case EJS_TYPEDARRAY_INT8: ((int8_t*)data)[i] = (int8_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_UINT8: ((uint8_t*)data)[i] = (uint8_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_UINT8CLAMPED: EJS_NOT_IMPLEMENTED(); case EJS_TYPEDARRAY_INT16: ((int16_t*)data)[i] = (int16_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_UINT16: ((uint16_t*)data)[i] = (uint16_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_INT32: ((int32_t*)data)[i] = (int32_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_UINT32: ((uint32_t*)data)[i] = (uint32_t)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_FLOAT32: ((float*)data)[i] = (float)EJSVAL_TO_NUMBER(item); break; case EJS_TYPEDARRAY_FLOAT64: ((double*)data)[i] = (double)EJSVAL_TO_NUMBER(item); break; default: EJS_NOT_REACHED(); } } return typedarr; }
// ECMA262: 15.10.6.3 static ejsval _ejs_RegExp_prototype_test (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { if (!EJSVAL_IS_REGEXP(_this)) EJS_NOT_IMPLEMENTED(); EJSRegExp* re = (EJSRegExp*)EJSVAL_TO_OBJECT(_this); ejsval subject = _ejs_undefined; if (argc > 0) subject = args[0]; pcre16_extra extra; memset (&extra, 0, sizeof(extra)); EJSPrimString *flat_subject = _ejs_string_flatten (subject); jschar* subject_chars = flat_subject->data.flat; int ovec[3]; int rv = pcre16_exec((pcre16*)re->compiled_pattern, &extra, subject_chars, flat_subject->length, 0, PCRE_NO_UTF16_CHECK, ovec, 3); return rv == PCRE_ERROR_NOMATCH ? _ejs_false : _ejs_true; }
static EJSBool json_value_to_ejsval(JSON_Value *v, ejsval *rv) { switch (json_value_get_type (v)) { case JSONNull: *rv = _ejs_null; return EJS_TRUE; case JSONString: *rv = _ejs_string_new_utf8 (json_value_get_string(v)); return EJS_TRUE; case JSONNumber: *rv = NUMBER_TO_EJSVAL(json_value_get_number(v)); return EJS_TRUE; case JSONObject: { JSON_Object *obj = json_value_get_object (v); *rv = _ejs_object_create (_ejs_null); int count = json_object_get_count (obj); for (int i = 0; i < count; i ++) { const char *propkey = json_object_get_name (obj, i); ejsval propval; if (!json_value_to_ejsval (json_object_get_value (obj, propkey), &propval)) return EJS_FALSE; _ejs_object_setprop_utf8 (*rv, propkey, propval); } return EJS_TRUE; } case JSONArray: { JSON_Array *arr = json_value_get_array (v); int count = json_array_get_count (arr); *rv = _ejs_array_new (count, EJS_FALSE); for (int i = 0; i < count; i ++) { ejsval propkey = _ejs_number_new (i); ejsval propval; if (!json_value_to_ejsval (json_array_get_value (arr, i), &propval)) return EJS_FALSE; _ejs_object_setprop (*rv, propkey, propval); } return EJS_TRUE; } case JSONBoolean: *rv = BOOLEAN_TO_EJSVAL(json_value_get_boolean(v)); return EJS_TRUE; case JSONError: EJS_NOT_IMPLEMENTED(); return EJS_FALSE; } }
static ejsval _ejs_DataView_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { if (EJSVAL_IS_UNDEFINED(_this)) { _ejs_log ("DataView called as a function\n"); EJS_NOT_IMPLEMENTED(); } if (argc == 0 || !EJSVAL_IS_ARRAYBUFFER(args[0])) { _ejs_log ("arg0 not an ArrayBuffer object\n"); EJS_NOT_IMPLEMENTED(); } EJSDataView* view = (EJSDataView*)EJSVAL_TO_OBJECT(_this); EJSArrayBuffer* buff = (EJSArrayBuffer*)EJSVAL_TO_OBJECT(args[0]); uint32_t offset; uint32_t len; switch (argc) { case 1: offset = 0; len = buff->size; break; case 2: offset = EJSVAL_TO_NUMBER(args[1]); len = buff->size - offset; break; default: offset = EJSVAL_TO_NUMBER(args[1]); len = EJSVAL_TO_NUMBER(args[2]); } view->buffer = args[0]; view->byteOffset = offset; view->byteLength = len; _ejs_object_define_value_property (_this, _ejs_atom_byteLength, DOUBLE_TO_EJSVAL_IMPL(view->byteLength), EJS_PROP_FLAGS_ENUMERABLE); _ejs_object_define_value_property (_this, _ejs_atom_byteOffset, DOUBLE_TO_EJSVAL_IMPL(view->byteOffset), EJS_PROP_FLAGS_ENUMERABLE); _ejs_object_define_value_property (_this, _ejs_atom_buffer, view->buffer, EJS_PROP_FLAGS_ENUMERABLE); return _this; }
ejsval _ejs_op_rsh (ejsval lhs, ejsval rhs) { if (EJSVAL_IS_NUMBER(lhs)) { if (EJSVAL_IS_NUMBER(rhs)) { return NUMBER_TO_EJSVAL ((int)((int)EJSVAL_TO_NUMBER(lhs) >> (((unsigned int)EJSVAL_TO_NUMBER(rhs)) & 0x1f))); } else { // need to call valueOf() on the object, or convert the string to a number EJS_NOT_IMPLEMENTED(); } }
static ejsval _ejs_RegExp_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { EJSRegExp *re; if (EJSVAL_IS_UNDEFINED(_this)) { // called as a function _this = _ejs_object_new(_ejs_RegExp_prototype, &_ejs_RegExp_specops); } re = (EJSRegExp*)EJSVAL_TO_OBJECT(_this); re->pattern = _ejs_undefined; re->flags = _ejs_undefined; if (argc > 0) re->pattern = args[0]; if (argc > 1) re->flags = args[1]; if (!EJSVAL_IS_STRING(re->pattern)) EJS_NOT_IMPLEMENTED(); EJSPrimString *flat_pattern = _ejs_string_flatten (re->pattern); jschar* chars = flat_pattern->data.flat; const unsigned char* pcre16_tables = pcre16_maketables(); const char *pcre_error; int pcre_erroffset; re->compiled_pattern = pcre16_compile(chars, PCRE_UTF16 | PCRE_NO_UTF16_CHECK, &pcre_error, &pcre_erroffset, pcre16_tables); _ejs_object_define_value_property (_this, _ejs_atom_source, re->pattern, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE); if (EJSVAL_IS_STRING(re->flags)) { EJSPrimString *flat_flags = _ejs_string_flatten(re->flags); chars = flat_flags->data.flat; for (int i = 0; i < flat_flags->length; i ++) { if (chars[i] == 'g' && !re->global) { re->global = EJS_TRUE; continue; } else if (chars[i] == 'i' && !re->ignoreCase) { re->ignoreCase = EJS_TRUE; continue; } else if (chars[i] == 'm' && !re->multiline) { re->multiline = EJS_TRUE; continue; } else if (chars[i] == 'y' && !re->sticky) { re->sticky = EJS_TRUE; continue; } else if (chars[i] == 'u' && !re->unicode) { re->unicode = EJS_TRUE; continue; } _ejs_throw_nativeerror_utf8 (EJS_SYNTAX_ERROR, "Invalid flag supplied to RegExp constructor"); } } return _this; }
ejsval _ejs_op_mod (ejsval lhs, ejsval rhs) { if (EJSVAL_IS_NUMBER(lhs)) { if (EJSVAL_IS_NUMBER(rhs)) { return NUMBER_TO_EJSVAL (fmod(EJSVAL_TO_NUMBER(lhs), EJSVAL_TO_NUMBER(rhs))); } else { // need to call valueOf() on the object, or convert the string to a number EJS_NOT_IMPLEMENTED(); } } else if (EJSVAL_IS_STRING(lhs)) { // string+ with anything we don't implement yet - it will call toString() on objects, and convert a number to a string EJS_NOT_IMPLEMENTED(); } else { // object+... how does js implement this anyway? EJS_NOT_IMPLEMENTED(); } return _ejs_nan; }
// same as SameValue, except in its treatment of +/- 0 EJSBool SameValueZero(ejsval x, ejsval y) { // 1. ReturnIfAbrupt(x). // 2. ReturnIfAbrupt(y). // 3. If Type(x) is different from Type(y), return false. if (EJSVAL_TO_TAG(x) != EJSVAL_TO_TAG(y)) return EJS_FALSE; // 4. If Type(x) is Undefined, return true. if (EJSVAL_IS_UNDEFINED(x)) return EJS_TRUE; // 5. If Type(x) is Null, return true. if (EJSVAL_IS_NULL(x)) return EJS_TRUE; // 6. If Type(x) is Number, then if (EJSVAL_IS_NUMBER(x)) { // a. If x is NaN and y is NaN, return true. if (isnan(EJSVAL_TO_NUMBER(x)) && isnan(EJSVAL_TO_NUMBER(y))) return EJS_TRUE; // b. If x is +0 and y is -0, return true. if (EJSVAL_TO_NUMBER(x) == 0.0 && EJSDOUBLE_IS_NEGZERO(EJSVAL_TO_NUMBER(y))) return EJS_TRUE; // c. If x is -0 and y is +0, return tryue. if (EJSDOUBLE_IS_NEGZERO(EJSVAL_TO_NUMBER(x)) == 0.0 && EJSVAL_TO_NUMBER(y) == 0) return EJS_TRUE; // d. If x is the same Number value as y, return true. if (EJSVAL_TO_NUMBER(x) == EJSVAL_TO_NUMBER(y)) return EJS_TRUE; // e. Return false. return EJS_FALSE; } // 7. If Type(x) is String, then if (EJSVAL_IS_STRING(x)) { // a. If x and y are exactly the same sequence of code units (same length and same code units in corresponding positions) return true; // otherwise, return false. if (EJSVAL_TO_STRLEN(x) != EJSVAL_TO_STRLEN(y)) return EJS_FALSE; // XXX there is doubtless a more efficient way to compare two ropes, but we convert but to flat strings for now. return ucs2_strcmp (EJSVAL_TO_FLAT_STRING(x), EJSVAL_TO_FLAT_STRING(y)) ? EJS_FALSE : EJS_TRUE; } // 8. If Type(x) is Boolean, then if (EJSVAL_IS_BOOLEAN(x)) { // a. If x and y are both true or both false, then return true; otherwise, return false. return EJSVAL_TO_BOOLEAN(x) == EJSVAL_TO_BOOLEAN(y) ? EJS_TRUE : EJS_FALSE; } // 9. If Type(x) is Symbol, then if (EJSVAL_IS_SYMBOL(x)) { // a. If x and y are both the same Symbol value, then return true; otherwise, return false. EJS_NOT_IMPLEMENTED(); } // 10. Return true if x and y are the same Object value. Otherwise, return false. return EJSVAL_EQ(x, y); }
static ejsval Module_impl (ejsval env, ejsval _this, int argc, ejsval *args) { if (EJSVAL_IS_UNDEFINED(_this)) { // called as a function EJS_NOT_IMPLEMENTED(); } else { Module* module = ((Module*)EJSVAL_TO_OBJECT(_this)); REQ_UTF8_ARG(0, name); module->llvm_module = new llvm::Module(name, llvm::getGlobalContext()); return _this; } }
// ECMA262: 26.1.12 Reflect.preventExtensions ( target ) static ejsval _ejs_Reflect_preventExtensions (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { ejsval target = _ejs_undefined; if (argc > 0) target = args[0]; // 1. Let obj be ToObject(target). // 2. ReturnIfAbrupt(obj). ejsval obj = ToObject(target); // 3. Return the result of calling the [[PreventExtensions]] internal method of obj. EJS_NOT_IMPLEMENTED(); return _ejs_null; }
EJSBool ToEJSBool(ejsval exp) { if (EJSVAL_IS_NULL(exp) || EJSVAL_IS_UNDEFINED(exp)) return EJS_FALSE; else if (EJSVAL_IS_BOOLEAN(exp)) return EJSVAL_TO_BOOLEAN(exp); else if (EJSVAL_IS_NUMBER(exp)) return EJSVAL_TO_NUMBER(exp) != 0; else if (EJSVAL_IS_STRING(exp)) return EJSVAL_TO_STRLEN(exp) != 0; else if (EJSVAL_IS_OBJECT(exp)) return EJS_TRUE; else EJS_NOT_IMPLEMENTED(); }
static ejsval DIBuilder_impl (ejsval env, ejsval _this, int argc, ejsval *args) { if (EJSVAL_IS_UNDEFINED(_this)) { // called as a function EJS_NOT_IMPLEMENTED(); } else { DIBuilder* dib = ((DIBuilder*)EJSVAL_TO_OBJECT(_this)); REQ_LLVM_MODULE_ARG(0, module); dib->llvm_dibuilder = new llvm::DIBuilder (*module); return _this; } }
static ejsval BasicBlock_impl (ejsval env, ejsval _this, int argc, ejsval *args) { if (EJSVAL_IS_UNDEFINED(_this)) { // called as a function EJS_NOT_IMPLEMENTED(); } else { BasicBlock* bb = ((BasicBlock*)EJSVAL_TO_OBJECT(_this)); REQ_UTF8_ARG(0, name); REQ_LLVM_FUN_ARG(1, fun); bb->llvm_bb = llvm::BasicBlock::Create(llvm::getGlobalContext(), name, fun); free (name); return _this; } }
// ES6 Draft rev32 Feb 2, 2015 // 9.2.3 // [[Construct]] ( argumentsList, newTarget) ejsval _ejs_construct_closure (ejsval _closure, ejsval newTarget, uint32_t argc, ejsval* args) { // 1. Assert: F is an ECMAScript function object. EJSFunction* F = (EJSFunction*)EJSVAL_TO_OBJECT(_closure); // 2. Assert: Type(newTarget) is Object. // 3. Let callerContext be the running execution context. // 4. Let kind be F’s [[ConstructorKind]] internal slot. EJSConstructorKind kind = F->constructor_kind; ejsval thisArgument = _ejs_undefined; // 5. If kind is "base", then if (kind == CONSTRUCTOR_KIND_BASE) { // a. Let thisArgument be OrdinaryCreateFromConstructor(newTarget, "%ObjectPrototype%"). // b. ReturnIfAbrupt(thisArgument). } // 6. Let calleeContext be PrepareForOrdinaryCall(F, newTarget). // 7. ReturnIfAbrupt(calleeContext). // 8. Assert: calleeContext is now the active execution context. // 9. If kind is "base", then if (kind == CONSTRUCTOR_KIND_BASE) { // a. Let status be OrdinaryCallBindThis(F, calleeContext, thisArgument). // b. If status is an abrupt completion, then // i. Remove calleeContext from the execution context stack and restore callerContext as the running execution context. // ii. Return status. } // 10. Let constructorEnv be the LexicalEnvironment of calleeContext. // 11. Let envRec be constructorEnv’s environment record. // 12. Let result be OrdinaryCallEvaluateBody(F, calleeContext, argumentsList). ejsval result = _ejs_invoke_closure(_closure, thisArgument, argc, args); // 13. Remove calleeContext from the execution context stack and restore callerContext as the running execution context. // 14. If result.[[type]] is return, then // a. If Type(result.[[value]]) is Object, return NormalCompletion(result.[[value]]). if (EJSVAL_IS_OBJECT(result)) return result; // b. If kind is "base", return NormalCompletion(thisArgument). if (kind == CONSTRUCTOR_KIND_BASE) return thisArgument; // c. Throw a TypeError exception. _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "9.2.3/14.c"); // 15. ReturnIfAbrupt(result). // 16. Return the result of calling the GetThisBinding concrete method of envRec’s with no arguments EJS_NOT_IMPLEMENTED(); }
static ejsval _ejs_ArrayBuffer_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { if (EJSVAL_IS_UNDEFINED(_this)) { printf ("ArrayBuffer called as a function\n"); EJS_NOT_IMPLEMENTED(); } uint32_t size = 0; if (argc > 0) size = ToUint32(args[0]); EJSArrayBuffer* buffer = (EJSArrayBuffer*)EJSVAL_TO_OBJECT(_this); buffer->dependent = EJS_FALSE; buffer->size = size; if (size) buffer->data.alloced_buf = calloc (1, size); return _this; }
static ejsval GlobalVariable_impl (ejsval env, ejsval _this, int argc, ejsval *args) { if (EJSVAL_IS_UNDEFINED(_this)) { // called as a function EJS_NOT_IMPLEMENTED(); } else { GlobalVariable* gv = (GlobalVariable*)EJSVAL_TO_OBJECT(_this); REQ_LLVM_MODULE_ARG(0, module); REQ_LLVM_TYPE_ARG(1, type); REQ_UTF8_ARG(2, name); REQ_LLVM_CONST_ARG(3, init); gv->llvm_global = new ::llvm::GlobalVariable(*module, type, false, llvm::GlobalValue::InternalLinkage, init, name); free(name); return _this; } }
static EJS_NATIVE_FUNC(GlobalVariable_impl) { if (EJSVAL_IS_UNDEFINED(newTarget)) { // called as a function EJS_NOT_IMPLEMENTED(); } else { ejsval O = OrdinaryCreateFromConstructor(newTarget, _ejs_GlobalVariable_prototype, &_ejs_GlobalVariable_specops); *_this = O; GlobalVariable* gv = (GlobalVariable*)EJSVAL_TO_OBJECT(O); REQ_LLVM_MODULE_ARG(0, module); REQ_LLVM_TYPE_ARG(1, type); REQ_UTF8_ARG(2, name); REQ_NULLABLE_LLVM_CONST_ARG(3, init); REQ_BOOL_ARG(4, visible); gv->llvm_global = new ::llvm::GlobalVariable(*module, type, false, visible ? llvm::GlobalValue::ExternalLinkage : llvm::GlobalValue::InternalLinkage, init, name); return *_this; } }
ejsval _ejs_unhandledException(ejsval env, ejsval _this, uint32_t argc, ejsval* args) { ejsval exc = _ejs_undefined; if (argc > 0) exc = args[0]; printf ("unhandled exception: "); if (EJSVAL_IS_UNDEFINED(exc)) { EJS_NOT_IMPLEMENTED(); } else { ejsval str = ToString(exc); printf ("%s\n", _ejs_string_to_utf8(_ejs_string_flatten(str))); } exit(-1); return _ejs_undefined; }
ejsval ToNumber(ejsval exp) { if (EJSVAL_IS_NUMBER(exp)) return exp; else if (EJSVAL_IS_BOOLEAN(exp)) return EJSVAL_TO_BOOLEAN(exp) ? _ejs_one : _ejs_zero; else if (EJSVAL_IS_STRING(exp)) { char* num_utf8 = ucs2_to_utf8(EJSVAL_TO_FLAT_STRING(exp)); char *endptr; double d = strtod(num_utf8, &endptr); if (*endptr != '\0') return _ejs_nan; ejsval rv = NUMBER_TO_EJSVAL(d); // XXX NaN free (num_utf8); return rv; } else if (EJSVAL_IS_UNDEFINED(exp)) return _ejs_nan; else if (EJSVAL_IS_OBJECT(exp)) { if (EJSVAL_IS_DATE(exp)) { return NUMBER_TO_EJSVAL(_ejs_date_get_time ((EJSDate*)EJSVAL_TO_OBJECT(exp))); } else if (EJSVAL_IS_ARRAY(exp)) { int len = EJS_ARRAY_LEN(exp); if (len == 0) return _ejs_zero; else if (len > 1) return _ejs_nan; else { // XXX we need to support sparse arrays here too EJS_ASSERT (EJSVAL_IS_DENSE_ARRAY(exp)); return ToNumber(EJS_DENSE_ARRAY_ELEMENTS(exp)[0]); } } else return _ejs_nan; } else EJS_NOT_IMPLEMENTED(); }
static ejsval _ejs_Function_prototype_create(ejsval env, ejsval _this, uint32_t argc, ejsval* args) { ejsval F = _this; if (!EJSVAL_IS_CONSTRUCTOR(F)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "'this' in Function.prototype[Symbol.create] is not a constructor"); EJSObject* F_ = EJSVAL_TO_OBJECT(F); ejsval proto = OP(F_,Get)(F, _ejs_atom_prototype, F); if (EJSVAL_IS_UNDEFINED(proto)) { proto = _ejs_Function_prototype; } if (!EJSVAL_IS_OBJECT(proto)) { EJS_NOT_IMPLEMENTED(); // cross-realm doesn't exist in ejs yet } EJSObject* obj = (EJSObject*)_ejs_gc_new (EJSObject); _ejs_init_object (obj, proto, &_ejs_Object_specops); return OBJECT_TO_EJSVAL(obj); }
ejsval ToObject(ejsval exp) { if (EJSVAL_IS_BOOLEAN(exp)) { ejsval new_boolean = _ejs_object_new (_ejs_Boolean_proto, &_ejs_Boolean_specops); _ejs_invoke_closure (_ejs_Boolean, new_boolean, 1, &exp); return new_boolean; } else if (EJSVAL_IS_NUMBER(exp)) { ejsval new_number = _ejs_object_new (_ejs_Number_proto, &_ejs_Number_specops); _ejs_invoke_closure (_ejs_Number, new_number, 1, &exp); return new_number; } else if (EJSVAL_IS_STRING(exp)) { ejsval new_str = _ejs_object_new (_ejs_String_prototype, &_ejs_String_specops); _ejs_invoke_closure (_ejs_String, new_str, 1, &exp); return new_str; } else if (EJSVAL_IS_UNDEFINED(exp)) return exp; // XXX else if (EJSVAL_IS_OBJECT(exp)) return exp; else EJS_NOT_IMPLEMENTED(); }
ejsval _ejs_op_typeof (ejsval exp) { if (EJSVAL_IS_NULL(exp)) return _ejs_atom_null; else if (EJSVAL_IS_BOOLEAN(exp)) return _ejs_atom_boolean; else if (EJSVAL_IS_STRING(exp)) return _ejs_atom_string; else if (EJSVAL_IS_SYMBOL(exp)) return _ejs_atom_symbol; else if (EJSVAL_IS_NUMBER(exp)) return _ejs_atom_number; else if (EJSVAL_IS_UNDEFINED(exp)) return _ejs_atom_undefined; else if (EJSVAL_IS_OBJECT(exp)) { if (EJSVAL_IS_FUNCTION(exp)) return _ejs_atom_function; else return _ejs_atom_object; } else EJS_NOT_IMPLEMENTED(); }
static ejsval _ejs_Reflect_enumerate (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { EJS_NOT_IMPLEMENTED(); }
static ejsval _ejs_Reflect_deleteProperty (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { EJS_NOT_IMPLEMENTED(); }
static ejsval _ejs_Reflect_construct (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { EJS_NOT_IMPLEMENTED(); }