⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jsinterp.c

📁 java script test programing source code
💻 C
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sw=4 et tw=78: * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Mozilla Communicator client code, released * March 31, 1998. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** *//* * JavaScript bytecode interpreter. */#include "jsstddef.h"#include <stdio.h>#include <string.h>#include <math.h>#include "jstypes.h"#include "jsarena.h" /* Added by JSIFY */#include "jsutil.h" /* Added by JSIFY */#include "jsprf.h"#include "jsapi.h"#include "jsarray.h"#include "jsatom.h"#include "jsbool.h"#include "jscntxt.h"#include "jsconfig.h"#include "jsdbgapi.h"#include "jsfun.h"#include "jsgc.h"#include "jsinterp.h"#include "jsiter.h"#include "jslock.h"#include "jsnum.h"#include "jsobj.h"#include "jsopcode.h"#include "jsscan.h"#include "jsscope.h"#include "jsscript.h"#include "jsstr.h"#if JS_HAS_XML_SUPPORT#include "jsxml.h"#endif#ifdef DEBUG#define ASSERT_CACHE_IS_EMPTY(cache)                                          \    JS_BEGIN_MACRO                                                            \        JSPropertyCacheEntry *end_, *pce_, entry_;                            \        JSPropertyCache *cache_ = (cache);                                    \        JS_ASSERT(cache_->empty);                                             \        end_ = &cache_->table[PROPERTY_CACHE_SIZE];                           \        for (pce_ = &cache_->table[0]; pce_ < end_; pce_++) {                 \            PCE_LOAD(cache_, pce_, entry_);                                   \            JS_ASSERT(!PCE_OBJECT(entry_));                                   \            JS_ASSERT(!PCE_PROPERTY(entry_));                                 \        }                                                                     \    JS_END_MACRO#else#define ASSERT_CACHE_IS_EMPTY(cache) ((void)0)#endifvoidjs_FlushPropertyCache(JSContext *cx){    JSPropertyCache *cache;    cache = &cx->runtime->propertyCache;    if (cache->empty) {        ASSERT_CACHE_IS_EMPTY(cache);        return;    }    memset(cache->table, 0, sizeof cache->table);    cache->empty = JS_TRUE;#ifdef JS_PROPERTY_CACHE_METERING    cache->flushes++;#endif}voidjs_DisablePropertyCache(JSContext *cx){    JS_ASSERT(!cx->runtime->propertyCache.disabled);    cx->runtime->propertyCache.disabled = JS_TRUE;}voidjs_EnablePropertyCache(JSContext *cx){    JS_ASSERT(cx->runtime->propertyCache.disabled);    ASSERT_CACHE_IS_EMPTY(&cx->runtime->propertyCache);    cx->runtime->propertyCache.disabled = JS_FALSE;}/* * Stack macros and functions.  These all use a local variable, jsval *sp, to * point to the next free stack slot.  SAVE_SP must be called before any call * to a function that may invoke the interpreter.  RESTORE_SP must be called * only after return from js_Invoke, because only js_Invoke changes fp->sp. */#define PUSH(v)         (*sp++ = (v))#define POP()           (*--sp)#ifdef DEBUG#define SAVE_SP(fp)                                                           \    (JS_ASSERT((fp)->script || !(fp)->spbase || (sp) == (fp)->spbase),        \     (fp)->sp = sp)#else#define SAVE_SP(fp)     ((fp)->sp = sp)#endif#define RESTORE_SP(fp)  (sp = (fp)->sp)/* * SAVE_SP_AND_PC commits deferred stores of interpreter registers to their * homes in fp, when calling out of the interpreter loop or threaded code. * RESTORE_SP_AND_PC copies the other way, to update registers after a call * to a subroutine that interprets a piece of the current script. */#define SAVE_SP_AND_PC(fp)      (SAVE_SP(fp), (fp)->pc = pc)#define RESTORE_SP_AND_PC(fp)   (RESTORE_SP(fp), pc = (fp)->pc)/* * Push the generating bytecode's pc onto the parallel pc stack that runs * depth slots below the operands. * * NB: PUSH_OPND uses sp, depth, and pc from its lexical environment.  See * js_Interpret for these local variables' declarations and uses. */#define PUSH_OPND(v)    (sp[-depth] = (jsval)pc, PUSH(v))#define STORE_OPND(n,v) (sp[(n)-depth] = (jsval)pc, sp[n] = (v))#define POP_OPND()      POP()#define FETCH_OPND(n)   (sp[n])/* * Push the jsdouble d using sp, depth, and pc from the lexical environment. * Try to convert d to a jsint that fits in a jsval, otherwise GC-alloc space * for it and push a reference. */#define STORE_NUMBER(cx, n, d)                                                \    JS_BEGIN_MACRO                                                            \        jsint i_;                                                             \        jsval v_;                                                             \                                                                              \        if (JSDOUBLE_IS_INT(d, i_) && INT_FITS_IN_JSVAL(i_)) {                \            v_ = INT_TO_JSVAL(i_);                                            \        } else {                                                              \            ok = js_NewDoubleValue(cx, d, &v_);                               \            if (!ok)                                                          \                goto out;                                                     \        }                                                                     \        STORE_OPND(n, v_);                                                    \    JS_END_MACRO#define STORE_INT(cx, n, i)                                                   \    JS_BEGIN_MACRO                                                            \        jsval v_;                                                             \                                                                              \        if (INT_FITS_IN_JSVAL(i)) {                                           \            v_ = INT_TO_JSVAL(i);                                             \        } else {                                                              \            ok = js_NewDoubleValue(cx, (jsdouble)(i), &v_);                   \            if (!ok)                                                          \                goto out;                                                     \        }                                                                     \        STORE_OPND(n, v_);                                                    \    JS_END_MACRO#define STORE_UINT(cx, n, u)                                                  \    JS_BEGIN_MACRO                                                            \        jsval v_;                                                             \                                                                              \        if ((u) <= JSVAL_INT_MAX) {                                           \            v_ = INT_TO_JSVAL(u);                                             \        } else {                                                              \            ok = js_NewDoubleValue(cx, (jsdouble)(u), &v_);                   \            if (!ok)                                                          \                goto out;                                                     \        }                                                                     \        STORE_OPND(n, v_);                                                    \    JS_END_MACRO#define FETCH_NUMBER(cx, n, d)                                                \    JS_BEGIN_MACRO                                                            \        jsval v_;                                                             \                                                                              \        v_ = FETCH_OPND(n);                                                   \        VALUE_TO_NUMBER(cx, v_, d);                                           \    JS_END_MACRO#define FETCH_INT(cx, n, i)                                                   \    JS_BEGIN_MACRO                                                            \        jsval v_ = FETCH_OPND(n);                                             \        if (JSVAL_IS_INT(v_)) {                                               \            i = JSVAL_TO_INT(v_);                                             \        } else {                                                              \            SAVE_SP_AND_PC(fp);                                               \            ok = js_ValueToECMAInt32(cx, v_, &i);                             \            if (!ok)                                                          \                goto out;                                                     \        }                                                                     \    JS_END_MACRO#define FETCH_UINT(cx, n, ui)                                                 \    JS_BEGIN_MACRO                                                            \        jsval v_ = FETCH_OPND(n);                                             \        jsint i_;                                                             \        if (JSVAL_IS_INT(v_) && (i_ = JSVAL_TO_INT(v_)) >= 0) {               \            ui = (uint32) i_;                                                 \        } else {                                                              \            SAVE_SP_AND_PC(fp);                                               \            ok = js_ValueToECMAUint32(cx, v_, &ui);                           \            if (!ok)                                                          \                goto out;                                                     \        }                                                                     \    JS_END_MACRO/* * Optimized conversion macros that test for the desired type in v before * homing sp and calling a conversion function. */#define VALUE_TO_NUMBER(cx, v, d)                                             \    JS_BEGIN_MACRO                                                            \        if (JSVAL_IS_INT(v)) {                                                \            d = (jsdouble)JSVAL_TO_INT(v);                                    \        } else if (JSVAL_IS_DOUBLE(v)) {                                      \            d = *JSVAL_TO_DOUBLE(v);                                          \        } else {                                                              \            SAVE_SP_AND_PC(fp);                                               \            ok = js_ValueToNumber(cx, v, &d);                                 \            if (!ok)                                                          \                goto out;                                                     \        }                                                                     \    JS_END_MACRO#define POP_BOOLEAN(cx, v, b)                                                 \    JS_BEGIN_MACRO                                                            \        v = FETCH_OPND(-1);                                                   \        if (v == JSVAL_NULL) {                                                \            b = JS_FALSE;                                                     \        } else if (JSVAL_IS_BOOLEAN(v)) {                                     \            b = JSVAL_TO_BOOLEAN(v);                                          \        } else {                                                              \            SAVE_SP_AND_PC(fp);                                               \            ok = js_ValueToBoolean(cx, v, &b);                                \            if (!ok)                                                          \                goto out;                                                     \        }                                                                     \        sp--;                                                                 \    JS_END_MACRO/* * Convert a primitive string, number or boolean to a corresponding object. * v must not be an object, null or undefined when using this macro. */#define PRIMITIVE_TO_OBJECT(cx, v, obj)                                       \    JS_BEGIN_MACRO                                                            \        SAVE_SP(fp);                                                          \        if (JSVAL_IS_STRING(v)) {                                             \            obj = js_StringToObject(cx, JSVAL_TO_STRING(v));                  \        } else if (JSVAL_IS_INT(v)) {                                         \            obj = js_NumberToObject(cx, (jsdouble)JSVAL_TO_INT(v));           \        } else if (JSVAL_IS_DOUBLE(v)) {                                      \            obj = js_NumberToObject(cx, *JSVAL_TO_DOUBLE(v));                 \        } else {                                                              \            JS_ASSERT(JSVAL_IS_BOOLEAN(v));                                   \            obj = js_BooleanToObject(cx, JSVAL_TO_BOOLEAN(v));                \        }                                                                     \    JS_END_MACRO#define VALUE_TO_OBJECT(cx, v, obj)                                           \    JS_BEGIN_MACRO                                                            \        if (!JSVAL_IS_PRIMITIVE(v)) {                                         \            obj = JSVAL_TO_OBJECT(v);                                         \        } else {                                                              \            SAVE_SP_AND_PC(fp);                                               \            obj = js_ValueToNonNullObject(cx, v);                             \            if (!obj) {                                                       \                ok = JS_FALSE;                                                \                goto out;                                                     \            }                                                                 \        }                                                                     \    JS_END_MACRO#define FETCH_OBJECT(cx, n, v, obj)                                           \    JS_BEGIN_MACRO                                                            \        v = FETCH_OPND(n);                                                    \        VALUE_TO_OBJECT(cx, v, obj);                                          \        STORE_OPND(n, OBJECT_TO_JSVAL(obj));                                  \    JS_END_MACRO#define VALUE_TO_PRIMITIVE(cx, v, hint, vp)                                   \    JS_BEGIN_MACRO                                                            \        if (JSVAL_IS_PRIMITIVE(v)) {                                          \            *vp = v;                                                          \        } else {                                                              \            SAVE_SP_AND_PC(fp);                                               \            ok = OBJ_DEFAULT_VALUE(cx, JSVAL_TO_OBJECT(v), hint, vp);         \            if (!ok)                                                          \                goto out;                                                     \        }                                                                     \    JS_END_MACROJS_FRIEND_API(jsval *)js_AllocRawStack(JSContext *cx, uintN nslots, void **markp){    jsval *sp;    if (markp)        *markp = JS_ARENA_MARK(&cx->stackPool);    JS_ARENA_ALLOCATE_CAST(sp, jsval *, &cx->stackPool, nslots * sizeof(jsval));    if (!sp) {        JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_STACK_OVERFLOW,                             (cx->fp && cx->fp->fun)                             ? JS_GetFunctionName(cx->fp->fun)                             : "script");    }    return sp;}JS_FRIEND_API(void)js_FreeRawStack(JSContext *cx, void *mark){    JS_ARENA_RELEASE(&cx->stackPool, mark);}JS_FRIEND_API(jsval *)js_AllocStack(JSContext *cx, uintN nslots, void **markp){    jsval *sp, *vp, *end;    JSArena *a;    JSStackHeader *sh;    JSStackFrame *fp;    /* Callers don't check for zero nslots: we do to avoid empty segments. */    if (nslots == 0) {        *markp = NULL;        return JS_ARENA_MARK(&cx->stackPool);    }    /* Allocate 2 extra slots for the stack segment header we'll likely need. */    sp = js_AllocRawStack(cx, 2 + nslots, markp);    if (!sp)        return NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -