mirror of
https://onedev.site.tesses.net/crosslang
synced 2026-04-17 09:37:03 +00:00
Add const variables
This commit is contained in:
@@ -666,7 +666,8 @@ typedef enum {
|
||||
PUSHCONTINUE,
|
||||
JMPIFBREAK,
|
||||
JMPIFCONTINUE,
|
||||
JMPIFDEFINED
|
||||
JMPIFDEFINED,
|
||||
DECLARECONSTVARIABLE
|
||||
} Instruction;
|
||||
/**
|
||||
* @brief Base type for bytecode instruction
|
||||
@@ -991,6 +992,12 @@ constexpr std::string_view DictionaryExpression = "dictionaryExpression";
|
||||
*
|
||||
*/
|
||||
constexpr std::string_view DeclareExpression = "declareExpression";
|
||||
/**
|
||||
* @brief const v = 59;
|
||||
*
|
||||
*/
|
||||
|
||||
constexpr std::string_view ConstExpression = "constExpression";
|
||||
/**
|
||||
* @brief Closure expression (a,b)=> a * b
|
||||
*
|
||||
@@ -1666,10 +1673,10 @@ class GC {
|
||||
virtual void Mark();
|
||||
};
|
||||
|
||||
|
||||
void ThrowConstError(std::string key);
|
||||
|
||||
class TEnvironment : public THeapObject {
|
||||
|
||||
std::vector<std::string> consts;
|
||||
public:
|
||||
std::vector<TCallable*> defers;
|
||||
TObject LoadFile(GC* gc, TFile* f);
|
||||
@@ -1687,6 +1694,9 @@ class GC {
|
||||
virtual void SetVariable(std::string key, TObject value)=0;
|
||||
TDictionary* EnsureDictionary(GC* gc, std::string key);
|
||||
virtual void DeclareVariable(std::string key, TObject value)=0;
|
||||
void DeclareConstVariable(std::string key, TObject value);
|
||||
bool HasConstForDeclare(std::string key);
|
||||
virtual bool HasConstForSet(std::string key);
|
||||
void DeclareVariable(GC* gc,std::vector<std::string> key, TObject value);
|
||||
virtual TRootEnvironment* GetRootEnvironment()=0;
|
||||
virtual TEnvironment* GetParentEnvironment()=0;
|
||||
@@ -1744,6 +1754,8 @@ class GC {
|
||||
TObject SetVariable(GCList& ls, std::string key, TObject v);
|
||||
|
||||
void DeclareVariable(std::string key, TObject value);
|
||||
bool HasConstForSet(std::string key);
|
||||
|
||||
TRootEnvironment* GetRootEnvironment();
|
||||
TEnvironment* GetParentEnvironment();
|
||||
|
||||
@@ -1846,7 +1858,8 @@ class GC {
|
||||
bool HasVariable(std::string key);
|
||||
bool HasVariableRecurse(std::string key);
|
||||
bool HasVariableOrFieldRecurse(std::string key, bool setting=false);
|
||||
|
||||
bool HasConstForSet(std::string key);
|
||||
|
||||
TObject GetVariable(std::string key);
|
||||
void SetVariable(std::string key, TObject value);
|
||||
TObject GetVariable(GCList& ls, std::string key);
|
||||
@@ -2226,6 +2239,7 @@ class GC {
|
||||
bool GetArray(GC* gc);
|
||||
bool SetArray(GC* gc);
|
||||
bool DeclareVariable(GC* gc);
|
||||
bool DeclareConstVariable(GC* gc);
|
||||
bool PushLong(GC* gc);
|
||||
bool PushDouble(GC* gc);
|
||||
bool PushChar(GC* gc);
|
||||
|
||||
@@ -451,6 +451,10 @@ namespace Tesses::CrossLang {
|
||||
{
|
||||
instrs.push_back(std::make_shared<SimpleChunkInstruction>(DECLAREVARIABLE));
|
||||
}
|
||||
else if(name == "declareconstvariable")
|
||||
{
|
||||
instrs.push_back(std::make_shared<SimpleChunkInstruction>(DECLARECONSTVARIABLE));
|
||||
}
|
||||
else if(name == "setfield")
|
||||
{
|
||||
instrs.push_back(std::make_shared<SimpleChunkInstruction>(SETFIELD));
|
||||
|
||||
@@ -459,6 +459,9 @@ namespace Tesses::CrossLang {
|
||||
case DECLAREVARIABLE:
|
||||
buffer.append("declarevariable");
|
||||
break;
|
||||
case DECLARECONSTVARIABLE:
|
||||
buffer.append("declareconstvariable");
|
||||
break;
|
||||
case SETFIELD:
|
||||
buffer.append("setfield");
|
||||
break;
|
||||
|
||||
@@ -1257,6 +1257,29 @@ namespace Tesses::CrossLang
|
||||
|
||||
}
|
||||
}
|
||||
else if(varNode.nodeName == ConstExpression && varNode.nodes.size() == 1 && std::holds_alternative<std::string>(varNode.nodes[0]))
|
||||
{
|
||||
GenNode(instructions,varNode.nodes[0],scope,contscope,brkscope,contI,brkI);
|
||||
GenNode(instructions,adv.nodes[1],scope,contscope,brkscope,contI,brkI);
|
||||
instructions.push_back(new SimpleInstruction(DECLARECONSTVARIABLE));
|
||||
}
|
||||
else if(varNode.nodeName == ConstExpression && varNode.nodes.size() == 1 && std::holds_alternative<AdvancedSyntaxNode>(varNode.nodes[0]))
|
||||
{
|
||||
auto adv2 = std::get<AdvancedSyntaxNode>(varNode.nodes[0]);
|
||||
|
||||
if(adv2.nodeName == ArrayExpression && adv2.nodes.size() == 1)
|
||||
{
|
||||
|
||||
auto vars= StringifyListOfVars(adv2.nodes[0]);
|
||||
|
||||
auto nArray = AdvancedSyntaxNode::Create(ArrayExpression,true,{vars});
|
||||
|
||||
this->GenNode(instructions,nArray ,scope ,contscope ,brkscope ,contI , brkI);
|
||||
GenNode(instructions,adv.nodes[1],scope,contscope,brkscope,contI,brkI);
|
||||
instructions.push_back(new SimpleInstruction(DECLARECONSTVARIABLE));
|
||||
|
||||
}
|
||||
}
|
||||
else if(varNode.nodeName == GetFieldExpression && varNode.nodes.size() == 2)
|
||||
{
|
||||
GenNode(instructions,varNode.nodes[0],scope,contscope,brkscope,contI,brkI);
|
||||
|
||||
@@ -730,6 +730,33 @@ namespace Tesses::CrossLang
|
||||
node = AdvancedSyntaxNode::Create(DeclareExpression,true,{variable.text});
|
||||
}
|
||||
}
|
||||
else if(IsIdentifier("const"))
|
||||
{
|
||||
if(i >= tokens.size()) throw std::out_of_range("End of file");
|
||||
auto variable = tokens[i];
|
||||
|
||||
i++;
|
||||
if(variable.type == LexTokenType::Symbol && variable.text == ".")
|
||||
{
|
||||
EnsureSymbol("[");
|
||||
node = AdvancedSyntaxNode::Create(ConstExpression,true,{
|
||||
AdvancedSyntaxNode::Create(GetVariableExpression ,true,{ParseExpression()})
|
||||
});
|
||||
EnsureSymbol("]");
|
||||
}
|
||||
else if(variable.type == LexTokenType::Symbol && variable.text == "[")
|
||||
{
|
||||
node = AdvancedSyntaxNode::Create(ConstExpression,true,{
|
||||
AdvancedSyntaxNode::Create(ArrayExpression ,true,{ParseExpression()})
|
||||
});
|
||||
EnsureSymbol("]");
|
||||
}
|
||||
else if(variable.type != LexTokenType::Identifier) throw SyntaxException(variable.lineInfo, "Expected an identifier got a " + LexTokenType_ToString(variable.type) + " \"" + variable.text + "\"");
|
||||
else
|
||||
{
|
||||
node = AdvancedSyntaxNode::Create(ConstExpression,true,{variable.text});
|
||||
}
|
||||
}
|
||||
else if(IsIdentifier("comptime"))
|
||||
{
|
||||
SyntaxNode n = nullptr;
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
#include "CrossLang.hpp"
|
||||
namespace Tesses::CrossLang {
|
||||
|
||||
bool TClassEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
if(this->env->HasVariableRecurse(key))
|
||||
{
|
||||
return this->env->HasConstForSet(key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TClassEnvironment* TClassEnvironment::Create(GCList* gc,TEnvironment* env,TClassObject* obj)
|
||||
{
|
||||
|
||||
@@ -95,6 +102,7 @@ namespace Tesses::CrossLang {
|
||||
if(GetObjectHeap(res,call)) return call->Call(ls,{v});
|
||||
}
|
||||
if(this->clsObj->HasValue(clsName,key)) { this->clsObj->SetValue(clsName,key,v); return v;}
|
||||
|
||||
return this->env->SetVariable(ls,key,v);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,27 @@
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
namespace Tesses::CrossLang {
|
||||
void ThrowConstError(std::string key)
|
||||
{
|
||||
throw std::runtime_error("Cannot set \"" + key + "\" because it is a const");
|
||||
}
|
||||
|
||||
void TEnvironment::DeclareConstVariable(std::string key, TObject value)
|
||||
{
|
||||
this->DeclareVariable(key,value);
|
||||
this->consts.push_back(key);
|
||||
}
|
||||
bool TEnvironment::HasConstForDeclare(std::string key)
|
||||
{
|
||||
for(auto item : this->consts)
|
||||
if(item == key)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool TEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
return HasConstForDeclare(key);
|
||||
}
|
||||
bool TRootEnvironment::TryFindClass(std::vector<std::string>& name, size_t& index)
|
||||
{
|
||||
for(size_t i = 0; i < this->classes.size(); i++)
|
||||
|
||||
@@ -50,6 +50,18 @@ namespace Tesses::CrossLang {
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
bool TSubEnvironment::HasConstForSet(std::string key)
|
||||
{
|
||||
if(this->dict->HasValue(key))
|
||||
{
|
||||
return this->HasConstForDeclare(key);
|
||||
}
|
||||
if(this->env->HasVariableRecurse(key))
|
||||
{
|
||||
return this->env->HasConstForSet(key);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
TObject TSubEnvironment::SetVariable(GCList& ls, std::string key, TObject value)
|
||||
{
|
||||
ls.GetGC()->BarrierBegin();
|
||||
|
||||
265
src/vm/vm.cpp
265
src/vm/vm.cpp
@@ -4390,19 +4390,53 @@ namespace Tesses::CrossLang {
|
||||
|
||||
gc->BarrierBegin();
|
||||
if(args.size() > 1 && GetArgument(args,0,key))
|
||||
env->SetVariable(key,args[1]);
|
||||
{
|
||||
if(env->HasConstForSet(key))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(key);
|
||||
}
|
||||
|
||||
env->SetVariable(key,args[1]);
|
||||
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
cse.back()->Push(gc,nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(key == "DeclareVariable")
|
||||
{
|
||||
std::string key;
|
||||
|
||||
gc->BarrierBegin();
|
||||
if(args.size() > 1 && GetArgument(args,0,key))
|
||||
env->DeclareVariable(key,args[1]);
|
||||
{
|
||||
if(env->HasConstForDeclare(key))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(key);
|
||||
}
|
||||
env->DeclareVariable(key,args[1]);
|
||||
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
cse.back()->Push(gc,nullptr);
|
||||
return false;
|
||||
}
|
||||
if(key == "DeclareConstVariable")
|
||||
{
|
||||
std::string key;
|
||||
|
||||
gc->BarrierBegin();
|
||||
if(args.size() > 1 && GetArgument(args,0,key))
|
||||
{
|
||||
if(env->HasConstForDeclare(key))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(key);
|
||||
}
|
||||
env->DeclareConstVariable(key,args[1]);
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
cse.back()->Push(gc,nullptr);
|
||||
return false;
|
||||
@@ -6048,6 +6082,12 @@ namespace Tesses::CrossLang {
|
||||
if(std::holds_alternative<std::string>(key))
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
|
||||
if(stk->env->HasConstForSet(std::get<std::string>(key)))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(std::get<std::string>(key));
|
||||
}
|
||||
stk->Push(gc,stk->env->SetVariable(ls,std::get<std::string>(key),value));
|
||||
|
||||
gc->BarrierEnd();
|
||||
@@ -6072,6 +6112,12 @@ namespace Tesses::CrossLang {
|
||||
{
|
||||
auto val = valueLs->Get(i);
|
||||
result->SetValue(mkey, val);
|
||||
|
||||
if(stk->env->HasConstForSet(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->SetVariable(ls,mkey,val);
|
||||
}
|
||||
}
|
||||
@@ -6093,6 +6139,12 @@ namespace Tesses::CrossLang {
|
||||
auto val = valueDynList->GetAt(ls,i);
|
||||
gc->BarrierBegin();
|
||||
result->SetValue(mkey, val);
|
||||
|
||||
if(stk->env->HasConstForSet(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->SetVariable(ls,mkey,val);
|
||||
}
|
||||
}
|
||||
@@ -6111,6 +6163,12 @@ namespace Tesses::CrossLang {
|
||||
{
|
||||
auto val = valueDict->GetValue(mkey);
|
||||
result->SetValue(mkey, val);
|
||||
|
||||
if(stk->env->HasConstForSet(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->SetVariable(ls,mkey,val);
|
||||
}
|
||||
}
|
||||
@@ -6131,6 +6189,12 @@ namespace Tesses::CrossLang {
|
||||
gc->BarrierBegin();
|
||||
|
||||
result->SetValue(mkey, val);
|
||||
|
||||
if(stk->env->HasConstForSet(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->SetVariable(ls,mkey,val);
|
||||
}
|
||||
}
|
||||
@@ -6144,6 +6208,12 @@ namespace Tesses::CrossLang {
|
||||
auto item = mls->Get(i);
|
||||
if(GetObject(item,mkey))
|
||||
{
|
||||
if(stk->env->HasConstForSet(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
|
||||
stk->env->SetVariable(ls,mkey, value);
|
||||
}
|
||||
}
|
||||
@@ -6174,6 +6244,11 @@ namespace Tesses::CrossLang {
|
||||
if(std::holds_alternative<std::string>(key))
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
if(stk->env->HasConstForDeclare(std::get<std::string>(key)))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(std::get<std::string>(key));
|
||||
}
|
||||
stk->env->DeclareVariable(std::get<std::string>(key),value);
|
||||
stk->Push(gc, value);
|
||||
gc->BarrierEnd();
|
||||
@@ -6198,6 +6273,11 @@ namespace Tesses::CrossLang {
|
||||
{
|
||||
auto val = valueLs->Get(i);
|
||||
result->SetValue(mkey, val);
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareVariable(mkey,val);
|
||||
}
|
||||
}
|
||||
@@ -6219,6 +6299,11 @@ namespace Tesses::CrossLang {
|
||||
auto val = valueDynList->GetAt(ls,i);
|
||||
gc->BarrierBegin();
|
||||
result->SetValue(mkey, val);
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareVariable(mkey,val);
|
||||
}
|
||||
}
|
||||
@@ -6237,6 +6322,11 @@ namespace Tesses::CrossLang {
|
||||
{
|
||||
auto val = valueDict->GetValue(mkey);
|
||||
result->SetValue(mkey, val);
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareVariable(mkey,val);
|
||||
}
|
||||
}
|
||||
@@ -6257,6 +6347,11 @@ namespace Tesses::CrossLang {
|
||||
gc->BarrierBegin();
|
||||
|
||||
result->SetValue(mkey, val);
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareVariable(mkey,val);
|
||||
}
|
||||
}
|
||||
@@ -6270,6 +6365,11 @@ namespace Tesses::CrossLang {
|
||||
auto item = mls->Get(i);
|
||||
if(GetObject(item,mkey))
|
||||
{
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareVariable(mkey, value);
|
||||
}
|
||||
}
|
||||
@@ -6287,6 +6387,165 @@ namespace Tesses::CrossLang {
|
||||
}
|
||||
|
||||
|
||||
bool InterperterThread::DeclareConstVariable(GC* gc)
|
||||
{
|
||||
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
|
||||
if(!cse.empty())
|
||||
{
|
||||
auto stk = cse.back();
|
||||
GCList ls(gc);
|
||||
|
||||
auto value = stk->Pop(ls);
|
||||
auto key = stk->Pop(ls);
|
||||
|
||||
TList* mls;
|
||||
|
||||
if(std::holds_alternative<std::string>(key))
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
if(stk->env->HasConstForDeclare(std::get<std::string>(key)))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(std::get<std::string>(key));
|
||||
}
|
||||
stk->env->DeclareConstVariable(std::get<std::string>(key),value);
|
||||
stk->Push(gc, value);
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
else if(GetObjectHeap(key,mls))
|
||||
{
|
||||
gc->BarrierBegin();
|
||||
|
||||
TList* valueLs;
|
||||
TDynamicList* valueDynList;
|
||||
TDictionary* valueDict;
|
||||
TDynamicDictionary* valueDynDict;
|
||||
if(GetObjectHeap(value, valueLs))
|
||||
{
|
||||
TDictionary* result = TDictionary::Create(ls);
|
||||
int64_t len = std::min(valueLs->Count(), mls->Count());
|
||||
for(int64_t i = 0; i < len; i++)
|
||||
{
|
||||
std::string mkey;
|
||||
auto item = mls->Get(i);
|
||||
if(GetObject(item,mkey))
|
||||
{
|
||||
auto val = valueLs->Get(i);
|
||||
result->SetValue(mkey, val);
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareConstVariable(mkey,val);
|
||||
}
|
||||
}
|
||||
stk->Push(gc,result);
|
||||
}
|
||||
else if(GetObjectHeap(value, valueDynList))
|
||||
{
|
||||
TDictionary* result = TDictionary::Create(ls);
|
||||
gc->BarrierEnd();
|
||||
int64_t len = std::min(valueDynList->Count(ls), mls->Count());
|
||||
gc->BarrierBegin();
|
||||
for(int64_t i = 0; i < len; i++)
|
||||
{
|
||||
std::string mkey;
|
||||
auto item = mls->Get(i);
|
||||
if(GetObject(item,mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
auto val = valueDynList->GetAt(ls,i);
|
||||
gc->BarrierBegin();
|
||||
result->SetValue(mkey, val);
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareConstVariable(mkey,val);
|
||||
}
|
||||
}
|
||||
stk->Push(gc,result);
|
||||
}
|
||||
else if(GetObjectHeap(value, valueDict))
|
||||
{
|
||||
|
||||
TDictionary* result = TDictionary::Create(ls);
|
||||
int64_t len = mls->Count();
|
||||
for(int64_t i = 0; i < len; i++)
|
||||
{
|
||||
std::string mkey;
|
||||
auto item = mls->Get(i);
|
||||
if(GetObject(item,mkey))
|
||||
{
|
||||
auto val = valueDict->GetValue(mkey);
|
||||
result->SetValue(mkey, val);
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareConstVariable(mkey,val);
|
||||
}
|
||||
}
|
||||
stk->Push(gc,result);
|
||||
}
|
||||
else if(GetObjectHeap(value, valueDynDict))
|
||||
{
|
||||
TDictionary* result = TDictionary::Create(ls);
|
||||
int64_t len =mls->Count();
|
||||
for(int64_t i = 0; i < len; i++)
|
||||
{
|
||||
std::string mkey;
|
||||
auto item = mls->Get(i);
|
||||
if(GetObject(item,mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
auto val = valueDynDict->GetField(ls,mkey);
|
||||
gc->BarrierBegin();
|
||||
|
||||
result->SetValue(mkey, val);
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareConstVariable(mkey,val);
|
||||
}
|
||||
}
|
||||
stk->Push(gc,result);
|
||||
}
|
||||
else {
|
||||
int64_t len =mls->Count();
|
||||
for(int64_t i = 0; i < len; i++)
|
||||
{
|
||||
std::string mkey;
|
||||
auto item = mls->Get(i);
|
||||
if(GetObject(item,mkey))
|
||||
{
|
||||
if(stk->env->HasConstForDeclare(mkey))
|
||||
{
|
||||
gc->BarrierEnd();
|
||||
ThrowConstError(mkey);
|
||||
}
|
||||
stk->env->DeclareConstVariable(mkey, value);
|
||||
}
|
||||
}
|
||||
stk->Push(gc, value);
|
||||
}
|
||||
gc->BarrierEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
throw VMException("[DECLARECONSTVARIABLE] Can't pop string, got type " + GetObjectTypeString(key) + " = " + ToString(gc,key) + ".");
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool InterperterThread::PushResource(GC* gc)
|
||||
{
|
||||
std::vector<CallStackEntry*>& cse=this->call_stack_entries;
|
||||
|
||||
@@ -63,7 +63,7 @@ static opcode opcodes[256]={
|
||||
&InterperterThread::JumpIfBreak,
|
||||
&InterperterThread::JumpIfContinue,
|
||||
&InterperterThread::JumpIfDefined,
|
||||
&InterperterThread::Illegal,
|
||||
&InterperterThread::DeclareConstVariable,
|
||||
&InterperterThread::Illegal,
|
||||
&InterperterThread::Illegal,
|
||||
&InterperterThread::Illegal,
|
||||
|
||||
Reference in New Issue
Block a user