public unsafe object EvalMain(byte[] source, string module_id, string fullPath, Type expectedReturnType) { var tagValue = ScriptRuntime.TryReadByteCodeTagValue(source); if (tagValue == ScriptRuntime.BYTECODE_ES6_MODULE_TAG) { throw new Exception("es6 module bytecode as main is unsupported"); } object csValue = null; var dirname = PathUtils.GetDirectoryName(module_id); var filename_bytes = TextUtils.GetNullTerminatedBytes(module_id); var module_id_atom = GetAtom(module_id); var dirname_atom = GetAtom(dirname); var full_path_atom = GetAtom(fullPath); var exports_obj = JSApi.JS_NewObject(_ctx); var require_obj = JSApi.JS_DupValue(_ctx, _require); var module_obj = _new_commonjs_script_module(null, module_id, fullPath, exports_obj, false); var module_id_obj = JSApi.JS_AtomToString(_ctx, module_id_atom); var filename_obj = JSApi.JS_AtomToString(_ctx, full_path_atom); var dirname_obj = JSApi.JS_AtomToString(_ctx, dirname_atom); var require_argv = new JSValue[5] { exports_obj, require_obj, module_obj, filename_obj, dirname_obj }; JSApi.JS_SetProperty(_ctx, require_obj, GetAtom("moduleId"), JSApi.JS_DupValue(_ctx, module_id_obj)); JSApi.JS_SetProperty(_ctx, require_obj, GetAtom("main"), JSApi.JS_DupValue(_ctx, module_obj)); if (tagValue == ScriptRuntime.BYTECODE_COMMONJS_MODULE_TAG) { // bytecode fixed(byte *intput_ptr = source) { var bytecodeFunc = JSApi.JS_ReadObject(_ctx, intput_ptr + sizeof(uint), source.Length - sizeof(uint), JSApi.JS_READ_OBJ_BYTECODE); if (bytecodeFunc.tag == JSApi.JS_TAG_FUNCTION_BYTECODE) { var func_val = JSApi.JS_EvalFunction(_ctx, bytecodeFunc); // it's CallFree (bytecodeFunc) if (JSApi.JS_IsFunction(_ctx, func_val) != 1) { JSApi.JS_FreeValue(_ctx, func_val); FreeValues(require_argv); throw new Exception("failed to eval bytecode module"); } var rval = JSApi.JS_Call(_ctx, func_val, JSApi.JS_UNDEFINED); JSApi.JS_FreeValue(_ctx, func_val); if (rval.IsException()) { _ctx.print_exception(); JSApi.JS_FreeValue(_ctx, rval); FreeValues(require_argv); throw new Exception("failed to eval bytecode module"); } // success Values.js_get_var(_ctx, rval, expectedReturnType, out csValue); JSApi.JS_FreeValue(_ctx, rval); JSApi.JS_SetProperty(_ctx, module_obj, GetAtom("loaded"), JSApi.JS_NewBool(_ctx, true)); FreeValues(require_argv); return(csValue); } JSApi.JS_FreeValue(_ctx, bytecodeFunc); FreeValues(require_argv); throw new Exception("failed to eval bytecode module"); } } else { // source var input_bytes = TextUtils.GetShebangNullTerminatedCommonJSBytes(source); fixed(byte *input_ptr = input_bytes) fixed(byte *resolved_id_ptr = filename_bytes) { var input_len = (size_t)(input_bytes.Length - 1); var func_val = JSApi.JS_Eval(_ctx, input_ptr, input_len, resolved_id_ptr, JSEvalFlags.JS_EVAL_TYPE_GLOBAL | JSEvalFlags.JS_EVAL_FLAG_STRICT); if (func_val.IsException()) { FreeValues(require_argv); _ctx.print_exception(); throw new Exception("failed to eval module"); } if (JSApi.JS_IsFunction(_ctx, func_val) == 1) { var rval = JSApi.JS_Call(_ctx, func_val, JSApi.JS_UNDEFINED, require_argv.Length, require_argv); if (rval.IsException()) { JSApi.JS_FreeValue(_ctx, func_val); FreeValues(require_argv); _ctx.print_exception(); throw new Exception("failed to eval module"); } Values.js_get_var(_ctx, rval, expectedReturnType, out csValue); JSApi.JS_FreeValue(_ctx, rval); } JSApi.JS_FreeValue(_ctx, func_val); JSApi.JS_SetProperty(_ctx, module_obj, GetAtom("loaded"), JSApi.JS_NewBool(_ctx, true)); FreeValues(require_argv); return(csValue); } } }
// this method will consume the module_obj refcount public unsafe JSValue LoadModuleFromSource(byte[] source, string resolved_id, JSValue module_obj) { var context = this; var ctx = _ctx; var dirname = PathUtils.GetDirectoryName(resolved_id); var resolved_id_bytes = Utils.TextUtils.GetNullTerminatedBytes(resolved_id); var filename_obj = JSApi.JS_GetProperty(ctx, module_obj, context.GetAtom("filename")); var module_id_atom = context.GetAtom(resolved_id); var dirname_atom = context.GetAtom(dirname); var require_obj = JSApi.JSB_NewCFunction(ctx, ScriptRuntime.module_require, context.GetAtom("require"), 1, JSCFunctionEnum.JS_CFUNC_generic, 0); var main_mod_obj = context._dup_commonjs_main_module(); var dirname_obj = JSApi.JS_AtomToString(ctx, dirname_atom); var exports_obj = JSApi.JS_GetProperty(ctx, module_obj, context.GetAtom("exports")); JSApi.JS_SetProperty(ctx, require_obj, context.GetAtom("moduleId"), JSApi.JS_AtomToString(ctx, module_id_atom)); JSApi.JS_SetProperty(ctx, require_obj, context.GetAtom("main"), main_mod_obj); var require_argv = new JSValue[5] { exports_obj, require_obj, module_obj, filename_obj, dirname_obj, }; var tagValue = ScriptRuntime.TryReadByteCodeTagValue(source); if (tagValue == ScriptRuntime.BYTECODE_COMMONJS_MODULE_TAG) { // bytecode fixed(byte *intput_ptr = source) { var bytecodeFunc = JSApi.JS_ReadObject(ctx, intput_ptr + sizeof(uint), source.Length - sizeof(uint), JSApi.JS_READ_OBJ_BYTECODE); if (bytecodeFunc.tag == JSApi.JS_TAG_FUNCTION_BYTECODE) { var func_val = JSApi.JS_EvalFunction(ctx, bytecodeFunc); // it's CallFree (bytecodeFunc) if (JSApi.JS_IsFunction(ctx, func_val) != 1) { JSApi.JS_FreeValue(ctx, func_val); JSApi.JS_FreeValue(ctx, require_argv); return(JSApi.JS_ThrowInternalError(ctx, "failed to require bytecode module")); } var rval = JSApi.JS_Call(ctx, func_val, JSApi.JS_UNDEFINED, require_argv.Length, require_argv); JSApi.JS_FreeValue(ctx, func_val); if (rval.IsException()) { JSApi.JS_FreeValue(ctx, require_argv); return(rval); } // success JSApi.JS_FreeValue(ctx, rval); } else { JSApi.JS_FreeValue(ctx, bytecodeFunc); JSApi.JS_FreeValue(ctx, require_argv); return(JSApi.JS_ThrowInternalError(ctx, "failed to require bytecode module")); } } } else { // source var input_bytes = TextUtils.GetShebangNullTerminatedCommonJSBytes(source); fixed(byte *input_ptr = input_bytes) fixed(byte *resolved_id_ptr = resolved_id_bytes) { var input_len = (size_t)(input_bytes.Length - 1); var func_val = JSApi.JS_Eval(ctx, input_ptr, input_len, resolved_id_ptr, JSEvalFlags.JS_EVAL_TYPE_GLOBAL | JSEvalFlags.JS_EVAL_FLAG_STRICT); if (func_val.IsException()) { JSApi.JS_FreeValue(ctx, require_argv); return(func_val); } if (JSApi.JS_IsFunction(ctx, func_val) == 1) { var rval = JSApi.JS_Call(ctx, func_val, JSApi.JS_UNDEFINED, require_argv.Length, require_argv); if (rval.IsException()) { JSApi.JS_FreeValue(ctx, func_val); JSApi.JS_FreeValue(ctx, require_argv); return(rval); } JSApi.JS_FreeValue(ctx, rval); } JSApi.JS_FreeValue(ctx, func_val); } } JSApi.JS_SetProperty(ctx, module_obj, context.GetAtom("loaded"), JSApi.JS_NewBool(ctx, true)); var exports_ = JSApi.JS_GetProperty(ctx, module_obj, context.GetAtom("exports")); JSApi.JS_FreeValue(ctx, require_argv); return(exports_); }