static void _ejs_function_init_proto() { _ejs_gc_add_root (&_ejs_Function_prototype); // Function.prototype = function () { return undefined; } EJSFunction* proto = _ejs_gc_new(EJSFunction); _ejs_Function_prototype = OBJECT_TO_EJSVAL(proto); _ejs_init_object ((EJSObject*)proto, _ejs_Object_prototype, &_ejs_Function_specops); proto->func = _ejs_Function_empty; proto->env = _ejs_null; _ejs_object_define_value_property (OBJECT_TO_EJSVAL(proto), _ejs_atom_name, _ejs_atom_empty, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE); }
ejsval _ejs_function_new_native (ejsval env, ejsval name, EJSClosureFunc func) { EJSFunction *rv = _ejs_gc_new(EJSFunction); _ejs_init_object ((EJSObject*)rv, _ejs_Function__proto__, &_ejs_Function_specops); rv->func = func; rv->env = env; ejsval fun = OBJECT_TO_EJSVAL(rv); _ejs_object_define_value_property (fun, _ejs_atom_name, name, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE); return OBJECT_TO_EJSVAL(rv); }
// ECMA262 25.4.4.6 Promise [ @@create ] ( ) static ejsval _ejs_Promise_create (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { // 1. Let F be the this value ejsval F = _this; // 2. Return AllocatePromise(F). // 1. Let obj be OrdinaryCreateFromConstructor(constructor, "%PromisePrototype%", ([[PromiseState]], [[PromiseConstructor]], [[PromiseResult]], [[PromiseFulfillReactions]], [[PromiseRejectReactions]]) ). ejsval proto = _ejs_undefined; if (!EJSVAL_IS_UNDEFINED(F)) { if (!EJSVAL_IS_CONSTRUCTOR(F)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "'this' in Promise[Symbol.create] is not a constructor"); EJSObject* F_ = EJSVAL_TO_OBJECT(F); proto = OP(F_,Get)(F, _ejs_atom_prototype, F); } if (EJSVAL_IS_UNDEFINED(proto)) proto = _ejs_Promise_prototype; EJSObject* obj = (EJSObject*)_ejs_gc_new (EJSPromise); _ejs_init_object (obj, proto, &_ejs_Promise_specops); // 2. Set the value of obj’s [[PromiseConstructor]] internal slot to constructor. ((EJSPromise*)obj)->constructor = F; // 3. Return obj. return OBJECT_TO_EJSVAL(obj); }
ejsval _ejs_nativeerror_new (EJSNativeErrorType err_type, ejsval msg) { EJSObject* exc_obj = _ejs_gc_new (EJSObject); ejsval proto; switch (err_type) { case EJS_ERROR: proto = _ejs_Error_prototype; break; case EJS_EVAL_ERROR: proto = _ejs_EvalError_prototype; break; case EJS_RANGE_ERROR: proto = _ejs_RangeError_prototype; break; case EJS_REFERENCE_ERROR: proto = _ejs_ReferenceError_prototype; break; case EJS_SYNTAX_ERROR: proto = _ejs_SyntaxError_prototype; break; case EJS_TYPE_ERROR: proto = _ejs_TypeError_prototype; break; case EJS_URI_ERROR: proto = _ejs_URIError_prototype; break; } _ejs_init_object (exc_obj, proto, &_ejs_Error_specops); ejsval exc = OBJECT_TO_EJSVAL(exc_obj); switch (err_type) { case EJS_ERROR: _ejs_Error_impl (_ejs_null, exc, 1, &msg); break; case EJS_EVAL_ERROR: _ejs_EvalError_impl (_ejs_null, exc, 1, &msg); break; case EJS_RANGE_ERROR: _ejs_RangeError_impl (_ejs_null, exc, 1, &msg); break; case EJS_REFERENCE_ERROR: _ejs_ReferenceError_impl (_ejs_null, exc, 1, &msg); break; case EJS_SYNTAX_ERROR: _ejs_SyntaxError_impl (_ejs_null, exc, 1, &msg); break; case EJS_TYPE_ERROR: _ejs_TypeError_impl (_ejs_null, exc, 1, &msg); break; case EJS_URI_ERROR: _ejs_URIError_impl (_ejs_null, exc, 1, &msg); break; } return exc; }
ejsval _ejs_set_iterator_new (ejsval set, EJSSetIteratorKind kind) { /* 1. If Type(set) is not Object, throw a TypeError exception. */ if (!EJSVAL_IS_OBJECT(set)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "set is not a Object"); /* 2. If set does not have a [[SetData]] internal slot throw a TypeError exception. */ if (!EJSVAL_IS_SET(set)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "value is not a Set"); /* 3. If set’s [[SetData]] internal slot is undefined, then throw a TypeError exception. */ /* 4. Let iterator be the result of ObjectCreate(%SetIteratorPrototype%, * ([[IteratedSet]], [[SetNextIndex]], [[SetIterationKind]])). */ EJSSetIterator *iter = _ejs_gc_new (EJSSetIterator); _ejs_init_object ((EJSObject*) iter, _ejs_SetIterator_prototype, &_ejs_SetIterator_specops); /* 5. Set iterator’s [[IteratedSet]] internal slot to set. */ iter->iterated = set; /* 6. Set iterator’s [[SetNextIndex]] internal slot to 0. */ iter->next_index = 0; /* 7. Set iterator’s [[SetIterationKind]] internal slot to kind. */ iter->kind = kind; /* 8. Return iterator */ return OBJECT_TO_EJSVAL(iter); }
ejsval GlobalVariable_new(llvm::GlobalVariable* llvm_global) { EJSObject* result = GlobalVariable_alloc_instance(); _ejs_init_object (result, _ejs_GlobalVariable_proto, NULL); ((GlobalVariable*)result)->llvm_global = llvm_global; return OBJECT_TO_EJSVAL(result); }
ejsval _ejs_iterator_wrapper_new (ejsval iterator) { EJSIteratorWrapper* rv = _ejs_gc_new (EJSIteratorWrapper); _ejs_init_object ((EJSObject*)rv, _ejs_IteratorWrapper_prototype, &_ejs_IteratorWrapper_specops); rv->iterator = iterator; return OBJECT_TO_EJSVAL(rv); }
ejsval FunctionType_new(llvm::FunctionType* llvm_ty) { EJSObject* result = FunctionType_alloc_instance(); _ejs_init_object (result, _ejs_FunctionType_proto, NULL); ((FunctionType*)result)->type = llvm_ty; return OBJECT_TO_EJSVAL(result); }
ejsval _ejs_set_new () { EJSSet *set = _ejs_gc_new (EJSSet); _ejs_init_object ((EJSObject*)set, _ejs_Set_prototype, &_ejs_Set_specops); return OBJECT_TO_EJSVAL(set); }
ejsval StructType_new(llvm::StructType* llvm_ty) { EJSObject* result = StructType_alloc_instance(); _ejs_init_object (result, _ejs_StructType_proto, NULL); ((StructType*)result)->type = llvm_ty; return OBJECT_TO_EJSVAL(result); }
ejsval Type_new(llvm::Type* llvm_ty) { EJSObject* result = Type_alloc_instance(); _ejs_init_object (result, _ejs_Type_prototype, NULL); ((Type*)result)->type = llvm_ty; return OBJECT_TO_EJSVAL(result); }
ejsval _ejs_symbol_new_object(ejsval symbol_data) { EJSSymbol *rv = _ejs_gc_new(EJSSymbol); _ejs_init_object ((EJSObject*)rv, _ejs_Symbol_prototype, &_ejs_Symbol_specops); rv->primSymbol = symbol_data; return OBJECT_TO_EJSVAL(rv); }
ejsval _ejs_regexp_new (ejsval pattern, ejsval flags) { EJSRegExp* rv = _ejs_gc_new(EJSRegExp); _ejs_init_object ((EJSObject*)rv, _ejs_RegExp_prototype, &_ejs_RegExp_specops); ejsval args[2] = { pattern, flags }; return _ejs_RegExp_impl (_ejs_null, OBJECT_TO_EJSVAL(rv), 2, args); }
ejsval _ejs_arguments_new (int numElements, ejsval* args) { size_t value_size = sizeof(EJSArguments) + numElements * sizeof(ejsval); EJSBool ool_buffer = EJS_FALSE; if (value_size > 2048) { value_size = sizeof(EJSArguments); ool_buffer = EJS_TRUE; } EJSArguments* arguments = _ejs_gc_new_obj(EJSArguments, value_size); _ejs_init_object ((EJSObject*)arguments, _ejs_Arguments__proto__, &_ejs_Arguments_specops); ejsval O = OBJECT_TO_EJSVAL((EJSObject*)arguments); // 7. Perform DefinePropertyOrThrow(obj, @@iterator, PropertyDescriptor {[[Value]]:%ArrayProto_values%, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true}) ejsval _values = _ejs_function_new_native (_ejs_null, _ejs_atom_values, _ejs_Array_prototype_values); _ejs_object_define_value_property (O, _ejs_Symbol_iterator, _values, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_WRITABLE | EJS_PROP_CONFIGURABLE); ejsval thrower = _ejs_function_new_native (_ejs_null, _ejs_undefined, ThrowTypeError); // 8. Perform DefinePropertyOrThrow(obj, "caller", PropertyDescriptor {[[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}). _ejs_object_define_accessor_property(O, _ejs_atom_caller, thrower, thrower, EJS_PROP_FLAGS_GETTER_SET | EJS_PROP_FLAGS_SETTER_SET | EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE); // 9. Perform DefinePropertyOrThrow(obj, "callee", PropertyDescriptor {[[Get]]: %ThrowTypeError%, [[Set]]: %ThrowTypeError%, [[Enumerable]]: false, [[Configurable]]: false}). _ejs_object_define_accessor_property(O, _ejs_atom_callee, thrower, thrower, EJS_PROP_FLAGS_GETTER_SET | EJS_PROP_FLAGS_SETTER_SET | EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE); arguments->argc = numElements; if (ool_buffer) { arguments->args = (ejsval*)calloc(numElements, sizeof (ejsval)); EJS_ARGUMENTS_SET_HAS_OOL_BUFFER(arguments); } else { arguments->args = (ejsval*)((char*)arguments + sizeof(EJSArguments)); } memmove (arguments->args, args, sizeof(ejsval) * numElements); return OBJECT_TO_EJSVAL(arguments); }
ejsval _ejs_arraybuffer_new (int size) { EJSArrayBuffer *rv = _ejs_gc_new(EJSArrayBuffer); _ejs_init_object ((EJSObject*)rv, _ejs_ArrayBuffer_prototype, &_ejs_ArrayBuffer_specops); rv->dependent = EJS_FALSE; rv->size = size; if (size) rv->data.alloced_buf = calloc(1, size); return OBJECT_TO_EJSVAL(rv); }
static ejsval Module_create (ejsval env, ejsval _this, int argc, ejsval *args) { ejsval F = _this; if (!EJSVAL_IS_CONSTRUCTOR(F)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "'this' in Module[Symbol.create] is not a constructor"); EJSObject* F_ = EJSVAL_TO_OBJECT(F); // 2. Let obj be the result of calling OrdinaryCreateFromConstructor(F, "%DatePrototype%", ([[DateData]]) ). ejsval proto = OP(F_,Get)(F, _ejs_atom_prototype, F); if (EJSVAL_IS_UNDEFINED(proto)) proto = _ejs_Module_prototype; EJSObject* obj = (EJSObject*)_ejs_gc_new (Module); _ejs_init_object (obj, proto, &_ejs_Module_specops); return OBJECT_TO_EJSVAL(obj); }
ejsval _ejs_function_new_without_proto (ejsval env, ejsval name, EJSClosureFunc func) { EJSFunction *rv = _ejs_gc_new(EJSFunction); _ejs_init_object ((EJSObject*)rv, _ejs_Function_prototype, &_ejs_Function_specops); rv->func = func; rv->env = env; rv->is_constructor = EJS_TRUE; ejsval fun = OBJECT_TO_EJSVAL(rv); _ejs_object_define_value_property (fun, _ejs_atom_name, name, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE); return fun; }
ejsval _ejs_arraybuffer_new_slice (ejsval bufferval, int offset, int size) { EJSArrayBuffer* rv = _ejs_gc_new(EJSArrayBuffer); EJSArrayBuffer* buffer = (EJSArrayBuffer*)EJSVAL_TO_OBJECT(bufferval); _ejs_init_object ((EJSObject*)rv, _ejs_ArrayBuffer_prototype, &_ejs_ArrayBuffer_specops); rv->dependent = EJS_TRUE; rv->data.dependent.offset = MIN(buffer->size, offset); rv->data.dependent.buf = bufferval; rv->size = size; if (rv->size + rv->data.dependent.offset > buffer->size) rv->size = buffer->size - offset; return OBJECT_TO_EJSVAL(rv); }
ejsval _ejs_function_new_utf8_with_proto (ejsval env, const char* name, EJSClosureFunc func, ejsval prototype) { ejsval function_name = _ejs_string_new_utf8 (name); EJSFunction *rv = _ejs_gc_new(EJSFunction); _ejs_init_object ((EJSObject*)rv, _ejs_Function_prototype, &_ejs_Function_specops); rv->func = func; rv->env = env; ejsval fun = OBJECT_TO_EJSVAL(rv); _ejs_object_define_value_property (fun, _ejs_atom_name, function_name, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE); _ejs_object_define_value_property (fun, _ejs_atom_prototype, prototype, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_CONFIGURABLE | EJS_PROP_WRITABLE); return fun; }
static ejsval FunctionType_get (ejsval env, ejsval _this, int argc, ejsval *args) { REQ_LLVM_TYPE_ARG(0, returnType); REQ_ARRAY_ARG(1, argTypes); std::vector<llvm::Type*> arg_types; for (int i = 0; i < EJSARRAY_LEN(argTypes); i ++) { arg_types.push_back (Type_GetLLVMObj(EJSDENSEARRAY_ELEMENTS(argTypes)[i])); } llvm::FunctionType *FT = llvm::FunctionType::get(returnType, arg_types, false); EJSObject* result = FunctionType_alloc_instance(); _ejs_init_object (result, _ejs_FunctionType_proto, NULL); ((FunctionType*)result)->type = FT; return OBJECT_TO_EJSVAL(result); }
ejsval _ejs_typedarray_new (EJSTypedArrayType element_type, uint32_t length) { int size = length * _ejs_typed_array_elsizes[element_type]; ejsval buffer = _ejs_arraybuffer_new (size); EJSTypedArray *rv = _ejs_gc_new(EJSTypedArray); _ejs_init_object ((EJSObject*)rv, _ejs_typed_array_protos[element_type], _ejs_typed_array_specops[element_type]); rv->buffer = buffer; rv->element_type = element_type; rv->length = length; rv->byteOffset = 0; rv->byteLength = size; return OBJECT_TO_EJSVAL(rv); }
ejsval _ejs_function_new (ejsval env, ejsval name, EJSClosureFunc func) { EJSFunction *rv = _ejs_gc_new(EJSFunction); _ejs_init_object ((EJSObject*)rv, _ejs_Function__proto__, &_ejs_Function_specops); rv->func = func; rv->env = env; ejsval fun = OBJECT_TO_EJSVAL(rv); // ECMA262: 15.3.2.1 ejsval fun_proto = _ejs_object_new (_ejs_Object_prototype, &_ejs_Object_specops); _ejs_object_define_value_property (fun, _ejs_atom_prototype, fun_proto, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_CONFIGURABLE | EJS_PROP_WRITABLE); _ejs_object_define_value_property (fun_proto, _ejs_atom_constructor, fun, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_CONFIGURABLE | EJS_PROP_WRITABLE); _ejs_object_define_value_property (fun, _ejs_atom_name, name, EJS_PROP_NOT_ENUMERABLE | EJS_PROP_NOT_CONFIGURABLE | EJS_PROP_NOT_WRITABLE); return fun; }
ejsval _ejs_generator_new (ejsval generator_body) { EJSGenerator* rv = _ejs_gc_new(EJSGenerator); _ejs_init_object ((EJSObject*)rv, _ejs_Generator_prototype, &_ejs_Generator_specops); rv->body = generator_body; rv->started = EJS_FALSE; rv->yielded_value = _ejs_undefined; rv->sent_value = _ejs_undefined; rv->stack = malloc(GENERATOR_STACK_SIZE); getcontext(&rv->generator_context); rv->generator_context.uc_stack.ss_sp = rv->stack; rv->generator_context.uc_stack.ss_size = GENERATOR_STACK_SIZE; rv->generator_context.uc_link = &rv->caller_context; makecontext(&rv->generator_context, (void(*)(void))_ejs_generator_start, 1, rv); memset(&rv->caller_context, 0, sizeof(rv->caller_context)); return OBJECT_TO_EJSVAL(rv); }
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); }
static ejsval _ejs_RegExp_create (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { // 1. Let F be the this value. ejsval F = _this; if (!EJSVAL_IS_CONSTRUCTOR(F)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "'this' in RegExp[Symbol.create] is not a constructor"); EJSObject* F_ = EJSVAL_TO_OBJECT(F); // 2. Let obj be the result of calling OrdinaryCreateFromConstructor(constructor, "%RegExpPrototype%", ( [[RegExpMatcher]], [[OriginalSource]], [[OriginalFlags]])). ejsval proto = OP(F_,Get)(F, _ejs_atom_prototype, F); if (EJSVAL_IS_UNDEFINED(proto)) proto = _ejs_RegExp_prototype; EJSRegExp* re = (EJSRegExp*)_ejs_gc_new (EJSRegExp); _ejs_init_object ((EJSObject*)re, proto, &_ejs_RegExp_specops); re->pattern = _ejs_undefined; re->flags = _ejs_undefined; return OBJECT_TO_EJSVAL((EJSObject*)re); }
// ES6: 23.2.1.1 Set ( [ iterable ] ) static ejsval _ejs_Set_impl (ejsval env, ejsval _this, uint32_t argc, ejsval *args) { // 1. Let set be the this value. ejsval set = _this; if (EJSVAL_IS_UNDEFINED(set)) { EJSObject* obj = (EJSObject*)_ejs_gc_new(EJSSet); _ejs_init_object (obj, _ejs_Set_prototype, &_ejs_Set_specops); set = OBJECT_TO_EJSVAL(obj); } // 2. If Type(set) is not Object then, throw a TypeError exception. if (!EJSVAL_IS_OBJECT(set)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set constructor called with non-object this."); // 3. If set does not have a [[SetData]] internal slot, then throw a TypeError exception. if (!EJSVAL_IS_SET(set)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set constructor called with non-Set this."); EJSSet* _set = EJSVAL_TO_SET(set); // 4. If set’s [[SetData]] internal slot is not undefined, then throw a TypeError exception. if (_set->head_insert) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set constructor called with an already initialized Set"); // 5. If iterable is not present, let iterable be undefined. ejsval iterable = _ejs_undefined; if (argc > 0) iterable = args[0]; ejsval iter = _ejs_undefined; ejsval adder = _ejs_undefined; // 6. If iterable is either undefined or null, then let iter be undefined. // 7. Else, if (!EJSVAL_IS_UNDEFINED(iterable) && !EJSVAL_IS_NULL(iterable)) { // a. Let iter be the result of GetIterator(iterable). // b. ReturnIfAbrupt(iter). iter = GetIterator (iterable, _ejs_undefined); // c. Let adder be the result of Get(set, "add"). // d. ReturnIfAbrupt(adder). adder = Get (set, _ejs_atom_add); // e. If IsCallable(adder) is false, throw a TypeError Exception. if (!EJSVAL_IS_CALLABLE(adder)) _ejs_throw_nativeerror_utf8 (EJS_TYPE_ERROR, "Set.prototype.add is not a function"); } // 8. If the value of sets’s [[SetData]] internal slot is not undefined, then throw a TypeError exception. // 9. Assert: set has not been reentrantly initialized. // 10. Set set’s [[SetData]] internal slot to a new empty List. // 11. If iter is undefined, then return set. if (EJSVAL_IS_UNDEFINED(iter)) return set; // 12. Repeat for (;;) { // a. Let next be the result of IteratorStep(iter). // b. ReturnIfAbrupt(next). ejsval next = IteratorStep (iter); // c. If next is false, then return set. if (!EJSVAL_TO_BOOLEAN(next)) return set; // d. Let nextValue be IteratorValue(next). // e. ReturnIfAbrupt(nextValue). ejsval nextValue = IteratorValue (next); // f. Let status be the result of calling the [[Call]] internal method of adder with set as thisArgument // and a List whose sole element is nextValue as argumentsList. // g. ReturnIfAbrupt(status). _ejs_invoke_closure (adder, set, 1, &nextValue); } return set; }